mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-17 08:08:07 +11:00
zasm: add support for local labels
This commit is contained in:
parent
17dbee6a49
commit
2de69ee7cd
@ -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
|
||||
|
@ -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
apps/zasm/tests/test3.asm
Normal file
20
apps/zasm/tests/test3.asm
Normal file
@ -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…
Reference in New Issue
Block a user