Thingamajig/examples/echo.asm

264 lines
5.9 KiB
NASM
Raw Normal View History

;String echo
;***
;Input
;Print a prompt
load r0, #3e
store ffff, r0
load r0, #20
store ffff, r0
;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
;Initialise the character counter
xor r0, r0
;Read a character
inloop: load r1, ffff
;Check for control characters and the buffer end
;Delete
load r2, #7f
breq r1, r2, delbr
;Escape
load r2, #1b
breq r1, r2, escbr
;Carriage return
load r2, #d
breq r1, r2, crbr
;Line feed
load r2, #a
breq r1, r2, lfbr
;Buffer end
load r2, bfsize
brneq r0, r2, chstor
;Backtrack if at the buffer end
load r2, #8
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, #1
cleq r0, r0, sum
;Store
xor r3, r3
xor r3, r0
;Increment the buffer address
;Low byte
load r0, chstor + 2
load r2, #1
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 an underscore
delbr: load r2, #5f
store ffff, r2
;Check for buffer start
xor r2, r2
breq r0, r2, inloop
;Decrement the character counter and store it in r3
;Decrement
load r2, #ff
cleq r0, r0, sum
;Store
xor r3, r3
xor r3, r0
;Decrement the buffer address
;High byte
load r0, chstor + 1
load r2, #ff
cleq r0, r0, sum
store chstor + 1, r0
;Low byte
load r0, chstor + 2
load r2, #ff
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, #20
store ffff, r0
load r0, #5c
store ffff, r0
;Newline
load r0, #d
store ffff, r0
load r0, #a
store ffff, r0
;Align
load r0, #20
store ffff, r0
store ffff, r0
;Start a new input line
breq r0, r0, input
;Print a line feed
crbr: load r0, #a
store ffff, r0
breq r0, r0, endnul
;Print a carriage return
lfbr: load r0, #d
store ffff, r0
;Store a carriage return in the buffer
;Get the buffer address
endnul: load r1, chstor + 1
store endsto + 1, r1
load r1, chstor + 2
store endsto + 2, r1
;Store
load r0, #d
endsto: store 0, r0
;Increment the buffer address
;Low byte
load r0, endsto + 2
load r2, #1
cleq r0, r0, sum
store endlf + 2, r0
;Add the overflow to the high byte
load r0, endsto + 1
xor r2, r2
xor r2, r1
cleq r0, r0, sum
store endlf + 1, r0
;Store a line feed in the buffer
load r0, #a
endlf: store 0, r0
;***
;Print
;Load a character from the buffer
chprnt: load r1, buffer
;Print the character
store ffff, r1
;Check for string end
load r2, #a
breq r1, r2, end
;Increment the buffer address
;Low byte
load r0, chprnt + 2
load r2, #1
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
;Halt
end: 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, 1
;Check for and store overflow if any
;Check
rol r1, 1
breq r1, r2, nvrflw
;Store
load r1, #1
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
;Variables
ovrflw: data 0
;Buffer
bfstrt: addr buffer
bfsize: data fe
buffer: