ReC98/libs/BorlandC/vprinter.asm

773 lines
12 KiB
NASM

Ssize = 50h
; enum flagBits
altFormatBit = 1
leftJustBit = 2
notZeroBit = 4
fillZerosBit = 8
isLongBit = 10h
farPtrBit = 20h
alt0xBit = 40h
floatBit = 80h
LongDoubleBit = 100h
; enum syntaxStages
flagStage = 0
fillzStage = 1
wideStage = 2
dotStage = 3
precStage = 4
ellStage = 5
typeStage = 6
Hex4 proc near
mov al, dh
call Byte2Ascii
mov al, dl
Byte2Ascii:
; Hack (aam 10h)
; AAM trick to separate nibbles in AL. TASM can actually
; assemble "aam 10h" correctly, but MASM/JWasm can't.
db 0d4h,10h
xchg ah, al
call Nibble2Ascii
xchg ah, al
Nibble2Ascii:
add al, 90h
daa
adc al, 40h
daa
stosb
ret
Hex4 endp
; int __pascal __near _vprinter(void * near *putter, void *outP, const char *formP, void *argP)
public __vprinter
__vprinter proc near
@@S = byte ptr -(16h + __CVTMAX__ + Ssize)
@@tempStr = byte ptr -(16h + __CVTMAX__)
@@eof_error = word ptr -16h
@@Scount = word ptr -14h
@@totalSent = word ptr -12h
@@abandonP = word ptr -10h
@@leadZ = word ptr -0Eh
@@plusSign = byte ptr -0Bh
@@precision = word ptr -0Ah
@@width = word ptr -8
@@isSigned = byte ptr -6
@@fc = byte ptr -5
@@aP = word ptr -4
@@flagSet = word ptr -2
@@argP = word ptr 4
@@formP = DPTR_ 6
@@outP = DPTR_ (6 + dPtrSize)
@@putter = word ptr (6 + dPtrSize + dPtrSize)
push bp
mov bp, sp
sub sp, (16h + __CVTMAX__ + Ssize)
push si
push di
mov [bp+@@totalSent], 0
mov [bp+@@Scount], Ssize
mov [bp+@@eof_error], 0
jmp short func_start
vpr_strlen:
push di
mov cx, -1
xor al, al
repne scasb
not cx
dec cx
pop di
retn
vpr_PutToS:
mov ss:[di], al
inc di
dec byte ptr [bp+@@Scount]
jnz short exit_PutToS
vpr_CallPutter:
push bx
push cx
push dx
push es
lea ax, [bp+@@S]
sub di, ax
push ss
lea ax, [bp+@@S]
push ax
push di
if LDATA
push word ptr [bp+@@outP+2]
endif
push word ptr [bp+@@outP]
call [bp+@@putter]
or ax, ax
jnz short vpr_CallPutter_end
mov [bp+@@eof_error], 1
vpr_CallPutter_end:
mov [bp+@@Scount], Ssize
add [bp+@@totalSent], di
lea di, [bp+@@S]
pop es
pop dx
pop cx
pop bx
exit_PutToS:
retn
func_start:
push es
cld
lea di, [bp+@@S]
mov [bp+@@aP], di
vpr_NEXTap:
mov di, [bp+@@aP]
vpr_NEXT:
les si, [bp+@@formP]
vpr_nextCh:
lods byte ptr ES_[si]
or al, al
jz short vpr_respondJmp
cmp al, '%'
jz short vpr_CONV
vpr_literal:
mov ss:[di], al
inc di
dec byte ptr [bp+@@Scount]
jg short vpr_nextCh
call vpr_CallPutter
jmp short vpr_nextCh
vpr_respondJmp:
jmp vpr_respond
vpr_CONV:
mov [bp+@@abandonP], si
lods byte ptr ES_[si]
cmp al, '%'
jz short vpr_literal
mov [bp+@@aP], di
xor cx, cx
mov [bp+@@leadZ], cx
if LDATA
mov [bp+@@flagSet], farPtrBit
else
mov [bp+@@flagSet], cx
endif
mov [bp+@@plusSign], cl
mov [bp+@@width], -1
mov [bp+@@precision], -1
jmp short vpr_doSwitch
vpr_nextSwitch:
lods byte ptr ES_[si]
vpr_doSwitch:
xor ah, ah
mov dx, ax
mov bx, ax
sub bl, ' '
cmp bl, 128 - ' '
jnb short vpr_jmpAbandon
mov bl, printCtype[bx]
cmp bx, 17h
jbe short vpr_switch
jmp vpr_abandon
vpr_switch:
add bx, bx
jmp cs:vpr_table[bx]
vpr_jmpAbandon:
jmp vpr_abandon
vpr_case_af:
cmp ch, 0
ja short vpr_jmpAbandon
or [bp+@@flagSet], altFormatBit
jmp short vpr_nextSwitch
vpr_case_lj:
cmp ch, 0
ja short vpr_jmpAbandon
or [bp+@@flagSet], leftJustBit
jmp short vpr_nextSwitch
vpr_case_si:
cmp ch, 0
ja short vpr_jmpAbandon
cmp [bp+@@plusSign], '+'
jz short gtvp_nxt_swit
mov [bp+@@plusSign], dl
gtvp_nxt_swit:
jmp short vpr_nextSwitch
vpr_case_ne:
and [bp+@@flagSet], not farPtrBit
jmp short ell_stagetail
vpr_case_fa:
or [bp+@@flagSet], farPtrBit
ell_stagetail:
mov ch, ellStage
jmp short vpr_nextSwitch
vpr_case_fz:
cmp ch, flagStage
ja short vpr_case_nu
test [bp+@@flagSet], leftJustBit
jnz short vpr_nextSwitchJmp
or [bp+@@flagSet], fillZerosBit
mov ch, fillzStage
jmp short vpr_nextSwitch
vpr_abandonJmp:
jmp vpr_abandon
vpr_case_ar:
mov di, [bp+@@argP]
mov ax, ss:[di]
add [bp+@@argP], 2
cmp ch, wideStage
jnb short vpr_argPrec
or ax, ax
jns short vpr_pos
neg ax
or [bp+@@flagSet], leftJustBit
vpr_pos:
mov [bp+@@width], ax
mov ch, wideStage + 1
vpr_nextSwitchJmp:
jmp vpr_nextSwitch
vpr_argPrec:
cmp ch, precStage
jnz short vpr_abandonJmp
mov [bp+@@precision], ax
inc ch
jmp vpr_nextSwitch
vpr_case_pr:
cmp ch, precStage
jnb short vpr_abandonJmp
mov ch, precStage
inc [bp+@@precision]
jmp vpr_nextSwitch
vpr_case_nu:
xchg ax, dx
sub al, '0'
cbw
cmp ch, wideStage
ja short vpr_precNumeral
mov ch, wideStage
xchg ax, [bp+@@width]
or ax, ax
jl short vpr_nextSwitchJmp
shl ax, 1
mov dx, ax
shl ax, 1
shl ax, 1
add ax, dx
add [bp+@@width], ax
jmp vpr_nextSwitch
vpr_precNumeral:
cmp ch, precStage
jnz short vpr_abandonJmp
xchg ax, [bp+@@precision]
or ax, ax
jz short vpr_nextSwitchJmp
shl ax, 1
mov dx, ax
shl ax, 1
shl ax, 1
add ax, dx
add [bp+@@precision], ax
jmp vpr_nextSwitch
vpr_case_lo:
or [bp+@@flagSet], isLongBit
jmp ell_stagetail
vpr_case_ld:
or [bp+@@flagSet], LongDoubleBit
vpr_case_sh:
and [bp+@@flagSet], not isLongBit
jmp ell_stagetail
vpr_case_oc:
mov bh, 8
jmp short vpr_NoSign
vpr_case_un:
mov bh, 10
jmp short vpr_NoSign
vpr_case_he:
mov bh, 10h
mov bl, 'A' - 'X'
add bl, dl
vpr_NoSign:
mov [bp+@@plusSign], 0
mov [bp+@@fc], dl
xor dx, dx
mov [bp+@@isSigned], dl
mov di, [bp+@@argP]
mov ax, ss:[di]
jmp short vpr_toAscii
vpr_case_de:
mov bh, 10
mov [bp+@@isSigned], 1
mov [bp+@@fc], dl
mov di, [bp+@@argP]
mov ax, ss:[di]
cwd
vpr_toAscii:
inc di
inc di
mov word ptr [bp+@@formP], si
test [bp+@@flagSet], isLongBit
jz short vpr_shortInt
mov dx, ss:[di]
inc di
inc di
vpr_shortInt:
mov [bp+@@argP], di
lea di, [bp+@@tempStr+1]
or ax, ax
jnz short vpr_flag_nz
or dx, dx
jnz short vpr_flag_nz
cmp [bp+@@precision], 0
jnz short vpr_flag_zr
mov byte ptr ss:[di], 0
mov ax, di
jmp short vpr_converted
vpr_flag_nz:
or [bp+@@flagSet], notZeroBit
vpr_flag_zr:
push dx
push ax
push ss
push di
mov al, bh
cbw
push ax
mov al, [bp+@@isSigned]
push ax
push bx
call __LONGTOA
vpr_converted:
push ss
pop es
mov dx, [bp+@@precision]
or dx, dx
jge short vpr_countActualJmp
jmp vpr_testFillZeros
vpr_countActualJmp:
jmp vpr_countActual
vpr_case_at:
mov [bp+@@fc], dl
mov word ptr [bp+@@formP], si
lea di, [bp+@@tempStr]
mov bx, [bp+@@argP]
push word ptr ss:[bx]
inc bx
inc bx
mov [bp+@@argP], bx
test [bp+@@flagSet], farPtrBit
jz short vpr_ptrLSW
mov dx, ss:[bx]
inc bx
inc bx
mov [bp+@@argP], bx
push ss
pop es
call Hex4
mov al, ':'
stosb
vpr_ptrLSW:
push ss
pop es
pop dx
call Hex4
mov byte ptr ss:[di], 0
mov [bp+@@isSigned], 0
and [bp+@@flagSet], not notZeroBit
lea cx, [bp+@@tempStr]
sub di, cx
xchg cx, di
mov dx, [bp+@@precision]
cmp dx, cx
jg short vpr_ptrEnd
mov dx, cx
vpr_ptrEnd:
jmp vpr_testFillZeros
vpr_case_ch:
mov word ptr [bp+@@formP], si
mov [bp+@@fc], dl
mov di, [bp+@@argP]
mov ax, ss:[di]
add [bp+@@argP], 2
push ss
pop es
lea di, [bp+@@tempStr+1]
xor ah, ah
mov ss:[di], ax
mov cx, 1
jmp vpr_CopyLen
vpr_case_st:
mov word ptr [bp+@@formP], si
mov [bp+@@fc], dl
mov di, [bp+@@argP]
test [bp+@@flagSet], 20h
jnz short vpr_farString
mov di, ss:[di]
add [bp+@@argP], 2
push ds
pop es
assume es:DGROUP
or di, di
jmp short vpr_countString
vpr_farString:
les di, ss:[di]
assume es:nothing
add [bp+@@argP], 4
mov ax, es
or ax, di
vpr_countString:
jnz short NotaNullPtr
push ds
pop es
assume es:DGROUP
mov di, offset NullString
NotaNullPtr:
call vpr_strlen
cmp cx, [bp+@@precision]
jbe short vpr_CopyLenJmp
mov cx, [bp+@@precision]
vpr_CopyLenJmp:
jmp vpr_CopyLen
vpr_case_fl:
mov word ptr [bp+@@formP], si
mov [bp+@@fc], dl
mov di, [bp+@@argP]
mov cx, [bp+@@precision]
or cx, cx
jge short vpr_cvtReal
mov cx, 6
vpr_cvtReal:
pushSS_
push di
push cx
pushSS_
lea bx, [bp+@@tempStr+1]
push bx
push dx
mov ax, 1
and ax, [bp+@@flagSet]
push ax
mov ax, [bp+@@flagSet]
test ax, LongDoubleBit
jz short its_plain_double
mov ax, F_10byteFloat
add [bp+@@argP], 10
jmp short push_argtype
its_plain_double:
add [bp+@@argP], 8
mov ax, F_8ByteFloat
push_argtype:
push ax
call __realcvt
push ss
pop es
assume es:nothing
lea di, [bp+@@tempStr+1]
vpr_testFillZeros:
test [bp+@@flagSet], fillZerosBit
jz short vpr_NUMERIC
mov dx, [bp+@@width]
or dx, dx
jle short vpr_NUMERIC
vpr_countActual:
call vpr_strlen
cmp byte ptr es:[di], '-'
jnz short vpr_noSignAdjust
dec cx
vpr_noSignAdjust:
sub dx, cx
jle short vpr_NUMERIC
mov [bp+@@leadZ], dx
vpr_NUMERIC:
cmp byte ptr es:[di], '-'
jz short vpr_AdjustLeadZ
mov al, [bp+@@plusSign]
or al, al
jz short vpr_COPY
dec di
mov es:[di], al
vpr_AdjustLeadZ:
cmp [bp+@@leadZ], 0
jle short vpr_COPY
mov cx, [bp+@@precision]
or cx, cx
jge short vpr_COPY
dec [bp+@@leadZ]
vpr_COPY:
call vpr_strlen
vpr_CopyLen:
mov si, di
mov di, [bp+@@aP]
mov bx, [bp+@@width]
mov ax, notZeroBit + altFormatBit
and ax, [bp+@@flagSet]
cmp ax, notZeroBit + altFormatBit
jnz short goto_doLead
mov ah, [bp+@@fc]
cmp ah, 'o'
jnz short vpr_maybeAltHex
cmp [bp+@@leadZ], 0
jg short goto_doLead
mov [bp+@@leadZ], 1
goto_doLead:
jmp short vpr_doLead
vpr_maybeAltHex:
cmp ah, 'x'
jz short vpr_isAltHex
cmp ah, 'X'
jnz short vpr_doLead
vpr_isAltHex:
or [bp+@@flagSet], alt0xBit
dec bx
dec bx
sub [bp+@@leadZ], 2
jge short vpr_doLead
mov [bp+@@leadZ], 0
vpr_doLead:
add cx, [bp+@@leadZ]
test [bp+@@flagSet], leftJustBit
jnz short vpr_check0x
jmp short vpr_nextJust
vpr_justLoop:
mov al, ' '
call vpr_PutToS
dec bx
vpr_nextJust:
cmp bx, cx
jg short vpr_justLoop
vpr_check0x:
test [bp+@@flagSet], alt0xBit
jz short vpr_checkLeadZ
mov al, '0'
call vpr_PutToS
mov al, [bp+@@fc]
call vpr_PutToS
vpr_checkLeadZ:
mov dx, [bp+@@leadZ]
or dx, dx
jle short vpr_actualCopy
sub cx, dx
sub bx, dx
mov al, es:[si]
cmp al, '-'
jz short vpr_leadSign
cmp al, ' '
jz short vpr_leadSign
cmp al, '+'
jnz short vpr_signedLead
vpr_leadSign:
lods byte ptr es:[si]
call vpr_PutToS
dec cx
dec bx
vpr_signedLead:
xchg cx, dx
jcxz short vpr_leadDone
vpr_leadZero:
mov al, '0'
call vpr_PutToS
loop vpr_leadZero
vpr_leadDone:
xchg cx, dx
vpr_actualCopy:
jcxz short vpr_copied
sub bx, cx
vpr_copyLoop:
lods byte ptr es:[si]
mov ss:[di], al
inc di
dec byte ptr [bp+@@Scount]
jg short vpr_loopTest
call vpr_CallPutter
vpr_loopTest:
loop vpr_copyLoop
vpr_copied:
or bx, bx
jle short vpr_done
mov cx, bx
vpr_rightLoop:
mov al, ' '
call vpr_PutToS
loop vpr_rightLoop
vpr_done:
jmp vpr_NEXT
vpr_case_ns:
mov word ptr [bp+@@formP], si
mov di, [bp+@@argP]
test [bp+@@flagSet], farPtrBit
jnz short vpr_farCount
ifdef __HUGE__
jmp vpr_abandonJmp
else
mov di, ss:[di]
add [bp+@@argP], 2
push ds
pop es
jmp short vpr_makeCount
endif
vpr_farCount:
les di, ss:[di]
assume es:nothing
add [bp+@@argP], 4
vpr_makeCount:
mov ax, Ssize
sub al, byte ptr [bp+@@Scount]
add ax, [bp+@@totalSent]
mov es:[di], ax
test [bp+@@flagSet], isLongBit
jz short vpr_shortN
inc di
inc di
mov word ptr es:[di], 0
vpr_shortN:
jmp vpr_NEXTap
vpr_abandon:
mov si, [bp+@@abandonP]
if LDATA
endif
mov es, word ptr [bp+@@formP+2]
mov di, [bp+@@aP]
mov al, '%'
vpr_abandLoop:
call vpr_PutToS
lods byte ptr es:[si]
or al, al
jnz short vpr_abandLoop
vpr_respond:
cmp byte ptr [bp+@@Scount], Ssize
jge short vpr_end
call vpr_CallPutter
vpr_end:
pop es
cmp [bp+@@eof_error], 0
jz short vpr_ret_totalSent
mov ax, EOF
jmp short vpr_ret
vpr_ret_totalSent:
mov ax, [bp+@@totalSent]
vpr_ret:
pop di
pop si
mov sp, bp
pop bp
ret 0Ch
__vprinter endp
vpr_table dw offset vpr_case_si
dw offset vpr_case_af
dw offset vpr_case_ar
dw offset vpr_case_lj
dw offset vpr_case_pr
dw offset vpr_case_nu
dw offset vpr_case_lo
dw offset vpr_case_ld
dw offset vpr_case_sh
dw offset vpr_case_fz
dw offset vpr_case_de
dw offset vpr_case_oc
dw offset vpr_case_un
dw offset vpr_case_he
dw offset vpr_case_at
dw offset vpr_case_fl
dw offset vpr_case_ch
dw offset vpr_case_st
dw offset vpr_case_ns
dw offset vpr_abandon
dw offset vpr_abandon
dw offset vpr_abandon
dw offset vpr_case_ne
dw offset vpr_case_fa