collapseos/apps/zasm/io.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

49 lines
908 B
NASM

; *** Variables ***
.equ IO_IN_GETC IO_RAMSTART
.equ IO_IN_PUTC IO_IN_GETC+2
.equ IO_IN_SEEK IO_IN_PUTC+2
.equ IO_IN_TELL IO_IN_SEEK+2
.equ IO_OUT_GETC IO_IN_TELL+2
.equ IO_OUT_PUTC IO_OUT_GETC+2
.equ IO_OUT_SEEK IO_OUT_PUTC+2
.equ IO_OUT_TELL IO_OUT_SEEK+2
; see ioPutBack below
.equ IO_PUTBACK_BUF IO_OUT_TELL+2
.equ IO_RAMEND IO_PUTBACK_BUF+1
; *** Code ***
ioInit:
xor a
ld (IO_PUTBACK_BUF), a
ret
ioGetC:
ld a, (IO_PUTBACK_BUF)
or a ; cp 0
jr nz, .getback
ld ix, (IO_IN_GETC)
jp (ix)
.getback:
push af
xor a
ld (IO_PUTBACK_BUF), a
pop af
ret
; Put back non-zero character A into the "ioGetC stack". The next ioGetC call,
; instead of reading from IO_IN_GETC, will return that character. That's the
; easiest way I found to handle the readWord/gotoNextLine problem.
ioPutBack:
ld (IO_PUTBACK_BUF), a
ret
ioPutC:
ld ix, (IO_OUT_PUTC)
jp (ix)
ioSeek:
ld ix, (IO_IN_SEEK)
jp (ix)