So because I am not well behaved I avoided the issue of signed division in my Forth system, since my needs were always positive numbers.
That is until I had to work with trigonometric coordinates...
So Lee Stewart to the rescue! (again)
I found the code in FBForth to be well suited to my needs so I re-coded it in structured assembler and added a variable called FLOOR to the system that let's one switch between symmetrical and floored division.
Preliminary testing seems to show I got the logic correct but I will beat it up a bit more.
1. Never trust preliminary testing. (it didn't work for all cases)
2. Working with your own tools is "interesting".
CON: I found a bug in my cross-assembler with JLT instruction
PRO: I fixed it!
Hats off once again to Dr. Stewart.
For the record here is where the code ended up. I then use M/MOD as a primitive that can perform symmetrical or floored division (default).
M/MOD is a primitive that is used to derive the rest of the division family. ( */MOD, /MOD, / )
CODE: M/MOD ( lsb msb n3 -- rem quot)
*SP+ R1 MOV, \ POP the high word of ud to r1
*SP R2 MOV, \ move low word of ud to r2 (keep stack pos.)
TOS R3 MOV, \ DUP for sign of den
R1 W MOV, \ DUP for sign of num
R1 R5 MOV, \ DUP 2nd copy of num for symmetric sign
TOS ABS, \ force den positive
R1 0 CMPI, \ check sign of num
LT IF, \ if numerator<0
R1 INV, \ DO DABS. invert num MSB and..
R2 NEG, \ ..negate num LSB
OC IF, \ if carry=TRUE
R1 INC, \ increment num MSB
TOS R1 DIV, \ perform the division. R1=quot, R2=rem
\ * Test for negative quotient
R3 W XOR, \ compare signs of den and num
LT IF, \ if different
R1 NEG, \ negate quotient
\ check for remainder
R2 0 CMPI,
NE IF, \ if <>0
R5 8000 ANDI, \ test for numerator negative
NE IF, \ if signbit<>0
R2 NEG, \ rem. takes sign of num(symmetric)
\ * Handle floored division, if necessary
_floor @@ R0 MOV, \ symmetric or floored division?
NE IF, \ if 0, it's symmetric and we're done
W 8000 ANDI, \ use XOR result to check num and den signs
R1 DEC, \ signs different, so floor quot
R3 R2 ADD, \ rem = den + rem
R1 TOS MOV, \ quotient to tos
R2 *SP MOV, \ put remainder on open stack location
NEXT, \ we're outta here!
Edited by TheBF, Fri Nov 9, 2018 1:10 PM.