mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-05-28 05:41:28 +00:00
Use CC65 runtime for Atari and C64 timer functions
This is just for the "C" interface of IP65. clk_timer.s replaces atr_timer.s (on Atari) and is new for the C64 (there wasn't an implementation for the "C" interface before).
This commit is contained in:
parent
673e2da011
commit
afada39f9a
|
@ -55,7 +55,8 @@ C64OBJS=\
|
||||||
cbmcharconv.o
|
cbmcharconv.o
|
||||||
|
|
||||||
C64_OBJS=\
|
C64_OBJS=\
|
||||||
c64timer.o \
|
clk_timer.o \
|
||||||
|
c64_cps.o \
|
||||||
c64_input.o
|
c64_input.o
|
||||||
|
|
||||||
A2OBJS=\
|
A2OBJS=\
|
||||||
|
@ -82,11 +83,11 @@ ATROBJS=\
|
||||||
atrcharconv.o
|
atrcharconv.o
|
||||||
|
|
||||||
ATR_OBJS=\
|
ATR_OBJS=\
|
||||||
atr_timer.o \
|
clk_timer.o \
|
||||||
atr_input.o
|
atr_input.o
|
||||||
|
|
||||||
ATRXL_OBJS=\
|
ATRXL_OBJS=\
|
||||||
atr_timer.xl.o \
|
clk_timer.xl.o \
|
||||||
atr_input.xl.o
|
atr_input.xl.o
|
||||||
|
|
||||||
VIC20OBJS=\
|
VIC20OBJS=\
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
; timer routines
|
|
||||||
;
|
|
||||||
; the timer should be a 16-bit counter that's incremented by about
|
|
||||||
; 1000 units per second. it doesn't have to be particularly accurate.
|
|
||||||
|
|
||||||
.include "atari.inc"
|
|
||||||
.include "../inc/common.i"
|
|
||||||
|
|
||||||
.export timer_init
|
|
||||||
.export timer_read
|
|
||||||
.export timer_seconds
|
|
||||||
|
|
||||||
.import _atexit
|
|
||||||
|
|
||||||
|
|
||||||
.bss
|
|
||||||
|
|
||||||
current_time_value: .res 2
|
|
||||||
current_seconds: .res 1
|
|
||||||
current_jiffies: .res 1
|
|
||||||
timer_freq: .res 1 ; VBLANK frequency: 50 - PAL, 60 - NTSC
|
|
||||||
timer_freq_reciproc:.res 1 ; reciprocal for timer_freq in ms: 20 - PAL, ~17 - NTSC
|
|
||||||
|
|
||||||
.data
|
|
||||||
|
|
||||||
vbichain: .word 0
|
|
||||||
|
|
||||||
|
|
||||||
.code
|
|
||||||
|
|
||||||
; reset timer to 0 and install handler
|
|
||||||
; inputs: none
|
|
||||||
; outputs: none
|
|
||||||
timer_init:
|
|
||||||
lda vbichain+1
|
|
||||||
bne @done
|
|
||||||
lda PAL ; hardware register describing TV system of GTIA
|
|
||||||
and #$0e ; mask out irrelevant bits
|
|
||||||
bne @ntsc
|
|
||||||
; PAL system
|
|
||||||
lda #50
|
|
||||||
sta timer_freq
|
|
||||||
lda #20
|
|
||||||
sta timer_freq_reciproc
|
|
||||||
bne @system_set
|
|
||||||
@ntsc:
|
|
||||||
; NTSC system
|
|
||||||
lda #60
|
|
||||||
sta timer_freq
|
|
||||||
lda #17
|
|
||||||
sta timer_freq_reciproc
|
|
||||||
@system_set:
|
|
||||||
lda #0 ; initialize time variables
|
|
||||||
sta current_time_value
|
|
||||||
sta current_time_value+1
|
|
||||||
sta current_seconds
|
|
||||||
sta current_jiffies
|
|
||||||
ldax VVBLKI ; IMMEDIATE VERTICAL BLANK NMI VECTOR
|
|
||||||
stax vbichain ; save old immediate vector
|
|
||||||
ldy #<timer_vbl_handler
|
|
||||||
ldx #>timer_vbl_handler
|
|
||||||
lda #6 ; STAGE 1 VBI
|
|
||||||
jsr SETVBV ; vector to set VBLANK parameters
|
|
||||||
@done:
|
|
||||||
ldax #timer_exit
|
|
||||||
jmp _atexit
|
|
||||||
|
|
||||||
timer_exit:
|
|
||||||
lda vbichain+1
|
|
||||||
beq @handler_not_installed
|
|
||||||
ldy vbichain
|
|
||||||
ldx vbichain+1
|
|
||||||
lda #6 ; STAGE 1 VBI
|
|
||||||
jsr SETVBV ; vector to set VBLANK parameters
|
|
||||||
lda #0
|
|
||||||
sta vbichain
|
|
||||||
sta vbichain+1
|
|
||||||
@handler_not_installed:
|
|
||||||
rts
|
|
||||||
|
|
||||||
; read the current timer value
|
|
||||||
; inputs: none
|
|
||||||
; outputs: AX = current timer value (roughly equal to number of milliseconds since the last call to 'timer_init')
|
|
||||||
timer_read:
|
|
||||||
ldax current_time_value
|
|
||||||
rts
|
|
||||||
|
|
||||||
; tick over the current timer value - should be called 50 or 60 times per second, depending on the TV system
|
|
||||||
; inputs: none
|
|
||||||
; outputs: none (all registers preserved, but carry flag can be modified)
|
|
||||||
timer_vbl_handler:
|
|
||||||
pha
|
|
||||||
lda timer_freq_reciproc ; ms per tick
|
|
||||||
clc
|
|
||||||
adc current_time_value
|
|
||||||
sta current_time_value
|
|
||||||
bcc :+
|
|
||||||
inc current_time_value+1
|
|
||||||
: inc current_jiffies
|
|
||||||
lda current_jiffies
|
|
||||||
cmp timer_freq ; full second?
|
|
||||||
bne @done ; no, we're done
|
|
||||||
lda #0 ; yes, increment "seconds" counter
|
|
||||||
sta current_jiffies
|
|
||||||
sed
|
|
||||||
clc
|
|
||||||
lda #$01
|
|
||||||
adc current_seconds
|
|
||||||
cld
|
|
||||||
cmp #$60
|
|
||||||
bne :+
|
|
||||||
lda #$00
|
|
||||||
: sta current_seconds
|
|
||||||
@done:
|
|
||||||
pla
|
|
||||||
jmp SYSVBV ; vector to process immediate VBLANK
|
|
||||||
|
|
||||||
timer_seconds:
|
|
||||||
lda current_seconds
|
|
||||||
rts
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-- LICENSE FOR atr_timer.s --
|
|
||||||
; The contents of this file are subject to the Mozilla Public License
|
|
||||||
; Version 1.1 (the "License"); you may not use this file except in
|
|
||||||
; compliance with the License. You may obtain a copy of the License at
|
|
||||||
; http://www.mozilla.org/MPL/
|
|
||||||
;
|
|
||||||
; Software distributed under the License is distributed on an "AS IS"
|
|
||||||
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
|
||||||
; License for the specific language governing rights and limitations
|
|
||||||
; under the License.
|
|
||||||
;
|
|
||||||
; The Original Code is ip65.
|
|
||||||
;
|
|
||||||
; The Initial Developer of the Original Code is Jonno Downes,
|
|
||||||
; jonno@jamtronix.com.
|
|
||||||
; Portions created by the Initial Developer are Copyright (C) 2009
|
|
||||||
; Jonno Downes. All Rights Reserved.
|
|
||||||
; -- LICENSE END --
|
|
13
drivers/c64_cps.s
Normal file
13
drivers/c64_cps.s
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
; implementation of __clocks_per_sec for C64
|
||||||
|
; CC65's C64 runtime library doesn't provide this function
|
||||||
|
; this file provides a version in order that clk_timer.s works without 'ifdefs'
|
||||||
|
|
||||||
|
.export __clocks_per_sec
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
__clocks_per_sec:
|
||||||
|
lda #60
|
||||||
|
rts
|
||||||
|
|
||||||
|
.end
|
171
drivers/clk_timer.s
Normal file
171
drivers/clk_timer.s
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
; timer routines
|
||||||
|
; this implementation is for Atari and C64.
|
||||||
|
; it uses parts of the C runtime library
|
||||||
|
;
|
||||||
|
; the timer should be a 16-bit counter that's incremented by about
|
||||||
|
; 1000 units per second. it doesn't have to be particularly accurate.
|
||||||
|
|
||||||
|
.include "../inc/common.i"
|
||||||
|
|
||||||
|
.export timer_init
|
||||||
|
.export timer_read
|
||||||
|
.export timer_seconds
|
||||||
|
|
||||||
|
.import __clocks_per_sec, _clock
|
||||||
|
.import tosumodeax, tosudiveax
|
||||||
|
.import pusheax, incsp4
|
||||||
|
.importzp sp, sreg
|
||||||
|
|
||||||
|
|
||||||
|
.bss
|
||||||
|
|
||||||
|
timer_freq: .res 1 ; VBLANK frequency: 50 - PAL, 60 - NTSC (Atari); always 60 (C64)
|
||||||
|
mult_temp: .res 2 ; temp var for multiplication routines
|
||||||
|
mult_temp_x:.res 1 ; another temp var for multiplication routines
|
||||||
|
|
||||||
|
|
||||||
|
.data
|
||||||
|
|
||||||
|
mult: .byte $4C ; JMP opcode
|
||||||
|
.res 2 ; address
|
||||||
|
|
||||||
|
|
||||||
|
.code
|
||||||
|
|
||||||
|
; get timer frequency and patch multiplication routine pointer
|
||||||
|
; inputs: none
|
||||||
|
; outputs: none
|
||||||
|
timer_init:
|
||||||
|
jsr __clocks_per_sec
|
||||||
|
sta timer_freq
|
||||||
|
cmp #50
|
||||||
|
beq @timer50
|
||||||
|
lda #<mult17
|
||||||
|
ldx #>mult17
|
||||||
|
bne @timerset ; jmp always
|
||||||
|
@timer50:
|
||||||
|
lda #<mult20
|
||||||
|
ldx #>mult20
|
||||||
|
@timerset:
|
||||||
|
sta mult+1
|
||||||
|
stx mult+2
|
||||||
|
rts
|
||||||
|
|
||||||
|
; read the current timer value
|
||||||
|
; inputs: none
|
||||||
|
; outputs: AX = current timer value in milliseconds
|
||||||
|
timer_read = mult
|
||||||
|
|
||||||
|
; get current seconds clock hand
|
||||||
|
; inputs: none
|
||||||
|
; outputs: A = seconds hand (in BCD, range $00..$59)
|
||||||
|
timer_seconds:
|
||||||
|
jsr _clock ; return current tick count in sreg:AX (high:low 16bits)
|
||||||
|
jsr pusheax ; push tick count onto stack
|
||||||
|
ldx #0
|
||||||
|
stx sreg
|
||||||
|
stx sreg+1
|
||||||
|
lda timer_freq
|
||||||
|
jsr tosudiveax ; dividend on stack, divisor in sreg:AX
|
||||||
|
jsr pusheax
|
||||||
|
ldx #0
|
||||||
|
stx sreg
|
||||||
|
stx sreg+1
|
||||||
|
lda #60
|
||||||
|
jsr tosumodeax ; result modulo 60
|
||||||
|
; convert to BCD, a poor man's conversion here....
|
||||||
|
cmp #50
|
||||||
|
bcs @rs_50
|
||||||
|
cmp #40
|
||||||
|
bcs @rs_40
|
||||||
|
cmp #30
|
||||||
|
bcs @rs_30
|
||||||
|
cmp #20
|
||||||
|
bcs @rs_20
|
||||||
|
cmp #10
|
||||||
|
bcs @rs_10
|
||||||
|
rts
|
||||||
|
@rs_10:
|
||||||
|
sbc #10
|
||||||
|
ora #$10
|
||||||
|
rts
|
||||||
|
@rs_20:
|
||||||
|
sbc #20
|
||||||
|
ora #$20
|
||||||
|
rts
|
||||||
|
@rs_30:
|
||||||
|
sbc #30
|
||||||
|
ora #$30
|
||||||
|
rts
|
||||||
|
@rs_40:
|
||||||
|
sbc #40
|
||||||
|
ora #$40
|
||||||
|
rts
|
||||||
|
@rs_50:
|
||||||
|
sbc #50
|
||||||
|
ora #$50
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; get the current tick count, multiply it by 20, and return the lower 16 bits
|
||||||
|
; x*20 = x*16 + x*4
|
||||||
|
; inputs: none
|
||||||
|
; outputs: AX - tick count times 20 ('milliseconds')
|
||||||
|
mult20:
|
||||||
|
jsr _clock ; return current tick count in sreg:AX (high:low 16bits)
|
||||||
|
stx mult_temp_x ; remember high byte of lower 16bits
|
||||||
|
asl a
|
||||||
|
rol mult_temp_x
|
||||||
|
asl a
|
||||||
|
rol mult_temp_x
|
||||||
|
sta mult_temp
|
||||||
|
ldx mult_temp_x
|
||||||
|
stx mult_temp+1 ; mult_temp = ticks * 4
|
||||||
|
asl a
|
||||||
|
rol mult_temp_x
|
||||||
|
asl a
|
||||||
|
rol mult_temp_x ; mult_temp_x:A = 'ticks * 16'
|
||||||
|
clc ; AX - tick count * 16, mult_temp - tick count * 4
|
||||||
|
adc mult_temp
|
||||||
|
sta mult_temp
|
||||||
|
lda mult_temp+1
|
||||||
|
adc mult_temp_x
|
||||||
|
tax
|
||||||
|
lda mult_temp
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; get the current tick count, multiply it by 17, and return the lower 16 bits
|
||||||
|
; x*17 = x*16 + x
|
||||||
|
; inputs: none
|
||||||
|
; outputs: AX - tick count times 17 ('milliseconds')
|
||||||
|
mult17:
|
||||||
|
jsr _clock ; return current tick count in sreg:AX (high:low 16bits)
|
||||||
|
sta mult_temp
|
||||||
|
stx mult_temp+1
|
||||||
|
stx mult_temp_x
|
||||||
|
.repeat 4
|
||||||
|
asl a
|
||||||
|
rol mult_temp_x
|
||||||
|
.endrepeat ; mult_temp_x:A = 'ticks * 16'
|
||||||
|
clc
|
||||||
|
adc mult_temp
|
||||||
|
sta mult_temp
|
||||||
|
lda mult_temp+1
|
||||||
|
adc mult_temp_x
|
||||||
|
tax
|
||||||
|
lda mult_temp
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
;-- LICENSE FOR clk_timer.s --
|
||||||
|
; The contents of this file are subject to the Mozilla Public License
|
||||||
|
; Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
; compliance with the License. You may obtain a copy of the License at
|
||||||
|
; http://www.mozilla.org/MPL/
|
||||||
|
;
|
||||||
|
; Software distributed under the License is distributed on an "AS IS"
|
||||||
|
; basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||||
|
; License for the specific language governing rights and limitations
|
||||||
|
; under the License.
|
||||||
|
; -- LICENSE END --
|
Loading…
Reference in New Issue
Block a user