mirror of https://github.com/nmlgc/ReC98.git
761 lines
12 KiB
NASM
761 lines
12 KiB
NASM
ScanNextArgPointer macro
|
|
call scn_NextArgPtr
|
|
ifdef __HUGE__
|
|
jnc $+5
|
|
jmp scn_END
|
|
endif
|
|
endm
|
|
|
|
scn_pushSrceP macro
|
|
if LDATA
|
|
push word ptr [bp+@@srceP+2]
|
|
endif
|
|
push word ptr [bp+@@srceP]
|
|
endm
|
|
|
|
; int __cdecl scanner(int (__cdecl __near near *Get)(), void (__cdecl __near near *UnGet)(), void *srceP, const char *formP, va_list varPP)
|
|
_scanner proc near
|
|
@@bitSet = byte ptr -2Ah
|
|
@@width = word ptr -0Ah
|
|
@@status = word ptr -8
|
|
@@charCt = word ptr -6
|
|
@@count = word ptr -4
|
|
@@flags = byte ptr -1
|
|
@@Get = word ptr 4
|
|
@@UnGet = word ptr 6
|
|
@@srceP = DPTR_ (8)
|
|
@@formP = DPTR_ (8 + dPtrSize)
|
|
@@varPP = DPTR_ (8 + dPtrSize + dPtrSize)
|
|
|
|
push bp
|
|
mov bp, sp
|
|
sub sp, 2Ah
|
|
push si
|
|
push di
|
|
mov [bp+@@count], 0
|
|
mov [bp+@@charCt], 0
|
|
jmp short RealCodeStart
|
|
|
|
scn_NextArgPtr:
|
|
LES_ di, [bp+@@varPP]
|
|
test [bp+@@flags], isFarPtr
|
|
jz short scn_nextNear
|
|
les di, ES_[di]
|
|
add word ptr [bp+@@varPP], 4
|
|
ifdef __HUGE__
|
|
clc
|
|
endif
|
|
retn
|
|
|
|
scn_nextNear:
|
|
ifdef __HUGE__
|
|
stc
|
|
else
|
|
mov di, ES_[di]
|
|
push ds
|
|
pop es
|
|
assume es:dseg
|
|
add word ptr [bp+@@varPP], 2
|
|
endif
|
|
ret
|
|
|
|
RealCodeStart:
|
|
push es
|
|
cld
|
|
|
|
scn_NEXT:
|
|
mov si, word ptr [bp+@@formP]
|
|
|
|
scn_nextChar:
|
|
if LDATA
|
|
mov es, word ptr [bp+@@formP+2]
|
|
endif
|
|
assume es:nothing
|
|
lods byte ptr ES_[si]
|
|
or al, al
|
|
jz short scn_respondJmp
|
|
cmp al, '%'
|
|
jz short scn_CONV
|
|
|
|
scn_percent:
|
|
xor ah, ah
|
|
xchg ax, di
|
|
inc [bp+@@charCt]
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
or ax, ax
|
|
jl short scn_EOFjmp
|
|
xor ah, ah
|
|
test di, 80h
|
|
jnz short scn_mustMatch
|
|
cmp scanCtype[di], 1
|
|
jnz short scn_mustMatch
|
|
|
|
scn_matchSpace:
|
|
xchg ax, bx
|
|
or bl, bl
|
|
js short scn_spaceEnded
|
|
cmp scanCtype[bx], 1
|
|
jnz short scn_spaceEnded
|
|
inc [bp+@@charCt]
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
or ax, ax
|
|
jg short scn_matchSpace
|
|
|
|
scn_EOFjmp:
|
|
jmp scn_EOF
|
|
|
|
scn_spaceEnded:
|
|
scn_pushSrceP
|
|
push bx
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
dec [bp+@@charCt]
|
|
jmp short scn_nextChar
|
|
|
|
scn_mustMatch:
|
|
cmp ax, di
|
|
jz short scn_nextChar
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
dec [bp+@@charCt]
|
|
jmp scn_END
|
|
|
|
scn_respondJmp:
|
|
jmp scn_END
|
|
|
|
scn_CONV:
|
|
mov [bp+@@width], -1
|
|
if LDATA
|
|
mov es, word ptr [bp+@@formP+2]
|
|
mov [bp+@@flags], isFarPtr
|
|
else
|
|
mov [bp+@@flags], 0
|
|
endif
|
|
|
|
scn_convNext:
|
|
lods byte ptr ES_[si]
|
|
xor ah, ah
|
|
mov word ptr [bp+@@formP], si
|
|
or al, al
|
|
xchg ax, di
|
|
jl short scn_anyOther
|
|
mov bl, scanCtype[di]
|
|
xor bh, bh
|
|
cmp bx, 15h
|
|
jbe short scn_switch
|
|
jmp scn_EOF
|
|
|
|
scn_switch:
|
|
add bx, bx
|
|
jmp cs:scn_table[bx]
|
|
|
|
scn_case_pc:
|
|
xchg ax, di
|
|
jmp scn_percent
|
|
|
|
scn_anyOther:
|
|
jmp scn_END
|
|
|
|
scn_case_su:
|
|
or [bp+@@flags], isSuppressed
|
|
jmp short scn_convNext
|
|
|
|
scn_case_nu:
|
|
sub di, '0'
|
|
xchg di, [bp+@@width]
|
|
or di, di
|
|
jl short scn_convNext
|
|
mov ax, 10
|
|
mul di
|
|
add [bp+@@width], ax
|
|
jmp short scn_convNext
|
|
|
|
scn_case_ld:
|
|
or [bp+@@flags], isLongDouble
|
|
jmp short scn_convNext
|
|
|
|
scn_case_lo:
|
|
or [bp+@@flags], isLong
|
|
jmp short scn_convNext
|
|
|
|
scn_case_ha:
|
|
or [bp+@@flags], isHalf
|
|
jmp short scn_convNext
|
|
|
|
scn_case_ne:
|
|
and [bp+@@flags], not isFarPtr
|
|
jmp short scn_convNext
|
|
|
|
scn_case_fa:
|
|
or [bp+@@flags], isFarPtr
|
|
jmp short scn_convNext
|
|
|
|
scn_case_ct:
|
|
mov ax, [bp+@@charCt]
|
|
sub dx, dx
|
|
test [bp+@@flags], isSuppressed
|
|
jz short scn_PUTINT
|
|
jmp scn_NEXT
|
|
|
|
scn_case_oc:
|
|
mov si, 8
|
|
jmp short scn_INT
|
|
|
|
scn_case_un_de:
|
|
mov si, 10
|
|
jmp short scn_INT
|
|
|
|
scn_case_he:
|
|
mov si, 16
|
|
jmp short scn_INT
|
|
|
|
scn_case_in:
|
|
xor si, si
|
|
|
|
scn_INT:
|
|
test di, 20h
|
|
jnz short scn_scantol
|
|
cmp di, 'X'
|
|
jz short scn_scantol
|
|
or [bp+@@flags], isLong
|
|
|
|
scn_scantol:
|
|
pushSS_
|
|
lea ax, [bp+@@status]
|
|
push ax
|
|
pushSS_
|
|
lea ax, [bp+@@charCt]
|
|
push ax
|
|
mov ax, [bp+@@width]
|
|
and ax, 7FFFh
|
|
push ax
|
|
push si
|
|
scn_pushSrceP
|
|
push [bp+@@UnGet]
|
|
push [bp+@@Get]
|
|
call __scantol
|
|
add sp, 8 + (dPtrSize * 3)
|
|
cmp [bp+@@status], 0
|
|
jle short scn_intEnd
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_intUpdated
|
|
inc [bp+@@count]
|
|
|
|
scn_PUTINT:
|
|
ScanNextArgPointer
|
|
stosw
|
|
test [bp+@@flags], isLong
|
|
jz short scn_intUpdated
|
|
xchg ax, dx
|
|
stosw
|
|
|
|
scn_intUpdated:
|
|
jmp scn_NEXT
|
|
|
|
scn_intEnd:
|
|
jl short scn_intEOF
|
|
jmp scn_END
|
|
|
|
scn_intEOF:
|
|
jmp scn_EOF
|
|
|
|
scn_case_pt:
|
|
call $+3
|
|
jmp scn_SkipSpace
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
dec [bp+@@charCt]
|
|
and [bp+@@width], 7FFFh
|
|
call $+3
|
|
jmp scn_InHex4
|
|
push dx
|
|
cmp al, ':'
|
|
jz short scn_ptrLSW
|
|
or ax, ax
|
|
jle short scn_noLookAhead
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
dec [bp+@@charCt]
|
|
|
|
scn_noLookAhead:
|
|
pop dx
|
|
mov bx, ds
|
|
jmp short scn_pointerReady
|
|
|
|
scn_ptrLSW:
|
|
call $+3
|
|
jmp scn_InHex4
|
|
pop bx
|
|
or ax, ax
|
|
jle short scn_pointerReady
|
|
push dx
|
|
push bx
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
dec [bp+@@charCt]
|
|
pop bx
|
|
pop dx
|
|
|
|
scn_pointerReady:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_ptrUpdated
|
|
ScanNextArgPointer
|
|
inc [bp+@@count]
|
|
xchg ax, dx
|
|
stosw
|
|
test [bp+@@flags], isFarPtr
|
|
jz short scn_ptrUpdated
|
|
xchg ax, bx
|
|
stosw
|
|
|
|
scn_ptrUpdated:
|
|
jmp scn_NEXT
|
|
|
|
scn_jmpEOF:
|
|
jmp scn_EOF
|
|
|
|
scn_case_fl:
|
|
pushSS_
|
|
lea ax, [bp+@@status]
|
|
push ax
|
|
pushSS_
|
|
lea ax, [bp+@@charCt]
|
|
push ax
|
|
mov ax, 7FFFh
|
|
and ax, [bp+@@width]
|
|
push ax
|
|
scn_pushSrceP
|
|
push [bp+@@UnGet]
|
|
push [bp+@@Get]
|
|
call _scantod
|
|
add sp, (3 * dPtrSize) + 2 + (2 * 2)
|
|
cmp [bp+@@status], 0
|
|
jle short scn_endFloat
|
|
mov al, [bp+@@flags]
|
|
cbw
|
|
test al, isSuppressed
|
|
jnz short scn_popFloat
|
|
ScanNextArgPointer
|
|
inc [bp+@@count]
|
|
test [bp+@@flags], isLong
|
|
jz short test_longDOuble
|
|
mov ax, isLong
|
|
jmp short push_type
|
|
|
|
test_longDOuble:
|
|
test [bp+@@flags], isLongDouble
|
|
jz short its_default_float
|
|
mov ax, isLongDouble
|
|
jmp short push_type
|
|
|
|
its_default_float:
|
|
xor ax, ax
|
|
|
|
push_type:
|
|
push ax
|
|
test [bp+@@flags], isFarPtr
|
|
jz short push_far
|
|
push es
|
|
jmp short scn_scanrslt
|
|
|
|
push_far:
|
|
push ds
|
|
|
|
scn_scanrslt:
|
|
push di
|
|
call _scanrslt
|
|
add sp, 6
|
|
jmp scn_NEXT
|
|
|
|
scn_popFloat:
|
|
call _scanpop
|
|
jmp scn_NEXT
|
|
|
|
scn_endFloat:
|
|
call _scanpop
|
|
jl short scn_jmpEOF
|
|
jmp scn_END
|
|
|
|
scn_case_st:
|
|
call $+3
|
|
jmp scn_SkipSpace
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_tokenWidth
|
|
ScanNextArgPointer
|
|
inc [bp+@@count]
|
|
|
|
scn_tokenWidth:
|
|
and [bp+@@width], 7FFFh
|
|
jz short scn_tokenEnd
|
|
|
|
scn_whileToken:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_tokenNextCh
|
|
stosb
|
|
|
|
scn_tokenNextCh:
|
|
inc [bp+@@charCt]
|
|
push es
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
pop es
|
|
or ax, ax
|
|
jle short scn_tokenEnd
|
|
or al, al
|
|
js short scn_isToken
|
|
xchg ax, bx
|
|
cmp scanCtype[bx], 1
|
|
xchg ax, bx
|
|
jle short scn_tokenEnd
|
|
|
|
scn_isToken:
|
|
dec [bp+@@width]
|
|
jg short scn_whileToken
|
|
|
|
scn_tokenEnd:
|
|
push es
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
pop es
|
|
dec [bp+@@charCt]
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_tokenUpdated
|
|
mov al, 0
|
|
stosb
|
|
|
|
scn_tokenUpdated:
|
|
jmp scn_NEXT
|
|
|
|
scn_case_ch:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_checkWidth
|
|
ScanNextArgPointer
|
|
|
|
scn_checkWidth:
|
|
mov si, [bp+@@width]
|
|
or si, si
|
|
jge short scn_charWidened
|
|
mov si, 1
|
|
|
|
scn_charWidened:
|
|
jz short scn_charEnd
|
|
|
|
scn_charLoop:
|
|
inc [bp+@@charCt]
|
|
push es
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
pop es
|
|
or ax, ax
|
|
jl short scn_charEOF
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_charNoPut
|
|
stosb
|
|
|
|
scn_charNoPut:
|
|
dec si
|
|
jg short scn_charLoop
|
|
|
|
scn_charEnd:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_charNext
|
|
inc [bp+@@count]
|
|
|
|
scn_charNext:
|
|
jmp scn_NEXT
|
|
|
|
scn_charEOF:
|
|
jmp scn_EOF
|
|
|
|
scn_case_sc:
|
|
if LDATA
|
|
push es
|
|
endif
|
|
sub ax, ax
|
|
cld
|
|
push ss
|
|
pop es
|
|
lea di, [bp+@@bitSet]
|
|
mov cx, 16
|
|
rep stosw
|
|
if LDATA
|
|
pop es
|
|
endif
|
|
lods byte ptr ES_[si]
|
|
and [bp+@@flags], not isExclusive
|
|
cmp al, '^'
|
|
jnz short scn_scanInc
|
|
or [bp+@@flags], isExclusive
|
|
lods byte ptr ES_[si]
|
|
|
|
scn_scanInc:
|
|
mov ah, 0
|
|
|
|
scn_scanSetBit:
|
|
mov dl, al
|
|
mov di, ax
|
|
mov cl, 3
|
|
shr di, cl
|
|
mov cx, 107h
|
|
and cl, dl
|
|
shl ch, cl
|
|
or [bp+di+@@bitSet], ch
|
|
|
|
scn_setNext:
|
|
lods byte ptr ES_[si]
|
|
cmp al, 0
|
|
jz short scn_scanOpen
|
|
cmp al, ']'
|
|
jz short scn_scanBounded
|
|
cmp al, '-'
|
|
jnz short scn_scanSetBit
|
|
cmp dl, ES_[si]
|
|
ja short scn_scanSetBit
|
|
cmp byte ptr ES_[si], ']'
|
|
jz short scn_scanSetBit
|
|
lods byte ptr ES_[si]
|
|
sub al, dl
|
|
jz short scn_setNext
|
|
add dl, al
|
|
|
|
scn_setRange:
|
|
rol ch, 1
|
|
adc di, 0
|
|
or [bp+di+@@bitSet], ch
|
|
dec al
|
|
jnz short scn_setRange
|
|
jmp short scn_setNext
|
|
|
|
scn_scanOpen:
|
|
jmp scn_END
|
|
|
|
scn_scanBounded:
|
|
mov word ptr [bp+@@formP], si
|
|
and [bp+@@width], 7FFFh
|
|
mov si, [bp+@@width]
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_scanLoop
|
|
ScanNextArgPointer
|
|
|
|
scn_scanLoop:
|
|
dec si
|
|
jl short scn_scanLimited
|
|
inc [bp+@@charCt]
|
|
push es
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
pop es
|
|
or ax, ax
|
|
jl short scn_scanEOF
|
|
xchg ax, si
|
|
mov bx, si
|
|
mov cl, 3
|
|
shr si, cl
|
|
mov cx, 107h
|
|
and cl, bl
|
|
shl ch, cl
|
|
test [bp+si+@@bitSet], ch
|
|
xchg ax, si
|
|
xchg ax, bx
|
|
jz short scn_scanNotIn
|
|
test [bp+@@flags], isExclusive
|
|
jz short scn_scanAccept
|
|
jmp short scn_scanTerminate
|
|
|
|
scn_scanNotIn:
|
|
test [bp+@@flags], isExclusive
|
|
jz short scn_scanTerminate
|
|
|
|
scn_scanAccept:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_scanLoop
|
|
stosb
|
|
jmp short scn_scanLoop
|
|
|
|
scn_scanTerminate:
|
|
push es
|
|
scn_pushSrceP
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
pop es
|
|
dec [bp+@@charCt]
|
|
inc si
|
|
cmp si, [bp+@@width]
|
|
jge short scn_scanEND
|
|
|
|
scn_scanLimited:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_scanUpdated
|
|
inc [bp+@@count]
|
|
|
|
scn_scanEND:
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_scanUpdated
|
|
mov al, 0
|
|
stosb
|
|
|
|
scn_scanUpdated:
|
|
jmp scn_NEXT
|
|
|
|
scn_scanEOF:
|
|
inc si
|
|
cmp si, [bp+@@width]
|
|
jge short scn_EOF
|
|
test [bp+@@flags], isSuppressed
|
|
jnz short scn_EOF
|
|
mov al, 0
|
|
stosb
|
|
inc [bp+@@count]
|
|
|
|
scn_EOF:
|
|
scn_pushSrceP
|
|
mov ax, EOF
|
|
push ax
|
|
call [bp+@@UnGet]
|
|
add sp, 2 + dPtrSize
|
|
cmp [bp+@@count], 1
|
|
sbb [bp+@@count], 0
|
|
|
|
scn_END:
|
|
pop es
|
|
mov ax, [bp+@@count]
|
|
jmp scn_ret
|
|
|
|
scn_SkipSpace:
|
|
inc [bp+@@charCt]
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
or ax, ax
|
|
jle short scn_skipEOF
|
|
or al, al
|
|
js short scn_skipEnd
|
|
xchg ax, bx
|
|
cmp scanCtype[bx], 1
|
|
xchg ax, bx
|
|
jz short scn_SkipSpace
|
|
|
|
scn_skipEnd:
|
|
pop cx
|
|
add cx, 3
|
|
jmp cx
|
|
|
|
scn_skipEOF:
|
|
jz short scn_skipEnd
|
|
pop cx
|
|
jmp short scn_EOF
|
|
|
|
scn_InHex4:
|
|
sub dx, dx
|
|
mov cx, 4
|
|
|
|
scn_h4loop:
|
|
dec [bp+@@width]
|
|
jl short scn_h4limited
|
|
push dx
|
|
push cx
|
|
inc [bp+@@charCt]
|
|
scn_pushSrceP
|
|
call [bp+@@Get]
|
|
popCX_
|
|
pop cx
|
|
pop cx
|
|
pop dx
|
|
or ax, ax
|
|
jle short scn_h4end
|
|
dec cl
|
|
jl short scn_h4end
|
|
mov ch, al
|
|
sub ch, '0'
|
|
jb short scn_h4end
|
|
cmp ch, 10
|
|
jb short scn_h4isDigit
|
|
sub ch, 'A' - '0'
|
|
jb short scn_h4end
|
|
cmp ch, 6
|
|
jb short scn_h4isHex
|
|
sub ch, 'a' - 'A'
|
|
jb short scn_h4end
|
|
cmp ch, 6
|
|
jnb short scn_h4end
|
|
|
|
scn_h4isHex:
|
|
add ch, 10
|
|
|
|
scn_h4isDigit:
|
|
shl dx, 1
|
|
shl dx, 1
|
|
shl dx, 1
|
|
shl dx, 1
|
|
add dl, ch
|
|
jmp short scn_h4loop
|
|
|
|
scn_h4limited:
|
|
sub ax, ax
|
|
|
|
scn_h4end:
|
|
cmp cl, 4
|
|
jz short scn_h4eof
|
|
pop cx
|
|
add cx, 3
|
|
jmp cx
|
|
|
|
scn_h4eof:
|
|
pop cx
|
|
jmp scn_EOF
|
|
|
|
scn_ret:
|
|
pop di
|
|
pop si
|
|
mov sp, bp
|
|
pop bp
|
|
ret
|
|
_scanner endp
|
|
|
|
scn_table dw offset scn_END
|
|
dw offset scn_END
|
|
dw offset scn_END
|
|
dw offset scn_case_pc
|
|
dw offset scn_case_su
|
|
dw offset scn_case_nu
|
|
dw offset scn_case_ch
|
|
dw offset scn_case_un_de
|
|
dw offset scn_case_un_de
|
|
dw offset scn_case_in
|
|
dw offset scn_case_fl
|
|
dw offset scn_case_ld
|
|
dw offset scn_case_ha
|
|
dw offset scn_case_lo
|
|
dw offset scn_case_oc
|
|
dw offset scn_case_st
|
|
dw offset scn_case_sc
|
|
dw offset scn_case_ct
|
|
dw offset scn_case_he
|
|
dw offset scn_case_pt
|
|
dw offset scn_case_ne
|
|
dw offset scn_case_fa
|