&8}Y(A(.7 7 @d b`w (.&fd@~5bߋb5b  f.Lw5b@ddUd5d0  b.r` w5bwx@ P2.RR`T TVUR5P} . PT R5P R *R5P%w AA w5 .TITLE TAPCPY 800 TO 1600 BPI TAPE COPY ; ; THIS PROGRAM COPIES 800 BPI NRZI TAPES TO PRODUCE ; 1600 BPI PE TAPES. ; R0 = %0 PC = %7 SP = %6 R5 = %5 MTC = 172522 MTCMA = 172526 MTWC = 172524 MTS = 172520 ; MAGCMD = 167544 MAGCMA = 167546 MAGWC = 167540 MAGST = 167542 ; READ = 1 MGCLR = 40000 CURDY = 200 ; MTCLR = L&8}YT,7 7 @d b` ,’\d@~5bߋb5b ,w5p\@ddUd5d,` w5bwx@ P,4RR`T TVUR5P%,Z PT R5P R (R5P%w w ,& +++ 7 w,L԰+w 7w  7|w ,rw \ĝZ7z+7N J z+G,r+!$  dR y8}Ud, %@Z{[lP}M]\Nk`K,& az^L~no|u,L 7 5x5@x7 h,r  w5x RAT' , V 5@P7 Z B& <, H7 B27 0R`T'V,  5R 5 x , !RT |w TeAw 4,0!jV $w `V $5x$$~E,V!$$~ $$~,|!$$ ; UPDATE SPECIAL 16,800 BUFFER/RECORDS ; UPDATE 21-FEB-74 TAPDUM.S02 S02 ; UPDATE 10-FEB-74 TAPDUM.S01 S01 ; UPDATE 25-JAN-74 TAPDUM .TITLE TAPDUM TAPE DUMP ;******* T A P E D U M P R O U T I N E ******* ; ; HANDLES UP TO A MAXIMUM OF 4096 BYTES PER RECORD. ; WILL DUMP VARIABLE LENGTH RECORDS FROM MAG TAPE TO THE LINE PRINTER. ; ONLY THE DATA BYTES READ ARE DUMPED AN 10000 WRITE = 4 TURDY = 1 GAP = 14 MATBSP = 12+1 MGBKSP = 200 MTEOF = 6+1 ; MAGEOF = 100000 START: CLR EOFCNT ST1: JSR PC,MAGCD CLR EOFCNT JSR PC,MTCMD BR START ; ; ; 800 BPI READ ; MAGCD: MOV #MGCLR,@#MAGCMD CLR @#MAGST MOV #4000,@#MAGWC MOV #BUFFER,MAGCMA MOV #READ,@#MAGCMD MOV 0w & x+r+7,@* D A  &DCc  ,w Dw  w  ' 7  r, Մ &w \w wXw w ,0 fw  w 7 wtwh,Vw  %+E eӂ wh,|H  =w XH A w L~,: w D3 w < w 4w < 7 w $,.7 w &7 7  \,w7  ww (b ww ?,ւw A B` %0,:օ w| ~ n j$@ p5@P+51,!x6'\RX010\,!0 &  d.ed& $ |,!wwd & 5xwF,"'0^1Y0T0O ,:" TdB Ԡ!Q  {,`" ee   zded $," ww PxEQ_RU,"R&@~5p % s,"&~ L  &~ P,"& L N',#~ ' D A BYTE COUNT IS ALSO LISTED. ; NORMALLY READS AND DUMPS ASCII DATA UNLESS OTHERWISE REQUESTED. ; READS SUCCESSIVE RECORDS AND DUMPS THEM UNTIL REQUESTED TO HALT. ; IF A RECORD EXCEEDS 4096 DEC CHARS, ONLY THE FIRST 4096 CHARS DUMPED. ; ; ; OPTIONS AND SWITCH BIT SETTINGS ARE AS FOLLOWS: ; SWITCH BIT: ; 0-3: DUMP MAG TAPE NO IN THESE SWITCHES S01 ; 8: EBCDIC TO ASCII CONVERSION (MT READ TO LP PRINT) ; 10: STOP DUMP ON END-OF-FILE  #100,R0 05$: SOB R0,05$ 10$: BIT #CURDY,@#MAGST BEQ 10$ 06$: TSTB @#MAGST BPL 06$ BIT #MAGEOF,@#MAGST BEQ 42$ TST (SP)+ JMP MTWEOF 42$: BIT #400,MAGST BPL 20$ MOV #MGCLR,@#MAGCMD MOV #MGBKSP,@#MAGCMD BIS #1,@#MAGCMD 12$: BIT #TURDY,@#MAGCMD BEQ 12$ BR MAGCD 20$: MOV # 7wr|wh,`y E 7ӂwhb E Z, tP Iw 0-",% w  =w (7,$ =w e0w ,w %,@w ke=,w @w jwww=w  ,D w  vw <Ae0w ,w ,j׀ZTXw H- @D7x,> ,: 4,*w _,?w &7 w 7 77 ,   w %B  B `& ,D# N     w,j#   NߋLN N,# ,nlddWwE%,# e7e0t%E% e7e,#0t &  " 5x ,$$&~ $&~&d,($  & % 9,N$ &  %| w DR% ',t$edw S % RECORD , BYTE C,$OUNT , DUMPED IN m#$ EBCDICAS; 11: ADVANCE TAPE FORWARD BEYOND NEXT END-OF-FILE AND STOP ; 12: PRINT DOUBLE SPACE ; 13: BYPASS RETRY ON MAG TAPE READ ERROR ; 14: STOP IMMEDIATELY AND REWIND TAPE ; 15: STOP IMMEDIATELY ; ; PROGRAMMER: 65 ; DATE: 2/7/73 ; ;************************************************* .PAGE ;*************** ; GLOBL'S ;*************** .GLOBL BASCNV .GLOBL ABSCNV ;*************** ; EQUATES ;***************4000,R5 SUB @#MAGWC,R5 ASL R5 MOV R5,BYTECT BIT #10000,@#MAGST ;ODD CHARACTER ERROR BEQ RTSPC JMP ODD RTSPC: RTS PC MTCMD: CLR @#MTS MOV #MTCLR,@#MTC MOV #WRITE,@#MTC 03$: MOV BYTECT,@#MTWC NEG @#MTWC MOV #BUFFER,@#MTCMA 05$: BIS #1,@#MTC 10$: BIT #TURDY,@#MTS BEQ 10$ TST @#MTS BPL 0 %7E ` , 1 W ֆ m7> ( y0hv؀V~cB:^֮LB֘,Vv4ט׶<׀Ԫԃl7gNR,|D D 7@7:%2. p,& w %=w ,w $B, w w ww  <, 7mw ,w %/w \,:  n,  L e`,`  !B !=L !6<,CII ASCII CHARS,$EBCDIC CHARS, TAPE READ ERROR *,% .1 .5 .,*%10 .15 .20 .25 .30 .35 .40 .45 :,P% .50 .55 .60 .65 .70 .75 .80 .8,v%5 .90 .95 .0100HEX ZONES - &HEX DIGIT &END-OF-FILER,u 6e%  w S,u 6 p  LY,vWp`v F V,6v( w e ,\v w`% e R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 SWR = 177570 TPB = 177566 MTCLR = BIT12 ; CLEAR MT CONTTROL EOF = BIT14 ; END OF FILE FLAG FROM MT (MTS) BC = 16800. ; ******* SPECIAL BYTE COUNT MTER = BIT15 ; ERROR FLAG FROM MT (MTC) MTC = MAGCMD ; MTCMA = MAGADR ; MTBRC = MAGWC ; MTS = MGSTAT ; BIT12  MTCMPT MOV #-1,@#MTWC MOV #MATBSP,@#MTC 20$: BIT #TURDY,@#MTS BEQ 20$ MOV #GAP,@#MTC BR 03$ MTCMPT: RTS PC ; MTWEOF: INC EOFCNT MOV #MTEOF,@#MTC 53$: BIT #TURDY,@#MTS BEQ 53$ CMP #2,EOFCNT BHI 63$ HALT 63$: JMP ST1 EOFCNT: .WORD 0 BYTECT: .WORD 0 BUFFER: .BLKW 8192. ODD: DEC BYTECT 44 Ԥ ,!44  p,% w .  @w @,,ـ % % w  ww X, D  &6,C@AEPA&fw w /w 8,Dڀw Lw   ` ,jE ` Z J ,ڰ w8`%w 71U&&E,w f7HE(%O,ڊ  p%w Z׭,$U,(ۮ7,v%  ,ve 6 U 5s,v B l7 6,vw w@A% 5%0,wUz%9UnUhE7^7 XmF,@wVPw JmJD <:v42V,fwv$"m"w mUl,w A w B,wB h-Cҕ0~DDc%C ,wBr'72 r EU0,wd~   V7 = 10000 ; BIT14 = 40000 ; BIT15 = 100000 ; ; MAGWC = 172524 ; MTBRC MGSTAT = 172520 ; MTS MAGCMD = 172522 ; MTC MAGADR = 172526 ; MTCMA ; LPS = LPCMD ; LPB = LPSTAT ; LPCMD = 177514 ; LPSTAT = 177516 ; ; READ = 1*2 ; BKSP = 5*2 ; REWD = 7* ;DECREMENT BYTE COUNT JMP RTSPC .END START w Dŝŝ>,NEw$rt wft!,t w w Jw @e:%ĕ,t72 Ԩw Bw .,e` w ;w ĝw  ,wf&f >, 4ӯ,2 2#0#7&#"#w K,Xr#5 ##g"b"1,~V  <ӄ !%&%, &e N @ e0w & ,  ,$x6A  Uwx B @ ,JxA e@ UwV&f&  ,px @ABAc@e !~  ,x@AB ~ @AB /,x~ BCE @E  ~ ,x BC D ~ 6m y `,y nxf 7 w,yNw 7$yCSw  7|w ,yw \ĝZ77N J ~G,y!z0w & =, z@J D A 2 ; SPFWD = 4*2 ; UNIT0 = 0 ; UNIT1 = 1*256. ; CURDY = BIT7 ; ; BIT7 = 200 ; FF = 14 ; LF = 12 ; LL = 131. ; LINE LENGTH - 1 ;*************** ; CONSTANTS AND TEMPORARY STORAGE ;*************** NOTRYS: .WORD 0 ERRFLG: .WORD 0 BYTECT: .WORD 0 CHARCT: .WORD 0 RECCT: .WORD 0 MAGBP:; UPDATE 28-APR-75 MTTOJT .TITLE TAPCPY 1600 TO 800 BPI TAPE COPY ; ; THIS PROGRAM COPIES BPI TAPES TO PRODUCE ; 800 BPI TAPES. ; R0 = %0 PC = %7 SP = %6 R5 = %5 MTC = 167544 MTCMA = 167546 MTWC = 167540 MTS = 167542 ; MAGCMD = 172522 MAGCMA =  ",7"t"p"E , w   w ׭6"l,<ݕ ^w Uw wn n%,bj  7,XR-P ,Dw@ 78 %(! ,݄  %??,w N%w 77,w Z e0w ,w , ްw p,F Cå å$ נA  ~,l  &DCc  ,Fzw Dw  w  ' 7  j,lz &w \w wXw w ,z fw  w 7 wtwh,zw } %E e$y wh,zvH ? =w XH A w Lh,{: w D3 w < w 4w < 7 w ,*{.7 w &7 7 2? \,P{w7  ww (b ww 7,v{w A B` %),{ w| 7wr|wh ,{y E 7Bywhb! .WORD 0 BYTCT: .WORD 0 MAXCCT: .WORD 0 WORK1: .WORD 0 .EVEN EBCTAB: .BYTE 005,045,000,024,025 EBCDIC: .BYTE 100,132,177,173,133,154,120,175,115,135 .BYTE 134,116,153,140,113,141,360,361,362,363 .BYTE 364,365,366,367,370,371,172,136,114,176 .BYTE 156,157,174,301,302,303,304,305,306,307 .BYTE 310,311,321,322,323,324,325,326,327,330 .BYTE 331,342,343,344,345,346,347,350,351 EBCEND =.-1 .PAGE ;*******" 172526 MAGWC = 172524 MAGST = 172520 ; READ = 3 MGCLR = 10000 CURDY = 1 ; MTCLR = 40000 WRITE = 2 TURDY = 200 GAP = 10 MATBSP = 200 MGBKSP = 12+1 MTEOF = 40000 ; MAGEOFe`  , Ëנe ee e ѐ  @(, ODT-11R V004A` BE, *;/\ $G _<^,OWEBP@>SRC-FI!XASPMCFRB,,?>$ E K,{ tByP ByIw 0-",|% w  =w (7,4|$ By=w e0w ,w %,Z|@w ke=,|w @w jwww=w ,| w  vw <Ae0w ,w ,|ZTXw H- @D7q,|By> ,: 4,*w P,}?w &7 w 7 77 ,>}   w %0 %7E ` ,d} 1a W ֆ %******** ; START HERE ;*************** TAPDUM: ;ENTRY POINT CLR RECCT ;RESET REC COUNTER JSR PC,TOP ;SKIP TO TOP OF NEW PAGE START: BIT #140000,@#SWR ;STOP TEST BEQ NOSTOP BIT #40000,@#SWR ;REWIND TEST BEFORE STOP BEQ 1$ CLR RECCT ;RESET REC COUNTER JSR PC,TOP ;SKIP TO TOP OF NEW PAGE MOV #REWD,R5 ; REWIND T& = 40000 START: CLR EOFCNT ST1: JSR PC,MAGCD CLR EOFCNT JSR PC,MTCMD BR START ; ; ; 1600 BPI READ ; MAGCD: MOV #MGCLR,@#MAGCMD CLR @#MAGST MOV #4000,@#MAGWC NEG @#MAGWC MOV #BUFFER,MAGCMA MOV #READ,@#MAGCMD MOV #100,R0 05$: SOB R0,05$ 10$: BIT #CURDY,@#MAGST '  L a8}YE, 7 * 7 " R PT T,& 2!*R@~5P5@P w ,L RTR R5P ,r T5T TT w b@, d`2!fd@~5b5@:, b5b b@dd5bj, H`2!f@ddw@d , !"d@~5b%w0!,a HR@ 7 w,a(w 7Jailylw  7|w s,aw \ĝ(m7/ } y}}}}6~zF~`{B~}~{\X~:r{z{{G,}{j|||}|z(z zl7gN ,}D D 7@7:%2. i,~& w %=w ,w $:,*~ w w ww  4,P~ 7mw ,v~w %/w \,~  n  L eRyJ,~  !`yB !`y=L !6%,~4Ry4 dy !4Ryvy4 dy =,% w .)APE JSR PC,GO 1$: HALT ;NOW STOP JMP START ;GO AGAIN NOSTOP: ;READ NEXT RECORD BIT #004000,@#SWR ;ADVANCE TAPE BEYOND NEXT EOF TEST BEQ 2$ MOV #MTCLR,@#MAGCMD ; RESET CONTROLLER MOV #BC,@#MAGWC ; MOV #MAGBUF,@#MAGADR MOV #READ,R5 JSR PC,GO ;READ A RECORD BIT #EOF,@#MGSTAT ; EOF ? BNE *BEQ 10$ BIT #MAGEOF,@#MAGST BEQ 42$ TST (SP)+ JMP MTWEOF 42$: TST @#MAGCMD ; ANY ERRORS BPL 20$ MOV #-1,@#MAGWC MOV #MGCLR,@#MAGCMD MOV #MGBKSP,@#MAGCMD ; 12$: BIT #CURDY,@#MAGST BEQ 12$ BR MAGCD 20$: NEG @#MAGWC ; NO ERRORS AFTER READ+Z77N J hI, b!&b0w & M,Fb@$ D A  &DCc  ,lbw Dw  w  ' 7  \,b &w \w wXw w ,b fw  w 7 wtwh,bw l %lE eJa wht,clH el =w XH A w L=,*c: w D3 w < w 4w < 7 w ,Pc.7 w &7 7 Xlel \j,vcw7  ww (b ww ),cw ,  @w @$,4 % % w  ww P,Z D  &.,C@AEPA&fw w /w 1,w Lw   ` ,E ` Z J , w8w 71U&&E,w f7HEO,>  pdyw Z׭,dU,7w Dŝŝ7,EwBrt- 4$ ;YES CLR RECCT ;NO, RESET REC CT BR START 4$: JSR PC,PRTBLK ;PRINT A BLANK LINE MOV #EOFM,R1 ;PRINT EOF MESSAGE MOV #11.,R5 JSR PC,PRINT HALT CLR RECCT ;RESET REC CT BR START 2$: MOV #7,NOTRYS ; 7 RETRYS NORMAL CLR ERRFLG 1$: MOV #MTCLR,@#MAGCMD ; RESET CONTROLLER MOV #-BC,@#MAGWC . BIT #1,@#MAGWC BEQ 50$ INC @#MAGWC 50$: MOV #4000,R5 SUB @#MAGWC,R5 ASR R5 MOV R5,BYTECT ; ; ; RTSPC: RTS PC MTCMD: CLR @#MTS MOV #MTCLR,@#MTC BR03: 03$: MOV BYTECT,@#MTWC MOV #BUFFER,@#MTCMA 05$: MOV #WRITE,@#MTC MOV #100,R0 04$: SOB R0,04$ 10$: /A B` %,c w| 7wr|wh,cy E 7hawhb E /,d thaP haIw 0-"x,4d% w  =w (7,Zd$ ha=w e0w ,w %,d@w ke=,dw @w jwww=w ,d w  vw <Ae0w ,w ,dZTXw H- @D7c,eha> ,: 4,*w 3,>e?w 0 wft!Ry,ր w w JTUw @e:%ĕ,tRy72 dydyw Bw .b,"e` w ;w ĝRyw ,Hw0yf&f .,n4RyvyRy, }}7}7}}w l,r}5}}g}b}P,V  <vyRy !%&, &e N @ e0w & ,, By "},R7}}}E1; SET BYTE COUNT MOV #MAGBUF,@#MAGADR ;ADDR OF MAG TAPE BUFFER MOV #READ,R5 ; READ COMMAND JSR PC,GO ;READ A RECORD BIT #MTER,@#MTC ; READ ERROR ON MT ? BEQ GOON ;NO IF BRANCH INC ERRFLG ;YES BIT #20000,@#SWR ;BYPASS RETRY TEST BNE GOON ;YES DEC NOTRYS ;TRY AGAIN TEST BLE GOON ;NO MORE MOV 2 BIT #TURDY,@#MTS BEQ 10$ BIT #40000,@#MTS ; EOT? BEQ OK HALT ;HALT IF EOT OK: BIT #4000,@#MTS ;ERROR? BEQ MTCMPT ;NO ERROR CLR @#MTS MOV #MTCLR,@#MTC ;BACKSPACE MOV #MATBSP,@#MTC 20$: BIT #TURDY,@#MTS BEQ 203&7 w 7 77 ,de   w %0 %7E ` ,e 1l W ֆ m7 e yeeef\fbhlfchfvefc6gg~gf`hccc,ecdd e>edcNb2bl7gN{,fD D 7@7:%2. Z,*f& w %=w ,w $,,Pf w w ww  &,vf 7mw ,fw %/w \,f  nl  L exa ,f 4 ,x w   w ׭|m, ^w Uw $ywn n,Ăj  7,ByXRBy-P ,Dw@ 78 %(! ,  %??_,6`^w N%w 77,\w Z e0w ,w  ,w p, Cå å$ נA  w,΃  e` & , Ëנe ee5 #MTCLR,@#MAGCMD ; RESET CONTROLLER MOV #-1,@#MAGWC ;BACKSPACE 1 RECORD S02 MOV #BKSP,R5 ; JSR PC,GO JMP 1$ ;TRY TO READ REC AGAIN GOON: INC RECCT ;BUMP REC READ COUNTER MOV @#MAGWC,BYTECT ; GET BYTE COUNT ADD #BC,BYTECT ; OF RECORD JSR R5,BASCNV ;GET BYTE COUNT .WORD BYTECT ;INTO PRINT HEADER FOR E6$ MOV BYTECT,@#MTWC MOV #BUFFER,@#MTCMA MOV #MTCLR,@#MTC MOV #GAP,@#MTC JMP BR03 MTCMPT: RTS PC ; MTWEOF: MOV #MTCLR,@#MTC INC EOFCNT MOV #4,@#MTC MOV #100,R0 52$: SOB R0,52$ 53$: BIT #TURDY,@#MTS BEQ 53$ CMP #2,EOFCNT BHI 63$ 7 !aB !a=L !6,g4xa4 a l!4xaa4 a ,4g% w .  @w @,Zg % % w  ww B,g D  & ,gC@AEPA&fw w /w #,gw Lw   ` ,gE ` Z J ,h w8ؗw 71U&&E,>hw f7HEO,dh  pa~w Z׭,h e ѐ  @(,. ODT-11R V004AX TBE,Z *;/\ $G _<^,OWEBP@>SRC-FI!XASPMCFRB,$y7Jy6R FACH REC .WORD BCT .WORD 4 JSR R5,BASCNV ;NOW RECORD COUNT .WORD RECCT .WORD RCT .WORD 4 BIT #400,@#SWR ;EBCDIC OR ASCII IN HEADER BEQ 10$ MOV #6,R2 11$: MOVB EBC-1(R2),DTY-1(R2) SOB R2,11$ BR 12$ 10$: MOV #6,R2 1$: MOVB ASC-1(R2),DTY-1(R2) SOB R2,1$ 12$: TST ERRFLG ;ANY TAPE READ ERRORS HALT 63$: JMP ST1 EOFCNT: .WORD 0 BYTECT: .WORD 0 BUFFER: .BLKW 8192. .END START EfU,h7w Dŝŝ),hEwrt wft!xay,h w w Jzl{lw @e:%ĕ,"itxa72 aaw Bw .),Hie` w ;w ĝxaw ,niwVaf&f ,i4xaaxaY,i 77w ,ir5|gtbr,jV  <axa !%&,,j DDD """"""@DDDDDDDDDDDDDD ADDB CA_^A_{NA_K18}UK 48}U{#tTd_|6tTd_K]#I$DFDDDDDDDDDa ͋,L  B8w&B ` % & }&*C$$Βe E%>k  aʋaՀ$ & * P$ ΋Ί   ΋   d Ί  ( 1'u  Q$f $5@ U C΋ Cb M΋U@ U &  B" .&0 M &0 & M 0 &I&e N @ e0w & ,Rj ha ,xj7E -,j w   w ׭m,j ^w Uw Jawn n,jj  7,haXRha-P ,kDw@ 78 %(! ,6k  %??l,\kllw N%w 77,kw Z e0w ,w ,kw pt,k Cå å$J BEQ 2$ ;THEN SAY SO IN HEADER LINE MOV #17.,R2 ;YES 3$: MOVB TRE-1(R2),RER-1(R2) SOB R2,3$ BR 4$ 2$: MOV #17.,R2 ;NO 5$: MOVB NTRE-1(R2),RER-1(R2) SOB R2,5$ 4$: JSR PC,PRTBLK ;PRINT A BLANK LINE JSR PC,PRTBLK ;PRINT A BLANK LINE MOV #HDMES,R1 ;NOW PRINT HEADER MOV #64.,R5 JSR PC,PRINT BIT #EOF,K CLEARED ACCUMULATOR BY 10(MULTIPLYING ITS CONTENTS ; BY 5 AND THEN DOUBLING) AND ADDING THE ; ASCII EQUIVALENT BCD VALUE. THIS WILL BE DONE ; FOR EACH SIGNIFICANT POSITION LEFT TO RIGHT. ; EACH DIGIT'S RESULT IS STORED BACK IN THE ; ACCUMULATOR TO USE FOR THE NEXT CALCULATION. ; ATB100: MOVB (R1)+,R4 ;GET NEXT ASCII BYTE AND BUMP ATB105: SUB #ZERO,R4 ;ASCII NUMERIC TO BCD BMI ATB200 ;ERROR IF LESS THAN ZERO CMPB L ;R0=DIVISION TABLE ADDRESS TST R4 ;IS INTEGER NEGATIVE? BMI BTA050 ;YES MOVB #PLUS,(R5)+ ;NO-SET PLUS SIGN AND BUMP BTA010: MOVB #SPACE,R1 ;R1=ZERO SUPPRESS BYTE REGISTER BTA020: CLR R2 ;INITIALIZE SUBTRACTION COUNTER BTA030: SUB (R0),R4 ;SUBTRACT DIVISOR FROM INTEGER BPL BTA060 ADD (R0)+,R4 ;ADD BACK & BUMP DIVISOR POINTER TST R2 BEQ BTA נA  i,k  e` Ll c,l Ëנe ee e ѐ@l  @(},Tl ODT-11R V004AJ zlBE,l *;/\ $G _<^,OWEBP@>SRC-FI!XASPMlCFRBl,Ja)pa( N@#MGSTAT ; EOF ? BNE EOFF ; YES BIT #400,@#SWR ;NO, EBCDIC READ TEST BNE EBBSEE ;YES ;USE BYTECT NOW FOR LOOP COUNTER MOV #MAGBUF,MAGBP ;ASSUME ASCII READ MOV BYTECT,BYTCT MOVB #'0,DIGITP+120. MOVB #'1,DIGITP+121. MOVB #'0,DIGITP+122. MOVB #'0,DIGITP+123. 15$: JSR PC,PRTBLK ;PRINT A BLANK LINE JSR PC,SUPHEX ;SET UP HEO R4,#NINE BHI ATB200 ;ERROR IF GREATER THAN NINE MOV R5,R3 ; ACCUM. TO SHIFT 2 MOV R3,R2 ;DUPLICATE IN SHIFT 1 ACCUM. ASL R3 ; MULTIPLY ASL R3 ; BY 4 ADD R3,R2 ; SAME AS N*5 ADD R2,R2 ; SAME AS N*10 ADD R4,R2 ;COMBINE WITH BCD VALUE MOV R2,R5 ; SET IN BINARY INT. ACCUM DEC R0 P040 MOV #ZERO,R1 ;STOP ZERO SUPPRESSION BTA040: ADD R1,R2 ;CALCULATE ASCII BYTE MOVB R2,(R5)+ ;SET IN STRING AND BUMP TST (R0) BNE BTA020 ;NOT FINISHED ADD #ZERO,R4 ;MAKE SURE UNITS SIGNIFICANT MOVB R4,(R5) ;PUT IN UNITS POSITION MOV 12.(SP),16.(SP) ; SET UP STACK FOR RETURN JSR R5,POPR ; RESTORE REGISTERS CMP (SP)+,(SP)+ ; STACQh7 Z7 X7 V7 kT7 RjDj: <j&j"6@7 m pthl  E  FwZ@ 7 f7 d7 b7 f  7 R7 P^ "  |tw w:wTC`N @7 wՕ 7 w>6@: Y N &,@, &&e  ee@(J_ DO YOU REQUIRE EXP ORX LINES JSR PC,PRTLNS ;PRINT SOME LINES SUB #100.,BYTCT ;HASNT RUN OUT YET ADD #100.,MAGBP TST BYTCT ;HAS BYTCT RUN DOWN BLE 14$ JSR PC,A100 ;ADD 100. TO LINER UPPER JMP 15$ 14$: JMP START ;GO GET NEXT RECORD EOFF: JSR PC,PRTBLK ;PRINT A BLANK LINE MOV #EOFM,R1 ;PRINT EOF MESSAGE MOV #11.,R5 JSR S ;FINISHED WITH STRING? BNE ATB100 ;NO ATB110: CMPB #MINUS,-6(R1) ;YES-STRING SIGN NEGATIVE BNE ATB120 ;NO NEG R5 ; YES-NEGATE BINARY INTEGER ATB120: MOV R5,14.(SP) ; SET BIN. INT. IN STACK CLR 16.(SP) ; SET NO ERROR IN INDICATOR ATB130: JSR R5,POPR ; RESTORE REGISTERS RTS PC ; RETURN TO CALLER ; ; ERROR IN STRING ; ATB200 = . K OK NOW RTS PC ; RETURN TO CALLER ; ; BTA050: MOVB #MINUS,(R5)+ ; SET MINUS SIGN AND BUMP NEG R4 ;SET INTEGER POSITIVE BR BTA010 ; BTA060: TSTB (R2)+ ;BUMP SUBTRACTION COUNTER BR BTA030 ; ; .END UR LOG (FLOATING ^)?xDO YOU NEED THE EXTENDED FUNCTIONS?HIGH-SPEED READER/PUNCH?SET UP THE EXTERNAL FUNCTION?MEMORY? <@VPC,PRINT BIT #002000,@#SWR ;STOP DUMP ON EOF TEST BEQ 1$ HALT 1$: JMP START ;GO GET NEXT RECORD EBBSEE: MOV #MAGBUF,MAGBP ;CONVERT FROM EBCDIC TO ASCII AND PRINT MOV BYTECT,BYTCT MOVB #'0,DIGITP+120. MOVB #'1,DIGITP+121. MOVB #'0,DIGITP+122. MOVB #'0,DIGITP+123. 15$: JSR PC,PRTBLK ;PRINT A BLANK LINE JSR PC,SUPHEX ;NOW MOV R4,16.(SP) ; SET ERROR INDICATOR BR ATB130 ; ; .END X; UPDATE 12/2/71 SAVE.S06 ; UPDATE 11/8/71 SAVE.S05 ; UPDATE 11/5/71 SAVE.S04 ; UPDATE 11/3/71 SAVE.S03 ; UPDATE 10/8/71 SAVE.S02 ; UPDATE 9/15/71 SAVE.S01 .TITLE SAVE ;*********************************************************************** ;* * ;* PROGRAM IDENTIFICATION. SAVE, CATALOG NO. ; * ;* SAVE EZ SET UP HEX LINES MOV #100.,R0 ;CONVERT EBCDIC TO ASCII MOV MAGBP,R1 3$: MOVB (R1),R2 ;FETCH NEXT CHAR MOV R2,R3 MOV #EBCTAB,R4 5$: CMPB R3,(R4)+ ;MATCH? BEQ 6$ CMP R4,#EBCEND ;MORE? BLOS 5$ MOV #' ,R4 ;BLANK INSERTED FOR ILLEGAL EBCDIC CHAR BR 7$ 6$: SUB #EBCDIC+1,R4 ;WAS IT REGUALR PART OF TABLE BGE [; UPDATE 12/2/71 RESTOR.S04 ; UPDATE 11/8/71 RESTOR.S03 ; UPDATE 10/8/71 RESTOR.S02 ; UPDATE 9/15/71 RESTOR.S01 .TITLE RESTOR ;*********************************************************************** ;* * ;* PROGRAM IDENTIFICATION. RESTOR, CATALOG NO. ; * ;* RESTORE ENVIRONMENT FROM INTERRUPT HANDLER. * ;* \NVIRONMENT FOR INTERRUPT HANDLER. * ;* * ;* PURPOSE. THIS SUBROUTINE WILL SAVE AN ENVIRONMENT * ;* (GENERAL REGISTERS) FOR AN INTERRUPT ROUTINE. IT IS THIS * ;* SUBROUTINE'S RESPONSIBILITY TO DETERMINE IF THE STACK * ;* REGISTER ALREADY CONTAINS THE CURRENT VALUE OF THE SYSTEM STACK* ;* OR WHETHER IT SHOULD BE LOADED WITH IT. * ;* ] . .WORD AC0000 .WORD AC0001 .WORD AC0002 .WORD AC0003 .WORD AC0004 .WORD AC0005 .WORD AC0006 .WORD AC0007 .WORD AC0008 .WORD AC0009 .WORD AC0010 .WORD AC0011 .WORD AC0012 .WORD AC0013 .WORD AC0014 .WORD AC0015 .WORD AC0016 .WORD AC0017 .WORD AC0018 .WORD AC0019 .WORD AC0020 ^8$ ;YES ADD #5+11-40,R4 ;WAS ONE OF SPECIALS AT BEGIN OF TABLE 8$: ADD #40,R4 ;CREATE ASCII CHAR FROM TABLE INDEX 7$: MOVB R4,(R1)+ ;REPLACE EBCDIC WITH NON-PARITY ASCII DEC R0 ;MORE CHARS? HANDLE 100 AT A TIME BGT 3$ ;NEXT CHAR JSR PC,PRTLNS ;PRINT SOME LINES SUB #100.,BYTCT ;HASNT RUN OUT YET ADD #100.,MAGBP TST BYTCT _ * ;* PURPOSE. THIS SUBROUTINE WILL SERVE AS AN INTERRUPT * ;* ROUTINE'S EXIT. IT WILL RESTORE THE ENVIRONMENT(GENERAL * ;* REGISTERS) AND RETURN TO IT. IT WILL BE RESPONSIBLE FOR * ;* DETERMINING IF THE ENVIRONMENT IS ANOTHER INTERRUPT ROUTINE * ;* OR A TASK. * ;* * ;* ` * ;* PROGRAM USAGE. THE LINKAGE TO SAVE SHALL BE THRU: * ;* * ;* SAVE * ;* WHICH IS A ROS MNUEMONIC FOR THE UN-NAMED TRAP INSTRUCTION * ;* 000003 BASE 8. UPON RETURN, REGISTER 5 (R5) WILL CONTAIN * ;* THE ADDRESS OF RESTOR SO THAT AN INTERRUPT ROUTINE *a; .= AUTCOD+ACTSIZ+ACTSIZ ; USE ONLY AMOUNT NEEDED .WORD -1. ; END OF TABLE .PAGE ; ; OPERATOR COMMAND TABLE - EITHER CONTAINS ADDRESSES OF ; COMMAND PROCESSORS OR SEGMENT NUMBERS DEPENDING ON ; WHETHER OR NOT INPUT IS AN OVERLAY TASK ; .IFZ OVRLAY OPCOMM = . .ASCII /EN/ .WORD ENABLE ; ADDRESS OF ENABLE .ASCII /DS/ .WORD DSABLE ; ADDRESS OF DSABLE .ASCIIb ;HAS BYTCT RUN DOWN BLE 14$ JSR PC,A100 ;ADD 100. TO LINER UPPER JMP 15$ 14$: JMP START ;GO GET NEXT RECORD ; ; SUBROUTINE TO PERFORM MAG TAPE COMMAND REQUESTED ; GO: CLR @#MGSTAT ;CLEAR STATUS MOV @#SWR,R4 ;ISOLATE TAPE UNIT NO S01 BIC #177760,R4 ; S01 SWAB R4 ; c PROGRAM USAGE. THE LINKAGE TO RESTOR SHALL BE: * ;* * ;* JMP RESTOR OR * ;* ALTERNATELY: * ;* JMP (R5) WHERE R5 CONTAINS * ;* THE ADDRESS OF RESTOR (NOTE: THIS IS SET IN SAVE). * ;* *d ;* NEED NOT BE 'LOADED' WITH ROS. REGISTER 4 (R4) WILL * ;* CONTAIN THE PS OF THE INTERRUPTED ENVIRONMENT. REGISTER * ;* 3 (R3) WILL CONTAIN THE PC OF THE INTERRUPTED ENVRIONMENT. * ;* * ;* PROGRAMMER 54 * ;* DATE * ;* REVISION e /QU/ .WORD QTASK ; ADDRESS OF QTASK .ASCII /XX/ .WORD TABORT ; ADDRESS OF TABORT .ASCII /TM/ .WORD TIME ; ADDRESS OF TIME .ASCII /DT/ .WORD DATE ; ADDRESS OF DATE .ASCII /RE/ .WORD RESET ; ADDRESS OF RESET .ASCII /EX/ .WORD 0 ; EXIT FROM INPUT TASK .WORD 0 ; END OF TABLE .ENDC ; ; f S01 BIS R4,R5 ; S01 MOV R5,@#MAGCMD ;PERFORM OPERATION REQUESTED S01 BIS #1,@#MAGCMD ; SET GO BIT MOV R0,-(SP) ;SAVE R0 MOV #100,R0 SOB R0,. ;LOOP UNTIL CONTROLLER SETTLES MOV (SP)+,R0 ;RESTORE R0 10$: BIT #CURDY,MTC ; UNIT READY ? BEQ 10$ g ;* PROGRAMMER 54 * ;* DATE * ;* REVISION * ;* * ;*********************************************************************** .DEF RESTOR .REF NINT,DSPTCH,MFLAG,TSKSTK .REF SBSYNA ; .CSECT ; PLOCK = 340 h * ;* * ;*********************************************************************** .DEF NINT,SAVE,TSKSTK .REF ACTIVE,QSAVEI,RESTOR,MFLAG,STACK .REF SBSYNA ; .ASECT . = 14 ; TRAP VECTOR ADDRESS FOR SAVE .WORD SAVE ; PC .WORD 340 ; PSR- PRIORITY LOCKOUT DURING SAVE ; .CSECT ; NINT: .WORD -1. i.IFNZ OVRLAY OPCOMM = . .ASCII /EN/ ; ENABLE TASK .BYTE 1.,1. ; SEGNO 1 - FIRST INSTRUCTION .ASCII /DS/ ; DISABLE TASK .BYTE 1.,2. ; SEGNO 1 - SECOND INSTRUCTION .ASCII /QU/ ; QUEUE TASK .BYTE 1.,3. ; SEGNO 1 - THIRD INSTRUCTION .ASCII /XX/ ; ABORT TASK .BYTE 1.,4. ; SEGNO 1 - FOURTH INSTRUCTION .ASCII /TM/ ; j ; NO - WAIT RTS PC ; ; BLANK OUT HEX BUFFERS SUBROUTINE ; BLKHX: MOV #112.,R2 1$: MOVB #40,HEXZ+20.-1(R2) MOVB #40,HEXD+20.-1(R2) SOB R2,1$ RTS PC ; ; SUBROUTINE TO SKIP TO THE TOP OF THE NEXT PAGE ON THE LP ; ONECHR: .BYTE 0 .BYTE 0 TOP: CLR @#LPS ; CLEAR LP MOV #FF,R0 ; WRITE TOP JSR PC,PRINTC ; OF FORM RTS PCk ; PRIORITY LOCKOUT MASK PSR = 177776 ; PROCESSOR STATUS REGISTER ADDRESS ; RESTOR = . MOV #PLOCK,PSR ; SET PRIORITY LOCKOUT DEC NINT ; DECREMENT NO. INTERRUPTS ACTIVE BMI RESB00 ; RESTORING FROM FIRST INTERRUPT RESA00: MOV (SP)+,R0 ; RESTORE MOV (SP)+,R1 ; GENERAL MOV (SP)+,R2 ; PURPOSE MOV (SP)+,R3 ; REGISTERS Ml ; NO. OF INTERRUPTS STACKED ; PSSAVE: .WORD 0 ; USED TO SAVE PS OF INTERRUPT VECTOR PCSAVE: .WORD 0 ; USED TO SAVE PC OF INTERRUPT VECTOR OLDPSR: .WORD 0 ; USED TO SAVE OLD PSR OF ENVIRONMENT OLDPC: .WORD 0 ; USED TO SAVE OLD PC OF ENVIRONMENT TSKSTK: .WORD 0 ; USED TO SAVE VALUE OF TASK'S ; ; STACK IF MFLAG SET ; SAVE = . MOV 6.(SP),OLDPSR ; SAVE PS OF ENV.mSET TIME - TYPE TIME .BYTE 2.,1. ; SEGNO 2 - FIRST INSTRUCTION .ASCII /DT/ ; SET DATE - TYPE DATE .BYTE 3.,1. ; SEGNO 3 - FIRST INSTRUCTION .ASCII /RE/ .BYTE 4.,1. ; SEGNO 4-FIRST INSTRUCTION .ASCII /EX/ ; EXIT FROM INPUT TASK .WORD 0 .WORD 0 ; END OF TABLE .ENDC ; .IFNZ OVRLAY ; ; IF INPUT AN OVERLAY, THE FOLLOWING IS RESERVEDn ; ; BLANK OUT SCRATCH LINE SUBROUTINE ; BLKSL: MOV #132.,R2 1$: MOVB #40,SCRBUF-1(R2) SOB R2,1$ RTS PC ; ; SUBROUTINE TO PRINT A BLANK LINE ; PRTBLK: JSR PC,BLKSL ;SET SCRATCH BUFFER TO BLANKS MOV #SCRBUF,R1 ;NOW PRINT IT MOV #LL,R5 ; JSR PC,PRINT RTS PC ; ; SUBROUTINE TO PRINT A LINE OF 132 CHARS ON THE LINE PRINTER oOV (SP)+,R4 MOV (SP)+,R5 TST MFLAG ; TASK LOCK-OUT SET BNE RESA20 ; YES RTI ; RETURN FROM INTERRUPT ; ; MFAG SET-SOFTWARE LOCKOUT ON ; RESA20: TST NINT ; RESTORING FROM FIRST INTERRUPT? BGE RESA30 ; NO-RETURN MOV TSKSTK,SP ; YES-RESTORE TASK'S STACK POINTER RESA30: RTI ; RETURN FROM INTERRUPT ; ; FIRST INTERRUPT ;p MOV (SP)+,PCSAVE ; SAVE PC AND PS FOR RETURN RTI MOV (SP)+,PSSAVE ; POP OFF STACK MOV (SP),OLDPC ; SAVE PC OF ENVIRONMENT INC NINT ; BUMP NO. INTERRUPTS STACKED BNE SAVE20 ; NOT FIRST ONE-ALREADY ON SYSTEM STACK TST ACTIVE ; INTERRUPT A TASK? BEQ SAVE30 ; NO-SYSTEM QUIESCENT-POINTING TO S.S TST MFLAG ; TASK LOCKOUT SET? BNE SAVEq SPACE ; FOR THE OPERATOR COMMAND PROCESSOR SEGMENTS. ; .CSECT OPCOSG ; SGSIZE = 100. ; MAX. SIZE OF OPERATOR COMMAND PROCESSOR ; ; SEGMENTS IN WORDS SEGHDR = . .WORD 0,0,0,0,0,0 ; SIX WORD SEGMENT HEADER .=.+SGSIZE+SGSIZE ; RESERVE SPACE FOR SEGMENT ; .CSECT .ENDC ; .PAGE ; ; EQUATES FOR ASCII STRING ; ASCIIS = ASCII ; ASCII SIGN POSITION Ar; PRINT: MOV #0,@#LPCMD ; CLR L/P 10$: TST @#LPB ; LP READY ? BPL 10$ ; NO - WAIT MOV #132.,R3 ;BLANK OUT PRINT BUFFER IN EVEN PARITY 1$: MOVB #240,PRTBUF-1(R3) SOB R3,1$ MOV #PRTBUF,R0 ;PRINT BUFFER ADDRESS MOV #132.,CHARCT ;CHAR COUNT 8$: MOVB (R1)+,R2 ;NEXT ASCII CHAR CMP R2,#40 ;<40 TEST BGE 2$ RESB00 = . TST SBSYNA ; WAS SYSTEM BUSY AND NO TASK ACTIVE? BNE RESA00 ; YES-DON'T GO TO DISPATCHER TST MFLAG ; TASK LOCKOUT SET? BNE RESA00 ; YES-RESTORE REGISTERS JMP DSPTCH ; GO TO DISPATCHER UNDER LOCKOUT ; .END t15 ; YES-DON'T SUSPEND MOV #1.,-(SP) ; SET INVOLUNTARY SUSPENSION JSR PC,QSAVEI ; SAVE TASK'S ENVIRONMENT-SWITCH STACK SAVE10: MOV PSSAVE,-(SP) ; RESTORE PSR FOR SAVE MOV PCSAVE,-(SP) ; RESTORE PC FOR SAVE MOV #RESTOR,R5 ; SEND BACK ADDRESS OF RESTOR MOV OLDPSR,R4 ; OLD PS OF ENVIRONMENT MOV OLDPC,R3 ; OLD PC OF ENVIRONMENT RTI ; RETURN TO INTERRUPuSCII1 = ASCII+1. ; 10,000 POSITION ASCII2 = ASCII+2. ; 1,000 POSITION ASCII3 = ASCII+3. ; 100 POSITION ASCII4 = ASCII+4. ; 10 POSITION ASCII5 = ASCII+5. ; DIGIT POSITION .PAGE ; ; IF AN OVERLAY - INPUT MAY BE CHECKPOINTED ; INPUT = . MOV #ACMSG,DATADR ; AUTHORIZATION CODE REQUEST MOV #TTYLST,-(SP) ; I/O LIST ADDRESS TO STACK JSR PC,TTYOUT ; TYPE "AC:" - EXITv ;NO 4$: MOVB #240,R0 ; CHANGE JSR PC,PRINTC ; TO SP BR 3$ 2$: CMP R2,#140 ;>137 TEST BGE 4$ ;YES CLR -(SP) ;GET EVEN PARITY FOR ASCII CHAR IN R2 MOV #7,R4 MOV R2,R3 5$: ASR R3 ADC (SP) DEC R4 BGT 5$ ASL R2 ASR (SP)+ RORB R2 MOVB R2,R0 ; PUT TO w; UPDATE 11/9/71 UNMASK.S03 ; UPDATE 11/8/71 UNMASK.S02 ; UPDATE 10/8/71 UNMASK.S01 .TITLE UNMASK ;*********************************************************************** ;* * ;* PROGRAM IDENTIFICATION. UNMASK, CATALOG NO. ; * ;* MASK SOFTWARE PRIORITY LOCK-OUT OFF. * ;* T HANDLER ; ; SWITCH TO SYSTEM STACK ; SAVE15: MOV SP,TSKSTK ; SAVE TASK'S STACK POINTER MOV STACK,SP ; SWITCH TO SYSTEM STACK ; ; ALREADY ON SYSTEM STACK - SAVE REGISTERS ; SAVE20: MOV R5,-(SP) ; SAVE MOV R4,-(SP) ; REGISTERS MOV R3,-(SP) ; ON MOV R2,-(SP) ; SYSTEM MOV R1,-(SP) ; STACK MOV R0,-(SP) BR SAVE10 y TYPE TWO MOV #100004,INBUF ; INPUT FOUR CHARACTER AUTHORIZATION MOV #INBUF,DATADR ; CODE -NO ECHO MOV #TTYLST,-(SP) JSR PC,TTYIN ; GET AUTHORIZATION CODE TST INERR ; ERROR OR TIMEOUT OCCUR? BNE IPTA20 ; YES CMP #4.,NOCHAR ; 4 CHARACTERS INPUT? BNE IPTA20 ; NO-EXIT CLR ASCII ; CLEAR SIGN & 10,000 POSITION MOV BUFST,ASCII2 z JSR PC,PRINTC ; PRINTER 3$: DEC R5 ;DECREMENT BYTE CT BLE 6$ DEC CHARCT ;DECREMENT CHAR CT BLE 6$ JMP 8$ ;NEXT CHAR 6$: JSR PC,PRIT ;PRINT IT RTS PC ;RETURN PRIT: MOVB #LF,R0 JSR PC,PRINTC RTS PC ; ; PRINT A CHAR ; PRINTC: TST @#LPB ; READY ? BPL PRINTC ; NO - { * ;* PURPOSE. THIS ROUTINE WILL RELEASE THE PRIORITY LOCK-OUT * ;* MFLAG, SET BY MASK. THUS THE ROS TASK PRIORITY * ;* STRUCTURE WILL BE BACK IN AFFECT. UNMASK THEN * ;* CALLS THE DISPATCHER TO SEE IF A HIGHER PRIORITY * ;* TASK IS IN THE ROS SYSTEM QUEUES * ;* * ;* PROGRAM USAGE. THE LINKAGE TO ROUTINE UNMA|. ERRTYP, CATALOG NO. ; * ;* TYPE ROS ERROR MESSAGES * ;* * ;* PURPOSE. THIS SUBROUTINE WILL TYPE A SYSTEM ERROR MESSAGE * ;* ON THE SYSTEM OUTPUT DEVICE WITH SPECIFIED ARGUMENTS * ;* GIVEN BY THE CALLER. THIS SUBROUTINE PROVIDES THE CON- * ;* SISTENT ERROR MESSAGE FORMAT: * ;* } ; SET UP 1,000 & 100 POSITION MOV BUFST+2,ASCII4 ; SET UP 10 & DIGIT POSITION MOV #ASCII,-(SP) ; ASCII STRING ADDRESS JSR PC,ASCBIN ; CONVERT ASCII TO BINARY MOV (SP)+,R1 ; GET CONVERTED A.C. TST (SP)+ ; CONVERSION ERROR OCCUR? BNE IPTA20 ; YES - EXIT MOV #AUTCOD,R0 ; SEARCH AUTCOD TABLE FOR MATCH IPTA10: CMP (R0)+,R1 ; MATCH? BEQ IPTB00 ; Y~ TSTB @#LPS ; BPL PRINTC ; MOVB R0,@#LPB ; YES - PRINT IT 20$: TST @#LPB ; READY ? BPL 20$ ; NO - RTS PC ; ; ; ; SET UP HEX LINES SUBROUTINE ; SUPHEX: JSR PC,BLKHX ;BLANK OUT HEX ZONES BUFFERS MOV MAGBP,R2 ;NOW DO HEX LINES MOV BYTCT,R3 MOV #20.,R4 MOSK IS: * ;* * ;* EMT UNMASK * ;* * ;* THE FORTRAN EQUIVALENT CALL IS: * ;* * ;* CALL UNMASK * ;* * ;* "ERROR (NUMBER) * ;* ARG1 * ;* ARG2 * ;* ARG3 * ;* ARG4" * ;* * ;* A ROS ES - CONTINUE TST (R0) ; END OF TABLE? BPL IPTA10 ; NO- KEEP-A- SEARCHIN' IPTA20: JMP EXIT ; EXIT FROM TASK ; ; MESSAGE INTERPRETER ; IPTB00 = . MOV #TTRLST,-(SP) ; TTY I/O LIST FOR READY MSG TO STACK JSR PC,TTYOUT ; TYPE '? ' WITH EXIT TYPE 1 MOV #MXCHIN,INBUF ; SET TO INPUT OPERATOR COMMAND MOV #INBUF,DATADR ; SET BUFFER ADDRESS IN LIST CLR BUFST+2 V #100.,MAXCCT ;MAX CHAR CT PER LINE IS 100 13$: MOVB (R2),R5 ;HANDLE HEX ZONES ASHC #-4,R5 BIC #177760,R5 CMP #12,R5 BGT 8$ ADD #67,R5 ;A-F, THEREFORE ADD 67 TO IT BR 9$ 8$: ADD #60,R5 ;0-9, THEREFORE ADD 60 TO IT 9$: MOVB R5,HEXZ(R4) MOVB (R2)+,R5 ;HANDLE DIGIT ZONES BIC #177760,R5 CMP #12,R5 BGT 10$ * ;* RETURN IS VIA THE DISPATCHER * ;* * ;* PROGRAMMER 54 * ;* DATE * ;* REVISION * ;* * ;*********************************ERROR LOG SHOULD BE MAINTAINED FOR CLASSIFICATION * ;* LOOK-UP AND MEANING OF ARGUMENTS. IT IS ALSO RECOMMENDED * ;* THAT USER ERROR NUMBERS START AT 500 SUCH THAT ERRORS * ;* 1-499 MAY BE RESERVED FOR ROS. * ;* * ;* PROGRAM USAGE. THE LINKAGE TO ERRTYP IS AS FOLLOWS: * ;* * ;* ; RESET DELIMITER POSITION MOV #TTYLST,-(SP) ; TTY I/O LIST TO STACK JSR PC,TTYIN ; WAIT FOR COMMAND TST INERR ; TIME-OUT OCCUR BNE IPTA20 ; YES- CANCEL THIS TASK MOV #NOCHAR,R5 ; SIZE OF INPUT MSG ADDRESS MOV (R5)+,R4 ; GET NO. CHARACTERS INPUT SUB #2.,R4 ; MUST BE AT LEAST TWO BMI IPTB20 ; CHARACTERS OR ERROR DEC R4 ADD #67,R5 ;A-F BR 11$ 10$: ADD #60,R5 ;0-9 11$: MOVB R5,HEXD(R4) INC R4 DEC R3 ;DEC BYTE COUNT BLE 12$ DEC MAXCCT ;DEC MAX CHAR CT PER LINE BLE 12$ BR 13$ 12$: RTS PC ; ; SUBROUTINE TO PRINT A BLANK LINE, DATA LINE, TWO HEX LINES, ; AND A LINER UPPER LINE. ; PRTLNS: JSR PC,BLKSL ;BLANK OUT S************************************** .DEF UNMASK .REF QSAVE,MFLAG,DSPTCH ; .CSECT PSR = 177776 ; ; UNMASK = . MOV PSR,-(SP) ; PSR TO STACK FOR QSAVE MOV #1.,-(SP) ; SET UP FOR INVOLUNTARY SUSPENSION JSR PC,QSAVE ; OF CURRENT TASK CLR MFLAG ; RESET TASK SOFTWARE PRIORITY LOCK-OUT JMP DSPTCH ; GO TO DISPATCHER TO CLEAN-UP QUEUES ; ; .END MOV MADDR,-(SP) * ;* EMT ERRTYP * ;* * ;* OR THE FORTRAN EQUIVALENT: * ;* * ;* CALL ERRTYP(MADDR) * ;* WHERE MADDR IS THE ADDRESS OF THE ERROR MODULE: * ; R4= # CHARS. IN PARAMETER MOV #OPCOMM,R3 ; ADDRESS OF OPCOMM TO R3 FOR IPTB10: CMP (R5),(R3)+ ; OPERATOR COMMAND CODE SEARCH BEQ IPTC00 ; FOUND IT TST (R3)+ ; BUMP TO NEXT POSSIBLE COMMAND TST (R3) ; END OF TABLE? BNE IPTB10 ; NO- KEEP LOOKING IPTB20: MOV #ER1MSG,DATADR ; YES- REPORT ERROR IPTB21: MOV #TTYLST,-(SP) ; TTY I/O LIST TO STACK JSR PC,TCRATCH BUFFER BIT #400,@#SWR ;EBCDIC OR ASCII CHARS BEQ 10$ MOV #12.,R2 11$: MOVB ECHA-1(R2),SCRBUF-1(R2) SOB R2,11$ BR 12$ 10$: MOV #11.,R2 13$: MOVB ACHA-1(R2),SCRBUF-1(R2) SOB R2,13$ 12$: MOV MAGBP,R2 ;SET UP POINTERS AND COUNTERS MOV BYTCT,R3 MOV #SCRBUF+20.,R4 MOV #100.,MAXCCT ;MAX CHAR CT PER LINE IS 100 7$: MOVB (R2) ;* * ;* WORD 0 = THREAD WORD * ;* WORD 1 = ERROR NUMBER * ;* WORD 2 = ARGUMENT 1 * ;* WORD 3 = ARGUMENT 2 * ;* WORD 4 = ARGUMENT 3 * ;* WORD 5 = ARGUMENT 4 TYOUT ; TYPE "ILL CMD!" BR IPTB00 ; REQUEST AGAIN ; ; TRANSFER TO APPROPRIATE PROCESSOR. ; CALLING SEQUENCE: ; JSR PC, PROCES ; WHERE R5 = ADDRESS OF COMMAND STRING ; DELIMITER POSITION ; R4 = NO. OF CHARACTERS IN PARAMETER ; IF LESS THAN 0-NONE ; IPTC00 = . TST (R3) ; IF ZERO- EX..IT CO+,(R4)+ ;MOVE CHARS TO SCRATCH BUFFER DEC R3 ;DEC BYTE COUNT BLE 6$ DEC MAXCCT ;DEC MAX CHAR CT PER LINE BLE 6$ BR 7$ ;LOOP TIL DONE 6$: MOV #SCRBUF,R1 ;PRINT THE ASCII LINE MOV #LL,R5 ; JSR PC,PRINT MOV #HEXZ,R1 ;PRINT HEX ZONES LINE MOV #LL,R5 ; JSR PC,PRINT MOV #HEXD,R1 4(SP) ;MOVE CALLER'S PS FOR RTI EXIT MOV R0,6(SP) ;WILL LEAVE CALLER'S PC ON STACK @ EXIT DEC R0 ;BACK POINTER ONE BYTE MOVB -(R0),R0 ;BACK POINTER TO EMT INSTR&GET EMT CODE ASL R0 ;NEED TO INDEX WORDS IN TABLE CMP R0,#MAXEMT*2 ;SEE IF CODE IS VALID BHI EMTA20 ;INVALID: OUTSIDE TABLE RANGE EMTA10: MOV EMTABL(R0),2(SP) ;LOAD STACK WITH SUBROUTINE ADDR ; IF * ;* * ;* THE ARGUMENTS WILL BE TYPED AS SIGNED ASCII INTEGERS * ;* OF THE FORM +/-XXXXX. IF ANY ERRORS OCCUR, IT * ;* WILL BE IGNORED. * ;* * ;* PROGRAMMER 54 * ;* DATE MMAND BEQ IPTA20 ; YES, GOOD-BY TST (R5)+ ; R5 = ADDRESS OF DELIMITER POSITION .IFZ OVRLAY JSR PC,@(R3)+ ; PERFORM COMMAND PROCESS - INC. TO SAVE WORD .ENDC .IFNZ OVRLAY MOVB (R3)+,R1 ; SEGMENT NO. TO LOAD MOVB (R3),R2 ; START EXECUTION AT THIS POINT MOV R1,-(SP) ; SET IN STACK MOV R2,-(SP) ; FOR SGLOAD JSR PC,SGLO;PRINT HEX DIGIT LINE MOV #LL,R5 ; JSR PC,PRINT MOV #DIGITP,R1 ;PRINT CHAR LINER UPPER MOV #124.,R5 JSR PC,PRINT RTS PC ;RETURN ; ; SUBROUTINE TO ADD 100. TO LINER UPPER ; A100: JSR R5,ABSCNV ;ADD 100 TO LINER UPPER .WORD DIGITP+120. .WORD WORK1 .WORD 4 ADD #100.,WORK1 JSR R5,BASCNV .WORD WOAN INVALID CODE IS USED, THE TABLE ENTRY WILL POINT TO "EMTERR". MOV (SP)+,R0 ;RESTORE USER'S RTI ;POP SUBRTNE ADDRESS AND OLD STATUS ;TO EFFECT TRANSFER, LEAVING RTN TO ;CALLER ON TOP. EMTA20: CLR R0 ;RANGE ERROR: USE ENTRY 0... BR EMTA10 ;...AND FORCE EXIT VIA "EMTERR" .PAGE EMTERR: RTS PC ;ERROR RETURN USED FOR I * ;* REVISION * ;* * ;*********************************************************************** .DEF ERRTYP,LERTYP .REF PUSHR,POPR,BINASC,TTYOUT ; .CSECT ; ; THE FOLLOWING IS THE FIRST AND LAST DIRECTORY FOR THE ; ERROR TYPE THREAD ; QFIRST: .WORD 0 QLAST: .WORD QFIRST ; IOLUSE: .WORD -1. ; I; 22-NOV-71 ; TIMER TASK MODULE FOR TESTING TIMERS .DEF T.30HD,T.31HD,T.32HD,T.33HD,T.34HD,T.35HD,T.36HD .TITLE TIMTSK SP=%6 EXIT = 4 QTIME = 7 DQTIME = 10 TTYOUT = 13 NN = 20. ;# WORDS RESERVED IN EACH TASK'S STACK T.30PR = 1 T.31PR = 1 T.32PR = 2 T.33PR = 3 T.34PR = 4 T.35PR = 5 T.36PR = 1 T.30IN = 0 T.31IN = 0 T.32IN = 0 T.33IN = 0 T.34IN = 0 T.35IN = 0 T.36IN = 0 TMWRD0: .BYTE 5 ;DRK1 .WORD DIGITP+120. .WORD 4 RTS PC .EVEN HDMES: .ASCII / RECORD / RCT: .BYTE 0,0,0,0 .ASCII /, BYTE COUNT / BCT: .BYTE 0,0,0,0 .ASCII /, DUMPED IN / DTY: .BYTE 0,0,0,0,0,0 RER: .ASCII / / .EVEN EBC: .ASCII /EBCDIC/ ASC: .ASCII /ASCII / .EVEN ACHA: .ASCII /ASCII CHARS/ .EVEN ECHA: .ASCII /EBCDIC CHARS/ .EVEN TRE: .ASCII /, TAPE NVALID CODES EMTABL = . ;TOP OF EMT LINK TABLE .WORD EMTERR ;#0 ALWAYS AN ERROR .WORD QUEUE ;#1 .WORD SUSPND ;#2 .WORD UNSPND ;#3 .WORD EXIT ;#4 .WORD FRETSK ;#5 .WORD ABORT ;#6 .WORD QTIME ;#7 .WORD DQTIME ;#10 .WORD QSKED ;#11 .WORD DQSKED ;#12 AD ; GET SEGMENT AND TRANSFER .ENDC ; ; RETURN FROM OPERATOR COMMAND PROCESSORS HERE ; OPCOMR = . TST R5 ; DID AN ERROR OCCUR BNE IPTB00 ; NO-SEND READY FOR ANOTHER REQUEST MOV #ER2MSG,DATADR ; TYPE "ILL PAR!" BR IPTB21 ; ; ;*********************************************************************** ;* * ;* RESET LOGICAL DEELAY COUNT .BYTE 0 ;RESET TIME TMWRD1: .BYTE 10. ;DELAY COUNT .BYTE 0 ;RESET TIME TMWRD2: .BYTE 15. ;DELAY COUNT .BYTE 0 ;RESET TIME TMWRD3: .BYTE 5 ;DELAY COUNT .BYTE 5 ;RESET TIME TMWRD4: .BYTE 10. ;DELAY COUNT .BYTE 10. ;RESET TIME TMWRD5: .BYTE 15. ;DELAY COUNT .BYTE 15. ;RESET TIME TMWRD6: .BYTE 0 ;DELAY COUNT .BYTE 0 ;RESETREAD ERROR/ NTRE: .ASCII / / .EVEN DIGITP: .ASCII / .1 .5 .10 .15 .20 .25 .30/ .ASCII / .35 .40 .45 .50 .55 .60 .65 .70 .75 .80 / .ASCII /.85 .90 .95 .0100/ .EVEN HEXZ: .ASCII /HEX ZONES / .=.+112. .EVEN HEXD: .ASCII /HEX DIGIT / .=.+112. .EVEN EOFM: .ASCII /END-OF-FILE/ .EVEN SCRBUF: .=.+132. .EVEN PR .WORD TTYOUT ;#13 .WORD TTYIN ;#14 .WORD EMTERR ;#15 CURRENTLY UNUSED .WORD BINASC ;#16 .WORD ASCBIN ;#17 .WORD MASK ;#20 .WORD UNMASK ;#21 .WORD ERRTYP ;#22 .IFNZ NDISCS .WORD DISCIO ;#23 .ENDC NDISCS MAXEMT = .-EMTABL/2 .END VICE AVAILABLE IN ROS PHYSICAL DEVICE TABLE. * ;* TO BE FUTHER DOCUMENTED AFTER ROS 1 DEMO. * ;* * ;*********************************************************************** .DEF RESET .REF LOGMAX,PHYDEV,CVTBIN ; ; COMMA = 54 ; ASCII COMMA ; RESET = . CMPB (R5)+,#COMMA ; DELIMITER A COMMA? BNE RESERR ; NO-ERROR TIME .PAGE T.30HD: .WORD 1 ;THREAD WORD .WORD T.30BG ;TASK ENTRY .WORD T.30IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.30PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT .BYTE 0 ;STATUS .BYTE 30. ;TASK # .WORD 0 TBUF = . .=.+132. .EVEN MAGBUF: .BLKB 20000. ; ***** SPECIAL BUFFER XFER .END TAPDUM ; ******************************************************************** ; * * ; * PROGRAM IDENTIFICATION: "SETGET" * ; * SET TIME SET DATE GET TIME GET DATE * ; * * ; * ROUTINES TO SET AND GET CURRENT TIME AND DATE * ; * TST R4 ; PARAM. MUST BE 1-3 CHARS. BEQ RESERR CMP R4,#3. BHI RESERR JSR PC,CVTBIN ; CONVERT TO BINARY INTEGER TST R5 BEQ RESERR ; CONVERSION ERROR CMP R4,LOGMAX ; VALID LOGICAL DEVICE? BGT RESERR ; NO-ERROR ASL R4 ; LOGICAL UNIT WORD INDEX BIC #120000,PHYDEV(R4) ; SET DEVICE AVAILABLE AND ; ;STACK SAVE .=NN*2+. T.31HD: .WORD 1 ;THREAD WORD .WORD T.31BG ;TASK ENTRY .WORD T.31IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.31PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT .BYTE 0 ;STATUS .BYTE 31. ;TASK # TDERR ; YES-ERROR MOV R4,-(SP) ; NO-SAVE ON STACK FOR STIME/SDATE ADD #3.,R5 ; BUMP TO NEXT TWO CHARACTER NUMBER DEC R0 ; FINISHED? BNE CVT210 ; NO JMP (R1) ; YES ; ; ERROR RETURN TO INPUT ; TDERR = . CLR R5 ; SET ERROR INDICATOR MOV SAVSTK,SP ; RESTORE STACK INCASE ERROR OCCURED ; * ; * USAGE: * ; * USED BY GENERAL ROUTINES TO FETCH CURRENT TIME * ; * AND/OR DATE. USED BY OPERATOR INPUT PROGRAM TO SET * ; * TIME AND/OR DATE FROM TTY KEYBOARD. * ; * * ; * CALLING SEQUENCES: * ; * MOV NEWHR,-(SP) ;PUSH NEW HOUR ; ALTERNATE DEVICE NOT IN USE RTS PC ; RETURN TO INPUT ; ; ERROR OCCURED ; RESERR = . CLR R5 ; SET ERROR GUY RTS PC ; RETURN ; .END .WORD 0 ;STACK SAVE .=NN*2+. T.32HD: .WORD 1 ;THREAD WORD .WORD T.32BG ;TASK ENTRY .WORD T.32IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.32PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT .BYTE 0 ;STATUS .BYTE 32. ; WHILE IN CVT2CH RTS PC ; RETURN ; TIME = . MOV SP,SAVSTK ; SAVE STACK POINTER INCASE ERROR RETURN CMPB (R5)+,#COMMA ; DELIMITER POSITION A COMMA? BNE TIMB00 ; NO- TYPE TIME-OF-DAY CMP R4,#TPARLN ; CORRECT NO. OF CHRACTERS TO SET TIME? BNE TDERR ; NO-ERROR MOV #2.,R0 ; GO THRU CONVERT LOOP TWICE JSR PC,CVT2CH ; CONVERT * ; * MOV NEWMIN,-(SP) ;PUSH NEW MINUTE * ; * JSR PC,STIME ;CALL "SET TIME" * ; * TST (SP)+ ;POP ERROR WORD * ; * BNE ERROR ;CALL PARAMETERS IN ERROR * ; * ---------------- * ; * MOV NEWMTH,-(SP) ;PUSH NEW MONTH * ; * MOV NEWDAY,-(SP) ;PUSH NEW /O LIST IN USE SWITCH-NO OF REQUESTS ; ; THE FOLLOWING TABLE IS THE I/O LIST FOR THE ; ERROR MESSAGE TYPE-OUT. ; IOLIST = . .WORD 1 ; THREAD WORD .BYTE SYSTTY ; LOGICAL DEVICE-SYSTEM TTY .BYTE 3 ; EXIT TYPE 3 .WORD TTYNXT ; I/O COMPLETE SUBROUTINE .BYTE 0 ; DON'T QUEUE ERROR TASK .BYTE 1 ; USE PRIORITY TYPE-OUT QUEUE .WORD 0,0 ;TASK # .WORD 0 ;STACK SAVE .=NN*2+. .PAGE T.33HD: .WORD 1 ;THREAD WORD .WORD T.33BG ;TASK ENTRY .WORD T.33IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.33PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT .BYTE 0 ;STATUS TO BINARY AND SET ON STACK JSR PC,STIME ; SET TIME OF DAY IN ROS TIMA10: TST (SP)+ ; ERROR OCCUR? BNE TDERR ; YES-ERROR RTS PC ; NO-RETURN TO INPUT ; ; NO DELIMITER-ASSUME TYPE TIME REQUESTED ; TIMB00 = . MOV #GTIME,R0 ; ADDRESS OF GET TIME SUBROUTINE MOV #TIMEDT,R1 ; ADDRESS OF TIME EDIT TABLE MOV #TIMMSG,R2 ; ADDRESS OF TIME MESSAGE JMDAY * ; * MOV NEWYR,-(SP) ;PUSH NEW YEAR * ; * JSR PC,SDATE ;CALL "SET DATE" * ; * TST (SP)+ ;POP ERROR WORD * ; * BNE ERROR ;CALL PARAMETERS IN ERROR * ; * ---------------- * ; * JSR PC,GDATE ;CALL "GET DATE" * ; * MOV (SP)+,CURYR ;P ; TWO SYSTEM USE WORDS .WORD TYPBUF ; ADDRESS OF OUTPUT BUFFER ; ; THE FOLLOWING IS THE MESSAGE STRING USED BY TTYOUT ; TYPBUF = . .WORD 41. ; NO. OF CHARACTERS TO OUTPUT .WORD 0 ; USED BY TTYOUT .BYTE 15 ; START OFF WITH CR/LF .ASCII /ERROR/ EDIT1: .ASCII / XXXXX/ .BYTE 15 EDIT2: .ASCII /SXXXXX/ ; ARG 1 .BYTE 15 EDIT3: .ASCII /SXXXXX/ ; .BYTE 33. ;TASK # .WORD 0 ;STACK SAVE .=NN*2+. T.34HD: .WORD 1 ;THREAD WORD .WORD T.34BG ;TASK ENTRY .WORD T.34IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.34PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT .BYTE 0 P TYPTOD ; TYPE TIME-OF-DAY ; DATE = . MOV SP,SAVSTK ; SAVE STACK POINTER INCASE ERROR RETURN CMPB (R5)+,#COMMA ; DELIMITER POSITION A COMMA? BNE DATB00 ; NO-TYPE DATE CMP R4,#DPARLN ; CORRECT NO. OF CHARACTERS TO SET DATE BNE TDERR ; NO-ERROR MOV #3.,R0 ; GO THRU CONVERT LOOP THREE TIMES JSR PC,CVT2CH ; CONVERT TO BINARY AND SET ON STAOP CURRENT YEAR (-1900) * ; * MOV (SP)+,CURDAY ;POP CURRENT DATE * ; * MOV (SP)+,CURMTH ;POP CURRENT MONTH * ; * ---------------- * ; * JSR PC,GTIME ;CALL "GET TIME" * ; * MOV (SP)+,CURHR ;POP CURRENT HOUR * ; * MOV (SP)+,CURMIN ;POP CURRENT MINUTE * ; * MOV (SP)+,CURS ARG 2 .BYTE 15 EDIT4: .ASCII /SXXXXX/ ; ARG 3 .BYTE 15 EDIT5: .ASCII /SXXXXX/ ; ARG 4 .BYTE 15 .EVEN ; ; THE FOLLOWING EDIT TABLE IS USED TO POINT TO 6 BYTE ASCII ; STRINGS IN THE MESSAGE INTO WHICH BINASC WILL PUT THE ; CONVERTED RESULTS. ; EDITBL = . .WORD EDIT1 ; POINTER FOR ERROR NUMBER .WORD EDIT2 ; FPOINTER FOR FIRST ARGUMENT .WORD EDIT3 ; POINT ;STATUS .BYTE 34. ;TASK # .WORD 0 ;STACK SAVE .=NN*2+. T.35HD: .WORD 1 ;THREAD WORD .WORD T.35BG ;TASK ENTRY .WORD T.35IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.35PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARGUMENT ; ******************************************************************** ; * MODULE IDENTIFICATION: T I M E R S * ; * .TITLE TIMERS * ; ******************************************************************** ; ******************************************************************** ; * Q T I M E * ; * PROGRAM IDENTIFICATION: "QTIME" EC ;POP CURRENT SECOND * ; * * ; * PROGRAMMER: 52 * ; * DATE: 12-DEC-71 * ; * VERSION:001.004 * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; **********************ER FOR SECOND ARGUMENT .WORD EDIT4 ; POINTER FOR THIRD ARGUMENT .WORD EDIT5 ; POINTER FOR FOURTH ARGUMENT .WORD 0 ; END OF TABLE ; ; EXITSW: .WORD 0 ; EXIT SWITCH. 0=SUBROUTINE EXIT ; ; 1=I/O COMPLETE SUB EXIT ; ; EQUATES FOR ERRTYP ; SPACE = 40 ; ASCII SPACE ; ; THE FOLLOWING EQUATES ARE FOR THE ERROR MODULE ; THREAD = 0. .BYTE 0 ;STATUS .BYTE 35. ;TASK # .WORD 0 ;STACK SAVE .=NN*2+. T.36HD: .WORD 1 ;THREAD WORD .WORD T.36BG ;TASK ENTRY .WORD T.36IN ;TASK INIT .WORD 0 ;MAX XEQ TIME .BYTE NN ;STACK SIZE .BYTE T.36PR ;TASK PRIORTY .WORD 0 ;TASK TIMER .WORD 0 ;ARG * ; * TIMER MODULE QUEUEING SUBROUTINE * ; * * ; * PURPOSE: LOADS TIMER MODULES ONTO "WAIT" STACK FOR "TIMER" * ; * "TMNSRT" IS RESPONSIBLE FOR UNLOADING FROM THE STACK * ; * AND STRINGING ONTO PROPER THREAD * ; * * ; * USAGE: CALLED BY ANY ROUTINE WISHING TO ACTIVAT********************************************** .TITLE SETGET .DEF STIME,SDATE,GTIME,GDATE .REF MONTH,MDAY,YEAR,JDATE,SECOND,MINUTE,HOUR .REF TICTOC,DAYTAB,PUSHR,POPR,MXDAYS,JANARY,FEBARY .REF THDTAB,CURTHD .PAGE STIME: ;SUBROUTINE TO SET NEW TIME MOV R0,-(SP) ;SAVE USER'S MOV 4(SP),R0 ;PULL NEW MINUTE OFF STACK MOV PS,4(SP) ;REPLACE WITH CURRENT ST ; THREAD WORD ERRNUM = 2. ; ERROR NUMBER ARGM1 = 4. ; ARGUMENT 1 ARGM2 = 6. ; ARGUMENT 2 ARGM3 = 8. ; ARGUMENT 3 ARGM4 = 10. ; ARGUMENT 4 ; ; PLOCK = 340 ; PRIORITY LOCK-OUT MASK FOR PSR PSR = 177776 ; ADDRESS OF PROCESSOR STATUS REGISTER ; TEMP: .WORD 0 ; TEMPORARY SAVE AREA FOR LERTYP ; ; LERTYP IS CALLED TO TYPE AN ERRUMENT .BYTE 0 ;STATUS .BYTE 36. ;TASK # .WORD 0 ;STACK SAVE .=NN*2+. .PAGE T.30BG: ;TASK #30 BEGIN MOV #MODUL0,-(SP) MOV TMWRD0,-(SP) EMT QTIME ;QUEUE ONE TIMER MODULE TST (SP)+ MOV #LIST30,-(SP) EMT TTYOUT ;TYPE TASK I.D. EMT EXIT T.31BG: ;TASK #31 E A TIMER * ; * MODULE. CALLING SEQUENCE: * ; * MOV #MODULE,-(SP) ;STACK MODULE'S ADDRESS * ; * MOV TIME,-(SP) ;STACK TIMER-RESET WORD * ; * EMT QTIME ;REQUEST TO QUEUE MODULE * ; * OR * ; * JSR PC,QTIME * ; * TST (SP)+ ;TEST ERATUS FOR RTI USE CMP R0,#60. ;SEE IF MINUTE WITHIN RANGE BHIS STIM10 ;NO: EXIT IN ERROR CMP 6(SP),#24. ;SEE IF NEW HOUR WITHIN RANGE BLO STIM20 ;YES: PROCEED STIM10: ;ROUTINE EXIT POINT: FOR GOOD AND BAD MOV (SP)+,R0 ;RESTORE USER'S RTI ;RETURN AND RESTORE OLD CPU STATUS STIM20: ;HERE WHEN PARAMTERS ARE WITHIN RANGE OR MESSAGE UNDER LOCKOUT. ; MOV PSR,-(SP) ; MOV MADDR,-(SP) ; JSR PC,LERTYP ; ; LOCKOUT WILL BE RELEASED UPON THREADING THE ERROR MODULE ; LERTYP = . MOV 2.(SP),TEMP ; SAVE MODULE ADDRESS UNDER LOCKOUT MOV (SP)+,(SP) ; FOR PROPER RETURN JSR R5,PUSHR ; SAVE ALL REGISTERS MOV 14.(SP),-(SP) ; PUT PSR ON STACK SOMOV #LIST31,-(SP) EMT TTYOUT MOV #MODUL2,-(SP) MOV TMWRD1,-(SP) EMT QTIME TST (SP)+ MOV #LIST31,-(SP) EMT TTYOUT EMT EXIT T.32BG: ;TASK #32 MOV #MODUL3,-(SP) MOV TMWRD0,-(SP) EMT QTIME TST (SP)+ MOV #MODUL4,-(SP) MOV TMWRD1,-(SP) EMT QTIME TST (SP)+ MOV #MODUL5,ROR RETURN CODE * ; * * ; * THE MODULE MUST BE SET UP, PRIOR TO THE CALL, AS DESCRIBED * ; * IN THE ROS USER'S MANUAL. NOTE THAT CALLS FOR MODULES HAVING * ; * THE "S" SUSPEND OPTION SET WILL CAUSE TRANSFER TO THE * ; * DISPATCHER, AND WILL NOT RETURN UNLESS THE CALL IS IN ERROR. * ; * ON THESE CALLS THE MODULE'S TASK NUMBER IS AUTOMATICALLY SET * ; * TO THE CURRENTLY ACTIVE TASK'S N MOV #340,PS ;LOCK OUT INTERFERENCE FROM CLOCK MOVB R0,MINUTE ;UPDATE CURRENT MINUTE MOVB 6(SP),HOUR ;UPDATE CURRENT HOUR MOV #1,TICTOC ;RESET [TICS] AND [SECOND] COUNTERS CLR 6(SP) ;CLEAR ERROR CODE BR STIM10 ;GO EXIT .PAGE SDATE: ;SUBROUTINE TO UPDATE CURRENT MONTH,DAY, AND YEAR JSR R5,PUSHR ;SAVE ALL REGISTERS MOV SP,R0 COMPATIBLE MOV TEMP,R5 ; ADDRESS OF MODULE BR ERRA05 ; DO IT ; ERRTYP = . JSR R5,PUSHR ; SAVE ALL REGISTERS MOV 14.(SP),R5 ; GET MODULE ADDRESS MOV PSR,-(SP) ; SAVE PROCESSOR PRIORITY ON STACK MOV #PLOCK,PSR ; SET PRIORITY LOCKOUT ERRA05: DEC (R5) ; IS MODULE THREADABLE BNE ERRA30 ; NO - BUMP BACK AND RETURN TO CALLER MOV R5,@-(SP) MOV TMWRD2,-(SP) EMT QTIME TST (SP)+ MOV #LIST32,-(SP) EMT TTYOUT EMT EXIT .PAGE T.33BG: ;TASK #33 MOV T.33HD+14,T.33AR ;TRANSFER ARGUMENT MOV #LIST33,-(SP) EMT TTYOUT EMT EXIT T.34BG: ;TASK #34 MOV T.34HD+14,T.34AR ;TRANSFER ARGUMENT MOV #LIST34,-(SP) EMT TTYOUT EMT EXIT T.35UMBER. * ; * IF THE "WAIT" STACK IS FULL, "QTIME" WILL EXIT WITH THE ERROR * ; * CODE WORD ON THE STACK NON-ZERO. THE MODULE WILL NOT BE QUEUED* ; * "QTIME" TAKES ITS ERROR EXIT IF THE REQUESTED MODULE IS ALREADY* ; * IN EITHER A TIMER THREAD OR THE "WAIT" STACK, AND HAS NOT BEEN * ; * FLAGGED FOR DE-QUEUEING. GOOD RETURNS ARE MADE WHEN THE MODULE* ; * IS FOUND INACTIVE OR MARKED FOR DE-QUEUEING IN THE "WAIT" STACK* ; * IN THIS LAST CASE, THE M ;UTILIZE AS SECONDARY STACK POINTER ADD #16,R0 ;POINT TO NEW "YEAR" ON STACK MOV (R0)+,R1 ;REMOVE YEAR MOV (R0)+,R2 ;AND NEW DAY MOV (R0),R3 ;GET MONTH FROM STACK MOV PS,-(R0) ;LOAD CURRENT PSW ON STACK FOR RTI USE MOV -4(R0),-(R0) ;AND MOVE RTN ADDR INTO PROPER PLACE,TOO CMP R3,#12. ;SEE IF MONTH IS WITHIN RANGE BHI SDAT30 ;ERROR: EXIT QLAST ; THREAD REQUEST MOV R5,QLAST ; VIA QLAST INC IOLUSE ; BUMP NO. OF REQUESTS BEQ ERRB00 ; FIRST ONE - LET'S DO IT ERRA10: MOV (SP)+,PSR ; RESTORE CPU PRIORITY ERRA20: JSR R5,POPR ; RESTORE REGISTERS MOV (SP)+,(SP) ; SET STACK UP FOR VALID RETURN RTS PC ; RETURN TO CALLER ; ; CAN'T THREAD ERROR MODULE ; ERRA30 = . INC (R5) ;BG: ;TASK #35 MOV T.35HD+14,T.35AR ;TRANSFER ARGUMENT MOV #LIST35,-(SP) EMT TTYOUT EMT EXIT T.36BG: MOV #MODUL0,-(SP) EMT DQTIME TST (SP)+ MOV #MODUL1,-(SP) EMT DQTIME TST (SP)+ MOV #MODUL2,-(SP) EMT DQTIME TST (SP)+ MOV #MODUL3,-(SP) EMT DQTIME TST (SP)+ MOV #MODULARK FOR DE-QUEUEING WILL BE REMOVED, * ; * AND THE MODULE WILL REMAIN WHERE IT IS ON THE "WAIT" STACK. * ; * * ; * PROGRAMMER: 52 * ; * VERSION:003.002 * ; * DATE: 12-DEC-71 * ; * * ; * G U L F MOVB #28.,FEBARY ;RESET FEBRUARY IN PREP FOR NEW YEAR MOV #365.,MXDAYS ;RESET MAX DAYS COUNT BIT #3,R1 ;IS NEW YEAR A LEAP? BNE SDAT40 ;NO: NO EXTRA DAY INCB FEBARY ;YES: ADD FEB 29 INC MXDAYS ;EXTRA DAY IN LEAP YEAR SDAT40: CMPB R2,DAYTAB(R3) ;CHECK DATE FOR PROPER RANGE THIS MONTH BLO SDAT50 ;O.K.: WITHIN RANGE MOVB DAYTAB(R3),R2 ;ERROR: USE SET BACK THREAD WORD BR ERRA10 ; RETURN ; ; FIRST REQUEST - START MESSAGE ; ERRB00 = . CLR EXITSW ; CLEAR EXIT SWITCH FOR GOOD RETURN ERRB10: MOV QFIRST,R5 ; GET NEXT REQUEST BEQ ERRB30 ; NO REQUESTS LEFT MOV (R5)+,QFIRST ; PULL THREAD, RELINK, R5=ADDR. ERRNUM BNE ERRB15 MOV #QFIRST,QLAST ; PULLED LAST REQUEST-RESET QLAST ERRB15: MOV (SP)+,PSR ; RESTORE CPU4,-(SP) EMT DQTIME TST (SP)+ MOV #LIST36,-(SP) EMT TTYOUT EMT EXIT .PAGE LIST30: .WORD 1 ;THREAD WORD .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.30 E L E C T R O N I C S Y S T E M S * ; * * ; ******************************************************************** .DEF QTIME .DEF TIMER .DEF TWAITB,TTBPTR,TFIRST,TLAST,RESTAB,CURTAB,TIMBSY,BASCNT .REF UNSPND,QUEUE .REF $CTASK,$PRIOR,SUSPND .REF PUSHR,POPR,RESTOR .PAGE QTIME: ;ROUTINE TO PUT TIMER MODULE IN "WAIT" STACK LAST DAY RATHER THAN ERR OUT SDAT50: MOV R3,-(SP) ;SAVE MONTH ON STACK FOR USE BELOW MOV #JANARY,R0 ;PREPARE TO CALC JULIAN DAY CLR R4 ;WILL ACCUM TOTAL DAYS SDAT10: DEC R3 ;COUNT DOWN MONTHS BLE SDAT20 ;DONE: EXIT LOOP MOVB (R0)+,R5 ;CAN'T ADD BYTES ADD R5,R4 ;ACCUM DAYS FROM DAY TABLE BR SDAT10 ;LOOP BACK FOR MORE .PAGE SDAT20: AD PRIORITY MOV #EDITBL,R4 ; ADDRESS OF MESSAGE EDIT TABLE ERRB20: MOV (R5)+,-(SP) ; INTEGER TO STACK AND BUMP POINTER MOV (R4)+,-(SP) ; EDIT STRING ADDRESS TO STACK JSR PC,BINASC ; CONVERT INTEGER TO ASCII BYTE STRING TST (R4) ; BUMP EDIT POINTER BNE ERRB20 ; NO - AGAIN MOVB #SPACE,EDIT1 ; WIPE OUT SIGN IN ERRNUM; SUB #12.,R5 ; R5 = THREAD WORD ADDRESS BF ;MSG BUFFER T.30BF: .WORD MSG30X-T.30BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #30 ARG=" T.30AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;CR MSG30X = .-1 .EVEN .PAGE LIST31: .WORD 1 ;THREAD WORD .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT MOV PS,-(SP) ;SAVE USER'S PS MOV #340,PS ;RAISE CPU LEVEL TO PROTECT ROUTINE MOV R0,-(SP) ;SAVE USER'S CMP TTBPTR,#TMTBND ;SEE IF STACK IS FULL BHI QTIM50 ;YES: ERROR EXIT MOV 10(SP),R0 ;ADDRESS OF MODULE DEC (R0) ;IS TIMER MODULE INACTIVE? (T/W=0?) BNE QTIM30 ;NO: SEE IF ACTIVE OR IN "WAIT" STATE QTIM20: ;HERE WHEN CLEAREDD R2,R4 ;ADD TODAY'S DATE MOV #JDATE,R3 ;WILL USE AS POINTER TO DATE BYTES MOV #340,PS ;LOCK OUT INTERFERENCE FROM CLOCK MOV R4,(R3)+ ;LOAD JULIAN DATE MOV (SP)+,(R3) ;LOAD NEW MONTH MOV #THDTAB,CURTHD ;INIT CURRENT THREAD POINTER BITB #1,(R3)+ ;IS MONTH ODD OR EVEN? BNE SDAT25 ;ODD: LEAVE AT THREAD #1 ADD #2,CURTHD ;EVEN: ADVANCE TO THREMOV #1.,(R5) ; SET THREADABLE MOV #IOLIST,-(SP) ; I/O LIST ADDRESS ON STACK FOR TTYOUT JSR PC,TTYOUT ; TYPE ERROR MESSAGE ERRB25: TST EXITSW ; CALLED FROM I/O COMPLETE? BEQ ERRA20 ; NO - RETURN TO CALLER RTS PC ; YES-RETURN TO TTYOUT ; ; I/O COMPLETE SUBROUTINE FROM TTYOUT - EXIT TYPE 3 ; TTYNXT = . INC EXITSW ; SET EXIT SWITCH FROM I/O COMPLETE MOV .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.31BF ;MSG BUFFER T.31BF: .WORD MSG31X-T.31BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #31 ARG=" T.31AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;CR MSG31X = .-1 .EVEN LIST32: .WORD 1 ;THREAD WORD TO STACK UP MODULE ADD #2,TTBPTR ;PUSH "WAIT" STACK POINTER MOV R0,@TTBPTR ;ENTER MODULE ADDRESS INTO "WAIT" STACK BIS #C1CBIT,C1COMD ;START UP CLOCK IF IT WAS OFF TST 2(R0) ;CHECK OPTION FLAG FOR "SUSPEND" BMI QTIM60 ;"SUSPEND" SELECTED QTIM40: ;THIS IS THE "SUCCESSFUL" EXIT CLR 10(SP) ;PREPARE ERROR RETURN CODE TO SHOW O.K. QTIM45: ;HERE WHEN EXITIAD #2 SDAT25: MOVB R2,(R3)+ ;LOAD DAY OF MONTH MOVB R1,(R3) ;LOAD CURRENT YEAR CLR 22(SP) ;CLEAR ERROR WORD FOR GOOD RETURN SDAT30: JSR R5,POPR ;RESTORE ALL REGISTERS TST (SP)+ ;POP THIRD ARGUMENT SINCE RTI NEEDS TWO RTI ;STACK SET TO RETURN AND RESTORE .PAGE ; NOTE: SUBROUTINES "GTIME" AND "GDATE" SHARE THE SAME CODE. ; THE CARRY BIT IS USED AS A SWITCH TO DE; UPDATE 12/11/71 IPL.S08 ; UPDATE 12/10/71 IPL.S07 ; UPDATE 12/2/71 IPL.S06 ; UPDATE 11/18/71 IPL.S05 ; UPDATE 11/15/71 IPL.S04 ; UPDATE 11/12/71 IPL.S03 ; UPDATE 11/11/71 IPL.S02 ; UPDATE 11/10/71 IPL.S01 .TITLE IPL ;*********************************************************************** ;* * ;* .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.32BF ;MSG BUFFER .PAGE T.32BF: .WORD MSG32X-T.32BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #32 ARG=" T.32AR: .ASCII " " PSR,-(SP) ; SAVE PROCESSOR PRIORITY MOV #PLOCK,PSR ; SET CPU LOCKOUT LEVEL 7 BR ERRB10 ; SEE IF ANY OTHER REQUESTS AND ; ; PROCESS THEM ACCORDINGLY ; ERRB30: MOV #-1.,IOLUSE ; RESET I/O LIST IN USE SWITCH MOV (SP)+,PSR ; RESTORE CPU PRIORITY RTS PC ; RETURN TO TTYOUT .END TERMINE WHETHER TO LOAD TIME ; OR DATE. BY USING THE PSW TO STORE THIS SWTICH, AND BY RUNNING THE ; ROUTINE UNDER LOCKOUT AFTER THE CARRY BIT IS SET/CLEARED, RE-ENTRANCY ; IS MAINTAINED, AND THE POSSIBILITY OF CLOCK ALIASING IS ELIMINATED. GDATE: ;SUBROUTINE TO GET DATE CLC ;MARK TO GET DATE (BELOW) BR GETSB1 ;SHARE ROUTINE GTIME: ;SUBROUTINE TO GET TIME SEC ;MARK TO GET TIME (BELOW) GETSB1 INITIAL PROGRAM LOAD WILL INITIALIZE THE ROS SYSTEM AND * ;* THEN EXIT TO DISPATCH. THIS MODULE SHOULD BE EXECUTED * ;* BEFORE ENTERING ROS FOR THE FIRST TIME. * ;* * ;* PROGRAMMER 51,52,53 AND 54 * ;* DATE 11/9/71 * ;* REVISION ;* REVISION ;TRANSMITTED ARG .BYTE 15 ;CR MSG32X = .-1 .EVEN LIST33: .WORD 1 ;THREAD WORD .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.33BF ;MSG BUFFER T.33BF: NG TO "SUSPEND". AVOID CLEARING 10(SP) MOV 6(SP),4(R0) ;LOAD NEW TIMER/RESET WORD INTO MODULE ; THIS SERVES AS NORMAL INIT FOR TIMER MODULE, AND ALSO RESETS ; THE "RESET" BYTE IN CASE MODULE IS BEING RE-QUEUED AFTER BEING ; DE-QUEUED, ALL WHILE REMAINING IN "WAIT" STACK. QTIM50: ;HERE WHEN EXIT IS TO LEAVE NON-ZERO ERROR CODE ON STACK DEC (R0) ;SET T/W=-1 TO SHOW IN "WAIT" STATE... ;...OR TO RESTORE MODULE'S T/W IF IT IS FOUND ALRE: ;COMMON ENTRY TO "GET" ROUTINE MOV PS,-(SP) ;SAVE CURRENT PSW MOV #340,PS ;LOCK OUT INTERFERENCE FROM CLOCK SUB #12,SP ;NEED FIVE STACK CELLS MOV R0,(SP)+ ;SAVE USER'S SO WE CAN USE IT MOV R1,(SP)+ ;ALSO TST (SP)+ ;PREPARE FOR MOVING PS AND PC MOV SP,R0 ;USE AS SECOND STACK POINTER CMP (R0)+,(R0)+ ;ZIP UP TO POI * ;* * ;*********************************************************************** .DEF IPL,SSTACK,LOGMAX,PHYDEV,ALTDEV .DEF QTIME,DQTIME,IDTASK,SSTACK .REF EMTRAP,TIMER,CLINIT .REF RQUEST,SAVE,DSPTCH,QIPL,TPRTY,HEADER,INPTHD .REF PFSIPL,PSTIPL .REF TSTAT,LARRY,DINT .REF PRTINT,KBDINT ;TTYIO PRINTER AND KEYBOARD .WORD MSG33X-T.33BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #33 ARG=" T.33AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;CR MSG33X = .-1 .EVEN .PAGE LIST34: .WORD 1 ;THREAD WORD .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNEADY ACTIVE... ; ...OR ALREADY IN "WAIT" STATE MOV (SP)+,R0 ;RESTORE USER'S MOV (SP)+,2(SP) ;MOVE OLD [PS] IN PREP FOR RTI RTI ;ZAP! RETURN TO USER OR GO TO SUSPEND ;ON OLD CPU LEVEL QTIM30: ADD #2,(R0) ;NOT INACTIVE. SEE IF ACTIVE OR "WAIT" BNE QTIM50 ;ACTIVE: TAKE ERROR EXIT CMPB 5(R0),#-1 ;IN "WAIT": IS IT FLAGGED FOR DE-QUEUE? NT TO WHERE PS WAS STORED MOV #MONTH,R1 ;INIT POINTER TO CLOCK AREA FOR DATE MOV (R0)+,(SP) ;MOVE PS TO NEW PLACE IN PREP FOR RTI BIT #1,(SP) ;WHILE HERE CHECK CARRY SET @ ENTRY BEQ GETSB2 ;WAS DATE: LEAVE AS IS MOV #SECOND,R1 ;WAS TIME: RE-INIT FOR TIME GETSB2: ;R1 NOW POINTING TO PROPER PARAMTER LIST MOV (R0),-(SP) ;ALSO TRANSFER PC CLR (R0) ;ALL UPPER ;INTERRUPT ROUTINES .REF TTINIT ;TTYIO INITIALIZATION SUBROUTINE ; .CSECT SSTACK = . ; BEGINNING VALUE OF SYSTEM STACK PSR = 177776 ; PROCESSOR STATUS REGISTER EQUATE ; ; INTERRUPT VECTOR EQUATES ; MPSHBT = 244 ; MANUAL PUSHBUTTON MPSHLV = 200 ; BR4 FOR MANUAL PUSHBUTTON SAVTRP = 14 ; SAVE TRAP SAVLEV = 340 ; SAVE UNDER LOC .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.34BF ;MSG BUFFER T.34BF: .WORD MSG34X-T.34BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #34 ARG=" T.34AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;CR MSG34X = .-1 .EVEN .PAGE LIST35: .WORD 1 ;THREAD WORD .BYTE 0 BNE QTIM50 ;NO: ERROR EXIT BR QTIM40 ;YES: LEAVE THERE AND REMOVE D-Q FLAG .PAGE QTIM60: ;HERE WHEN TASK IS TO BE SUSPENDED UNTIL TIMER EXPIRES MOVB $CTASK,2(R0) ;LOAD MODULE TASK # WITH CURRENT TASK MOV 4(SP),10(SP) ;SET CALLER RTN TO LOOK LIKE "JSR" MOV #SUSPND,4(SP) ;SET STACK SO RTI WILL GO TO "SUSPEND" MOVB #5,QTMCNT ;MUST SHIFT FIVE WORDS ON STACK QTIM70: MOV (SP)+,-4(SP) BYTES WILL BE CLEARED... ;...BEFORE DATA LOADED ONTO STACK MOVB (R1)+,(R0) ;LOAD MONTH [OR] SECOND CLR -(R0) ;NEXT STACK CELL MOVB (R1)+,(R0) ;LOAD DAY [OR] MINUTE CLR -(R0) MOVB (R1)+,(R0) ;LOAD YEAR [OR] HOUR CMP -(SP),-(SP) ;MOVE TO POINT AT SAVED REGISTERS MOV (SP)+,R0 ;RESTORE USER'S MOV (SP)+,R1 ;ALSO RTI KOUT ; ; ; PHYSICAL DEVICE TABLE ; LOGMAX: .WORD 4 ;LARGEST VALID LOGICAL DEVICE NO. PHYDEV: .WORD 040000 ; TTY UNIT 3, AVAIL, ALTERNATE AVAIL .WORD 000400 ;DISC UNIT 0, AVAIL, NO ALTERNATE .WORD 100000 .WORD 100000 .WORD 040001 ; TTY UNIT 1, AVAIL., ALTERNATE AVAIL ; ; ; ALTERNATE DEVICE TABLE (PARALLEL TO PHYSICAL DEVICE TABLE) ; ALTDEV: .WORD 4,0,0,0,0 ; ; IPL = . ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.35BF ;MSG BUFFER T.35BF: .WORD MSG35X-T.35BF-4 ;BUFFER LENGTH .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #35 ARG=" T.35AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;SHIFT THE FIVE WORDS ON STACK DOWN ONE ;WORD. CAN FOOL WITH POINTER SINCE UNDER LOCKOUT DECB QTMCNT ;DONE? BNE QTIM70 ;NOT YET CLR -(SP) ;"BOTTOM" OF STACK WILL BE RETURN ERROR ;CODE WHEN SUSPENDED TASK IS UNSUSPENDED SUB #12,SP ;RE-POSITION POINTER AT "TOP" OF STACK BR QTIM45 ;INSTEAD OF RETURNING TO CALLER .PAGE ; ******************************************************************** ; * PROGRAM IDENTIFICATION: "CALENDAR" * ; * DATE & TIME-OF-DAY ROUTINE * ; * * ; * PURPOSE: * ; * --KEEPS 24-HOUR CLOCK AND PERPETUAL CALENDAR UPDATED. * ; * --CALLS THE SCHEDULER ONCE A MINUTE, ON THE MINUTE. RESET ; SEND INIT PULSE TO ALL DEVICES MOV #340,PSR ; SET CPU LEVEL TO 7 DURING IPL MOV #SSTACK,SP ; SET UP SYSTEM STACK ; ; SET UP INTERRUPT AND TRAP VECTORS ; MOV #RQUEST,MPSHBT ; SET UP HANDLER FOR MANUAL PUSHBUTTON MOV #MPSHLV,MPSHBT+2 MOV #SAVE,SAVTRP ; SET UP SAVE TRAP HANDLER MOV #SAVLEV,SAVTRP+2 MOV #EMTRAP,30 ;INIT EMT TRAP VECTOR MOV ;CR MSG35X = .-1 .EVEN LIST36: .WORD 1 ;THREAD WORD .BYTE 0 ;TTY DEVICE # .BYTE 1 ;IMEDIATE RTN .WORD 0 ;NO I/O CMPLT .BYTE 0 ;NO ERR RTNE .BYTE 0 ;NORMAL MSG .WORD , ;SYS RESERVE .WORD T.36BF ;MSG BUFFER T.36BF: .WORD MSG36X-T.36BF-4 ;BUFFER LENGTH ;ZAP! RETURN TO CALLER WITH HIS STATUS ; ...AND THREE PARAMETERS ON STACK. .END ; ******************************************************************** ; * * ; * D Q T I M E * ; * PROGRAM IDENTIFICATION: "DQTIME" * ; * TIMER MODULE DE-QUEUEING SUBROUTINE * ; * * ; * PURPOSE: #340,32 ;LEVEL 7 MOV #TIMER,100 ;INIT CLOCK TO L-F CLOCK INTERRUPT MOV #340,102 .IFGE NTTYS-1 MOV #200,R1 ;INIT INTERRUPT VECTORS FOR MOV #KBDINT,60 ;TTY UNIT 0 MOV R1,62 MOV #PRTINT,64 MOV R1,66 .ENDC .IFGE NTTYS-2 INC R1 ;INIT INTERRUPT VECTORS FOR MOV #KBDINT,340 ;TTY UNIT 1 MOV R1,342 .WORD 0 ;SYSTEM RESERVED .ASCII "TASK #36 ARG=" T.36AR: .ASCII " " ;TRANSMITTED ARG .BYTE 15 ;CR MSG36X = .-1 .EVEN .PAGE MODUL0: .WORD 1 ;THREAD WORD .BYTE 33. ;TASK # .BYTE 3 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG1 ;ARG .WORD FLAG1 ;FLAG ADDR .WORD MASK1 * ; * * ; * USAGE: * ; * TRIGGERED BY TIME-OF-DAY CLOCK INTERRUPT. * ; * IF TIME OR DATE IS ALTERED BY OUTSIDE PROGRAM(S), * ; * CPU MUST BE ON LEVEL 7 TO AVOID INTERFERENCE. * ; * WHEN READING TIME OR DATE, SAME PRECAUTION SHOULD * ; * BE TAKEN. * ; * REMOVES TIMER MODULES FROM TIMER THREADS, IF ACTIVE * ; * AND IF FOUND IN ITS PROPER THREAD. IF ACTIVE BUT NOT * ; * FOUND, ERROR EXIT IS TAKEN. IF STILL IN "WAIT" STACK * ; * IT IS MARKED FOR REMOVAL WHEN "TMNSRT" IS RUN. * ; * IF MODULE IS ALREADY INACTIVE, NO ACTION TAKEN, AND * ; * GOOD EXIT IS TAKEN. * ; * MOV #PRTINT,344 MOV R1,346 .ENDC .IFG NTTYS-2 XXXXXX ;CREATE ASSY ERROR IF NTTYS .GT. 2 .ENDC .IFNZ NDISCS MOV #DINT,204 ; SET UP FOR DISC 0 MOV #240,206 ; AT INTERRUPT LEVEL 5 .ENDC ; ; XFER TO OTHER INITIALIZATION SUBROUTINES ; JSR PC,TTINIT ;INITIALIZE TTYIO TABLES JSR PC,QIPL ; INITIALIZE QUEUE TABLES ;FLAG MASK .WORD JSRTNE ;JSR TARGET MODUL1: .WORD 1 ;THREAD WORD .BYTE 34. ;TASK # .BYTE 43 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG2 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL2: .WORD 1 ;THREAD WORD .BYTE 2 * ; * PROGRAMMER: 52 * ; * VERSION:003.005 * ; * DATE: 12-DEC-71 * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; ******************************************************************** SAVE = 3 ;OP-CODE FOR CAL * ; * USAGE: CALLED BY ANY ROUTINE WISHING TO DE-ACTIVATE A TIMER * ; * MODULE. CALLING SEQUENCE: * ; * * ; * MOV #MODULE,-(SP) ;STACK MODULE'S ADDRESS * ; * EMT DQTIME ;REQUEST TO DE-QUEUE MODULE * ; * OR * ; * JSR PC,DQTIME ;DIRECT JSR PC,IDTASK ; INITIALIZE DUMMY TASKS JSR PC,CLINIT ;INIT FOR CLOCK ROUTINES JSR PC,PFSIPL ; POWER FAIL INIT. JSR PC,PSTIPL ; TRAP INIT. JSR PC,LARRY ; ; SET UP INPUT IN TASK TABLE ; MOV #1,R1 ; SET UP FOR TASK NO. ONE MOVB #NPRIOR-1,TPRTY(R1) ; SET PRIORITY OF INPUT CLRB TSTAT(R1) ; SET QUIESCENT ASL R1 ; TASK WORD INDEX ;TASK # .BYTE 243 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG1 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL3: .WORD 1 ;THREAD WORD .BYTE 33. ;TASK # .BYTE 3 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG2 ;ARG L TO [SAVE] SUBROUTINE STRTWD = 4 ;INDEX TO MODULE TIME& DATE WORD DELTA = 6 ;INDEX TO MODULE INCREMENT WORD .DEF CALEND .DEF QSKED,DQSKED,COUNTR .DEF DAYTAB,CLOCK,TICTOC,SECOND,MINUTE,HOUR .DEF JDATE,MDAY,MONTH,YEAR,MXDAYS,JANARY,FEBARY .DEF SWAITB,STBPTR,THDTAB,CURTHD,ABMPLR,SKDBSY .REF PUSHR,POPR,PPTAB,ABORT .REF QUEUE,FIRST,LAST,$PRIOR,RESTOR,$CTASK .TITLE CALE CALL WITH PROPER LINK * ; * TST (SP)+ ;POP ERROR RETURN CODE * ; * * ; * NOTE THAT THE THREE ROUTINES: [TIMER], [QTIME], AND * ; * [DQTIME] ALLOW AN UNLIMITED NUMBER OF CALLS TO QUEUE * ; * OR DE-QUEUE THE SAME MODULE, REGARDLESS OF ITS STATUS * ; * AT ANY GIVEN TIME. THE STATE UPON THE RETURN FROM A * ; * CALL TO [QTIME] OR [DQTI MOV #INPTHD,HEADER(R1) ; SET HEADER ADDRESS .IFNZ NDISCS ; .REF FILE ; ; SET UP DISCS FILES FOR TTY ; MOV #20.,R1 MOV #FILE,R2 MOV #20,R3 IPLX50: MOV R1,(R2)+ ; SET UP FILE ID MOV R3,(R2)+ ; SET UP START SECTOR MOV #4,(R2)+ ; P=0,DE5ICE=0,FILE TYPE =4 MOV #FILESZ,(R2)+ ; SET UP LENGTH CLR (R2)+ ; CKSAVE = 0 ADD #F .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL4: .WORD 1 ;THREAD WORD .BYTE 34. ;TASK # .BYTE 3 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG3 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET .PAGE MODUND .PAGE CALENDAR: ;TIME & DATE ROUTINE ;ENTRY FROM TIME-OF-DAY CLOCK INTERRUPT ;ENTERED ON CPU LEVEL 7 .IFNZ $ABMPL ;OPTION FOR "ABORT" MULTIPLIER DEC ABMPLR ;COUNT DOWN THE ABORT MULTIPLIER BGT CALA08 ;NOT YET: DON'T RUN ABORT OR TIME-SLICE MOV #$ABMPL,ABMPLR ;RESET THE ABORT MULTIPLIER .ENDC $ABMPL DEC ME], ASSUMING A ZERO ERROR CODE* ; * ASSURES THAT THE MODULE IS IN THE MOST RECENTLY * ; * REQUESTED STATE. THE ONLY EXCEPTION IS WHEN A CALL TO * ; * [DQTIME] HAS BEEN MADE AFTER THE REQUESTED MODULE HAS * ; * TIMED OUT AND BEGUN EXECUTION. STRICTLY SPEAKING, THE * ; * CALL IN THIS CASE CAME AFTER THE MODULE WAS RUN. * ; * * ; * G U L F E L E ILESZ,R3 ; START SECTOR NEXT FILE INC R1 ; BUMP FILE ID CMP R1,#35. ; FINISHED? BLE IPLX50 ; NO .ENDC CLR R0 CLR R1 CLR R2 CLR R3 CLR R4 CLR R5 JMP DSPTCH ; FINISHED WITH IPL-EXECUTE ROS ; ; ; .END L5: .WORD 1 ;THREAD WORD .BYTE 35. ;TASK # .BYTE 3 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD ARG4 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL6: .WORD 1 ;THREAD WORD .BYTE 2 ;TASK # .BYTE 0 ;OPTIONS .WORD COUNTR ;TIC OFF CURRENT TASK TIMER BGT CALA08 ;STILL SOME LIFE LEFT INC COUNTR ;RESTORE IN CASE WAS ZERO BEQ CALA08 ;IT WAS. WE IGNORE ZEROES AS "OFF" .PAGE .IFNZ $TMSLC ;OPTION FOR TIME SLICING MOV R1,-(SP) ;SAVE USER'S MOV $PRIOR,R1 ;PRIORITY OF TASK INVOLUNTARILY ; SUSPENDED BY INTERRUPT, OR OF MOST RECENTLY RUN TASK. TSTB PPTAB(R1) ;CHECK FOR TC T R O N I C S Y S T E M S * ; * * ; ******************************************************************** .DEF DQTIME .PAGE DQTIME: ;SYSTEM SUBROUTINE TO DE-QUEUE A TIMER MODULE MOV (SP),-(SP) ;MOVE RTN ADDR IN PREP FOR "RTI" AT END MOV PS,2(SP) ;PLACE [PS] ALSO FOR "RTI" MOV #340,PS ;RAISE CPU LEVEL: PROTECT AGAINST "TIMER" ; ******************************************************************** ; * MODULE IDENTIFICATION: T I M E R S * .TITLE TIMERS ; ******************************************************************** ; * Q T I M E * ; * PROGRAM IDENTIFICATION: "QTIME" * ; * TIMER MODULE QUEUEING SUBROUTINE * ; *  0 ;TIMER/RESET .WORD 0 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL7: .WORD 1 ;THREAD WORD .BYTE 2 ;TASK # .BYTE 0 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD 0 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAIME-SLICING ON THIS LEVEL BLE CALA06 ;NOT A T/S LEVEL: GO DO ABORT SEQUENCE MOV R2,-(SP) ;SAVE USER'S ASL R1 ;USED AS A WORD INDEX MOV FIRST(R1),R2 ;ADDRESS OF FIRST TASK BEQ CALA05 ;NO TASKS IN QUEUE: DON'T SLICE MOV R2,@LAST(R1) ;LINK FRONT TASK TO END OF THREAD... MOV R2,LAST(R1) ;...AND UPDATE THE "LAST" POINTER MOV (R2),FIRST(R1) ;THEN MAKE "FIRS JSR R5, PUSHR ;SAVE ALL REGISTERS MOV 20(SP),R0 ;GET MODULE'S ADDRESS CMP #1,(R0) ;IS MODULE ALREADY INACTIVE? BEQ DQTM20 ;YES: TAKE GOOD EXIT MOVB #-1,5(R0) ;FLAG D-Q WITH "RESET" BYTE ALL ONES CMP #-1,(R0) ;IS MODULE STILL IN "WAIT" STACK? BEQ DQTM20 ;YES: NO NEED TO REMOVE FROM THREAD MOVB 3(R0),R1 ;IS IN ACTIVE QUEUE: TAKE IT OUT BIC  * ; * PURPOSE: LOADS TIMER MODULES ONTO "WAIT" STACK FOR "TIMER" * ; * "TMNSRT" IS RESPONSIBLE FOR UNLOADING FROM THE STACK * ; * AND STRINGING ONTO PROPER THREAD * ; * * ; * USAGE: CALLED BY ANY ROUTINE WISHING TO ACTIVATE A TIMER * ; * MODULE. CALLING SEQUENCE: * ; * MOV #MODULE,-(SPG MASK .WORD 0 ;JSR TARGET MODUL8: .WORD 1 ;THREAD WORD .BYTE 2 ;TASK # .BYTE 0 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD 0 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET MODUL9: .WORD 1 ;THREAD WORD .BYTE 2 ;TASK T" POINT TO WHAT WAS ;THE SECOND TASK IN QUEUE CLR @LAST(R1) ;ZERO THREAD WORD OF NEW LAST TASK CALA05: ;EXIT FROM TIME-SLICE MOV (SP)+,R2 ;RESTORE USER'S MOV (SP)+,R1 ;LIKEWISE BR CALA08 ;BYPASS ABORT SEQUENCE CALA06: ;HERE WHEN LEVEL IS NOT A SLICER: DO ABORT==> MOV (SP)+,R1 ;RESTORE USER'S .ENDC $TMSLC ; ABORT SE#177760,R1 ;GET MODULE'S RESOLUTION ASL R1 ;USED AS WORD INDEX BELOW MOV R1,R3 ;SAVE RESOLUTION IN CASE NEEDED BELOW CMPB R1,CURRES ;DID WE INTERRUPT "TIMER"... ;...WHILE IT IS ON THIS RESOLUTION? BNE DQTM05 ;NO: O.K. TO DE-QUEUE INC DQFLAG ;YES: FLAG "TIMER" TO RE-SCAN THREAD... BR DQTM20 ;...AND DO NOT REMOVE FROM THREAD NOW. DQ) ;STACK MODULE'S ADDRESS * ; * MOV TIME,-(SP) ;STACK TIMER-RESET WORD * ; * EMT QTIME ;REQUEST TO QUEUE MODULE * ; * OR * ; * JSR PC,QTIME * ; * TST (SP)+ ;TEST ERROR RETURN CODE * ; * * ; * THE MODULE MUST # .BYTE 0 ;OPTIONS .WORD 0 ;TIMER/RESET .WORD 0 ;ARG .WORD 0 ;FLAG ADDR .WORD 0 ;FLAG MASK .WORD 0 ;JSR TARGET .PAGE MASK1 = 123 MASK2 = 234 MASK3 = 345 JSRTNE: MOV #MODUL1,-(SP) MOV TMWRD0,-(SP) EMT QTIME TST (SP)+ RTS PC ARG1: '1 ARG2: '2 ARG3 QUENCE: TASK'S ABORT COUNTER REACHED ZERO (@TIMA40) MOV $CTASK,-(SP) ;STACK CURRENTLY ACTIVE TASK'S NUMBER... JSR PC,ABORT ;...AND REQUEST ITS ABORTION CALA08: ;HERE WHEN READY TO RUN THE CLOCK DECB TICTOC ;# OF TICS PER SECOND BEQ CALA10 ;NEW SECOND CALA09: RTI ;USED AS RETURN ALSO FROM[CALA40] .PAGE CALA10: ;ON EACH SECOND COME HERE CLRB SKSW TM05: ADD #TFIRST,R1 ;ADDR OF RESOLUTION'S "FIRST" WORD DQTM10: ;LOOP RETURN POINT FOR THREAD SEARCH MOV R1,R2 ;SAVE UPSTREAM MODULE'S ADDR MOV (R1),R1 ;ADDR OF DOWNSTREAM MODULE BEQ DQTM30 ;END OF THREAD: SEARCH FAIL ERROR CMP R0,R1 ;IS THIS THE MODULE TO BE DE-QUEUED? BNE DQTM10 ;NO: KEEP LOOKING MOV (R1),(R2) ;FOUND IT! BRIDGE OVER THIS MODULE. BE SET UP, PRIOR TO THE CALL, AS DESCRIBED * ; * IN THE ROS USER'S MANUAL. NOTE THAT CALLS FOR MODULES HAVING * ; * THE "S" SUSPEND OPTION SET WILL CAUSE TRANSFER TO THE * ; * DISPATCHER, AND WILL NOT RETURN UNLESS THE CALL IS IN ERROR. * ; * ON THESE CALLS THE MODULE'S TASK NUMBER IS AUTOMATICALLY SET * ; * TO THE CURRENTLY ACTIVE TASK'S NUMBER. * ; * IF THE "WAIT" STACK IS FULL, "QTIME" WILL EXIT WITH THE ERROR * ; * CODE WOR: '3 ARG4: '4 ARG5: '5 FLAG1: .BYTE 0 FLAG2: .BYTE 0 FLAG3: .BYTE 0 .EVEN .END CH ;INIT TO RUN "SKNSRT" AND NOT "SKED" MOV R0,-(SP) MOV R1,-(SP) MOV #CLOCK,R0 ;POINTER TO TIME & DATE BYTES MOVB #TICRES,(R0)+ ;RESET [TICTOC] INCB (R0) ;NEXT SECOND CMPB (R0),#60. ;NEW MINUTE? BLT CALA40 ;NO: BUT GO TO END TO RUN "SKNSRT" INCB SKSWCH ;SET TO RUN "SKED" AND NOT "SKNSRT" CLRB (R0)+ ;RESET [SECOND] & GO ON TO... .. BNE DQTM15 ;...AND EXIT IF NOT LAST MODULE MOV R2,TLAST(R3) ;...BUT UPDATE "LAST" ENTRY IF WAS @ END DQTM15: MOV #1,(R1) ;FINALLY, FLAG MODULE INACTIVE DQTM20: CLR 20(SP) ;CLEAR RETURN ERROR FLAG FOR GOOD EXIT DQTM30: JSR R5,POPR ;RESTORE SAVED REGISTERS... RTI ;...AND RETURN TO CALLER WITH HIS PS .PAGE ; ******************************************************************** ; D ON THE STACK NON-ZERO. THE MODULE WILL NOT BE QUEUED* ; * "QTIME" TAKES ITS ERROR EXIT IF THE REQUESTED MODULE IS ALREADY* ; * IN EITHER A TIMER THREAD OR THE "WAIT" STACK, AND HAS NOT BEEN * ; * FLAGGED FOR DE-QUEUEING. GOOD RETURNS ARE MADE WHEN THE MODULE* ; * IS FOUND INACTIVE OR MARKED FOR DE-QUEUEING IN THE "WAIT" STACK* ; * IN THIS LAST CASE, THE MARK FOR DE-QUEUEING WILL BE REMOVED, * ; * AND THE MODULE WILL REMAIN WHERE IT IS ON THE "WAIT" STACK. * ; * CK JSR PC,SDATE ; SET DATE IN ROS BR TIMA10 ; CHECK FOR ERROR & RETURN ; ; NO DELIMITER-ASSUME TYPE DATE REQUESTED ; DATB00 = . MOV #GDATE,R0 ; ADDRESS OF GET DATE SUBROUTINE MOV #DATEDT,R1 ; ADDRESS OF DATE EDIT TABLE MOV #DATMSG,R2 ; ADDRESS OF DATE MESSAGE ; ; TYPTOD IS USED BY TIME AND DATE TO TYPE THE TIME-OF-DAY ; OR TO TYPE THE DATE. ; UPON ENTRY:  INCB (R0) ;...BUMP [MINUTE] CMPB (R0),#60. ;NEW HOUR? BLT CALA40 ;NO: BUT GO RUN SCHEDULER CLRB (R0)+ ;RESET [MINUTE]... INCB (R0) ;...AND BUMP [HOUR] CMPB (R0),#24. ;NEW DAY? BLT CALA40 ;NO CLRB (R0)+ ;YES: RESET [HOUR]... INC (R0) ;...AND BUMP [JDATE] CMP (R0),(PC)+ ;NEW YEAR? MXDAYS: .WOR ; SET UP R5 & RETURN ; ; FIRST INTERRUPT-SYSTEM BUSY AND NO TASKS ACTIVE ; ALREADY ON SYSTEM STACK ; SAVE30: MOV PC,SBSYNA ; SET SYSTEM BUSY NOT ACTIVE FLAG ; ; PC NOT EQUAL 0 BR SAVE20 ; NOW SAVE REGISTERS ; ; .END * T I M E R * ; * PROGRAM IDENTIFICATION: "TIMER" * ; * HIGH-RESOLUTION CLOCK PULSE SERVICE ROUTINE * ; * * ; * PURPOSE: --SERVICES ALL TIMER MODULES AT THEIR RESPECTIVE * ; * RESOLUTIONS, PROVIDING THE FEATURES OF TASK * ; * TIME-DELAY, PERIODIC OR ONE-SHOT QUEUEING,  R0 = ADDRESS OF GTIME OR GDATE ; R1 = APPROPRIATE EDIT TABLE ADDRESS ; R2 = ADDRESS OF MESSAGE ; TYPTOD = . MOV #3.,R5 ; GO THRU LOOP THREE TIMES JSR PC,(R0) ; GET TIME OR GET DATE TYPT10: MOV #ASCII,-(SP) ; ADDRESS OF CONVERSION WORK STRING JSR PC,BINASC ; CONVERT NO. ON STACK TO ASCII MOV (R1)+,R4 ; ADDR. AT WHICH TO STORE 2 CHAR. ASCID 0 ;HOLDS #DAYS IN CURRENT YEAR BLE CALA30 ;NO: GO TO NEXT DAY + MAYBE NEW MONTH ;HAPPY NEW YEAR!! MOV #1,R1 MOV R1,(R0)+ ;RESET [JDATE] MOVB R1,(R0)+ ;RESET [MONTH] MOVB R1,(R0)+ ;RESET [MDAY] INCB (R0) ;BUMP TO NEW YEAR MOVB #28.,FEBARY ;RESET FEBRUARY MOV #365.,MXDAYS ;RESET YEAR LENGTH BITB MOV #PLOCK,PSR ; SET CPU LOCKOUT LEVEL 7 BR ERRB10 ; SEE IF ANY OTHER REQUESTS AND ; ; PROCESS THEM ACCORDINGLY ; ERRB30: MOV #-1.,IOLUSE ; RESET I/O LIST IN USE SWITCH MOV (SP)+,PSR ; RESTORE CPU PRIORITY RTS PC ; RETURN TO TTYOUT .END  * ; * FLAG-SETTING,AND COMPLETION-ROUTINE CALLS. * ; * --KEEPS TRACK OF THE TASK-EXECUTION TIME (ABORT) * ; * COUNTER, AND CALLS FOR TASK ABORT IF TIME * ; * RUNS OUT. * ; * --PROVIDES (OPTIONAL) TIME-SLICE FEATURE BY * ; * PERIODICALLY ROTATING THE TASKS IN A QUEUE. * ; * I MOVB ASCII+4,(R4)+ ; SET IN APPROPRIATE PLACE MOVB ASCII+5,(R4)+ ; IN MESSAGE DEC R5 ; FINISHED? BNE TYPT10 ; NO DEC R5 ; SET R5 NON-ZERO FOR NO ERROR MOV R2,DATADR ; SET MESSAGE ADDRESS IN I/O LIST MOV #TTYLST,-(SP) ; I/O LIST TO STACK JSR PC,TTYOUT ; OUTPUT TIME OR DATE MESSAGE RTS PC ; RETURN TO INPUT ;  #3,(R0) ;IS THIS A LEAP YEAR? BNE CALA35 ;NO INC MXDAYS ;YES: BUMP YEAR LENGTH INCB FEBARY ;...AND FEBRUARY BR CALA35 CALA30: ;HERE @ BEGIN OF DAY & NOT NEW YEAR MOV #MONTH,R1 ;INIT POINTER TO DATE BYTE TABLE MOVB (R1)+,R0 ;[MONTH]: USED AS INDEX INCB (R1) ;[MDAY]: NEW DAY CMPB (R1),DAYTAB(R0) ;[MDAY]: END OF MONTH .TITLE TIMCTL ;CONTROL OF TIMERS AND CLOCK .REF TIMER,CALEND SP =%6 MOV #340,-(SP) MOV #A,-(SP) JMP TIMER A: MOV #340,-(SP) MOV #B,-(SP) JMP CALEND B: RTI .=.+1000 ;RESERVE FOR PATCHES .END  * ; * USAGE: ACTIVATED BY CLOCK INTERRUPT. ALL PROGRAMS HANDLE * ; * COMMUNICATION VIA "QTIME" AND "DQTIME". "TIMER" * ; * CALLS SYSTEM SUBROUTINES "QUEUE", "SAVE", "UNSPND", * ; * AND "ABORT". * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; * .END  BLE CALA40 ;NO MOVB #1,(R1) ;RESET DAY TO FIRST OF MONTH INCB -(R1) ;NEXT MONTH: CAN'T BE JANUARY (ABOVE) CALA35: ;HERE TO ADJUST THE THREAD POINTER POINTER AT THE BEGIN ; OF EACH MONTH. "CURTHD" ALWAYS POINTS TO "TH1BGN" DURING ; ODD-NUMBERED MONTHS, AND TO "TH2BGN" DURING EVEN MONTHS. MOV #THDTAB,CURTHD ;INIT THREAD-START TABLE POINTER BITB #1,MONTH ;ODD-NUMBERED MONT; ******************************************************************** ; * PROGRAM IDENTIFICATION: "CALENDAR" * ; * DATE & TIME-OF-DAY ROUTINE * ; * * ; * PURPOSE: * ; * --KEEPS 24-HOUR CLOCK AND PERPETUAL CALENDAR UPDATED. * ; * --CALLS THE SCHEDULER ONCE A MINUTE, ON THE MINUTE.  * ; ******************************************************************** ; FOLLOWING ARE OFFSET PARAMETERS FOR TIMER MODULE REFERENCES SAVE = 3 ;OP-CODE FOR TRAP TO "SAVE" SUBROUTINE TASKNO = 2 ;TASK NUMBER BYTE OPTION = 3 ;OPTION FLAGS BYTE TIMBYT = 4 ;MODULE TIMER BYTE RESET = 5 ;TIMER RESET BYTE TIMARG = 6 ;ARGUMENT (FOR QUEUEING) ADD! * ; * PROGRAMMER: 52 * ; * VERSION:003.001 * ; * DATE: 09-DEC-71 * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; * * "H? BNE CALA40 ;YES: LEAVE AS IS ADD #2,CURTHD ;EVEN: ADVANCE TO POINT TO THREAD #2 CALA40: ;HERE ON EVERY MINUTE BOUNDARY TO RUN... ;...THE SCHEDULER. ON THE OTHER 59 SECONDS, RUN "INSERT" ROUTINE. MOV (SP)+,R1 ;RESTORE USER'S FOR "SAVE" MOV (SP)+,R0 ;ALSO INCB SKDBSY ;MARK AND TEST BUSY FLAG BEFORE ENTERING BNE CALA09 ;LOG-JAM: SCHEDULER CURRENTLY RUNNIN# * ; * * ; * USAGE: * ; * TRIGGERED BY TIME-OF-DAY CLOCK INTERRUPT. * ; * IF TIME OR DATE IS ALTERED BY OUTSIDE PROGRAM(S), * ; * CPU MUST BE ON LEVEL 7 TO AVOID INTERFERENCE. * ; * WHEN READING TIME OR DATE, SAME PRECAUTION SHOULD * ; * BE TAKEN. $RESS WORD TMFLAG = 6 ;FLAG ADDRESS WORD (DYNAMIC OFFSET) TIMASK = 8. ;FLAG MASK WORD (DYNAMIC OFFSET) JSTARG = 6 ;USER ROUTINE ADDRESS WORD (DYN OFFSET) .PAGE TIMA00: RTI ;RETURN USED IF CLOCK IS RE-ENTERED ;TO PROCESS QUEUE WHILE PREVIOUS REQUEST IN PROGRESS. TIMA70: ;HERE TO RESET RESOLUTION COUNTERS ;WHEN THEY EXPIRE (FROM TIMA20%; ******************************************************************** .DEF QTIME .DEF TIMER .DEF TWAITB,TTBPTR,TFIRST,TLAST,RESTAB,CURTAB,TIMBSY,BASCNT .REF UNSPND,QUEUE .REF $CTASK,$PRIOR,SUSPND .REF PUSHR,POPR,RESTOR .PAGE QTIME: ;ROUTINE TO PUT TIMER MODULE IN "WAIT" STACK MOV PS,-(SP) ;SAVE USER'S PS MOV #340,PS ;RAISE CPU LEVEL TO PROTECT ROUTINE MO&G... ;...DON'T RE-ENTER: IT WILL CLEAN UP AFTER ITSELF. ; O.K. TO ENTER "SKNSRT" OR ""SKED". SAVE ;SAVE REGS OF INTERRUPTED PGM & RTN HERE SKSWCH: BR .+2 ;SWITCH NORMALLY OPEN TO FALL THROUGH... BR SKRELY ;...TO SKIP "SKED" AND RUN "SKNSRT" ; ON THE MINUTE IT IS CLOSED TO FORCE RUN OF "SKED" INSTEAD. .PAGE SKED: ;THIS IS THE SCHEDULER ;ENTER HERE EVERY MINUTE ON THE MINUTE FROM "CALENDAR" ' * ; * PROGRAMMER: 52 * ; * VERSION:003.004 * ; * DATE: 06-DEC-71 * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; ******************************************************************** SAVE = 3 ;OP-CODE FOR CAL() MOVB RESTAB(R0),CURTAB(R0) ;RESET FROM PERM TABLE INC R0 ;BUMP TO NEXT RESOLUTION... TSTB RESTAB(R0) ;...AND SEE IF THIS IS THE END BNE TIMA20 ;NOT YET: MORE BR TIMA30 ;END OF COUNTERS: DO ALL THREADS TIMER: ;ENTRY FROM INTERRUPT: CPU LEVEL 7 .IFNZ $TMBAS ;OPTION ALLOWS RESOLUTION FINER THAN RES1 DECB BASCNT ;COUNT DOWN BASIC MULTIPLIER )V R0,-(SP) ;SAVE USER'S CMP TTBPTR,#TMTBND ;SEE IF STACK IS FULL BHI QTIM50 ;YES: ERROR EXIT MOV 10(SP),R0 ;ADDRESS OF MODULE DEC (R0) ;IS TIMER MODULE INACTIVE? (T/W=0?) BNE QTIM30 ;NO: SEE IF ACTIVE OR IN "WAIT" STATE QTIM20: ;HERE WHEN CLEARED TO STACK UP MODULE ADD #2,TTBPTR ;PUSH "WAIT" STACK POINTER MOV R0,@TTBPTR ;ENTER MOD* MOV @CURTHD,R0 ;[TH1BGN] OR [TH2BGN] MOV R0,R1 ;SAVE CURRENT THREAD ADDRESS FOR... ;...POSSIBLE MODULE REMOVAL (BELOW) MOV (R0),R0 ;NEXT MODULE'S ADDRESS BEQ SKDEX2 ;END OF THREAD: EXIT MOV R4,PS ;DROP CPU LEVEL TO BE FAIR TO OTHERS MOV STRTWD(R0),-(SP);STACK THIS MODULE'S START WORD FOR... JSR PC,UNPACK ;...CALL TO UNPACK SUBROUTINE,+L TO [SAVE] SUBROUTINE STRTWD = 4 ;INDEX TO MODULE TIME& DATE WORD DELTA = 6 ;INDEX TO MODULE INCREMENT WORD .DEF CALEND .DEF QSKED,DQSKED,COUNTR .DEF DAYTAB,CLOCK,TICTOC,SECOND,MINUTE,HOUR .DEF JDATE,MDAY,MONTH,YEAR,MXDAYS,JANARY,FEBARY .DEF SWAITB,STBPTR,THDTAB,CURTHD,ABMPLR,SKDBSY .REF PUSHR,POPR,PPTAB,ABORT .REF QUEUE,FIRST,LAST,$PRIOR,RESTOR,$CTASK .TITLE CALE,BEQ TIMA10 ;TURNED OVER: ENTER TIMER PROGRAM RTI ;NO NEED TO ENTER TIMA10: ;HERE WHEN BASIC RES'N TURNS OVER MOVB #$TMBAS,BASCNT ;RESET BASE PERIOD MULTIPLIER .ENDC $TMBAS INCB TIMBSY ;CHECK FOR PREVIOUS CALL STILL ACTIVE BNE TIMA00 ;YES: LEAVE INDICATOR SET TO SHOW ;PENDING REQUEST TO RUN; AND RETURN. SAVE -ULE ADDRESS INTO "WAIT" STACK BIS #C1CBIT,C1COMD ;START UP CLOCK IF IT WAS OFF TST 2(R0) ;CHECK OPTION FLAG FOR "SUSPEND" BMI QTIM60 ;"SUSPEND" SELECTED QTIM40: ;THIS IS THE "SUCCESSFUL" EXIT CLR 10(SP) ;PREPARE ERROR RETURN CODE TO SHOW O.K. QTIM45: ;HERE WHEN EXITING TO "SUSPEND". AVOID CLEARING 10(SP) MOV 6(SP),4(R0) ;LOAD NEW TIMER/RESET WORD INTO MODULE ; TH. WHICH ; RETURNS WITH TIME & DATE OF MODULE'S START WORD SPREAD ON STACK ; (SP) = DAY OF MONTH 2(SP) = HOUR 4(SP) = MINUTE CMPB (SP),MDAY ;SEE IF MODULE IS FOR TODAY BGT SKDEX1 ;FOR TOMORROW OR BEYOND: EXIT BLT SKDB10 ;FOR YESTERDAY OR EARLIER: EXECUTE MODULE CMPB 2(SP),HOUR ;TODAY: THIS HOUR? BGT SKDEX1 ;MODULE IS EARLY: EXIT BLT SKDB10 ;MODULE IS LATE: EXECUTE /ND .PAGE CALENDAR: ;TIME & DATE ROUTINE ;ENTRY FROM TIME-OF-DAY CLOCK INTERRUPT ;ENTERED ON CPU LEVEL 7 .IFNZ $ABMPL ;OPTION FOR "ABORT" MULTIPLIER DEC ABMPLR ;COUNT DOWN THE ABORT MULTIPLIER BGT CALA08 ;NOT YET: DON'T RUN ABORT OR TIME-SLICE MOV #$ABMPL,ABMPLR ;RESET THE ABORT MULTIPLIER .ENDC $ABMPL DEC 0 ;NOT ACTIVE, SO SAFE TO ENTER. CALL TO ;SAVE ENVIRONMENT AND RETURN WITH: ;(R4) = (PS) BEFORE CLOCK INTERRUPT ;(R5) = ADDRESS OF "RESTOR" ROUTINE .PAGE TMNSRT: ;TIMER INSERT ROUTINE: TRANSFERS TIMER MODULE ADDRESS ; FROM WAIT STACK TO APPROPRIATE QUEUE WHEN CONVENIENT FOR TIMER. ; CPU LEVEL SEVEN: AVOID INTERFERENCE WITH "QTIME". MOV @TTBPTR,R0 ;ADD1IS SERVES AS NORMAL INIT FOR TIMER MODULE, AND ALSO RESETS ; THE "RESET" BYTE IN CASE MODULE IS BEING RE-QUEUED AFTER BEING ; DE-QUEUED, ALL WHILE REMAINING IN "WAIT" STACK. QTIM50: ;HERE WHEN EXIT IS TO LEAVE NON-ZERO ERROR CODE ON STACK DEC (R0) ;SET T/W=-1 TO SHOW IN "WAIT" STATE... ;...OR TO RESTORE MODULE'S T/W IF IT IS FOUND ALREADY ACTIVE... ; ...OR ALREADY IN "WAIT" STATE MOV (SP)+,R0 ;RESTORE USER'S MOV (S2 CMPB 4(SP),MINUTE ;FOR THIS HOUR. THIS MINUTE? BGT SKDEX1 ;TOO SOON SKDB10: MOV #340,PS ;LOCK OUT INTERFERENCE FROM "DQSKED" CMP (R0),#1 ;ALREADY DE-QUEUED? BNE SKDB20 ;STILL O.K. ADD #6,SP ;POP SP DUE TO "UNPACK"... BR SKED ;...AND GO BACK FOR ANOTHER ONE SKRELY: BR SKNSRT ;RELAY POINT FOR SKIP TO 'INSERT' RTNE .PAGE SKDB20: 3COUNTR ;TIC OFF CURRENT TASK TIMER BGT CALA08 ;STILL SOME LIFE LEFT INC COUNTR ;RESTORE IN CASE WAS ZERO BEQ CALA08 ;IT WAS. WE IGNORE ZEROES AS "OFF" .PAGE .IFNZ $TMSLC ;OPTION FOR TIME SLICING MOV R1,-(SP) ;SAVE USER'S MOV $PRIOR,R1 ;PRIORITY OF TASK INVOLUNTARILY ; SUSPENDED BY INTERRUPT, OR OF MOST RECENTLY RUN TASK. TSTB PPTAB(R1) ;CHECK FOR T4RESS OF TIMER MODULE FROM TOP OF ;"WAIT" STACK BEQ TIMA15 ;STACK EMPTY SUB #2,TTBPTR ;NOT EMPTY: POP STACK ONE CELL MOV #1,(R0) ;SET T/W INACTIVE IN CASE WAS DE-QUEUED CMPB 5(R0),#-1 ;IS "RESET" ALL ONES? BEQ TMNSRT ;YES: MODULE WAS "DE-QUEUED": IGNORE IT MOVB 3(R0),R1 ;GET OPTION BYTE BIC #177760,R1 ;ISOLATE RESOLUTION CM5P)+,2(SP) ;MOVE OLD [PS] IN PREP FOR RTI RTI ;ZAP! RETURN TO USER OR GO TO SUSPEND ;ON OLD CPU LEVEL QTIM30: ADD #2,(R0) ;NOT INACTIVE. SEE IF ACTIVE OR "WAIT" BNE QTIM50 ;ACTIVE: TAKE ERROR EXIT CMPB 5(R0),#-1 ;IN "WAIT": IS IT FLAGGED FOR DE-QUEUE? BNE QTIM50 ;NO: ERROR EXIT BR QTIM40 ;YES: LEAVE THERE AND REMOVE D-Q FLAG .P6;O.K. TO WORK ON THIS MODULE MOV (R0),(R1) ;FIRST: REMOVE MODULE BY "BRIDGING" THE ;THREAD OVER ITSELF, CONNECTING PREVIOUS ;MODULE WITH FOLLOWING ONE MOV #1,(R0) ;SET THIS MODULE INACTIVE... MOV R4,PS ;...DROP CPU LEVEL TO INTERRUPTED LEVEL MOV R0,R1 ;...AND SET UP THE SECONDARY MODULE PNTR MOV 2(R1),R2 ;GET OPTION & TASK WORD 7IME-SLICING ON THIS LEVEL BLE CALA06 ;NOT A T/S LEVEL: GO DO ABORT SEQUENCE MOV R2,-(SP) ;SAVE USER'S ASL R1 ;USED AS A WORD INDEX MOV FIRST(R1),R2 ;ADDRESS OF FIRST TASK BEQ CALA05 ;NO TASKS IN QUEUE: DON'T SLICE MOV R2,@LAST(R1) ;LINK FRONT TASK TO END OF THREAD... MOV R2,LAST(R1) ;...AND UPDATE THE "LAST" POINTER MOV (R2),FIRST(R1) ;THEN MAKE "FIRS8P R1,#$NRES-1 ;IS RESOLUTION IN RANGE? BGT TMNSRT ;NO: TOO LARGE ASL R1 ;USED AS WORD INDEX BELOW MOV R0,@TLAST(R1) ;PUT NEW MODULE'S ADDR @ END PROPER THD> MOV R0,TLAST(R1) ;...AND UPDATE THE "LAST" POINTER ITSELF CLR (R0) ;CLEAR MODULE'S T/W: END OF THREAD BR TMNSRT ;NOW GO BACK AND POP ANY MORE MODULES .PAGE TIMA15: ;RE-ENTER HERE FOR9AGE QTIM60: ;HERE WHEN TASK IS TO BE SUSPENDED UNTIL TIMER EXPIRES MOVB $CTASK,2(R0) ;LOAD MODULE TASK # WITH CURRENT TASK MOV 4(SP),10(SP) ;SET CALLER RTN TO LOOK LIKE "JSR" MOV #SUSPND,4(SP) ;SET STACK SO RTI WILL GO TO "SUSPEND" BR QTIM45 ;INSTEAD OF RETURNING TO CALLER .PAGE ; ******************************************************************** ; * : BPL SKDC10 ;"R" REPEAT FLAG NOT SET MOV DELTA(R1),-(SP) ;GET REPEAT WORD & STACK IT FOR CALL... JSR PC,UNPACK ;...TO SPREAD IT ON STACK ;NOW THE STACK HAS BOTH THE MODULE'S ;"START" AND "DELTA" WORDS SPREAD ON IT: ;(SP)= D-DATE 2(SP)= D-HOUR 4(SP)= D-MINUTE ["D" MEANS "DELTA"] ;6(SP)= S-DATE 8(SP)= S-HOUR 10(SP)= S-MINUTE ["S" MEANS "START"] MOV SP,R5 ;T" POINT TO WHAT WAS ;THE SECOND TASK IN QUEUE CLR @LAST(R1) ;ZERO THREAD WORD OF NEW LAST TASK CALA05: ;EXIT FROM TIME-SLICE MOV (SP)+,R2 ;RESTORE USER'S MOV (SP)+,R1 ;LIKEWISE BR CALA08 ;BYPASS ABORT SEQUENCE CALA06: ;HERE WHEN LEVEL IS NOT A SLICER: DO ABORT==> MOV (SP)+,R1 ;RESTORE USER'S .ENDC $TMSLC ; ABORT SE< REPEATS (TIMBSY>/=1) MOV R4,PS ;RESTORE PROCESSOR LEVEL TO PREVIOUS CLR R0 ;INIT RESOLUTION INDEX TIMA20: ;RETURN HERE WHEN ADVANCING TO NEXT RESN DECB CURTAB(R0) ;COUNT DOWN A RESOLUTION COUNTER BEQ TIMA70 ;EXPIRED: GO RESET IT & BUMP RES'N INDEX TIMA30: ;FALL THROUGH HERE WHEN A RESOLUTION COUNTER IS FOUND ; THAT HAS NOT EXPIRED. SINCE THE RESOLUTIONS ARE COUNTED STARTING ; = * ; * D Q T I M E * ; * PROGRAM IDENTIFICATION: "DQTIME" * ; * TIMER MODULE DE-QUEUEING SUBROUTINE * ; * * ; * PURPOSE: * ; * REMOVES TIMER MODULES FROM TIMER THREADS, IF ACTIVE * ; * AND IF FOUND IN > ;INIT SECONDARY STACK POINTER ADD #6,R5 ;POINT TO "S-DATE" ADD (SP)+,(R5)+ ;[D-DATE] + [S-DATE]: ACCUMULATE DAYS ADD (SP)+,(R5)+ ;[D-HOUR] + [S-HOUR]: ACCUMULATE HOURS ADD (SP)+,(R5)+ ;[D-MIN] + [S-MIN]: ACCUMULATE MINUTES CMP #60.,(R5) ;SEE IF MINUTES OVERFLOWED BGT SKDB30 ;NO: O.K. SUB #60.,(R5) ;YES: STRIP MODULUS... INC -(R5) ;...AND BUMP HOU?QUENCE: TASK'S ABORT COUNTER REACHED ZERO (@TIMA40) MOV $CTASK,-(SP) ;STACK CURRENTLY ACTIVE TASK'S NUMBER... JSR PC,ABORT ;...AND REQUEST ITS ABORTION CALA08: ;HERE WHEN READY TO RUN THE CLOCK DECB TICTOC ;# OF TICS PER SECOND BEQ CALA10 ;NEW SECOND CALA09: RTI ;USED AS RETURN ALSO FROM[CALA40] .PAGE CALA10: ;ON EACH SECOND COME HERE CLRB SKSW@ FROM THE FINEST TOWARDS THE COARSEST, THE RESOLUTION CURRENTLY IN R0 ; IS THE FINEST RESOLUTION THAT HAS NOT EXPIRED. BY DECREMENTING R0, ; THE COARSEST RESOLUTION TO EXPIRE IS FOUND. FALLS THROUGH HERE ALSO ; IF ALL RESOLUTIONS EXPIRE, WHICH WILL HAPPEN FROM TIME TO TIME. ASL R0 ;RESOLUTION*2: USE AS WORD INDEX TIMA35: ;LOOP BACK HERE FOR SUCCESSIVE RESOLUTIONS DEC R0 DEC R0 ;COUNT DOWN RESOLUTION INDEX (TWICE, ; AITS PROPER THREAD. IF ACTIVE BUT NOT * ; * FOUND, ERROR EXIT IS TAKEN. IF STILL IN "WAIT" STACK * ; * IT IS MARKED FOR REMOVAL WHEN "TMNSRT" IS RUN. * ; * IF MODULE IS ALREADY INACTIVE, NO ACTION TAKEN, AND * ; * GOOD EXIT IS TAKEN. * ; * * ; * USAGE: CALLED BY ANY ROUTINE WISHING TO DE-ACTIVATE A TIMER * ; * MODULE. BRS TST (R5)+ ;(EQUALIZE POINTER IN CASE OF BRANCH) SKDB30: CMP #24.,-(R5) ;SEE IF HOURS OVERFLOWED BGT SKDB32 ;NO SUB #24.,(R5) ;YES: STRIP MODULUS... INC (SP) ;...AND BUMP DAYS SKDB32: MOVB MONTH,R3 ;USE CURRENT MONTH AS INDEX MOVB DAYTAB(R3),R3 ;GET # DAYS/MONTH INTO A WORD CMP R3,(SP) ;CHECK IF PAST END OF MONTH BGE SKDB40 ;SCCH ;INIT TO RUN "SKNSRT" AND NOT "SKED" MOV R0,-(SP) MOV R1,-(SP) MOV #CLOCK,R0 ;POINTER TO TIME & DATE BYTES MOVB #TICRES,(R0)+ ;RESET [TICTOC] INCB (R0) ;NEXT SECOND CMPB (R0),#60. ;NEW MINUTE? BLT CALA40 ;NO: BUT GO TO END TO RUN "SKNSRT" INCB SKSWCH ;SET TO RUN "SKED" AND NOT "SKNSRT" CLRB (R0)+ ;RESET [SECOND] & GO ON TO... D SINCE IT WAS MADE INTO A WORD INDEX ABOVE). ON THE FIRST PASS AFTER ; FINDING THE FIRST RES'N NOT TO EXPIRE, THIS BRINGS COUNTER BACK TO ; (DOUBLE) THE COARSEST RES'N TO EXPIRE. ON SUCCESSIVE PASSES THIS ; MOVES TO NEXT FINER RES'N FOR SERVICING. BLT TIMEXT ;EXIT HERE WHEN ALL RESOLUTIONS HAVE ; BEEN SERVICED, OR IF NO LEVELS ACTUALLY EXPIRED. .PAGE TIMB10: ;NOW WE BEGIN TRAVELING THE THREADS ;ALSO LOOP RE-ENTRY POE CALLING SEQUENCE: * ; * * ; * MOV #MODULE,-(SP) ;STACK MODULE'S ADDRESS * ; * EMT DQTIME ;REQUEST TO DE-QUEUE MODULE * ; * OR * ; * JSR PC,DQTIME ;DIRECT CALL WITH PROPER LINK * ; * TST (SP)+ ;POP ERROR RETURN CODE * ; * FTILL THIS MONTH SUB R3,(SP) ;GET DAY OF NEXT MONTH .PAGE SKDB40: ;NOW RESTORE MODULE START WORD & STACK SWAB (SP) ;POSITION "DATE"... ASL (SP) ASL (SP) ASL (SP) ;...FOR PLACE BACK IN "START" WORD SWAB 2(SP) ;POSITION "HOUR" ASR 2(SP) ASR 2(SP) ;...FOR ITS PLACE BIS (SP)+,(SP) ;[OR] DATE & HOUR... G INCB (R0) ;...BUMP [MINUTE] CMPB (R0),#60. ;NEW HOUR? BLT CALA40 ;NO: BUT GO RUN SCHEDULER CLRB (R0)+ ;RESET [MINUTE]... INCB (R0) ;...AND BUMP [HOUR] CMPB (R0),#24. ;NEW DAY? BLT CALA40 ;NO CLRB (R0)+ ;YES: RESET [HOUR]... INC (R0) ;...AND BUMP [JDATE] CMP (R0),(PC)+ ;NEW YEAR? MXDAYS: .WORHINT FOR EACH RESOLUTION MOV #TFIRST,R1 ;CALC ADDRESS IN THE QUEUE POINTER TABLE ADD R0,R1 ;...OF POINTER FOR CURRENT RESOLUTION TIMB15: ;LOOP HERE FOR EACH SUCCESSIVE MODULE MOV #340,PS ;AVOID INTERFERENCE WITH "DQTIME" MOVB R0,CURRES ;INIT "CURRENT RESOLUTION" BEFORE BEGIN TIMB16: ;LOOP RE-ENTRY POINT MOV R1,R2 ;REMEMBER UPSTREAM MODULE ADDRESS... I * ; * NOTE THAT THE THREE ROUTINES: [TIMER], [QTIME], AND * ; * [DQTIME] ALLOW AN UNLIMITED NUMBER OF CALLS TO QUEUE * ; * OR DE-QUEUE THE SAME MODULE, REGARDLESS OF ITS STATUS * ; * AT ANY GIVEN TIME. THE STATE UPON THE RETURN FROM A * ; * CALL TO [QTIME] OR [DQTIME], ASSUMING A ZERO ERROR CODE* ; * ASSURES THAT THE MODULE IS IN THE MOST RECENTLY * ; * J BIS (SP)+,(SP) ;...WITH MINUTE... MOV (SP)+,STRTWD(R1);...AND RE-STORE INTO START WORD TST (R1)+ ;BUMP POINTER TO ALLOW FOR "DELTA" WORD MOV R0,-(SP) JSR PC,QSKED ;RE-QUEUE MODULE IN NEW TIME SLOT TST (SP)+ ;POP RETURN ERROR WORD SKDC10: ;CONTINUE PROCESSING MODULE... ;...WHETHER OR NOT IT WAS REPEATED TSTB R2 ;TASKD 0 ;HOLDS #DAYS IN CURRENT YEAR BLE CALA30 ;NO: GO TO NEXT DAY + MAYBE NEW MONTH ;HAPPY NEW YEAR!! MOV #1,R1 MOV R1,(R0)+ ;RESET [JDATE] MOVB R1,(R0)+ ;RESET [MONTH] MOVB R1,(R0)+ ;RESET [MDAY] INCB (R0) ;BUMP TO NEW YEAR MOVB #28.,FEBARY ;RESET FEBRUARY MOV #365.,MXDAYS ;RESET YEAR LENGTH BITB L ;...FOR USE IN DE-QUEUEING "ONE-SHOTS" MOV (R1),R1 ;NEXT MODULE'S THREAD WORD ADDRESS BEQ TIMB90 ;END OF THREAD: GO CHECK FOR DE-QUEUE CMPB RESET(R1),#377 ;IF MODULE IS FLAGGED... BEQ TIMB16 ;...DON'T EXECUTE IT. DECB TIMBYT(R1) ;COUNT DOWN MODULE'S TIMER BNE TIMB16 ;NOT EXPIRED: GET NEXT MODULE ;TIMER EXPIRED! IT IS MODULEM REQUESTED STATE. THE ONLY EXCEPTION IS WHEN A CALL TO * ; * [DQTIME] HAS BEEN MADE AFTER THE REQUESTED MODULE HAS * ; * TIMED OUT AND BEGUN EXECUTION. STRICTLY SPEAKING, THE * ; * CALL IN THIS CASE CAME AFTER THE MODULE WAS RUN. * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; * * NK NUMBER BEQ SKDD10 ;NO QUEUEING WHEN IT IS ZERO MOVB R2,-(SP) ;STACK TASK # IN PREP FOR CALL TO QUEUE .IFNZ DPRTY ;OPTION FOR DYNAMIC PRIORITIES CLR -(SP) ;USE SYSTEM-ASSIGNED PRIORITIES .ENDC DPRTY CLR -(SP) ;IMMEDIATE RETURN REQUESTED... ;...OR INIT OF [ARG] IF NEEDED ASL R2 ;IS THE "A" (ARGUMENT) FLAG SET? BPL SKDCO #3,(R0) ;IS THIS A LEAP YEAR? BNE CALA35 ;NO INC MXDAYS ;YES: BUMP YEAR LENGTH INCB FEBARY ;...AND FEBRUARY BR CALA35 CALA30: ;HERE @ BEGIN OF DAY & NOT NEW YEAR MOV #MONTH,R1 ;INIT POINTER TO DATE BYTE TABLE MOVB (R1)+,R0 ;[MONTH]: USED AS INDEX INCB (R1) ;[MDAY]: NEW DAY CMPB (R1),DAYTAB(R0) ;[MDAY]: END OF MONTH P'S TIME. ; SINCE COMPLETION ROUTINES RUN UNDER THE "J" OPTION ASSUME R1 POINTS TO ; THE CURRENT MODULE (IT'S THREAD WORD), R1 MUST BE PRESERVED AS SUCH ; UNTIL THE POSSIBLE ROUTINE IS RUN. BUT TWO OTHER POINTERS ARE NEEDED: ; R3 MOVES DOWN THE MODULE TO COMPENSATE FOR OPTIONAL PARAMTERS WHICH ; MAKE THE LIST LONGER, AND R5 IS RESET TO POINT TO THE UPSTREAM MODULE ; IN CASE THE CURRENT MODULE IS A "ONE-SHOT" AND IS REMOVED FROM THE ; THREAD. R1 IS LOADED FROM R5 AT THE END OF THE LOOP TO ALLOW Q; ******************************************************************** .DEF DQTIME .PAGE DQTIME: ;SYSTEM SUBROUTINE TO DE-QUEUE A TIMER MODULE MOV (SP),-(SP) ;MOVE RTN ADDR IN PREP FOR "RTI" AT END MOV PS,2(SP) ;PLACE [PS] ALSO FOR "RTI" MOV #340,PS ;RAISE CPU LEVEL: PROTECT AGAINST "TIMER" JSR R5, PUSHR ;SAVE ALL REGISTERS MOV 20(SP),R0 ;GET MODULE'S ADDRESS CMP R20 ;NO: LEAVE THE ZERO ON STACK FOR ARG'MNT .IFNZ ARG ;OPTION FOR TRANSMITTING ARGUMENT MOV @6(R1),(SP) ;YES: PUT ACTUAL ARG IN PLACE OF ZERO .ENDC ARG TST (R1)+ ;BUMP POINTER IN ANY CASE IF "A" IS SET SKDC20: .IFNZ ARG ;OPTION FOR TRANSMITTING ARGUMENT CLR -(SP) ;PUSH RETURN CODE .ENDC ARG JSR PC,QUEUE ;NOW CALL "QUEUE" TO RUN REQUESTED TASK S BLE CALA40 ;NO MOVB #1,(R1) ;RESET DAY TO FIRST OF MONTH INCB -(R1) ;NEXT MONTH: CAN'T BE JANUARY (ABOVE) CALA35: ;HERE TO ADJUST THE THREAD POINTER POINTER AT THE BEGIN ; OF EACH MONTH. "CURTHD" ALWAYS POINTS TO "TH1BGN" DURING ; ODD-NUMBERED MONTHS, AND TO "TH2BGN" DURING EVEN MONTHS. MOV #THDTAB,CURTHD ;INIT THREAD-START TABLE POINTER BITB #1,MONTH ;ODD-NUMBERED MONTTTHIS. MOV R1,R3 ;INIT R3 AS DYNAMIC LIST POINTER MOV R1,R5 ;INIT R5 IN PREP FOR R1 RESET BELOW MOVB RESET(R1),TIMBYT(R1) ;RESET TIMER BYTE BNE TIMB20 ;MODULE IS A REPEATER: LEAVE IN THREAD MOV (R1),(R2) ;"ONE-SHOT": REMOVE FROM THREAD ... BNE TIMB22 ;...BY "BRIDGING". BRANCH IF NOT LAST MOV R2,TLAST(R0) ;BUT UPDATE "LAST" POINTER IF WAS END TIMB22: MOV #1U #1,(R0) ;IS MODULE ALREADY INACTIVE? BEQ DQTM20 ;YES: TAKE GOOD EXIT MOVB #-1,5(R0) ;FLAG D-Q WITH "RESET" BYTE ALL ONES CMP #-1,(R0) ;IS MODULE STILL IN "WAIT" STACK? BEQ DQTM20 ;YES: NO NEED TO REMOVE FROM THREAD MOVB 3(R0),R1 ;IS IN ACTIVE QUEUE: TAKE IT OUT BIC #177760,R1 ;GET MODULE'S RESOLUTION ASL R1 ;USED AS WORD INDEX BELOW MOV V TST (SP)+ ;...AND POP ERROR CODE ON RETURN SKDD10: ;QUEUEING OR NO, NOW CHECK FOR FLAG-SET ASL R2 ;IS THE "F" FLAG OPTION SET? BPL SKED ;NO: THIS MODULE DONE: BACK FOR MORE BISB 8.(R1),@6(R1) ;YES: DO [IOR] OF MASK INTO FLAG LOC'N BR SKED ;DONE WITH MODULE: LOOK FOR MORE SKDEX1: ADD #6,SP ;ADJUST SP FROM CALL TO "UNPACK" SKDEX2: ;SWH? BNE CALA40 ;YES: LEAVE AS IS ADD #2,CURTHD ;EVEN: ADVANCE TO POINT TO THREAD #2 CALA40: ;HERE ON EVERY MINUTE BOUNDARY TO RUN... ;...THE SCHEDULER. ON THE OTHER 59 SECONDS, RUN "INSERT" ROUTINE. MOV (SP)+,R1 ;RESTORE USER'S FOR "SAVE" MOV (SP)+,R0 ;ALSO INCB SKDBSY ;MARK AND TEST BUSY FLAG BEFORE ENTERING BNE CALA09 ;LOG-JAM: SCHEDULER CURRENTLY RUNNINX,(R1) ;SET THREAD WORD INACTIVE IN EITHER CASE MOV R2,R5 ;BACK POINTER TO UPSTREAM MODULE TIMB20: MOV R4,PS ;UNLOCK INTERRUPTS: SAFE NOW MOVB OPTION(R3),R2 ;GET OPTION BYTE FOR THIS MODULE TSTB TASKNO(R3) ;IS MODULE TASK-RELATED? BEQ TIMB54 ;NO: CHECK FOR OTHER OPTIONS ;YES: SET UP STACK FOR CALL TO EITHER ;[SUSPEND] OR [QUEUE] MOVBY R1,R3 ;SAVE RESOLUTION IN CASE NEEDED BELOW CMPB R1,CURRES ;DID WE INTERRUPT "TIMER"... ;...WHILE IT IS ON THIS RESOLUTION? BNE DQTM05 ;NO: O.K. TO DE-QUEUE INC DQFLAG ;YES: FLAG "TIMER" TO RE-SCAN THREAD... BR DQTM20 ;...AND DO NOT REMOVE FROM THREAD NOW. DQTM05: ADD #TFIRST,R1 ;ADDR OF RESOLUTION'S "FIRST" WORD DQTM10: ;LOOP RETURN POINT FOR TZCHEDULER EXIT WITH NO STACK POP MOV #340,PS ;PROTECT CHECK OF BUSY FLAG MOVB #-1,SKDBSY ;RESET FLAG TO ALLOW NEXT ENTRY JMP RESTOR ;RETURN TO INTERRUPTED PGM ==>[RESTOR] .PAGE UNPACK: ;INTERNAL SUBROUTINE TO SPREAD A SCHEDULER TIME&DATE ;WORD ONTO THE STACK ;UPON ENTRY, ROUTINE ASSUMES PACKED WORD IS ON TOP OF STACK; ; 15 11 10 6 5 1 ; DAY ^ HOUR ^ MINU[G... ;...DON'T RE-ENTER: IT WILL CLEAN UP AFTER ITSELF. ; O.K. TO ENTER "SKNSRT" OR ""SKED". SAVE ;SAVE REGS OF INTERRUPTED PGM & RTN HERE SKSWCH: BR .+2 ;SWITCH NORMALLY OPEN TO FALL THROUGH... BR SKRELY ;...TO SKIP "SKED" AND RUN "SKNSRT" ; ON THE MINUTE IT IS CLOSED TO FORCE RUN OF "SKED" INSTEAD. .PAGE SKED: ;THIS IS THE SCHEDULER ;ENTER HERE EVERY MINUTE ON THE MINUTE FROM "CALENDAR" \ TASKNO(R3),-(SP);PUSH TASK # FIRST CLR -(SP) ;IMMEDIATE RETURN REQUEST FOR BOTH, OR ;INIT OF PRIORITY IF NEEDED FOR [QUEUE]. TSTB R2 ;IS "SUSPEND" OPTION SELECTED? BPL TIMB30 ;NO: GO DO QUEUEING JSR PC,UNSPND ;CALL TO "UN-SUSPEND" BR TIMB50 ;GO POP ERROR WORD & CHECK FLAG OPTION TIMB30: ;HERE TO QUEUE A TASK. TASK # AND RETURN CODE ]HREAD SEARCH MOV R1,R2 ;SAVE UPSTREAM MODULE'S ADDR MOV (R1),R1 ;ADDR OF DOWNSTREAM MODULE BEQ DQTM30 ;END OF THREAD: SEARCH FAIL ERROR CMP R0,R1 ;IS THIS THE MODULE TO BE DE-QUEUED? BNE DQTM10 ;NO: KEEP LOOKING MOV (R1),(R2) ;FOUND IT! BRIDGE OVER THIS MODULE... BNE DQTM15 ;...AND EXIT IF NOT LAST MODULE MOV R2,TLAST(R3) ;...BUT UPDATE^TE ;UPON EXIT, STACK HAS THREE WORDS ON IT: ; (SP)= DAY 2(SP)= HOUR 4(SP)= MINUTE TST -(SP) ;MUST PUSH STACK TO RE-POSITION (PC) MOV 2(SP),-(SP) ;MOVE (PC) TO NEW PLACE ON STACK MOV 6(SP),R3 ;COPY TIME & DATE WORD FOR USE BELOW MOV R3,R5 ;ALSO SAVE IT FOR BELOW BELOW BIC #177700,6(SP) ;LEAVE "MINUTE" ALL BY ITSELF ASL R3 ASL R3 SWAB R3 ;GET "HO_ MOV @CURTHD,R0 ;[TH1BGN] OR [TH2BGN] MOV R0,R1 ;SAVE CURRENT THREAD ADDRESS FOR... ;...POSSIBLE MODULE REMOVAL (BELOW) MOV (R0),R0 ;NEXT MODULE'S ADDRESS BEQ SKDEX2 ;END OF THREAD: EXIT MOV R4,PS ;DROP CPU LEVEL TO BE FAIR TO OTHERS MOV STRTWD(R0),-(SP);STACK THIS MODULE'S START WORD FOR... JSR PC,UNPACK ;...CALL TO UNPACK SUBROUTINE,` ;(OR INITED PRIORITY) ALREADY PUSHED ONTO STACK. .IFNZ DPRTY ;DYNAMIC PRIORITIES OPTION CLR -(SP) ;USE SYSTEM-ASSIGNED PRIORITY ; (ACTUALLY LEAVES ZERO AS PRIORITY AND PUSHES NEW RETURN CODE OF ZERO, ; POSSIBLY INITING STACK SPACE FOR PASSED ARGUMENT, IF OPTION IS ON.) .ENDC DPRTY .IFNZ ARG ;SYSTEM OPTION TO PASS ARGUMENT ON QUEUE BIT #100,R2 ;DOES MODULE HAVE AN ARGUMENT TO PASS? BEQ TIMBa "LAST" ENTRY IF WAS @ END DQTM15: MOV #1,(R1) ;FINALLY, FLAG MODULE INACTIVE DQTM20: CLR 20(SP) ;CLEAR RETURN ERROR FLAG FOR GOOD EXIT DQTM30: JSR R5,POPR ;RESTORE SAVED REGISTERS... RTI ;...AND RETURN TO CALLER WITH HIS PS .PAGE ; ******************************************************************** ; * T I M E R * ; * PROGRAM IDENTIFICATION: "TIMER" bUR" INTO LOW BYTE BIC #177740,R3 ;CLEAR ALL OTHER STUFF MOV R3,4(SP) ;PUT "HOUR" IN ITS OWN PLACE ON STACK SWAB R5 ASR R5 ASR R5 ASR R5 ;GET [DAY] INTO LOWER BYTE... BIC #177740,R5 ; ...CLEAR GARBAGE... MOV R5,2(SP) ; ...AND PUT IN ITS OWN PLACE RTS PC .PAGE SKNSRT: ;ROUTINE TO INSERT SCHEDULER MODULES FROM THE WAITINc WHICH ; RETURNS WITH TIME & DATE OF MODULE'S START WORD SPREAD ON STACK ; (SP) = DAY OF MONTH 2(SP) = HOUR 4(SP) = MINUTE CMPB (SP),MDAY ;SEE IF MODULE IS FOR TODAY BGT SKDEX1 ;FOR TOMORROW OR BEYOND: EXIT BLT SKDB10 ;FOR YESTERDAY OR EARLIER: EXECUTE MODULE CMPB 2(SP),HOUR ;TODAY: THIS HOUR? BGT SKDEX1 ;MODULE IS EARLY: EXIT BLT SKDB10 ;MODULE IS LATE: EXECUTE d40 ;NO MOV @TIMARG(R3),(SP);YES: REPLACE THE ZERO WITH ACTUAL ARG TIMB40: CLR -(SP) ;MUST PUSH RETURN CODE SINCE ARGUMENT .ENDC ARG ;USED UP LAST ONE. JSR PC,QUEUE ;CALL QUEUE TIMB50: ;HERE AFTER [QUEUE] OR [UNSPND] TST (SP)+ ;POP ERROR RETURN CODE TIMB54: ;HERE WHEN NOT TASK-RELATED ASLB R2 ;MOVE "ARG" OPTION INTO SIGN BIT BPL e * ; * HIGH-RESOLUTION CLOCK PULSE SERVICE ROUTINE * ; * * ; * PURPOSE: --SERVICES ALL TIMER MODULES AT THEIR RESPECTIVE * ; * RESOLUTIONS, PROVIDING THE FEATURES OF TASK * ; * TIME-DELAY, PERIODIC OR ONE-SHOT QUEUEING, * ; * FLAG-SETTING,AND COMPLETION-ROUTINE CALLS. * ; * --KEEPS TRACK OF THEfG ;TABLE. ALSO LOOP RE-ENTRY POINT FROM END MOV #340,PS ;LOCK OUT INTERFERENCE FROM "QSKED" SKNA10: ;LOOP RETURN WHEN LOCKOUT IS ALREADY SET MOV @STBPTR,R0 ;GET ADDRESS OF NEXT MODULE BEQ SKDEX2 ;TABLE EMPTY: EXIT VIA "RESTOR" SUB #2,STBPTR ;NOT EMPTY: POP POINTER BACK ONE CELL MOV #1,(R0) ;SET INACTIVE IN CASE DE-QUEUED BIT #10000,2(R0) ;WAS IT DE-QUEUED g CMPB 4(SP),MINUTE ;FOR THIS HOUR. THIS MINUTE? BGT SKDEX1 ;TOO SOON SKDB10: MOV #340,PS ;LOCK OUT INTERFERENCE FROM "DQSKED" CMP (R0),#1 ;ALREADY DE-QUEUED? BNE SKDB20 ;STILL O.K. SKDB15: ;ALSO RETURN POINT FROM [SKDD10] ADD #6,SP ;POP SP DUE TO "UNPACK"... BR SKED ;...AND GO BACK FOR ANOTHER ONE SKRELY: BR SKNSRT ;RELAY Ph TIMB56 ;"A" NOT SET TST (R3)+ ;PASS POINTER OVER ARG, WHETHER USED OR NOT TIMB56: ASLB R2 ;GET "FLAG" OPTION BIT INTO SIGN BPL TIMB60 ;NO FLAG OPTION BISB TIMASK(R3),@TMFLAG(R3) ;"IOR" MASK INTO FLAG LOCATION CMP (R3)+,(R3)+ ;BUMP SECONDARY MODULE POINTER FOR FLAGS TIMB60: ASLB R2 ;GET "J" OPTION BIT INTO SIGN BPL TIMB70 ;NOT SELECTED JSR PC,@JSTAi TASK-EXECUTION TIME (ABORT) * ; * COUNTER, AND CALLS FOR TASK ABORT IF TIME * ; * RUNS OUT. * ; * --PROVIDES (OPTIONAL) TIME-SLICE FEATURE BY * ; * PERIODICALLY ROTATING THE TASKS IN A QUEUE. * ; * * ; * USAGE: ACTIVATED BY CLOCK INTERRUPT. ALL PROGRAMS HANDLE * ; * COMMUNICATION jWHILE IN TABLE? BNE SKNA10 ;YES: IGNORE AND CONTINUE MOV R4,PS ;RESTORE PREVIOUS CPU LEVEL MOV 4(R0),-(SP) ;STACK MODULE'S DATE WORD FOR... JSR PC,UNPACK ;...CALL TO SPREAD IT ON STACK TST (SP) ;IF "DATE" = 0,... BNE SKNA20 MOVB MDAY,(SP) ;...THEN USE TODAY'S DATE SKNA20: CMP 2(SP),#37 ;IF "HOUR" IS ALL ONES... BNE SKNA30 MOVB HOURkOINT FOR SKIP TO 'INSERT' RTNE .PAGE SKDB20: ;O.K. TO WORK ON THIS MODULE MOV (R0),(R1) ;FIRST: REMOVE MODULE BY "BRIDGING" THE ;THREAD OVER ITSELF, CONNECTING PREVIOUS ;MODULE WITH FOLLOWING ONE MOV #1,(R0) ;SET THIS MODULE INACTIVE... MOV R4,PS ;...DROP CPU LEVEL TO INTERRUPTED LEVEL MOV R0,R1 ;...AND SET UP THE SECONDARY MODULE PNlRG(R3) ;LINK TO USER RTNE. (R1)= MODULE BEGIN TIMB70: MOV R5,R1 ;RESET MODULE POINTER (SEE EXPLN. ABOVE) BR TIMB15 ;LOOP BACK FOR MORE MODULES .PAGE TIMB90: ;HERE AT END OF A RESOLUTION THREAD MOVB (PC),CURRES ;KILL "CURRENT RESOLUTION" @ THREAD END TST DQFLAG ;DID "DQTIME" REQUEST ANY DURING THREAD? BEQ TIMA35 ;NO: NO CHECK NECESSARY. GET NEXT RES'N MOV #TFIRST,R1 mVIA "QTIME" AND "DQTIME". "TIMER" * ; * CALLS SYSTEM SUBROUTINES "QUEUE", "SAVE", "UNSPND", * ; * AND "ABORT". * ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; * * ; ******************************************************************** ; FOLLOWINn,2(SP) ;...THEN USE CURRENT HOUR SKNA30: CMP 4(SP),#77 ;IF "MIN" IS ALL ONES... BNE SKNA40 MOVB MINUTE,4(SP) ;...THEN USE CURRENT MINUTE .PAGE SKNA40: ;NOW THAT MODULE'S TIME IS READY, BEGIN SEARCH FOR ITS ;PLACE IN ONE OF THE TWO SCHEDULER THREADS. MOV CURTHD,R1 ;POINTS TO [THDTAB] OR [THDTAB+2] CMPB (SP),MDAY ;MODULE DATE :: TODAY'S DATE BGT SKNA60 ;AFTER TODAYoTR MOV 2(R1),R2 ;GET OPTION & TASK WORD BPL SKDC10 ;"R" REPEAT FLAG NOT SET MOV DELTA(R1),-(SP) ;GET REPEAT WORD & STACK IT FOR CALL... JSR PC,UNPACK ;...TO SPREAD IT ON STACK ;NOW THE STACK HAS BOTH THE MODULE'S ;"START" AND "DELTA" WORDS SPREAD ON IT: ;(SP)= D-DATE 2(SP)= D-HOUR 4(SP)= D-MINUTE ["D" MEANS "DELTA"] ;6(SP)= S-DATE 8(SP)= S-HOUR 10(SP)p;IS NECESSARY TO RE-TRAVEL THREAD ADD R0,R1 ;PROPER THREAD START WORD MOV R1,R2 ;REMEMBER UPSTREAM WORD TIMB92: MOV (R1),R1 ;NEXT MODULE'S ADDRESS BEQ TIMA35 ;THREAD'S END: CAN NOW EXIT CMP 5(R1),#377 ;WAS THIS MODULE FLAGGED? BNE TIMB92 ;NO: KEEP LOOKING MOV (R1),(R2) ;FOUND ONE! BRIDGE OVER DE-QUEUED MODULE BNE TIMB94 ;NOT FINAL IN THREADqG ARE OFFSET PARAMETERS FOR TIMER MODULE REFERENCES SAVE = 3 ;OP-CODE FOR TRAP TO "SAVE" SUBROUTINE TASKNO = 2 ;TASK NUMBER BYTE OPTION = 3 ;OPTION FLAGS BYTE TIMBYT = 4 ;MODULE TIMER BYTE RESET = 5 ;TIMER RESET BYTE TIMARG = 6 ;ARGUMENT (FOR QUEUEING) ADDRESS WORD TMFLAG = 6 ;FLAG ADDRESS WORD (DYNAMIC OFFSET) TIMASK = 8. ;Fr: USE CURRENT THREAD BLT SKNA50 ;BEFORE TODAY: USE "FUTURE" THREAD CMPB 2(SP),HOUR ;MODULE HOUR :: CURRENT HOUR BGT SKNA60 ;LATER TODAY: USE CURRENT THREAD BLT SKNA50 ;WAS EARLIER TODAY: PUT IN "FUTURE" CMPB 4(SP),MINUTE ;MODULE MINUTE :: CURRENT MINUTE BGE SKNA60 ;NOW OR WITHIN HOUR: CURRENT THREAD SKNA50: TST (R1)+ ;WE ARE PAST MODULE'S TIME: USE "FUTURE" SKNA60: s= S-MINUTE ["S" MEANS "START"] MOV SP,R5 ;INIT SECONDARY STACK POINTER ADD #6,R5 ;POINT TO "S-DATE" ADD (SP)+,(R5)+ ;[D-DATE] + [S-DATE]: ACCUMULATE DAYS ADD (SP)+,(R5)+ ;[D-HOUR] + [S-HOUR]: ACCUMULATE HOURS ADD (SP)+,(R5)+ ;[D-MIN] + [S-MIN]: ACCUMULATE MINUTES CMP #60.,(R5) ;SEE IF MINUTES OVERFLOWED BGT SKDB30 ;NO: O.K. SUB #60.,(R5) ;YES: t MOV R2,TLAST(R0) ;WAS END MODULE: UPDATE "LAST" POINTER TIMB94: MOV #1,(R1) ;SET THREAD-WORD INACTIVE DEC DQFLAG ;ANY MORE TO FIND? BGT TIMB92 ;YES: KEEP LOOKING BR TIMA35 ;DONE: EXIT EARLY TIMEXT: ;EXIT POINT FOR [TIMER] MOV #TFIRST,R0 ;PREPARE TO SCAN LIST OF "FIRST" WORDS MOV #$NRES,R1 ;LIST SIZE MOV #340,PS ;LOCK OUT PULSuLAG MASK WORD (DYNAMIC OFFSET) JSTARG = 6 ;USER ROUTINE ADDRESS WORD (DYN OFFSET) .PAGE TIMA00: RTI ;RETURN USED IF CLOCK IS RE-ENTERED ;TO PROCESS QUEUE WHILE PREVIOUS REQUEST IN PROGRESS. TIMA70: ;HERE TO RESET RESOLUTION COUNTERS ;WHEN THEY EXPIRE (FROM TIMA20) MOVB RESTAB(R0),CURTAB(R0) ;RESET FROM PERM TABLE INC R0 ;BUMP TO NEXT REv ;NOW THAT PROPER THREAD BEGIN WORD'S ADDRESS IS IN R1, ;WE CAN BEGIN SEARCH OF THAT THREAD. MOV (R1),R2 ;ADDR OF ONE OF THE THREAD-BEGIN WORDS BR SKNB00 ;ENTER LOOP FOR FIRST TIME SKNB10: ;THIS IS THE LOOP RETURN POINT AS LONG AS SEARCH CONT'S ADD #6,SP ;POP STACK POINTER FROM "UNPACK" BELOW SKNB00: ;HERE FOR FIRST-TIME ENTRY MOV R2,R1 ;SAVE OLD T/W ADDRESwSTRIP MODULUS... INC -(R5) ;...AND BUMP HOURS TST (R5)+ ;(EQUALIZE POINTER IN CASE OF BRANCH) SKDB30: CMP #24.,-(R5) ;SEE IF HOURS OVERFLOWED BGT SKDB32 ;NO SUB #24.,(R5) ;YES: STRIP MODULUS... INC (SP) ;...AND BUMP DAYS SKDB32: MOVB MONTH,R3 ;USE CURRENT MONTH AS INDEX MOVB DAYTAB(R3),R3 ;GET # DAYS/MONTH INTO A WORD CMP R3,(SP) xE DURING EXIT SEQUENCE TIMEX1: TST (R0)+ ;IF ANY IS NON-ZERO... BNE TIMEX2 ;...DON'T TURN OFF CLOCK DEC R1 ;BE SURE TO DO WHOLE LIST BNE TIMEX1 TST @TTBPTR ;CHECK FOR EMPTY "WAIT" LIST BNE TIMEX2 ;NOT EMPTY: LEAVE CLOCK ON BIC #C1CBIT,C1COMD ;NO MODULES ACTIVE: KILL INTERRUPT TIMEX2: DECB TIMBSY ;NESTING "BUSY" COUNTER BGE TIMA15 ySOLUTION... TSTB RESTAB(R0) ;...AND SEE IF THIS IS THE END BNE TIMA20 ;NOT YET: MORE BR TIMA30 ;END OF COUNTERS: DO ALL THREADS TIMER: ;ENTRY FROM INTERRUPT: CPU LEVEL 7 .IFNZ $TMBAS ;OPTION ALLOWS RESOLUTION FINER THAN RES1 DECB BASCNT ;COUNT DOWN BASIC MULTIPLIER BEQ TIMA10 ;TURNED OVER: ENTER TIMER PROGRAM RTI ;NO NEED TO ENTER TIzS MOV (R2),R2 ;GET NEXT MODULE'S (T/W) ADDRESS BEQ SKNB30 ;AT END OF THREAD ;NOT @ END: TEST MODULE FOR TIME MOV 4(R2),-(SP) ;STACK TEST MODULE'S DATE WORD... JSR PC,UNPACK ;...FOR CALL TO SPREAD IT ON STACK CMP 6(SP),(SP) ;NEW MOD'S DATE :: TEST MOD'S DATE BGT SKNB10 ;LATER: KEEP LOOKING BLT SKNB20 ;EARLIER: THREAD NOW CMP 10(SP),2(SP) ;NEW MOD{ ;CHECK IF PAST END OF MONTH BGE SKDB40 ;STILL THIS MONTH SUB R3,(SP) ;GET DAY OF NEXT MONTH .PAGE SKDB40: ;NOW RESTORE MODULE START WORD & STACK SWAB (SP) ;POSITION "DATE"... ASL (SP) ASL (SP) ASL (SP) ;...FOR PLACE BACK IN "START" WORD SWAB 2(SP) ;POSITION "HOUR" ASR 2(SP) ASR 2(SP) ;...FOR | ;NORMALLY RESIDES @ ZERO DURING ROUTINE ;EXECUTION. GOES ABOVE IF ADDITIONAL ;OCCASIONS TO ENTER ROUTINE HAVE ;OCCURRED DURING EXECUTION. IN THIS ;CASE ROUTINE IS RE-EXECUTED IMMEDIATELY ;IN AN ATTEMPT TO RE-SYNCHRONIZE JMP RESTOR ;NORMAL RETURN TO INTERRUPTED PROGRAM .PAGE TTBPTR: .WORD TWAITB }MA10: ;HERE WHEN BASIC RES'N TURNS OVER MOVB #$TMBAS,BASCNT ;RESET BASE PERIOD MULTIPLIER .ENDC $TMBAS INCB TIMBSY ;CHECK FOR PREVIOUS CALL STILL ACTIVE BNE TIMA00 ;YES: LEAVE INDICATOR SET TO SHOW ;PENDING REQUEST TO RUN; AND RETURN. SAVE ;NOT ACTIVE, SO SAFE TO ENTER. CALL TO ;SAVE ENVIRONMENT AND RETURN WITH: ~'S HOUR :: TEST MOD'S HOUR BGT SKNB10 ;STILL LATER BLT SKNB20 ;EARLIER CMP 12(SP),4(SP) ;COMPARE MINUTES BGT SKNB10 .PAGE SKNB20: ;HAVE FINALLY FOUND SLOT FOR NEW MODULE. R1 CONTAINS ;ADDR OF PREVIOUS OR "UPSTREAM" MODULE (MIGHT BE THE ;THREAD START WORD) AND R2 CONTAINS ADDR OF DOWNSTREAM ;MODULE, OR ZERO IF NEW MODULE IS BEING PLACED AT END ;OITS PLACE BIS (SP)+,(SP) ;[OR] DATE & HOUR... BIS (SP)+,(SP) ;...WITH MINUTE... MOV (SP)+,STRTWD(R1);...AND RE-STORE INTO START WORD TST (R1)+ ;BUMP POINTER TO ALLOW FOR "DELTA" WORD MOV R0,-(SP) JSR PC,QSKED ;RE-QUEUE MODULE IN NEW TIME SLOT TST (SP)+ ;POP RETURN ERROR WORD SKDC10: ;CONTINUE PROCESSING MODULE... ;...WH;TIMER TABLE POINTER TO "WAIT" STACK TWAITB: .WORD 0 ;FIRST LOC'N OF "WAIT" TABLE IS ALWAYS 0 .=$TWATZ*2+. ;RESERVE SPACE FOR TABLE TMTBND = .-2 ;ADDRESS OF LAST TALBE LOCATION TFIRST: ;TABLE OF POINTERS TO FIRST MODULE IN ;EACH RESOLUTION'S THREAD. CONTAIN ZERO ;WHEN THREAD IS EMPTY. .WORD ,,,,,,,,,,,,,,, ;MAX TABLE SIZE: 16 WORDS .= ;(R4) = (PS) BEFORE CLOCK INTERRUPT ;(R5) = ADDRESS OF "RESTOR" ROUTINE .PAGE TMNSRT: ;TIMER INSERT ROUTINE: TRANSFERS TIMER MODULE ADDRESS ; FROM WAIT STACK TO APPROPRIATE QUEUE WHEN CONVENIENT FOR TIMER. ; CPU LEVEL SEVEN: AVOID INTERFERENCE WITH "QTIME". MOV @TTBPTR,R0 ;ADDRESS OF TIMER MODULE FROM TOP OF ;"WAIT" STACK BEQ TIMA15 ;SF THREAD. R0 CONTAINS ADDR OF NEW MODULE. ADD #6,SP ;POP SP FROM 1ST CALL TO "UNPACK" SKNB30: ADD #6,SP ;POP SP FROM 2ND CALL TO "UNPACK" MOV R0,(R1) ;LOAD UPSTREAM THREAD-WORD FOR NEW MOD MOV R2,(R0) ;LOAD NEW T/W FOR DOWNSTREAM MOD BR SKNSRT ;GO BACK FOR POSSIBLE MORE MODULES. .PAGE ; ******************************************************************** ; * PROGRAM IDENTIFICATION: ETHER OR NOT IT WAS REPEATED TSTB R2 ;TASK NUMBER BEQ SKDD10 ;NO QUEUEING WHEN IT IS ZERO MOVB R2,-(SP) ;STACK TASK # IN PREP FOR CALL TO QUEUE .IFNZ DPRTY ;OPTION FOR DYNAMIC PRIORITIES CLR -(SP) ;USE SYSTEM-ASSIGNED PRIORITIES .ENDC DPRTY CLR -(SP) ;IMMEDIATE RETURN REQUESTED... ;...OR INIT OF [ARG] IF NEEDED ASL R2 $NRES*2+TFIRST ;ACTUAL TABLE SIZE = [$NRES] WORDS TLAST: ;TABLE OF POINTERS TO LAST MODULE IN ;EACH RESOLUTION'S THREAD. CONTAIN THE ;ADDRESS OF [TFIRST(R)] WHEN THREAD ;IS EMPTY. .WORD ,,,,,,,,,,,,,,, ;MAX TABLE SIZE: 16 WORDS .=$NRES*2+TLAST ;ACTUAL TABLE SIZE = [$NRES] WORDS .PAGE RESTAB: ;RESOLUTION COUNTACK EMPTY SUB #2,TTBPTR ;NOT EMPTY: POP STACK ONE CELL MOV #1,(R0) ;SET T/W INACTIVE IN CASE WAS DE-QUEUED CMPB 5(R0),#-1 ;IS "RESET" ALL ONES? BEQ TMNSRT ;YES: MODULE WAS "DE-QUEUED": IGNORE IT MOVB 3(R0),R1 ;GET OPTION BYTE BIC #177760,R1 ;ISOLATE RESOLUTION CMP R1,#$NRES-1 ;IS RESOLUTION IN RANGE? BGT TMNSRT ;NO: TOO LARGE ASL R1 "QSKED" * ; * SYSTEM SUBROUTINE TO QUEUE A SCHEDULER MODULE * ; * * ; * PURPOSE: * ; * PUTS ADDRESS OF CALLER'S MODULE IN INTERNAL STACK. * ; * THIS TABLE IS EMPTIED BY THE ROUTINE "SKNSRT" WHICH IS * ; * CALLED BY THE SCHEDULER EACH MINUTE JUST BEFORE IT RUNS* ; * THIS MET ;IS THE "A" (ARGUMENT) FLAG SET? BPL SKDC20 ;NO: LEAVE THE ZERO ON STACK FOR ARG'MNT .IFNZ ARG ;OPTION FOR TRANSMITTING ARGUMENT MOV @6(R1),(SP) ;YES: PUT ACTUAL ARG IN PLACE OF ZERO .ENDC ARG TST (R1)+ ;BUMP POINTER IN ANY CASE IF "A" IS SET SKDC20: .IFNZ ARG ;OPTION FOR TRANSMITTING ARGUMENT CLR -(SP) ;PUSH RETURN CODE .ENDC ARG JSTER TABLE: PERMANENT .BYTE RES0,RES1,RES2,RES3,RES4,RES5,RES6,RES7,RES8 .BYTE RES9,RES10,RES11,RES12,RES13,RES14,RES15 .=RESTAB+$NRES ;SET TO ACTUAL TABLE SIZE .BYTE 0 ;END BYTE CURTAB: .BYTE RES0,RES1,RES2,RES3,RES4,RES5,RES6,RES7,RES8 .BYTE RES9,RES10,RES11,RES12,RES13,RES14,RES15 .=CURTAB+$NRES ;SET TO ACTUAL TABLE SIZE QTMCNT: .BYTE 0 ;COUNTER FOR USE IN "QTIME" TIMBSY:  ;USED AS WORD INDEX BELOW MOV R0,@TLAST(R1) ;PUT NEW MODULE'S ADDR @ END PROPER THD> MOV R0,TLAST(R1) ;...AND UPDATE THE "LAST" POINTER ITSELF CLR (R0) ;CLEAR MODULE'S T/W: END OF THREAD BR TMNSRT ;NOW GO BACK AND POP ANY MORE MODULES .PAGE TIMA15: ;RE-ENTER HERE FOR REPEATS (TIMBSY>/=1) MOV R4,PS ;RESTORE PROCESSOR LEVEL TO PREVIOUS CLR R0 HOD AVOIDS QUEUEING AND SCHEDULER CONFLICTS WHE* ; * ACCESSING THE TWO SCHEDULER THREADS(THE SCHEDULER DROPS* ; * THE CPU LEVEL SO AS NOT TO LOCK OUT INTERRUPTS UNNECES-* ; * SARILY), REDUCING THE CONFLICT AREA TO JUST THE FIFO * ; * TABLE. THIS CONFLICT IS AVOIDED, THEN, BY RUNNING * ; * "QSKED" (A SHORT ROUTINE) AND THE FEW WORDS OF CODE * ; * IN "SKNSRT" WHICH ACCESS THE TABLE, UNDER INTERRUPT- * ; * R PC,QUEUE ;NOW CALL "QUEUE" TO RUN REQUESTED TASK TST (SP)+ ;...AND POP ERROR CODE ON RETURN SKDD10: ;QUEUEING OR NO, NOW CHECK FOR FLAG-SET ASL R2 ;IS THE "F" FLAG OPTION SET? BPL SKDB15 ;NO: THIS MODULE DONE: BACK FOR MORE BISB 8.(R1),@6(R1) ;YES: DO [IOR] OF MASK INTO FLAG LOC'N BR SKDB15 ;DONE WITH MODULE: LOOK FOR MORE SKDEX1: ADD #6,SP ;A.BYTE 0 ;FLAG & NESTING COUNTER FOR [TIMER] BASCNT: .BYTE 0 ;OPTIONAL SUB-RESOLUTION PULSE COUNTER CURRES: .BYTE 0 ;CURRENT RESOLUTION WHEN "TIMER" ACTIVE .EVEN DQFLAG: .WORD 0 ;# OF MODULES REQUESTED TO BE DE-QUEUED ;ON CURRENT RESOLUTION WHILE ACTIVE IN "TIMER" .END  ;INIT RESOLUTION INDEX TIMA20: ;RETURN HERE WHEN ADVANCING TO NEXT RESN DECB CURTAB(R0) ;COUNT DOWN A RESOLUTION COUNTER BEQ TIMA70 ;EXPIRED: GO RESET IT & BUMP RES'N INDEX TIMA30: ;FALL THROUGH HERE WHEN A RESOLUTION COUNTER IS FOUND ; THAT HAS NOT EXPIRED. SINCE THE RESOLUTIONS ARE COUNTED STARTING ; FROM THE FINEST TOWARDS THE COARSEST, THE RESOLUTION CURRENTLY IN R0 ; IS THE FINEST RESOLUTION THAT HAS NOT EXPLOCKOUT. * ; * * ; * USAGE: * ; * USERS CAN CALL "QSKED" EITHER VIA JSR (IF LINKED) OR * ; * VIA EMT. IN EITHER CASE THE ADDRESS OF THE MODULE TO BE* ; * THREADED MUST FIRST BE PLACED ON THE STACK.THE STACK * ; * POINTER IS LEFT UNCHANGED ON RETURN. THE STACK LOCATION* ; * DJUST SP FROM CALL TO "UNPACK" SKDEX2: ;SCHEDULER EXIT WITH NO STACK POP MOV #340,PS ;PROTECT CHECK OF BUSY FLAG MOVB #-1,SKDBSY ;RESET FLAG TO ALLOW NEXT ENTRY JMP RESTOR ;RETURN TO INTERRUPTED PGM ==>[RESTOR] .PAGE UNPACK: ;INTERNAL SUBROUTINE TO SPREAD A SCHEDULER TIME&DATE ;WORD ONTO THE STACK ;UPON ENTRY, ROUTINE ASSUMES PACKED WORD IS ON TOP OF STACK; ; 15 1ITSELF WILL BE CLEARED IF THE TABLE HAS ROOM FOR * ; * IT AND THE MODULE ITSELF IS INACTIVE (ITS THREAD WORD * ; * MUST BE =1). IN CASE OF ONE OF THE ABOVE ERRORS, THE * ; * STACK LOCATION IS LEFT UNCHANGED (NON-ZERO) FOR TESTING* ; * BY THE CALLER. * ; * "QSKED" SAVES & RESTORES ALL REGISTERS THAT IT USES. * ; * IT MAY BE CALLED BY ANY TYPE OF USER AT ANY TIME. * ; * IRED. BY DECREMENTING R0, ; THE COARSEST RESOLUTION TO EXPIRE IS FOUND. FALLS THROUGH HERE ALSO ; IF ALL RESOLUTIONS EXPIRE, WHICH WILL HAPPEN FROM TIME TO TIME. ASL R0 ;RESOLUTION*2: USE AS WORD INDEX TIMA35: ;LOOP BACK HERE FOR SUCCESSIVE RESOLUTIONS DEC R0 DEC R0 ;COUNT DOWN RESOLUTION INDEX (TWICE, ; SINCE IT WAS MADE INTO A WORD INDEX ABOVE). ON THE FIRST PASS AFTER ; FINDING THE FIRST RES'N NOT TO EXPIRE, TH ITSELF WILL BE CLEARED IF THE TABLE HAS ROOM FOR * ; * IT AND THE MODULE ITSELF IS INACTIVE (ITS THREAD WORD * ; * MUST BE =1). IN CASE OF ONE OF THE ABOVE ERRORS, THE * ; * STACK LOCATION IS LEFT UNCHANGED (NON-ZERO) FOR TESTING* ; * BY THE CALLER. * ; * "QSKED" SAVES & RESTORES ALL REGISTERS THAT IT USES. * ; * IT MAY BE CALLED BY ANY TYPE OF USER AT ANY TIME. * 1 10 6 5 1 ; DAY ^ HOUR ^ MINUTE ;UPON EXIT, STACK HAS THREE WORDS ON IT: ; (SP)= DAY 2(SP)= HOUR 4(SP)= MINUTE MOV (SP),R3 ;COPY T&D WORD MOV R3,R5 ;SAVE IT FOR BELOW BIC #177700,(SP) ;LEAVE MINUTE ALL BY ITSELF ASL R3 ASL R3 SWAB R3 ;GET "HOUR" INTO LOW BYTE BIC #177740,R3 ;CLEAR ALL OTHER STUFF MOV R3,-(SP)  * ; * G U L F E L E C T R O N I C S Y S T E M S * ; ******************************************************************** .PAGE QSKED: ;SUBROUTINE TO QUEUE A SCHEDULER MODULE ;TO WAIT FOR INSERTION INTO ONE OF THE ;TWO SCHEDULER THREADS MOV (SP),-(SP) ;MOVE RETURN ADDRESS UP FOR RTI LATER IS BRINGS COUNTER BACK TO ; (DOUBLE) THE COARSEST RES'N TO EXPIRE. ON SUCCESSIVE PASSES THIS ; MOVES TO NEXT FINER RES'N FOR SERVICING. BLT TIMEXT ;EXIT HERE WHEN ALL RESOLUTIONS HAVE ; BEEN SERVICED, OR IF NO LEVELS ACTUALLY EXPIRED. .PAGE TIMB10: ;NOW WE BEGIN TRAVELING THE THREADS ;ALSO LOOP RE-ENTRY POINT FOR EACH RESOLUTION MOV #TFIRST,R1 ;CALC ADDRESS IN THE QUEUE POINTER TABLE ADD ; * * ; * G U L F E L E C T R O N I C S Y S T E M S * ; ******************************************************************** .PAGE QSKED: ;SUBROUTINE TO QUEUE A SCHEDULER MODULE ;TO WAIT FOR INSERTION INTO ONE OF THE ;TWO SCHEDULER THREADS MOV (SP),-(SP) ;MOVE RETURN ADDRESS UP FOR RTI LATER ;PUT IT IN ITS OWN PLACE SWAB R5 ASR R5 ASR R5 ASR R5 ;GET [DAY] INTO LOWER BYTE... BIC #177740,R5 ; ...CLEAR GARBAGE... MOV R5,-(SP) ; ...AND PUT IN ITS OWN PLACE RTS PC .PAGE SKNSRT: ;ROUTINE TO INSERT SCHEDULER MODULES FROM THE WAITING ;TABLE. ALSO LOOP RE-ENTRY POINT FROM END MOV #340,PS ;LOCK OUT INTERFERENCE F MOV PS,2(SP) ;...AND SET UP PS FOR RTI, TOO MOV R0,-(SP) ;SAVE USER'S MOV #340,PS ;RAISE CPU LEVEL TO AVOID INTERFERENCE CMP STBPTR,#SKTBND ;IS TABLE FULL? BHIS QSKA40 ;YES: POINTER IS AT BOTTOM, SO ERROR XIT MOV 6(SP),R0 ;MODULE'S ADDRESS BIC #10000,2(R0) ;CLEAR "D" FLAG IN CASE WAS DE-QUEUED DEC (R0) ;IS MODULE INACTIVE (THREAD WORD = 1)? BEQ R0,R1 ;...OF POINTER FOR CURRENT RESOLUTION TIMB15: ;LOOP HERE FOR EACH SUCCESSIVE MODULE MOV #340,PS ;AVOID INTERFERENCE WITH "DQTIME" MOVB R0,CURRES ;INIT "CURRENT RESOLUTION" BEFORE BEGIN TIMB16: ;LOOP RE-ENTRY POINT MOV R1,R2 ;REMEMBER UPSTREAM MODULE ADDRESS... ;...FOR USE IN DE-QUEUEING "ONE-SHOTS" MOV (R1),R1 ;NEXT MODULE MOV PS,2(SP) ;...AND SET UP PS FOR RTI, TOO MOV R0,-(SP) ;SAVE USER'S MOV #340,PS ;RAISE CPU LEVEL TO AVOID INTERFERENCE CMP STBPTR,#SKTBND ;IS TABLE FULL? BHIS QSKA40 ;YES: POINTER IS AT BOTTOM, SO ERROR XIT MOV 6(SP),R0 ;MODULE'S ADDRESS BIC #10000,2(R0) ;CLEAR "D" FLAG IN CASE WAS DE-QUEUED DEC (R0) ;IS MODULE INACTIVE (THREAD WORD = 1)? ROM "QSKED" SKNA10: ;LOOP RETURN WHEN LOCKOUT IS ALREADY SET MOV @STBPTR,R0 ;GET ADDRESS OF NEXT MODULE BEQ SKDEX2 ;TABLE EMPTY: EXIT VIA "RESTOR" ADD #2,STBPTR ;NOT EMPTY: POP POINTER BACK ONE CELL MOV #1,(R0) ;SET INACTIVE IN CASE DE-QUEUED BIT #10000,2(R0) ;WAS IT DE-QUEUED WHILE IN TABLE? BNE SKNA10 ;YES: IGNORE AND CONTINUE MOV R4,PS ;RESTORE PRE QSKA20 ;O.K. ADD #2,(R0) ;SEE IF IN "WAIT" TABLE BEQ QSKA30 ;YES: O.K. TO TAKE GOOD EXIT NOW BR QSKA35 ;IN THREAD: TAKE ERROR EXIT QSKA20: ;MODULE READY FOR INSERTION IN TABLE ADD #2,STBPTR ;PUSH TABLE POINTER MOV R0,@STBPTR ;LOAD NEW MODULE INTO TABLE QSKA30: CLR 6(SP) ;NOW READY TO EXIT. CLEAR ERROR FLAG QSKA35: DEC (R0) ;EITHER SE'S THREAD WORD ADDRESS BEQ TIMB90 ;END OF THREAD: GO CHECK FOR DE-QUEUE CMPB RESET(R1),#377 ;IF MODULE IS FLAGGED... BEQ TIMB16 ;...DON'T EXECUTE IT. DECB TIMBYT(R1) ;COUNT DOWN MODULE'S TIMER BNE TIMB16 ;NOT EXPIRED: GET NEXT MODULE ;TIMER EXPIRED! IT IS MODULE'S TIME. ; SINCE COMPLETION ROUTINES RUN UNDER THE "J" OPTION ASSUME R1 POINTS TO ; THE CURRENT MODULE (IT'S THREA BEQ QSKA20 ;O.K. ADD #2,(R0) ;SEE IF IN "WAIT" TABLE BEQ QSKA30 ;YES: O.K. TO TAKE GOOD EXIT NOW BR QSKA35 ;IN THREAD: TAKE ERROR EXIT QSKA20: ;MODULE READY FOR INSERTION IN TABLE ADD #2,STBPTR ;PUSH TABLE POINTER MOV R0,@STBPTR ;LOAD NEW MODULE INTO TABLE QSKA30: CLR 6(SP) ;NOW READY TO EXIT. CLEAR ERROR FLAG QSKA35: DEC (R0) ;EVIOUS CPU LEVEL MOV 4(R0),-(SP) ;STACK MODULE'S DATE WORD FOR... JSR PC,UNPACK ;...CALL TO SPREAD IT ON STACK TST (SP) ;IF "DATE" = 0,... BNE SKNA20 MOVB MDAY,(SP) ;...THEN USE TODAY'S DATE SKNA20: CMP 2(SP),#37 ;IF "HOUR" IS ALL ONES... BNE SKNA30 MOVB HOUR,2(SP) ;...THEN USE CURRENT HOUR SKNA30: CMP 4(SP),#77 ;IF "MIN" IS ALL ONES... BNE SKNA40 TS T/W = -1 TO SHOW IN "WAIT" ;...OR RESTORES T/W TO ORIGINAL, IF NOT THREADED QSKA40: MOV (SP)+,R0 ;RESTORE USER'S RTI ;RESTORE USER'S PS & RETURN .PAGE DQSKED: ;SYSTEM SUBROUTINE TO DE-QUEUE A SCHEDULER MODULE MOV (SP),-(SP) ;RE-ORDER STACK FOR "RTI" RETURN AT END MOV PS,2(SP) ;STACK NOW READY FOR "RTI" JSR R5,PUSHR ;PUSH ALL REGS ONTO STACK MOV 20(SP)D WORD), R1 MUST BE PRESERVED AS SUCH ; UNTIL THE POSSIBLE ROUTINE IS RUN. BUT TWO OTHER POINTERS ARE NEEDED: ; R3 MOVES DOWN THE MODULE TO COMPENSATE FOR OPTIONAL PARAMTERS WHICH ; MAKE THE LIST LONGER, AND R5 IS RESET TO POINT TO THE UPSTREAM MODULE ; IN CASE THE CURRENT MODULE IS A "ONE-SHOT" AND IS REMOVED FROM THE ; THREAD. R1 IS LOADED FROM R5 AT THE END OF THE LOOP TO ALLOW THIS. MOV R1,R3 ;INIT R3 AS DYNAMIC LIST POINTER MOV R1,R5 ;INIT R5ITHER SETS T/W = -1 TO SHOW IN "WAIT" ;...OR RESTORES T/W TO ORIGINAL, IF NOT THREADED QSKA40: MOV (SP)+,R0 ;RESTORE USER'S RTI ;RESTORE USER'S PS & RETURN .PAGE DQSKED: ;SYSTEM SUBROUTINE TO DE-QUEUE A SCHEDULER MODULE MOV (SP),-(SP) ;RE-ORDER STACK FOR "RTI" RETURN AT END MOV PS,2(SP) ;STACK NOW READY FOR "RTI" JSR R5,PUSHR ;PUSH ALL REGS ONTO STACK MOV  MOVB MINUTE,4(SP) ;...THEN USE CURRENT MINUTE .PAGE SKNA40: ;NOW THAT MODULE'S TIME IS READY, BEGIN SEARCH FOR ITS ;PLACE IN ONE OF THE TWO SCHEDULER THREADS. MOV CURTHD,R1 ;POINTS TO [THDTAB] OR [THDTAB+2] CMPB (SP),MDAY ;MODULE DATE :: TODAY'S DATE BGT SKNA60 ;AFTER TODAY: USE CURRENT THREAD BLT SKNA50 ;BEFORE TODAY: USE "FUTURE" THREAD CMPB 2(SP),HOUR ,R0 ;MODULE'S ADDRESS MOV #340,PS ;LOCK OUT INTERFERENCE FROM SCHEDULER CMP #1,(R0) ;HAS MODULE BEEN DE-QUEUED ALREADY? BEQ DQSK20 ;YES: INACTIVE,SO IGNORE CMP #-1,(R0) ;IS IT STILL IN "WAIT" TABLE? BEQ DQSK50 ;YES: GO SET THE "D" FLAG MOV #2,R5 ;INIT COUNTER TO SEARCH BOTH THREADS MOV #TH1BGN,R1 ;START BY SEARCHING THREAD #1 DQSK10: ;LOOP  IN PREP FOR R1 RESET BELOW MOVB RESET(R1),TIMBYT(R1) ;RESET TIMER BYTE BNE TIMB20 ;MODULE IS A REPEATER: LEAVE IN THREAD MOV (R1),(R2) ;"ONE-SHOT": REMOVE FROM THREAD ... BNE TIMB22 ;...BY "BRIDGING". BRANCH IF NOT LAST MOV R2,TLAST(R0) ;BUT UPDATE "LAST" POINTER IF WAS END TIMB22: MOV #1,(R1) ;SET THREAD WORD INACTIVE IN EITHER CASE MOV R2,R5 ;BACK POINTER TO UPSTREAM MO 20(SP),R0 ;MODULE'S ADDRESS MOV #340,PS ;LOCK OUT INTERFERENCE FROM SCHEDULER CMP #1,(R0) ;HAS MODULE BEEN DE-QUEUED ALREADY? BEQ DQSK20 ;YES: INACTIVE,SO IGNORE CMP #-1,(R0) ;IS IT STILL IN "WAIT" TABLE? BEQ DQSK50 ;YES: GO SET THE "D" FLAG MOV #2,R5 ;INIT COUNTER TO SEARCH BOTH THREADS MOV #TH1BGN,R1 ;START BY SEARCHING THREAD #1 DQSK10: ;MODULE HOUR :: CURRENT HOUR BGT SKNA60 ;LATER TODAY: USE CURRENT THREAD BLT SKNA50 ;WAS EARLIER TODAY: PUT IN "FUTURE" CMPB 4(SP),MINUTE ;MODULE MINUTE :: CURRENT MINUTE BGE SKNA60 ;NOW OR WITHIN HOUR: CURRENT THREAD SKNA50: TST (R1)+ ;WE ARE PAST MODULE'S TIME: USE "FUTURE" SKNA60: ;NOW THAT PROPER THREAD BEGIN WORD'S ADDRESS IS IN R1, ;WE CAN BEGIN SEARCH OF THAT THREAD. RETURN POINT FOR THREAD SEARCH MOV R1,R2 ;COPY ADDRESS OF UPSTREAM MODULE MOV (R1),R1 ;GET DOWNSTREAM MODULE'S ADDRESS BEQ DQSK40 ;END OF THREAD CMP R0,R1 ;IS THIS THE MODULE WE ARE LOOKING FOR? BNE DQSK10 ;NO MOV (R1),(R2) ;YES: "BRIDGE" OVER THIS MODULE IN THREAD MOV #1,(R1) ;...AND SET T/W = 1 TO SHOW INACTIVE DQSK20: ;HERE UPON SUCCESSFUL DEDULE TIMB20: MOV R4,PS ;UNLOCK INTERRUPTS: SAFE NOW MOVB OPTION(R3),R2 ;GET OPTION BYTE FOR THIS MODULE TSTB TASKNO(R3) ;IS MODULE TASK-RELATED? BEQ TIMB54 ;NO: CHECK FOR OTHER OPTIONS ;YES: SET UP STACK FOR CALL TO EITHER ;[SUSPEND] OR [QUEUE] MOVB TASKNO(R3),-(SP);PUSH TASK # FIRST CLR -(SP) ;IMMEDIATE RETURN REQUEST FOR BOTH, OR  ;LOOP RETURN POINT FOR THREAD SEARCH MOV R1,R2 ;COPY ADDRESS OF UPSTREAM MODULE MOV (R1),R1 ;GET DOWNSTREAM MODULE'S ADDRESS BEQ DQSK40 ;END OF THREAD CMP R0,R1 ;IS THIS THE MODULE WE ARE LOOKING FOR? BNE DQSK10 ;NO MOV (R1),(R2) ;YES: "BRIDGE" OVER THIS MODULE IN THREAD MOV #1,(R1) ;...AND SET T/W = 1 TO SHOW INACTIVE DQSK20: ;HERE UPON SUCCE MOV (R1),R2 ;ADDR OF ONE OF THE THREAD-BEGIN WORDS BR SKNB00 ;ENTER LOOP FOR FIRST TIME SKNB10: ;THIS IS THE LOOP RETURN POINT AS LONG AS SEARCH CONT'S ADD #6,SP ;POP STACK POINTER FROM "UNPACK" BELOW SKNB00: ;HERE FOR FIRST-TIME ENTRY MOV R2,R1 ;SAVE OLD T/W ADDRESS MOV (R2),R2 ;GET NEXT MODULE'S (T/W) ADDRESS BEQ SKNB30 ;AT END OF THREAD -QUEUE CLR 20(SP) ;ERROR RETURN STATUS: O.K. DQSK30: ;HERE FOR GENERAL EXIT FROM ROUTINE JSR R5,POPR ;POP REGS FROM STACK RTI ;RETURN SET ABOVE: RESTORE ORIGINAL CPU STATUS & RETURN DQSK40: ;HERE WHEN END OF THREAD REACHED MOV #TH2BGN,R1 ;SET UP FOR POSSIBLE SEARCH OF THREAD #2 DEC R5 ;LOOP COUNTER BNE DQSK10 ;STILL MUST DO THREAD #2 BR DQSK30  ;INIT OF PRIORITY IF NEEDED FOR [QUEUE]. TSTB R2 ;IS "SUSPEND" OPTION SELECTED? BPL TIMB30 ;NO: GO DO QUEUEING JSR PC,UNSPND ;CALL TO "UN-SUSPEND" BR TIMB50 ;GO POP ERROR WORD & CHECK FLAG OPTION TIMB30: ;HERE TO QUEUE A TASK. TASK # AND RETURN CODE ;(OR INITED PRIORITY) ALREADY PUSHED ONTO STACK. .IFNZ DPRTY ;DYNAMIC PRIORITIES OPTION SSFUL DE-QUEUE CLR 20(SP) ;ERROR RETURN STATUS: O.K. DQSK30: ;HERE FOR GENERAL EXIT FROM ROUTINE JSR R5,POPR ;POP REGS FROM STACK RTI ;RETURN SET ABOVE: RESTORE ORIGINAL CPU STATUS & RETURN DQSK40: ;HERE WHEN END OF THREAD REACHED MOV #TH2BGN,R1 ;SET UP FOR POSSIBLE SEARCH OF THREAD #2 DEC R5 ;LOOP COUNTER BNE DQSK10 ;STILL MUST DO THREAD #2 BR DQ ;NOT @ END: TEST MODULE FOR TIME MOV 4(R2),-(SP) ;STACK TEST MODULE'S DATE WORD... JSR PC,UNPACK ;...FOR CALL TO SPREAD IT ON STACK CMP 6(SP),(SP) ;NEW MOD'S DATE :: TEST MOD'S DATE BGT SKNB10 ;LATER: KEEP LOOKING BLT SKNB20 ;EARLIER: THREAD NOW CMP 10(SP),2(SP) ;NEW MOD'S HOUR :: TEST MOD'S HOUR BGT SKNB10 ;STILL LATER BLT SKNB20 ;EARLIER  ;SEARCH FAIL: EXIT WITH NON-ZERO ERROR DQSK50: ;HERE WHEN MODULE STILL IN WAIT" TABLE. MUST SET THE ; "D" DE-QUEUE FLAG IN MODULE TO FORCE IGNORE WHEN ; "SKNSRT" RUNS. IF MODULE IS QUEUED AGAIN BEFORE ; "SKNSRT" RUNS, THIS "D" FLAG WILL BE CLEREAD, AND MODULE ; WILL BE LEFT IN THE "WAIT" TABLE. BIS #10000,2(R0) ;SET "D" FLAG IN MODULE OPTION BYTE BR DQSK20 ;TAKE GOOD EXIT COUNTR:  CLR -(SP) ;USE SYSTEM-ASSIGNED PRIORITY ; (ACTUALLY LEAVES ZERO AS PRIORITY AND PUSHES NEW RETURN CODE OF ZERO, ; POSSIBLY INITING STACK SPACE FOR PASSED ARGUMENT, IF OPTION IS ON.) .ENDC DPRTY .IFNZ ARG ;SYSTEM OPTION TO PASS ARGUMENT ON QUEUE BIT #100,R2 ;DOES MODULE HAVE AN ARGUMENT TO PASS? BEQ TIMB40 ;NO MOV @TIMARG(R3),(SP);YES: REPLACE THE ZERO WITH ACTUAL ARG TIMB40: CLR -(SP) SK30 ;SEARCH FAIL: EXIT WITH NON-ZERO ERROR DQSK50: ;HERE WHEN MODULE STILL IN WAIT" TABLE. MUST SET THE ; "D" DE-QUEUE FLAG IN MODULE TO FORCE IGNORE WHEN ; "SKNSRT" RUNS. IF MODULE IS QUEUED AGAIN BEFORE ; "SKNSRT" RUNS, THIS "D" FLAG WILL BE CLEREAD, AND MODULE ; WILL BE LEFT IN THE "WAIT" TABLE. BIS #10000,2(R0) ;SET "D" FLAG IN MODULE OPTION BYTE BR DQSK20 ;TAKE GOOD EXIT  CMP 12(SP),4(SP) ;COMPARE MINUTES BGT SKNB10 .PAGE SKNB20: ;HAVE FINALLY FOUND SLOT FOR NEW MODULE. R1 CONTAINS ;ADDR OF PREVIOUS OR "UPSTREAM" MODULE (MIGHT BE THE ;THREAD START WORD) AND R2 CONTAINS ADDR OF DOWNSTREAM ;MODULE, OR ZERO IF NEW MODULE IS BEING PLACED AT END ;OF THREAD. R0 CONTAINS ADDR OF NEW MODULE. ADD #6,SP ;POP SP FROM 1ST CALL TO "UNPACK" SKNB30: AD.WORD 0 ;THIS IS THE ABORT/TIME-SLICE COUNTER!! ABMPLR: .WORD 0 ;MULTIPLIER FOR ABORT AND TIME/SLICE CURTHD: .WORD THDTAB ;POINTER TO CURRENT THREAD BEGIN WORD THDTAB: .WORD TH1BGN ;THREAD BEGIN TABLE .WORD TH2BGN .WORD TH1BGN TH1BGN: .WORD 0 ;ACTUAL BEGIN OF THREAD #1 TH2BGN: .WORD 0 ;#2 STBPTR: .WORD SWAITB ;SCHEDULER "WAIT" TABLE POINTER SWAITB: .WORD 0 ;T ;MUST PUSH RETURN CODE SINCE ARGUMENT .ENDC ARG ;USED UP LAST ONE. JSR PC,QUEUE ;CALL QUEUE TIMB50: ;HERE AFTER [QUEUE] OR [UNSPND] TST (SP)+ ;POP ERROR RETURN CODE TIMB54: ;HERE WHEN NOT TASK-RELATED ASLB R2 ;MOVE "ARG" OPTION INTO SIGN BIT BPL TIMB56 ;"A" NOT SET TST (R3)+ ;PASS POINTER OVER ARG, WHETHER USED OR NOT TIMB56: ASLB COUNTR: .WORD 0 ;THIS IS THE ABORT/TIME-SLICE COUNTER!! ABMPLR: .WORD 0 ;MULTIPLIER FOR ABORT AND TIME/SLICE CURTHD: .WORD THDTAB ;POINTER TO CURRENT THREAD BEGIN WORD THDTAB: .WORD TH1BGN ;THREAD BEGIN TABLE .WORD TH2BGN .WORD TH1BGN TH1BGN: .WORD 0 ;ACTUAL BEGIN OF THREAD #1 TH2BGN: .WORD 0 ;#2 STBPTR: .WORD SWAITB ;SCHEDULER "WAIT" TABLE POINTER SWAITB: .WORD 0 D #6,SP ;POP SP FROM 2ND CALL TO "UNPACK" MOV R0,(R1) ;LOAD UPSTREAM THREAD-WORD FOR NEW MOD MOV R2,(R0) ;LOAD NEW T/W FOR DOWNSTREAM MOD BR SKNSRT ;GO BACK FOR POSSIBLE MORE MODULES. .PAGE ; ******************************************************************** ; * PROGRAM IDENTIFICATION: "QSKED" * ; * SYSTEM SUBROUTINE TO QUEUE A SCHEDULER MODULE * ; * OP OF "WAIT" STACK IS ALWAYS ZERO .=$SWATZ*2+. ;THE SCHEDULER "WAIT" TABLE SKTBND = .-2 ;END OF "WAIT" TABLE DAYTAB = .-1 ;THIS IS THE 12-BYTE TABLE OF DAYS-PER-MONTH JANARY = . FEBARY = .+1 .BYTE 31.,28.,31.,30.,31.,30.,31.,31.,30.,31.,30.,31. .EVEN CLOCK: ;EXTERNAL REFERENCE FOR TIME-OF-DAY CLOCK AND CALENDAR TICTOC: .BYTE 0 ;COUNTS CLOCK BEATS PER SECOND SECOND: .BYTE 0 ;C R2 ;GET "FLAG" OPTION BIT INTO SIGN BPL TIMB60 ;NO FLAG OPTION BISB TIMASK(R3),@TMFLAG(R3) ;"IOR" MASK INTO FLAG LOCATION CMP (R3)+,(R3)+ ;BUMP SECONDARY MODULE POINTER FOR FLAGS TIMB60: ASLB R2 ;GET "J" OPTION BIT INTO SIGN BPL TIMB70 ;NOT SELECTED JSR PC,@JSTARG(R3) ;LINK TO USER RTNE. (R1)= MODULE BEGIN TIMB70: MOV R5,R1 ;RESET MODULE POINTER (SEE EXPLN. AB ;TOP OF "WAIT" STACK IS ALWAYS ZERO .=$SWATZ*2+. ;THE SCHEDULER "WAIT" TABLE SKTBND = .-2 ;END OF "WAIT" TABLE DAYTAB = .-1 ;THIS IS THE 12-BYTE TABLE OF DAYS-PER-MONTH JANARY = . FEBARY = .+1 .BYTE 31.,28.,31.,30.,31.,30.,31.,31.,30.,31.,30.,31. .EVEN CLOCK: ;EXTERNAL REFERENCE FOR TIME-OF-DAY CLOCK AND CALENDAR TICTOC: .BYTE 0 ;COUNTS CLOCK BEATS PER SECOND SECOND: .BYTE 0  * ; * PURPOSE: * ; * PUTS ADDRESS OF CALLER'S MODULE IN INTERNAL STACK. * ; * THIS TABLE IS EMPTIED BY THE ROUTINE "SKNSRT" WHICH IS * ; * CALLED BY THE SCHEDULER EACH MINUTE JUST BEFORE IT RUNS* ; * THIS METHOD AVOIDS QUEUEING AND SCHEDULER CONFLICTS WHE* ; * ACCESSING THE TWO SCHEDULER THREADS(THE SCHEDULER DROPS*URRENT TIME MINUTE: .BYTE 0 ;CURRENT TIME HOUR: .BYTE 0 ;CURRENT TIME JDATE: .WORD 1 ;CURRENT JULIAN DATE MONTH: .BYTE 1 ;CURRENT MONTH MDAY: .BYTE 1 ;CURRENT DAY OF MONTH YEAR: .BYTE 71. ;CURRENT YEAR (MINUS 1900) SKDBSY: .BYTE -1 ;SCHEDULER BUSY FLAG: IDLE=-1; .END OVE) BR TIMB15 ;LOOP BACK FOR MORE MODULES .PAGE TIMB90: ;HERE AT END OF A RESOLUTION THREAD MOVB (PC),CURRES ;KILL "CURRENT RESOLUTION" @ THREAD END TST DQFLAG ;DID "DQTIME" REQUEST ANY DURING THREAD? BEQ TIMA35 ;NO: NO CHECK NECESSARY. GET NEXT RES'N MOV #TFIRST,R1 ;IS NECESSARY TO RE-TRAVEL THREAD ADD R0,R1 ;PROPER THREAD START WORD MOV R1,R ;CURRENT TIME MINUTE: .BYTE 0 ;CURRENT TIME HOUR: .BYTE 0 ;CURRENT TIME JDATE: .WORD 1 ;CURRENT JULIAN DATE MONTH: .BYTE 1 ;CURRENT MONTH MDAY: .BYTE 1 ;CURRENT DAY OF MONTH YEAR: .BYTE 71. ;CURRENT YEAR (MINUS 1900) SKDBSY: .BYTE -1 ;SCHEDULER BUSY FLAG: IDLE=-1; .END  ; * THE CPU LEVEL SO AS NOT TO LOCK OUT INTERRUPTS UNNECES-* ; * SARILY), REDUCING THE CONFLICT AREA TO JUST THE FIFO * ; * TABLE. THIS CONFLICT IS AVOIDED, THEN, BY RUNNING * ; * "QSKED" (A SHORT ROUTINE) AND THE FEW WORDS OF CODE * ; * IN "SKNSRT" WHICH ACCESS THE TABLE, UNDER INTERRUPT- * ; * LOCKOUT. * ; * 2 ;REMEMBER UPSTREAM WORD TIMB92: MOV (R1),R1 ;NEXT MODULE'S ADDRESS BEQ TIMA35 ;THREAD'S END: CAN NOW EXIT CMP 5(R1),#377 ;WAS THIS MODULE FLAGGED? BNE TIMB92 ;NO: KEEP LOOKING MOV (R1),(R2) ;FOUND ONE! BRIDGE OVER DE-QUEUED MODULE BNE TIMB94 ;NOT FINAL IN THREAD MOV R2,TLAST(R0) ;WAS END MODULE: UPDATE "LAST" POINTER TIMB94: MOV #1,(R1) ;SET THREA * ; * USAGE: * ; * USERS CAN CALL "QSKED" EITHER VIA JSR (IF LINKED) OR * ; * VIA EMT. IN EITHER CASE THE ADDRESS OF THE MODULE TO BE* ; * THREADED MUST FIRST BE PLACED ON THE STACK.THE STACK * ; * POINTER IS LEFT UNCHANGED ON RETURN. THE STACK LOCATION* ; * ITSELF WILL BE CLEARED IF THE TABLE HAS ROOM FOR * ; * IT AND THE MODULE ITSELF IS INACTIVE (ITD-WORD INACTIVE DEC DQFLAG ;ANY MORE TO FIND? BGT TIMB92 ;YES: KEEP LOOKING BR TIMA35 ;DONE: EXIT EARLY TIMEXT: ;EXIT POINT FOR [TIMER] MOV #TFIRST,R0 ;PREPARE TO SCAN LIST OF "FIRST" WORDS MOV #$NRES,R1 ;LIST SIZE MOV #340,PS ;LOCK OUT PULSE DURING EXIT SEQUENCE TIMEX1: TST (R0)+ ;IF ANY IS NON-ZERO... BNE TIMEX2 ;...S THREAD WORD * ; * MUST BE =1). IN CASE OF ONE OF THE ABOVE ERRORS, THE * ; * STACK LOCATION IS LEFT UNCHANGED (NON-ZERO) FOR TESTING* ; * BY THE CALLER. * ; * "QSKED" SAVES & RESTORES ALL REGISTERS THAT IT USES. * ; * IT MAY BE CALLED BY ANY TYPE OF USER AT ANY TIME. * ; * * ; * G U L F E L E C T R O N I C DON'T TURN OFF CLOCK DEC R1 ;BE SURE TO DO WHOLE LIST BNE TIMEX1 TST @TTBPTR ;CHECK FOR EMPTY "WAIT" LIST BNE TIMEX2 ;NOT EMPTY: LEAVE CLOCK ON BIC #C1CBIT,C1COMD ;NO MODULES ACTIVE: KILL INTERRUPT TIMEX2: DECB TIMBSY ;NESTING "BUSY" COUNTER BGE TIMA15 ;NORMALLY RESIDES @ ZERO DURING ROUTINE ;EXECUTION. GOES ABOVE IF ADDITIONAL S Y S T E M S * ; ******************************************************************** .PAGE QSKED: ;SUBROUTINE TO QUEUE A SCHEDULER MODULE ;TO WAIT FOR INSERTION INTO ONE OF THE ;TWO SCHEDULER THREADS MOV (SP),-(SP) ;MOVE RETURN ADDRESS UP FOR RTI LATER MOV PS,2(SP) ;...AND SET UP PS FOR RTI, TOO MOV R0,-(SP) ;SAVE USER'S MO ;OCCASIONS TO ENTER ROUTINE HAVE ;OCCURRED DURING EXECUTION. IN THIS ;CASE ROUTINE IS RE-EXECUTED IMMEDIATELY ;IN AN ATTEMPT TO RE-SYNCHRONIZE JMP RESTOR ;NORMAL RETURN TO INTERRUPTED PROGRAM .PAGE TTBPTR: .WORD TWAITB ;TIMER TABLE POINTER TO "WAIT" STACK TWAITB: .WORD 0 ;FIRST LOC'N OF "WAIT" TABLE IS ALWAYS 0 V #340,PS ;RAISE CPU LEVEL TO AVOID INTERFERENCE CMP STBPTR,#SKTBND ;IS TABLE FULL? BLOS QSKA40 ;YES: POINTER IS AT BOTTOM, SO ERROR XIT MOV 6(SP),R0 ;MODULE'S ADDRESS BIC #10000,2(R0) ;CLEAR "D" FLAG IN CASE WAS DE-QUEUED DEC (R0) ;IS MODULE INACTIVE (THREAD WORD = 1)? BEQ QSKA20 ;O.K. ADD #2,(R0) ;SEE IF IN "WAIT" TABLE BEQ QSKA30  .=$TWATZ*2+. ;RESERVE SPACE FOR TABLE TMTBND = .-2 ;ADDRESS OF LAST TALBE LOCATION TFIRST: ;TABLE OF POINTERS TO FIRST MODULE IN ;EACH RESOLUTION'S THREAD. CONTAIN ZERO ;WHEN THREAD IS EMPTY. .WORD ,,,,,,,,,,,,,,, ;MAX TABLE SIZE: 16 WORDS .=$NRES*2+TFIRST ;ACTUAL TABLE SIZE = [$NRES] WORDS TLAST: ;TABLE OF POINTERS TO LA ;YES: O.K. TO TAKE GOOD EXIT NOW BR QSKA35 ;IN THREAD: TAKE ERROR EXIT QSKA20: ;MODULE READY FOR INSERTION IN TABLE SUB #2,STBPTR ;PUSH TABLE POINTER MOV R0,@STBPTR ;LOAD NEW MODULE INTO TABLE QSKA30: CLR 6(SP) ;NOW READY TO EXIT. CLEAR ERROR FLAG QSKA35: DEC (R0) ;EITHER SETS T/W = -1 TO SHOW IN "WAIT" ;...OR RESTORES T/W TO ORIGINAL, IF NOT THREADED QSKA40: MOV ST MODULE IN ;EACH RESOLUTION'S THREAD. CONTAIN THE ;ADDRESS OF [TFIRST(R)] WHEN THREAD ;IS EMPTY. .WORD ,,,,,,,,,,,,,,, ;MAX TABLE SIZE: 16 WORDS .=$NRES*2+TLAST ;ACTUAL TABLE SIZE = [$NRES] WORDS .PAGE RESTAB: ;RESOLUTION COUNTER TABLE: PERMANENT .BYTE RES0,RES1,RES2,RES3,RES4,RES5,RES6,RES7,RES8 .BYTE RES9,RES10,RES11(SP)+,R0 ;RESTORE USER'S RTI ;RESTORE USER'S PS & RETURN .PAGE DQSKED: ;SYSTEM SUBROUTINE TO DE-QUEUE A SCHEDULER MODULE MOV (SP),-(SP) ;RE-ORDER STACK FOR "RTI" RETURN AT END MOV PS,2(SP) ;STACK NOW READY FOR "RTI" JSR R5,PUSHR ;PUSH ALL REGS ONTO STACK MOV 20(SP),R0 ;MODULE'S ADDRESS MOV #340,PS ;LOCK OUT INTERFERENCE FROM SCHEDULER CMP ,RES12,RES13,RES14,RES15 .=RESTAB+$NRES ;SET TO ACTUAL TABLE SIZE .BYTE 0 ;END BYTE CURTAB: .BYTE RES0,RES1,RES2,RES3,RES4,RES5,RES6,RES7,RES8 .BYTE RES9,RES10,RES11,RES12,RES13,RES14,RES15 .=CURTAB+$NRES ;SET TO ACTUAL TABLE SIZE TIMBSY: .BYTE 0 ;FLAG & NESTING COUNTER FOR [TIMER] BASCNT: .BYTE 0 ;OPTIONAL SUB-RESOLUTION PULSE COUNTER CURRES: .BYTE 0 ;CURRENT RES #1,(R0) ;HAS MODULE BEEN DE-QUEUED ALREADY? BEQ DQSK20 ;YES: INACTIVE,SO IGNORE CMP #-1,(R0) ;IS IT STILL IN "WAIT" TABLE? BEQ DQSK50 ;YES: GO SET THE "D" FLAG MOV #2,R5 ;INIT COUNTER TO SEARCH BOTH THREADS MOV #TH1BGN,R1 ;START BY SEARCHING THREAD #1 DQSK10: ;LOOP RETURN POINT FOR THREAD SEARCH MOV R1,R2 ;COPY ADDRESS OF UPSTREAM MODULE MOV OLUTION WHEN "TIMER" ACTIVE .EVEN DQFLAG: .WORD 0 ;# OF MODULES REQUESTED TO BE DE-QUEUED ;ON CURRENT RESOLUTION WHILE ACTIVE IN "TIMER" .END (R1),R1 ;GET DOWNSTREAM MODULE'S ADDRESS BEQ DQSK40 ;END OF THREAD CMP R0,R1 ;IS THIS THE MODULE WE ARE LOOKING FOR? BNE DQSK10 ;NO MOV (R1),(R2) ;YES: "BRIDGE" OVER THIS MODULE IN THREAD MOV #1,(R1) ;...AND SET T/W = 1 TO SHOW INACTIVE DQSK20: ;HERE UPON SUCCESSFUL DE-QUEUE CLR 20(SP) ;ERROR RETURN STATUS: O.K. DQSK30: ;HERE FOR GENERAL EXIT FROM ROUTINE JSR R5,POPR ;POP REGS FROM STACK RTI ;RETURN SET ABOVE: RESTORE ORIGINAL CPU STATUS & RETURN DQSK40: ;HERE WHEN END OF THREAD REACHED MOV #TH2BGN,R1 ;SET UP FOR POSSIBLE SEARCH OF THREAD #2 DEC R5 ;LOOP COUNTER BNE DQSK10 ;STILL MUST DO THREAD #2 BR DQSK30 ;SEARCH FAIL: EXIT WITH NON-ZERO ERROR DQSK50: ;HERE WHEN MODULE STILL IN WAIT" TABLE. MUST SET THE ; "D" DE-QUEUE FLAG IN MODULE TO FORCE IGNORE WHEN ; "SKNSRT" RUNS. IF MODULE IS QUEUED AGAIN BEFORE ; "SKNSRT" RUNS, THIS "D" FLAG WILL BE CLEREAD, AND MODULE ; WILL BE LEFT IN THE "WAIT" TABLE. BIS #10000,2(R0) ;SET "D" FLAG IN MODULE OPTION BYTE BR DQSK20 ;TAKE GOOD EXIT COUNTR: .WORD 0 ;THIS IS THE ABORT/TIME-SLICE COUNTER!! ABMPLR: .WORD 0 ;MULTIPLIER FOR ABORT AND TIME/SLICE CURTHD: .WORD THDTAB ;POINTER TO CURRENT THREAD BEGIN WORD THDTAB: .WORD TH1BGN ;THREAD BEGIN TABLE .WORD TH2BGN .WORD TH1BGN TH1BGN: .WORD 0 ;ACTUAL BEGIN OF THREAD #1 TH2BGN: .WORD 0 ;#2 STBPTR: .WORD SWAITB ;SCHEDULER "WAIT" TABLE POINTER SWAITB: .WORD 0 ;TOP OF "WAIT" STACK IS ALWAYS ZERO .=$SWATZ*2+. ;THE SCHEDULER "WAIT" TABLE SKTBND = .-2 ;END OF "WAIT" TABLE DAYTAB = .-1 ;THIS IS THE 12-BYTE TABLE OF DAYS-PER-MONTH JANARY = . FEBARY = .+1 .BYTE 31.,28.,31.,30.,31.,30.,31.,31.,30.,31.,30.,31. CLOCK: ;EXTERNAL REFERENCE FOR TIME-OF-DAY CLOCK AND CALENDAR TICTOC: .BYTE 0 ;COUNTS CLOCK BEATS PER SECOND SECOND: .BYTE 0 ;CURRENT TIME MINUTE: .BYTE 0 ;CURRENT TIME HOUR: .BYTE 0 ;CURRENT TIME JDATE: .WORD 0 ;CURRENT JULIAN DATE MONTH: .BYTE 0 ;CURRENT MONTH MDAY: .BYTE 0 ;CURRENT DAY OF MONTH YEAR: .BYTE 0 ;CURRENT YEAR (MINUS 1900) SKDBSY: .BYTE -1 ;SCHEDULER BUSY FLAG: IDLE=-1; .END