mirror of
https://github.com/hsoft/collapseos.git
synced 2024-11-17 07:08:05 +11:00
zasm: add support for .org directive
This commit is contained in:
parent
49be50b730
commit
acddb045a5
@ -3,7 +3,8 @@
|
|||||||
.equ D_DB 0x00
|
.equ D_DB 0x00
|
||||||
.equ D_DW 0x01
|
.equ D_DW 0x01
|
||||||
.equ D_EQU 0x02
|
.equ D_EQU 0x02
|
||||||
.equ D_INC 0x03
|
.equ D_ORG 0x03
|
||||||
|
.equ D_INC 0x04
|
||||||
.equ D_BAD 0xff
|
.equ D_BAD 0xff
|
||||||
|
|
||||||
; *** Variables ***
|
; *** Variables ***
|
||||||
@ -16,6 +17,7 @@ directiveNames:
|
|||||||
.db ".DB", 0
|
.db ".DB", 0
|
||||||
.db ".DW", 0
|
.db ".DW", 0
|
||||||
.db ".EQU"
|
.db ".EQU"
|
||||||
|
.db ".ORG"
|
||||||
.db "#inc"
|
.db "#inc"
|
||||||
|
|
||||||
; This is a list of handlers corresponding to indexes in directiveNames
|
; This is a list of handlers corresponding to indexes in directiveNames
|
||||||
@ -23,6 +25,7 @@ directiveHandlers:
|
|||||||
.dw handleDB
|
.dw handleDB
|
||||||
.dw handleDW
|
.dw handleDW
|
||||||
.dw handleEQU
|
.dw handleEQU
|
||||||
|
.dw handleORG
|
||||||
.dw handleINC
|
.dw handleINC
|
||||||
|
|
||||||
handleDB:
|
handleDB:
|
||||||
@ -67,14 +70,6 @@ handleDW:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
handleEQU:
|
handleEQU:
|
||||||
call zasmIsFirstPass
|
|
||||||
jr nz, .begin
|
|
||||||
; first pass? .equ are noops Consume args and return
|
|
||||||
call readWord
|
|
||||||
call readWord
|
|
||||||
xor a
|
|
||||||
ret
|
|
||||||
.begin:
|
|
||||||
push hl
|
push hl
|
||||||
push de
|
push de
|
||||||
push bc
|
push bc
|
||||||
@ -90,12 +85,10 @@ handleEQU:
|
|||||||
call readWord
|
call readWord
|
||||||
ld hl, scratchpad
|
ld hl, scratchpad
|
||||||
call parseExpr
|
call parseExpr
|
||||||
jr nz, .error
|
jr nz, .end
|
||||||
ld hl, DIREC_SCRATCHPAD
|
ld hl, DIREC_SCRATCHPAD
|
||||||
push ix \ pop de
|
push ix \ pop de
|
||||||
call symRegister
|
call symRegister
|
||||||
jr .end
|
|
||||||
.error:
|
|
||||||
.end:
|
.end:
|
||||||
xor a ; 0 bytes written
|
xor a ; 0 bytes written
|
||||||
pop bc
|
pop bc
|
||||||
@ -103,6 +96,13 @@ handleEQU:
|
|||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
handleORG:
|
||||||
|
call readWord
|
||||||
|
call parseExpr
|
||||||
|
ret nz
|
||||||
|
push ix \ pop hl
|
||||||
|
jp zasmSetOrg
|
||||||
|
|
||||||
handleINC:
|
handleINC:
|
||||||
call readWord
|
call readWord
|
||||||
jr nz, .end
|
jr nz, .end
|
||||||
|
@ -675,7 +675,7 @@ getUpcode:
|
|||||||
bit 7, (ix+3)
|
bit 7, (ix+3)
|
||||||
jr z, .absoluteValue ; bit not set? regular byte value,
|
jr z, .absoluteValue ; bit not set? regular byte value,
|
||||||
; Our argument is a relative address ("e" type in djnz and jr). We have
|
; Our argument is a relative address ("e" type in djnz and jr). We have
|
||||||
; to subtract (IO_PC) from it.
|
; to subtract PC from it.
|
||||||
|
|
||||||
; First, check whether we're on first pass. If we are, skip processing
|
; First, check whether we're on first pass. If we are, skip processing
|
||||||
; below because not having real symbol value makes relative address
|
; below because not having real symbol value makes relative address
|
||||||
@ -686,7 +686,10 @@ getUpcode:
|
|||||||
|
|
||||||
; We're on second pass
|
; We're on second pass
|
||||||
push de ; Don't let go of this, that's our dest
|
push de ; Don't let go of this, that's our dest
|
||||||
ld de, (IO_PC)
|
push hl
|
||||||
|
call zasmGetPC ; --> HL
|
||||||
|
ex de, hl
|
||||||
|
pop hl
|
||||||
call intoHL
|
call intoHL
|
||||||
dec hl ; what we write is "e-2"
|
dec hl ; what we write is "e-2"
|
||||||
dec hl
|
dec hl
|
||||||
|
@ -11,7 +11,9 @@
|
|||||||
.equ ZASM_LOCAL_PASS ZASM_FIRST_PASS+1
|
.equ ZASM_LOCAL_PASS ZASM_FIRST_PASS+1
|
||||||
; What IO_PC was when we started our context
|
; What IO_PC was when we started our context
|
||||||
.equ ZASM_CTX_PC ZASM_LOCAL_PASS+1
|
.equ ZASM_CTX_PC ZASM_LOCAL_PASS+1
|
||||||
.equ ZASM_RAMEND ZASM_CTX_PC+2
|
; current ".org" offset, that is, what we must offset all our label by.
|
||||||
|
.equ ZASM_ORG ZASM_CTX_PC+2
|
||||||
|
.equ ZASM_RAMEND ZASM_ORG+2
|
||||||
|
|
||||||
; 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.
|
||||||
@ -27,6 +29,8 @@ zasmMain:
|
|||||||
; Init modules
|
; Init modules
|
||||||
xor a
|
xor a
|
||||||
ld (ZASM_LOCAL_PASS), a
|
ld (ZASM_LOCAL_PASS), a
|
||||||
|
ld (ZASM_ORG), a
|
||||||
|
ld (ZASM_ORG+1), a
|
||||||
call ioInit
|
call ioInit
|
||||||
call symInit
|
call symInit
|
||||||
|
|
||||||
@ -54,6 +58,20 @@ zasmIsLocalPass:
|
|||||||
cp 1
|
cp 1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
; Set ZASM_ORG to specified number in HL
|
||||||
|
zasmSetOrg:
|
||||||
|
ld (ZASM_ORG), hl
|
||||||
|
ret
|
||||||
|
|
||||||
|
; Return current PC (properly .org offsetted) in HL
|
||||||
|
zasmGetPC:
|
||||||
|
push de
|
||||||
|
ld hl, (ZASM_ORG)
|
||||||
|
ld de, (IO_PC)
|
||||||
|
add hl, de
|
||||||
|
pop de
|
||||||
|
ret
|
||||||
|
|
||||||
; Repeatedly reads lines from IO, assemble them and spit the binary code in
|
; Repeatedly reads lines from IO, assemble them and spit the binary code in
|
||||||
; IO. Z is set on success, unset on error. DE contains the last line number to
|
; IO. Z is set on success, unset on error. DE contains the last line number to
|
||||||
; be read (first line is 1).
|
; be read (first line is 1).
|
||||||
@ -135,7 +153,10 @@ _parseLabel:
|
|||||||
call _endLocalPass
|
call _endLocalPass
|
||||||
jr .success
|
jr .success
|
||||||
.registerLabel:
|
.registerLabel:
|
||||||
ld de, (IO_PC)
|
push hl
|
||||||
|
call zasmGetPC
|
||||||
|
ex de, hl
|
||||||
|
pop hl
|
||||||
call symRegister
|
call symRegister
|
||||||
jr nz, .error
|
jr nz, .error
|
||||||
; continue to .success
|
; continue to .success
|
||||||
|
@ -226,13 +226,10 @@ parseLiteral:
|
|||||||
parseNumberOrSymbol:
|
parseNumberOrSymbol:
|
||||||
call parseLiteral
|
call parseLiteral
|
||||||
ret z
|
ret z
|
||||||
call zasmIsFirstPass
|
|
||||||
ret z ; first pass? we don't care about the value,
|
|
||||||
; return success.
|
|
||||||
; Not a number. Try symbol
|
; Not a number. Try symbol
|
||||||
call symSelect
|
call symSelect
|
||||||
call symFind
|
call symFind
|
||||||
ret nz ; not found
|
jr nz, .notfound
|
||||||
; Found! let's fetch value
|
; Found! let's fetch value
|
||||||
push de
|
push de
|
||||||
call symGetVal
|
call symGetVal
|
||||||
@ -241,3 +238,9 @@ parseNumberOrSymbol:
|
|||||||
pop de
|
pop de
|
||||||
cp a ; ensure Z
|
cp a ; ensure Z
|
||||||
ret
|
ret
|
||||||
|
.notfound:
|
||||||
|
; If not found, check if we're in first pass. If we are, it doesn't
|
||||||
|
; matter that we didn't find our symbol. Return success anyhow.
|
||||||
|
; Otherwise return error. Z is already unset, so in fact, this is the
|
||||||
|
; same as jumping to zasmIsFirstPass
|
||||||
|
jp zasmIsFirstPass
|
||||||
|
@ -155,9 +155,13 @@ symNamesEnd:
|
|||||||
; If successful, Z is set and A is the symbol index. Otherwise, Z is unset and
|
; If successful, Z is set and A is the symbol index. Otherwise, Z is unset and
|
||||||
; A is an error code (SYM_ERR_*).
|
; A is an error code (SYM_ERR_*).
|
||||||
symRegister:
|
symRegister:
|
||||||
|
call symFind
|
||||||
|
jr z, .alreadyThere
|
||||||
|
|
||||||
push hl ; will be used during processing. it's the symbol to add
|
push hl ; will be used during processing. it's the symbol to add
|
||||||
push de ; will be used during processing. it's our value.
|
push de ; will be used during processing. it's our value.
|
||||||
|
|
||||||
|
|
||||||
; First, let's get our strlen
|
; First, let's get our strlen
|
||||||
call strlen
|
call strlen
|
||||||
ld c, a ; save that strlen for later
|
ld c, a ; save that strlen for later
|
||||||
@ -201,11 +205,20 @@ symRegister:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
; Z already unset
|
call unsetZ
|
||||||
pop de
|
pop de
|
||||||
pop hl
|
pop hl
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.alreadyThere:
|
||||||
|
push hl
|
||||||
|
ld hl, (SYM_CTX_PTR)
|
||||||
|
ex de, hl
|
||||||
|
call writeHLinDE
|
||||||
|
pop hl
|
||||||
|
cp a ; ensure Z
|
||||||
|
ret
|
||||||
|
|
||||||
; Select global or local registry according to label name in (HL)
|
; Select global or local registry according to label name in (HL)
|
||||||
symSelect:
|
symSelect:
|
||||||
call symIsLabelLocal
|
call symIsLabelLocal
|
||||||
|
6
tools/tests/zasm/test8.asm
Normal file
6
tools/tests/zasm/test8.asm
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
; test .org directive
|
||||||
|
.equ foo 1234
|
||||||
|
.org foo
|
||||||
|
label1:
|
||||||
|
jp label1
|
||||||
|
jr label1
|
Loading…
Reference in New Issue
Block a user