mirror of
https://github.com/hsoft/collapseos.git
synced 2025-04-11 11:38:15 +10:00
I fixed the errors for numbers >0x1999, sadly it is now 6 bytes bigger, so 5 bytes larger than the original, but the speed increases should still hold.
80 lines
1.7 KiB
NASM
80 lines
1.7 KiB
NASM
; *** Requirements ***
|
|
; None
|
|
;
|
|
; *** Code ***
|
|
|
|
; Parse the decimal char at A and extract it's 0-9 numerical value. Put the
|
|
; result in A.
|
|
;
|
|
; On success, the carry flag is reset. On error, it is set.
|
|
; Also, zero flag set if '0'
|
|
; parseDecimalDigit has been replaced with the following code inline:
|
|
; add a, 0xc6 ; Maps '0'-'9' onto 0xf6-0xff
|
|
; sub 0xf6 ; Anything but 0xf6-0xff carries
|
|
; Maps 0xf6-0xff onto 0-9
|
|
|
|
; Parse string at (HL) as a decimal value and return value in IX under the
|
|
; same conditions as parseLiteral.
|
|
; Sets Z on success, unset on error.
|
|
|
|
; 61 bytes
|
|
; 107 cycles overhead + up to 73 cycles if length >= 5
|
|
; 136 cycles in loop
|
|
; first digit is skipped in overhead
|
|
parseDecimal:
|
|
push hl
|
|
|
|
ld a, (hl)
|
|
add a, 0xc6 ; converts '0'-'9' to 0-9
|
|
sub 0xf6 ; carries if out of range
|
|
exx ; preserve bc, hl, de
|
|
ld h, 0
|
|
ld l, a ; load first digit in without multiplying
|
|
ld b, 4 ; Carries can only occur for decimals >=5 in length
|
|
jr c, .error
|
|
|
|
.loop:
|
|
exx
|
|
inc hl
|
|
ld a, (hl)
|
|
exx
|
|
|
|
add a, 0xc6 ; converts '0'-'9' to 0-9
|
|
sub 0xf6 ; carries if out of range
|
|
jr c, .error
|
|
|
|
add hl, hl ; x2
|
|
ld d, h
|
|
ld e, l ; de is x2
|
|
add hl, hl ; x4
|
|
add hl, hl ; x8
|
|
add hl, de ; x10
|
|
ld d, 0
|
|
ld e, a
|
|
add hl, de
|
|
jr c, .error ; if hl was 0x1999, it may carry here
|
|
djnz .loop
|
|
|
|
|
|
inc b ; so loop only executes once more
|
|
; only numbers >0x1999 can carry when multiplied by 10.
|
|
ld de, 0xE666
|
|
ex de, hl
|
|
add hl, de
|
|
ex de, hl
|
|
jr nc, .loop ; if it doesn't carry, it's small enough
|
|
|
|
exx
|
|
inc hl
|
|
ld a, (hl)
|
|
exx
|
|
add a, 0xd0
|
|
.error:
|
|
sub 0xd0 ; if a is null, set Z
|
|
; a is checked for null before any errors
|
|
.end:
|
|
push hl \ pop ix
|
|
exx ; restore original de and bc
|
|
pop hl
|
|
ret
|