mirror of
https://github.com/daniel5151/ANESE.git
synced 2025-04-02 10:32:00 -04:00
232 lines
4.7 KiB
ArmAsm
Executable file
Vendored
232 lines
4.7 KiB
ArmAsm
Executable file
Vendored
; Delays in CPU clocks, milliseconds, etc. All routines are re-entrant
|
|
; (no global data). No routines touch X or Y during execution.
|
|
; Code generated by macros is relocatable; it contains no JMPs to itself.
|
|
|
|
zp_byte delay_temp_ ; only written to
|
|
|
|
; Delays n clocks, from 2 to 16777215
|
|
; Preserved: A, X, Y, flags
|
|
.macro delay n
|
|
.if (n) < 0 .or (n) = 1 .or (n) > 16777215
|
|
.error "Delay out of range"
|
|
.endif
|
|
delay_ (n)
|
|
.endmacro
|
|
|
|
|
|
; Delays n milliseconds (1/1000 second)
|
|
; n can range from 0 to 1100.
|
|
; Preserved: A, X, Y, flags
|
|
.macro delay_msec n
|
|
.if (n) < 0 .or (n) > 1100
|
|
.error "time out of range"
|
|
.endif
|
|
delay ((n)*CLOCK_RATE+500)/1000
|
|
.endmacro
|
|
|
|
|
|
; Delays n microseconds (1/1000000 second).
|
|
; n can range from 0 to 100000.
|
|
; Preserved: A, X, Y, flags
|
|
.macro delay_usec n
|
|
.if (n) < 0 .or (n) > 100000
|
|
.error "time out of range"
|
|
.endif
|
|
delay ((n)*((CLOCK_RATE+50)/100)+5000)/10000
|
|
.endmacro
|
|
|
|
.align 128
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Delays X:A clocks+overhead
|
|
; Time: 256*X+A+30 clocks (including JSR)
|
|
; Written by Joel Yliluoma. Clobbers A,X. Preserves Y. Has relocations.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
delay_256x_a_30_clocks:
|
|
cpx #0 ; +2
|
|
beq delay_a_25_clocks ; +3 (25+5 = 30 cycles overhead)
|
|
; do 256 cycles. ; 4 cycles so far. Loop is 1+1+ 2+3+ 1+3 = 11 bytes.
|
|
dex ; 2 cycles
|
|
pha ; 3 cycles
|
|
lda #(256-25-9-2-7) ; +2
|
|
jsr delay_a_25_clocks
|
|
pla ; 4
|
|
jmp delay_256x_a_30_clocks ; 3.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Delays A:X clocks+overhead
|
|
; Time: 256*A+X+31 clocks (including JSR)
|
|
; Written by Joel Yliluoma. Clobbers A. Preserves X,Y. Has relocations.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
: ; do 256 cycles. ; 5 cycles done so far. Loop is 2+1+ 2+3+ 1 = 9 bytes.
|
|
sbc #1 ; 2 cycles - Carry was set from cmp
|
|
pha ; 3 cycles
|
|
lda #(256-25-10-2-4) ; +2
|
|
jsr delay_a_25_clocks
|
|
pla ; 4 cycles
|
|
delay_256a_x_31_clocks:
|
|
cmp #1 ; +2; 2 cycles overhead
|
|
bcs :- ; +2; 4 cycles overhead
|
|
; 0-255 cycles remain, overhead = 4
|
|
txa ; +2; 6; +25 = 31
|
|
;passthru
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
; Delays A clocks + overhead
|
|
; Preserved: X, Y
|
|
; Time: A+25 clocks (including JSR)
|
|
;;;;;;;;;;;;;;;;;;;;;;;;
|
|
: sbc #7 ; carry set by CMP
|
|
delay_a_25_clocks:
|
|
cmp #7
|
|
bcs :- ; do multiples of 7
|
|
lsr a ; bit 0
|
|
bcs :+
|
|
: ; A=clocks/2, either 0,1,2,3
|
|
beq @zero ; 0: 5
|
|
lsr a
|
|
beq :+ ; 1: 7
|
|
bcc :+ ; 2: 9
|
|
@zero: bne :+ ; 3: 11
|
|
: rts ; (thanks to dclxvi for the algorithm)
|
|
|
|
|
|
; Delays A*256 clocks + overhead
|
|
; Preserved: X, Y
|
|
; Time: A*256+16 clocks (including JSR)
|
|
delay_256a_16_clocks:
|
|
cmp #0
|
|
bne :+
|
|
rts
|
|
delay_256a_11_clocks_:
|
|
: pha
|
|
lda #256-19-22
|
|
jsr delay_a_25_clocks
|
|
pla
|
|
clc
|
|
adc #-1&$FF
|
|
bne :-
|
|
rts
|
|
|
|
|
|
|
|
; Delays A*65536 clocks + overhead
|
|
; Preserved: X, Y
|
|
; Time: A*65536+16 clocks (including JSR)
|
|
delay_65536a_16_clocks:
|
|
cmp #0
|
|
bne :+
|
|
rts
|
|
delay_65536a_11_clocks_:
|
|
: pha
|
|
lda #256-19-22-13
|
|
jsr delay_a_25_clocks
|
|
lda #255
|
|
jsr delay_256a_11_clocks_
|
|
pla
|
|
clc
|
|
adc #-1&$FF
|
|
bne :-
|
|
rts
|
|
|
|
max_short_delay = 41
|
|
; delay_short_ macro jumps into these
|
|
.res (max_short_delay-12)/2,$EA ; NOP
|
|
delay_unrolled_:
|
|
rts
|
|
|
|
|
|
;max_small_delay = 10
|
|
;.align $40
|
|
; .res (max_small_delay-2), $C9 ; cmp #imm - 2 cycles
|
|
; .byte $C5,$EA ; cmp zp - 3 cycles
|
|
;delay_unrolled_small_:
|
|
; rts
|
|
|
|
.macro delay_short_ n
|
|
.if n < 0 .or n = 1 .or n > max_short_delay
|
|
.error "Internal delay error"
|
|
.endif
|
|
.if n = 0
|
|
; nothing
|
|
.elseif n = 2
|
|
nop
|
|
.elseif n = 3
|
|
sta <delay_temp_
|
|
.elseif n = 4
|
|
nop
|
|
nop
|
|
.elseif n = 5
|
|
sta <delay_temp_
|
|
nop
|
|
.elseif n = 6
|
|
nop
|
|
nop
|
|
nop
|
|
.elseif n = 7
|
|
php
|
|
plp
|
|
.elseif n = 8
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
.elseif n = 9
|
|
php
|
|
plp
|
|
nop
|
|
.elseif n = 10
|
|
sta <delay_temp_
|
|
php
|
|
plp
|
|
.elseif n = 11
|
|
php
|
|
plp
|
|
nop
|
|
nop
|
|
.elseif n = 13
|
|
php
|
|
plp
|
|
nop
|
|
nop
|
|
nop
|
|
.elseif n & 1
|
|
sta <delay_temp_
|
|
jsr delay_unrolled_-((n-15)/2)
|
|
.else
|
|
jsr delay_unrolled_-((n-12)/2)
|
|
.endif
|
|
.endmacro
|
|
|
|
.macro delay_nosave_ n
|
|
; 65536+17 = maximum delay using delay_256a_11_clocks_
|
|
; 255+27 = maximum delay using delay_a_25_clocks
|
|
; 27 = minimum delay using delay_a_25_clocks
|
|
.if n > 65536+17
|
|
lda #^(n - 15)
|
|
jsr delay_65536a_11_clocks_
|
|
; +2 ensures remaining clocks is never 1
|
|
delay_nosave_ (((n - 15) & $FFFF) + 2)
|
|
.elseif n > 255+27
|
|
lda #>(n - 15)
|
|
jsr delay_256a_11_clocks_
|
|
; +2 ensures remaining clocks is never 1
|
|
delay_nosave_ (<(n - 15) + 2)
|
|
.elseif n >= 27
|
|
lda #<(n - 27)
|
|
jsr delay_a_25_clocks
|
|
.else
|
|
delay_short_ n
|
|
.endif
|
|
.endmacro
|
|
|
|
.macro delay_ n
|
|
.if n > max_short_delay
|
|
php
|
|
pha
|
|
delay_nosave_ (n - 14)
|
|
pla
|
|
plp
|
|
.else
|
|
delay_short_ n
|
|
.endif
|
|
.endmacro
|
|
|