mirror of
https://github.com/nathanriggs/AppleIIAsm-Collection.git
synced 2024-12-12 01:30:00 +00:00
333 lines
7.4 KiB
Plaintext
333 lines
7.4 KiB
Plaintext
|
*
|
||
|
*``````````````````````````````*
|
||
|
* 16-BIT DIVISION: *
|
||
|
* *
|
||
|
* SDIV16, UDIV16, SREM16, AND *
|
||
|
* UREM16. *
|
||
|
*- -*
|
||
|
* SDIV16: DIVIDED 2 SIGNED BIT *
|
||
|
* WORDS AND RETURN A 16-BIT *
|
||
|
* SIGNED QUOTIENT. *
|
||
|
* *
|
||
|
* UDIV16: DIVIDE 2 UNSIGNED *
|
||
|
* 16BIT WORDS AND RETURN A *
|
||
|
* 16BIT UNSIGNED QUOTIENT. *
|
||
|
* *
|
||
|
* SREM16: DIVIDE 2 SIGNED *
|
||
|
* 16BIT WORDS AND RETURN A *
|
||
|
* 16BIT SIGNED REMAINDER. *
|
||
|
* *
|
||
|
* UREM16: DIVIDE 2 UNSIGNED *
|
||
|
* 16BIT WORKDS AND RETURN A *
|
||
|
* 16BIT UNSIGNED REMAINDER. *
|
||
|
*- -*
|
||
|
* CLOBBERS: *
|
||
|
* *
|
||
|
* FLAGS: ????---- REG: AXYM *
|
||
|
*- -*
|
||
|
* CYCLES: ??? *
|
||
|
* SIZE: *
|
||
|
*- -*
|
||
|
* USAGE: *
|
||
|
* *
|
||
|
** ALL ROUTINES USE THE SAME *
|
||
|
** FORMAT. *
|
||
|
* *
|
||
|
* LDA #>10000 *
|
||
|
* PHA *
|
||
|
* LDA #<10000 ; DIVIDEND *
|
||
|
* PHA *
|
||
|
* LDA #>1000 ; DIVISOR *
|
||
|
* PHA *
|
||
|
* LDA #<1000 *
|
||
|
* PHA *
|
||
|
* JSR UDIV16 *
|
||
|
*- -*
|
||
|
* ENTRY *
|
||
|
* *
|
||
|
* TOP OF STACK *
|
||
|
* *
|
||
|
* LOW BYTE OF RETURN ADDRESS *
|
||
|
* HI BYTE OF RETURN ADDRESS *
|
||
|
* LOW BYTE OF DIVISOR *
|
||
|
* HIGH BYTE OF DIVISOR *
|
||
|
* LOW BYTE OF DIVIDEND *
|
||
|
* HIGH BYTE OF DIVIDEND *
|
||
|
*- -*
|
||
|
* EXIT *
|
||
|
* *
|
||
|
* TOP OF STACK *
|
||
|
* *
|
||
|
* LOW BYTE OF RETURN ADDRESS *
|
||
|
* HI BYTE OF RETURN ADDRESS *
|
||
|
* *
|
||
|
* IF NO ERRORS, CARRY = 0, *
|
||
|
* ELSE CARRY=1, QUOTIENT=0, *
|
||
|
* AND REMAINDER=0 *
|
||
|
* *
|
||
|
* .Y = COUNTER; TRASH *
|
||
|
* .X = COUNTER; TRASH *
|
||
|
* .A = LOW BYTE OF RET ADDR *
|
||
|
* *
|
||
|
* [RETURN] = RESULT (2 BYTES) *
|
||
|
* [RETLEN] = 2 (RESULT LENGTH) *
|
||
|
*- -*
|
||
|
* ADAPTED FROM LEVANTHAL AND *
|
||
|
* WINTHROP'S /6502 ASSEMBLY *
|
||
|
* LANGUAGE ROUTINES/. *
|
||
|
* AS SUCH, IT MAY FALL UNDER A *
|
||
|
* DIFFERENT LICENSE UNTIL IT *
|
||
|
* IS RADICALLY REWORKED. *
|
||
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
||
|
*
|
||
|
UDIVD16
|
||
|
LDA #0
|
||
|
BEQ UDIVMD
|
||
|
UREMD16
|
||
|
LDA #2
|
||
|
UDIVMD
|
||
|
STA _RSLTI
|
||
|
*
|
||
|
** GET RETURN ADDRESS
|
||
|
*
|
||
|
PLA
|
||
|
STA RETADR
|
||
|
PLA
|
||
|
STA RETADR+1
|
||
|
*
|
||
|
** GET PARAMETERS
|
||
|
*
|
||
|
PLA
|
||
|
STA _DVSOR
|
||
|
PLA
|
||
|
STA _DVSOR+1
|
||
|
PLA
|
||
|
STA _DVEND
|
||
|
PLA
|
||
|
STA _DVEND+1
|
||
|
*
|
||
|
JSR UDIV
|
||
|
BCC DIVOK ; BR IF NO ERR
|
||
|
DIVERR JMP EREXIT
|
||
|
DIVOK JMP OKEXIT
|
||
|
*
|
||
|
** SIGNED DIVISION
|
||
|
*
|
||
|
SDIVD16
|
||
|
LDA #0 ; RESULT IS QUOTIENT
|
||
|
BEQ SDIVMD ; (INDEX=0)
|
||
|
*
|
||
|
** SIGNED REMAINDER
|
||
|
*
|
||
|
SREMD16
|
||
|
LDA #2 ; RES = REMAINDER (I=2)
|
||
|
BNE SDIVMD
|
||
|
*
|
||
|
SDIVMD
|
||
|
STA _RSLTI ;RESULT INDEX;0=Q,2=R
|
||
|
*
|
||
|
** GET RETURN ADDRESS
|
||
|
*
|
||
|
PLA
|
||
|
STA RETADR
|
||
|
PLA
|
||
|
STA RETADR+1
|
||
|
*
|
||
|
** GET PARAMETERS
|
||
|
*
|
||
|
PLA
|
||
|
STA _DVSOR
|
||
|
PLA
|
||
|
STA _DVSOR+1
|
||
|
PLA
|
||
|
STA _DVEND
|
||
|
PLA
|
||
|
STA _DVEND+1
|
||
|
*
|
||
|
*
|
||
|
** DETERMINE SIGN OF QUOTIENT BY
|
||
|
** PERFORMING AN EXCLUSIVE OR OF
|
||
|
** THE HIGH BYTES. IF THE SIGNS
|
||
|
** ARE THE SAME THEN BIT 7 WILL
|
||
|
** BE 0 AND THE QUOTIENT IS
|
||
|
** POSITIVE. IF THE SIGNS ARE
|
||
|
** DIFFERENT THEN THE QUOTIENT
|
||
|
** IS NEGATIVE.
|
||
|
*
|
||
|
LDA _DVEND+1
|
||
|
EOR _DVSOR+1
|
||
|
STA _SQUOT
|
||
|
*
|
||
|
** SIGN OF REMAINDER IS THE SIGN
|
||
|
** OF THE DIVIDEND
|
||
|
*
|
||
|
LDA _DVEND+1
|
||
|
STA _SREMD
|
||
|
*
|
||
|
** TAKE THE ABSOLUTE VALUE OF
|
||
|
** THE DIVISOR
|
||
|
*
|
||
|
LDA _DVSOR+1
|
||
|
BPL CHKDE ; BR IF ALREADY POS
|
||
|
LDA #0 ; SUB DVSOR FROM ZERO
|
||
|
SEC
|
||
|
SBC _DVSOR
|
||
|
STA _DVSOR
|
||
|
LDA #0
|
||
|
SBC _DVSOR+1
|
||
|
STA _DVSOR+1
|
||
|
*
|
||
|
** TAKE ABS VALUE OF THE DIVIDEND
|
||
|
*
|
||
|
CHKDE
|
||
|
LDA _DVEND+1
|
||
|
BPL DODIV ; BR IF DVEND IS POS
|
||
|
LDA #0 ; SUB DVEND FROM ZERO
|
||
|
SEC
|
||
|
SBC _DVEND
|
||
|
STA _DVEND
|
||
|
LDA #0
|
||
|
SBC _DVEND+1
|
||
|
STA _DVEND+1
|
||
|
*
|
||
|
** DIVIDE ABS VALUES
|
||
|
*
|
||
|
DODIV
|
||
|
JSR UDIV
|
||
|
BCS EREXIT ; EXIT IF DIV BY 0
|
||
|
*
|
||
|
** NEGATE QUOTIENT IF IT IS NEGATIVE
|
||
|
*
|
||
|
LDA _SQUOT
|
||
|
BPL DOREM ; BR IF Q IS POS
|
||
|
LDA #0
|
||
|
SEC
|
||
|
SBC _DVEND
|
||
|
STA _DVEND
|
||
|
LDA #0
|
||
|
SBC _DVEND+1
|
||
|
STA _DVEND+1
|
||
|
*
|
||
|
DOREM
|
||
|
*
|
||
|
** NEGATE REMAINDER IF IT IS NEG
|
||
|
*
|
||
|
LDA _SREMD
|
||
|
BPL OKEXIT ; BR IF REM IS POS
|
||
|
LDA #0
|
||
|
SEC
|
||
|
SBC _DVEND+2
|
||
|
STA _DVEND+2
|
||
|
LDA #0
|
||
|
SBC _DVEND+3
|
||
|
STA _DVEND+3
|
||
|
JMP OKEXIT
|
||
|
*
|
||
|
** ERROR EXIT (CARRY=1, RSLTS ARE 0)
|
||
|
*
|
||
|
EREXIT
|
||
|
LDA #0
|
||
|
STA _DVEND
|
||
|
STA _DVEND+1 ;QUOTIENT = 0
|
||
|
STA _DVEND+2
|
||
|
STA _DVEND+3 ; REMAINDER=0
|
||
|
STA RETURN
|
||
|
STA RETURN+1
|
||
|
LDA #2
|
||
|
STA RETLEN
|
||
|
SEC ; CARRY=1 IF ERROR
|
||
|
BCS DVEXIT
|
||
|
*
|
||
|
** GOOD EXIT (CARRY = 0)
|
||
|
*
|
||
|
OKEXIT
|
||
|
CLC ; CARRY = 0, NO ERRORS
|
||
|
*
|
||
|
DVEXIT
|
||
|
*
|
||
|
** STORE RESULT
|
||
|
*
|
||
|
LDX _RSLTI ;GET INDEX TO RESULT
|
||
|
; 0=QUOTIENT, 2=REMAINDER
|
||
|
*
|
||
|
** STORE RESULT
|
||
|
*
|
||
|
LDA _DVEND,X
|
||
|
TAY
|
||
|
LDA _DVEND+1,X
|
||
|
TAX
|
||
|
STY RETURN
|
||
|
STX RETURN+1
|
||
|
LDA #2
|
||
|
STA RETLEN
|
||
|
*
|
||
|
** RESTORE RETURN ADDRESS
|
||
|
*
|
||
|
LDA RETADR+1
|
||
|
PHA
|
||
|
LDA RETADR
|
||
|
PHA
|
||
|
*
|
||
|
RTS
|
||
|
*
|
||
|
********************************
|
||
|
* UDIV ROUTINE
|
||
|
********************************
|
||
|
UDIV
|
||
|
*
|
||
|
** ZERO UPPER WORD DIVIDEND
|
||
|
** THIS WILL BE CALLED
|
||
|
** DIVIDEND(1) BELOW
|
||
|
*
|
||
|
LDA #0
|
||
|
STA _DVEND+2
|
||
|
STA _DVEND+3
|
||
|
*
|
||
|
** FIRST CHECK FOR DIV BY 0
|
||
|
*
|
||
|
LDA _DVSOR
|
||
|
ORA _DVSOR+1
|
||
|
BNE OKUDIV ; BR IF DVSOR NOT 0
|
||
|
SEC
|
||
|
RTS
|
||
|
*
|
||
|
** PERFORM THE DIVISION BY
|
||
|
** TRIAL SUBTRACTIONS
|
||
|
*
|
||
|
OKUDIV
|
||
|
LDX #16 ; LOOP THROUGH 16 BITS
|
||
|
DIVLP
|
||
|
ROL _DVEND ;SHFT CARRY INTO BIT 0 OF DVEND
|
||
|
ROL _DVEND+1 ;WHICH WILL BE THE QUOTIENT AND
|
||
|
ROL _DVEND+2 ;SHFT DVEND AT THE SAME TIME
|
||
|
ROL _DVEND+3
|
||
|
CHKLT
|
||
|
SEC
|
||
|
LDA _DVEND+2
|
||
|
SBC _DVSOR
|
||
|
TAY ; SAVE LOW BYTE IN Y
|
||
|
LDA _DVEND+3
|
||
|
SBC _DVSOR+1 ;SUB HIGHBYTES W RES IN A
|
||
|
BCC DECCNT ; BR IF DVEND < DVSOR AND CARRY
|
||
|
STY _DVEND+2 ; ELSE
|
||
|
STA _DVEND+3 ;VEN(1)=DVEND(1)-DVSOR
|
||
|
*
|
||
|
DECCNT
|
||
|
DEX
|
||
|
BNE DIVLP
|
||
|
*
|
||
|
ROL _DVEND ;SHFT IN LAST CAR FOR QUOT
|
||
|
ROL _DVEND+1
|
||
|
CLC ; NO ERRORS, CLEAR CARRY
|
||
|
RTS
|
||
|
*
|
||
|
** DATA
|
||
|
*
|
||
|
_DVSOR DS 2 ; DIVISOR
|
||
|
_DVEND DS 4 ; DIVIDEND[0] AND QUOTIENT
|
||
|
; DIVIDEND[1] AND REMAINDER
|
||
|
_SQUOT DS 1 ; SIGN OF QUOTIENT
|
||
|
_SREMD DS 1 ; SIGN OF REMAINDER
|
||
|
_RSLTI DS 1 ; RESULT INDEX
|
||
|
*
|