366 lines
No EOL
8.2 KiB
NASM
366 lines
No EOL
8.2 KiB
NASM
;ThingamaTerm: A simple terminal emulator
|
||
|
||
;***
|
||
|
||
;Check for input and incoming data
|
||
|
||
;Load the masks
|
||
check: load r2, #1
|
||
load r3, #20
|
||
|
||
;Load the input status
|
||
chklop: load r0, fff8
|
||
xor r1, r1
|
||
xor r1, r0
|
||
|
||
;Mask out unnecessary data
|
||
and r0, r2
|
||
and r1, r3
|
||
|
||
;Branch
|
||
breq r0, r2, input
|
||
breq r1, r3, recv
|
||
breq r0, r0, chklop
|
||
|
||
;***
|
||
|
||
;Input a line
|
||
|
||
;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
|
||
|
||
;Check for an initial end-of-file
|
||
load r1, ffff
|
||
load r2, #1a
|
||
brneq r1, r2, chknul
|
||
|
||
;Print a newline and halt
|
||
cleq r0, r0, newln
|
||
halt
|
||
|
||
;Read a character
|
||
inloop: load r1, ffff
|
||
|
||
;Check for control characters and the buffer end
|
||
;Null
|
||
chknul: load r2, #0
|
||
breq r1, r2, inloop
|
||
;FF
|
||
load r2, #ff
|
||
breq r1, r2, inloop
|
||
;Delete
|
||
load r2, #7f
|
||
breq r1, r2, delbr
|
||
;Escape
|
||
load r2, #1b
|
||
breq r1, r2, escbr
|
||
;End-of-file
|
||
load r2, #1a
|
||
breq r1, r2, eofbr
|
||
;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 and re-input the line
|
||
;Backslash
|
||
escbr: load r0, #20
|
||
store ffff, r0
|
||
load r0, #5c
|
||
store ffff, r0
|
||
;Newline
|
||
cleq r0, r0, newln
|
||
;Re-input the line
|
||
breq r0, r0, input
|
||
|
||
;Print a newline and exit input mode
|
||
eofbr: cleq r0, r0, newln
|
||
breq r0, r0, check
|
||
|
||
;Print a line feed
|
||
crbr: load r1, #a
|
||
store ffff, r1
|
||
breq r0, r0, endnl
|
||
|
||
;Print a carriage return and a null
|
||
lfbr: load r1, #d
|
||
store ffff, r1
|
||
load r1, #0
|
||
store ffff, r1
|
||
|
||
;Get the buffer address
|
||
endnl: load r1, chstor + 1
|
||
store endcr + 1, r1
|
||
load r1, chstor + 2
|
||
store endcr + 2, r1
|
||
|
||
;Store the CR of a newline in the buffer
|
||
load r0, #d
|
||
endcr: store 0, r0
|
||
|
||
;Increment the buffer address
|
||
;Load the address
|
||
load r0, chstor + 1
|
||
load r1, chstor + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store endlf + 1, r0
|
||
store endlf + 2, r1
|
||
|
||
;Store the LF of a newline in the buffer
|
||
load r0, #a
|
||
endlf: store 0, r0
|
||
|
||
;***
|
||
|
||
;Send the line
|
||
|
||
;Restore the buffer start address
|
||
;High byte
|
||
load r0, bfstrt
|
||
store lodmsg + 1, r0
|
||
;Low byte
|
||
load r0, bfstrt + 1
|
||
store lodmsg + 2, r0
|
||
|
||
;Send a character
|
||
;Send
|
||
lodmsg: load r0, 0
|
||
store fffa, r0
|
||
;Check for line feed
|
||
load r1, #a
|
||
breq r0, r1, check
|
||
|
||
;Increment the buffer address
|
||
load r0, lodmsg + 1
|
||
load r1, lodmsg + 2
|
||
cleq r0, r0, incdw
|
||
store lodmsg + 1, r0
|
||
store lodmsg + 2, r1
|
||
|
||
;Send the next character
|
||
breq r0, r0, lodmsg
|
||
|
||
;***
|
||
|
||
;Recieve a character
|
||
|
||
;Check for connection
|
||
recv: load r1, fff9
|
||
load r2, #1
|
||
brneq r1, r2, noconn
|
||
|
||
;Read and print a character
|
||
load r1, fffa
|
||
store ffff, r1
|
||
|
||
;Check for input and incoming data
|
||
breq r0, r0, check
|
||
|
||
;Print a newline and halt
|
||
noconn: cleq r0, r0, newln
|
||
halt
|
||
|
||
;***
|
||
|
||
;Print a newline
|
||
newln: load r0, #d
|
||
store ffff, r0
|
||
load r0, #a
|
||
store ffff, r0
|
||
ret
|
||
|
||
;***
|
||
|
||
;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
|
||
|
||
;***
|
||
|
||
;Increment a value stored in r0 and r1
|
||
|
||
;Store the high byte in r3
|
||
incdw: xor r3, r3
|
||
xor r3, r0
|
||
|
||
;Load the low byte to r0
|
||
xor r0, r0
|
||
xor r0, r1
|
||
|
||
;Increment the low byte
|
||
load r2, #1
|
||
cleq r0, r0, sum
|
||
|
||
;Load the high byte to r0 and store the low byte in r3
|
||
;Move the high byte to r2
|
||
xor r2, r2
|
||
xor r2, r3
|
||
;Store the low byte to r3
|
||
xor r3, r3
|
||
xor r3, r0
|
||
;Load the high byte to r0
|
||
xor r0, r0
|
||
xor r0, r2
|
||
|
||
;Add the overflow to the high byte
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
|
||
;Load the low byte in r1
|
||
xor r1, r1
|
||
xor r1, r3
|
||
|
||
;Return
|
||
ret
|
||
|
||
;***
|
||
|
||
;Data
|
||
|
||
;Ping
|
||
pingst: addr ping
|
||
ping: data 50
|
||
data 49
|
||
data 4e
|
||
data 47
|
||
data 20
|
||
data 3a
|
||
|
||
;Variables
|
||
ovrflw: data 0
|
||
|
||
;Buffer
|
||
bfstrt: addr buffer
|
||
bfsize: data fe
|
||
|
||
buffer:
|
||
|