Browse Source

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.
pull/85/head
Virgil Dupras 4 years ago
parent
commit
dcb96aefe9
5 changed files with 55 additions and 88 deletions
  1. +25
    -64
      apps/lib/parse.asm
  2. +10
    -8
      apps/zasm/main.asm
  3. +6
    -7
      recipes/sms/romasm/glue.asm
  4. +0
    -1
      recipes/sms/romasm/user.h
  5. +14
    -8
      tools/tests/unit/test_lib_parse.asm

+ 25
- 64
apps/lib/parse.asm View File

@@ -22,42 +22,6 @@ parseHex:
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
; result in A.
;
@@ -142,40 +106,35 @@ parseDecimal:

; Parse string at (HL) as a hexadecimal value without the "0x" prefix and
; return value in DE.
; HL is advanced to the character following the last successfully read char.
; Sets Z on success.
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)
call parseHex
jr c, .error
inc hl ; now HL is on first char of next pair
ld d, a
.single:
call parseHexPair
jr c, .error
jp c, unsetZ ; we need at least one char
push bc
ld de, 0
ld b, 0
.loop:
; 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
cp a ; ensure Z
jr .end
.error:
call unsetZ
; did we overflow?
ld a, b
or a
jr nz, .end ; overflow, NZ already set
; next char
inc hl
ld a, (hl)
call parseHex
jr nc, .loop
cp a ; ensure Z
.end:
pop hl
pop bc
ret

; Parse string at (HL) as a binary value (010101) without the "0b" prefix and
@@ -271,7 +230,9 @@ parseLiteral:
ret ; Z already set

.hex:
push hl
call parseHexadecimal
pop hl
jr .hexOrBinEnd

.bin:


+ 10
- 8
apps/zasm/main.asm View File

@@ -25,30 +25,32 @@
zasmMain:
; Parse args in (HL)
; blkdev in
call parseHexPair ; --> A
jr c, .badargs
call parseHexadecimal ; --> DE
jr nz, .badargs
ld a, e
ld de, IO_IN_BLK
call blkSel
inc hl ; char following last hex char

; blkdev in
call rdWS
jr nz, .badargs
call parseHexPair ; --> A
jr c, .badargs
call parseHexadecimal ; --> DE
jr nz, .badargs
ld a, e
ld de, IO_OUT_BLK
call blkSel
inc hl ; char following last hex char

; .org high byte
ld e, 0 ; in case we .skipOrgSet
call rdWS
jr nz, .skipOrgSet ; no org argument
call parseHexPair ; --> A
jr c, .badargs
call parseHexadecimal ; --> DE
jr nz, .badargs

.skipOrgSet:
; Init .org with value of E
; Save in "@" too
ld a, e
ld (ZASM_ORG+1), a ; high byte of .org
ld (DIREC_LASTVAL+1), a
xor a


+ 6
- 7
recipes/sms/romasm/glue.asm View File

@@ -16,7 +16,6 @@
jp upcase
jp findchar
jp parseHex
jp parseHexPair
jp blkSel
jp blkSet
jp fsFindFN
@@ -145,9 +144,9 @@ basFindCmdExtra:
jp basPgmHook
.mycmds:
.db "ed", 0
.dw 0x1e00
.dw 0x1f00
.db "zasm", 0
.dw 0x2300
.dw 0x2400
.db 0xff

f0GetB:
@@ -166,13 +165,13 @@ f1PutB:
ld ix, FS_HANDLES+FS_HANDLE_SIZE
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.
.fill 0x1e00-$
.fill 0x1f00-$
.bin "ed.bin"

; Last check: 0x22dd
.fill 0x2300-$
; Last check: 0x23b0
.fill 0x2400-$
.bin "zasm.bin"

.fill 0x7ff0-$


+ 0
- 1
recipes/sms/romasm/user.h View File

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


tools/tests/unit/test_parse.asm → tools/tests/unit/test_lib_parse.asm View File

@@ -13,7 +13,7 @@ test:
ld sp, 0xffff

call testParseHex
call testParseHexPair
call testParseHexadecimal

; success
xor a
@@ -40,24 +40,30 @@ testParseHex:
call nexttest
ret

testParseHexPair:
testParseHexadecimal:
ld hl, .s99
call parseHexPair
jp c, fail
call parseHexadecimal
jp nz, fail
ld a, e
cp 0x99
jp nz, fail
call nexttest

ld hl, .saB
call parseHexPair
jp c, fail
call parseHexadecimal
jp nz, fail
ld a, e
cp 0xab
jp nz, fail
call nexttest

; The string "Foo" will not cause a failure. We will parse up to "o"
; and then stop.
ld hl, .sFoo
call parseHexPair
jp nc, fail
call parseHexadecimal
jp nz, fail
ld a, e
cp 0xf
call nexttest
ret


Loading…
Cancel
Save