Thingamajig/examples/echo.asm

213 lines
4.6 KiB
NASM
Raw Normal View History

;String echo
;***
;Input
;Restore the buffer start address
;High byte
input: load r0, bfstrt
store chstor + 1, r0
;Low byte
load r0, bfstrt + 1
store chstor + 2, r0
;Print a prompt
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 control characters and the buffer end
;Escape
load r2, esc
breq r1, r2, escbr
;Carriage return
load r2, cr
breq r1, r2, crbr
;Buffer end
load r2, bfsize
brneq r0, r2, chstor
;Backtrack if at the buffer end
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 store it in r3
;Increment
load r2, one
cleq r0, r0, sum
;Store
xor r3, r3
xor r3, r0
;Increment the buffer address
;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
;Backslash
escbr: load r0, space
store ffff, r0
load r0, bslash
store ffff, r0
;Newline
load r0, cr
store ffff, r0
load r0, lf
store ffff, r0
;Start a new input line
breq r0, r0, input
;Store a string-terminating zero in the buffer
;Get the buffer address
crbr: load r1, chstor + 1
store endsto + 1, r1
load r1, chstor + 2
store endsto + 2, r1
;Store
xor r0, r0
endsto: store 0000, r0
;***
;Print
;Print a line feed and align with the input
;Line feed
load r0, lf
store ffff, r0
;Align
load r0, space
store ffff, r0
store ffff, r0
;Load a character from the buffer
chprnt: load r1, buffer
;Check for string end
xor r2, r2
breq r1, r2, end
;Print the character
store ffff, r1
;Increment the buffer address
;Low byte
load r0, chprnt + 2
load r2, one
cleq r0, r0, sum
store chprnt + 2, r0
;Add the overflow to the high byte
load r0, chprnt + 1
xor r2, r2
xor r2, r1
cleq r0, r0, sum
store chprnt + 1, r0
;Print the next character
breq r0, r0, chprnt
;Print a newline
end: 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
;Sum
xor r0, r2
;Carry
and r2, r1
;Copy the pre-shift carry
xor r1, r1
xor r1, r2
;Shift the carry
shl r2
;Check for and store overflow if any
;Check
rol r1
breq r1, r2, nvrflw
;Store
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
;***
;Data
;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
bfstrt: addr buffer
bfsize: data ff
buffer: