Thingamajig/examples/echo.asm

264 lines
5.9 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;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: