Okay, I have an embarrassing confession ... I can't figure out how to use the IIgs monitor well enough to test this 16-bit UM/MOD ... I'm quite proficient with the original Apple monitor, but success in working the enhanced version somehow eludes me. Can anyone comment on this brutally raw attempt, and possibly give me a thumbs up or down? Garth is buried in legitimate work, and he's the only one I know with an '802/'816 Forth.
Code:
;------------------------------------------------------
; UM/MOD for the 65802/816 by Michael T. Barry.
; Free to copy and/or modify, but without warranty.
;
; ( ud u1 -- u2 u3 )
;
; ud is the 32-bit dividend.
; u1 is the 16-bit divisor.
; u2 is the 16-bit remainder.
; u3 is the 16-bit quotient.
; All values are unsigned.
;
; Quotient overflow or /0 results in a quotient and
; remainder of $FFFF. Although $FFFF could be a
; valid quotient, it cannot be a valid remainder,
; so the caller may use this fact to check for an
; invalid result.
;
; 0,x is TOS ( divisor -- quotient )
; 2,x is NOS ( hi dividend -- remainder )
; 4,x is 3OS ( lo dividend -- )
;
; Accumulator and memory are in 16-bit mode.
; Index registers are in 8-bit mode.
;
HEADER "UM/MOD", NOT_IMMEDIATE ; ( ud u -- rem quot )
CODE ; Machine code primitive.
umslashmod:
lda 2,x ; If hi cell of dividend is
cmp 0,x ; >= divisor, make a note
php ; of overflow for later.
ldy #17 ; Init loop counter.
.db $c0 ; Skip following rol.
umsm2:
rol ; Shift hi cell of dividend.
; !!!!!!!!! Bug !!!!!!!!! 17th bit is lost here !!!!!!!!!
cmp 0,x ; if (hi dividend >= divisor)
bcc umsm3 ; then update remainder
sbc 0,x ; and leave carry set
umsm3:
rol 4,x ; Shift carry into quotient.
dey ; Loop until done.
bne umsm2
plp ; Check for overflow.
bcc umsm5 ;
tya ; If so, put $ffff in
dec ; quotient and remainder.
sta 4,x ;
umsm5: ;
sta 2,x ; Save remainder in NOS.
inx ;
inx ; DROP
jmp swap ; SWAP ;
; 34 bytes, not counting HEADER.
If I made any glaring errors, I will correct them here, with appropriate credit.
Mike B.
[Edit: I've been able to play with it just a bit, and the quotient doesn't seem to be correct for any divisor other than 1 ... that could be considered a significant bug! Work continues ...]
[Edit #2: I have substituted a second (but still not tested) attempt above, completely replacing the first, which was s**t. It was inspired by
https://raw.githubusercontent.com/Acher ... muldiv.asm, but please don't hold that against White Flame if this attempt turns out to be s**t as well.]
[Edit: This version is buggy for larger inputs. See below for a properly debugged version.]