zasm: fix bug with registry selection
During expression parsing, if a local label was parsed, it would select the local registry and keep that selection, making subsequent global labels register in the wrong place.
This commit is contained in:
parent
a7afbe091e
commit
fe15bafeca
@ -169,24 +169,22 @@ parseNumberOrSymbol:
|
|||||||
call parseLiteral
|
call parseLiteral
|
||||||
ret z
|
ret z
|
||||||
; Not a number. Try PC
|
; Not a number. Try PC
|
||||||
push de
|
push de ; --> lvl 1
|
||||||
ld de, .sDollar
|
ld de, .sDollar
|
||||||
call strcmp
|
call strcmp
|
||||||
pop de
|
pop de ; <-- lvl 1
|
||||||
jr z, .returnPC
|
jr z, .returnPC
|
||||||
; Not PC either, try symbol
|
; Not PC either, try symbol
|
||||||
call symSelect
|
push de ; --> lvl 1
|
||||||
call symFind
|
call symFindVal ; --> DE
|
||||||
jr nz, .notfound
|
jr nz, .notfound
|
||||||
; Found! let's fetch value
|
|
||||||
push de
|
|
||||||
call symGetVal
|
|
||||||
; value in DE. We need it in IX
|
; value in DE. We need it in IX
|
||||||
push de \ pop ix
|
push de \ pop ix
|
||||||
pop de
|
pop de ; <-- lvl 1
|
||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
.notfound:
|
.notfound:
|
||||||
|
pop de ; <-- lvl 1
|
||||||
; If not found, check if we're in first pass. If we are, it doesn't
|
; If not found, check if we're in first pass. If we are, it doesn't
|
||||||
; matter that we didn't find our symbol. Return success anyhow.
|
; matter that we didn't find our symbol. Return success anyhow.
|
||||||
; Otherwise return error. Z is already unset, so in fact, this is the
|
; Otherwise return error. Z is already unset, so in fact, this is the
|
||||||
|
@ -238,12 +238,6 @@ symRegister:
|
|||||||
ld a, ERR_DUPSYM
|
ld a, ERR_DUPSYM
|
||||||
jp unsetZ ; return
|
jp unsetZ ; return
|
||||||
|
|
||||||
; Select global or local registry according to label name in (HL)
|
|
||||||
symSelect:
|
|
||||||
call symIsLabelLocal
|
|
||||||
jp z, symSelectLocalRegistry
|
|
||||||
jp symSelectGlobalRegistry
|
|
||||||
|
|
||||||
; Find name (HL) in (SYM_CTX_NAMES) and make (SYM_CTX_PTR) point to the
|
; Find name (HL) in (SYM_CTX_NAMES) and make (SYM_CTX_PTR) point to the
|
||||||
; corresponding entry in (SYM_CTX_VALUES).
|
; corresponding entry in (SYM_CTX_VALUES).
|
||||||
; If we find something, Z is set, otherwise unset.
|
; If we find something, Z is set, otherwise unset.
|
||||||
@ -277,7 +271,21 @@ symFind:
|
|||||||
pop ix
|
pop ix
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; For a given symbol name in (HL), find it in the appropriate symbol register
|
||||||
|
; and return its value in DE. If (HL) is a local label, the local register is
|
||||||
|
; searched. Otherwise, the global one. It is assumed that this routine is
|
||||||
|
; always called when the global registry is selected. Therefore, we always
|
||||||
|
; reselect it afterwards.
|
||||||
|
symFindVal:
|
||||||
|
call symIsLabelLocal
|
||||||
|
jp nz, .notLocal
|
||||||
|
call symSelectLocalRegistry
|
||||||
|
.notLocal:
|
||||||
|
call symFind
|
||||||
|
jr nz, .end
|
||||||
|
; Found! let's fetch value
|
||||||
; Return value that (SYM_CTX_PTR) is pointing at in DE.
|
; Return value that (SYM_CTX_PTR) is pointing at in DE.
|
||||||
symGetVal:
|
|
||||||
ld de, (SYM_CTX_PTR)
|
ld de, (SYM_CTX_PTR)
|
||||||
jp intoDE
|
call intoDE
|
||||||
|
.end:
|
||||||
|
jp symSelectGlobalRegistry
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -11,8 +11,7 @@ jp test
|
|||||||
zasmGetPC:
|
zasmGetPC:
|
||||||
zasmIsFirstPass:
|
zasmIsFirstPass:
|
||||||
symSelect:
|
symSelect:
|
||||||
symFind:
|
symFindVal:
|
||||||
symGetVal:
|
|
||||||
jp fail
|
jp fail
|
||||||
|
|
||||||
testNum: .db 1
|
testNum: .db 1
|
||||||
|
@ -34,9 +34,8 @@ test:
|
|||||||
jp nz, fail
|
jp nz, fail
|
||||||
|
|
||||||
ld hl, sFOO
|
ld hl, sFOO
|
||||||
call symFind ; don't match FOOBAR
|
call symFindVal ; don't match FOOBAR
|
||||||
jp nz, fail
|
jp nz, fail
|
||||||
call symGetVal
|
|
||||||
ld a, d
|
ld a, d
|
||||||
or a
|
or a
|
||||||
jp nz, fail
|
jp nz, fail
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
TMPFILE=$(mktemp)
|
|
||||||
KERNEL=../../../kernel
|
KERNEL=../../../kernel
|
||||||
APPS=../../../apps
|
APPS=../../../apps
|
||||||
ZASM=../../zasm.sh
|
ZASM=../../zasm.sh
|
||||||
@ -10,9 +9,8 @@ ASMFILE=${APPS}/zasm/instr.asm
|
|||||||
|
|
||||||
cmpas() {
|
cmpas() {
|
||||||
FN=$1
|
FN=$1
|
||||||
shift 1
|
|
||||||
EXPECTED=$(xxd ${FN}.expected)
|
EXPECTED=$(xxd ${FN}.expected)
|
||||||
ACTUAL=$(cat ${FN} | $ZASM "$@" | xxd)
|
ACTUAL=$(cat ${FN} | $ZASM "${KERNEL}" "${APPS}" | xxd)
|
||||||
if [ "$ACTUAL" == "$EXPECTED" ]; then
|
if [ "$ACTUAL" == "$EXPECTED" ]; then
|
||||||
echo ok
|
echo ok
|
||||||
else
|
else
|
||||||
@ -24,9 +22,14 @@ cmpas() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if [[ ! -z $1 ]]; then
|
||||||
|
cmpas $1
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
for fn in *.asm; do
|
for fn in *.asm; do
|
||||||
echo "Comparing ${fn}"
|
echo "Comparing ${fn}"
|
||||||
cmpas $fn "${KERNEL}" "${APPS}"
|
cmpas $fn
|
||||||
done
|
done
|
||||||
|
|
||||||
./errtests.sh
|
./errtests.sh
|
||||||
|
Binary file not shown.
11
tools/tests/zasm/test9.asm
Normal file
11
tools/tests/zasm/test9.asm
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
; test some weird label bug zasm had at some point. Simply to refer to a local
|
||||||
|
; label in a .dw directive would mess up future label references.
|
||||||
|
foo:
|
||||||
|
inc a
|
||||||
|
.bar:
|
||||||
|
inc b
|
||||||
|
.baz:
|
||||||
|
.dw .bar
|
||||||
|
|
||||||
|
loop:
|
||||||
|
jr loop
|
BIN
tools/tests/zasm/test9.asm.expected
Normal file
BIN
tools/tests/zasm/test9.asm.expected
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user