Код:
unsigned int printfx(unsigned char* cmdstr,...) __naked
{cmdstr;
__asm
TheFlag .equ 1
TheNum .equ 2
TheSize .equ 3
TheType .equ 4
sz_l .equ 0
sz_hh .equ 1
sz_h .equ 2
sz_ll .equ 3
sz_j .equ 4
sz_z .equ 5
sz_t .equ 6
sz_L .equ 7
PRINTF::
LD (EXITT+1),SP
POP BC ; return addres
POP HL ; direct string addres
EXX
LD HL,#0
ADD HL,SP ; args ptr
LD BC,#0 ; C = char counter
LD DE,#buffer
EXX
PUSH HL
PUSH BC
MCICLE: PUSH HL
CALL RESET
POP HL
WCICLE: LD A,(HL)
OR A
JR Z,EXIT
CP #'%'
JR NZ,M3
inc hl
ld a,(hl)
cp #'%'
jr z,M3
M4: CALL ParseFormat
OR A
JR NZ,M1 ; что за спецификатор?
LD A,(HL) ; нераспознанный спецификатор печатается как обычный символ.
M3: CALL OUTCHR
INC HL
JR WCICLE
M1: INC HL
CP #TheType
JR Z,MCICLE
LD A,(HL)
JR M4
EXIT: exx
push bc
inc de
ex de,hl
ld (hl),#0
exx
ld hl,#buffer
ld a,#0x0e
call 0x8003
pop hl ; char counter
EXITT: LD SP,#0
RET
; parsing routines for PRINTF
ParseFormat::
; in: A = checking symbol.
PUSH HL
LD HL,#FlagL
LD D,H
LD E,L
LD BC,#5
CPIR
JR NZ,ChkNum ; found
DoFlags: LD BC,#FlagSbr
DO: OR A,A
SBC HL,DE
DEC HL
ADD HL,HL
ADD HL,BC
LD E,(HL)
INC HL
LD D,(HL)
EX DE,HL
JP (HL)
ChkNum: LD HL,#NumL
LD D,H
LD E,L
LD BC,#10
CPIR
JR NZ,ChkSize
LD C,A
LD A,#TheNum
RET
ChkSize:
LD HL,#SztpL
LD D,H
LD E,L
LD BC,#6
CPIR
JR NZ,#ChkType
LD BC,#SizeSbr
JR DO
ChkType:
LD HL,#TypeL
LD D,H
LD E,L
LD BC,#7; 19
CPIR
JR NZ,ChkPoint
DoType:
LD BC,#TypeSbr
JR DO
ChkPoint:
XOR A,A
DoPresn:
DoStar:
RET
; service subroutines for PRINTF
I2D:: LD C,#0
LD DE,#10000
CALL CNT
LD DE,#1000
CALL CNT
LD DE,#100
CALL CNT
LD DE,#10
CALL CNT
LD A,L
CALL OUTNUM
RET
CNT: XOR A,A
CNTL: OR A,A
SBC HL,DE
JR C,CNT1
INC A
JR CNTL
CNT1: ADD HL,DE
CALL OUTNUM
RET
;-----------------------
GETWORD::
GETPTR::
EXX
LD E,(HL)
INC HL
LD D,(HL)
INC HL
PUSH DE
EXX
POP DE
RET
;-----------------------
GETBYTE::
EXX
LD A,(HL)
INC HL
EXX
RET
OUTSTR::
LD A,(HL)
OR A
RET Z
CALL OUTCHR
INC HL
JR OUTSTR
OUTCHR::
exx
bit 7,c ; charcounter > 127 ?
jr nz,OCHe
OUTCH: ld (de),a
inc de
inc c
OCHe: exx
ret
OUTNUM::
PUSH HL
LD HL,#zero
OR A
JR Z,oNM1
SET 0,(HL)
JR oNM2
oNM1: BIT 0,(HL)
JR Z,oNMe
JR oNMo
oNM2: CP #0x0A
JR C,oNMo ; not HEX
BIT 2,(HL)
JR Z,oNM3 ; upper case HEX
ADD A,#32 ; lower case HEX
oNM3: ADD A,#7
oNMo: ADD A,#"0"
CALL OUTCHR
oNMe: POP HL
RET
RESET:: LD HL,#sizes
LD DE,#sizes+#1
LD BC,#12
LDIR
EX DE,HL
LD (HL),#6
RET
; обработка флагов
FlagSbr:
.dw doDefice
.dw doSign
.dw doSpc
.dw doOkto
.dw doZero
doDefice:
LD A,#TheFlag
LD (defice),A
POP HL
RET
doSign:
LD A,#1
LD (sign),A
LD A,#TheFlag
POP HL
RET
doSpc:
LD A,#TheFlag
LD (#space),A
POP HL
RET
doOkto:
LD A,#TheFlag
LD (#alter),A
POP HL
RET
doZero:
LD A,#TheFlag
LD (zero),A
POP HL
RET
SizeSbr:
.dw do_l
.dw do_h
.dw do_j
.dw do_z
.dw do_t
.dw do_L
do_l:
POP HL
INC HL
CP (HL)
JR NZ,do_l1
LD A,(sizes)
SET sz_ll,A
JR do_h1e
do_l1: DEC HL
LD A,(sizes)
SET sz_l,A
JR do_h1e
do_h:
POP HL
INC HL
CP (HL)
JR NZ,do_h1
LD A,(sizes)
SET sz_hh,A
JR do_h1e
do_h1: DEC HL
LD A,(sizes)
SET sz_h,A
do_h1e: LD (sizes),A
LD A,#TheSize
POP HL
RET
do_j:
LD A,(sizes)
SET sz_j,A
POP HL
JR do_h1e
do_z:
LD A,(sizes)
SET sz_z,A
JR do_h1e
do_t:
LD A,(sizes)
SET sz_t,A
JR do_h1e
do_L:
LD A,(sizes)
SET sz_L,A
JR do_h1e
TypeSbr:
.dw do_d
.dw do_d
.dw do_u
.dw do_x
.dw do_X
.dw do_c
.dw do_s
do_d:: CALL GETWORD
EX DE,HL
BIT 7,H
JR Z,do_dpl
LD DE,#0
EX DE,HL
OR A,A
SBC HL,DE
LD A,#'-'
CALL OUTCHR
JR do_d1
do_dpl:
LD A,(sign)
OR A,A
JR Z,do_d1
LD A,#'+'
CALL OUTCHR
do_d1: LD A,(zero)
LD B,A
CALL I2D
LD A,#TheType
POP HL
RET
do_u:: CALL GETWORD
EX DE,HL
JR do_d1
do_x:: LD A,(zero)
SET 2,A
LD (zero),A
do_X:: LD A,#0x30
CALL OUTCHR
LD A,#'x'
CALL OUTCHR
CALL GETWORD
LD A,(sizes)
BIT sz_l,A
JR Z,do_X1
EX DE,HL
CALL GETWORD
EX DE,HL
LD A,#7
LD B,A
LD (do_XB+1),A
JR do_XL1
do_X1: BIT sz_hh,A
JR Z,do_X2
LD A,#1
LD B,A
LD (do_XB+1),A
JR do_XL1
do_X2: LD A,#3
LD B,A
LD (do_XB+#1),A
do_XL1: LD C,#4
PUSH DE
do_XL2: SRL H
RR L
RR D
RR E
DEC C
JR NZ,do_XL2
DJNZ do_XL1
LD A,E
do_XAND: AND A,#15
CALL OUTNUM
do_XB: LD B,#15
do_XL3: POP DE
LD A,E
AND #15
CALL OUTNUM
DJNZ do_XL3
do_xe: LD A,#TheType
POP HL
RET
do_c:
CALL GETWORD
LD A,E
do_ce: CALL OUTCHR
JR do_xe
do_s: CALL GETPTR
EX DE,HL
JR do_ce
sizes: .db 0
large: .db 0
field: .db 0
size: .db 0
type: .db 0
defice: .db 0
sign: .db 0
plus: .db 0
space: .db 0
alter: .db 0
zero: .db 0
before: .db 0
after: .db 0
presi: .db 0 ; default 6.
chcount: .dw 0
FlagL: .ascii '-+ #0'
NumL: .ascii '0123456789'
TypeL: .ascii 'diuxXcs'
SztpL: .ascii "lhjztL"
buffer:
.ascii "0123456789012345678901234567890123456789012345678901234567890000"
.ascii "01234567890123456789012345678901234567890123456789012345678900001"
__endasm;
}