|
|
|
org 0
|
|
|
|
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, dumpFloat
|
|
|
|
|
|
|
|
cleq r0, r0, normalize
|
|
|
|
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, dumpFloat
|
|
|
|
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, fPack
|
|
|
|
|
|
|
|
cleq r0, r0, fPrint
|
|
|
|
cleq r0, r0, newline
|
|
|
|
|
|
|
|
halt
|
|
|
|
|
|
|
|
cleq r0, r0, readline
|
|
|
|
|
|
|
|
load r0, linelen+0
|
|
|
|
load r1, linelen+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stPrinthex
|
|
|
|
|
|
|
|
xor r0, r0
|
|
|
|
xor r1, r1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
printloop:
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stGtEq
|
|
|
|
brneq r0, r1, printend
|
|
|
|
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
load r0, linebufStart+0
|
|
|
|
load r1, linebufStart+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, stEmit
|
|
|
|
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
|
|
|
|
breq r0, r0, printloop
|
|
|
|
|
|
|
|
printend:
|
|
|
|
cleq r0, r0, newline
|
|
|
|
halt
|
|
|
|
|
|
|
|
dumpFloat:
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #12
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
dumpFloatLoop:
|
|
|
|
cleq r0, r0, peekWord
|
|
|
|
or r0, r1
|
|
|
|
xor r2, r2
|
|
|
|
breq r0, r2, dumpFloatEnd
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
xor r0, r0
|
|
|
|
or r0, r1
|
|
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, dumpFloatLoop
|
|
|
|
|
|
|
|
dumpFloatEnd:
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
breq r0, r0, newline
|
|
|
|
|
|
|
|
|
|
|
|
debug:
|
|
|
|
store debugr0, r0
|
|
|
|
store debugr1, r1
|
|
|
|
store debugr2, r2
|
|
|
|
store debugr3, r3
|
|
|
|
|
|
|
|
debugRegs:
|
|
|
|
load r0, debugr0
|
|
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, debugr1
|
|
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, debugr2
|
|
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, debugr3
|
|
|
|
cleq r0, r0, writehexByte
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
debugTmpWords:
|
|
|
|
load r0, tmpWordHigh
|
|
|
|
load r1, tmpWordLow
|
|
|
|
cleq r0, r0, writeHexWord
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, tmpWord2High
|
|
|
|
load r1, tmpWord2Low
|
|
|
|
cleq r0, r0, writeHexWord
|
|
|
|
load r0, #20
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, tmpWord3High
|
|
|
|
load r1, tmpWord3Low
|
|
|
|
cleq r0, r0, writeHexWord
|
|
|
|
load r0, #7c
|
|
|
|
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, #20
|
|
|
|
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
|
|
|
|
|
|
|
|
; --
|
|
|
|
readline:
|
|
|
|
; 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, #0d
|
|
|
|
breq r0, r1, readlineEnter
|
|
|
|
|
|
|
|
; Is it backspace?
|
|
|
|
load r0, #08
|
|
|
|
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 it's not needed
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
store linelen+0, r0
|
|
|
|
store linelen+1, r1
|
|
|
|
|
|
|
|
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
|
|
|
|
; TODO: utf-8
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
load r3, #20
|
|
|
|
store ffff, r3
|
|
|
|
load r3, #08
|
|
|
|
store ffff, r3
|
|
|
|
|
|
|
|
breq r0, r0, readlineLoop
|
|
|
|
|
|
|
|
readlineBufFull:
|
|
|
|
; Drop the input byte and erase the echoed character
|
|
|
|
; TODO: utf-8
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
load r3, #08
|
|
|
|
store ffff, r3
|
|
|
|
load r3, #20
|
|
|
|
store ffff, r3
|
|
|
|
load r3, #08
|
|
|
|
store ffff, r3
|
|
|
|
breq r0, r0, readlineLoop
|
|
|
|
|
|
|
|
; ==================================================================
|
|
|
|
; Floating point
|
|
|
|
; ==================================================================
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
; Format conversion
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
; When on-stack, a floating point number uses an 8-byte packed BCD format
|
|
|
|
; 0 1 2 3 4 5 6 7
|
|
|
|
; seee mmmm mmmm mmmm
|
|
|
|
; |\_/ \____________/
|
|
|
|
; | | |
|
|
|
|
; | | mantissa, first digit being before and rest after the point
|
|
|
|
; | exponent, with a bias of 500 (i.e. value of 0 means ×10⁻⁵⁰⁰)
|
|
|
|
; sign, 00 for non-negative, 01 for negative, 02 for overflow
|
|
|
|
|
|
|
|
; For operation, the format is instead an 18-byte unpacked BCD format
|
|
|
|
; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11
|
|
|
|
; 0s 0e 0e 0e 0o 0m 0m 0m 0m 0m 0m 0m 0m 0m 0m 0m 0m 0r
|
|
|
|
; | \______/ | \_________________________________/ |
|
|
|
|
; | | | | extra digit for rounding
|
|
|
|
; | | | mantissa
|
|
|
|
; | | extra digit for overflow
|
|
|
|
; | exponent
|
|
|
|
; sign
|
|
|
|
|
|
|
|
; f ptr --
|
|
|
|
fUnpack:
|
|
|
|
; Start from the end
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #11
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
; Zero out rounding digit
|
|
|
|
xor r0, r0
|
|
|
|
xor r1, r1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; Mantissa
|
|
|
|
cleq r0, r0, fUnpackWord
|
|
|
|
cleq r0, r0, fUnpackWord
|
|
|
|
cleq r0, r0, fUnpackWord
|
|
|
|
|
|
|
|
; Zero out overflow digit
|
|
|
|
xor r0, r0
|
|
|
|
xor r1, r1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; Sign and exponent
|
|
|
|
cleq r0, r0, fUnpackWord
|
|
|
|
|
|
|
|
; Clear off the pointer from the stack
|
|
|
|
breq r0, r0, popWord
|
|
|
|
|
|
|
|
; w ptr -- ptr-4
|
|
|
|
fUnpackWord:
|
|
|
|
; Low nybble of low byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLowNybble
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; High nybble of low byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stShr4
|
|
|
|
cleq r0, r0, stLowNybble
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; Low nybble of high byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stShr8
|
|
|
|
cleq r0, r0, stLowNybble
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; High nybble of high byte
|
|
|
|
cleq r0, r0, stSwap ; Clear off the word from the stack
|
|
|
|
cleq r0, r0, stShr8
|
|
|
|
cleq r0, r0, stShr4
|
|
|
|
cleq r0, r0, stLowNybble
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
breq r0, r0, stDec
|
|
|
|
|
|
|
|
; ptr -- f
|
|
|
|
fPack:
|
|
|
|
; Sign and exponent
|
|
|
|
cleq r0, r0, fPackWord
|
|
|
|
|
|
|
|
; Skip over the overflow digit
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
|
|
|
|
; Mantissa
|
|
|
|
cleq r0, r0, fPackWord
|
|
|
|
cleq r0, r0, fPackWord
|
|
|
|
cleq r0, r0, fPackWord
|
|
|
|
|
|
|
|
; Clean off the pointer from stack
|
|
|
|
breq r0, r0, popWord
|
|
|
|
|
|
|
|
; ptr -- w ptr+4
|
|
|
|
fPackWord:
|
|
|
|
; High nybble of high byte
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, stShl8
|
|
|
|
cleq r0, r0, stShl4
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
|
|
|
|
; Low nybble of high byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, stShl8
|
|
|
|
cleq r0, r0, stOr
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
|
|
|
|
; High nybble of low byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, stShl4
|
|
|
|
cleq r0, r0, stOr
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
|
|
|
|
; Low nybble of low byte
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, stOr
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stInc
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
; Unpacked floating point variables
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
fArg1Ptr: addr fArg1
|
|
|
|
fArg1:
|
|
|
|
data 00 ; sign
|
|
|
|
data 00 ; exponent
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00 ; overflow
|
|
|
|
data 00 ; mantissa
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 00 ; rounding
|
|
|
|
|
|
|
|
fResultPtr: addr fResult
|
|
|
|
fResult:
|
|
|
|
data 00 ; sign
|
|
|
|
data 05 ; exponent
|
|
|
|
data 00
|
|
|
|
data 00
|
|
|
|
data 09 ; overflow
|
|
|
|
data 09 ; mantissa
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 09
|
|
|
|
data 04 ; rounding
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
; Arithmetic
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
; x y z -- tens(x+y+z) ones(x+y+z)
|
|
|
|
bcdDigitAdd3:
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #a
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stGtEq
|
|
|
|
breq r0, r1, bcdDigitAdd
|
|
|
|
|
|
|
|
; Adjust so that carry is in the high 3 bits
|
|
|
|
; Basically we want 9+1=a₁₆ to become 20₁₆
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #16
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
; x y -- tens(x+y) ones(x+y)
|
|
|
|
bcdDigitAdd:
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
; Only look at the bottom 5 bits, since high 3 bits may already
|
|
|
|
; contain carry
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
load r2, #1f
|
|
|
|
and r1, r2
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #a
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stGtEq
|
|
|
|
breq r0, r1, bcdDigitAddNoAdjust
|
|
|
|
|
|
|
|
; Adjust so that carry is in the high 3 bits
|
|
|
|
; Basically we want 9+1=a₁₆ to become 20₁₆
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #16
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
bcdDigitAddNoAdjust:
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stShr4
|
|
|
|
cleq r0, r0, stShr1
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stLowNybble
|
|
|
|
|
|
|
|
; x -- 9-x
|
|
|
|
bcdDigit9sComplement:
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #9
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stSub
|
|
|
|
|
|
|
|
; ptr --
|
|
|
|
incExponent:
|
|
|
|
; Ones
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #3
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Tens
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Hundreds
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
brneq r0, r1, incExponentOverflow
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
incExponentOverflow:
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #2
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; ptr --
|
|
|
|
decExponent:
|
|
|
|
; Ones
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #3
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #9
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Tens
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #9
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, bcdDigitAdd3
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Ones
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #9
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, bcdDigitAdd3
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
breq r0, r1, error ; Should never underflow
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
breq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; ptr --
|
|
|
|
shiftMantissaLeft:
|
|
|
|
; Shift-in a zero to zero-out the rightmost mantissa digit
|
|
|
|
xor r0, r0
|
|
|
|
xor r1, r1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
; Starting at the end of the extended mantissa
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #11
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
; We run the loop 14 times
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #e
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
shiftMantissaLeftLoop:
|
|
|
|
; See if loop counter hit zero and decrement if not
|
|
|
|
cleq r0, r0, peekWord
|
|
|
|
or r0, r1
|
|
|
|
xor r2, r2
|
|
|
|
breq r0, r2, shiftMantissaLeftEnd
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; Load ("shift-out") the current value at pointer
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
|
|
|
|
; Store ("shift-in") the previous value
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Decrememnt pointer and put stack back in order
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
|
|
|
|
breq r0, r0, shiftMantissaLeftLoop
|
|
|
|
|
|
|
|
shiftMantissaLeftEnd:
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
breq r0, r0, popWord
|
|
|
|
|
|
|
|
; ptr --
|
|
|
|
shiftMantissaRight:
|
|
|
|
; Shift-in a zero to zero-out the leftmost mantissa digit
|
|
|
|
xor r0, r0
|
|
|
|
xor r1, r1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
; Starting at the beginning of the extended mantissa
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #4
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
; We run the loop 14 times
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #e
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
shiftMantissaRightLoop:
|
|
|
|
; See if loop counter hit zero and decrement if not
|
|
|
|
cleq r0, r0, peekWord
|
|
|
|
or r0, r1
|
|
|
|
xor r2, r2
|
|
|
|
breq r0, r2, shiftMantissaRightEnd
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
; Load ("shift-out") the current value at pointer
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
|
|
|
|
; Store ("shift-in") the previous value
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
|
|
|
|
; Increment pointer and put stack back in order
|
|
|
|
cleq r0, r0, stInc
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
|
|
|
|
breq r0, r0, shiftMantissaRightLoop
|
|
|
|
|
|
|
|
shiftMantissaRightEnd:
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
breq r0, r0, popWord
|
|
|
|
|
|
|
|
; --
|
|
|
|
normalize:
|
|
|
|
; Do we have a digit in overflow?
|
|
|
|
load r0, fResult+4
|
|
|
|
xor r1, r1
|
|
|
|
breq r0, r1, normalizeNoOverflow
|
|
|
|
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, shiftMantissaRight
|
|
|
|
cleq r0, r0, incExponent
|
|
|
|
|
|
|
|
; Did we overflow the exponent?
|
|
|
|
load r0, fResult+0
|
|
|
|
load r1, #2
|
|
|
|
breq r0, r1, normalizeEnd
|
|
|
|
|
|
|
|
normalizeNoOverflow:
|
|
|
|
; Is extended mantissa all zeroes?
|
|
|
|
load r0, fResult+4
|
|
|
|
load r1, fResult+5
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+6
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+7
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+8
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+9
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+a
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+b
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+c
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+d
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+e
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+f
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+10
|
|
|
|
or r0, r1
|
|
|
|
load r1, fResult+11
|
|
|
|
or r0, r1
|
|
|
|
|
|
|
|
xor r1, r1
|
|
|
|
brneq r0, r1, normalizeNonZero
|
|
|
|
|
|
|
|
; Zero out the entire number
|
|
|
|
; This causes sign to be 0 (non-negative), exponent -500, and
|
|
|
|
; extended mantissa 00.000000000000
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #12
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
breq r0, r0, stZeroMem ; returns
|
|
|
|
|
|
|
|
normalizeNonZero:
|
|
|
|
normalizeTooSmallMantissa:
|
|
|
|
; Do we have a zero as the digit before the point?
|
|
|
|
load r0, fResult+5
|
|
|
|
xor r1, r1
|
|
|
|
brneq r0, r1, normalizeMantissaNormalized
|
|
|
|
|
|
|
|
; Can we decrement the exponent?
|
|
|
|
load r0, fResult+1
|
|
|
|
load r1, fResult+2
|
|
|
|
or r0, r1
|
|
|
|
load r2, fResult+3
|
|
|
|
or r0, r1
|
|
|
|
|
|
|
|
xor r1, r1
|
|
|
|
breq r0, r1, normalizeMantissaNormalized
|
|
|
|
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stDup
|
|
|
|
cleq r0, r0, shiftMantissaLeft
|
|
|
|
cleq r0, r0, decExponent
|
|
|
|
|
|
|
|
breq r0, r0, normalizeTooSmallMantissa
|
|
|
|
|
|
|
|
normalizeMantissaNormalized:
|
|
|
|
; Is the rounding digit at least 5?
|
|
|
|
load r0, fResult+11
|
|
|
|
xor r1, r1
|
|
|
|
breq r0, r1, normalizeRoundDown
|
|
|
|
load r1, #1
|
|
|
|
breq r0, r1, normalizeRoundDown
|
|
|
|
load r1, #2
|
|
|
|
breq r0, r1, normalizeRoundDown
|
|
|
|
load r1, #3
|
|
|
|
breq r0, r1, normalizeRoundDown
|
|
|
|
load r1, #4
|
|
|
|
breq r0, r1, normalizeRoundDown
|
|
|
|
|
|
|
|
normalizeRoundUp:
|
|
|
|
; Pointer to last digit of non-extended mantissa
|
|
|
|
load r0, fResultPtr+0
|
|
|
|
load r1, fResultPtr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #10
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, stAdd
|
|
|
|
|
|
|
|
; Carry-in is 1 since we are rounding up
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
; Number of times to run the loop
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #d ; 12 normal mantissa + 1 overflow
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
|
|
|
|
normalizeRoundUpLoop:
|
|
|
|
cleq r0, r0, peekWord
|
|
|
|
or r0, r1
|
|
|
|
xor r2, r2
|
|
|
|
breq r0, r2, normalizeRoundUpEnd
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stLoadByte
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stOver
|
|
|
|
cleq r0, r0, stStoreByte
|
|
|
|
cleq r0, r0, stDec
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, stRot
|
|
|
|
|
|
|
|
breq r0, r0, normalizeRoundUpLoop
|
|
|
|
|
|
|
|
normalizeRoundUpEnd:
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
|
|
|
|
; Zero out the rounding digit
|
|
|
|
xor r0, r0
|
|
|
|
store fResult+11, r0
|
|
|
|
|
|
|
|
; We might have ended up with a digit in the overflow
|
|
|
|
breq r0, r0, normalize
|
|
|
|
|
|
|
|
normalizeRoundDown:
|
|
|
|
; Zero out the rounding digit
|
|
|
|
xor r0, r0
|
|
|
|
store fResult+11, r0
|
|
|
|
|
|
|
|
normalizeEnd:
|
|
|
|
ret
|
|
|
|
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
; Output
|
|
|
|
; ------------------------------------------------------------------
|
|
|
|
|
|
|
|
fPrint:
|
|
|
|
load r0, fArg1Ptr+0
|
|
|
|
load r1, fArg1Ptr+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, fUnpack
|
|
|
|
|
|
|
|
; Overflow?
|
|
|
|
load r0, fArg1+0
|
|
|
|
load r1, #2
|
|
|
|
breq r0, r1, fPrintOverflow
|
|
|
|
|
|
|
|
; Negative?
|
|
|
|
load r1, #1
|
|
|
|
brneq r0, r1, fPrintMantissa
|
|
|
|
|
|
|
|
load r0, #2d ; -
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
fPrintMantissa:
|
|
|
|
load r0, fArg1+5
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
|
|
|
|
load r0, #2e ; .
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
load r0, fArg1+6
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+7
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+8
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+9
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+a
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+b
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+c
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+d
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+e
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+f
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+10
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
|
|
|
|
fPrintExponent:
|
|
|
|
load r0, #65 ; e
|
|
|
|
store ffff, r0
|
|
|
|
|
|
|
|
; Adjust the hundreds digit for the bias
|
|
|
|
xor r0, r0,
|
|
|
|
load r1, fArg1+1
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
xor r0, r0
|
|
|
|
load r1, #5
|
|
|
|
cleq r0, r0, pushWord
|
|
|
|
cleq r0, r0, bcdDigitAdd
|
|
|
|
|
|
|
|
; Is the exponent negative?
|
|
|
|
cleq r0, r0, stSwap
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
breq r0, r1, fPrintNegativeExponent
|
|
|
|
|
|
|
|
cleq r0, r0, popWord
|
|
|
|
xor r0, r0
|
|
|
|
or r0, r1
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
|
|
|
|
load r0, fArg1+2
|
|
|
|
cleq r0, r0, writehexNybble
|
|
|
|
load r0, fArg1+3
|
|
|
|
breq r0, r0, writehexNybble
|
|
|
|
|
|
|
|
fPrintNegativeExponent:
|
|
|
|
c |