瀏覽代碼

zasm: add support for local labels

pull/10/head
Virgil Dupras 5 年之前
父節點
當前提交
2de69ee7cd
共有 3 個檔案被更改,包括 93 行新增6 行删除
  1. +19
    -4
      apps/zasm/main.asm
  2. +54
    -2
      apps/zasm/symbol.asm
  3. +20
    -0
      apps/zasm/tests/test3.asm

+ 19
- 4
apps/zasm/main.asm 查看文件

@@ -56,12 +56,16 @@ jp zasmMain
; Read file through blockdev ID in H and outputs its upcodes through blockdev
; ID in L.
zasmMain:
; Init I/O
ld a, h
ld de, IO_IN_GETC
call JUMP_BLKSEL
ld a, l
ld de, IO_OUT_GETC
call JUMP_BLKSEL
; Init modules
call symInit

; First pass
ld a, 1
ld (ZASM_FIRST_PASS), a
@@ -155,14 +159,25 @@ parseLine:
djnz .loopDirec
jr .success
.label:
call zasmIsFirstPass
jr nz, .success ; not in first pass? nothing to do
; The string in (scratchpad) is a label with its trailing ':' removed.
ld hl, scratchpad
call zasmIsFirstPass
jr z, .registerLabel ; When we encounter a label in the first
; pass, we register it in the symbol
; list
; When we're not in the first pass, we set the context (if label is not
; local) to that label.
call symIsLabelLocal
jr z, .success ; local? nothing to do.
call symSetContext
jr z, .success
; NZ? this means that (HL) couldn't be found in symbol list. Weird
jr .error
.registerLabel:
ld de, (curOutputOffset)
call symRegister

jr .success
jr nz, .error
; continue to .success
.success:
xor a ; ensure Z
jr .end


+ 54
- 2
apps/zasm/symbol.asm 查看文件

@@ -29,7 +29,14 @@
; index of the name, then go get the value at that index in SYM_VALUES.
.equ SYM_NAMES SYM_VALUES+(SYM_MAXCOUNT*2)

.equ SYM_RAMEND SYM_NAMES+SYM_BUFSIZE
; Index of the symbol found during the last symSetContext call
.equ SYM_CONTEXT_IDX SYM_NAMES+SYM_BUFSIZE

; Pointer, in the SYM_NAMES buffer, of the string found during the last
; symSetContext call
.equ SYM_CONTEXT_PTR SYM_CONTEXT_IDX+1

.equ SYM_RAMEND SYM_CONTEXT_PTR+2

; *** Code ***

@@ -52,6 +59,20 @@ _symNext:
cp a ; ensure Z
ret

symInit:
xor a
ld (SYM_NAMES), a
ld (SYM_CONTEXT_IDX), a
ld hl, SYM_CONTEXT_PTR
ld (SYM_CONTEXT_PTR), hl
ret

; Sets Z according to whether label in (HL) is local (starts with a dot)
symIsLabelLocal:
ld a, '.'
cp (hl)
ret

; Place HL at the end of SYM_NAMES end (that is, at the point where we have two
; consecutive null chars. We return the index of that new name in A.
; If we're within bounds, Z is set, otherwise unset.
@@ -148,6 +169,12 @@ symRegister:
; If we find something, Z is set, otherwise unset.
symFind:
push hl
call _symFind
pop hl
ret

; Same as symFind, but leaks HL
_symFind:
push bc
push de

@@ -155,10 +182,21 @@ symFind:
call strlen
ld c, a ; let's save that

call symIsLabelLocal ; save Z for after the 3 next lines, which
; doesn't touch flags. We need to call this now
; before we lose HL.
ex hl, de ; it's easier if HL is haystack and DE is
; needle.
ld b, 0
ld hl, SYM_NAMES
jr nz, .loop ; not local? jump right to loop
; local? then we need to adjust B and HL
ld hl, (SYM_CONTEXT_PTR)
ld a, (SYM_CONTEXT_IDX)
ld b, a
xor a
sub b
ld b, a
.loop:
ld a, c ; recall strlen
call JUMP_STRNCMP
@@ -179,7 +217,6 @@ symFind:
.end:
pop de
pop bc
pop hl
ret

; Return value associated with symbol index A into DE
@@ -194,3 +231,18 @@ symGetVal:
ld d, (hl)
pop hl
ret

; Find symbol name (HL) in the symbol list and set SYM_CONTEXT_* accordingly.
; When symFind will be called with a symbol name starting with a '.', the search
; will begin at that context instead of the beginning of the register.
; Sets Z if symbol is found, unsets it if not.
symSetContext:
push hl
call _symFind
jr nz, .end ; Z already unset
ld (SYM_CONTEXT_IDX), a
ld (SYM_CONTEXT_PTR), hl
; Z already set
.end:
pop hl
ret

+ 20
- 0
apps/zasm/tests/test3.asm 查看文件

@@ -0,0 +1,20 @@
; test local labels
addDE:
push af
add a, e
jr nc, .end ; no carry? skip inc
inc d
.end:
ld e, a
pop af
ret

addHL:
push af
add a, l
jr nc, .end ; no carry? skip inc
inc h
.end:
ld l, a
pop af
ret

Loading…
取消
儲存