0
|
1 ********************************************************************
|
|
2 * Clock - OS-9 Level Two V3.00 Clock part 1
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Ed. Comments Who YY/MM/DD
|
|
7 * ------------------------------------------------------------------
|
|
8 * Original version KKD 87/01/01
|
|
9 * Fixed labels KDM 87/05/22
|
|
10 * Break into 2 modules KKD 88/09/29
|
|
11 * Fixed GIME IRQ toggle BRI 88/10/05
|
|
12 * Changed to TSlice = 3 BRI 88/11/12
|
|
13 * Changed to TSlice = 2 BRI 88/11/16
|
|
14 * Added F$TPS, chopped size BRI 88/12/09
|
|
15 * 14 Added F$TPS, chopped size BRI 88/12/09
|
|
16 * 15 Fixed bug where F$Link to Clock2 BRI ??/??/??
|
|
17 * was being done without switching D.Proc to the
|
|
18 * system state D.SysPrc first. This bug caused
|
|
19 * crashes in certain situations.
|
|
20 * 16 The only change in this edition is that BRI 90/04/15
|
|
21 * Simmy's F$TimAlm call has been combined into
|
|
22 * the standard F$Alarm call, with a few enhancements.
|
|
23 * The best documentation for this (it would probably
|
|
24 * be a good start on a manual page) is the comments
|
|
25 * from the source code.
|
|
26 * 17 Fixed bug where jmp [D.Crash] should instead BGP 98/10/20
|
|
27 * jmp D.Crash
|
|
28
|
|
29
|
|
30 nam Clock
|
|
31 ttl OS-9 Level Two V3.00 Clock part 1
|
|
32
|
|
33 ifp1
|
|
34 use defsfile
|
|
35 endc
|
|
36
|
|
37 edition equ 17
|
|
38
|
|
39 *******************************************************
|
|
40
|
|
41 mod len,name,systm+objct,reent+1,Init,0
|
|
42
|
|
43 *******************************************************
|
|
44
|
|
45 name fcs "Clock"
|
|
46 fcb edition
|
|
47
|
|
48 * Svc Calls:
|
|
49
|
|
50 SvcTbl fcb F$Time
|
|
51 fdb FTime-*-2
|
|
52 fcb F$STime
|
|
53 fdb FSTime-*-2
|
|
54 fcb F$VIRQ
|
|
55 fdb FVIRQ-*-2
|
|
56 fcb F$Alarm
|
|
57 fdb FAlarm-*-2
|
|
58 fcb F$TPS *** new BRI ***
|
|
59 fdb FTPS-*-2 *** new BRI ***
|
|
60 * fcb $26
|
|
61 * fdb FUnk-*-2
|
|
62 fcb $80
|
|
63
|
|
64 *---------------------------------
|
|
65 * IRQ Handler:
|
|
66 * Note NO STACK HERE!
|
|
67
|
|
68 IRQChek lda >IRQEnR get GIME irq status
|
|
69 ora <D.IRQS save it
|
|
70 bita #$08 was it VBORD irq?
|
|
71 bne L0035 ..yes, increment time
|
|
72 sta <D.IRQS
|
|
73 ldd <D.GPoll set D.SvcIRQ to GIME polling
|
|
74 bra L0043 ..and jmp D.XIRQ
|
|
75
|
|
76 * WAS VBORD IRQ so increment Time Vars:
|
|
77 L0035 anda #^$08 drop vbord irq
|
|
78 sta <D.IRQS
|
|
79 dec <D.Tick ticks-1
|
|
80 bne L0041 ..skip if not yet
|
|
81 lda #TkPerSec reset ticks to start of second
|
|
82 sta <D.Tick (also F$Alarm check flag!!)
|
|
83 L0041 ldd <D.VIRQ set alternate IRQ
|
|
84 L0043 std <D.SvcIrq for system state
|
|
85 jmp [D.XIRQ] and finish irq handling.
|
|
86
|
|
87 *---------------------------------
|
|
88 * NEW GIME irq register reset:
|
|
89
|
|
90 GPoll jsr [>D.Poll] do regular polling
|
|
91 bcc GPoll
|
|
92 GFix lda #$FE get enabled bits
|
|
93 anda <D.IRQS
|
|
94 sta <D.IRQS
|
|
95 lda <D.IRQER
|
|
96 tfr a,b copy it for GIME IRQ re-trigger
|
|
97 anda #^$01 select GIME IRQ input(s) to toggle
|
|
98 sta >IrqEnR disable selected GIME input(s)
|
|
99 stb >IrqEnR trigger GIME again
|
|
100 clrb
|
|
101 rts
|
|
102
|
|
103 *------------------------------
|
|
104 * VIRQ Handler:
|
|
105
|
|
106 VIRQChek clr ,-s clear found flag
|
|
107 lda <D.IRQS check for other irqs
|
|
108 bita #$37 any others?
|
|
109 beq L006D ..no
|
|
110 inc ,s yes, set flag
|
|
111 L006D ldy <D.CLTb point to virqtable
|
|
112 bra L008A ..begin search
|
|
113
|
|
114 * Main Loop:
|
|
115
|
|
116 L0072 ldd ,x get virq counter
|
|
117 subd #$0001 decrement
|
|
118 bne L0088 ..skip if not ready
|
|
119 inc ,s
|
|
120 lda $04,x check kill flag
|
|
121 bne L0082 ..nope
|
|
122 lbsr L01D9 ..yep, delete entry
|
|
123 L0082 ora #$01 set software irq bit
|
|
124 sta $04,x
|
|
125 ldd $02,x reset counter
|
|
126 L0088 std ,x
|
|
127 L008A ldx ,y++ last entry?
|
|
128 bne L0072 ..no
|
|
129 lda ,s+ else any found?
|
|
130 beq L0092 ..no
|
|
131 bsr GPoll
|
|
132 bra L0094
|
|
133 L0092 bsr GFix
|
|
134 L0094 jsr [>D.AltIRQ] poll keyboard
|
|
135 lda #TkPerSec
|
|
136 cmpa <D.Tick new second starting?
|
|
137 bne L011D ..not yet
|
|
138 ldd #3 gettime vector
|
|
139 lbsr L0125
|
|
140 lda <$002D
|
|
141 cmpa #$10
|
|
142 bhi L011D
|
|
143 beq L00E5
|
|
144 ldx #$1016
|
|
145 ldb ,x
|
|
146 beq L011D
|
|
147 leay -$07,x
|
|
148 bsr L00CE
|
|
149 bne L011D
|
|
150 lda <$002D
|
|
151 cmpa #$0F
|
|
152 bcs L00C5
|
|
153 tstb
|
|
154 bpl L00C5
|
|
155 clr ,x
|
|
156 L00C5 ldx >$1017
|
|
157 beq L011D
|
|
158 jsr ,x
|
|
159 bra L011D
|
|
160 L00CE ldb #$04
|
|
161 pshs x,b
|
|
162 ldx #$0028
|
|
163 L00D5 lda b,y
|
|
164 bmi L00DF
|
|
165 dec ,s
|
|
166 cmpa b,x
|
|
167 bne L00E3
|
|
168 L00DF decb
|
|
169 bpl L00D5
|
|
170 clrb
|
|
171 L00E3 puls pc,x,b
|
|
172 L00E5 ldx <$0048
|
|
173 leax <$21,x
|
|
174 L00EA lda ,-x
|
|
175 beq L0119
|
|
176 ldb #$C3
|
|
177 tfr d,y
|
|
178 lda $06,y
|
|
179 beq L0119
|
|
180 bsr L00CE
|
|
181 bne L0119
|
|
182 pshs b
|
|
183 ldd $06,y
|
|
184 exg d,y
|
|
185 clrb
|
|
186 exg d,y
|
|
187 pshs x
|
|
188 ldx <D.Proc
|
|
189 sty <D.Proc
|
|
190 os9 F$Send
|
|
191 stx <D.Proc
|
|
192 puls x
|
|
193 tst ,s+
|
|
194 bpl L0119
|
|
195 clra
|
|
196 clrb
|
|
197 std $06,y
|
|
198 L0119 cmpx <$0048
|
|
199 bhi L00EA
|
|
200 L011D jmp [D.Clock] continue w/multitasking
|
|
201
|
|
202 *--------------------------------- new!
|
|
203 * F$STime
|
|
204
|
|
205 FSTime ldx #D.Time
|
|
206 bsr Copy6
|
|
207 ldd #06 do setime in clock2:
|
|
208
|
|
209 *---------------------------------
|
|
210 * CALL CLOCK2: D=offset
|
|
211 L0125 ldx <D.Clock2 else update time vars
|
|
212 jmp d,x do it and rts
|
|
213
|
|
214 *---------------------------------
|
|
215 * F$Time
|
|
216 * Note that time is already here
|
|
217 * from once/second clock polling!
|
|
218
|
|
219 FTime ldx #D.Time point to time packet Moved ****
|
|
220 L012C ldy <D.Proc user process
|
|
221 lda <D.SysTsk from sys map
|
|
222 ldb P$Task,y to user map
|
|
223 ldu R$X,u destination=user(X)
|
|
224 bra L015B
|
|
225
|
|
226 Copy6 ldy <D.Proc calling process *** changed BRI ***
|
|
227 lda P$Task,y from user map *** changed BRI ***
|
|
228 ldb <D.SysTsk
|
|
229 ldu R$X,u packet
|
|
230 exg x,u
|
|
231 L015B ldy #6 number bytes
|
|
232 os9 F$Move get them
|
|
233 rts
|
|
234
|
|
235
|
|
236
|
|
237 *--------------------------------------------
|
|
238 * F$Alarm
|
|
239 *
|
|
240 * Note: The time packet is standard F$Time format, except seconds are always
|
|
241 * set to zero and $80 through $FF are wild cards that will match any
|
|
242 * time constant. Use of wild cards to replace one or more time
|
|
243 * constants in a time packet results in a repetitive alarm. The BELL
|
|
244 * alarm sounds once per second up to and including the 15th second in
|
|
245 * the alarm minute. Signal alarms are sent on the 16th second of the
|
|
246 * alarm minute to avoid misses when using a real-time Clock2, which may
|
|
247 * be out of sync with the internal VBORD (60 Hz) tick count.
|
|
248 * EG1: X=>$5A0216000000 sets an alarm at midnight on Feb. 22, 1990.
|
|
249 * EG2: X=>$5AFFFF0D0000 sets an alarm at 1:00 PM every day in 1990.
|
|
250 * EG3: X=>$FFFFFFFFFF00 sets an alarm at every minute.
|
|
251 *
|
|
252 * INPUT: A = alarm type or process ID
|
|
253 * B = action or signal code (depending on A)
|
|
254 * X = pointer to caller's time packet (if alarm set or return)
|
|
255 *
|
|
256 * OUTPUT: Alarm set, cleared, or returned, as follows:
|
|
257 *
|
|
258 * - if A=0:
|
|
259 * - if B=0, clear alarm
|
|
260 * - if B=1, set "BELL" alarm
|
|
261 * - D = alarm info
|
|
262 * - X = pointer to caller's 6 byte time packet
|
|
263 * - if B=2, return alarm info
|
|
264 * - D = alarm info
|
|
265 * - X = pointer to caller's 6 byte time packet
|
|
266 *
|
|
267 * - if A<>0:
|
|
268 * - A = process ID to be signalled
|
|
269 * - B = signal code to be sent
|
|
270 * - X = pointer to caller's 6 byte time packet
|
|
271 *
|
|
272 * ERROR OUTPUT: CC = Carry set
|
|
273 * B = error code
|
|
274
|
|
275 FAlarm ldx <D.Proc
|
|
276 leax >$00C3,x
|
|
277 ldd $01,u
|
|
278 beq L0167
|
|
279 tsta
|
|
280 bne L017C
|
|
281 cmpb #$01
|
|
282 beq L0179
|
|
283 cmpb #$02
|
|
284 beq L0170
|
|
285 comb
|
|
286 ldb #$BB
|
|
287 rts
|
|
288 L0167 tst $06,x
|
|
289 bne L0188
|
|
290 ldx #$100F
|
|
291 bra L0188
|
|
292 L0170 ldx #$100F
|
|
293 ldd $06,x
|
|
294 std $01,u
|
|
295 bra L012C
|
|
296 L0179 ldx #$100F
|
|
297 L017C pshs x,b,a
|
|
298 clra
|
|
299 clrb
|
|
300 std $06,x
|
|
301 bsr Copy6
|
|
302 puls x,b,a
|
|
303 clr $05,x
|
|
304 L0188 std $06,x
|
|
305 clrb
|
|
306 rts
|
|
307
|
|
308 *--------------------------------- *** new ***
|
|
309 * get ticks per second:
|
|
310
|
|
311 FTPS ldd #TkPerSec number of ticks per second
|
|
312 std R$D,u save it to caller's reg stack
|
|
313 clrb no error...
|
|
314 rts
|
|
315
|
|
316 *---------------------------------
|
|
317 FVIRQ pshs cc save irq status
|
|
318 orcc #IntMasks stop irq/firqs
|
|
319 ldy <D.CLTb point to virq table
|
|
320 ldx <D.Init and Init module
|
|
321 ldb PollCnt,x get max devices
|
|
322 ldx R$X,u get X parameter
|
|
323 beq L01C3 ..remove entry
|
|
324 tst ,y first entry empty?
|
|
325 beq L01B9 ..yes
|
|
326 subb #$02 else point to last
|
|
327 lslb entry in table
|
|
328 leay b,y
|
|
329 tst ,y empty?
|
|
330 bne L01D3 ..no, error
|
|
331 L01B3 tst ,--y found spot?
|
|
332 beq L01B3 ..no, back up
|
|
333 leay $02,y yes, reset ptr
|
|
334 L01B9 ldx R$Y,u get packet ptr
|
|
335 stx ,y set entry
|
|
336 ldd R$D,u get first count *** changed BRI ***
|
|
337 std ,x set it *** changed BRI ***
|
|
338 bra L01CF return okay.
|
|
339 L01C3 ldx R$Y,u get entry
|
|
340 L01C5 tst ,y return if
|
|
341 beq L01CF no entries
|
|
342 cmpx ,y++ else search for
|
|
343 bne L01C5 this entry
|
|
344 bsr L01D9 then remove it
|
|
345 L01CF puls cc restore intrpt status
|
|
346 clrb ok
|
|
347 rts .
|
|
348 L01D3 puls cc retrieve CC reg
|
|
349 comb set error bit
|
|
350 ldb #E$Poll 'Polling Table Full'
|
|
351 rts .
|
|
352
|
|
353 *--------------------------
|
|
354 * delete virq entry:
|
|
355
|
|
356 L01D9 pshs y,x save regs
|
|
357 L01DB ldx ,y++ move entries
|
|
358 stx -$04,y up in table
|
|
359 bne L01DB until last one (0000)
|
|
360 puls y,x
|
|
361 leay -$02,y reset table ptr
|
|
362 rts
|
|
363
|
|
364
|
|
365 *---------------------------------
|
|
366 * Clock Init:
|
|
367
|
|
368 Init clrb necessary???
|
|
369 pshs cc save intpt status
|
|
370 ldd #(TkPerSec*256)+02
|
|
371 sta <D.Tick
|
|
372 stb <D.TSlice two ticks/time slice
|
|
373 stb <D.Slice and first slice
|
|
374 orcc #IntMasks stop interrupts
|
|
375 leax >IRQChek,pcr set IRQ handler
|
|
376 stx <D.IRQ
|
|
377 leax >VIRQChek,pcr set VIRQ handler
|
|
378 stx <D.VIRQ
|
|
379 leax >GPoll,pcr set GIME irq reset
|
|
380 stx <D.GPoll
|
|
381 * install system calls
|
|
382 leay >SvcTbl,pcr insert syscalls
|
|
383 os9 F$SSvc
|
|
384 clra
|
|
385 ldx #PIA0Base point to PIA0
|
|
386 sta $01,x dir register
|
|
387 sta ,x side A are inputs
|
|
388 sta $03,x dir register
|
|
389 coma
|
|
390 sta $02,x side B outputs
|
|
391 ldd #$343C reset D
|
|
392 sta $01,x control reg
|
|
393 stb $03,x set up irq from VBORD
|
|
394 lda $02,x dummy reset
|
|
395 lda #$08
|
|
396 ora <D.IRQER get GIME IRQ reg/enable VBord irqs
|
|
397 sta <D.IRQER save shadow reg
|
|
398 sta >IRQEnR set VBorder irqs
|
|
399
|
|
400 ldx <D.Proc save user proc
|
|
401 pshs x
|
|
402 ldx <D.SysPrc make sys for link
|
|
403 stx <D.Proc
|
|
404
|
|
405 leax <Clock2,pcr
|
|
406 lda #Systm+Objct
|
|
407 os9 F$Link
|
|
408
|
|
409 * And here, we restore the original D.Proc value
|
|
410 puls x
|
|
411 stx <D.Proc restore user proc
|
|
412
|
|
413 bcs err
|
|
414 sty <D.Clock2 save exec vector
|
|
415 jsr ,y do init of clock (ignore errs)
|
|
416 puls pc,cc
|
|
417
|
|
418 err ldb #5 "no clock2" err
|
|
419 jmp D.Crash tell user the booterr
|
|
420
|
|
421 Clock2 fcs "Clock2"
|
|
422
|
|
423 emod
|
|
424 len equ *
|
|
425 end
|
|
426
|