1
0
mirror of https://github.com/hsoft/collapseos.git synced 2024-11-17 09:18:06 +11:00
collapseos/apps/zasm/directive.asm
Virgil Dupras e9244b80ee zasm: big I/O overhaul
Instead of buffering input in memory one line at a time, we go in "just
in time" mode and always read contents directly from I/O, without
buffering.

It forces us to implement a `ioPutback` scheme, but on the other hand it
greatly simplifies cases where multiple tokens are on the same line
(when a label is directly followed by an instruction).

The end result feels much more solid and less hackish.
2019-05-16 07:53:42 -04:00

119 lines
2.0 KiB
NASM

; *** CONSTS ***
.equ D_DB 0x00
.equ D_DW 0x01
.equ D_EQU 0x02
.equ D_BAD 0xff
; *** Variables ***
.equ DIREC_SCRATCHPAD DIREC_RAMSTART
.equ DIREC_RAMEND DIREC_SCRATCHPAD+SCRATCHPAD_SIZE
; *** CODE ***
; 4 bytes per row, fill with zero
directiveNames:
.db ".DB", 0
.db ".DW", 0
.db ".EQU"
; This is a list of handlers corresponding to indexes in directiveNames
directiveHandlers:
.dw handleDB
.dw handleDW
.dw handleEQU
handleDB:
push hl
call readWord
ld hl, scratchpad
call parseLiteral
ld a, ixl
ld (direcData), a
ld a, 1
pop hl
ret
handleDW:
push hl
call readWord
ld hl, scratchpad
call parseExpr
ld a, ixl
ld (direcData), a
ld a, ixh
ld (direcData+1), a
ld a, 2
pop hl
ret
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 de
push bc
; Read our constant name
call readWord
; We can't register our symbol yet: we don't have our value!
; Let's copy it over.
ld de, DIREC_SCRATCHPAD
ld bc, SCRATCHPAD_SIZE
ldir
; Now, read the value associated to it
call readWord
ld hl, scratchpad
call parseExpr
jr nz, .error
ld hl, DIREC_SCRATCHPAD
ld d, ixh
ld e, ixl
call symRegister
jr .end
.error:
.end:
xor a ; 0 bytes written
pop bc
pop de
pop hl
ret
; Reads string in (HL) and returns the corresponding ID (D_*) in A. Sets Z if
; there's a match.
getDirectiveID:
push bc
push de
ld b, D_EQU+1 ; D_EQU is last
ld c, 4
ld de, directiveNames
call findStringInList
pop de
pop bc
ret
; Parse directive specified in A (D_* const) with args in I/O and act in
; an appropriate manner. If the directive results in writing data at its
; current location, that data is in (direcData) and A is the number of bytes
; in it.
parseDirective:
push de
; double A to have a proper offset in directiveHandlers
add a, a
ld de, directiveHandlers
call JUMP_ADDDE
call JUMP_INTODE
ld ixh, d
ld ixl, e
pop de
jp (ix)
; *** Variables ***
direcData:
.fill 2