lib/parse: remove parseHexPair

Also, make parseHexadecimal "tail" (HL). Soon, all routines in lib/parse
will do that, making the life of lib/expr easier.
This commit is contained in:
Virgil Dupras 2019-12-29 21:39:51 -05:00
parent 2503bdfced
commit dcb96aefe9
5 changed files with 55 additions and 88 deletions

View File

@ -22,42 +22,6 @@ parseHex:
ret ret
; Parses 2 characters of the string pointed to by HL and returns the numerical
; value in A. If the second character is a "special" character (<0x21) we don't
; error out: the result will be the one from the first char only.
; HL is set to point to the last char of the pair.
;
; On success, the carry flag is reset. On error, it is set.
parseHexPair:
push bc
ld a, (hl)
call parseHex
jr c, .end ; error? goto end, keeping the C flag on
rla \ rla \ rla \ rla ; let's push this in MSB
ld b, a
inc hl
ld a, (hl)
cp 0x21
jr c, .single ; special char? single digit
call parseHex
jr c, .end ; error?
or b ; join left-shifted + new. we're done!
; C flag was set on parseHex and is necessarily clear at this point
jr .end
.single:
; If we have a single digit, our result is already stored in B, but
; we have to right-shift it back.
ld a, b
and 0xf0
rra \ rra \ rra \ rra
dec hl
.end:
pop bc
ret
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the ; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
; result in A. ; result in A.
; ;
@ -142,40 +106,35 @@ parseDecimal:
; Parse string at (HL) as a hexadecimal value without the "0x" prefix and ; Parse string at (HL) as a hexadecimal value without the "0x" prefix and
; return value in DE. ; return value in DE.
; HL is advanced to the character following the last successfully read char.
; Sets Z on success. ; Sets Z on success.
parseHexadecimal: parseHexadecimal:
push hl
call strlen
cp 3
jr c, .single
cp 4
jr c, .doubleShort ; 0x123
cp 5
jr c, .double ; 0x1234
; too long, error
jr .error
.double:
call parseHexPair
jr c, .error
inc hl ; now HL is on first char of next pair
ld d, a
jr .single
.doubleShort:
ld a, (hl) ld a, (hl)
call parseHex call parseHex
jr c, .error jp c, unsetZ ; we need at least one char
inc hl ; now HL is on first char of next pair push bc
ld d, a ld de, 0
.single: ld b, 0
call parseHexPair .loop:
jr c, .error ; we push to B to verify overflow
rl e \ rl d \ rl b
rl e \ rl d \ rl b
rl e \ rl d \ rl b
rl e \ rl d \ rl b
or e
ld e, a ld e, a
cp a ; ensure Z ; did we overflow?
jr .end ld a, b
.error: or a
call unsetZ jr nz, .end ; overflow, NZ already set
; next char
inc hl
ld a, (hl)
call parseHex
jr nc, .loop
cp a ; ensure Z
.end: .end:
pop hl pop bc
ret ret
; Parse string at (HL) as a binary value (010101) without the "0b" prefix and ; Parse string at (HL) as a binary value (010101) without the "0b" prefix and
@ -271,7 +230,9 @@ parseLiteral:
ret ; Z already set ret ; Z already set
.hex: .hex:
push hl
call parseHexadecimal call parseHexadecimal
pop hl
jr .hexOrBinEnd jr .hexOrBinEnd
.bin: .bin:

View File

