@@ -415,14 +415,12 @@ matchArg: | |||
dec hl | |||
ret | |||
; Compare primary row at (DE) with ID at (token+1). Sets Z flag if there's a | |||
; match, reset if not. | |||
; Compare primary row at (DE) with ID in A. Sets Z flag if there's a match. | |||
matchPrimaryRow: | |||
push hl | |||
push ix | |||
ld ixh, d | |||
ld ixl, e | |||
ld a, (token+1) | |||
cp (ix) | |||
jr nz, .end | |||
; name matches, let's see the rest | |||
@@ -778,18 +776,22 @@ processArg: | |||
ld a, ixh | |||
ld (de), a | |||
cp a ; ensure Z is set | |||
pop hl | |||
ret | |||
jr .end | |||
.error: | |||
call JUMP_UNSETZ | |||
.end: | |||
pop hl | |||
ret | |||
; Parse instruction specified in A (I_* const) with args in (HL) and write | |||
; resulting opcode(s) in (curUpcode). Returns the number of bytes written in A. | |||
parseInstruction: | |||
push bc | |||
push hl | |||
push de | |||
; A is reused in matchPrimaryRow but that register is way too changing. | |||
; Let's keep a copy in a more cosy register. | |||
ld c, a | |||
ld de, curArg1 | |||
call processArg | |||
jr nz, .error | |||
@@ -800,7 +802,7 @@ parseInstruction: | |||
ld de, instrTBl | |||
ld b, INSTR_TBL_CNT | |||
.loop: | |||
ld a, (de) | |||
ld a, c ; recall A param | |||
call matchPrimaryRow | |||
jr z, .match | |||
ld a, INSTR_TBL_ROWSIZE | |||
@@ -819,6 +821,7 @@ parseInstruction: | |||
.end: | |||
pop de | |||
pop hl | |||
pop bc | |||
ret | |||
@@ -32,18 +32,15 @@ parseLine: | |||
call gotoNextNotBlankLine | |||
jr nz, .error | |||
push de | |||
ld de, token | |||
call tokenize | |||
pop de | |||
ld a, (token) ; TOK_* | |||
ld a, b ; TOK_* | |||
cp TOK_BAD | |||
jr z, .error | |||
cp TOK_INSTR | |||
jr z, .instr | |||
jr .error ; directive not supported yet | |||
.instr: | |||
ld a, (token+1) ; I_* | |||
ld a, c ; I_* | |||
call parseInstruction | |||
or a ; is zero? | |||
jr z, .error | |||
@@ -62,9 +59,5 @@ parseLine: | |||
ret | |||
; *** Variables *** | |||
token: | |||
.fill 5 | |||
scratchpad: | |||
.fill 0x20 |
@@ -11,40 +11,35 @@ TOK_DIRECTIVE .equ 0x02 | |||
TOK_BAD .equ 0xff | |||
; *** Code *** | |||
; Parse line in (HL) and read the next token in (DE). The token is written on | |||
; two bytes. The first byte is a token type (TOK_* constants) and the second | |||
; byte is an ID specific to that token type. | |||
; If no token matches, TOK_BAD is written to (DE) | |||
; Parse line in (HL) and read the next token in BC. The token is written on | |||
; two bytes (B and C). B is a token type (TOK_* constants) and C is an ID | |||
; specific to that token type. | |||
; Advance HL to after the read word. | |||
; If no token matches, TOK_BAD is written to B | |||
tokenize: | |||
xor a | |||
ld (de), a | |||
push de | |||
call toWord | |||
ld a, 4 | |||
ld de, scratchpad | |||
call readWord | |||
ex hl, de | |||
push hl ; Save advanced HL for later | |||
ld hl, scratchpad | |||
call getInstID | |||
jr z, .instr | |||
call getDirectiveID | |||
jr z, .direc | |||
; no match | |||
ex hl, de ; swap it back | |||
ld a, TOK_BAD | |||
ld (de), a | |||
ret | |||
ld b, TOK_BAD | |||
jr .end | |||
.instr: | |||
ex af, af' | |||
ld a, TOK_INSTR | |||
ld b, TOK_INSTR | |||
jr .end | |||
.direc: | |||
ex af, af' | |||
ld a, TOK_DIRECTIVE | |||
jr .end | |||
ld b, TOK_DIRECTIVE | |||
.end: | |||
ex hl, de ; swap it back | |||
ld (de), a | |||
ex af, af' | |||
inc de | |||
ld (de), a | |||
ld c, a | |||
pop hl | |||
pop de | |||
ret | |||
; Sets Z is A is ';', CR, LF, or null. | |||