mirror of
https://github.com/hsoft/collapseos.git
synced 2024-12-24 14:28:06 +11:00
zasm: make io unit handle PC and output suppression
This commit is contained in:
parent
6547e83f20
commit
ad7428e471
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user