; This file contains the basics needed to write a JOB device handler. ; It should be .INSERTed by the file containing the device specific code. ; It defines that startup code, a few .CALL blocks, a stack, an ; interrupt handler, etc. For full details, see the PTDD on the ; JOB device. ; The file containing the device specific code must supply the following: ; STOPER an eight word table. Entry i contains the address ; of the code that handles op-code i. If a particular ; op-code is not handled, put the address BADOP in its ; table slot. ; CALCNT a variable whose value is set (via ==) to the total ; number of .CALL names that the handler knows about. ; CALNAM a table CALCNT words long. Entry i contains the sixbit ; name of a .CALL operation. ; CALXCT a table CALCNT words long. Entry i contains the address ; of the code that handles the operation whose name is ; given in in slot i of CALNAM. ;AC DEFS A=1 B=2 C=3 D=4 E=5 TT=6 I=7 Q=10 J=11 R=12 W=13 H=14 P=15 ;DO NOT CHANGE! ;PDL POINTER T=16 ;" U=17 ;" ;USER INDEX BOJC==1 XXXX==. LOC 42 JSR TSINT LOC XXXX PAT: PATCH: BLOCK 20 LPDLL=100 PDLPTR: -LPDLL,,PDL PDL: BLOCK LPDLL INTOP: 0 ; PLACE TO GET OP-CODE AT INTERRUPT LEVEL ; JOBGET AREA AND JOBGET FOR MAIN PROGRAM LEVEL WD1: 0 WD2: 0 WD3: 0 WD4: 0 WD5: 0 WD6: 0 WD7: 0 WD8: 0 WD9: 0 WD10: 0 WD11: 0 WD12: 0 WD13: 0 RET=2000,,0 IJGET: SETZ ; GET OPERATOR WORD ONLY SIXBIT/JOBCAL/ 1000,,BOJC SETZM INTOP JGET: SETZ ; GET ALL INFO ABOUT LAST JOB I/O OP SIXBIT/JOBCAL/ 1000,,BOJC RET WD1 SETZ [-12.,,WD2] JRET: SETZ ; UNHANG LAST JOB I/O OP SIXBIT/JOBRET/ 1000,,BOJC H SETZ I RETBLK: REPEAT 8.,0 JIOC: SETZ ; GIVE JOB USER AN I/O CHANNEL ERROR SIXBIT/SETIOC/ 1000,,BOJC SETZ I JINT: SETZ ; GIVE JOB USER AN I/O INTERRUPT SIXBIT/JOBINT/ 401000,,BOJC JSTAT: SETZ ; CHANGE STATUS OF JOB USER'S CHANNEL SIXBIT/JOBSTS/ 1000,,BOJC SETZ H START: JFCL ; LEAVE PLACE TO PUT .VALUE FOR DEBUGGING .SUSET [.SMASK,,[1_10]] ; ENABLE IOCERR INTERRUPT .SUSET [.SMSK2,,[1_BOJC]] ; ENABLE CHANNEL INTERRUPT .OPEN BOJC,[17,,(SIXBIT/BOJ/)] ; OPEN CHANNEL JRST CLOSE ; CAN'T START1: MOVE P,PDLPTR ; RESET PDL SETOM HNGFLG ; SET NOT HUNG LOOP: MOVEI A,GOTOPR ; NO IOT IN PROGRESS MOVEM A,INIOT ; MAKE INTERRUPTS GO AFTER HANG SETZM INTSW ; INTERRUPTS SHOULD NEVER BE LOCKED OUT HERE SKIPN HNGFLG ; SEE IF HUNG .HANG ; YES - WAIT UNTIL NOT GOTOPR: SETZM HNGFLG MOVE P,[-LPDLL-1,,PDL-1] ; RESET PDL IN CASE SOMEBODY INTERRUPTED MOVEI A,LOOP ; NO IOT IN PROGRESS MOVEM A,INIOT ; MAKE INTERRUPTS ABORT OPERATION .CALL JGET ; GET INFO FOR CALL JRST CHKOPN ; FAILED - IGNORE LDB A,[370200,,WD1] ; SEE IF CLOSE BITS SET JUMPN A,CLOSE ; YES - GO CLOSE LDB A,[000400,,WD1] ; GET OP CODE CAIGE A,10 ; .CALL? JRST @STOPER(A) ; STANDARD OPERATOR - GO PROCESS MOVE A,WD2 ; GET SIXBIT OF .CALL NAME SKIPL B,[-CALCNT,,0] ; GET POINTER TO NAMES WE KNOW ABOUT JRST BADOP ; IF CALCNT=0, THEN NO .CALLS HANDLED CAMN A,CALNAM(B) JRST @CALXCT(B) ; FOUND IT - GO EXECUTE THE RIGHT CODE AOBJN B,.-2 ; NO - KEEP LOOKING BADOP: HRLZI H,12 ; SET "MODE NOT AVAILABLE" FOR ILLEGAL OPS SETZM I ; NO RETURNS .CALL JRET ; MAKE HIM CONTINUE W/O SKIPPING JFCL ; DON'T CARE IF HE HAS QUIT JRST LOOP ; DON'T DIE FOR THAT CHKOPN: SKIPE IFOPEN ; IS THE CHANNEL ALREADY OPEN? JRST LOOP ; YES - STAY IN LOOP UNTIL CLOSE JRST CLOSE ; NO - LET SOMEBODY ELSE HAVE IT CLOSE: .CLOSE BOJC, ; CLOSE THE CHANNEL SKIPE CLSCOD ; DID USER SUPPLY CLOSE ROUTINE? JRST @CLSCOD ; YES - EXEUCUTE IT .LOGOUT .VALUE ; NOTE!! - BECAUSE OF PCLSR HACKING IN THE SYSTEM, INTERRUPTS FROM ; THE JOB USER MUST CAUSE ANY CURRENT OPERATION TO BE ABORTED. IOT'S ; ARE HANDLED IN A SPECIAL WAY TO ALLOW THE BOJ TO RECORD INTERRUPTED ; IOTS THAT WERE HALF COMPLETED. IF YOU WANT SOMETHING TO BE DONE ; WHEN IOTS ARE INTERRUPTED, PUT AN ADDRESS INTO THE WORD "INIOT". ; THE INTERRUPT HANDLER WILL JUMP TO THAT ADDRESS INSTEAD OF DISMISSING. ; THE LAST THING THAT SHOULD BE DONE AT THAT ADDRESS IS THE FOLLOWING: ; .DISMISS [LOOP] TSINT: 0 0 SKIPL TSINT ; IOC INTERRUPT JRST INTIOE ; NO - IOERR INTERRUPT .CALL IJGET ; GET COMMAND INFO JRST TSINT1 ; NONE - DISMISS WITHOUT WAKEUP PUSH P,A ; SAVE A LDB A,[370200,,INTOP] ; GET CLOSE BITS JUMPE A,TSINT0 ; SEE IF CLOSE? SKIPN INTSW ; ARE INTERRUPTS LOCKED OUT? JRST CLOSE ; NO - GO CLOSE RIGHT NOW MOVEI A,1 ; YES - MARK CLOSE WANTED WHEN UNLOCKED MOVEM A,INTSW2 POP P,A .DISMIS TSINT+1 TSINT0: POP P,A ; OTHERWISE - RESTORE A SETOM HNGFLG ; WAKEUP MAIN PROGRAM LEVEL TSINT1: SKIPN INTSW ; BOJ INTERRUPTS LOCKED OUT? .DISMIS INIOT ; NO - DISMISS REGULAR WAY SETOM INTSW2 ; SET INTERRUPT OCCURRED SWITCH .DISMIS TSINT+1 ; CONTINUE INTERRUPTED CODE FOR NOW INTIOE: MOVEI I,3 .CALL JIOC ; SIGNAL IOC ERROR TO USER JFCL MOVEI A,300 ; SLEEP AWHILE TO TRY AVOID STATUS TIMING ERROR .SLEEP A, JRST CLOSE ; DIE ; INTOFF - THIS ROUTINE CAN BE CALLED TO TELL THE INTERRUPT HANDLER ; NOT TO INTERRUPT UNTIL AN INTON IS DONE (INTOFF'S ARE NOT CUMMULATIVE) INTOFF: SKIPG INTSW ; IF NOT LOCKED - FLUSH PENDING STUFF SETZM INTSW2 ; NO PENDING INTERRUPTS AOS INTSW ; BUMP INTERRUPT LOCK COUNT POPJ P, ; INTON - THIS ROUTINE CAN BE CALLED TO TELL THE INTERRUPT HANDLER ; THAT BOJ INTERRUPTS ARE OK AGAIN. ANY INTERRUPT THAT HAS ARRIVED ; SINCE THE INTOFF WILL BE PRESENTED NOW (I.E. INTON WILL NOT RETURN ; TO THE CALLER UNLESS THERE IS NO PENDING INTERRUPT). INTON: PUSH P,A SOSLE INTSW ; DECREMENT INTERRUPT LOCK SWITCH JRST INTON2 ; STILL POSITIVE - STILL LOCKED SETZM INTSW SKIPLE INTSW2 ; DID A CLOSE OCCUR? JRST CLOSE ; YES - CLOSE RIGHT NOW SKIPN INTSW2 ; DID AN INTERRUPT OCCUR? JRST INTON2 ; NO - FORGET IT SETOM HNGFLG ; MAKE SURE HE DOESN'T HANG POP P,A JRST @INIOT ; OK TO PROCESS NOW INTON2: POP P,A ; OTHERWISE RETURN TO CALLER POPJ P, INTSW: 0 ; 0=> BOJ INTERRUPTS OK, -1=>NO BOJ INTERRUPTS INTSW2: 0 ; -1=>BOJ INTERRUPT OCCURRED WHILE LOCKED HNGFLG: 0 IFOPEN: 0 INIOT: START ; INTERRUPTS CAUSE RESTART UNTIL ; MAIN LOOP IS ENTERED THE FIRST TIME CLSCOD: 0