Thingamajig/examples/echo.asm

198 lines
4.5 KiB
NASM

;String echo
;Store the buffer start address in buffst
;High byte
load r0, chstor + 1
store buffst, r0
;Low byte
load r0, chstor + 2
store buffst + 1, r0
;Print a prompt
start: load r0, prompt
store ffff, r0
load r0, space
store ffff, r0
;Initialise the character counter
xor r0, r0
;Read a character
inloop: load r1, ffff
;Check for an escape
load r2, esc
breq r1, r2, escbr
;Check for a return
load r2, cr
breq r1, r2, inend
;Check for end of the buffer
load r2, buffsz
brneq r0, r2, chstor
;Backtrack if end of the buffer
load r2, bs
store ffff, r2
breq r0, r0, inloop
;Store the character in the buffer
chstor: store buffer, r1
;Increment the character counter and load it in r3
load r2, one
cleq r0, r0, sum
xor r3, r3
xor r3, r0
;Increment the buffer address
;High byte
load r0, chstor + 1
load r2, one
cleq r0, r0, sum
store chstor + 1, r0
;Low byte
load r0, chstor + 2
load r2, one
cleq r0, r0, sum
store chstor + 2, r0
;Add the overflow to the high byte
load r0, chstor + 1
xor r2, r2
xor r2, r1
cleq r0, r0, sum
store chstor + 1, r0
;Reload the character counter to r0
xor r0, r0
xor r0, r3
;Read the next character
breq r0, r0, inloop
;Print a backslash and a newline
escbr: load r0, space
store ffff, r0
load r0, bslash
store ffff, r0
load r0, cr
store ffff, r0
load r0, lf
store ffff, r0
;Restore the buffer address to its start
;High byte
load r0, buffst
store chstor + 1, r0
;Low byte
load r0, buffst + 1
store chstor + 2, r0
;Start a new input line
breq r0, r0, start
;Store a string-terminating zero in the buffer
inend: xor r0, r0
load r1, chstor + 1
store endsto + 1, r1
load r1, chstor + 2
store endsto + 2, r1
endsto: store 0000, r0
;Print a line feed and align with the input
load r0, lf
store ffff, r0
load r0, space
store ffff, r0
store ffff, r0
;Load a character from the buffer
outlop: load r1, buffer
;Check for string end
xor r2, r2
breq r1, r2, outend
;Print the character
store ffff, r1
;Increment the buffer address
;High byte
load r0, outlop + 1
load r2, one
cleq r0, r0, sum
store outlop + 1, r0
;Low byte
load r0, outlop + 2
load r2, one
cleq r0, r0, sum
store outlop + 2, r0
;Add the overflow to the high byte
load r0, outlop + 1
xor r2, r2
xor r2, r1
cleq r0, r0, sum
store outlop + 1, r0
;Print the next character
breq r0, r0, outlop
;Print a newline
outend: load r0, cr
store ffff, r0
load r0, lf
store ffff, r0
;Halt
halt
;Add r2 to r0 with the overflow stored in r1
;Reset overflow
sum: xor r1, r1
store ovrflw, r1
;Copy the first argument to r1
sumlop: xor r1, r1
xor r1, r0
;Calculate the sum and carry and copy the pre-shift carry to r1
xor r0, r2
and r2, r1
xor r1, r1
xor r1, r2
shl r2
;Check for overflow
rol r1
breq r1, r2, nvrflw
;Store overflow
load r1, one
store ovrflw, r1
;Check for no carry
nvrflw: xor r1, r1
breq r1, r2, sumend
;Loop
breq r0, r0, sumlop
;Load overflow and return
sumend: load r1, ovrflw
ret
;Constants
one: data 1
;Characters
bs: data 8
lf: data a
cr: data d
esc: data 1b
space: data 20
prompt: data 3e
bslash: data 5c
;Variables
ovrflw: data 0
;Buffer
buffst: data 0
data 0
buffsz: data f
buffer: