1931 lines
No EOL
47 KiB
NASM
1931 lines
No EOL
47 KiB
NASM
;Gidubba: A simple line editor
|
||
|
||
;***
|
||
|
||
;Check the RAM size
|
||
|
||
;Initialise the comparison value
|
||
load r0, #1b
|
||
|
||
;Check a memory location
|
||
mchks: store ffef, r0
|
||
mchkl: load r1, ffef
|
||
breq r0, r1, svlmit
|
||
|
||
;Decrement the pointer
|
||
load r0, mchks + 1
|
||
load r2, #fc
|
||
cleq r0, r0, sum
|
||
store mchks + 1, r0
|
||
store mchkl + 1, r0
|
||
|
||
;Check the next location
|
||
breq r0, r0, mchks
|
||
|
||
;Save the RAM limit
|
||
svlmit: load r0, mchks + 1
|
||
store limit, r0
|
||
|
||
;***
|
||
|
||
;Save an end-of-file at the start address
|
||
load r0, #1a
|
||
store buffer + 100, r0
|
||
|
||
;***
|
||
|
||
;Command prompt
|
||
cmdp: load r0, #3e
|
||
store ffff, r0
|
||
load r0, #20
|
||
store ffff, r0
|
||
|
||
;Input the command
|
||
cmdin: cleq r0, r0, input
|
||
|
||
;Check for control characters
|
||
;Escape
|
||
load r0, #1b
|
||
breq r0, r2, cmdesc
|
||
;End-of-file
|
||
load r0, #1a
|
||
breq r0, r2, end
|
||
|
||
;Initialise the command and argument
|
||
xor r0, r0
|
||
store cmd, r0
|
||
store argf1, r0
|
||
store argf2, r0
|
||
load r0, #30
|
||
store arg1, r0
|
||
store arg1 + 1, r0
|
||
store arg1 + 2, r0
|
||
store arg1 + 3, r0
|
||
store arg2, r0
|
||
store arg2 + 1, r0
|
||
|
||
;Parse the command and its first argument
|
||
;Command
|
||
load r0, buffer
|
||
store cmd, r0
|
||
;Load carriage return and hash
|
||
load r1, #d
|
||
load r2, #23
|
||
;Check for no command
|
||
breq r0, r1, cmdp
|
||
;First digit
|
||
load r0, buffer + 1
|
||
breq r0, r1, chkcmd
|
||
load r3, #1
|
||
store argf1, r3
|
||
breq r0, r2, hsharg
|
||
load r3, arg1d2 + 1
|
||
store arg2d1 + 1, r3
|
||
load r3, arg1d2 + 2
|
||
store arg2d1 + 2, r3
|
||
load r3, #2c
|
||
breq r0, r3, 2ndarg
|
||
store arg1 + 3, r0
|
||
;Second digit
|
||
arg1d2: load r0, buffer + 2
|
||
breq r0, r1, getarg
|
||
load r3, arg1d3 + 1
|
||
store arg2d1 + 1, r3
|
||
load r3, arg1d3 + 2
|
||
store arg2d1 + 2, r3
|
||
load r3, #2c
|
||
breq r0, r3, 2ndarg
|
||
load r2, arg1 + 3
|
||
store arg1 + 2, r2
|
||
store arg1 + 3, r0
|
||
;Third digit
|
||
arg1d3: load r0, buffer + 3
|
||
breq r0, r1, getarg
|
||
load r3, arg1d4 + 1
|
||
store arg2d1 + 1, r3
|
||
load r3, arg1d4 + 2
|
||
store arg2d1 + 2, r3
|
||
load r3, #2c
|
||
breq r0, r3, 2ndarg
|
||
load r2, arg1 + 2
|
||
store arg1 + 1, r2
|
||
load r2, arg1 + 3
|
||
store arg1 + 2, r2
|
||
store arg1 + 3, r0
|
||
;Fourth digit
|
||
arg1d4: load r0, buffer + 4
|
||
breq r0, r1, getarg
|
||
load r3, arg1d5 + 1
|
||
store arg2d1 + 1, r3
|
||
load r3, arg1d5 + 2
|
||
store arg2d1 + 2, r3
|
||
load r3, #2c
|
||
breq r0, r3, 2ndarg
|
||
load r2, arg1 + 1
|
||
store arg1, r2
|
||
load r2, arg1 + 2
|
||
store arg1 + 1, r2
|
||
load r2, arg1 + 3
|
||
store arg1 + 2, r2
|
||
store arg1 + 3, r0
|
||
;Check for command end
|
||
load r0, arg1d5 + 1
|
||
load r1, arg1d5 + 2
|
||
cleq r0, r0, incdw
|
||
store arg2d1 + 1, r0
|
||
store arg2d1 + 2, r1
|
||
load r1, #d
|
||
arg1d5: load r0, buffer + 5
|
||
breq r0, r1, getarg
|
||
load r3, #2c
|
||
breq r0, r3, 2ndarg
|
||
breq r0, r0, cmderr
|
||
|
||
;Parse the second argument
|
||
;Set the addresses
|
||
2ndarg: load r0, arg2d1 + 1
|
||
load r1, arg2d1 + 2
|
||
cleq r0, r0, incdw
|
||
store arg2d2 + 1, r0
|
||
store arg2d2 + 2, r1
|
||
cleq r0, r0, incdw
|
||
store arg2d3 + 1, r0
|
||
store arg2d3 + 2, r1
|
||
;Load carriage return
|
||
load r1, #d
|
||
;First digit
|
||
arg2d1: load r0, 0
|
||
breq r0, r1, chkcmd
|
||
load r3, #1
|
||
store argf2, r3
|
||
store arg2 + 1, r0
|
||
;Second digit
|
||
arg2d2: load r0, 0
|
||
breq r0, r1, getarg
|
||
load r2, arg2 + 1
|
||
store arg2, r2
|
||
store arg2 + 1, r0
|
||
;Check for command end
|
||
arg2d3: load r0, 0
|
||
breq r0, r1, getarg
|
||
breq r0, r0, cmderr
|
||
|
||
;Hash is a shortcut for FFFF
|
||
;Check for command end
|
||
hsharg: load r0, buffer + 2
|
||
brneq r0, r1, cmderr
|
||
;Save FFFF
|
||
xor r0, r0
|
||
nand r0, r0
|
||
store target, r0
|
||
store target + 1, r0
|
||
breq r0, r0, chkcmd
|
||
|
||
;Get the value of the first argument
|
||
;First digit
|
||
getarg: load r0, arg1
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
xor r2, r2
|
||
xor r2, r0
|
||
shl r2, 4
|
||
;Second digit
|
||
load r0, arg1 + 1
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
;Combine and store the first and second digits
|
||
or r0, r2
|
||
store target, r0
|
||
;Third digit
|
||
load r0, arg1 + 2
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
xor r2, r2
|
||
xor r2, r0
|
||
shl r2, 4
|
||
;Fourth digit
|
||
load r0, arg1 + 3
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
;Combine and store the third and fourth digits
|
||
or r0, r2
|
||
store target + 1, r0
|
||
|
||
;Get the value of the second argument
|
||
;First digit
|
||
load r0, arg2
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
xor r2, r2
|
||
xor r2, r0
|
||
shl r2, 4
|
||
;Second digit
|
||
load r0, arg2 + 1
|
||
cleq r0, r0, hex2n
|
||
load r1, #3f
|
||
breq r0, r1, cmderr
|
||
;Combine and store the first and second digits
|
||
or r0, r2
|
||
store count, r0
|
||
|
||
;Check for commands
|
||
;Load the command
|
||
chkcmd: load r0, cmd
|
||
;Check for no argument
|
||
load r2, argf1
|
||
xor r3, r3
|
||
breq r2, r3, cnarg
|
||
;Check for single argument
|
||
load r2, argf2
|
||
xor r3, r3
|
||
breq r2, r3, onearg
|
||
;Copy to mark
|
||
load r1, #43
|
||
breq r0, r1, copy
|
||
load r1, #63
|
||
breq r0, r1, copy
|
||
;Delete
|
||
load r1, #44
|
||
breq r0, r1, delete
|
||
load r1, #64
|
||
breq r0, r1, delete
|
||
;List
|
||
load r1, #4c
|
||
breq r0, r1, list
|
||
load r1, #6c
|
||
breq r0, r1, list
|
||
;Branch to error
|
||
breq r0, r0, cmderr
|
||
;Insert
|
||
onearg: load r1, #49
|
||
breq r0, r1, insln
|
||
load r1, #69
|
||
breq r0, r1, insln
|
||
;Set a mark
|
||
load r1, #4d
|
||
breq r0, r1, setmrk
|
||
load r1, #6d
|
||
breq r0, r1, setmrk
|
||
;Branch to error
|
||
breq r0, r0, cmderr
|
||
;Print
|
||
cnarg: load r1, #50
|
||
breq r0, r1, print
|
||
load r1, #70
|
||
breq r0, r1, print
|
||
;Write to tape
|
||
load r1, #57
|
||
breq r0, r1, write
|
||
load r1, #77
|
||
breq r0, r1, write
|
||
;Read from tape
|
||
load r1, #52
|
||
breq r0, r1, read
|
||
load r1, #72
|
||
breq r0, r1, read
|
||
|
||
;Print an error and return to the command prompt
|
||
cmderr: load r0, #3f
|
||
store ffff, r0
|
||
cleq r0, r0, newln
|
||
breq r0, r0, cmdp
|
||
|
||
cmdesc: load r0, #20
|
||
store ffff, r0
|
||
store ffff, r0
|
||
breq r0, r0, cmdin
|
||
|
||
;***
|
||
|
||
;Insert a line
|
||
|
||
;Reset the line number
|
||
insln: xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Find the argument line in the save and store its number
|
||
nextln: cleq r0, r0, fend
|
||
|
||
;Print a line number prompt
|
||
instrt: cleq r0, r0, prnln
|
||
|
||
;Input the line
|
||
inline: cleq r0, r0, input
|
||
|
||
;Check for control characters
|
||
;Escape
|
||
load r0, #1b
|
||
breq r0, r2, inesc
|
||
;End-of-file
|
||
load r0, #1a
|
||
breq r0, r2, cmdp
|
||
|
||
;Increment the line number
|
||
;Load the number
|
||
load r0, lnnum
|
||
load r1, lnnum + 1
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the number
|
||
store target, r0
|
||
store target + 1, r1
|
||
|
||
;Store the save address
|
||
;High byte
|
||
load r3, eoflod + 1
|
||
store eofchk + 1, r3
|
||
store cmpadr, r3
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store eofchk + 2, r0
|
||
store cmpadr + 1, r0
|
||
|
||
;Make room for the line
|
||
cleq r0, r0, eofchk
|
||
xor r0, r0
|
||
brneq r0, r1, cmdp
|
||
|
||
;Restore the buffer start address
|
||
;High byte
|
||
load r0, bfstrt
|
||
store chload + 1, r0
|
||
;Low byte
|
||
load r0, bfstrt + 1
|
||
store chload + 2, r0
|
||
|
||
;Store the save address
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store chsave + 1, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store chsave + 2, r0
|
||
|
||
;Load and save a character from the buffer
|
||
;Load
|
||
chload: load r1, buffer
|
||
;Save
|
||
chsave: store buffer + 100, r1
|
||
|
||
;Check for line end
|
||
load r2, #a
|
||
breq r1, r2, nextln
|
||
|
||
;Increment the buffer address
|
||
;Load the address
|
||
load r0, chload + 1
|
||
load r1, chload + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chload + 1, r0
|
||
store chload + 2, r1
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
load r0, chsave + 1
|
||
load r1, chsave + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chsave + 1, r0
|
||
store chsave + 2, r1
|
||
|
||
;Load and save the next character
|
||
breq r0, r0, chload
|
||
|
||
inesc: load r0, #20
|
||
store ffff, r0
|
||
store ffff, r0
|
||
store ffff, r0
|
||
store ffff, r0
|
||
store ffff, r0
|
||
store ffff, r0
|
||
breq r0, r0, inline
|
||
|
||
;***
|
||
|
||
;Set a mark for copying
|
||
setmrk: load r0, target
|
||
store mark, r0
|
||
load r0, target + 1
|
||
store mark + 1, r0
|
||
breq r0, r0, cmdp
|
||
|
||
;***
|
||
|
||
;Copy to mark
|
||
|
||
;Check for an empty counter
|
||
copy: xor r0, r0
|
||
load r1, count
|
||
breq r0, r1, cmdp
|
||
|
||
;Reset the line number
|
||
xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Find the argument line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Get the save address of the line
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store strsz, r0
|
||
store chsend + 1, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store strsz + 1, r0
|
||
store chsend + 2, r0
|
||
|
||
;Check for the save end
|
||
chsend: load r0, 0
|
||
load r1, #1a
|
||
breq r0, r1, cmdp
|
||
|
||
;Save the buffer address to tmp1 and increment it
|
||
;Low byte
|
||
load r0, target + 1
|
||
store tmp1 + 1, r0
|
||
load r2, count
|
||
cleq r0, r0, sum
|
||
store target + 1, r0
|
||
;Add the overflow to the high byte
|
||
load r0, target
|
||
store tmp1, r0
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store target, r0
|
||
|
||
;Find the next line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Get the save address of the line
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store tmp2, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store tmp2 + 1, r0
|
||
|
||
;Negate the first address
|
||
;Low byte
|
||
load r0, strsz + 1
|
||
nand r0, r0
|
||
load r2, #1
|
||
cleq r0, r0, sum
|
||
store strsz + 1, r0
|
||
;Reverse and add the overflow to the high byte
|
||
load r0, strsz
|
||
nand r0, r0
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store strsz, r0
|
||
|
||
;Get the copy length
|
||
;High byte
|
||
load r0, tmp2
|
||
load r2, strsz
|
||
cleq r0, r0, sum
|
||
store strsz, r0
|
||
;Low byte
|
||
load r0, tmp2 + 1
|
||
load r2, strsz + 1
|
||
cleq r0, r0, sum
|
||
store strsz + 1, r0
|
||
;Reverse and add the overflow to the high byte
|
||
load r0, strsz
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store strsz, r0
|
||
|
||
;Load the mark to target
|
||
load r0, mark
|
||
store target, r0
|
||
load r0, mark + 1
|
||
store target + 1, r0
|
||
|
||
;Reset the line number
|
||
xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Find the marked line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Store the save address
|
||
;High byte
|
||
load r3, eoflod + 1
|
||
store eofchk + 1, r3
|
||
store cmpadr, r3
|
||
store cstor + 1, r3
|
||
store cinit + 1, r3
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store eofchk + 2, r0
|
||
store cmpadr + 1, r0
|
||
store cstor + 2, r0
|
||
store cinit + 2, r0
|
||
|
||
;Make room for the copy
|
||
cleq r0, r0, eofchk
|
||
xor r0, r0
|
||
brneq r0, r1, cmdp
|
||
|
||
;Check for the end of the space
|
||
cendsp: load r0, movsto + 1
|
||
load r1, cinit + 1
|
||
brneq r0, r1, cinist
|
||
load r0, movsto + 2
|
||
load r1, cinit + 2
|
||
brneq r0, r1, cinist
|
||
breq r0, r1, relodt
|
||
|
||
;Initialise a character
|
||
cinist: load r0, #0
|
||
cinit: store 0, r0
|
||
|
||
;Increment the source address
|
||
;Load the address
|
||
incini: load r0, cinit + 1
|
||
load r1, cinit + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store cinit + 1, r0
|
||
store cinit + 2, r1
|
||
|
||
;Initialise the next character
|
||
breq r0, r0, cendsp
|
||
|
||
;Reload the target from tmp1
|
||
relodt: load r0, tmp1
|
||
store target, r0
|
||
load r0, tmp1 + 1
|
||
store target + 1, r0
|
||
|
||
;Reset the line number
|
||
xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Find the marked line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Store the save address
|
||
;High byte
|
||
load r3, eoflod + 1
|
||
store cload + 1, r3
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store cload + 2, r0
|
||
|
||
;Copy a character
|
||
;Load
|
||
cload: load r1, 0
|
||
;Check for a null
|
||
xor r2, r2
|
||
breq r1, r2, skip0
|
||
;Check for save end
|
||
load r2, #1a
|
||
breq r1, r2, cmdp
|
||
;Save
|
||
cstor: store 0, r1
|
||
|
||
;Check for line end
|
||
load r2, #a
|
||
brneq r1, r2, cincs
|
||
|
||
;Decrement the counter
|
||
load r0, count
|
||
load r2, #ff
|
||
cleq r0, r0, sum
|
||
store count, r0
|
||
|
||
;Check the counter
|
||
xor r0, r0
|
||
load r1, count
|
||
breq r0, r1, cmdp
|
||
|
||
;Increment the source address
|
||
;Load the address
|
||
cincs: load r0, cload + 1
|
||
load r1, cload + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store cload + 1, r0
|
||
store cload + 2, r1
|
||
|
||
;Increment the copy address
|
||
;Load the address
|
||
load r0, cstor + 1
|
||
load r1, cstor + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store cstor + 1, r0
|
||
store cstor + 2, r1
|
||
|
||
;Load and save the next character
|
||
breq r0, r0, cload
|
||
|
||
;Increment the source address
|
||
;Load the address
|
||
skip0: load r0, cload + 1
|
||
load r1, cload + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store cload + 1, r0
|
||
store cload + 2, r1
|
||
|
||
;Load the next character
|
||
breq r0, r0, cload
|
||
|
||
;***
|
||
|
||
;Delete a line
|
||
|
||
;Check for an empty counter
|
||
delete: xor r0, r0
|
||
load r1, count
|
||
breq r0, r1, cmdp
|
||
|
||
;Reset the line number
|
||
xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Find the argument line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Get the save address of the line
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store stomov + 1, r0
|
||
store dchend + 1, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store stomov + 2, r0
|
||
store dchend + 2, r0
|
||
|
||
;Check for the save end
|
||
dchend: load r0, 0
|
||
load r1, #1a
|
||
breq r0, r1, cmdp
|
||
|
||
;Increment the buffer address
|
||
;Low byte
|
||
load r0, target + 1
|
||
load r2, count
|
||
cleq r0, r0, sum
|
||
store target + 1, r0
|
||
;Add the overflow to the high byte
|
||
load r0, target
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store target, r0
|
||
|
||
;Find the next line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Get the save address of the line
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store lodmov + 1, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store lodmov + 2, r0
|
||
|
||
;Move the remainder of the text back
|
||
lodmov: load r0, 0
|
||
stomov: store 0, r0
|
||
|
||
;Check for the save end
|
||
load r1, #1a
|
||
breq r0, r1, delend
|
||
|
||
;Increment the first save address
|
||
;Load the address
|
||
load r0, stomov + 1
|
||
load r1, stomov + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store stomov + 1, r0
|
||
store stomov + 2, r1
|
||
|
||
;Increment the second save address
|
||
;Load the address
|
||
load r0, lodmov + 1
|
||
load r1, lodmov + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store lodmov + 1, r0
|
||
store lodmov + 2, r1
|
||
|
||
;Move the next character
|
||
breq r0, r0, lodmov
|
||
|
||
;Return to the command prompt
|
||
delend: breq r0, r0, cmdp
|
||
|
||
;***
|
||
|
||
;List a line
|
||
|
||
;Reset the line number
|
||
list: xor r0, r0
|
||
store lnnum, r0
|
||
store lnnum + 1, r0
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
load r0, svstrt
|
||
store eoflod + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store eoflod + 2, r0
|
||
|
||
;Check the counter
|
||
lcount: xor r0, r0
|
||
load r1, count
|
||
breq r0, r1, cmdp
|
||
|
||
;Find the argument line in the save and store its number
|
||
cleq r0, r0, fend
|
||
|
||
;Get the save address of the line
|
||
;High byte
|
||
load r0, eoflod + 1
|
||
store chlist + 1, r0
|
||
store lchend + 1, r0
|
||
;Low byte
|
||
load r0, eoflod + 2
|
||
store chlist + 2, r0
|
||
store lchend + 2, r0
|
||
|
||
;Check for the save end
|
||
lchend: load r0, 0
|
||
load r1, #1a
|
||
breq r0, r1, cmdp
|
||
|
||
;Print a line number prompt
|
||
cleq r0, r0, prnln
|
||
|
||
;Load a character from the save
|
||
chlist: load r1, 0
|
||
|
||
;Check for the save end
|
||
load r2, #1a
|
||
breq r1, r2, prnwln
|
||
|
||
;Print the character
|
||
store ffff, r1
|
||
|
||
;Check for the line end
|
||
load r2, #a
|
||
breq r1, r2, lstend
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
load r0, chlist + 1
|
||
load r1, chlist + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chlist + 1, r0
|
||
store chlist + 2, r1
|
||
|
||
;Print the next character
|
||
breq r0, r0, chlist
|
||
|
||
;Print a newline
|
||
prnwln: cleq r0, r0, newln
|
||
|
||
;Loop
|
||
;Decrement the counter
|
||
lstend: load r0, count
|
||
load r2, #ff
|
||
cleq r0, r0, sum
|
||
store count, r0
|
||
;Increment the line number
|
||
load r0, target
|
||
load r1, target + 1
|
||
cleq r0, r0, incdw
|
||
store target, r0
|
||
store target + 1, r1
|
||
;Loop
|
||
breq r0, r0, lcount
|
||
|
||
;***
|
||
|
||
;Print the text
|
||
|
||
;Get the printer address
|
||
;High byte
|
||
print: load r0, #ff
|
||
store prwrch + 1, r0
|
||
;Low byte
|
||
load r0, #fe
|
||
store prwrch + 2, r0
|
||
|
||
;Print
|
||
cleq r0, r0, prwr
|
||
|
||
;Return to the command prompt
|
||
breq r0, r0, cmdp
|
||
|
||
;***
|
||
|
||
;Write the text to the tape punch
|
||
|
||
;Get the tape punch address
|
||
;High byte
|
||
write: load r0, #ff
|
||
store prwrch + 1, r0
|
||
;Low byte
|
||
load r0, #fd
|
||
store prwrch + 2, r0
|
||
|
||
;Write
|
||
cleq r0, r0, prwr
|
||
|
||
;Return to the command prompt
|
||
breq r0, r0, cmdp
|
||
|
||
;***
|
||
|
||
;Read the text from the tape reader
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
read: load r0, svstrt
|
||
store chrsto + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store chrsto + 2, r0
|
||
|
||
;Ignore the leader
|
||
iglead: load r1, fffd
|
||
xor r2, r2
|
||
breq r1, r2, iglead
|
||
breq r0, r0, chkend
|
||
|
||
;Check for the RAM limit
|
||
load r0, chrsto + 1
|
||
load r1, chrsto + 2
|
||
chkram: cleq r0, r0, ramchk
|
||
xor r2, r2
|
||
brneq r1, r2, cmdp
|
||
|
||
;Read a character
|
||
chread: load r1, fffd
|
||
|
||
;Check for trailer or empty tape reader
|
||
;Trailer
|
||
chkend: xor r2, r2
|
||
brneq r1, r2, chkntp
|
||
load r1, #1a
|
||
breq r0, r0, chrsto
|
||
;Empty tape reader
|
||
chkntp: nand r2, r2
|
||
brneq r1, r2, chklf
|
||
load r1, #1a
|
||
breq r0, r0, chrsto
|
||
|
||
;Check for a line feed
|
||
chklf: load r2, #a
|
||
load r3, #0
|
||
brneq r1, r2, chrsto
|
||
load r1, #d
|
||
load r3, #a
|
||
|
||
;Store a character
|
||
chrsto: store buffer + 100, r1
|
||
|
||
;Check for a newline
|
||
;Line feed
|
||
load r2, #a
|
||
breq r2, r3, readlf
|
||
;Carriage return
|
||
load r2, #d
|
||
breq r1, r2, readcr
|
||
|
||
;Check for the save end
|
||
load r2, #1a
|
||
breq r1, r2, redend
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
load r0, chrsto + 1
|
||
load r1, chrsto + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chrsto + 1, r0
|
||
store chrsto + 2, r1
|
||
|
||
;Read the next character
|
||
breq r0, r0, chkram
|
||
|
||
;Read a newline beginning with a carriage return
|
||
readcr: cleq r0, r0, readnl
|
||
|
||
;Check for a line feed
|
||
load r2, #a
|
||
breq r1, r2, chread
|
||
breq r0, r0, chkend
|
||
|
||
;Read a newline beginning with a line feed
|
||
readlf: cleq r0, r0, readnl
|
||
|
||
;Check for a carriage return
|
||
load r2, #d
|
||
breq r1, r2, chread
|
||
breq r0, r0, chkend
|
||
|
||
;Return to the command prompt
|
||
redend: breq r0, r0, cmdp
|
||
|
||
;***
|
||
|
||
;Halt
|
||
end: 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
|
||
|
||
;***
|
||
|
||
;Decrement a value stored in r0 and r1
|
||
|
||
;Store the low byte in r3
|
||
decdw: xor r3, r3
|
||
xor r3, r1
|
||
|
||
;Decrement the high byte
|
||
load r2, #ff
|
||
cleq r0, r0, sum
|
||
|
||
;Load the low byte to r0 and store the high byte in r3
|
||
;Move the low byte to r2
|
||
xor r2, r2
|
||
xor r2, r3
|
||
;Store the high byte to r3
|
||
xor r3, r3
|
||
xor r3, r0
|
||
;Load the low byte to r0
|
||
xor r0, r0
|
||
xor r0, r2
|
||
|
||
;Decrement the low byte
|
||
load r2, #ff
|
||
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
|
||
|
||
;***
|
||
|
||
;Get the hexadecimal digit of a nibble
|
||
|
||
;Extract the low nibble
|
||
n2hex: load r1, #f
|
||
and r0, r1
|
||
|
||
;Get the nibble value
|
||
load r1, #0
|
||
breq r0, r1, dgt0
|
||
load r1, #1
|
||
breq r0, r1, dgt1
|
||
load r1, #2
|
||
breq r0, r1, dgt2
|
||
load r1, #3
|
||
breq r0, r1, dgt3
|
||
load r1, #4
|
||
breq r0, r1, dgt4
|
||
load r1, #5
|
||
breq r0, r1, dgt5
|
||
load r1, #6
|
||
breq r0, r1, dgt6
|
||
load r1, #7
|
||
breq r0, r1, dgt7
|
||
load r1, #8
|
||
breq r0, r1, dgt8
|
||
load r1, #9
|
||
breq r0, r1, dgt9
|
||
load r1, #a
|
||
breq r0, r1, dgta
|
||
load r1, #b
|
||
breq r0, r1, dgtb
|
||
load r1, #c
|
||
breq r0, r1, dgtc
|
||
load r1, #d
|
||
breq r0, r1, dgtd
|
||
load r1, #e
|
||
breq r0, r1, dgte
|
||
load r1, #f
|
||
breq r0, r1, dgtf
|
||
|
||
;Load the hexadecimal digit of the nibble
|
||
dgt0: load r0, #30
|
||
breq r0, r0, n2hend
|
||
dgt1: load r0, #31
|
||
breq r0, r0, n2hend
|
||
dgt2: load r0, #32
|
||
breq r0, r0, n2hend
|
||
dgt3: load r0, #33
|
||
breq r0, r0, n2hend
|
||
dgt4: load r0, #34
|
||
breq r0, r0, n2hend
|
||
dgt5: load r0, #35
|
||
breq r0, r0, n2hend
|
||
dgt6: load r0, #36
|
||
breq r0, r0, n2hend
|
||
dgt7: load r0, #37
|
||
breq r0, r0, n2hend
|
||
dgt8: load r0, #38
|
||
breq r0, r0, n2hend
|
||
dgt9: load r0, #39
|
||
breq r0, r0, n2hend
|
||
dgta: load r0, #41
|
||
breq r0, r0, n2hend
|
||
dgtb: load r0, #42
|
||
breq r0, r0, n2hend
|
||
dgtc: load r0, #43
|
||
breq r0, r0, n2hend
|
||
dgtd: load r0, #44
|
||
breq r0, r0, n2hend
|
||
dgte: load r0, #45
|
||
breq r0, r0, n2hend
|
||
dgtf: load r0, #46
|
||
breq r0, r0, n2hend
|
||
|
||
;Return
|
||
n2hend: ret
|
||
|
||
;***
|
||
|
||
;Get the nibble of a hexadecimal digit
|
||
|
||
;Get the nibble value
|
||
;Numeric digits
|
||
hex2n: load r1, #30
|
||
breq r0, r1, nbl0
|
||
load r1, #31
|
||
breq r0, r1, nbl1
|
||
load r1, #32
|
||
breq r0, r1, nbl2
|
||
load r1, #33
|
||
breq r0, r1, nbl3
|
||
load r1, #34
|
||
breq r0, r1, nbl4
|
||
load r1, #35
|
||
breq r0, r1, nbl5
|
||
load r1, #36
|
||
breq r0, r1, nbl6
|
||
load r1, #37
|
||
breq r0, r1, nbl7
|
||
load r1, #38
|
||
breq r0, r1, nbl8
|
||
load r1, #39
|
||
breq r0, r1, nbl9
|
||
;Uppercase letter digits
|
||
load r1, #41
|
||
breq r0, r1, nbla
|
||
load r1, #42
|
||
breq r0, r1, nblb
|
||
load r1, #43
|
||
breq r0, r1, nblc
|
||
load r1, #44
|
||
breq r0, r1, nbld
|
||
load r1, #45
|
||
breq r0, r1, nble
|
||
load r1, #46
|
||
breq r0, r1, nblf
|
||
;Lowercase letter digits
|
||
load r1, #61
|
||
breq r0, r1, nbla
|
||
load r1, #62
|
||
breq r0, r1, nblb
|
||
load r1, #63
|
||
breq r0, r1, nblc
|
||
load r1, #64
|
||
breq r0, r1, nbld
|
||
load r1, #65
|
||
breq r0, r1, nble
|
||
load r1, #66
|
||
breq r0, r1, nblf
|
||
;Load a question mark if the character is not a digit
|
||
load r0, #3f
|
||
breq r0, r0, h2nend
|
||
|
||
;Load the hexadecimal digit of the nibble
|
||
nbl0: load r0, #0
|
||
breq r0, r0, h2nend
|
||
nbl1: load r0, #1
|
||
breq r0, r0, h2nend
|
||
nbl2: load r0, #2
|
||
breq r0, r0, h2nend
|
||
nbl3: load r0, #3
|
||
breq r0, r0, h2nend
|
||
nbl4: load r0, #4
|
||
breq r0, r0, h2nend
|
||
nbl5: load r0, #5
|
||
breq r0, r0, h2nend
|
||
nbl6: load r0, #6
|
||
breq r0, r0, h2nend
|
||
nbl7: load r0, #7
|
||
breq r0, r0, h2nend
|
||
nbl8: load r0, #8
|
||
breq r0, r0, h2nend
|
||
nbl9: load r0, #9
|
||
breq r0, r0, h2nend
|
||
nbla: load r0, #a
|
||
breq r0, r0, h2nend
|
||
nblb: load r0, #b
|
||
breq r0, r0, h2nend
|
||
nblc: load r0, #c
|
||
breq r0, r0, h2nend
|
||
nbld: load r0, #d
|
||
breq r0, r0, h2nend
|
||
nble: load r0, #e
|
||
breq r0, r0, h2nend
|
||
nblf: load r0, #f
|
||
breq r0, r0, h2nend
|
||
|
||
;Return
|
||
h2nend: ret
|
||
|
||
;***
|
||
|
||
;Get the hexadecimal digits of a byte
|
||
|
||
;Load the byte to to r2
|
||
bt2hex: xor r2, r2
|
||
xor r2, r0
|
||
|
||
;Convert the low nibble to a digit and store it in r2
|
||
;Convert
|
||
cleq r0, r0, n2hex
|
||
;Store
|
||
xor r1, r1
|
||
xor r1, r0
|
||
|
||
;Re-load the byte to r0
|
||
xor r0, r0
|
||
xor r0, r2
|
||
|
||
;Store the low nibble in r2
|
||
xor r2, r2
|
||
xor r2, r1
|
||
|
||
;Convert the high nibble to a digit
|
||
ror r0, 4
|
||
cleq r0, r0, n2hex
|
||
|
||
;Load the digit of the low nibble to r1
|
||
xor r1, r1
|
||
xor r1, r2
|
||
|
||
;Return
|
||
ret
|
||
|
||
;***
|
||
|
||
;Input a character
|
||
|
||
;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
|
||
;Null
|
||
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
|
||
|
||
;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
|
||
cleq r0, r0, newln
|
||
|
||
;Return with escape in r2
|
||
ret
|
||
|
||
;Print a newline
|
||
eofbr: cleq r0, r0, newln
|
||
|
||
;Return with End-of-file at r2
|
||
ret
|
||
|
||
;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
|
||
|
||
;Increment and store the string size
|
||
endnl: load r2, #2
|
||
cleq r0, r0, sum
|
||
store strsz + 1, r0
|
||
load r0, #0
|
||
store strsz, r0
|
||
|
||
;Get the buffer address
|
||
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
|
||
|
||
;Return
|
||
ret
|
||
|
||
;***
|
||
|
||
;Make room for the line
|
||
|
||
;Find the end of the save address
|
||
;Check for an end-of-file
|
||
eofchk: load r0, 0
|
||
load r1, #1a
|
||
breq r0, r1, endfnd
|
||
;Load the address
|
||
load r0, eofchk + 1
|
||
load r1, eofchk + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store eofchk + 1, r0
|
||
store eofchk + 2, r1
|
||
;Check the next character
|
||
breq r0, r0, eofchk
|
||
|
||
;Store the end of the save address
|
||
;High byte
|
||
endfnd: load r0, eofchk + 1
|
||
store movlod + 1, r0
|
||
;Low byte
|
||
load r3, eofchk + 2
|
||
store movlod + 2, r3
|
||
|
||
;Calculate the new end of the save
|
||
;High byte
|
||
load r2, strsz
|
||
cleq r0, r0, sum
|
||
store strsz, r0
|
||
;Check for overflow from the high byte
|
||
xor r0, r0
|
||
brneq r0, r1, lmterr
|
||
;Low byte
|
||
xor r0, r0
|
||
xor r0, r3
|
||
load r2, strsz + 1
|
||
cleq r0, r0, sum
|
||
store strsz + 1, r0
|
||
;Add the overflow to the high byte
|
||
load r0, strsz
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
;Store the new end of the save
|
||
store movsto + 1, r0
|
||
load r3, strsz + 1
|
||
store movsto + 2, r3
|
||
;Check for overflow from the high byte
|
||
xor r0, r0
|
||
brneq r0, r1, lmterr
|
||
|
||
;Negate the RAM limit
|
||
;Low byte
|
||
load r0, limit + 1
|
||
nand r0, r0
|
||
load r2, #1
|
||
cleq r0, r0, sum
|
||
store tmp2 + 1, r0
|
||
;Reverse and add the overflow to the high byte
|
||
load r0, limit
|
||
nand r0, r0
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store tmp2, r0
|
||
|
||
;Subtract the RAM limit from the new end of the save
|
||
;High byte
|
||
load r0, movsto + 1
|
||
load r2, tmp2
|
||
cleq r0, r0, sum
|
||
store tmp2, r0
|
||
;Check for overflow from the high byte
|
||
xor r0, r0
|
||
brneq r0, r1, lmterr
|
||
;Low byte
|
||
load r0, movsto + 2
|
||
load r2, tmp2 + 1
|
||
cleq r0, r0, sum
|
||
store tmp2 + 1, r0
|
||
;Add the overflow to the high byte
|
||
load r0, tmp2
|
||
xor r2, r2
|
||
xor r2, r1
|
||
cleq r0, r0, sum
|
||
store tmp2, r0
|
||
;Check for overflow from the high byte
|
||
xor r0, r0
|
||
brneq r0, r1, lmterr
|
||
|
||
;Move the End-of-file
|
||
movlod: load r0, 0
|
||
movsto: store 0, r0
|
||
|
||
;Check for the address of the new line
|
||
load r0, cmpadr
|
||
load r1, movlod + 1
|
||
brneq r0, r1, decsav
|
||
load r0, cmpadr + 1
|
||
load r1, movlod + 2
|
||
brneq r0, r1, decsav
|
||
breq r0, r1, roomnd
|
||
|
||
;Decrement the old save address
|
||
;load the address
|
||
decsav: load r0, movlod + 1
|
||
load r1, movlod + 2
|
||
;Decrement
|
||
cleq r0, r0, decdw
|
||
;Store the address
|
||
store movlod + 1, r0
|
||
store movlod + 2, r1
|
||
|
||
;Decrement the new save address
|
||
;load the address
|
||
load r0, movsto + 1
|
||
load r1, movsto + 2
|
||
;Decrement
|
||
cleq r0, r0, decdw
|
||
;Store the address
|
||
store movsto + 1, r0
|
||
store movsto + 2, r1
|
||
|
||
;Move the next character
|
||
breq r0, r0, movlod
|
||
|
||
;Return with a null at r1
|
||
roomnd: xor r1, r1
|
||
ret
|
||
|
||
;Print an error and return with an exclamation mark at r1
|
||
lmterr: load r0, #21
|
||
store ffff, r0
|
||
cleq r0, r0, newln
|
||
load r1, #21
|
||
ret
|
||
|
||
;***
|
||
|
||
;Find the argument line in the save and store its number
|
||
|
||
;Check for the argument
|
||
fend: load r0, target
|
||
load r1, lnnum
|
||
brneq r0, r1, feof
|
||
load r0, target + 1
|
||
load r1, lnnum + 1
|
||
breq r0, r1, fendnd
|
||
|
||
;Check for control characters
|
||
;End-of-file
|
||
feof: load r0, #1a
|
||
eoflod: load r1, 0
|
||
breq r0, r1, fendnd
|
||
;Line feed
|
||
load r2, #a
|
||
brneq r1, r2, incsav
|
||
|
||
;Increment the line number
|
||
;Load the number
|
||
load r0, lnnum
|
||
load r1, lnnum + 1
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the number
|
||
store lnnum, r0
|
||
store lnnum + 1, r1
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
incsav: load r0, eoflod + 1
|
||
load r1, eoflod + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store eoflod + 1, r0
|
||
store eoflod + 2, r1
|
||
|
||
;Check the next character
|
||
breq r0, r0, fend
|
||
|
||
;Return
|
||
fendnd: ret
|
||
|
||
;***
|
||
|
||
;Print a line number prompt
|
||
|
||
;Print the high byte
|
||
;Get the byte
|
||
prnln: load r0, lnnum
|
||
;Convert
|
||
cleq r0, r0, bt2hex
|
||
;Print
|
||
load r2, #30
|
||
breq r0, r2, lead0
|
||
store ffff, r0
|
||
nlead0: store ffff, r1
|
||
load r3, #1
|
||
breq r0, r0, lbtln
|
||
lead0: load r0, #20
|
||
store ffff, r0
|
||
brneq r1, r2, nlead0
|
||
load r1, #20
|
||
store ffff, r1
|
||
xor r3, r3
|
||
|
||
;Print the low byte
|
||
;Get the byte
|
||
lbtln: load r0, lnnum + 1
|
||
;Convert
|
||
cleq r0, r0, bt2hex
|
||
;Check for preceding leading zeroes
|
||
xor r2, r2
|
||
brneq r2, r3, nled0s
|
||
;Print
|
||
load r2, #30
|
||
brneq r0, r2, nled0s
|
||
load r0, #20
|
||
store ffff, r0
|
||
store ffff, r1
|
||
breq r0, r0, prcln
|
||
nled0s: store ffff, r0
|
||
store ffff, r1
|
||
|
||
;Print a colon
|
||
prcln: load r0, #3a
|
||
store ffff, r0
|
||
load r0, #20
|
||
store ffff, r0
|
||
|
||
;Return
|
||
ret
|
||
|
||
;***
|
||
|
||
;Print or write to tape
|
||
|
||
;Get the save start address
|
||
;High byte
|
||
prwr: load r0, svstrt
|
||
store chprwr + 1, r0
|
||
;Low byte
|
||
load r0, svstrt + 1
|
||
store chprwr + 2, r0
|
||
|
||
;Load a character from the save
|
||
chprwr: load r1, buffer + 100
|
||
|
||
;Print the character
|
||
prwrch: store fffe, r1
|
||
|
||
;Check for the save end
|
||
load r2, #1a
|
||
breq r1, r2, pwend
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
load r0, chprwr + 1
|
||
load r1, chprwr + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chprwr + 1, r0
|
||
store chprwr + 2, r1
|
||
|
||
;Print the next character
|
||
breq r0, r0, chprwr
|
||
|
||
;Return
|
||
pwend: ret
|
||
|
||
;***
|
||
|
||
;Check for the RAM limit
|
||
|
||
;Check
|
||
ramchk: load r2, limit
|
||
load r3, limit + 1
|
||
brneq r0, r2, ramend
|
||
brneq r1, r3, ramend
|
||
|
||
;Save an end-of-file at the start address
|
||
load r0, #1a
|
||
store buffer + 100, r0
|
||
|
||
;Print an error
|
||
load r0, #21
|
||
store ffff, r0
|
||
cleq r0, r0, newln
|
||
|
||
;Return with an exclamation mark at r1
|
||
load r1, #21
|
||
ret
|
||
|
||
;Return with a null at r1
|
||
ramend: load r1, #0
|
||
ret
|
||
|
||
;***
|
||
|
||
;Read a newline
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
readnl: load r0, chrsto + 1
|
||
load r1, chrsto + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chrsto + 1, r0
|
||
store lfstor + 1, r0
|
||
store chrsto + 2, r1
|
||
store lfstor + 2, r1
|
||
|
||
;Check for the RAM limit
|
||
cleq r0, r0, ramchk
|
||
xor r2, r2
|
||
brneq r1, r2, cmdp
|
||
|
||
;Store a line feed
|
||
load r1, #a
|
||
lfstor: store 0, r1
|
||
|
||
;Increment the save address
|
||
;Load the address
|
||
load r0, chrsto + 1
|
||
load r1, chrsto + 2
|
||
;Increment
|
||
cleq r0, r0, incdw
|
||
;Store the address
|
||
store chrsto + 1, r0
|
||
store chrsto + 2, r1
|
||
|
||
;Check for the RAM limit
|
||
cleq r0, r0, ramchk
|
||
xor r2, r2
|
||
brneq r1, r2, cmdp
|
||
|
||
;Read a character
|
||
load r1, fffd
|
||
|
||
;Return
|
||
ret
|
||
|
||
;***
|
||
|
||
;Data
|
||
|
||
;Variables
|
||
ovrflw: data 0
|
||
lnnum: data 0
|
||
data 0
|
||
strsz: data 0
|
||
data 0
|
||
dgtcnt: data 0
|
||
dgtadr: addr buffer + 2
|
||
cmd: data 0
|
||
arg1: data 30
|
||
data 30
|
||
data 30
|
||
data 30
|
||
argf1: data 0
|
||
arg2: data 30
|
||
data 30
|
||
argf2: data 0
|
||
target: data 0
|
||
data 0
|
||
count: data 0
|
||
mark: data 0
|
||
data 0
|
||
mrkadr: data 0
|
||
data 0
|
||
cmpadr: data 0
|
||
data 0
|
||
tmp1: data 0
|
||
data 0
|
||
tmp2: data 0
|
||
data 0
|
||
|
||
;Buffer and save
|
||
bfstrt: addr buffer
|
||
bfsize: data fe
|
||
svstrt: addr buffer + 100
|
||
limit: data 0
|
||
data 0
|
||
|
||
buffer:
|
||
|