mirror of
https://github.com/nathanriggs/AppleIIAsm-Collection.git
synced 2024-12-01 06:49:59 +00:00
875dd80998
- fixed a bunch of bugs - separated common and stdio libraries - commenting upgrades - created min versions of each library
996 lines
25 KiB
Plaintext
996 lines
25 KiB
Plaintext
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
|
|
* *
|
|
* MATH.LIB *
|
|
* *
|
|
* AUTHOR: NATHAN RIGGS *
|
|
* CONTACT: NATHAN.RIGGS@ *
|
|
* OUTLOOK.COM *
|
|
* *
|
|
* VERSION: 0.1.2 *
|
|
* DATE: 30-OCT-2018 *
|
|
* ASSEMBLER: MERLIN 8 PRO *
|
|
* *
|
|
* LICENSE: APACHE 2.0, WHERE *
|
|
* APPLICABLE. CODE INSPIRED *
|
|
* BY THE WORKS OF OTHERS MAY *
|
|
* FALL UNDER A DIFFERENT *
|
|
* LICENSE (NOTED IN ROUTINE). *
|
|
* *
|
|
* STANDARD INTEGER MATH *
|
|
* LIBRARY FOR 8-BIT AND 16-BIT *
|
|
* CALCALUATIONS, AS WELL AS *
|
|
* COMMON ROUTINES LIKE PSEUDO- *
|
|
* RANDOM NUMBER GENERATORS. *
|
|
* *
|
|
*------------------------------*
|
|
* *
|
|
* LIST OF ROUTINES *
|
|
* *
|
|
* ADD16 : 16BIT ADD *
|
|
* SUB16 : 16BIT SUBTRACT *
|
|
* MUL16 : 16BIT MULTIPLY *
|
|
* SDIV16 : 16BIT DIVIDE (SIGN) *
|
|
* UDIV16 : 16BIT DIVIDE (UNSN) *
|
|
* SREM16 : 16BIT REMNDR (SIGN) *
|
|
* UREM16 : 16BIT REMNDR (UNSN) *
|
|
* CMP16 : 16BIT COMPARE *
|
|
* RND16 : RANDOM # 0..65535 *
|
|
* *
|
|
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
|
|
*
|
|
*``````````````````````````````*
|
|
* ADD16 :: ADD 16-BIT VALUES *
|
|
*- -*
|
|
* ADDS TWO SIXTEEN BIT VALUES *
|
|
* AND RETURNS A 16 BIT VALUE *
|
|
* IN Y (LOW) AND X (HIGH). *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: ????---- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
* LDA #>1000 *
|
|
* PHA *
|
|
* LDA #<1000 *
|
|
* PHA *
|
|
* LDA #>1200 ; ADD2 *
|
|
* PHA *
|
|
* LDA #<1200 *
|
|
* PHA *
|
|
* JSR ADD16 *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* ADDEND 2 LOW BYTE *
|
|
* ADDEND 2 HIGH BYTE *
|
|
* ADDEND 1 LOW BYTE *
|
|
* ADDEND 1 HIGH BYTE *
|
|
*- -*
|
|
* EXIT *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* *
|
|
* Y = LOW BYTE OF RESULT *
|
|
* X = HIGH BYTE OF RESULT *
|
|
* A = LOW BYTE OF RET ADDR *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
* AS SUCH, THIS MAY NOT FALL *
|
|
* UNDER THE APACHE 2.0 LICENSE *
|
|
* AGREEMENT, SINCE THE BOOK *
|
|
* WAS WRITTEN BEFORE THE *
|
|
* LICENSE! *
|
|
* *
|
|
* THAT SAID, LEVENTHAL WROTE *
|
|
* THAT THE PURPOSE OF THE BOOK *
|
|
* WAS TO COPY THE SOURCE CODE, *
|
|
* AS REINVENTING THE WHEEL IS *
|
|
* TEDIOUS, AND HE PLACED NO *
|
|
* RESTRICTIONS ON ITS USE. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
ADD16
|
|
*
|
|
** GET RETURN ADDR
|
|
*
|
|
PLA
|
|
STA :RETADR
|
|
PLA
|
|
STA :RETADR+1
|
|
*
|
|
** GET PARAMETERS
|
|
*
|
|
PLA
|
|
STA :ADD2
|
|
PLA
|
|
STA :ADD2+1
|
|
PLA
|
|
STA :ADD1
|
|
PLA
|
|
STA :ADD1+1
|
|
*
|
|
LDA :ADD1
|
|
CLC
|
|
ADC :ADD2
|
|
TAY ; LOW BYTE
|
|
LDA :ADD1+1
|
|
ADC :ADD2+1
|
|
TAX ; HIGH BYTE
|
|
*
|
|
** RESTORE RETURN ADDRESS
|
|
*
|
|
LDA :RETADR+1
|
|
PHA
|
|
LDA :RETADR
|
|
PHA
|
|
*
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:RETADR DS 2
|
|
:ADD1 DS 2
|
|
:ADD2 DS 2
|
|
*
|
|
*``````````````````````````````*
|
|
* SUB16 :: SUBTRACT WORDS *
|
|
*- -*
|
|
* SUBTRACT ONE 16BIT NUMBER *
|
|
* FROM ANOTHER, RETURNING THE *
|
|
* RESULT IN X (HI) AND Y (LOW) *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: ????---- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
* LDA #>1000 ; MINU *
|
|
* PHA *
|
|
* LDA #<1000 *
|
|
* PHA *
|
|
* LDA #>500 ; SUBT *
|
|
* PHA *
|
|
* LDA #<500 *
|
|
* PHA *
|
|
* JSR SUB16 *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* LOW BYTE OF SUBTRAHEND *
|
|
* HIGH BYTE OF SUBTRAHEND *
|
|
* LOW BYTE OF MINUEND *
|
|
* HIGH BYTE OF MINUEND *
|
|
*- -*
|
|
* EXIT *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* *
|
|
* Y = RESULT LOW BYTE *
|
|
* X = RESULT HIGH BYTE *
|
|
* A = LOW BYTE OF RET ADDR *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
* AS SUCH, THIS MAY NOT FALL *
|
|
* UNDER THE APACHE 2.0 LICENSE *
|
|
* AGREEMENT, SINCE THE BOOK *
|
|
* WAS WRITTEN BEFORE THE *
|
|
* LICENSE! *
|
|
* *
|
|
* THAT SAID, LEVENTHAL WROTE *
|
|
* THAT THE PURPOSE OF THE BOOK *
|
|
* WAS TO COPY THE SOURCE CODE, *
|
|
* AS REINVENTING THE WHEEL IS *
|
|
* TEDIOUS, AND HE PLACED NO *
|
|
* RESTRICTIONS ON ITS USE. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
SUB16
|
|
*
|
|
** GET RETURN ADDRESS
|
|
*
|
|
PLA
|
|
STA :RETADR
|
|
PLA
|
|
STA :RETADR+1
|
|
*
|
|
** GET PARAMETERS
|
|
*
|
|
PLA
|
|
STA :SUBT
|
|
PLA
|
|
STA :SUBT+1 ; SUBTRAHEND
|
|
PLA
|
|
STA :MINU
|
|
PLA
|
|
STA :MINU+1 ; MINUEND
|
|
*
|
|
** MINUEND - SUBTRAHEND
|
|
*
|
|
LDA :MINU
|
|
SEC
|
|
SBC :SUBT
|
|
TAY ; LOW BYTE
|
|
LDA :MINU+1
|
|
SBC :SUBT+1
|
|
TAX ; HIGH BYTE
|
|
*
|
|
** RESTORE REUTNR ADDRESS
|
|
*
|
|
LDA :RETADR+1
|
|
PHA
|
|
LDA :RETADR
|
|
PHA
|
|
*
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:RETADR DS 2
|
|
:MINU DS 2
|
|
:SUBT DS 2
|
|
*
|
|
*``````````````````````````````*
|
|
* MUL16 :: MULTIPLY WORDS *
|
|
*- -*
|
|
* PERFORM MULTIPLICATION USING *
|
|
* THE SHIFT AND ADD ALGORITHM *
|
|
* *
|
|
* THIS ALGORITHM PRODUCES AN *
|
|
* UNSIGNED 32-BIT PRODUCT IN *
|
|
* HIPROD AND MLIER WITH HIPROD *
|
|
* BEING THE HIGH WORD. *
|
|
* *
|
|
* NOTE: WHILE THIS DOES PASS *
|
|
* THE FULL 32BIT PRODUCT BACK *
|
|
* VIA X AND Y, BUT THIS WOULD *
|
|
* RETURN FALSE RESULTS IF ONE *
|
|
* OF THE PARAMETERS HAD BEEN *
|
|
* SIGNED. THIS, USUALLY ONLY *
|
|
* THE LOW WORD IS USED. *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: ????---- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
* LDA #>1000 *
|
|
* PHA *
|
|
* LDA #<1000 ; MCAND *
|
|
* PHA *
|
|
* LDA #>3 *
|
|
* PHA *
|
|
* LDA #<3 ; MLIER *
|
|
* PHA *
|
|
* JSR MUL16 ; = 3000 *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* LOW BYTE OF MULTIPLIER *
|
|
* HIGH BYTE OF MULTIPLIER *
|
|
* LOW BYTE OF MULTIPLICAND *
|
|
* HIGH BYTE OF MULTIPLICAND *
|
|
*- -*
|
|
* EXIT *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* LOW BYTE OF PRODUCT *
|
|
* HIGH BYTE OF PRODUCT (16BIT) *
|
|
* *
|
|
* Y = LOW BYTE OF HIGH WORD *
|
|
* X = HIGH BYTE OF HIGH WORD *
|
|
* A = LOW BYTE OF RET ADDR *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
* AS SUCH, THIS MAY NOT FALL *
|
|
* UNDER THE APACHE 2.0 LICENSE *
|
|
* AGREEMENT, SINCE THE BOOK *
|
|
* WAS WRITTEN BEFORE THE *
|
|
* LICENSE! *
|
|
* *
|
|
* THAT SAID, LEVENTHAL WROTE *
|
|
* THAT THE PURPOSE OF THE BOOK *
|
|
* WAS TO COPY THE SOURCE CODE, *
|
|
* AS REINVENTING THE WHEEL IS *
|
|
* TEDIOUS, AND HE PLACED NO *
|
|
* RESTRICTIONS ON ITS USE. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
MUL16
|
|
*
|
|
** GET RETURN ADDRESS
|
|
*
|
|
PLA
|
|
STA :RETADR
|
|
PLA
|
|
STA :RETADR+1
|
|
*
|
|
** GET PARAMETERS
|
|
*
|
|
PLA
|
|
STA :MLIER
|
|
PLA
|
|
STA :MLIER+1
|
|
PLA
|
|
STA :MCAND
|
|
PLA
|
|
STA :MCAND+1
|
|
*
|
|
** PERFORM MULTIPLICATION USING THE SHIFT
|
|
** AND ADD ALGORITHM, WHICH PRODUCES AN
|
|
** UNSIGNED 32-BIT PRODUCT IN :HIPROD AND
|
|
** :MLIER WITH :HIPROD BEING THE HIGH WORD.
|
|
*
|
|
LDA #0
|
|
STA :HPROD ; ZERO HIGH WORD
|
|
STA :HPROD+1
|
|
LDX #17 ; # OF BITS IN MPLIER
|
|
; PLUS 1. EXTRA LOOP IS
|
|
; TO MOVE LAST CARRY INTO
|
|
; THE PRODUCT.
|
|
CLC ; CLEAR CARRY FOR 1ST TIME
|
|
; THROUGH LOOP.
|
|
:MULLP
|
|
*
|
|
** IF NEXT BIT = 1 THEN
|
|
** HIPROD = HIPROD+MCAND
|
|
*
|
|
ROR :HPROD+1
|
|
ROR :HPROD
|
|
ROR :MLIER+1
|
|
ROR :MLIER
|
|
BCC :DECCNT ; BR IF NEXT BIT OF
|
|
; MULTIPLIER IS 0
|
|
CLC ; NEXT BIT=1 SO ADD MCAND
|
|
; TO PRODUCT
|
|
LDA :MCAND
|
|
ADC :HPROD
|
|
STA :HPROD
|
|
LDA :MCAND+1
|
|
ADC :HPROD+1
|
|
STA :HPROD+1 ; CARRY = OVERFLOW
|
|
; FROM ADD
|
|
:DECCNT
|
|
DEX
|
|
BNE :MULLP ; CONTINUE UNTIL DONE
|
|
|
|
LDY :HPROD ; LOW BYTE OF HIGH WORD
|
|
LDX :HPROD+1 ; HIGH BYTE OF HIGH WORD
|
|
*
|
|
** PUSH LOW WORD OF PRODUCT ONTO THE STACK
|
|
*
|
|
LDA :MLIER+1
|
|
TAX
|
|
LDA :MLIER
|
|
TAY
|
|
*
|
|
** RESTORE RETURN ADDRESS
|
|
*
|
|
LDA :RETADR+1
|
|
PHA
|
|
LDA :RETADR
|
|
PHA
|
|
*
|
|
LDA :HPROD ;24BIT
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:MCAND DS 3
|
|
:MLIER DS 3
|
|
:HPROD DS 2
|
|
:RETADR DS 2
|
|
*
|
|
*``````````````````````````````*
|
|
* 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 ; DIVIDND *
|
|
* 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 *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
* AS SUCH, THIS MAY NOT FALL *
|
|
* UNDER THE APACHE 2.0 LICENSE *
|
|
* AGREEMENT, SINCE THE BOOK *
|
|
* WAS WRITTEN BEFORE THE *
|
|
* LICENSE! *
|
|
* *
|
|
* THAT SAID, LEVENTHAL WROTE *
|
|
* THAT THE PURPOSE OF THE BOOK *
|
|
* WAS TO COPY THE SOURCE CODE, *
|
|
* AS REINVENTING THE WHEEL IS *
|
|
* TEDIOUS, AND HE PLACED NO *
|
|
* RESTRICTIONS ON ITS USE. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
UDIV16
|
|
LDA #0
|
|
BEQ UDIVMD
|
|
UREM16
|
|
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
|
|
*
|
|
SDIV16
|
|
LDA #0 ; RESULT IS QUOTIENT
|
|
BEQ SDIVMD ; (INDEX=0)
|
|
*
|
|
** SIGNED REMAINDER
|
|
*
|
|
SREM16
|
|
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
|
|
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 IN STACK
|
|
*
|
|
LDA _DVEND,X
|
|
TAY
|
|
LDA _DVEND+1,X
|
|
TAX
|
|
*
|
|
** RESTORE RETURN ADDRESS
|
|
*
|
|
LDA _RETADR+1
|
|
PHA
|
|
LDA _RETADR
|
|
PHA
|
|
*
|
|
RTS
|
|
*
|
|
*
|
|
********************************
|
|
* UDIVE 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
|
|
*
|
|
** MAKING THESE GLOBAL FOR NOW WHILE I TRY TO
|
|
** UNDERSTAND THIS ALGORITHM ENOUGH TO MAKE
|
|
** IT USE LOCAL VARIABLES
|
|
*
|
|
_DVSOR DS 2 ; DIVISOR
|
|
_DVEND DS 4 ; DIVIDEND[0] AND QUOTIENT
|
|
; DIVIDEND[1] AND REMAINDER
|
|
_RETADR DS 2
|
|
_SQUOT DS 1 ; SIGN OF QUOTIENT
|
|
_SREMD DS 1 ; SIGN OF REMAINDER
|
|
_RSLTI DS 1 ; RESULT INDEX
|
|
*
|
|
*
|
|
*``````````````````````````````*
|
|
* CMP16 :: 16-BIT COMPARE *
|
|
*- -*
|
|
* COMPARE TWO 16BIT SIGNED OR *
|
|
* UNSIGNED WORDS AND RETURN *
|
|
* THE C,Z,N FLAGS AS SET OR *
|
|
* CLEARED. *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: CZN----- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
* LDA #>123 *
|
|
* PHA *
|
|
* LDA #<123 *
|
|
* PHA ; WORD 1 *
|
|
* LDA #>1023 *
|
|
* PHA *
|
|
* LDA #<1023 *
|
|
* PHA ; WORD 2 *
|
|
* JSR CMP16 *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HI BYTE OF RETURN ADDRESS *
|
|
* LOW BYTE OF WORD 2 (SUBTRA) *
|
|
* HIGH BYTE OF WORD 2 *
|
|
* LOW BYTE OF WORD 1 (MINU) *
|
|
* HIGH BYTE OF WORD 1 *
|
|
*- -*
|
|
* EXIT *
|
|
* *
|
|
* TOP OF STACK *
|
|
* *
|
|
* FLAGS RETURNED BASED ON WORD *
|
|
* 1 - WORD 2. *
|
|
* *
|
|
* IF W1 & W2 ARE 2S COMPLEMENT *
|
|
* IF W1 = W2 Z=1,N=0 *
|
|
* IF W1 > W2 Z=0,N=0 *
|
|
* IF W1 < W2 Z=0,N=1 *
|
|
* ELSE *
|
|
* IF W1 = W2 Z=1,C=1 *
|
|
* IF W1 > W2 Z=0,C=1 *
|
|
* IF W1 < W2 Z=0,C=0 *
|
|
* *
|
|
*- -*
|
|
* ADAPTED FROM LEVANTHAL AND *
|
|
* WINTHROP'S /6502 ASSEMBLY *
|
|
* LANGUAGE ROUTINES/. *
|
|
* AS SUCH, THIS MAY NOT FALL *
|
|
* UNDER THE APACHE 2.0 LICENSE *
|
|
* AGREEMENT, SINCE THE BOOK *
|
|
* WAS WRITTEN BEFORE THE *
|
|
* LICENSE! *
|
|
* *
|
|
* THAT SAID, LEVENTHAL WROTE *
|
|
* THAT THE PURPOSE OF THE BOOK *
|
|
* WAS TO COPY THE SOURCE CODE, *
|
|
* AS REINVENTING THE WHEEL IS *
|
|
* TEDIOUS, AND HE PLACED NO *
|
|
* RESTRICTIONS ON ITS USE. *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
CMP16
|
|
*
|
|
** GET RETURN ADDRESS
|
|
*
|
|
PLA
|
|
STA :RETADR
|
|
PLA
|
|
STA :RETADR+1
|
|
*
|
|
** GET PARAMETERS
|
|
*
|
|
PLA
|
|
STA :SUBT ; SUBTRAHEND
|
|
PLA
|
|
STA :SUBT+1
|
|
PLA
|
|
STA :MINU ; MINUEND
|
|
PLA
|
|
STA :MINU+1
|
|
*
|
|
** RESTORE RETURN ADDRESS
|
|
*
|
|
LDA :RETADR+1
|
|
PHA
|
|
LDA :RETADR
|
|
PHA
|
|
*
|
|
LDA :MINU
|
|
CMP :SUBT ; COMPARE LOW BYTES
|
|
BEQ :EQUAL
|
|
*
|
|
** LOW BYTES ARE NOTE EQUAL
|
|
** COMPARE HIGH BYTES
|
|
*
|
|
LDA :MINU+1
|
|
SBC :SUBT+1 ; COMPARE HIGH BYTES
|
|
ORA #1 ; MAKE Z=0, SINCE LOW
|
|
; BYTES ARE NOT EQUAL
|
|
BVS :OVFLOW ; MUST HANDLE OVERFLOW
|
|
; FOR SIGNED MATH
|
|
RTS ; EXIT
|
|
*
|
|
** LOW BYTES ARE UQAL -- COMPARE HIGH
|
|
*
|
|
:EQUAL
|
|
LDA :MINU+1
|
|
SBC :SUBT+1 ; UPPER BYTES
|
|
BVS :OVFLOW
|
|
RTS ; RETURN W FLAGS SET
|
|
*
|
|
**
|
|
** OVERFLOW WITH SIGNED ARITHMETIC SO
|
|
** COMPLEMENT THE NEGATIVE FLAG.
|
|
** DO NO CHANGE THE CARRY FLAG AND
|
|
** MAKE THE ZERO FLAG EQUAL TO 0.
|
|
** COMPLEMENT NEG FLAG BY EORING
|
|
** #$80 AND ACCUMULATOR.
|
|
**
|
|
*
|
|
:OVFLOW
|
|
EOR #$80 ; COMPLEMENT N FLAG
|
|
ORA #1 ; IF OVERFLOW THEN THE
|
|
; WORDS ARE !=. Z= 0
|
|
; CARRY UNCHANGED
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:MINU DS 2
|
|
:SUBT DS 2
|
|
:RETADR DS 2
|
|
*
|
|
*``````````````````````````````*
|
|
* RND16 : 16BIT RANDOM NUMBER *
|
|
*- -*
|
|
* GENERATE A 16BIT PSEUDO- *
|
|
* RANDOM NUMBER AND RETURN IT *
|
|
* IN Y,X (LOW, HIGH). *
|
|
* *
|
|
* ORIGINAL AUTHOR IS WHITE *
|
|
* FLAME, AS SHARED ON *
|
|
* CODEBASE64. I HAVE MADE SOME *
|
|
* MINOR ALTERATIONS, BUT NOT *
|
|
* NEARLY ENOUGH TO CALL IT MY *
|
|
* OWN. *
|
|
*- -*
|
|
* CLOBBERS: *
|
|
* *
|
|
* FLAGS: ????---- REG: AXYM *
|
|
*- -*
|
|
* CYCLES: ??? *
|
|
* SIZE: *
|
|
*- -*
|
|
* USAGE: *
|
|
* *
|
|
*- -*
|
|
* ENTRY *
|
|
* *
|
|
* LOW BYTE OF RETURN ADDRESS *
|
|
* HIGH BYTE OF RETURN ADDRESS *
|
|
*- -*
|
|
* EXIT *
|
|
* *
|
|
* Y = HIGH BYTE OF PRODUCT *
|
|
* X = LOW BYTE OF PRODUCT *
|
|
* A = LOW BYTE OF PRODUCT *
|
|
*- -*
|
|
* NOTE: THERE ARE 2048 MAGIC *
|
|
* NUMBERS THAT COULD BE EOR'D *
|
|
* TO GENERATE A PSEUDO-RANDOM *
|
|
* PATTERN THAT DOESN'T REPEAT *
|
|
* UNTIL 65535 ITERATIONS. TOO *
|
|
* MANY TO LIST HERE, BUT SOME *
|
|
* ARE: $002D, $1979, $1B47, *
|
|
* $41BB, $3D91, $B5E9, $FFEB *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
RND16
|
|
*
|
|
LDA RNDL
|
|
STA :SEED
|
|
LDA RNDH
|
|
STA :SEED+1
|
|
*
|
|
LDA :SEED
|
|
BEQ :LOW0
|
|
*
|
|
** DO A NORMAL SHIFT
|
|
*
|
|
ASL :SEED
|
|
LDA :SEED+1
|
|
ROL
|
|
BCC :NOEOR
|
|
:DOEOR ; HIGH BYTE IN A
|
|
EOR #>$0369
|
|
STA :SEED+1
|
|
LDA :SEED
|
|
EOR #<$0369
|
|
STA :SEED
|
|
JMP :EXIT
|
|
:LOW0
|
|
LDA :SEED+1
|
|
BEQ :DOEOR
|
|
ASL
|
|
BEQ :NOEOR
|
|
BCS :DOEOR
|
|
:NOEOR
|
|
STA :SEED+1
|
|
:EXIT LDX :SEED+1
|
|
LDY :SEED
|
|
RTS
|
|
*
|
|
** DATA
|
|
*
|
|
:SEED DS 2
|
|
*
|
|
*
|
|
*``````````````````````````````*
|
|
* RANDW :: RANDOM WORD *
|
|
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
|
|
*
|
|
*
|
|
** THIS WILL BE INCLUDED IN FUTURE UPDATES
|
|
*
|
|
*
|