Browse Source

zasm: simplify readWord calling

It always reads in the scratchpad with the same max size. No need for
DE-dancing anymore.
pull/10/head
Virgil Dupras 5 years ago
parent
commit
f9ae5ca46b
6 changed files with 133 additions and 149 deletions
  1. +0
    -8
      apps/zasm/directive.asm
  2. +1
    -1
      apps/zasm/emul/Makefile
  3. +3
    -9
      apps/zasm/instr.asm
  4. +1
    -3
      apps/zasm/main.asm
  5. +128
    -0
      apps/zasm/parse.asm
  6. +0
    -128
      apps/zasm/tok.asm

+ 0
- 8
apps/zasm/directive.asm View File

@@ -17,11 +17,8 @@ directiveHandlers:
.dw handleDW

handleDB:
push de
push hl
call toWord
ld de, scratchpad
ld a, 8
call readWord
ld hl, scratchpad
call parseNumber
@@ -29,15 +26,11 @@ handleDB:
ld (direcData), a
ld a, 1
pop hl
pop de
ret

handleDW:
push de
push hl
call toWord
ld de, scratchpad
ld a, 8
call readWord
ld hl, scratchpad
call parseNumber
@@ -47,7 +40,6 @@ handleDW:
ld (direcData+1), a
ld a, 2
pop hl
pop de
ret

; Reads string in (HL) and returns the corresponding ID (D_*) in A. Sets Z if


+ 1
- 1
apps/zasm/emul/Makefile View File

@@ -8,5 +8,5 @@ libz80/libz80.o: libz80/z80.c
kernel.h: glue.asm
scas -o - -I ../../../parts/z80 $< | ./bin2c.sh KERNEL | tee $@ > /dev/null

zasm.h: $(addprefix ../, main.asm instr.asm directive.asm tok.asm literal.asm util.asm)
zasm.h: $(addprefix ../, main.asm instr.asm directive.asm tok.asm parse.asm literal.asm util.asm)
scas -o - -I.. $< | ./bin2c.sh ZASM | tee $@ > /dev/null

+ 3
- 9
apps/zasm/instr.asm View File

@@ -688,17 +688,11 @@ getUpcode:
; Parse next argument in string (HL) and place it in (DE)
; Sets Z on success, reset on error.
processArg:
push de
call toWord
xor a
ld de, scratchpad
ld (de), a
ld a, 8
call readWord
pop de
; Read word is in scratchpad, (DE) is back to initial value, HL is
; properly advanced. Now, let's push that HL value and replace it with
; (scratchpad) so that we can parse that arg.
; Read word is in scratchpad, HL is properly advanced. Now, let's push
; that HL value and replace it with (scratchpad) so that we can parse
; that arg.
push hl
ld hl, scratchpad



+ 1
- 3
apps/zasm/main.asm View File

@@ -20,6 +20,7 @@ main:
ret

#include "util.asm"
#include "parse.asm"
#include "literal.asm"
#include "instr.asm"
#include "tok.asm"
@@ -76,6 +77,3 @@ parseLine:
pop bc
ret

; *** Variables ***
scratchpad:
.fill 0x20

+ 128
- 0
apps/zasm/parse.asm View File

@@ -0,0 +1,128 @@
; *** Consts ***
.equ SCRATCHPAD_SIZE 0x20
; *** Variables ***
scratchpad:
.fill SCRATCHPAD_SIZE

; *** Code ***

; Sets Z is A is ';', CR, LF, or null.
isLineEndOrComment:
cp ';'
ret z
; Continues onto isLineEnd...

; Sets Z is A is CR, LF, or null.
isLineEnd:
or a ; same as cp 0
ret z
cp 0x0d
ret z
cp 0x0a
ret

; Sets Z is A is ' ' '\t' or ','
isSep:
cp ' '
ret z
cp 0x09
ret z
cp ','
ret

; Sets Z is A is ' ', ',', ';', CR, LF, or null.
isSepOrLineEnd:
call isSep
ret z
call isLineEndOrComment
ret

; read word in (HL) and put it in (scratchpad), null terminated, for a maximum
; of SCRATCHPAD_SIZE-1 characters. As a result, A is the read length. HL is
; advanced to the next separator char.
readWord:
push bc
push de
ld de, scratchpad
ld b, SCRATCHPAD_SIZE-1
.loop:
ld a, (hl)
call isSepOrLineEnd
jr z, .success
call JUMP_UPCASE
ld (de), a
inc hl
inc de
djnz .loop
.success:
xor a
ld (de), a
ld a, SCRATCHPAD_SIZE-1
sub a, b
.end:
pop de
pop bc
ret

; (HL) being a string, advance it to the next non-sep character.
; Set Z if we could do it before the line ended, reset Z if we couldn't.
toWord:
.loop:
ld a, (hl)
call isLineEndOrComment
jr z, .error
call isSep
jr nz, .success
inc hl
jr .loop
.error:
call JUMP_UNSETZ
ret
.success:
xor a ; ensure Z
ret

