mirror of
https://github.com/blondie7575/GSCats.git
synced 2024-11-21 15:33:11 +00:00
221 lines
3.5 KiB
ArmAsm
221 lines
3.5 KiB
ArmAsm
;
|
|
; utility
|
|
; Helper routines
|
|
;
|
|
; Created by Quinn Dunki on 8/14/17
|
|
;
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; intToString
|
|
;
|
|
; PARAML0 = Number to convert
|
|
; Returns result as pascal string in intToStringResult
|
|
;
|
|
intToString:
|
|
SAVE_AXY
|
|
|
|
; Convert value to BCD digits
|
|
; This section courtesy of John Brooks
|
|
sep #9
|
|
tdc
|
|
rol PARAML0
|
|
intToStringLoop:
|
|
sta SCRATCHL
|
|
adc SCRATCHL
|
|
rol intToStringBCD
|
|
asl PARAML0
|
|
bne intToStringLoop
|
|
cld
|
|
xba
|
|
sta intToStringBCD+1
|
|
|
|
; Convert digits to characters
|
|
BITS8
|
|
|
|
; Skip leading double zeros
|
|
ldx #0
|
|
ldy #1
|
|
|
|
intToStringSkipLoop:
|
|
lda intToStringBCD,x
|
|
bne intToStringSkipSingle
|
|
inx
|
|
cpx #3
|
|
bne intToStringSkipLoop
|
|
|
|
; Special case for full zero
|
|
sty intToStringResult
|
|
lda #'0'
|
|
sta intToStringResult+1
|
|
bra intToStringDone
|
|
|
|
intToStringSkipSingle:
|
|
; Process transition from leading-zero nibble
|
|
lda intToStringBCD,x
|
|
and #$f0
|
|
bne intToStringFullDigitsLoop
|
|
lda intToStringBCD,x
|
|
clc
|
|
adc #'0'
|
|
sta intToStringResult,y
|
|
iny
|
|
inx
|
|
cpx #3
|
|
beq intToStringFinish ; Single digit number so we're done
|
|
|
|
intToStringFullDigitsLoop:
|
|
; Remaining bytes all contain two digits
|
|
lda intToStringBCD,x
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
clc
|
|
adc #'0'
|
|
sta intToStringResult,y
|
|
iny
|
|
lda intToStringBCD,x
|
|
and #$0f
|
|
clc
|
|
adc #'0'
|
|
sta intToStringResult,y
|
|
iny
|
|
inx
|
|
cpx #3
|
|
bne intToStringFullDigitsLoop
|
|
|
|
intToStringFinish:
|
|
; Store final length and we're done
|
|
dey
|
|
sty intToStringResult
|
|
|
|
intToStringDone:
|
|
BITS16
|
|
RESTORE_AXY
|
|
rts
|
|
|
|
intToStringBCD: .byte 0,0,0
|
|
intToStringPrefix: .byte 0
|
|
intToStringResult: .byte 0,0,0,0,0,0
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; mult16
|
|
;
|
|
; PARAML0 = Operand 1 (16 bits)
|
|
; PARAML1 = Operand 2 (16 bits)
|
|
; A => Op1 * Op2 (16 bits)
|
|
; Algorithm from https://apple2.gs/downloads/Programmanual.pdf
|
|
;
|
|
; Trashes X,PARAML0,PARAML1
|
|
;
|
|
mult16:
|
|
lda #0 ; Initialize result
|
|
|
|
mult16L1:
|
|
ldx PARAML0 ; Get operand 1
|
|
beq mult16Done ; If operand is zero, we're done
|
|
lsr PARAML0 ; Get low bit
|
|
bcc mult16L2 ; If clear, no additions to previous products
|
|
clc ; Otherwise add oeprand 2 to partial result
|
|
adc PARAML1
|
|
|
|
mult16L2:
|
|
asl PARAML1 ; Now shift operand 2 left for possible add next time
|
|
bra mult16L1
|
|
|
|
mult16Done:
|
|
rts
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; mult88
|
|
;
|
|
; PARAML0 = Operand 1 (8.8 fixed point)
|
|
; PARAML1 = Operand 2 (8.8 fixed point)
|
|
; A => Op1 * Op2 (8.8 fixed point)
|
|
; Substantial precision loss occurs here, but it's usually good enough
|
|
;
|
|
mult88:
|
|
lda PARAML0 ; Convert operands to 12.4
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta PARAML0
|
|
|
|
lda PARAML1
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
sta PARAML1
|
|
|
|
jsr mult16 ; Result is 8.8
|
|
rts
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; delayShort
|
|
; Sleeps for a teeny bit
|
|
;
|
|
delayShort:
|
|
SAVE_AXY
|
|
|
|
ldy #$01 ; Loop a bit
|
|
delayShortOuter:
|
|
ldx #$ff
|
|
delayShortInner:
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
dex
|
|
bne delayShortInner
|
|
dey
|
|
bne delayShortOuter
|
|
|
|
RESTORE_AXY
|
|
rts
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; delayMedium
|
|
; Sleeps for medium time (about 0.25 sec, but not calculated as such)
|
|
;
|
|
delayMedium:
|
|
SAVE_AX
|
|
|
|
ldx #$50
|
|
delayMediumInner:
|
|
jsr delayShort
|
|
dex
|
|
bne delayMediumInner
|
|
|
|
RESTORE_AX
|
|
rts
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; delayLong
|
|
; Sleeps for long time (about 1.5 sec, but not calculated as such)
|
|
;
|
|
delayLong:
|
|
SAVE_AXY
|
|
|
|
ldy #$03 ; Loop a bit
|
|
delayLongOuter:
|
|
ldx #$ff
|
|
delayLongInner:
|
|
jsr delayShort
|
|
dex
|
|
bne delayLongInner
|
|
dey
|
|
bne delayLongOuter
|
|
|
|
RESTORE_AXY
|
|
rts
|