1068 lines
18 KiB
NASM
1068 lines
18 KiB
NASM
org 0
|
|
|
|
start:
|
|
cleq r0, r0, stReadline
|
|
cleq r0, r0, dumpstack
|
|
|
|
halt
|
|
|
|
debug:
|
|
store debugr0, r0
|
|
store debugr1, r1
|
|
store debugr2, r2
|
|
store debugr3, r3
|
|
|
|
debugRegs:
|
|
load r0, debugr0
|
|
cleq r0, r0, writehexByte
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
load r0, debugr1
|
|
cleq r0, r0, writehexByte
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
load r0, debugr2
|
|
cleq r0, r0, writehexByte
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
load r0, debugr3
|
|
cleq r0, r0, writehexByte
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
debugTmpWords:
|
|
load r0, tmpWordHigh
|
|
load r1, tmpWordLow
|
|
cleq r0, r0, writeHexWord
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
load r0, tmpWord2High
|
|
load r1, tmpWord2Low
|
|
cleq r0, r0, writeHexWord
|
|
load r0, litcharPipe
|
|
store ffff, r0
|
|
|
|
load r0, SPStart+0
|
|
load r1, SPStart+1
|
|
store debugPtr+0, r0
|
|
store debugPtr+1, r1
|
|
|
|
debugLoop:
|
|
load r0, debugPtr+0
|
|
load r1, debugPtr+1
|
|
load r2, SP+0
|
|
load r3, SP+1
|
|
|
|
brneq r0, r2, debugDumpword
|
|
breq r1, r3, debugEnd
|
|
|
|
debugDumpword:
|
|
load r0, debugPtr+0
|
|
load r1, debugPtr+1
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
cleq r0, r0, loadByte
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, debugPtr+0
|
|
load r1, debugPtr+1
|
|
cleq r0, r0, incWord
|
|
store debugPtr+0, r0
|
|
store debugPtr+1, r1
|
|
|
|
load r0, debugPtr+0
|
|
load r1, debugPtr+1
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
cleq r0, r0, loadByte
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, debugPtr+0
|
|
load r1, debugPtr+1
|
|
cleq r0, r0, incWord
|
|
store debugPtr+0, r0
|
|
store debugPtr+1, r1
|
|
|
|
load r0, litcharSpace
|
|
store ffff, r0
|
|
|
|
breq r0, r0, debugLoop
|
|
|
|
debugEnd:
|
|
cleq r0, r0, newline
|
|
|
|
load r0, debugr0
|
|
load r1, debugr1
|
|
load r2, debugr2
|
|
load r3, debugr3
|
|
|
|
ret
|
|
|
|
debugPtr: addr debugPtr
|
|
debugr0: data 0
|
|
debugr1: data 0
|
|
debugr2: data 0
|
|
debugr3: data 0
|
|
|
|
stReadline:
|
|
; Current index starts at 0
|
|
xor r0, r0
|
|
xor r1, r1
|
|
cleq r0, r0, pushWord
|
|
|
|
readlineLoop:
|
|
; Read a byte of input
|
|
cleq r0, r0, stKey
|
|
|
|
; Is it enter?
|
|
cleq r0, r0, peekWord
|
|
load r0, litcharCR
|
|
breq r0, r1, readlineEnter
|
|
|
|
; Is it backspace?
|
|
load r0, litcharBS
|
|
breq r0, r1, readlineBackspace
|
|
|
|
; Is the buffer full?
|
|
cleq r0, r0, stOver
|
|
load r0, linebufSize+0
|
|
load r1, linebufSize+1
|
|
cleq r0, r0, pushWord
|
|
cleq r0, r0, stGtEq
|
|
brneq r0, r1, readlineBufFull
|
|
|
|
; Calculate address
|
|
cleq r0, r0, stOver
|
|
load r0, linebufStart+0
|
|
load r1, linebufStart+1
|
|
cleq r0, r0, pushWord
|
|
cleq r0, r0, stAdd
|
|
|
|
; Store the read byte
|
|
cleq r0, r0, stStoreByte
|
|
|
|
; Increase index
|
|
cleq r0, r0, stInc
|
|
|
|
breq r0, r0, readlineLoop
|
|
|
|
readlineEnter:
|
|
; Remove the CR byte off the stack, as we only want to return the length
|
|
cleq r0, r0, popWord
|
|
breq r0, r0, newline
|
|
|
|
readlineBackspace:
|
|
; Remove the BS byte off the stack
|
|
cleq r0, r0, popWord
|
|
|
|
; Are we at the beginning of the line?
|
|
cleq r0, r0, stDup
|
|
xor r0, r0
|
|
xor r1, r1
|
|
cleq r0, r0, pushWord
|
|
cleq r0, r0, stSwap
|
|
cleq r0, r0, stGtEq
|
|
brneq r0, r1, readlineLoop
|
|
|
|
; Decrease the index and erase the echoed character
|
|
cleq r0, r0, stDec
|
|
load r3, litcharSpace
|
|
store ffff, r3
|
|
load r3, litcharBS
|
|
store ffff, r3
|
|
|
|
breq r0, r0, readlineLoop
|
|
|
|
readlineBufFull:
|
|
; Drop the input byte and erase the echoed character
|
|
cleq r0, r0, popWord
|
|
load r3, litcharBS
|
|
store ffff, r3
|
|
load r3, litcharSpace
|
|
store ffff, r3
|
|
load r3, litcharBS
|
|
store ffff, r3
|
|
breq r0, r0, readlineLoop
|
|
|
|
; ==================================================================
|
|
; Stack-based functions
|
|
; ==================================================================
|
|
|
|
; ------------------------------------------------------------------
|
|
; Arithmetic
|
|
; ------------------------------------------------------------------
|
|
|
|
; a b -- a+b
|
|
stAdd:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpLoadWord23
|
|
cleq r0, r0, addWord
|
|
breq r0, r0, pushWord
|
|
|
|
; a b -- a-b
|
|
stSub:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpLoadWord23
|
|
cleq r0, r0, subWord
|
|
breq r0, r0, pushWord
|
|
|
|
; a -- a+1
|
|
stInc:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, incWord
|
|
breq r0, r0, pushWord
|
|
|
|
; a -- a-1
|
|
stDec:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, decWord
|
|
breq r0, r0, pushWord
|
|
|
|
; a b --
|
|
; if a >= b then r0:r1 = 0001
|
|
; else r0:r1 = 0000
|
|
stGtEq:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpLoadWord23
|
|
cleq r0, r0, subWord
|
|
xor r0, r0
|
|
xor r1, r1
|
|
or r1, r2
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; I/O
|
|
; ------------------------------------------------------------------
|
|
|
|
; n -- n
|
|
stPrinthex:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, writehexWord
|
|
breq r0, r0, newline
|
|
|
|
; -- c
|
|
stKey:
|
|
xor r0, r0
|
|
load r1, ffff
|
|
breq r0, r0, pushWord
|
|
|
|
; c --
|
|
stEmit:
|
|
cleq r0, r0, popWord
|
|
store ffff, r1
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; Stack manipulation
|
|
; ------------------------------------------------------------------
|
|
|
|
; a - a a
|
|
stDup:
|
|
cleq r0, r0, peekWord
|
|
breq r0, r0, pushWord
|
|
|
|
; a b -- a b a
|
|
stOver:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, peekWord
|
|
cleq r0, r0, tmp2StoreWord01
|
|
cleq r0, r0, tmpLoadWord01
|
|
cleq r0, r0, pushWord
|
|
cleq r0, r0, tmp2LoadWord01
|
|
breq r0, r0, pushWord
|
|
|
|
; a b -- b a
|
|
stSwap:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmp2StoreWord01
|
|
cleq r0, r0, tmpLoadWord01
|
|
cleq r0, r0, pushWord
|
|
cleq r0, r0, tmp2LoadWord01
|
|
breq r0, r0, pushWord
|
|
|
|
; ------------------------------------------------------------------
|
|
; Memory
|
|
; ------------------------------------------------------------------
|
|
|
|
; b ptr --
|
|
stStoreByte:
|
|
cleq r0, r0, popWord
|
|
store storeByteHigh, r0
|
|
store storeByteLow, r1
|
|
cleq r0, r0, popWord
|
|
xor r0, r0
|
|
or r0, r1
|
|
breq r0, r0, storeByte
|
|
|
|
; ptr -- b
|
|
stLoadByte:
|
|
cleq r0, r0, popWord
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
cleq r0, r0, loadByte
|
|
xor r1, r1
|
|
or r1, r0
|
|
xor r0, r0
|
|
breq r0, r0, pushWord
|
|
|
|
; n ptr --
|
|
stStoreWord:
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, tmpStoreWord01
|
|
store storeByteHigh, r0
|
|
store storeByteLow, r1
|
|
cleq r0, r0, peekWord
|
|
cleq r0, r0, storeByte
|
|
cleq r0, r0, tmpLoadWord01
|
|
cleq r0, r0, incWord
|
|
store storeByteHigh, r0
|
|
store storeByteLow, r1
|
|
cleq r0, r0, popWord
|
|
xor r0, r0
|
|
or r0, r1
|
|
breq r0, r0, storeByte
|
|
|
|
; ptr -- n
|
|
stLoadWord:
|
|
cleq r0, r0, peekWord
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
cleq r0, r0, loadByte
|
|
cleq r0, r0, tmpStoreWord01
|
|
cleq r0, r0, popWord
|
|
cleq r0, r0, incWord
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
cleq r0, r0, loadByte
|
|
xor r2, r2
|
|
or r2, r0
|
|
cleq r0, r0, tmpLoadWord01
|
|
xor r1, r1
|
|
or r1, r2
|
|
breq r0, r0, pushWord
|
|
|
|
; ==================================================================
|
|
; Low-level functions
|
|
; ==================================================================
|
|
|
|
; ------------------------------------------------------------------
|
|
; Memory
|
|
; ------------------------------------------------------------------
|
|
|
|
tmpWordHigh: data 0
|
|
tmpWordLow: data 0
|
|
tmpWord2High: data 0
|
|
tmpWord2Low: data 0
|
|
|
|
; in:
|
|
; r0:r1 = word
|
|
tmpStoreWord01:
|
|
store tmpWordHigh, r0
|
|
store tmpWordLow, r1
|
|
ret
|
|
|
|
; out:
|
|
; r0:r1 = word
|
|
tmpLoadWord01:
|
|
load r0, tmpWordHigh
|
|
load r1, tmpWordLow
|
|
ret
|
|
|
|
; out:
|
|
; r2:r3 = word
|
|
tmpLoadWord23:
|
|
load r2, tmpWordHigh
|
|
load r3, tmpWordLow
|
|
ret
|
|
|
|
; in:
|
|
; r0:r1 = word
|
|
tmp2StoreWord01:
|
|
store tmpWord2High, r0
|
|
store tmpWord2Low, r1
|
|
ret
|
|
|
|
; out:
|
|
; r0:r1 = word
|
|
tmp2LoadWord01:
|
|
load r0, tmpWord2High
|
|
load r1, tmpWord2Low
|
|
ret
|
|
|
|
; out:
|
|
; r0:r1 = word
|
|
; clobbers:
|
|
; r2, r3
|
|
peekWord:
|
|
cleq r0, r0, popWord
|
|
store peekWordHigh, r0
|
|
store peekWordLow, r1
|
|
|
|
; Return SP back to where it was
|
|
load r0, SP+0
|
|
load r1, SP+1
|
|
xor r2, r2
|
|
load r3, lit02
|
|
cleq r0, r0, addWord
|
|
store SP+0, r0
|
|
store SP+1, r1
|
|
|
|
load r0, peekWordHigh
|
|
load r1, peekWordLow
|
|
ret
|
|
|
|
peekWordHigh: data 0
|
|
peekWordLow: data 0
|
|
|
|
; in:
|
|
; r0:r1 = word
|
|
; clobbers:
|
|
; r0, r1, r2, r3
|
|
pushWord:
|
|
store pushWordLow, r1
|
|
cleq r0, r0, pushByte
|
|
load r0, pushWordLow
|
|
breq r0, r0, pushByte
|
|
|
|
pushWordLow: data 0
|
|
|
|
; out:
|
|
; r0:r1
|
|
; clobbers:
|
|
; r2, r3
|
|
popWord:
|
|
cleq r0, r0, popByte
|
|
store popWordLow, r0
|
|
|
|
cleq r0, r0, popByte
|
|
|
|
load r1, popWordLow
|
|
|
|
ret
|
|
|
|
popWordLow: data 0
|
|
|
|
; in:
|
|
; r0 = byte
|
|
; clobbers:
|
|
; r0, r1, r2, r3
|
|
pushByte:
|
|
load r2, SP+0
|
|
store storeByteHigh, r2
|
|
load r3, SP+1
|
|
store storeByteLow, r3
|
|
cleq r0, r0, storeByte
|
|
|
|
load r0, SP+0
|
|
load r1, SP+1
|
|
cleq r0, r0, incWord
|
|
store SP+0, r0
|
|
store SP+1, r1
|
|
|
|
ret
|
|
|
|
; out:
|
|
; r0 = byte
|
|
; clobbers:
|
|
; r1, r2, r3
|
|
popByte:
|
|
load r0, SP+0
|
|
load r1, SP+1
|
|
cleq r0, r0, decWord
|
|
store SP+0, r0
|
|
store SP+1, r1
|
|
|
|
store loadByteHigh, r0
|
|
store loadByteLow, r1
|
|
breq r0, r0, loadByte
|
|
|
|
; in:
|
|
; storeByteHigh:storeByteLow = address
|
|
; r0 = byte
|
|
storeByte:
|
|
data b0 ; store addr, r0
|
|
storeByteHigh: data 0
|
|
storeByteLow: data 0
|
|
ret
|
|
|
|
; in:
|
|
; loadByteHigh:loadByteLow = address
|
|
; out:
|
|
; r0 = byte
|
|
loadByte:
|
|
data a0 ; load r0, addr
|
|
loadByteHigh: data 0
|
|
loadByteLow: data 0
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; Arithmetic
|
|
; ------------------------------------------------------------------
|
|
|
|
; in:
|
|
; r0:r1 = first addend
|
|
; r2:r3 = second addend
|
|
; out:
|
|
; r0:r1 = result
|
|
; r2 = carryout
|
|
; clobbers:
|
|
; r3
|
|
addWord:
|
|
store addWordFirstHigh, r0
|
|
store addWordSecondHigh, r2
|
|
|
|
; Add low bytes
|
|
xor r0, r0
|
|
or r0, r3
|
|
cleq r0, r0, addByte
|
|
store addWordResultLow, r0
|
|
|
|
; Add high bytes and carry (in r1)
|
|
load r0, addWordFirstHigh
|
|
load r2, addWordSecondHigh
|
|
cleq r0, r0, addByte3
|
|
|
|
; Move carryout to r2
|
|
xor r2, r2
|
|
or r2, r1
|
|
|
|
load r1, addWordResultLow
|
|
|
|
ret
|
|
|
|
addWordFirstHigh: data 0
|
|
addWordSecondHigh: data 0
|
|
addWordResultLow: data 0
|
|
|
|
; in:
|
|
; r0:r1 = minuend
|
|
; r2:r3 = subtrahend
|
|
; out:
|
|
; r0:r1 = result
|
|
; r2 = carryout
|
|
; clobbers:
|
|
; r3
|
|
subWord:
|
|
store subWordMinuendHigh, r0
|
|
store subWordSubtrahendHigh, r2
|
|
|
|
; Subtract low bytes
|
|
; a - b = a + (-b) = a + ~b + 1
|
|
xor r0, r0
|
|
or r0, r3
|
|
nand r0, r0
|
|
load r2, lit01
|
|
cleq r0, r0, addByte3
|
|
store subWordResultLow, r0
|
|
|
|
; Subtract high bytes with carry-in in r1
|
|
load r0, subWordMinuendHigh
|
|
load r2, subWordSubtrahendHigh
|
|
nand r2, r2
|
|
cleq r0, r0, addByte3
|
|
|
|
; Move carryout to r2
|
|
xor r2, r2
|
|
or r2, r1
|
|
|
|
load r1, subWordResultLow
|
|
|
|
ret
|
|
|
|
subWordMinuendHigh: data 0
|
|
subWordSubtrahendHigh: data 0
|
|
subWordResultLow: data 0
|
|
|
|
; in/out:
|
|
; r0:r1 = word
|
|
; clobbers:
|
|
; r2, r3
|
|
incWord:
|
|
store incWordHigh, r0
|
|
|
|
; Add 1 to low byte
|
|
load r0, lit01
|
|
cleq r0, r0, addByte
|
|
store incWordLow, r0
|
|
|
|
; Add carry to high byte
|
|
load r0, incWordHigh
|
|
cleq r0, r0, addByte
|
|
|
|
load r1, incWordLow
|
|
|
|
ret
|
|
|
|
incWordHigh: data 0
|
|
incWordLow: data 0
|
|
|
|
; in/out:
|
|
; r0:r1 = word
|
|
; clobbers:
|
|
; r2, r3
|
|
decWord:
|
|
store decWordHigh, r0
|
|
|
|
; Add ff to low byte
|
|
load r0, litff
|
|
cleq r0, r0, addByte
|
|
store decWordLow, r0
|
|
|
|
; Add ff and carry to high byte
|
|
load r0, litff
|
|
load r2, decWordHigh
|
|
cleq r0, r0, addByte3
|
|
|
|
load r1, decWordLow
|
|
|
|
ret
|
|
|
|
decWordHigh: data 0
|
|
decWordLow: data 0
|
|
|
|
; in:
|
|
; r0 = first addend
|
|
; r1 = second addend
|
|
; r2 = third addend
|
|
; out:
|
|
; r0 = result
|
|
; r1 = carryout
|
|
; clobbers:
|
|
; r2, r3
|
|
addByte3:
|
|
store addByte3ThirdAddend, r2
|
|
|
|
cleq r0, r0, addByte
|
|
store addByte3Carryout, r1
|
|
|
|
load r1, addByte3ThirdAddend
|
|
cleq r0, r0, addByte
|
|
|
|
load r3, addByte3Carryout
|
|
or r1, r3
|
|
|
|
ret
|
|
|
|
addByte3ThirdAddend: data 0
|
|
addByte3Carryout: data 0
|
|
|
|
; in:
|
|
; r0 = first addend
|
|
; r1 = second addend
|
|
; out:
|
|
; r0 = result
|
|
; r1 = carryout
|
|
; clobbers:
|
|
; r2, r3
|
|
addByte:
|
|
; Initiliaze carryout to 0
|
|
xor r2, r2
|
|
|
|
addByteLoop:
|
|
; Copy second addend to r3
|
|
xor r3, r3
|
|
or r3, r1
|
|
; Calculate carries in r3
|
|
and r3, r0
|
|
or r2, r3 ; Accumulate carry into carryout
|
|
shl r3
|
|
; Calculate sums in r0
|
|
xor r0, r1
|
|
; Copy carries into second addend
|
|
xor r1, r1
|
|
or r1, r3
|
|
|
|
; Loop until second addend is 0
|
|
xor r3, r3
|
|
brneq r1, r3, addByteLoop
|
|
|
|
; Shift carryout, as we want carry from highest place = 1
|
|
shr r2
|
|
shr r2
|
|
shr r2
|
|
shr r2
|
|
shr r2
|
|
shr r2
|
|
shr r2
|
|
|
|
; Move carryout to r1
|
|
; (We know r1 is already 0 since it's the loop condition)
|
|
or r1, r2
|
|
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; Hex conversion routines
|
|
; ------------------------------------------------------------------
|
|
|
|
; in:
|
|
; r0 = number in range [0, 0xf]
|
|
; out:
|
|
; r0 = ascii character corresponding to input
|
|
; clobbers:
|
|
; r3
|
|
nybble2hex:
|
|
xor r3, r3
|
|
breq r0, r3, nybble2hex0
|
|
load r3, lit01
|
|
breq r0, r3, nybble2hex1
|
|
load r3, lit02
|
|
breq r0, r3, nybble2hex2
|
|
load r3, lit03
|
|
breq r0, r3, nybble2hex3
|
|
load r3, lit04
|
|
breq r0, r3, nybble2hex4
|
|
load r3, lit05
|
|
breq r0, r3, nybble2hex5
|
|
load r3, lit06
|
|
breq r0, r3, nybble2hex6
|
|
load r3, lit07
|
|
breq r0, r3, nybble2hex7
|
|
load r3, lit08
|
|
breq r0, r3, nybble2hex8
|
|
load r3, lit09
|
|
breq r0, r3, nybble2hex9
|
|
load r3, lit0a
|
|
breq r0, r3, nybble2hexa
|
|
load r3, lit0b
|
|
breq r0, r3, nybble2hexb
|
|
load r3, lit0c
|
|
breq r0, r3, nybble2hexc
|
|
load r3, lit0d
|
|
breq r0, r3, nybble2hexd
|
|
load r3, lit0e
|
|
breq r0, r3, nybble2hexe
|
|
load r3, lit0f
|
|
breq r0, r3, nybble2hexf
|
|
|
|
breq r0, r0, error
|
|
|
|
nybble2hex0:
|
|
load r0, litchar0
|
|
ret
|
|
nybble2hex1:
|
|
load r0, litchar1
|
|
ret
|
|
nybble2hex2:
|
|
load r0, litchar2
|
|
ret
|
|
nybble2hex3:
|
|
load r0, litchar3
|
|
ret
|
|
nybble2hex4:
|
|
load r0, litchar4
|
|
ret
|
|
nybble2hex5:
|
|
load r0, litchar5
|
|
ret
|
|
nybble2hex6:
|
|
load r0, litchar6
|
|
ret
|
|
nybble2hex7:
|
|
load r0, litchar7
|
|
ret
|
|
nybble2hex8:
|
|
load r0, litchar8
|
|
ret
|
|
nybble2hex9:
|
|
load r0, litchar9
|
|
ret
|
|
nybble2hexa:
|
|
load r0, litchara
|
|
ret
|
|
nybble2hexb:
|
|
load r0, litcharb
|
|
ret
|
|
nybble2hexc:
|
|
load r0, litcharc
|
|
ret
|
|
nybble2hexd:
|
|
load r0, litchard
|
|
ret
|
|
nybble2hexe:
|
|
load r0, litchare
|
|
ret
|
|
nybble2hexf:
|
|
load r0, litcharf
|
|
ret
|
|
|
|
; in:
|
|
; r0 = ascii hex digit
|
|
; out:
|
|
; r0 = corresponding nybble
|
|
; clobbers:
|
|
; r3
|
|
hex2nybble:
|
|
load r3, litchar0
|
|
breq r0, r3, hex2nybble0
|
|
load r3, litchar1
|
|
breq r0, r3, hex2nybble1
|
|
load r3, litchar2
|
|
breq r0, r3, hex2nybble2
|
|
load r3, litchar3
|
|
breq r0, r3, hex2nybble3
|
|
load r3, litchar4
|
|
breq r0, r3, hex2nybble4
|
|
load r3, litchar5
|
|
breq r0, r3, hex2nybble5
|
|
load r3, litchar6
|
|
breq r0, r3, hex2nybble6
|
|
load r3, litchar7
|
|
breq r0, r3, hex2nybble7
|
|
load r3, litchar8
|
|
breq r0, r3, hex2nybble8
|
|
load r3, litchar9
|
|
breq r0, r3, hex2nybble9
|
|
load r3, litchara
|
|
breq r0, r3, hex2nybblea
|
|
load r3, litcharb
|
|
breq r0, r3, hex2nybbleb
|
|
load r3, litcharc
|
|
breq r0, r3, hex2nybblec
|
|
load r3, litchard
|
|
breq r0, r3, hex2nybbled
|
|
load r3, litchare
|
|
breq r0, r3, hex2nybblee
|
|
load r3, litcharf
|
|
breq r0, r3, hex2nybblef
|
|
load r3, litcharUppera
|
|
breq r0, r3, hex2nybblea
|
|
load r3, litcharUpperb
|
|
breq r0, r3, hex2nybbleb
|
|
load r3, litcharUpperC
|
|
breq r0, r3, hex2nybblec
|
|
load r3, litcharUpperD
|
|
breq r0, r3, hex2nybbled
|
|
load r3, litcharUpperE
|
|
breq r0, r3, hex2nybblee
|
|
load r3, litcharUpperF
|
|
breq r0, r3, hex2nybblef
|
|
|
|
breq r0, r0, error
|
|
|
|
hex2nybble0:
|
|
xor r0, r0
|
|
ret
|
|
hex2nybble1:
|
|
load r0, lit01
|
|
ret
|
|
hex2nybble2:
|
|
load r0, lit02
|
|
ret
|
|
hex2nybble3:
|
|
load r0, lit03
|
|
ret
|
|
hex2nybble4:
|
|
load r0, lit04
|
|
ret
|
|
hex2nybble5:
|
|
load r0, lit05
|
|
ret
|
|
hex2nybble6:
|
|
load r0, lit06
|
|
ret
|
|
hex2nybble7:
|
|
load r0, lit07
|
|
ret
|
|
hex2nybble8:
|
|
load r0, lit08
|
|
ret
|
|
hex2nybble9:
|
|
load r0, lit09
|
|
ret
|
|
hex2nybblea:
|
|
load r0, lit0a
|
|
ret
|
|
hex2nybbleb:
|
|
load r0, lit0b
|
|
ret
|
|
hex2nybblec:
|
|
load r0, lit0c
|
|
ret
|
|
hex2nybbled:
|
|
load r0, lit0d
|
|
ret
|
|
hex2nybblee:
|
|
load r0, lit0e
|
|
ret
|
|
hex2nybblef:
|
|
load r0, lit0f
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; Hex output
|
|
; ------------------------------------------------------------------
|
|
|
|
; in:
|
|
; r1:r0 = word
|
|
; clobbers:
|
|
; r0, r2, r3
|
|
writehexWord:
|
|
cleq r0, r0, writehexByte
|
|
|
|
; Move low byte to r0
|
|
xor r0, r0
|
|
or r0, r1
|
|
breq r0, r0, writehexByte
|
|
|
|
; in:
|
|
; r0 = byte
|
|
; clobbers:
|
|
; r0, r2, r3
|
|
writehexByte:
|
|
; Store copy of the byte (as r0 is modified by nybble2hex)
|
|
xor r2, r2
|
|
or r2, r0
|
|
|
|
; High nybble
|
|
shr r0
|
|
shr r0
|
|
shr r0
|
|
shr r0
|
|
cleq r0, r0, nybble2hex
|
|
store ffff, r0
|
|
|
|
; Low nybble
|
|
load r0, lit0f
|
|
and r0, r2
|
|
cleq r0, r0, nybble2hex
|
|
store ffff, r0
|
|
|
|
ret
|
|
|
|
; ------------------------------------------------------------------
|
|
; Common output routines
|
|
; ------------------------------------------------------------------
|
|
|
|
; clobbers:
|
|
; r3
|
|
newline:
|
|
load r3, litcharCR
|
|
store ffff, r3
|
|
load r3, litcharLF
|
|
store ffff, r3
|
|
ret
|
|
|
|
; noreturn
|
|
error:
|
|
load r0, litchare
|
|
store ffff, r0
|
|
load r0, litcharr
|
|
store ffff, r0
|
|
store ffff, r0
|
|
load r1, litcharo
|
|
store ffff, r1
|
|
store ffff, r0
|
|
cleq r0, r0, newline
|
|
halt
|
|
|
|
; ==================================================================
|
|
; Literals pool
|
|
; ==================================================================
|
|
|
|
lit01: data 01
|
|
lit02: data 02
|
|
lit03: data 03
|
|
lit04: data 04
|
|
lit05: data 05
|
|
lit06: data 06
|
|
lit07: data 07
|
|
litcharBS:
|
|
lit08: data 08
|
|
lit09: data 09
|
|
litcharLF:
|
|
lit0a: data 0a
|
|
lit0b: data 0b
|
|
lit0c: data 0c
|
|
litcharCR:
|
|
lit0d: data 0d
|
|
lit0e: data 0e
|
|
lit0f: data 0f
|
|
|
|
litcharSpace:
|
|
lit20: data 20
|
|
|
|
litchar0:
|
|
lit30: data 30
|
|
litchar1:
|
|
lit31: data 31
|
|
litchar2:
|
|
lit32: data 32
|
|
litchar3:
|
|
lit33: data 33
|
|
litchar4:
|
|
lit34: data 34
|
|
litchar5:
|
|
lit35: data 35
|
|
litchar6:
|
|
lit36: data 36
|
|
litchar7:
|
|
lit37: data 37
|
|
litchar8:
|
|
lit38: data 38
|
|
litchar9:
|
|
lit39: data 39
|
|
|
|
litcharUppera:
|
|
lit41: data 41
|
|
litcharUpperb:
|
|
lit42: data 42
|
|
litcharUpperc:
|
|
lit43: data 43
|
|
litcharUpperd:
|
|
lit44: data 44
|
|
litcharUppere:
|
|
lit45: data 45
|
|
litcharUpperf:
|
|
lit46: data 46
|
|
|
|
litchara:
|
|
lit61: data 61
|
|
litcharb:
|
|
lit62: data 62
|
|
litcharc:
|
|
lit63: data 63
|
|
litchard:
|
|
lit64: data 64
|
|
litchare:
|
|
lit65: data 65
|
|
litcharf:
|
|
lit66: data 66
|
|
|
|
litcharo:
|
|
lit6f: data 6f
|
|
|
|
litcharr:
|
|
lit72: data 72
|
|
|
|
litcharPipe:
|
|
lit7c: data 7c
|
|
|
|
litff: data ff
|
|
|
|
; ==================================================================
|
|
; Data
|
|
; ==================================================================
|
|
|
|
linebufStart: addr end
|
|
linebufSize:
|
|
data 00
|
|
data 80
|
|
SP: addr end + 80
|
|
SPStart: addr end + 80
|
|
|
|
end:
|