mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-27 15:08:05 +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
|
; Read file through blockdev ID in H and outputs its upcodes through blockdev
|
||||||
; ID in L.
|
; ID in L.
|
||||||
zasmMain:
|
zasmMain:
|
||||||
|
; Init I/O
|
||||||
ld a, h
|
ld a, h
|
||||||
ld de, IO_IN_GETC
|
ld de, IO_IN_GETC
|
||||||
call JUMP_BLKSEL
|
call JUMP_BLKSEL
|
||||||
ld a, l
|
ld a, l
|
||||||
ld de, IO_OUT_GETC
|
ld de, IO_OUT_GETC
|
||||||
call JUMP_BLKSEL
|
call JUMP_BLKSEL
|
||||||
|
; Init modules
|
||||||
|
call symInit
|
||||||
|
|
||||||
; First pass
|
; First pass
|
||||||
ld a, 1
|
ld a, 1
|
||||||
ld (ZASM_FIRST_PASS), a
|
ld (ZASM_FIRST_PASS), a
|
||||||
@ -155,14 +159,25 @@ parseLine:
|
|||||||
djnz .loopDirec
|
djnz .loopDirec
|
||||||
jr .success
|
jr .success
|
||||||
.label:
|
.label:
|
||||||
call zasmIsFirstPass
|
|
||||||
jr nz, .success ; not in first pass? nothing to do
|
|
||||||
; The string in (scratchpad) is a label with its trailing ':' removed.
|
; The string in (scratchpad) is a label with its trailing ':' removed.
|
||||||
ld hl, scratchpad
|
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)
|
ld de, (curOutputOffset)
|
||||||
call symRegister
|
call symRegister
|
||||||
|
jr nz, .error
|
||||||
jr .success
|
; continue to .success
|
||||||
.success:
|
.success:
|
||||||
xor a ; ensure Z
|
xor a ; ensure Z
|
||||||
jr .end
|
jr .end
|
||||||
|
@ -29,7 +29,14 @@
|
|||||||
; index of the name, then go get the value at that index in SYM_VALUES.
|
; 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_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 ***
|
; *** Code ***
|
||||||
|
|
||||||
@ -52,6 +59,20 @@ _symNext:
|
|||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
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
|
; 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.
|
; consecutive null chars. We return the index of that new name in A.
|
||||||
; If we're within bounds, Z is set, otherwise unset.
|
; If we're within bounds, Z is set, otherwise unset.
|
||||||
@ -148,6 +169,12 @@ symRegister:
|
|||||||
; If we find something, Z is set, otherwise unset.
|
; If we find something, Z is set, otherwise unset.
|
||||||
symFind:
|
symFind:
|
||||||
push hl
|
push hl
|
||||||
|
call _symFind
|
||||||
|
pop hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Same as symFind, but leaks HL
|
||||||
|
_symFind:
|
||||||
push bc
|
push bc
|
||||||
push de
|
push de
|
||||||
|
|
||||||
@ -155,10 +182,21 @@ symFind:
|
|||||||
call strlen
|
call strlen
|
||||||
ld c, a ; let's save that
|
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
|
ex hl, de ; it's easier if HL is haystack and DE is
|
||||||
; needle.
|
; needle.
|
||||||
ld b, 0
|
ld b, 0
|
||||||
ld hl, SYM_NAMES
|
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:
|
.loop:
|
||||||
ld a, c ; recall strlen
|
ld a, c ; recall strlen
|
||||||
call JUMP_STRNCMP
|
call JUMP_STRNCMP
|
||||||
@ -179,7 +217,6 @@ symFind:
|
|||||||
.end:
|
.end:
|
||||||
pop de
|
pop de
|
||||||
pop bc
|
pop bc
|
||||||
pop hl
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; Return value associated with symbol index A into DE
|
; Return value associated with symbol index A into DE
|
||||||
@ -194,3 +231,18 @@ symGetVal:
|
|||||||
ld d, (hl)
|
ld d, (hl)
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
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