source: buchla-68k/rom/timeint.s@ 4f508e6

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

Converted assembly language files.

  • Property mode set to 100644
File size: 10.7 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 = 0x00000400 | LONG - System timer trap vector
49
50FC_SW = 0x00000420 | WORD - Frame clock switch
51FC_VAL = 0x00000422 | LONG - Frame clock value
52
53HZ_1K = 0x0000049A | LONG - 1000 Hz clock
54HZ_200 = 0x0000049E | LONG - 200 Hz clock
55FRCLOCK = 0x000004A2 | LONG - 50 Hz clock
56
57T3COUNT = 0x000004AA | 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 = 0x00000E0C | 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 = 0x001015EE | floppy VI handler address <<<=====
75
76| ==============================================================================
77
78 .page
79
80| Hardware address equates:
81| -------------------------
82TI_VEC = 0x00000070 | Timer interrupt autovector
83
84TIMER = 0x003A0001 | Timer base address
85
86| ------------------------------------------------------------------------------
87
88| Timer register equates:
89| -----------------------
90TIME_CRX = TIMER | Control register 1 or 3
91TIME_CR2 = TIMER+2 | Control register 2
92TIME_T1H = TIMER+4 | Timer 1 high byte
93TIME_T1L = TIMER+6 | Timer 1 low byte
94TIME_T2H = TIMER+8 | Timer 2 high byte
95TIME_T2L = TIMER+10 | Timer 2 low byte
96TIME_T3H = TIMER+12 | Timer 3 high byte
97TIME_T3L = TIMER+14 | Timer 3 low byte
98
99| VSDD register offsets:
100| ----------------------
101VSDD_R5 = 10 | VSDD bank control register
102VSDD_R11 = 22 | VSDD access table register
103
104| ==============================================================================
105
106| Miscellaneous equates:
107| ----------------------
108IPL7 = 0x0700 | IPL mask for interrupt disable
109
110FCMAX = 0x00FFFFFF | Maximum frame counter value
111FCMIN = 0x00000000 | Minimum frame counter value
112
113NTIMERS = 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 #0x00,TIME_T1H | Setup timer 1 (PLL)
142 move.b #0x1F,TIME_T1L | ... for divide by 64
143 move.b #0x0C,TIME_T2H | Setup timer 2 (FC)
144 move.b #0x7F,TIME_T2L | ... for divide by 3200
145 move.b #0x03,TIME_T3H | Setup timer 3 (RTC)
146 move.b #0x20,TIME_T3L | ... for 1Ms interval
147 move.b #0x42,TIME_CRX | Setup CR3
148 move.b #0x41,TIME_CR2 | Setup CR2
149 move.b #0x81,TIME_CRX | Setup CR1
150 move.b #0x80,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.