1 * ***********************************************************
2 * * *
3 * * Copyright, C Honeywell Information Systems Inc., 1982 *
4 * * *
5 * * Copyright c 1972 by Massachusetts Institute of *
6 * * Technology and Honeywell Information Systems, Inc. *
7 * * *
8 * ***********************************************************
9
10 lbl ,scheduler
11 ttl multics/fnp scheduler and timer manager
12 pcc off
13 pmc off
14 editp on
15 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
16 *
17 * scheduler, sked
18 *
19 * This module is the scheduler and timer manager
20 * for the multics/fnp communications system mcs. it
21 * handles all interrupts and dispatches routines to
22 * process them. it also will queue routines to be run as soon
23 * as possible or delay for some time before letting them run.
24 *
25 * the timer manager handles the elapsed and interval
26 * timers, and includes mechanisms to support time outs
27 * for the control_tables and the delayed queueing for the
28 * scheduler.
29 *
30 * modified and revised 11/18/74 by mike grady
31 * modified 79 jul 26 by art beattie to add support for
32 * dn6670 extended memory.
33 *
34 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
35 rem
36 symdef sked
37 symdef invp,mdisp,msdsp
38 symdef dspqur,secdsp
39 symdef g3wjt
40 symdef simclk
41 symdef setime
42 symdef etrip
43 symdef timrjt
44 symdef skdata address of scheduler data
45 symdef etrmon pointer to ic monitoring data
46 symdef etrint elapsed timer interval
47 symdef idlmrk address of one before start of idle loop
48 symdef idloop address of start of idle loop
49 symdef idlend address of end of idle loop
50 symdef idlint idle metering interval used by init
51 symdef idlcnt idle loop count used by init
52 symdef idlmax idle loop maximum count set by init
53 symdef idlmin idle loop minimum count set by init
54 rem
55 symref trace
56 symref chkiv
57 symref hintr
58 symref dterm
59 symref dmail
60 symref lip
61 symref consol
62 symref tdip
63 symref getbuf
64 symref frelbf
65 symref itmout
66 symref icmon
67 symref gettib
68 symref setptw set up variable cpu page table word
69 rem
70 rem
71 pmc save,on
72 systm
73 tib
74 hwcm
75 comreg
76 pmc restore
77 ttls symbol definitions
78 rem dsptab symbol definitions
79 rem
80 crtwd equ 0 control word
81 prent equ 1 primary entry point
82 scent equ 2 secondary entry point
83 rqcnt equ 3 request count
84 rem
85 rem where the control word has the following
86 rem format:
87 rem
88 rem bit - 0 ** request bit
89 rem 1 ** execution bit
90 rem 2 ** secondary entry pt. present
91 rem 3-17 ** suppression bits
92 rem
93 rem
94 rem dattab symbol definitions
95 rem
96 stadd equ 0 starting add. for list of data
97 entcnt equ 1 entry count
98 excnt equ 2 exit count
99 msk equ 3 count mask
100 rem
101 rem
102 rem dispatcher queuer symbol definitions
103 rem
104 dqlink equ 0 link word
105 dqrtn equ 1 routine address
106 dqx1 equ 2 x1 - passed to routine when run
107 dqpri equ 3 priority
108 rem
109 nmqlk equ 10 number of permanent queue links
110 nmdqlk equ 20 number of permanent delay queue links
111 rem
112 rem assigned locations in interrupt saver blocks
113 rem
114 intx1 equ 0 x1
115 intx2 equ 1 x2
116 intx3 equ 2 x3
117 inta equ 3 a reg.
118 intq equ 4 q reg.
119 intir equ 5 indicator reg.
120 intic equ 6 ic at interrupt
121 intptw equ 7 cpu ptw at interrupt
122 intbpw equ 8 buffering ptw at interrupt
123 rem
124 rem
125 rem miscellaneous
126 rem
127 bufsiz equ 32
128 dqlpb equ bufsiz/4 dispatcher links/buffer
129 rem
130 modtmr equ 5
131 rem
132 rem control word symbol definitions
133 rem
134 rqstbt bool 400000 request bit
135 exctbt bool 200000 execute bit
136 scdent bool 100000 secondary entry present
137 suprmk bool /rqstbt*/exctbt*/scdent suppression mask
138 rem
139 rem mask bits for jump table data
140 rem
141 iocmk bool 740000 mask for ioc#
142 clmmk bool 30000 mask for clm#
143 clmsmk bool 7600 mask for clmsc#
144 modmk bool 77 mask for mod#
145 rem
146 rem dispatcher priority definitions
147 rem
148 intpri bool 7 priority of interpreter
149 itpri bool 4 interval timer priority
150 rem
151 base 8 temporary for debugging
152 ttls trace types and switches
153 rem
154 tt.int equ 1 trace interrupts
155 tt.idl equ 2 trace idle time
156 tt.run equ 3 trace running of interrupt rtn
157 tt.rst equ 4 trace restart of interrupted routine
158 tt.rnq equ 5 trace running of queued routine
159 tt.set equ 6 trace set timer calls
160 tt.itr equ 7 trace interval timer runouts
161 tt.que equ 8 trace dspqur entries
162 rem
163 rem
164 ts.int bool 000002
165 ts.skd bool 000004
166 ts.tim bool 000010
167 ttls various scheduler macros
168 rem
169 mpy macro multiplier location-*
170 mpf #1
171 lrl 1
172 endm mpy
173 rem
174 rem
175 dvd macro divisor location-*
176 qls 1
177 dvf #1
178 endm dvd
179 rem
180 rem
181 dspm macro
182 oct 0
183 zero #1
184 oct 0,0
185 endm
186 rem
187 rem
188 chkivs macro
189 tsy 2,*
190 tra 2
191 ind chkiv
192 endm chkivs
193 rem
194 rem
195 datm macro
196 pcc save,off
197 pmc save,off
198 offset set 0
199 count set 0
200 pmc restore
201 dattab null
202 idrp #1
203 zero data+offset
204 dec 0,0,#1
205 pmc save,off
206 offset set offset+#1
207 count set count+1
208 pmc restore
209 idrp
210 odd
211 savtab bss 10*count
212 rem
213 data bss offset
214 pcc restore
215 endm
216 eject
217 cmpaq macro
218 crsm off
219 ife '#2','',2
220 cmpa #1
221 ife 1,2,1
222 cmpa #1,#2
223 tnz 2
224 ife '#2','',2
225 cmpq #1+1
226 ife 1,2,1
227 cmpq #1+1,#2
228 crsm on
229 endm cmpaq
230 rem
231 rem
232 tblk macro number of blocks to create
233 tcnt set #1-1
234 dup 2,tcnt
235 zero *+2
236 oct 0
237 oct 0,0
238 endm tblk
239 rem
240 rem
241 dlyblk macro number of blocks to create
242 dcnt set #1-1
243 dup 4,dcnt
244 zero *+6
245 oct 0
246 oct 0,0
247 oct 0,0
248 oct 0,0
249 oct 0,0
250 oct 0,0
251 endm dlyblk
252 ttls links macro
253 rem
254 rem this macro is used to generate linked buffers.
255 rem the calling sequence is
256 rem
257 rem links n,l
258 rem
259 rem n is the number of buffers to generate
260 rem l is the length of each buffer
261 rem the first word of each buffer points to the
262 rem first word of the next buffer. the last
263 rem buffer has a pointer of zero
264 rem
265 links macro
266 pmc save,off
267 dup 2,#1-1
268 zero *+#2
269 bss #2-1
270 zero 0
271 bss #2-1
272 pmc restore
273 endm links
274 ttls common area for invp, savreg and mdisp
275 rem
276 sked null
277 rem
278 even
279 indreg oct indicator register save-store
280 icreg oct ic of the interrupt
281 modsv oct temporary save locations
282 dtsv oct x
283 asv oct x
284 qsv oct x
285 x1sv oct x
286 zerow oct a zero word always
287 reqbt vfd 18/rqstbt request bit
288 excmsk vfd 18/exctbt execute bit
289 secmsk vfd 18/scdent secondary entry present
290 supmsk vfd 18/suprmk suppression mask
291 dstnum oct number of interrupted module
292 rem
293 dspta zero dsptab address of dsptab
294 datta zero dattab " " dattab
295 savra zero savtab address of savtabmust start on odd loc.
296 dspi ind dsptab,1 indirect word for dsptab
297 rem
298 rem at end of dsptab insert:
299 rem dspsz zero *-dsptab
300 rem
301 rem
302 start sked,1
303 ttls interrupt vector processor
304 rem
305 ***********************************************************
306 *
307 * invp
308 *
309 * input
310 * address of third word of jump table
311 * stored in invp.
312 *
313 * format of jump table:
314 *
315 * 1 - zero ic at interrupt
316 * 2 - tsy invp-*
317 * 3 - ioc#, clm#, clmsc#, mod#
318 *
319 * bit # 4 , 2 , 5 , 7
320 *
321 ***********************************************************
322 invp zero add. of third word of jump table
323 sti indreg-* save indicator register
324 inh inhibit on
325 staq asv-* temp. save a register
326 stx1 x1sv-* and x1 register
327 rem
328 * chkivs
329 rem
330 ldx1 invp-*
331 lda 0,1 have ioc#,clmx#,clmsc#,mod#
332 sta dtsv-* save for later
333 ldx1 -2,1 have ic at interrupt
334 stx1 icreg-* save it
335 rem
336 iana modmk mask out all but mod#
337 iaa -1 subtract 1 from mod#
338 als 2 mult. mod# by 4
339 sta modsv-* save it
340 rem
341 ada dspta-* find right place in dsptab
342 cax1 have dsptab add. + 4 x mod#
343 rem
344 lda reqbt-*
345 orsa crtwd,1 set request bit on for this mod
346 aos rqcnt,1 add 1 to request count
347 rem
348 ldx1 datta-*
349 adcx1 modsv-* have dattab add. + 4 x mod#
350 lda entcnt,1 entry count
351 cmpa msk,1 compare to que size
352 tmi invp5-* ok
353 rem
354 stz entcnt,1 reset
355 ila 0 this too
356 rem
357 invp5 ada stadd,1 address of list + entry count
358 aos entcnt,1 add 1 to entry count
359 cax1
360 lda dtsv-* get the saved data
361 sta 0,1 store it
362 rem
363 rem if requested, trace 1 the ic at the interrupt
364 rem and 2 the third word of the jump table.
365 rem
366 trace tt.int,ts.int,icregdtsv
367 rem
368 rem m a s t e r s a v e r
369 rem
370 lda dstnum-* get mod#
371 tze msdsp-* were in the dispatcher on the interrupt
372 rem
373 iaa -1 mod# is one more than position in dsptab
374 mpy l.a001-* mult. mod# by 10
375 cqa
376 cax1
377 adcx1 savra-* savtab + 10 x mod#
378 ldaq asv-* get original contents of aq
379 stx2 intx2,1 store x2
380 ldx2 x1sv-* get orig. contents of x1
381 stx2 intx1,1
382 stx3 intx3,1
383 staq inta,1
384 ldaq indreg-* get indicator and ic
385 staq intir,1 store indicator and ic
386 lda a.a001-*,* .crpte* get current page table entry
387 sta intptw,1 store page table entry
388 lda a.a002-*,* .crbpe* likewise buffer pte
389 sta intbpw,1
390 rem
391 tra msdsp-* go to master dispatcher
392 rem
393 rem
394 a.a001 ind .crpte,* variable cpu page table entry
395 a.a002 ind .crbpe,*
396 rem
397 l.a001 dec 10
398 ttls m a s t e r d i s p a t c h e r
399 rem
400 rem entry on completion of dispatched routine
401 rem
402 mdisp null
403 inh inhibit on
404 lda dstnum-* get mod#
405 iaa -1 subtract one
406 als 2 mult. by 4
407 cax1
408 adcx1 dspta-* dsptab address + 4 x mod#
409 lda excmsk-* execute mask
410 ersa crtwd,1 turn off execute mask
411 rem
412 rem normal entry point from master saver
413 rem
414 msdsp null
415 stz dstnum-* set to 0 - are in master dispatcher
416 eni allow interrupts
417 * chkivs
418 nop
419 nop
420 rem
421 msds5 ldx1 zerow-* zero x1
422 rem
423 msrch null
424 lda dspi-*,* examine dsptab control words
425 tze nxmd-* nothing on at all
426 rem
427 cana excmsk-* was mod interrupted?
428 tnz hvint-* yes
429 rem
430 cana supmsk-* is it suppressed?
431 tnz nxmd-* yes - continue search
432 rem
433 cana reqbt-* is it requested?
434 tnz hvreq-* yes
435 rem
436 nxmd iacx1 4 increment x1 by 4
437 cmpx1 dspsz-* are we at the end of table ??
438 tnz msrch-* no
439 rem
440 ttls idle routine
441 rem
442 rem trace state at start of idle
443 rem
444 rier read interrupt enable registers
445 sta tcrier-* save for use in trace
446 sti tcint-* save indicators register
447 rem
448 * trace tt.idl,ts.int,tcinttcrier
449 rem
450 nop
451 idlmrk nop
452 **********************************************************************
453 *
454 * idle loop increments a counter continuously, which permits
455 * metering of idle time by comparing counter to value to its
456 * maximum value which is established during initialization by
457 * running the idle loop for a second
458 *
459 **********************************************************************
460 rem
461 idloop ila 0 get a doubleword 1
462 ilq 1
463 inh have to protect load/store sequence
464 adaq idlcnt-* increment counter
465 staq idlcnt-*
466 eni ok
467 tra idloop-* go around again until interrupted
468 idlend null so icmon can locate idle loop
469 rem
470 even
471 idlcnt bss 2
472 tcint bss 1
473 tcrier bss 1
474 ttls run the requested routine
475 rem
476 hvreq cx1a get the dsptab offset
477 ars 2 divide by 4
478 iaa 1 increment by 1
479 rem
480 inh inhibit
481 sta dstnum-* set dstnum to mod# 123
482 adcx1 dspta-* address of dsptab + cx1
483 ila -1
484 asa rqcnt,1 subtract 1 from rqcnt
485 tnz hv1-* did request count go to zero?
486 rem
487 lda reqbt-* yes -- set request bit to 0
488 ersa crtwd,1
489 rem
490 hv1 lda excmsk-* set execute bit
491 orsa crtwd,1
492 rem
493 * chkivs
494 rem
495 * trace tt.run,ts.int,prent1
496 rem
497 ldi zerow-* initialize the indicator register
498 tra prent,1* go to routine
499 ttls return to interrupted module
500 rem
501 rem module was interrupted: restore registers and
502 rem transfer to point of interrupt or secondary
503 rem entry point if present.
504 rem
505 hvint stx1 x1sv-* save for awhile
506 stz hvsec-* initialize
507 cana secmsk-* is there a secondary entry point?
508 tze noscp-* no
509 rem
510 aos hvsec-* have a secondary entry
511 adcx1 dspta-* have desired 4 word block in dsptab
512 ldx2 scent,1 get secondary entry point
513 rem
514 noscp lda x1sv-* get the dsptab offset again
515 ars 2 divide by 4 to module offset
516 mpy l.a001-* multiply by 10
517 cqa
518 cax1 for use in accessing savtab
519 adcx1 savra-* desired block in savtab
520 lda x1sv-* recover dsptab offset once more
521 ars 2 convert to module offset
522 iaa 1 add 1, have mod# 123...
523 rem
524 szn hvsec-* did we find secondary entry?
525 tze ictr-* no
526 rem
527 ldx3 intic,1 yes - get ic at interrupt
528 stx3 0,2 store as first word of secondary routine
529 iacx2 1
530 tra ictr5-*
531 rem
532 ictr ldx2 intic,1 ic at interrupt
533 rem
534 ictr5 stx2 icreg-* store for transfer
535 cax2 mod# in x2
536 rem
537 * trace tt.rst,tt.int,icreg
538 rem
539 ldx3 intx3,1 restore registers -- x3
540 lda intir,1 get indicator register
541 sta indreg-* save
542 lda intptw,1 restore page table word
543 sta a.a001-*,* .crpte*
544 lda intbpw,1 and buffer page table word
545 sta a.a002-*,* .crbpe*
546 rem
547 ldaq inta,1 restore a and q reg.
548 inh
549 stx2 dstnum-* set dstnum to mod#
550 ldx2 intx2,1 restore x2
551 ldx1 intx1,1 and x1
552 rem
553 rem
554 ldi indreg-* load indicator reg.
555 tra icreg-*,* restart the interrupted routine
556 rem
557 rem
558 hvsec bss 1 indicates whether we have secondary entry
559 ttls master dispatcher tables
560 rem
561 pmc save,on
562 even
563 dsptab null
564 dspm lip lsla_man, module 1
565 dspm dterm dia_man terminate, module 2
566 dspm dmail dia_man special, module 3
567 dspm hintr hsla_man, module 4
568 dspm itrout timer_manager, module 5
569 dspm consol console_man, module 6
570 dspm tdip colts t&d, module 7
571 scdspa vfd 18/scdent
572 zero secdsp
573 zero intsv
574 oct 0
575 rem
576 dspsz zero *-dsptab
577 eject
578 datm 82882321
579 pmc restore
580 odd
581 grph bss 10
582 grpm bss 10
583 grpl bss 10
584 rem
585 ttls retrieve jump table data
586 rem
587 *******************************************************
588 *
589 * g3wjt
590 * load q register with saved third word
591 * of jump table and set up registers
592 * x2 and x3 as shown:
593 *
594 * x2 - software communication region
595 * x3 - hardware communication region
596 *
597 * calling sequence -
598 *
599 * tsy g3wjt-*
600 * return
601 *
602 *********************************************************
603 rem
604 g3wjt subr g3w,inh
605 rem
606 lda a.c001-*,* =dstnum get mod number of him
607 iaa -1 subtract one
608 als 2 mult. by 4
609 ada a.c002-* =dattab have respective 4 word block
610 cax1 in dattab
611 rem
612 ldx2 excnt,1 exit count
613 cmpx2 msk,1 compare to length of que
614 tnz g3wjt5-* ok
615 rem
616 stz excnt,1 reset it
617 ldx2 excnt,1 zero x2 also
618 rem
619 g3wjt5 adcx2 stadd,1 address of list + exit count
620 aos excnt,1 increment exit count
621 ldq 0,2 data ioc#clm#clmsc#mod#
622 cqa
623 ana l.c001-* =037600 mask out clm# and clmsc#
624 ars 3 convert to relative address
625 cax3 x3 - hardware communication region
626 ldx2 h.sfcm,3 x2 - software communication region
627 rem
628 return g3wjt return to caller
629 rem
630 l.c001 oct 37600 mask for clm# and subchannel #
631 rem
632 a.c001 zero dstnum pointer to interupted module number
633 a.c002 zero dattab pointer to dattab
634 ttls dispatcher queuer
635 rem
636 ********************************************************************
637 *
638 * dspqur
639 * inputs
640 * ar -- time delay/priority
641 * qr -- routine name
642 * x1 -- passed to routine when run
643 * outputs
644 * none
645 * registers altered - a,q
646 *
647 **********************************************************************
648 rem
649 dspqur subr qur,aqx1x2x3inh
650 rem
651 * trace tt.que,ts.skd,qursaqursqx1
652 rem
653 lda qursa-*
654 ldq qursq-* restore a and q
655 icana -64 777700 entry for delayed queuer?
656 tnz delayq-* yes
657 rem
658 ldx2 lnkptr-* get link from available chain
659 tnz dspq2-* unless chain is exhausted
660 tsy a.d010-*,* =getqlk get and format a new block
661 ind lnkchn
662 rem
663 dspq2 sta dqpri,2 store priority into link
664 stq dqrtn,2 store routine into link
665 stx1 dqx1,2 store x1 into link
666 ldq dqlink,2 detatch link from remainder of
667 stq lnkptr-* availible chain
668 rem
669 ldq a.d001-* =dque get address of pointer
670 stq dtmp1-* to dispatcher queue chain
671 rem
672 ldx3 dque-* get start of chain
673 tnz dspq6-* good chain, start search
674 rem
675 stz dqlink,2 make link end of chain
676 tra dspq12-*
677 rem
678 dspq6 cmpa dqpri,3 search chain until lower priority
679 tnc dspq10-* is found
680 stx3 dtmp1-* not yet - save previous link
681 ldx3 dqlink,3 get next
682 tnz dspq6-* test for end of chain
683 eject
684 dspq10 stx3 dqlink,2 put the foward pointer into new link
685 rem
686 dspq12 stx2 dtmp1-*,* make previous link point at new one
687 ldx2 a.d002-* get address of secondary disp. block
688 rem
689 lda l.d001-* =rqstbt get request bit
690 orsa crtwd,2 set request bit on for secondary disp.
691 ila 1
692 sta rqcnt,2 set request count to one
693 rem
694 dspq20 null
695 return dspqur return to caller
696 rem
697 dtmp1 oct 0 temp for workspace
698 rem
699 dque zero 0 pointer to the dispatcher que chain
700 rem
701 rem
702 lnkchn ind 0 extra buffer chain
703 ind nmqlk number of permanent links
704 ind 0 number of calls on getqlk
705 lnkptr ind *+1 pointer to available link chain
706 links nmqlk,4 generate permanent links
707 rem
708 a.d001 ind dque
709 a.d002 ind scdspa
710 a.d010 ind getqlk
711 rem
712 l.d001 vfd 18/rqstbt
713 ttls delayq -- time delay queuer routine
714 ************************************************************************
715 * the function of this routine is identical to the normal queuer
716 * routine "dspqur" with the following single exception --
717 *
718 * the routine to be queued will be queued only after
719 * the specified time interval has elapsed.
720 *
721 * the calling sequence is also identical to that of the normal queuer
722 * except that bits 0-11 of the accumulator are non-zero and represent
723 * the desired time delay before the routine is actually queued.
724 *
725 * inputs--
726 * ar00-11= desired time delay, in seconds
727 * ar12-17= priority
728 * qr = routine address
729 * x1 = will be passed to routine when run
730 *
731 * outputs -- none
732 *
733 ************************************************************************
734 rem
735 delayq null transfered to by dspqur
736 rem
737 sel tmch select timer channel
738 cioc a.e006-*,* =mskpcw mask the interval timer
739 rem
740 lda a.e003-*,* =itmb get the timer value
741 sta dtimer+1-* save it
742 rem
743 ldaq a.e004-*,* =simclk get the simulated clock
744 sbaq dtimer-* get the current time
745 staq curtim-* and save it away
746 rem
747 ldx3 dfree-* get ptr to free chain
748 tnz 2 all ok
749 die 1 no more delay queue buffers
750 rem
751 lda dfwd,3 get fwd ptr from first blk
752 sta dfree-* put into free ptr, taking blk
753 rem
754 lda qursa-* restore a reg
755 iana 63 leave priority
756 sta dpri,3 put into block
757 lda qursq-* get the routine addr
758 sta drtn,3 save in block
759 ldx1 qursx1-* get the value of x1
760 stx1 dx1,3 save in block, also
761 lda qursa-* get time value
762 ars 6 shift down
763 mpy l.e002-* =1000 in to milliseconds
764 adaq curtim-* add in current time
765 staq dtime,3 and put into block
766 staq ntime-* save local copy
767 rem
768 stx3 dnew-* save addr of new block
769 lda a.e005-* =dnext get addr of next ptr
770 sta dlasta-* save it also
771 rem
772 ldx3 dnext-* get the next ptr, head of chain
773 tze dqr020-* no chain, start one
774 rem
775 dqr010 ldaq ntime-* get the new time
776 cmpaq dtime,3 is ntime < dtime?
777 tnc dqr020-* yes, chain in here
778 rem
779 stx3 dlasta-* save addr of this block
780 ldx3 dfwd,3 bump to next block
781 tnz dqr010-* loop for more
782 rem
783 ldx3 dnew-* get ptr to new block
784 stx3 dlasta-*,* store into fwd of last block
785 stz dfwd,3 zero fwd ptr, end of chain
786 tra dqr030-* all done
787 rem
788 dqr020 cx3a save addr of current block
789 ldx3 dnew-* get addr of new block
790 stx3 dlasta-*,* put into last block fwd ptr
791 sta dfwd,3 chain ahead to next block
792 rem
793 dqr030 szn a.e009-*,* =itrint has interval timer run out?
794 tnz dqr060-* yes, all done, will be set later
795 rem
796 ldx3 dnext-* get ptr to first block
797 szn a.e008-*,* =runing is the clock runing?
798 tze dqr032-* no, just start it
799 rem
800 ldaq a.e004-*,* =simclk get the simclk
801 cmpaq dtime,3 is simclk < dtime?
802 tnc dqr050-* yes, go start clock
803 rem
804 dqr032 ldaq dtime,3 get the time in block
805 sbaq curtim-* subtract current time, leaving interval
806 tnz dqr035-* zero interval, bad
807 rem
808 ila 0 set to very small one
809 ilq 1 like 1 or so
810 tra dqr040-* done
811 rem
812 dqr035 iaa 0 set the indicators
813 tze dqr040-* less than max, set clock
814 rem
815 ila 1 get the max value for clock
816 ilq 0 into the aq
817 rem
818 dqr040 stq a.e003-*,* =itmb set the interval timer
819 adaq curtim-* get the new simclk time
820 staq a.e004-*,* =simclk and save it
821 rem
822 dqr050 sel tmch select the timer channel
823 cioc a.e007-*,* =runpcw start the timer
824 aos a.e008-*,* =runing it is running now
825 rem
826 dqr060 tra dspq20-* restore registers and return
827 rem
828 rem
829 even
830 dtimer oct 0,0 interval timer value
831 curtim oct 0,0 current time
832 ntime oct 0,0 new time for new block
833 rem
834 dnext oct 0 ptr to chain of active blocks
835 dfree ind dlyque ptr to chain of free blocks
836 rem
837 dlyque dlyblk nmdqlk
838 rem
839 dlasta oct 0
840 dnew oct 0
841 rem
842 rem
843 a.e003 ind itmb
844 a.e004 ind simclk
845 a.e005 ind dnext
846 a.e006 ind mskpcw
847 a.e007 ind runpcw
848 a.e008 ind runing
849 a.e009 ind itrint
850 a.e012 ind frelbf
851 rem
852 l.e002 dec 1000
853 rem
854 rem equates for a delay queue block
855 rem
856 dfwd equ 0
857 drtn equ 1
858 dtime equ 2
859 dx1 equ 4
860 dpri equ 5
861 ttls emergency queue link routines
862 rem
863 ************************************************************
864 * the function of this subroutine is to fetch and format
865 * buffers needed by the normal queuer. the address of
866 * the first word of the new link chain is returned
867 * in x2 on exit.
868 ************************************************************
869 rem
870 getqlk subr sub,aq
871 rem
872 ilq bufsiz set size of buffer desired
873 tsy a.i004-*,* =getbuf get a buffer
874 die 1 ** error - no more buffers **
875 ldx2 getqlk-*,* get pointer to link control words
876 aos 2,2 increment call count
877 lda 0,2 get the extended chain
878 sta 0,3 link it to the new buffer
879 stx3 0,2 set new chain pointer
880 iacx3 4 compute first link address
881 cx3a save link address in x2
882 cax2
883 ilq dqlpb-2 number of links to link
884 rem
885 get010 iacx3 4 move to next link
886 stx3 -4,3 save new pointer in link
887 iaq -1 bump loop control counter
888 tnz get010-* process next unless done
889 rem
890 stz 0,3 yes, reset last link pointer to zero
891 aos getqlk-* increment return address
892 rem
893 return getqlk return to caller
894 eject
895 rem
896 ************************************************************
897 * this routine returns to available space the
898 * buffers used by the queuer routines
899 ************************************************************
900 rem
901 relqlk subr rel,x1x2x3inh
902 rem
903 ldx1 relqlk-*,* get pointer to link control words
904 ldq 1,1 get number of permanent links
905 iaq -1
906 cx1a
907 iaa 4 compute address of first link
908 sta 3,1 set new link chain pointer
909 cax2
910 rem
911 rel010 iacx2 4 step address to next link
912 stx2 -4,2 link it to previous link
913 iaq -1 decrement link count
914 tnz rel010-* process next unless done
915 rem
916 stz 0,2 zero last link pointer
917 lda 0,1 get the buffer chain
918 stz 0,1 clear pointer to it
919 tsy a.e012-*,* =frelbf release the chain
920 rem
921 aos relqlk-* increment return address
922 rem
923 return relqlk return to caller
924 ttls e v e n t d i s p a t c h e r
925 rem
926 *************************************************************
927 *
928 * purpose - dispatch routines from a queued list
929 *
930 * calling sequence - tra secdsp-*
931 *
932 * input
933 * dque - points to top of
934 * queued chain
935 * dlink - points to avail. chain
936 * prdrt - set to minus one
937 *
938 * output
939 * x1 - contains saved value
940 * x3 - contains link address
941 * prdrt - contains priority
942 * shifted 3 right
943 *
944 *************************************************************
945 rem
946 secdsp null
947 rem
948 * chkivs
949 rem
950 inh inhibit on
951 ila -1 set to minus
952 sta prdrt-* in the disp. routine
953 ldx3 a.h002-*,* =dque get queue pointer
954 tnz dspr10-* process next entry
955 rem
956 szn a.h003-*,* =lnkchn queue empty - any buffers to release
957 tze a.h001-*,* no - return to master dispatcher
958 tsy relqlk-* yes - release them
959 ind lnkchn
960 tra secdsp-* process new entry in queue
961 rem
962 dspr10 lda dqlink,3 get link address of first rtn queued
963 sta a.h002-*,* =dque update queue pointer
964 ldq a.h004-*,* =lnkptr pres. disp. routine pointer
965 stq dqlink,3 store in queue link
966 stx3 a.h004-*,* =lnkptr place on top of availible list
967 lda dqpri,3 get priority
968 ars 3 shift right 012...
969 sta prdrt-*
970 rem
971 * trace tt.rnq,ts.skd,dqrtn3
972 rem
973 ila pte.s turn on security bit in ptws so any reference will
974 orsa a.h005-*,* .crpte* cause a store fault
975 orsa a.h006-*,* .crbpe*
976 rem
977 ldx1 dqx1,3 saved value in x1
978 stx1 svx1-* save for interrupt
979 ldi l.h001-* =0 initialize indicator register
980 tra dqrtn,3* go execute
981 rem
982 rem
983 prdrt oct 400000
984 svx1 zero
985 rem
986 a.h001 ind mdisp
987 a.h002 ind dque
988 a.h003 ind lnkchn
989 a.h004 ind lnkptr
990 a.h005 ind .crpte,* variable cpu page table entry
991 a.h006 ind .crbpe,* buffering page table entry
992 rem
993 l.h001 oct 0
994 rem
995 pte.s bool 100 page table entry security bit
996 ttls secondary level s a v e r
997 rem
998 ******************************************************************
999 *
1000 * purpose - save all registers of the interrupted
1001 * routine in the following block
1002 * format:
1003 *
1004 * note: block must start at an
1005 * odd location
1006 *
1007 * word contents
1008 * 0 x1
1009 * 1 x2
1010 * 2 x3
1011 * 3 a reg.
1012 * 4 q reg.
1013 * 5 ind. reg.
1014 * 6 ic at interrupt
1015 * 7 page table word
1016 *
1017 *
1018 * each priority group has its own 7 word
1019 * block. after all saves; get interrupted
1020 * routine's priority, tib address and
1021 * queue.
1022 *
1023 ******************************************************************
1024 rem
1025 intsv zero will contain ic at interrupt on entry
1026 rem from master dispatcher
1027 sti sv1-* save ind. register
1028 inh inhibit on
1029 szn prdrt-* were we in dispatched routine?
1030 tmi int020-* no
1031 tnz svrg-* yes- save registers and queue
1032 rem
1033 ldi sv1-* priority is 0 -- skip queueing
1034 eni
1035 tra intsv-*,* go to point of interrupt
1036 rem
1037 svrg stx1 sv2-* save registers in respective group
1038 ldx1 prdrt-* get priority 012...
1039 ldx1 a.i002-** =grptbl1 load x1 with add. of group
1040 staq inta1 store a and q reg. in word 3 and 4
1041 stx2 intx21 " x2 in word 1
1042 stx3 intx31 " x3 " " 2
1043 ldaq sv1-* load ind. reg. and x1 in aq
1044 sta intir1 indicator register
1045 stq intx11 x1 saved in word 0
1046 lda intsv-* ic at interrupt
1047 sta intic1 save in block
1048 lda a.h005-** .crpte* get current ptw
1049 sta intptw1 save page table word
1050 lda a.h006-** .crbpe*
1051 sta intbpw1 and buffer ptw
1052 rem
1053 lda prdrt-* get priority
1054 rem
1055 als 3 reposition 0-710-17...
1056 ldq a.i003-* =restor add. of restore routine
1057 ldx1 svx1-* restore x1 for restorer
1058 tsy a.i001-** =dspqur call queuer
1059 rem
1060 eni
1061 int020 tra secdsp-* return to event dispatcher
1062 rem
1063 even
1064 sv1 oct 0 start at even location
1065 sv2 oct 0
1066 rem
1067 grptbl zero grph points to priority group - h
1068 zero grpm " " " " m
1069 zero grpl " " " " l
1070 rem
1071 a.i001 ind dspqur
1072 a.i002 ind grptbl1
1073 a.i003 ind restor
1074 a.i004 ind getbuf
1075 ttls r e s t o r e r
1076 rem
1077 ******************************************************************
1078 *
1079 * entered from the dispatcher.
1080 * restores all registers and transfers to
1081 * the interrupted routine via ic word 6
1082 * of block.
1083 *
1084 ******************************************************************
1085 rem
1086 restor null
1087 inh
1088 ldx1 prdrt-* get priority 012..
1089 ldx1 a.i002-** =grptbl load x1 with add. of chain
1090 ldaq intir1 load ind. reg. and ic at interrupt
1091 staq sv1-* store temp
1092 lda intptw1 restore page table entry
1093 sta a.h005-** .crpte*
1094 lda intbpw1
1095 sta a.h006-** .crbpe*
1096 rem
1097 ldaq inta1 restore a and q
1098 ldx2 intx21 restore x2
1099 ldx3 intx31 restore x3
1100 ldx1 intx11 restore x1
1101 ldi sv1-* restore indicator register
1102 tra sv2-** go finish it
1103 ttls etrip -- elapsed timer rollover interrupt processor
1104 ************************************************************************
1105 * this routine is implemented directly from the interrupt vector.
1106 *
1107 * this routine handles elapsed timer runouts. it is responsible for idle
1108 * time metering and calling the instruction counter monitor if the latter
1109 * is enabled. the idle meter interval is established at initialization
1110 * time and is normally one second. the ic monitor interval is dynamically
1111 * configurable and is apt to be shorter.
1112 *
1113 * when this routine finds that the idle meter interval has expired it
1114 * updates the running total of the idle loop counter so that user-ring
1115 * programs can determine an average idle time.
1116 *
1117 * the idle loop is run for one meter interval during initialization to
1118 * establish a maximum value for the counter.
1119 ************************************************************************
1120 rem
1121 etrip subr etrinhaq
1122 ldi l.o001-* =024000o inhibit overflow as well
1123 lda etrprv-* last setting of elapsed timer
1124 tze etr035-* this is first time don't meter
1125 cmpa idlint-* was it a full idle time interval?
1126 tpl etr010-* yes meter idle count
1127 ada etrcum-* no has idle interval passed since we
1128 cmpa idlint-* last recorded it?
1129 tpl etr010-* yes meter idle now
1130 sta etrcum-* no update cumulative time
1131 tra etr040-* check for ic monitoring
1132 rem
1133 etr010 ldaq a.o001-** idlcnt
1134 cmpaq idlmin-* new minimum?
1135 tpl etr020-* no
1136 staq idlmin-* yes store it
1137 tra etr030-* don't check for max
1138 etr020 cmpaq idlmax-* new maximum?
1139 tmi etr030-* no
1140 staq idlmax-* yes record it
1141 etr030 adaq idlcum-* increment cumulative count
1142 staq idlcum-* save result
1143 ila 0 get a double-word 1
1144 ilq 1
1145 adaq idlinc-* to update count of idle meters
1146 staq idlinc-*
1147 etr035 null now zero the counter. note that a reg
1148 ilq 0 contains 0 no matter how we got here
1149 staq a.o001-** idlcnt
1150 stz etrcum-* starting new idle interval
1151 rem
1152 etr040 szn etrmon-* ic monitoring in effect?
1153 tze etr050-* no skip it
1154 tsy a.o002-** icmon yes call routine
1155 etr050 lda etrint-* new interval value
1156 sta a.o003-** etmb to elapsed timer mailbox
1157 iera -1 convert to positive number
1158 iaa 1
1159 sta etrprv-* save for next time
1160 return etrip
1161 rem
1162 rem
1163 etrprv bss 1 most recent setting of elapsed timer
1164 etrcum bss 1 time since last idle measurement
1165 idlint dec 1000 default idle meter interval 1 second
1166 rem
1167 l.o001 oct 024000 inhibit interrupts and overflow
1168 rem
1169 a.o001 ind idlcnt counter kept by idle loop
1170 a.o002 ind icmon address of ic monitoring routine
1171 a.o003 ind etmb address of elapsed timer
1172 rem
1173 * the following data is pointed to .crskd in the comm region
1174 * ring 4 multics software knows the format of this data
1175 rem
1176 even
1177 skdata null
1178 idlcum oct 00 cumulative value of idle counter
1179 idlinc oct 00 count of increments to ildcum
1180 idlmax oct 00 max value of counter
1181 idlmin oct 00 min value of counter
1182 etrint dec -1000 interrupt every second may be changed
1183 etrmon oct 0 address of data block in ic metering module
1184 rem if configured
1185 ttls setime -- routine to set time-outs for tib lines
1186 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1187 *
1188 * setime
1189 *
1190 * setime is a routine called by the control tables
1191 * via the interpreter to set time-outs for the various ttys
1192 * so that the line can be prodded every so often to determine
1193 * its state.
1194 *
1195 * upon entry:
1196 * x1 - virtual tib address for this line
1197 * a - time to wait in seconds
1198 * - or zero to reset a timer
1199 *
1200 * returns:
1201 * with a timer set to queue itmout when it goes off.
1202 *
1203 * notes:
1204 * If a timer is already running for the line it will
1205 * just be reset to the new value.
1206 *
1207 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1208 rem
1209 setime subr setx1x2x3a
1210 rem
1211 sel tmch select the timer channel
1212 cioc mskpcw-* mask the timer now
1213 rem
1214 lda a.h005-** .crpte* get current cpu page table entry
1215 sta savpte-* save it for return
1216 rem
1217 lda t.line1 get the line number
1218 tsy a.l002-** gettib get real tib address
1219 sta strtib-* save it for trace call
1220 rem
1221 trace tt.setts.timsetsastrtib
1222 rem
1223 lda a.l007-** =itmb get the value of the interval timer
1224 sta itimer+1-* store it away
1225 rem
1226 ldaq simclk-* get the simulated clock value
1227 sbaq itimer-* subtract interval timer value
1228 staq ctime-* store as current time
1229 rem
1230 ldx3 tnext-* get the next ptr
1231 tze set030-* none in queue
1232 rem
1233 lda a.l006-* =tnext save addr of next ptr
1234 sta tlasta-* in tlasta for now
1235 lda strtib-* get real tib address
1236 rem
1237 set010 cmpa ttib3 is this the same tib?
1238 tze set020-* yes process
1239 rem
1240 stx3 tlasta-* save addr of this block
1241 ldx3 tfwd3 get fwd ptr
1242 tze set030-* end of queue done
1243 tra set010-* loop for more
1244 rem
1245 set020 lda tfwd3 get the fwd ptr
1246 sta tlasta-** and store in last blk
1247 lda tfree-* get free ptr
1248 sta tfwd3 put into this block
1249 stx3 tfree-* reset free putting this on head
1250 rem
1251 set030 lda setsa-* restore a reg value
1252 tze set080-* zero no new value to set
1253 tpl set031-* positive value in seconds
1254 ila 0
1255 ilq 0
1256 sbq setsa-* compute positive milliseconds
1257 tra set032-*
1258 rem
1259 set031 mpy l.l001-* =1000 convert to milliseconds
1260 set032 adaq ctime-* add in current time
1261 staq time-* save as expected timeout time
1262 staq t.time1 update into tib
1263 rem
1264 ldx3 tfree-* get ptr to free block
1265 tnz set050-* good we have one
1266 rem
1267 ilq bufsiz load buffer size
1268 tsy a.i004-** =getbuf get the needed buffer
1269 die 1
1270 stx3 tfree-* save its address
1271 rem
1272 ila bufsiz-2 get size minus two
1273 ars 1 divide by two
1274 set040 iacx3 2 bump to next block
1275 stx3 -23 store its addr in last fwd ptr
1276 iaa -1 decrement count
1277 tnz set040-* loop for more
1278 rem
1279 stz 03 zero the last fwd ptr
1280 ldx3 tfree-* get the free ptr again
1281 rem
1282 set050 lda tfwd3 take the block
1283 sta tfree-* update free ptr
1284 lda strtib-* get real tib address
1285 sta ttib3 save real tib address in blk
1286 rem
1287 stx3 tcur-* save addr of new block
1288 lda a.l006-* =tnext save addr of next ptr
1289 sta tlasta-* for later reference
1290 ldx3 tnext-* get addr of chain
1291 tze set070-* no chain here
1292 rem
1293 set060 lda ttib3 get real tib address from blk
1294 tsy a.l001-** setptw virtualize it
1295 cax1 put virtual tib address in x1
1296 ldaq time-* get the new time value
1297 cmpaq t.time1 is time < t.time?
1298 tnc set070-* yes chain new block here
1299 rem
1300 stx3 tlasta-* save addr of this blk
1301 ldx3 tfwd3 bump to next blk
1302 tnz set060-* loop if more blks to look at
1303 rem
1304 ldx3 tcur-* pick up addr of new blk
1305 stx3 tlasta-** store in fwd ptr of last blk
1306 stz tfwd3 zero fwd ptr of this one
1307 tra set080-* continue
1308 rem
1309 set070 cx3a save addr of next blk
1310 ldx3 tcur-* pick up addr of new blk
1311 stx3 tlasta-** store in fwd ptr of last blk
1312 sta tfwd3 reset fwd ptr of this blk
1313 rem
1314 set080 szn itrint-* has interval timer run out?
1315 tnz set110-* yes will be set later...
1316 rem
1317 ldx3 tnext-* pick up next ptr again
1318 tnz set081-* there are tib entries
1319 szn runing-* timer runing?
1320 tze set110-* no nothing at all to do
1321 tra set100-* yes just restart from current value
1322 rem
1323 set081 lda ttib3 get real tib address from first blk
1324 tsy a.l001-** setptw virtualize it
1325 cax1 put virtual tib address in x1
1326 szn runing-* is the clock running now?
1327 tze set082-* no just set it
1328 rem
1329 ldaq simclk-* get the simulated clk value
1330 cmpaq t.time1 is simclk < t.time?
1331 tnc set100-* yes all set
1332 rem
1333 set082 ldaq t.time1 get the tib time
1334 sbaq ctime-* subtract current time
1335 tnz set085-*
1336 rem
1337 ila 0 set clock to very small number
1338 ilq 1 so we will get interrupt
1339 tra set090-*
1340 rem
1341 set085 iaa 0 set the indicators
1342 tze set090-* less than max set clock
1343 rem
1344 ila 1 set max timer value in aq
1345 ilq 0 all zeros in q
1346 rem
1347 set090 stq a.l007-** =itmb reset the clock
1348 rem
1349 adaq ctime-* add in current time to get new
1350 staq simclk-* simulated clock time and store
1351 rem
1352 set100 sel tmch select the timer channel
1353 cioc runpcw-* run clock run
1354 aos runing-* is running now
1355 rem
1356 set110 null
1357 lda savpte-* get orig page table entry
1358 sta a.l009-** .crpte* restore page table entry
1359 rem
1360 return setime
1361 rem
1362 rem
1363 savpte bss 1 saves variable page table entry
1364 strtib bss 1 saves real tib address
1365 rem
1366 even
1367 mskpcw vfd 18/0
1368 vfd 5/01/112/0
1369 runpcw vfd 18/0
1370 vfd 18/0
1371 rem
1372 simclk oct 00
1373 ctime oct 00
1374 itimer oct 00
1375 time oct 00
1376 rem
1377 runing oct 0
1378 rem
1379 tnext oct 0
1380 tfree ind tque
1381 rem
1382 tque tblk 16
1383 rem
1384 rem equates for the symbols in a tque entry
1385 rem
1386 tfwd equ 0
1387 ttib equ 1
1388 rem
1389 rem
1390 tcur oct 0
1391 tlasta oct 0
1392 rem
1393 rem
1394 l.l001 dec 1000
1395 even
1396 l.l002 vfd 18/intpri
1397 ind itmout
1398 rem
1399 a.l001 ind setptw set up variable cpu page table word
1400 a.l002 ind gettib
1401 a.l003 ind dspqur
1402 a.l004 ind dnext
1403 a.l005 ind dfree
1404 a.l006 ind tnext
1405 a.l007 ind itmb
1406 a.l008 ind secdsp
1407 a.l009 ind .crpte* variable cpu page table entry
1408 ttls itrout -- interval timer runout interrupt processor
1409 rem
1410 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1411 *
1412 * itrout
1413 *
1414 * this routine handles the interval timer runout
1415 * interrupt and schedules the itrip routine to
1416 * handle the processing of the timouts.
1417 *
1418 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1419 rem
1420 itrout ldaq l.m001-* get the priority and routine
1421 rem don't care whats in x1
1422 tsy a.m001-** =dspqur queue to run
1423 rem
1424 aos itrint-* interval timer has run out.
1425 rem
1426 tra a.m002-** =mdisp return to master dispatcher
1427 rem
1428 itrint oct 0
1429 even
1430 l.m001 zero itpri
1431 ind itrip
1432 rem
1433 a.m001 ind dspqur
1434 a.m002 ind mdisp
1435 rem
1436 rem
1437 rem jump table for interval timer runout
1438 rem
1439 timrjt zero
1440 tsy .invp-**
1441 vfd 18/modtmr
1442 rem
1443 .invp ind invp
1444 ttls itrip - interval timer processor
1445 rem
1446 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1447 *
1448 * itrip
1449 *
1450 * this routine does the actual processing for
1451 * the interval timer runout. it finds all people
1452 * in the tib and delayq lists who have reached
1453 * the requested time.
1454 *
1455 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1456 rem
1457 itrip null called by dispatcher
1458 rem
1459 stz itrint-* we have handled interrupt now
1460 stz runing-* not running now
1461 ila 0 get a very small number in aq
1462 ilq 2 to use as fudge in finding timouts
1463 adaq simclk-* get the real time of this
1464 staq ctime-* and save as current time
1465 rem
1466 trace tt.itrts.timctimectime+1
1467 rem
1468 ldx3 tnext-* get ptr to tib list
1469 tze itr020-* no tibs in tib list
1470 rem
1471 itr010 lda ttib3 get ptr to first tib in list
1472 tsy a.l001-** setptw virtualize it
1473 cax1 put virtual tib address in x1
1474 ldaq ctime-* get current time
1475 cmpaq t.time1 is ctime < t.time?
1476 tnc itr020-* yes all done
1477 rem no give timeout
1478 ldx1 ttib3 need real tib address for dspqur
1479 ldaq l.l002-* get priority and addr of itmout
1480 tsy a.l003-** =dspqur queue it up real tib in x1
1481 rem
1482 lda tfwd3 save old fwd ptr
1483 ldq tfree-* get the free ptr
1484 stq tfwd3 save as fwd ptr of this one
1485 stx3 tfree-* make this one first free
1486 rem
1487 cax3 bump to next block
1488 stx3 tnext-* point the que head at this blk
1489 iacx3 0 set the indicators
1490 tnz itr010-* loop if more blks to look at
1491 rem
1492 itr020 ldx3 a.l004-** =dnext get delayq next ptr
1493 tze itr040-* none in queue now
1494 rem
1495 itr030 ldaq ctime-* get the current time
1496 cmpaq dtime3 compare: is ctime < dtime?
1497 tnc itr040-* yes all done
1498 rem no give time out
1499 lda dpri3 get the priority
1500 ldq drtn3 and the routine addr
1501 ldx1 dx13 and his value in x1
1502 tsy a.l003-** =dspqur and queue him to run
1503 rem
1504 lda dfwd3 get the fwd ptr in this blk
1505 ldq a.l005-** =dfree get the free ptr
1506 stq dfwd3 and put into this blk
1507 stx3 a.l005-** =dfree and put this on at top
1508 rem
1509 cax3 bump to next guy in list
1510 stx3 a.l004-** =dnext point head at this one
1511 iacx3 0 set the indicators
1512 tnz itr030-* loop for more work
1513 rem
1514 itr040 stz itrsw-* zero the switch word
1515 rem
1516 szn tnext-* any tibs in tib list?
1517 tze 3 no
1518 rem
1519 ila 1 yes set bit
1520 orsa itrsw-*
1521 rem
1522 szn a.l004-** =dnext any entries in delayq?
1523 tze 3 no
1524 rem
1525 ila 2 yes set other bit
1526 orsa itrsw-*
1527 rem
1528 ldx3 itrsw-* load the switch word
1529 tra a.n001-** =itrtbl3* use as index to label array
1530 rem
1531 itrtbl ind itr041 no timers needed
1532 ind itr042 only tib timers set
1533 ind itr043 only delayq timers on
1534 ind itr044 both set compare
1535 rem
1536 itr041 ila 0 set standard time for clock
1537 ldq l.n001-* =60*1000 so we idle for a minute
1538 adaq ctime-* add it in so we can subtract it out
1539 tra itr050-* set clock
1540 rem
1541 itr042 ldx3 tnext-* get ptr to first tib entry
1542 lda ttib3 get real tib address
1543 tsy a.l001-** setptw virtualize it
1544 cax1 put virtual tib address in x1
1545 ldaq t.time1 have tib time
1546 tra itr050-* set clock
1547 rem
1548 itr043 ldx3 a.l004-** =dnext get ptr to delayq list
1549 ldaq dtime3 get first delayq time
1550 tra itr050-* set clock
1551 rem
1552 itr044 ldx3 tnext-* get ptr to tib list
1553 lda ttib3 get real ptr to first tib in list
1554 tsy a.l001-** setptw virtualize it
1555 cax1 put virtual tib address in x1
1556 ldaq t.time1 get the tib time
1557 rem
1558 ldx3 a.l004-** =dnext get ptr to delay list
1559 cmpaq dtime3 is t.time < dtime?
1560 tnc itr050-* yes all set
1561 rem
1562 ldaq dtime3 get the delay q time instead
1563 rem
1564 itr050 sbaq ctime-* subtract current time to get interval
1565 tnz itr055-* non-zero all set
1566 rem
1567 ila 0 set to a very
1568 ilq 1 small number to get interrupt
1569 tra itr060-*
1570 rem
1571 itr055 iaa 0 set indicators
1572 tze itr060-* less than max timer values all set
1573 rem
1574 ila 1 set max value allowed
1575 ilq 0
1576 rem
1577 itr060 stq a.l007-** =itmb put into timer loc
1578 adaq ctime-* get next simclk time
1579 staq simclk-* and save it away
1580 rem
1581 sel tmch select timer
1582 cioc runpcw-* start the clock run run run.
1583 aos runing-* running again
1584 rem
1585 itr070 tra a.l008-** =secdsp return dispatcher
1586 rem
1587 itrsw bss 1
1588 rem
1589 l.n001 dec 60000
1590 rem
1591 a.n001 ind itrtbl3*
1592 end