@ -25,30 +25,32 @@
zasmMain: zasmMain:
; Parse args in (HL) ; Parse args in (HL)
; blkdev in ; blkdev in
call parseHexPair ; --> A call parseHexadecimal ; --> DE
jr c, .badargs jr nz, .badargs
ld a, e
ld de, IO_IN_BLK ld de, IO_IN_BLK
call blkSel call blkSel
inc hl ; char following last hex char
; blkdev in ; blkdev in
call rdWS call rdWS
jr nz, .badargs jr nz, .badargs
call parseHexPair ; --> A call parseHexadecimal ; --> DE
jr c, .badargs jr nz, .badargs
ld a, e
ld de, IO_OUT_BLK ld de, IO_OUT_BLK
call blkSel call blkSel
inc hl ; char following last hex char
; .org high byte ; .org high byte
ld e, 0 ; in case we .skipOrgSet
call rdWS call rdWS
jr nz, .skipOrgSet ; no org argument jr nz, .skipOrgSet ; no org argument
call parseHexPair ; --> A call parseHexadecimal ; --> DE
jr c, .badargs jr nz, .badargs
.skipOrgSet: .skipOrgSet:
; Init .org with value of E ; Init .org with value of E
; Save in "@" too ; Save in "@" too
ld a, e
ld (ZASM_ORG+1), a ; high byte of .org ld (ZASM_ORG+1), a ; high byte of .org
ld (DIREC_LASTVAL+1), a ld (DIREC_LASTVAL+1), a
xor a xor a

View File

@ -16,7 +16,6 @@
jp upcase jp upcase
jp findchar jp findchar
jp parseHex jp parseHex
jp parseHexPair
jp blkSel jp blkSel
jp blkSet jp blkSet
jp fsFindFN jp fsFindFN
@ -145,9 +144,9 @@ basFindCmdExtra:
jp basPgmHook jp basPgmHook
.mycmds: .mycmds:
.db "ed", 0 .db "ed", 0
.dw 0x1e00 .dw 0x1f00
.db "zasm", 0 .db "zasm", 0
.dw 0x2300 .dw 0x2400
.db 0xff .db 0xff
f0GetB: f0GetB:
@ -166,13 +165,13 @@ f1PutB:
ld ix, FS_HANDLES+FS_HANDLE_SIZE ld ix, FS_HANDLES+FS_HANDLE_SIZE
jp fsPutB jp fsPutB
; last time I checked, PC at this point was 0x1df8. Let's give us a nice margin ; last time I checked, PC at this point was 0x1e92. Let's give us a nice margin
; for the start of ed. ; for the start of ed.
.fill 0x1e00-$ .fill 0x1f00-$
.bin "ed.bin" .bin "ed.bin"
; Last check: 0x22dd ; Last check: 0x23b0
.fill 0x2300-$ .fill 0x2400-$
.bin "zasm.bin" .bin "zasm.bin"
.fill 0x7ff0-$ .fill 0x7ff0-$

View File

@ -14,7 +14,6 @@
.equ upcase @+3 .equ upcase @+3
.equ findchar @+3 .equ findchar @+3
.equ parseHex @+3 .equ parseHex @+3
.equ parseHexPair @+3
.equ blkSel @+3 .equ blkSel @+3
.equ blkSet @+3 .equ blkSet @+3
.equ fsFindFN @+3 .equ fsFindFN @+3

View File

@ -13,7 +13,7 @@ test:
ld sp, 0xffff ld sp, 0xffff
call testParseHex call testParseHex
call testParseHexPair call testParseHexadecimal
; success ; success
xor a xor a
@ -40,24 +40,30 @@ testParseHex:
call nexttest call nexttest
ret ret
testParseHexPair: testParseHexadecimal:
ld hl, .s99 ld hl, .s99
call parseHexPair call parseHexadecimal
jp c, fail jp nz, fail
ld a, e
cp 0x99 cp 0x99
jp nz, fail jp nz, fail
call nexttest call nexttest
ld hl, .saB ld hl, .saB
call parseHexPair call parseHexadecimal
jp c, fail jp nz, fail
ld a, e
cp 0xab cp 0xab
jp nz, fail jp nz, fail
call nexttest call nexttest
; The string "Foo" will not cause a failure. We will parse up to "o"
; and then stop.
ld hl, .sFoo ld hl, .sFoo
call parseHexPair call parseHexadecimal
jp nc, fail jp nz, fail
ld a, e
cp 0xf
call nexttest call nexttest
ret ret