From 394137950f347a2843e18a404b677071248d7f48 Mon Sep 17 00:00:00 2001 From: CrazyEttin <> Date: Thu, 4 Aug 2022 16:04:05 +0300 Subject: [PATCH] Change the adder to a calculator capable of both adding and subtracting and move error messages to their own lines in it --- examples/{adder.asm => calc.asm} | 101 +++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 18 deletions(-) rename examples/{adder.asm => calc.asm} (80%) diff --git a/examples/adder.asm b/examples/calc.asm similarity index 80% rename from examples/adder.asm rename to examples/calc.asm index 264c0a8..9b73cb9 100644 --- a/examples/adder.asm +++ b/examples/calc.asm @@ -1,4 +1,4 @@ - ;Two-digit hexadecimal adder + ;Hexadecimal adder and subtractor for two-digit unsigned values ;Print a prompt start: load r0, prompt @@ -13,9 +13,16 @@ start: load r0, prompt ;Print a newline cleq r0, r0, newln - ;Print a plus sign - load r0, plus - store ffff, r0 + ;Read the operation sign + load r0, ffff + load r1, plus + breq r0, r1, storsg + load r1, minus + breq r0, r1, storsg + ;Error and halt if the character is not a sign + breq r0, r0, error +storsg: store sign, r0 + ;Print a space load r0, space store ffff, r0 @@ -34,19 +41,55 @@ start: load r0, prompt load r3, equals store ffff, r3 - ;Add the arguments and load the result to r3 + ;Check the operation + load r3, sign + load r1, minus + breq r1, r3, brsub + + ;Add and load the result to r3 + ;Addition cleq r0, r0, adder + ;Load the result to r3 + xor r3, r3 + xor r3, r0 + ;Skip the subtraction code + breq r0, r0, nosign + + ;Subtract and load the result to r3 + ;Subtraction +brsub: cleq r0, r0, sub + ;Load the result to r3 xor r3, r3 xor r3, r0 - ;Convert and print the result - ;Overflow + ;Print a minus sign and unnegate the result if negative + ;Check the sign xor r0, r0 + breq r0, r1, nosign + ;Print a minus sign + load r0, minus + store ffff, r0 + ;Un-negate the result + store arg1, r3 + load r2, one + cleq r0, r0, sub + nand r0, r0 + ;Reload the result to r3 + xor r3, r3 + xor r3, r0 + ;Skip printing the first digit + breq r0, r0, skip + + ;Print the overflow for addition or zero for positive results of + ;subtraction +nosign: xor r0, r0 xor r0, r1 cleq r0, r0, n2hex store ffff, r0 + + ;Convert and print the result ;Restore the result back to r0 - xor r0, r0 +skip: xor r0, r0 xor r0, r3 ;High nibble shr r0 @@ -68,6 +111,13 @@ start: load r0, prompt ;Loop breq r0, r0, start + ;Error +error: cleq r0, r0, newln + load r0, qmark + store ffff, r0 + cleq r0, r0, newln + halt + ;Read and convert an argument and load it to r0 ;First digit rarg: load r0, ffff @@ -89,10 +139,7 @@ rarg2: load r0, ffff breq r3, r1, rarg2 load r1, cr breq r3, r1, rarg3 - load r0, qmark - store ffff, r0 - cleq r0, r0, newln - halt + breq r0, r0, error ;Combine the digits rarg3: or r0, r2 ;Return @@ -151,11 +198,8 @@ hex2n: load r1, tbl01 breq r0, r1, vale load r1, tbl2b breq r0, r1, valf - ;Print a question mark and halt if the character is not a digit - load r0, qmark - store ffff, r0 - cleq r0, r0, newln - halt + ;Error and halt if the character is not a digit + breq r0, r0, error ;Load the value of the hexadecimal digit val0: load r0, tbl00 breq r0, r0, h2nend @@ -219,6 +263,25 @@ nvrflw: breq r2, r3, addend addend: load r1, ovrflw ret + ;Subtract r2 from arg1 and store the result in r0 with the sign + ;bit stored in r1 + ;Negate the second argument +sub: load r0, one + nand r2, r2 + cleq r0, r0, adder + ;Load the first argument to r2 + load r2, arg1 + ;Subtract + cleq r0, r0, adder + ;Invert the sign bit + xor r3, r3 + breq r3, r1, submin + xor r1, r1 + breq r0, r0, subend +submin: load r1, one + ;Return +subend: ret + ;Get the hexadecimal digit of a nibble ;Extract the low nibble n2hex: load r1, mask @@ -296,6 +359,7 @@ n2hend: ret space: data 20 prompt: data 3e plus: data 2b +minus: data 2d equals: data 3d qmark: data 3f backsp: data 8 @@ -357,6 +421,7 @@ tbl29: data 65 tbl2a: data f tbl2b: data 66 - ;First argument + ;Variables ovrflw: data 0 arg1: data 0 +sign: data 0