lib/expr: use the IX register a bit less
It's an awkward register to use and avoiding its use allows us to strip the resulting binary significantly. parseEXPR keeps the same signature though.
This commit is contained in:
parent
2f71ad6d2f
commit
501fe96e07
@ -1,6 +1,7 @@
|
|||||||
; *** Requirements ***
|
; *** Requirements ***
|
||||||
; findchar
|
; findchar
|
||||||
; multDEBC
|
; multDEBC
|
||||||
|
; callIXI
|
||||||
;
|
;
|
||||||
; *** Defines ***
|
; *** Defines ***
|
||||||
;
|
;
|
||||||
@ -14,6 +15,9 @@
|
|||||||
; **This routine mutates (HL).**
|
; **This routine mutates (HL).**
|
||||||
; We expect (HL) to be disposable: we mutate it to avoid having to make a copy.
|
; We expect (HL) to be disposable: we mutate it to avoid having to make a copy.
|
||||||
; Sets Z on success, unset on error.
|
; Sets Z on success, unset on error.
|
||||||
|
; TODO: the IX output register is a bit awkward. Nearly everywhere, I need
|
||||||
|
; to push \ pop that thing. See if we could return the result in DE
|
||||||
|
; instead.
|
||||||
parseExpr:
|
parseExpr:
|
||||||
push de
|
push de
|
||||||
push hl
|
push hl
|
||||||
@ -38,15 +42,16 @@ _parseExpr:
|
|||||||
; Operator found, string splitted. Left in (HL), right in (DE)
|
; Operator found, string splitted. Left in (HL), right in (DE)
|
||||||
call _resolveLeftAndRight
|
call _resolveLeftAndRight
|
||||||
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
|
; Whether _resolveLeftAndRight was a success, we pop our lvl 1 stack
|
||||||
; out, which contains our operator row. We pop it in HL because we
|
; out, which contains our operator row. We pop it in IX.
|
||||||
; don't need our string anymore. L-R numbers are parsed, and in DE and
|
; L-R numbers are parsed in HL (left) and DE (right).
|
||||||
; IX.
|
pop ix ; <-- lvl 1
|
||||||
pop hl ; <-- lvl 1
|
|
||||||
ret nz
|
ret nz
|
||||||
; Resolving left and right succeeded, proceed!
|
; Resolving left and right succeeded, proceed!
|
||||||
inc hl ; point to routine pointer
|
inc ix ; point to routine pointer
|
||||||
call intoHL
|
call callIXI
|
||||||
jp (hl)
|
push de \ pop ix
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret
|
||||||
|
|
||||||
; Given a string in (HL) and a separator char in A, return a splitted string,
|
; Given a string in (HL) and a separator char in A, return a splitted string,
|
||||||
; that is, the same (HL) string but with the found A char replaced by a null
|
; that is, the same (HL) string but with the found A char replaced by a null
|
||||||
@ -90,7 +95,7 @@ _findAndSplit:
|
|||||||
.find:
|
.find:
|
||||||
|
|
||||||
; parse expression on the left (HL) and the right (DE) and put the results in
|
; parse expression on the left (HL) and the right (DE) and put the results in
|
||||||
; DE (left) and IX (right)
|
; HL (left) and DE (right)
|
||||||
_resolveLeftAndRight:
|
_resolveLeftAndRight:
|
||||||
call parseExpr
|
call parseExpr
|
||||||
ret nz ; return immediately if error
|
ret nz ; return immediately if error
|
||||||
@ -98,12 +103,14 @@ _resolveLeftAndRight:
|
|||||||
; IX. What we need to do now is the same thing on (DE) and then apply
|
; IX. What we need to do now is the same thing on (DE) and then apply
|
||||||
; the + operator. Let's save IX somewhere and parse this.
|
; the + operator. Let's save IX somewhere and parse this.
|
||||||
ex de, hl ; right expr now in HL
|
ex de, hl ; right expr now in HL
|
||||||
push ix
|
push ix ; --> lvl 1
|
||||||
pop de ; numeric left expr result in DE
|
call parseExpr
|
||||||
jp parseExpr
|
pop hl ; <-- lvl 1. left
|
||||||
|
push ix \ pop de ; right
|
||||||
|
ret ; Z is parseExpr's result
|
||||||
|
|
||||||
; Routines in here all have the same signature: they take two numbers, DE (left)
|
; Routines in here all have the same signature: they take two numbers, DE (left)
|
||||||
; and IX (right), apply the operator and put the resulting number in IX.
|
; and IX (right), apply the operator and put the resulting number in DE.
|
||||||
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
|
; The table has 3 bytes per row: 1 byte for operator and 2 bytes for routine
|
||||||
; pointer.
|
; pointer.
|
||||||
exprTbl:
|
exprTbl:
|
||||||
@ -130,107 +137,87 @@ exprTbl:
|
|||||||
.db 0 ; end of table
|
.db 0 ; end of table
|
||||||
|
|
||||||
.plus:
|
.plus:
|
||||||
add ix, de
|
add hl, de
|
||||||
cp a ; ensure Z
|
ex de, hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.minus:
|
.minus:
|
||||||
push ix
|
or a ; clear carry
|
||||||
pop hl
|
|
||||||
ex de, hl
|
|
||||||
scf \ ccf
|
|
||||||
sbc hl, de
|
sbc hl, de
|
||||||
push hl
|
ex de, hl
|
||||||
pop ix
|
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.mult:
|
.mult:
|
||||||
push ix \ pop bc
|
ld b, h
|
||||||
call multDEBC
|
ld c, l
|
||||||
push hl \ pop ix
|
call multDEBC ; --> HL
|
||||||
cp a ; ensure Z
|
ex de, hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.div:
|
.div:
|
||||||
; divide takes HL/DE
|
; divide takes HL/DE
|
||||||
push bc
|
push bc
|
||||||
ex de, hl
|
|
||||||
push ix \ pop de
|
|
||||||
call divide
|
call divide
|
||||||
push bc \ pop ix
|
ld e, c
|
||||||
|
ld d, b
|
||||||
pop bc
|
pop bc
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.mod:
|
.mod:
|
||||||
call .div
|
call .div
|
||||||
push hl \ pop ix
|
ex de, hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.and:
|
.and:
|
||||||
push ix \ pop hl
|
|
||||||
ld a, h
|
ld a, h
|
||||||
and d
|
and d
|
||||||
ld h, a
|
ld d, a
|
||||||
ld a, l
|
ld a, l
|
||||||
and e
|
and e
|
||||||
ld l, a
|
ld e, a
|
||||||
push hl \ pop ix
|
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
.or:
|
.or:
|
||||||
push ix \ pop hl
|
|
||||||
ld a, h
|
ld a, h
|
||||||
or d
|
or d
|
||||||
ld h, a
|
ld d, a
|
||||||
ld a, l
|
ld a, l
|
||||||
or e
|
or e
|
||||||
ld l, a
|
ld e, a
|
||||||
push hl \ pop ix
|
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.xor:
|
.xor:
|
||||||
push ix \ pop hl
|
|
||||||
ld a, h
|
ld a, h
|
||||||
xor d
|
xor d
|
||||||
ld h, a
|
ld d, a
|
||||||
ld a, l
|
ld a, l
|
||||||
xor e
|
xor e
|
||||||
ld l, a
|
ld e, a
|
||||||
push hl \ pop ix
|
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.rshift:
|
.rshift:
|
||||||
push ix \ pop hl
|
ld a, e
|
||||||
ld a, l
|
|
||||||
and 0xf
|
and 0xf
|
||||||
ret z
|
ret z
|
||||||
push bc
|
push bc
|
||||||
ld b, a
|
ld b, a
|
||||||
.rshiftLoop:
|
.rshiftLoop:
|
||||||
srl d
|
srl h
|
||||||
rr e
|
rr l
|
||||||
djnz .rshiftLoop
|
djnz .rshiftLoop
|
||||||
push de \ pop ix
|
ex de, hl
|
||||||
pop bc
|
pop bc
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.lshift:
|
.lshift:
|
||||||
push ix \ pop hl
|
ld a, e
|
||||||
ld a, l
|
|
||||||
and 0xf
|
and 0xf
|
||||||
ret z
|
ret z
|
||||||
push bc
|
push bc
|
||||||
ld b, a
|
ld b, a
|
||||||
.lshiftLoop:
|
.lshiftLoop:
|
||||||
sla e
|
sla l
|
||||||
rl d
|
rl h
|
||||||
djnz .lshiftLoop
|
djnz .lshiftLoop
|
||||||
push de \ pop ix
|
ex de, hl
|
||||||
pop bc
|
pop bc
|
||||||
cp a ; ensure Z
|
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user