264 lines
No EOL
6 KiB
NASM
264 lines
No EOL
6 KiB
NASM
;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
|
||
|
||
;Ignore the input and print an underscore if at the buffer end
|
||
load r2, #5f
|
||
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:
|
||
|