From 8356dbbd9305d15d96ccd44ce76c7ef5f69d758b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Wed, 28 Sep 2022 02:02:30 +0300 Subject: [PATCH] Finish up normalize in calculator.asm --- calculator.asm | 439 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 408 insertions(+), 31 deletions(-) diff --git a/calculator.asm b/calculator.asm index 1073b97..633fd4a 100644 --- a/calculator.asm +++ b/calculator.asm @@ -2,10 +2,38 @@ org 0 cleq r0, r0, normalize +xor r0, r0 +load r1, #12 +cleq r0, r0, pushWord load r0, fResultPtr+0 load r1, fResultPtr+1 cleq r0, r0, pushWord +dumpFResult: + cleq r0, r0, stSwap + cleq r0, r0, peekWord + or r0, r1 + xor r2, r2 + breq r0, r2, dumpFResultEnd + 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 + breq r0, r0, dumpFResult + +dumpFResultEnd: +cleq r0, r0, newline + +load r0, fResultPtr+0 +load r1, fResultPtr+1 +cleq r0, r0, pushWord cleq r0, r0, fPack cleq r0, r0, fPrint @@ -87,6 +115,12 @@ debug: 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 @@ -415,24 +449,24 @@ fArg1: fResultPtr: addr fResult fResult: - data 01 ; sign - data 04 ; exponent - data 09 - data 09 + data 00 ; sign + data 05 ; exponent + data 00 + data 00 data 00 ; overflow - data 01 ; mantissa - data 00 - data 00 - data 00 - data 00 - data 00 - data 00 - data 00 - data 00 - data 00 - data 00 - data 01 - data 00 ; rounding + 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 @@ -495,8 +529,227 @@ bcdDigit9sComplement: 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 @@ -527,24 +780,117 @@ normalize: or r0, r1 xor r1, r1 - breq r0, r1, normalizeZero + brneq r0, r1, normalizeNonZero - ; XXX: Implement rest + ; 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 + + ; 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 - normalizeZero: - ; 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 - ; ------------------------------------------------------------------ ; Output ; ------------------------------------------------------------------ @@ -884,6 +1230,21 @@ stSwap: cleq r0, r0, tmp2LoadWord01 breq r0, r0, pushWord +; a b c -- b c a +stRot: + cleq r0, r0, popWord + cleq r0, r0, tmpStoreWord01 + cleq r0, r0, popWord + cleq r0, r0, tmp2StoreWord01 + cleq r0, r0, popWord + cleq r0, r0, tmp3StoreWord01 + cleq r0, r0, tmp2LoadWord01 + cleq r0, r0, pushWord + cleq r0, r0, tmpLoadWord01 + cleq r0, r0, pushWord + cleq r0, r0, tmp3LoadWord01 + breq r0, r0, pushWord + ; ------------------------------------------------------------------ ; Memory ; ------------------------------------------------------------------ @@ -979,6 +1340,8 @@ tmpWordHigh: data 0 tmpWordLow: data 0 tmpWord2High: data 0 tmpWord2Low: data 0 +tmpWord3High: data 0 +tmpWord3Low: data 0 ; in: ; r0:r1 = word @@ -1015,6 +1378,20 @@ tmp2LoadWord01: load r1, tmpWord2Low ret +; in: +; r0:r1 = word +tmp3StoreWord01: + store tmpWord3High, r0 + store tmpWord3Low, r1 + ret + +; out: +; r0:r1 = word +tmp3LoadWord01: + load r0, tmpWord3High + load r1, tmpWord3Low + ret + ; out: ; r0:r1 = word ; clobbers: