1
0
mirror of https://github.com/RevCurtisP/C02.git synced 2024-11-22 16:34:15 +00:00
C02/include/stdlib.a02
2018-02-02 18:02:06 -05:00

191 lines
6.3 KiB
Plaintext

; C02 library stdlib.h02 assembly language subroutines
; Requires
; external zero page locations SRCLO and srchi
; and external locations RANDOM, RDSEED, TEMP0, TEMP1, and TEMP2.
;Return ABSolute Value of Accumulator
ABS: CMP #$80 ;If Negative (High Bit Set)
BCC ABSX ; Carry will Already be Set
EOR #$FF ; One's Complement
ADC #$00 ; and Increment (Carry set by CMP)
ABSX: RTS
;Return Higher of A and Y
;Uses TEMP0
;Affects A,N,Z,C
MAX: STY TEMP0 ;Save Second Parameter
CMP TEMP0 ;If First Parameter
BCC MAXX ; Greater than Second Parameter
TYA ;Copy Second Parameter into Accumulator
MAXX: RTS
;Return Lower of A and &
;Uses TEMP0
;Affects A,N,Z,C
MIN: STY TEMP0 ;Save Second Parameter
CMP TEMP0 ;If First Parameter
BCS MINX ; Less than Second Parameter
TYA ;Copy Second Parameter into Accumulator
MINX: RTS
;Multiply A times Y
;Uses TEMP0, TEMP1
;Affects A,N,Z,C
MULT: STA TEMP0 ;Store Multiplicand
STY TEMP1 ;Store Multiplier
;Multiply TEMP0 times TEMP1
MULTT: LDA #$00 ;Initialize Accumulator
BEQ MULTE ;Enter Loop
MULTA: CLC
ADC TEMP0 ;Add Multiplicand
MULTL: ASL TEMP0 ;Shift Multiplicand Left
MULTE: LSR TEMP1 ;Shift Multiplier Right
BCS MULTA ;If Bit Shifted Out, Add Multiplicand
BNE MULTL ;Loop if Any 1 Bits Left
RTS
;Divide A by Y
;Used TEMP0,TEMP1
;Affects A,X,N,Z,C
DIV: STA TEMP0 ;Store Dividend
STY TEMP1 ;Store Divisor
;Divide TEMP0 by TEMP1
DIVT: LDA #$00 ;Clear Accumulator
LDX #$07 ;Load Loop Counter
CLC
DIVL: ROL TEMP0 ;Shift Bit Out of Dividend
ROL ; into Accumulator
CMP TEMP1 ;If Accumulator
BCC DIVS ; >= Divisor
SBC TEMP1 ;Subtract Divisor
DIVS: DEX ;Decrement Counter
BPL DIVL ; and Loop
ROL TEMP0 ;Shift Result into Dividend
LDA TEMP0 ;Load Result into Accumulator
RTS
;Generate Pseudo-Random Number between 1 and 255
;Uses RANDOM (must be non-zero on entry)
;Affects A,N,Z,C
RAND: LDA RANDOM ;Load Last Result
ASL ;Shift the Seed
BCC RANDX ;If a one was shifted out
EOR #$1D ; Twiddle the bite
RANDX: STA RANDOM ;Save the Seed
RTS
;Seed Pseudo-Random Number Generator
;Uses RDSEED (if A is zero)
;Affects A,N,Z,C
;Sets RANDOM
RANDS: ORA #$00 ;If Passed Value not 0
BNE RANDX ; Store in Seed and Return
LDA RDSEED ;Load System Generated Seed
BNE RANDX ;If Not 0, Store and Return
ADC #$01 ;Else Add 1 or 2
BNE RANDX ; then Store and Return
;Return A Shifted Y Bytes to the Left
;Affects A,Y,N,Z,C
SHIFTL: ASL ;Shift Byte to Left
DEY ;Decrement Counter
BNE SHIFTL ; and Loop if Not 0
RTS
;Return A Shifted Y Bytes to the Right
;Affects A,Y,N,Z,C
SHIFTR: LSR ;Shift Byte to Right
DEY ;Decrement Counter
BNE SHIFTL ; and Loop if Not 0
RTS
;Convert ASCII to Byte
;Uses TEMP0, TEMP1
;Affects A,X,Y,N,Z,C
ATOC: JSR SETSRC ;Initialize Source String
STY TEMP0 ;Initialize Result
ATOCL: LDA (SRCLO),Y ;Get Next Character
CMP #$30 ;If Less Than '0'
BCC ATOCX ; Exit
CMP #$3A ;If Greater Than '9'
BCS ATOCX ; Exit
AND #$0F ;Convert to Binary Nybble
STA TEMP1 ; and Save It
LDA TEMP0 ;Load Result
ASL ;Multiply by 5 by
ASL ; Multiplying by 4
ADC TEMP0 ; And Adding Itself
ASL ;Multiply that by 2
ADC TEMP1 ;Add Saved Nybble
STA TEMP0 ; and Store Result
INY ;Increment Index
BPL ATOCL ; and Loop
ATOCX: LDA TEMP0 ;Load Result
RTS ;And Return
;Convert Byte to ASCII String
;Uses SRCLO, srchi, TEMP0, TEMP1, TEMP2
;Affects A,X,Y,N,Z
CTOA: JSR SETSRC ;Initialize Source String
JSR CUBCD ;Convert Accumulator to Unpacked BCD
LDA TEMP2 ;Get High Byte
BEQ CTOA1 ;If Not Zero
JSR CTOAN ; Convert Low Nybble
CTOA1: LDA TEMP1 ;Get Low Byte
BNE CTOA2 ;If Not Zero
CMP TEMP2 ; and Hundreds
BEQ CTOA3 ; not Zero
CTOA2: JSR CTOAN ; Convert It
CTOA3: LDA TEMP0 ;Get Low Byte
JSR CTOAN ;and Convert Low Nybble
LDA #$00
BEQ CTOAX ;Terminate String
CTOAN: ORA #$30 ;Convert to ASCII digit
CTOAX: STA (SRCLO),Y ;Store in StringCTOAS: STA (SRCLO),Y ;Store in String
INY ;and Increment Offset
RTS
;Unpack 3-Digit BCD Number
;Input: TEMP1 = Low Byte
; TEMP2 = High Nybble
;Output: TEMP0 = Ones Digit
; TEMP1 = Tens Digit
; TEMP2 = Hundreds Digit
;Affects: A,N,Z
;Returns: X = 0
CUBCD: JSR CVBCD ;Convert Accumulator to BCD
UPBCD: LDA TEMP1 ;Get Low Byte
AND #$0F ;Strip High Nybbleet
STA TEMP0 ;Save in Ones
LDA TEMP1 ;Get Low Byte
LSR ;Shift High Nybble
LSR ; into Low Nybble
LSR
LSR
STA TEMP1 ;Save in Tens
RTS
;Convert Binary Number in Accumulator to Binary Coded Decimal
;Uses: TEMP0
;Returns BCD in TEMP1,temp and A,X = 0
CVBCD: STA TEMP0 ;Save Binary Value
CVBCDT: LDA #0 ;Clear BCD Bytes
STA TEMP1
STA TEMP2
LDX #8 ;Process 8 bits of Binary
SEI ;Disable Interupts
SED ;Set Decimal Mode
CVBCDL: ASL TEMP0 ;Shift High Bit Into Carry
LDA TEMP1 ;Add BCD Low Byte to Itself
ADC TEMP1 ; Plus Bit Shifted out of Binary
STA TEMP1 ; Effectively Multiplying It by 2
LDA TEMP2 ;Add BCD High Byte to Itself
ADC TEMP2 ; Plus Bit Shifted out of Low Byte
STA TEMP2 ; Effectively Multiplying It by 2
DEX ;Decrement Counter and
BNE CVBCDL ; Process Next Bit
CLD ;Clear Decimal Mode
CLI ;Enable Interrupts
RTS