; Advance HL to the beginning of the next line, that is, right after the next
; 0x10 or 0x13 or both. If we reach null, we stop and error out.
; Sets Z on success, unsets it on error.
gotoNextLine:
dec hl ; a bit weird, but makes the looping easier
.loop:
inc hl
ld a, (hl)
call isLineEnd
jr nz, .loop
; (HL) is 0x10, 0x13 or 0
or a ; is 0?
jr z, .error
; we might have 0x13 followed by 0x10, let's account for this.
; Yes, 0x10 followed by 0x10 will make us skip two lines, but this is of
; no real consequence in our context.
inc hl
ld a, (hl)
call isLineEnd
jr nz, .success
or a ; is 0?
jr z, .error
; There was another line sep. Skip this char
inc hl
; Continue on to .success
.success:
xor a ; ensure Z
ret
.error:
call JUMP_UNSETZ
ret

; Repeatedly calls gotoNextLine until the line in (HL) points to a line that
; isn't blank or 100% comment. Sets Z if we reach a line, Unset Z if we reach
; EOF
gotoNextNotBlankLine:
call toWord
ret z ; Z set? we have a not-blank line
; Z not set? (HL) is at the end of the line or at the beginning of
; comments.
call gotoNextLine
ret nz
jr gotoNextNotBlankLine


+ 0
- 128
apps/zasm/tok.asm View File

@@ -1,7 +1,3 @@
; tok
;
; Tokenizes an ASM source file into 1, 2 or 3-sized structures.
;
; *** Requirements ***
; JUMP_UPCASE

@@ -17,10 +13,7 @@ TOK_BAD .equ 0xff
; Advance HL to after the read word.
; If no token matches, TOK_BAD is written to B
tokenize:
push de
call toWord
ld a, 4
ld de, scratchpad
call readWord
push hl ; Save advanced HL for later
ld hl, scratchpad
@@ -39,125 +32,4 @@ tokenize:
.end:
ld c, a
pop hl
pop de
ret

; Sets Z is A is ';', CR, LF, or null.
isLineEndOrComment:
cp ';'
ret z
; Continues onto isLineEnd...

; Sets Z is A is CR, LF, or null.
isLineEnd:
or a ; same as cp 0
ret z
cp 0x0d
ret z
cp 0x0a
ret

; Sets Z is A is ' ' '\t' or ','
isSep:
cp ' '
ret z
cp 0x09
ret z
cp ','
ret

; Sets Z is A is ' ', ',', ';', CR, LF, or null.
isSepOrLineEnd:
call isSep
ret z
call isLineEndOrComment
ret

; read word in (HL) and put it in (DE), null terminated, for a maximum of A
; characters. As a result, A is the read length. HL is advanced to the next
; separator char.
readWord:
push bc
push de
ld b, a
.loop:
ld a, (hl)
call isSepOrLineEnd
jr z, .success
call JUMP_UPCASE
ld (de), a
inc hl
inc de
djnz .loop
.success:
xor a
ld (de), a
ld a, 4
sub a, b
.end:
pop de
pop bc
ret

; (HL) being a string, advance it to the next non-sep character.
; Set Z if we could do it before the line ended, reset Z if we couldn't.
toWord:
.loop:
ld a, (hl)
call isLineEndOrComment
jr z, .error
call isSep
jr nz, .success
inc hl
jr .loop
.error:
call JUMP_UNSETZ
ret
.success:
xor a ; ensure Z
ret

; Advance HL to the beginning of the next line, that is, right after the next
; 0x10 or 0x13 or both. If we reach null, we stop and error out.
; Sets Z on success, unsets it on error.
gotoNextLine:
dec hl ; a bit weird, but makes the looping easier
.loop:
inc hl
ld a, (hl)
call isLineEnd
jr nz, .loop
; (HL) is 0x10, 0x13 or 0
or a ; is 0?
jr z, .error
; we might have 0x13 followed by 0x10, let's account for this.
; Yes, 0x10 followed by 0x10 will make us skip two lines, but this is of
; no real consequence in our context.
inc hl
ld a, (hl)
call isLineEnd
jr nz, .success
or a ; is 0?
jr z, .error
; There was another line sep. Skip this char
inc hl
; Continue on to .success
.success:
xor a ; ensure Z
ret
.error:
call JUMP_UNSETZ
ret

; Repeatedly calls gotoNextLine until the line in (HL) points to a line that
; isn't blank or 100% comment. Sets Z if we reach a line, Unset Z if we reach
; EOF
gotoNextNotBlankLine:
call toWord
ret z ; Z set? we have a not-blank line
; Z not set? (HL) is at the end of the line or at the beginning of
; comments.
call gotoNextLine
ret nz
jr gotoNextNotBlankLine


Loading…
Cancel
Save