source: buchla-68k/rom/timeint.s@ 109c83b

Last change on this file since 109c83b was 109c83b, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Compiled full ROM in Hatari.

  • Property mode set to 100644
File size: 11.2 KB
Line 
1* ------------------------------------------------------------------------------
2* timeint.s -- timer interrupt handler
3* Version 9 -- 1988-06-20 -- D.N. Lynx Crowe
4* ------------------------------------------------------------------------------
5*
6* This code replaces the interrupt handler in bios.s, which is known to
7* have a bug in it, and adds support for the VSDD and an array of programable
8* timers with 1 Ms resolution.
9*
10* WARNING: There are equates to addresses in the bios EPROM which may change
11* when the bios is reassembled. If the bios is reassembled be sure to update
12* the equates flagged by "<<<=====".
13*
14* The addresses currently in the equates are for EPROMs dated 1988-04-18 or
15* 1988-06-20 ONLY.
16*
17* ------------------------------------------------------------------------------
18* Hardware timer usage:
19* ---------------------
20* Timer 1 PLL divider for score clock -- fixed at 64
21* Timer 2 PLL divider for score clock -- nominally 3200
22* Timer 3 1 Ms Real Time Clock
23*
24* ------------------------------------------------------------------------------
25*
26 .text
27*
28 .xdef _tsetup * tsetup() -- timer setup function
29 .xdef timeint * timer interrupt handler
30*
31 .xdef _timers * timer array -- short timers[NTIMERS]
32 .xdef _vi_clk * VSDD scroll delay timer
33 .xdef _vi_tag * VSDD VI tag
34 .xdef line * Line we entered on
35*
36 .xref lclsadr * score object base address
37 .xref lclscrl * score object scroll offset
38 .xref _v_odtab * VSDD object descriptor table
39 .xref _v_regs * VSDD registers
40*
41 .page
42* ==============================================================================
43*
44* Equates to variables in bios.s:
45* -------------------------------
46* These variables are permanently assigned.
47*
48TIMEVEC .equ $00000400 * LONG - System timer trap vector
49*
50FC_SW .equ $00000420 * WORD - Frame clock switch
51FC_VAL .equ $00000422 * LONG - Frame clock value
52*
53HZ_1K .equ $0000049A * LONG - 1000 Hz clock
54HZ_200 .equ $0000049E * LONG - 200 Hz clock
55FRCLOCK .equ $000004A2 * LONG - 50 Hz clock
56*
57T3COUNT .equ $000004AA * WORD - Timer 3 count
58*
59* ------------------------------------------------------------------------------
60*
61* WARNING: The address of "FLOCK" depends on the version of the bios EPROM.
62* The address below is for EPROMs dated 1988-04-18 ONLY.
63*
64FLOCK .equ $00000E0C * WORD - Floppy semaphore <<<=====
65*
66* ==============================================================================
67*
68* Equates to routines in bios.s:
69* ------------------------------
70*
71* WARNING: The address of "FLOPVBL" depends on the version of the bios EPROM.
72* The address below is for EPROMs dated 1988-04-18 ONLY.
73*
74FLOPVBL .equ $001015EE * floppy VI handler address <<<=====
75*
76* ==============================================================================
77*
78 .page
79*
80* Hardware address equates:
81* -------------------------
82TI_VEC .equ $00000070 * Timer interrupt autovector
83*
84TIMER .equ $003A0001 * Timer base address
85*
86* ------------------------------------------------------------------------------
87*
88* Timer register equates:
89* -----------------------
90TIME_CRX .equ TIMER * Control register 1 or 3
91TIME_CR2 .equ TIMER+2 * Control register 2
92TIME_T1H .equ TIMER+4 * Timer 1 high byte
93TIME_T1L .equ TIMER+6 * Timer 1 low byte
94TIME_T2H .equ TIMER+8 * Timer 2 high byte
95TIME_T2L .equ TIMER+10 * Timer 2 low byte
96TIME_T3H .equ TIMER+12 * Timer 3 high byte
97TIME_T3L .equ TIMER+14 * Timer 3 low byte
98*
99* VSDD register offsets:
100* ----------------------
101VSDD_R5 .equ 10 * VSDD bank control register
102VSDD_R11 .equ 22 * VSDD access table register
103*
104* ==============================================================================
105*
106* Miscellaneous equates:
107* ----------------------
108IPL7 .equ $0700 * IPL mask for interrupt disable
109*
110FCMAX .equ $00FFFFFF * Maximum frame counter value
111FCMIN .equ $00000000 * Minimum frame counter value
112*
113NTIMERS .equ 8 * Number of timers in the timer array
114*
115* ==============================================================================
116*
117 .page
118* ==============================================================================
119* _tsetup -- tsetup() -- timer setup function
120* ==============================================================================
121*
122_tsetup: move.w sr,-(a7) * Save old interrupt mask
123 ori.w #IPL7,sr * Disable interrupts
124*
125 clr.w FC_SW * Stop the frame clock
126 clr.l FC_VAL * ... and reset it
127 clr.w _vi_tag * Clear VSDD VI tag
128 clr.w _vi_clk * Clear VSDD delay timer
129 clr.w lclsadr * Clear score scroll address
130 clr.w lclscrl * Clear score scroll offset
131*
132 lea _timers,a0 * Point at timer array
133 move.w #NTIMERS-1,d0 * Setup to clear timer array
134*
135tclr: clr.w (a0)+ * Clear a timer array entry
136 dbra d0,tclr * Loop until done
137*
138 move.l #nullrts,TIMEVEC * Set timer interrupt vector
139 move.l #timeint,TI_VEC * Set timer trap vector
140*
141 move.b #$00,TIME_T1H * Setup timer 1 (PLL)
142 move.b #$1F,TIME_T1L * ... for divide by 64
143 move.b #$0C,TIME_T2H * Setup timer 2 (FC)
144 move.b #$7F,TIME_T2L * ... for divide by 3200
145 move.b #$03,TIME_T3H * Setup timer 3 (RTC)
146 move.b #$20,TIME_T3L * ... for 1Ms interval
147 move.b #$42,TIME_CRX * Setup CR3
148 move.b #$41,TIME_CR2 * Setup CR2
149 move.b #$81,TIME_CRX * Setup CR1
150 move.b #$80,TIME_CRX * Start the timers
151*
152 move.w (a7)+,sr * Restore interrupts
153*
154nullrts: rts * Return to caller
155*
156 .page
157* ==============================================================================
158* timeint -- timer interrupt handler
159* ==============================================================================
160*
161timeint: movem.l d0-d7/a0-a6,-(a7) * Save registers
162 move.b TIME_CR2,d0 * Get timer interrupt status
163* ------------------------------------------------------------------------------
164* process 1 MS timer
165* ------------------------------------------------------------------------------
166 btst.l #2,d0 * Check timer 3 status
167 beq tmi02 * Jump if not active
168*
169 move.b TIME_T3H,d1 * Read timer 3 count
170 lsl.w #8,d1 * ...
171 move.b TIME_T3L,d1 * ...
172 move.w d1,T3COUNT * ... and save it
173*
174 addq.l #1,HZ_1K * Update 1ms clock (1 KHz)
175*
176 move.l d0,-(a7) * Preserve D0
177* ------------------------------------------------------------------------------
178* process VSDD timer
179* ------------------------------------------------------------------------------
180 tst.w _vi_tag * Does the VSDD need service ?
181 beq updtime * Jump if not
182*
183 move.w _vi_clk,d0 * Get VSDD scroll delay timer
184 subq.w #1,d0 * Decrement timer
185 move.w d0,_vi_clk * Update timer
186 bne updtime * Jump if it's not zero yet
187*
188 move.w lclsadr,_v_odtab+12 * Update scroll address
189 move.w lclscrl,_v_odtab+10 * Update scroll offset
190 clr.w _vi_tag * Reset the tag
191*
192 .page
193*
194* ------------------------------------------------------------------------------
195* process programable timers
196* ------------------------------------------------------------------------------
197*
198updtime: move.w #NTIMERS-1,d0 * Setup timer array counter
199 lea _timers,a0 * Point at timer array
200*
201tdcr: move.w (a0),d1 * Get timer array entry
202 beq tdcr1 * Jump if already 0
203*
204 subq.w #1,d1 * Decrement timer
205*
206tdcr1: move.w d1,(a0)+ * Store updated timer value
207 dbra d0,tdcr * Loop until done
208*
209* ------------------------------------------------------------------------------
210* process timer hook vector
211* ------------------------------------------------------------------------------
212 movea.l TIMEVEC,a0 * Get RTC vector
213 move.w #1,-(a7) * Pass 1 msec on stack
214 jsr (a0) * Process RTC vector
215 addq.l #2,a7 * Clean up stack
216*
217 move.l (a7)+,d0 * Restore D0
218*
219 .page
220* ------------------------------------------------------------------------------
221* process 5 Ms clock
222* ------------------------------------------------------------------------------
223 move.w tdiv1,d1 * Update divider
224 addq.w #1,d1 * ...
225 move.w d1,tdiv1 * ...
226*
227 cmpi.w #5,d1 * Do we need to update HZ_200 ?
228 blt tmi02 * Jump if not
229*
230 addq.l #1,HZ_200 * Update 5ms clock (200 Hz)
231* ------------------------------------------------------------------------------
232* process 20 Ms floppy clock
233* ------------------------------------------------------------------------------
234 move.w tdiv2,d1 * Update divider
235 addq.w #1,d1 * ...
236 move.w d1,tdiv2 * ...
237*
238 cmpi.w #4,d1 * Do we need to update FRCLOCK ?
239 blt tmi01 * Jump if not
240*
241 addq.l #1,FRCLOCK * Update 20 Ms clock (50 Hz)
242 tst.w FLOCK * See if floppy is active
243 bne tmi00 * Don't call FLOPVBL if so
244*
245 jsr FLOPVBL * Check on the floppy
246*
247tmi00: move.w #0,tdiv2 * Reset tdiv2
248*
249tmi01: move.w #0,tdiv1 * Reset tdiv1
250*
251 .page
252* ------------------------------------------------------------------------------
253* process PLL timers
254* ------------------------------------------------------------------------------
255*
256tmi02: btst.l #0,d0 * Check timer 1 int
257 beq tmi03 * Jump if not set
258*
259 move.b TIME_T1H,d1 * Read timer 1 to clear int.
260 move.b TIME_T1L,d1 * ...
261*
262tmi03: btst.l #1,d0 * Check for timer 2 int.
263 beq tmi04 * Jump if not set
264*
265 move.b TIME_T2H,d1 * Read timer 2 to clear int.
266 move.b TIME_T2L,d1 * ...
267*
268 .page
269* ------------------------------------------------------------------------------
270* update score frame counter
271* ------------------------------------------------------------------------------
272 tst.w FC_SW * Should we update the frame ?
273 beq tmi04 * Jump if not
274*
275 bmi tmi05 * Jump if we count down
276*
277 move.l FC_VAL,d0 * Get the frame count
278 cmp.l #FCMAX,d0 * See it we've topped out
279 bge tmi06 * Jump if limit was hit
280*
281 addq.l #1,d0 * Count up 1 frame
282 move.l d0,FC_VAL * Store updated frame count
283 bra tmi04 * Done
284*
285tmi07: move.l #FCMIN,FC_VAL * Force hard limit, just in case
286 bra tmi04 * Done
287*
288tmi06: move.l #FCMAX,FC_VAL * Force hard limit, just in case
289 bra tmi04 * Done
290*
291tmi05: move.l FC_VAL,d0 * Get the frame count
292 ble tmi07 * Done if already counted down
293*
294 subq.l #1,d0 * Count down 1 frame
295 move.l d0,FC_VAL * Store udpated frame count
296 bra tmi04 * Done
297*
298 nop * Filler to force equal paths
299*
300tmi04: movem.l (a7)+,d0-d7/a0-a6 * Restore registers
301 rte * Return to interrupted code
302*
303 .page
304* ==============================================================================
305 .bss
306* ==============================================================================
307*
308* A note on tdiv1 and tdiv2:
309* --------------------------
310*
311* tdiv1 and tdiv2 are actually defined in the bios, but since they could move
312* we define them here and ignore the ones in the bios.
313*
314tdiv1: ds.w 1 * Timer divider 1 (divides HZ_1K)
315tdiv2: ds.w 1 * Timer divider 2 (divides HZ_200)
316*
317* ------------------------------------------------------------------------------
318*
319_timers: ds.w NTIMERS * Timer array -- short timers[16];
320*
321_vi_clk: ds.w 1 * VSDD scroll delay timer
322_vi_tag: ds.w 1 * VSDD VI 'needs service' tag
323*
324bank: ds.w 1 * VSDD bank we enterd with
325line: ds.w 1 * Line we came in on (for analysis)
326* ==============================================================================
327*
328 .end
Note: See TracBrowser for help on using the repository browser.