* BLO.S MSLAMW ; yes\r
* MOVE.L D3,-(PSP) ; no, bail to bit divide\r
* BRA.S BSLASH+NATWID \r
-MSLAMW AND.L #$FFFF,D3 ; just to be safe\r
+MSLAMW:\r
+* AND.L #$FFFF,D3 ; Masking out bits doesn't make it more correct.\r
CLR.L D0 ; Clear working register\r
CLR.L D1 ; Clear result registers\r
CLR.L D2\r
MOVE.w D0,D2 ; result in place\r
CLR.W D0 ; prepare remainder\r
SWAP D0 ; final remainder is 16-bit\r
- MOVE.L D0,NATWID*2(PSP)\r
- MOVE.L D2,-(PSP) ; low word first\r
+ MOVE.L D0,NATWID(PSP) ; remainder\r
+ CLR.L (PSP)\r
+ MOVE.L D2,-(PSP) ; quotient low word first\r
MOVE.L D1,-(PSP) ; high word\r
RTS\r
*\r
-\r
+*\r
+*CSLAW: ; No run-time optimizationm something like this\r
+* MOVE.L (PSP)+,D3 ; get divisor\r
+* CLR.L D0 ; first working register\r
+* MOVE.W (PSP),D0\r
+* DIVU.W D3,D0 ; column quotient in low half-word, remainder in high\r
+* MOVE.L D0,D1 ; save remainder\r
+* SWAP D0 ; shift column quotient\r
+* MOVE.W NATWID/2(PSP),D1 ; Next column in low half\r
+* DIVU.W D3,D1\r
+* MOVE.W D1,D0 ; record column quotient in D0 low half, remainder in D1 high\r
+* MOVE.W NATWID(PSP),D1 ; Next column in low half\r
+* DIVU.W D3,D1\r
+* MOVE.L D1,D2 ; save column remainder in D2 high\r
+* SWAP D1 ; shift column quotient into D1 high\r
+* MOVE.W NATWID*3/2(PSP),D2 ; final column\r
+* DIVU.W D3,D2\r
+* MOVE.W D2,D1 ; complete the quotient\r
+* CLR.W D2 ; get rid of the quotient\r
+* SWAP D2 ; put the remainder in place\r
+* MOVE.L D2,NATWID(PSP) ; remainder\r
+* CLR.L (PSP)\r
+* MOVE.L D1,-(PSP) ; quotient low word first\r
+* MOVE.L D0,-(PSP) ; high word\r
+* RTS ; about 100~ + 4*140~ , about 660=, linear\r
+*\r
+* Would be possible to add test before divide to the above, \r
+* to run-time optimize into range of 300~ to 720~\r
+* something like this:\r
+*OSLAW: ; No run-time optimization\r
+* MOVE.L (PSP)+,D3 ; get divisor\r
+* CLR.L D0 ; first working register\r
+* MOVE.W (PSP),D0\r
+* CMP.L D0,D3 ; Anything to divide?\r
+* BLS.S OSLAW1\r
+* SWAP D0\r
+* BRA.S OSLAWD\r
+*OSLAW1 DIVU.W D3,D0 ; column quotient in low half-word, remainder in high\r
+*OSLAWD MOVE.L D0,D1 ; save remainder\r
+* SWAP D0 ; shift column quotient\r
+* MOVE.W NATWID/2(PSP),D1 ; Next column in low half\r
+* CMP.L D1,D3 ; Anything to divide?\r
+* BLS.S OSLAW2\r
+* SWAP D1 ; works because divisor is 16-bit.\r
+* BRA.S OSLAWC\r
+*OSLAW2 DIVU.W D3,D1\r
+*OSLAWC MOVE.W D1,D0 ; record column quotient in D0 low half, remainder in D1 high\r
+* MOVE.W NATWID(PSP),D1 ; Next column in low half\r
+* CMP.L D1,D3 ; Anything to divide?\r
+* BLS.S OSLAW3\r
+* SWAP D1 ; works because divisor is 16-bit.\r
+* BRA.S OSLAWB\r
+*OSLAW3 DIVU.W D3,D1\r
+*OSLAWB MOVE.L D1,D2 ; save column remainder in D2 high\r
+* SWAP D1 ; shift column quotient into D1 high\r
+* MOVE.W NATWID*3/2(PSP),D2 ; final column\r
+* CMP.L D2,D3 ; Anything to divide?\r
+* BLS.S OSLAW4\r
+* SWAP D2 ; works because divisor is 16-bit.\r
+* BRA.S OSLAWA\r
+*OSLAW4 DIVU.W D3,D2\r
+*OSLAWA MOVE.W D2,D1 ; complete the quotient\r
+* CLR.W D2 ; get rid of the quotient\r
+* SWAP D2 ; put the remainder in place\r
+* MOVE.L D2,NATWID(PSP) ; remainder\r
+* CLR.L (PSP)\r
+* MOVE.L D1,-(PSP) ; quotient low word first\r
+* MOVE.L D0,-(PSP) ; high word\r
+* RTS ; about 100~ + 4*140~ , about 660=, linear\r
+*\r
*\r
* ( ud u --- uremainder uquotient )\r
* Divides the top unsigned integer\r
USLA16 CMP.L #$10000,D3 ; 16-bit divisor?\r
BLO.S USLAW ; yes\r
MOVE.L D3,-(PSP) ; no, put divisor back and bail to bit divide\r
- BRA.S BSLASH+NATWID \r
+ BRA.s BSLASH+NATWID \r
USLAW:\r
BSR.W MSLMWT\r
MOVEM.L (PSP)+,D0/D1/D2 ; drop extra/high word of both remainder and quotient\r
MOVE.L D1,-(PSP) \r
RTS\r
*\r
-\r
-* CLR.L D0 ; working register\r
-* MOVE.W (PSP),D0 ; Start from high word\r
-* CMP.L D3,D0 ; Anything to divide?\r
-* BLO.S USLAW3\r
-* DIVU.W D3,D0\r
-*\r
-*USLAW3 SWAP D0 ; Shift the column\r
-* MOVE.W NATWID/2(PSP),D0 ; get the next column\r
-* CMP.L D3,D0 ; Anything to divide?\r
-* BLO.S USLAW2\r
-* DIVU.W D3,D0\r
-*\r
-*USLAW2 SWAP D0 ; Shift the column\r
-* MOVE.W NATWID(PSP),D0 ; get the next column\r
-* CMP.L D3,D0 ; Anything to divide?\r
-* BLO.S USLAW1\r
-* DIVU.W D3,D0\r
-*\r
-*USLAW1 SWAP D0 ; Shift the column\r
-* MOVE.W NATWID*3/2(PSP),D0 ; get the next column\r
-* CMP.L D3,D0 ; Anything to divide?\r
-* BLO.S USLAW0\r
-* DIVU.W D3,D0\r
-\r
-\r
-*\r
* ( ud_dividend u_divisor --- u_remainder u_quotient )\r
* Divides the top unsigned integer\r
* into the second and third words on the stack\r