VZEditor/SRC/sprintf.inc
2025-03-31 14:42:09 +09:00

293 lines
4.0 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;------------------------------------------------
; sprintf.inc
;
; Copyright (c) 1991 by c.mos
;------------------------------------------------
;----- Equations -----
PF_LEFT equ 000001b
PF_ZERO equ 000010b
PF_LONG equ 000100b
PF_MINUS equ 001000b
PF_TRIPLE equ 010000b
;----- Local work -----
_printwk struc
pmode db ?
db ?
pnum db ?
knjh db ?
_printwk ends
;------------------------------------------------
; sprintf
;------------------------------------------------
;-->
; DS:SI :format string ptr
;*ES:DI :output buffer ptr
; SS:BX :parameter top ptr
; $ld_strseg :load %s str seg to DS
; usage :" %[-][0][n][,][l]{d|u|x|c|s} "
$sprintf proc
pushm <bx,cx,dx,si,bp,ds,es>
sub sp,type _printwk
mov bp,sp
skip1 al
prnt1:
stosb
prnt2: lodsb
tst al
jz prnt8
cmp al,'%'
jne prnt1
lodsb
cmp al,'%'
je prnt1
call prnt_form
jmp prnt2
prnt8:
stosb
add sp,type _printwk
popm <es,ds,bp,si,dx,cx,bx>
ret
$sprintf endp
;----- Analyze format -----
prnt_form proc
clr ah
cmp al,'-'
_if e
or ah,PF_LEFT
lodsb
_endif
cmp al,'0'
_if e
or ah,PF_ZERO
lodsb
_endif
mov [bp].pmode,ah
call scandeci
mov [bp].pnum,dl
cmp al,','
_if e
or [bp].pmode,PF_TRIPLE
lodsb
_endif
cmp al,'l'
_if e
or [bp].pmode,PF_LONG
lodsb
_endif
mov dl,al
mov ax,ss:[bx]
inc bx
inc bx
cmp dl,'d'
je prnt_deci
cmp dl,'u'
je prnt_unsigned
cmp dl,'x'
je prnt_hexa
cmp dl,'s'
je prnt_str
cmp dl,'c'
je prnt_chr
ret
;----- %c : character -----
prnt_chr:
tst ax
_ifn z
tst ah
_if z
stosb
_else
xchg al,ah
stosw
_endif
_endif
ret
;----- %s : string -----
prnt_str:
pushm <si,ds>
$ld_strseg
mov si,ax
tst si
jz pstr8
clr ah
clr cl
mov ch,[bp].pnum
_repeat
lodsb
tst al
jz pstr1
stosb
inc cl
tst ch
_cont z
cmp cl,ch
_while b
jmps pstr8
pstr1:
test [bp].pmode,PF_LEFT
jz pstr8
sub cl,ch
jnc pstr8
neg cl
clr ch
mov al,SPC
rep stosb
pstr8: popm <ds,si>
ret
;----- %x,%u,%d : number -----
;(special thanks to Oh!No! & moritan)
prnt_deci:
movhl cx,TRUE,10
cwd
jmps pnum1
prnt_hexa:
mov cl,16
skip2 dx
prnt_unsigned:
mov cl,10
mov ch,FALSE
clr dx
pnum1:
test [bp].pmode,PF_LONG
_ifn z
mov dx,ss:[bx]
inc bx
inc bx
_endif
tst ch
_ifn z
clr ch
tst dx
_if s
neg ax
adc dx,0
neg dx
or [bp].pmode,PF_MINUS
_endif
_endif
pushm <bx,si>
mov bx,cx
clr cx
_repeat
inc cx
test cl,3
_if z
test [bp].pmode,PF_TRIPLE
_ifn z
mov si,','
push si
inc cx
_endif
_endif
push ax
mov ax,dx
clr dx
div bx
mov si,ax
pop ax
div bx
xchg ax,dx
cmp al,10 ;
sbb al,69h ; Tricky !
das ;
push ax
mov ax,dx
mov dx,si
or si,ax
_until z
test [bp].pmode,PF_MINUS
_ifn z
mov al,'-'
push ax
inc cx
_endif
sub [bp].pnum,cl
_if b
mov [bp].pnum,0
_endif
test [bp].pmode,PF_LEFT
_if z
call prnt_fill
_endif
_repeat
pop ax
stosb
dec cx
_until z
test [bp].pmode,PF_LEFT
_ifn z
call prnt_fill
_endif
popm <si,bx>
ret
;----- Fill space or '0' -----
prnt_fill proc
push cx
mov cl,[bp].pnum
clr ch
tst cx
_if g
mov al,' '
test [bp].pmode, PF_ZERO
_ifn z
mov al,'0'
_endif
rep stosb
_endif
pop cx
ret
prnt_fill endp
prnt_form endp
;------------------------------------------------
; Scan decimal
;------------------------------------------------
;-->
; SI :pointer
; AL :1st char
;<--
; DX :number
; AL :next char
public scandeci
scandeci proc
clr dx
_repeat
cmp al,'0'
_break b
cmp al,'9'
_break a
sub al,'0'
cbw
push ax
mov ax,10
mul dx
mov dx,ax
pop ax
add dx,ax
lodsb
_until
ret
scandeci endp
;------------------------------------------------
; End of sprintf.inc
;------------------------------------------------