]> git.the-white-hart.net Git - vhdl/commitdiff
Add divmod routine and test within emulator
authorrs <>
Fri, 10 Oct 2025 22:29:20 +0000 (17:29 -0500)
committerrs <>
Fri, 10 Oct 2025 22:29:20 +0000 (17:29 -0500)
projects/cpu_0/asm/emu.py
projects/cpu_0/asm/runtime.asm

index 8cc6832c5f35ae0e33002659b8fcfe192090ef49..ffff076ce6bd3cead9bae1b9d287b1231b746051 100755 (executable)
@@ -236,8 +236,8 @@ def main() -> int:
     emu.dump()
     emu.r_push(0xdeadbeef)
     emu.p_push(0x1234)
-    emu.p_push(0x567)
-    emu.pc = 'mul_uu'
+    emu.p_push(0x41)
+    emu.pc = 'div_uu'
     emu.dump()
 
     emu.run_until(0xdeadbeef)
index e5ad06fbe88aa47241ff71c1829226ff16b226ea..bb78d7bfd33ed5847cd8517d9bcb19c75fd40567 100644 (file)
@@ -190,7 +190,7 @@ mem_set_16:
 
 
 ( Multiply two unsigned integers )
-( a b -- b*a )
+( a b -- a*b )
 mul_uu:
     #8 0i8 ~ >r >r >r #8 0i8 ( acc ) ( ctr b a )
 .loop:
@@ -224,13 +224,49 @@ mul_uu:
     drop drop drop ;
 
 
+( Compute division with remainder of two unsigned integers )
+( a b -- a%b a/b )
+divmod_uu:
+    #8 0i8 ~ >r >r >r #8 0i8 ( rem ) ( ctr b a  )
+.loop:
+    ( rem ) ( ctr b a )
+    ( if ctr == 0 then done )
+    r> r> r> dup jz .done
+
+    ( rem a b ctr ) ( )
+    ( decrement counter )
+    lsr >r
+
+    ( rem a b ) ( ctr )
+    ( shift accumulator )
+    >r >r shl r@ #32 0x80000000i32 & jz .nocarry
+    #8 1i8 |
+.nocarry:
+    r> shl
+
+    ( rem a ) ( ctr b )
+    ( attempt subtraction )
+    >r dup r> r@ swap >r
+    ( rem rem b ) ( ctr b a )
+    swap - dup jn .next
+    swap r> #8 1i8 + >r
+.next:
+    drop
+    ( rem ) ( ctr b a )
+    jmp .loop
+
+.done:
+    ( rem a b ctr ) ( )
+    drop drop ;
+
+
 ( Divide an unsigned integer by another unsigned integer )
-( a b -- b/a )
+( a b -- a/b )
 div_uu:
-    ;
+    call divmod_uu swap drop ;
 
 
 ( Take one unsigned integer modulo another unsigned integer )
-( a b -- b%a )
+( a b -- a%b )
 mod_uu:
-    ;
+    call divmod_uu drop ;