zasm: make io unit handle PC and output suppression

This commit is contained in:
Virgil Dupras 2019-05-17 14:58:16 -04:00
parent 6547e83f20
commit ad7428e471
3 changed files with 32 additions and 29 deletions

View File

@ -634,7 +634,7 @@ getUpcode:
bit 7, (ix+3)
jr z, .absoluteValue ; bit not set? regular byte value,
; Our argument is a relative address ("e" type in djnz and jr). We have
; to subtract (ZASM_PC) from it.
; to subtract (IO_PC) from it.
; First, check whether we're on first pass. If we are, skip processing
; below because not having real symbol value makes relative address
@ -645,7 +645,7 @@ getUpcode:
; We're on second pass
push de ; Don't let go of this, that's our dest
ld de, (ZASM_PC)
ld de, (IO_PC)
call intoHL
dec hl ; what we write is "e-2"
dec hl

View File

@ -4,6 +4,9 @@
; parameter, two blockdevs: One that we can read and seek and one that we can
; write to (we never seek into it).
;
; This unit also has the responsibility of counting the number of written bytes,
; maintaining IO_PC and of properly disabling output on first pass.
;
; zasm doesn't buffers its reads during tokenization, which simplifies its
; process. However, it also means that it needs, in certain cases, a "putback"
; mechanism, that is, a way to say "you see that character I've just read? that
@ -47,7 +50,8 @@
; see ioPutBack below
.equ IO_PUTBACK_BUF IO_INCLUDE_HDL+FS_HANDLE_SIZE
.equ IO_IN_INCLUDE IO_PUTBACK_BUF+1
.equ IO_RAMEND IO_IN_INCLUDE+1
.equ IO_PC IO_IN_INCLUDE+1
.equ IO_RAMEND IO_PC+2
; *** Code ***
@ -55,7 +59,7 @@ ioInit:
xor a
ld (IO_PUTBACK_BUF), a
ld (IO_IN_INCLUDE), a
ret
jp ioResetPC
ioGetC:
ld a, (IO_PUTBACK_BUF)
@ -101,8 +105,20 @@ ioPutBack:
ret
ioPutC:
push hl
ld hl, (IO_PC)
inc hl
ld (IO_PC), hl
pop hl
push af
call zasmIsFirstPass
jr z, .skip
pop af
ld ix, (IO_OUT_PUTC)
jp (ix)
.skip:
pop af
ret
ioSavePos:
call _ioTell
@ -117,6 +133,11 @@ ioRewind:
ld hl, 0
jr _ioSeek
ioResetPC:
ld hl, 0
ld (IO_PC), hl
ret
; always in absolute mode (A = 0)
_ioSeek:
call ioInInclude

View File

@ -43,13 +43,11 @@
; that when we parse instructions and directive that error out because of a
; missing symbol, we don't error out and just write down a dummy value.
.equ ZASM_FIRST_PASS RAMSTART
; The offset where we currently are with regards to outputting opcodes
.equ ZASM_PC ZASM_FIRST_PASS+1
; whether we're in "local pass", that is, in local label scanning mode. During
; this special pass, ZASM_FIRST_PASS will also be set so that the rest of the
; code behaves as is we were in the first pass.
.equ ZASM_LOCAL_PASS ZASM_PC+2
; What ZASM_PC was when we started our context
.equ ZASM_LOCAL_PASS ZASM_FIRST_PASS+1
; What IO_PC was when we started our context
.equ ZASM_CTX_PC ZASM_LOCAL_PASS+1
.equ ZASM_RAMEND ZASM_CTX_PC+2
@ -109,21 +107,11 @@ zasmIsLocalPass:
cp 1
ret
; Increase (ZASM_PC) by A
incOutputOffset:
push de
ld de, (ZASM_PC)
call addDE
ld (ZASM_PC), de
pop de
ret
; 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
; be read (first line is 1).
zasmParseFile:
ld de, 0
ld (ZASM_PC), de
call ioResetPC
.loop:
call parseLine
ret nz ; error
@ -142,7 +130,7 @@ zasmParseFile:
ret
; Parse next token and accompanying args (when relevant) in I/O, write the
; resulting opcode(s) through ioPutC and increases (ZASM_PC) by the number of
; resulting opcode(s) through ioPutC and increases (IO_PC) by the number of
; bytes written. BC is set to the result of the call to tokenize.
; Sets Z if parse was successful, unset if there was an error. EOF is not an
; error.
@ -166,9 +154,6 @@ _parseInstr:
or a ; is zero?
jr z, .error
ld b, a ; save output byte count
call incOutputOffset
call zasmIsFirstPass
jr z, .success ; first pass, nothing to write
ld hl, instrUpcode
.loopInstr:
ld a, (hl)
@ -189,9 +174,6 @@ _parseDirec:
or a ; cp 0
jr z, .success ; if zero, shortcut through
ld b, a ; save output byte count
call incOutputOffset
call zasmIsFirstPass
jr z, .success ; first pass, nothing to write
ld hl, direcData
.loopDirec:
ld a, (hl)
@ -233,7 +215,7 @@ _parseLabel:
call _endLocalPass
jr .success
.registerLabel:
ld de, (ZASM_PC)
ld de, (IO_PC)
call symRegister
jr nz, .error
; continue to .success
@ -248,7 +230,7 @@ _beginLocalPass:
; remember were I/O was
call ioSavePos
; Remember where PC was
ld hl, (ZASM_PC)
ld hl, (IO_PC)
ld (ZASM_CTX_PC), hl
; Fake first pass
ld a, 1
@ -268,7 +250,7 @@ _endLocalPass:
call ioRecallPos
; recall PC
ld hl, (ZASM_CTX_PC)
ld (ZASM_PC), hl
ld (IO_PC), hl
; unfake first pass
xor a
ld (ZASM_FIRST_PASS), a