X-Git-Url: https://jxself.org/git/?p=pdp10-muddle.git;a=blobdiff_plain;f=sumex%2Finterr.mcr239;fp=sumex%2Finterr.mcr239;h=b71bf2d3b4345eebec7c861eae5a0514178bb110;hp=0000000000000000000000000000000000000000;hb=1c973408824dee4a587c040bc8075cd1bf047ba3;hpb=a3df309bdd1ea54242d39e62403548d1e4845f8e diff --git a/sumex/interr.mcr239 b/sumex/interr.mcr239 new file mode 100644 index 0000000..b71bf2d --- /dev/null +++ b/sumex/interr.mcr239 @@ -0,0 +1,2261 @@ +TITLE INTERRUPT HANDLER FOR MUDDLE + +RELOCATABLE + +;C. REEVE APRIL 1971 + +.INSRT MUDDLE > + +SYSQ + +IF1,[ +IFE ITS,.INSRT MUDSYS;STENEX > +] + +PDLGRO==10000 ;AMOUNT TO GROW A PDL THAT LOSES +NINT==72. ;MAXIMUM NUMBER OF INTERRUPTS POSSIBLE + +IFN ITS,[ +;SET UP LOCATION 42 TO POINT TO TSINT + +RMT [ + +ZZZ==$. ;SAVE CURRENT LOCATION + +LOC 42 + + JSR MTSINT ;GO TO HANDLER + +LOC ZZZ +] +] + +; GLOBALS NEEDED BY INTERRUPT HANDLER + +.GLOBAL ONINT ; FUDGE INS EXECUTED IF NON ZERO AT START OF INTERRUPT +.GLOBA GCFLG ;TELLS WHETHER OR NOT GARBAGE COLLECTOR IS RUNNING +.GLOBAL GCFLCH ; FLUSH CHARS IMMEDIATE SO GC CAN SEE THEM +.GLOBAL CORTOP ; TOP OF CORE +.GLOBA GCINT ;TELLS GARBAGE COLLECTOR TO SIMULATE AN INTERRUPT +.GLOBAL INTNUM,INTVEC ;TV ENTRIES CONCERNING INTERRUPTS +.GLOBAL AGC ;CALL THE GARBAGE COLLECTOR +.GLOBAL VECNEW,PARNEW,GETNUM ;GC PSEUDO ARGS +.GLOBAL GCPDL ;GARBAGE COLLECTORS PDL +.GLOBAL VECTOP,VECBOT ;DELIMIT VECTOR SPACE +.GLOBAL PURTOP +.GLOBAL PDLBUF ;AMOUNT OF PDL GROWTH +.GLOBAL PGROW ;POINTS TO DOPE WORD OF NEXT PDL TO GROW +.GLOBAL TPGROW ;POINTS TO NEXT MUDDLE PDL TO GROW +.GLOBAL TOPLEV,ERROR%,N.CHNS,CHNL1 +.GLOBAL BUFRIN,CHNL0,SYSCHR ;CHANNEL GLOBALS +.GLOBAL IFALSE,TPOVFL,1STEPR,INTOBL,INCHAR,CURPRI,RDEVIC,RDIREC,GFALS,STATUS +.GLOBAL PSTAT,NOTRES,IOIN2,INAME,INTFCN,CHNCNT,CHANNO,GIBLOK,ICONS,INCONS +.GLOBAL IEVECT,INSRTX,ILOOKC,IPUT,IREMAS,IGET,CSTAK,EMERGE +.GLOBAL MTSINT ;BEGINNING OF INTERRUPT HANDLER +.GLOBAL INTINT ;CALLED BY INITIALIZER TO TAKE CARE OF INT PCS +.GLOBAL FRMSTK,APPLY,CHUNW +.GLOBAL IPCGOT,DIRQ ;HANDLE BRANCHING OFF TO IPC KLUDGERY + +; GLOBALS FOR GC +.GLOBAL GCTIM,GCCAUS,GCCALL + +; GLOBALS FOR MONITOR ROUTINES + +.GLOBAL MONCH,MONCH0,RMONCH,RMONC0,LOCQ,SMON,BAPT,APLQ,MAKACT,NAPT +.GLOBAL PURERR,BUFRIN,INSTAT + +MONITOR + +.GLOBAL MSGTYP,MTYI,UPLO,IFLUSH,OCLOS,ERRET,MASK1,MASK2 ;SUBROUTINES USED +.GLOBAL ERROR,LISTEN,ECHO,RRESET,MTYO,GCHAPN,P.CORE,P.TOP,QUEUES,NOTTY,TTYOP2,TTICHN +.GLOBAL INTHLD,BNDV,SPECBE +;BEGINNING OF ACTUAL INTERRUPT HANDLER (MUST BE IMPURE) + + +;***** TEMP FUDGE ******* + +QUEUES==INTVEC + + +; DECLARATIONS ASSOCIATED WITH INTERRUPT HANDERS AND HEADERS + +; SPECIAL TABLES + +SPECIN: IRP A,,[CHAR,CLOCK,MPV,ILOPR,WRITE,READ,IOC,PURE,SYSDOWN,INFERIOR,RUNT,REALT +PARITY] + MQUOTE A,[A]INTRUP + TERMIN +SPECLN==.-SPECIN + +; TABLE OF SPECIAL FINDING ROUTINES + +FNDTBL: IRP A,,[GETCHN,0,0,0,LOCGET,LOCGET,0,0,0,0,0,0,0] + A + TERMIN + +; TABLE OF SPECIAL SETUP ROUTINES + +INTBL: IRP A,,[S.CHAR,S.CLOK,S.MPV,S.ILOP,S.WMON,S.RMON,S.IOC,S.PURE,S.DOWN,S.INF +S.RUNT,S.REAL,S.PAR] + A + S!A==.IRPCNT + TERMIN + +IFN ITS,[ + +; EXTERNAL INTERRUPT TABLE + +EXTINT: REPEAT NINT-36.,0 + REPEAT 16.,HCHAR + 0 + 0 + REPEAT 8.,HINF + REPEAT NINT-62.,0 +EXTEND: + +IRP A,,[[HCLOCK,13.],[HMPV,14.],[HILOPR,6],[HIOC,9],[HPURE,26.],[HDOWN,7],[HREAL,35.] +[HRUNT,34.],[HPAR,28.]] + IRP B,C,[A] + LOC EXTINT+C + B + .ISTOP + TERMIN +TERMIN + + +LOC EXTEND +] + +IFE ITS,[ + +; TABLES FOR TENEX INTERRUPT SYSTEM + +LEVTAB: P1 ; POINTS TO INT PC HOLDERS FOR LEVS 1,2 AND 3 + P2 + P3 + +CHNMSK==0 ; WILL BE MASK WORD FOR INT SET UP +MFORK==400000 +NNETS==10. ; ALLOW 10 NETWRK INTERRUPTS +NETCHN==36.-NNETS + +CHNTAB: ; LOCATION OF INT ROUTINES FOR VARIOUS "CHANNELS" + BLOCK 36.-NNETS ; THERE AR 36. TENEX INT CHANNELS + +REPEAT NNETS, 1,,INTNET+3*.RPCNT + +IRP A,,[[0,CNTLG],[1,CNTLS],[9.,TNXPDL]] + IRP B,C,[A] + LOC CHNTAB+B + 1,,C + CHNMSK==CHNMSK+<1_<35.-B>> + .ISTOP + TERMIN +TERMIN +LOC CHNTAB+36. + +EXTINT: BLOCK NINT-NNETS + +REPEAT NNETS,HNET + +IRP A,,[[HCNTLG,36.],[HCNTLS,37.]] + IRP B,C,[A] + LOC EXTINT+C + B + .ISTOP + TERMIN +TERMIN +LOC EXTINT+NINT +] + + +; HANDLER/HEADER PARAMETERS + +; HEADER BLOCKS + +IHDRLN==4 ; LENGTH OF HEADER BLOCK + +INAME==0 ; NAME OF INTERRUPT +ISTATE==2 ; CURRENT STATE +IHNDLR==4 ; POINTS TO LIST OF HANDLERS +INTPRI==6 ; CONTAINS PRIORITY OF INTERRUPT + +IHANDL==4 ; LENGTH OF A HANDLER BLOCK + +INXT==0 ; POINTS TO NEXTIN CHAIN +IPREV==2 ; POINTS TO PREV IN CHAIN +INTFCN==4 ; FUNCTION ASSOCIATED WITH THIS HANDLER +INTPRO==6 ; PROCESS TO RUN INT IN + +IFN ITS,[ +RMT [ +IMPURE +TSINT: +MTSINT: 0 ;INTERRUPT BITS GET STORED HERE +TSINTR: 0 ;INTERRUPT PC WORD STORED HERE + JRST TSINTP ;GO TO PURE CODE + +; SOFTWARE INTERNAL INTERRUPTS JSR TO HERE + +LCKINT: 0 + JRST DOINT + +PURE +] +] +IFE ITS,[ +RMT [ +; JSR HERE FOR SOFTWARE INTERNAL INTERRUPTS + +LCKINT: 0 + JRST DOINT +] +] + + +IFN ITS,[ + +;THE REST OF THIS CODE IS PURE + +TSINTP: SOSGE INTFLG ; SKIP IF ENABLED + SETOM INTFLG ;DONT GET LESS THAN -1 + + MOVEM A,TSAVA ;SAVE TWO ACS + MOVEM B,TSAVB + MOVE A,TSINT ;PICK UP INT BIT PATTERN + JUMPL A,2NDWORD ;DONT CHECK FOR PDL OVERFLOW ETC. IF SIGN BIT ON + + TRZE A,200000 ;IS THIS A PDL OVERFLOW? + JRST IPDLOV ;YES, GO HANDLE IT FIRST + +IMPCH: MOVEI B,0 + TRNE A,20000 ;IS IT A MEMORY PROTECTION VIOLATION? + MOVEI B,1 ; FLAG SAME + + TRNE A,40 ;ILLEGAL OP CODE? + MOVEI B,2 ; ALSO FLAG + TRNN A,400 ; IOC? + JRST .+3 + SOS TSINTR + MOVEI B,3 + TLNE A,200 ; PURE? + MOVEI B,4 + SOJGE B,DO.NOW ; CANT WAIT AROUND + +;DECODE THE REST OF THE INTERRUPTS USING A TABLE + +2NDWORD: + JUMPL A,GC2 ;2ND WORD? + IORM A,PIRQ ;NO, INTO WORD 1 + JRST GCQUIT ;AND DISMISS INT + +GC2: TLZ A,400000 ;TURN OFF SIGN BIT + IORM A,PIRQ2 + TRNE A,177777 ;CHECK FOR CHANNELS + JRST CHNACT ;GO IF CHANNEL ACTIVITY +] +GCQUIT: SKIPGE INTFLG ;SKIP IF INTERRUPTS ENABLED + JRST INTDON ;NO, DEFER REAL HANDLING UNTIL LATER + + MOVE A,TSINTR ;PICKUP RETURN WORD +IFE ITS,[ + TLON A,10000 ; EXEC PC? + SUBI A,1 ; YES FIXUP PC +] + MOVEM A,LCKINT ;STORE ELSEWHERE + MOVEI A,DOINTE ;CAUSE DISMISS TO HANDLER + HRRM A,TSINTR ;STORE IN INT RETURN + PUSH P,INTFLG ;SAVE INT FLAG + SETOM INTFLG ;AND DISABLE + + +INTDON: MOVE A,TSAVA ;RESTORE ACS + MOVE B,TSAVB +IFN ITS, .DISMISS TSINTR ;AND DISMISS THE INTERRUPT +IFE ITS, DEBRK + + +DO.NOW: SKIPE GCFLG + JRST DLOSER ; HANDLE FATAL GC ERRORS + MOVSI B,1 + SKIPGE INTFLG ; IF NOT ENABLED + MOVEM B,INTFLG ; PRETEND IT IS + JRST 2NDWORD + +IFE ITS,[ + +; HERE FOR TENEX PDL OVER FLOW INTERRUPT + +TNXPDL: SOSGE INTFLG + SETOM INTFLG + MOVEM A,TSAVA + MOVEM B,TSAVB + JRST IPDLOV ; GO TO COMMON HANDLER + +; HERE FOR TENEX ^G AND ^S INTERRUPTS + +CNTLG: MOVEM A,TSAVA + MOVEI A,1 + JRST CNTSG + +CNTLS: MOVEM A,TSAVA + MOVEI A,2 + +CNTSG: MOVEM B,TSAVB + IORM A,PIRQ2 ; SAY FOR MUDDLE LEVEL + SOSGE INTFLG + SETOM INTFLG + JRST GCQUIT +INTNET: +REPEAT NNETS,[ + MOVEM A,TSAVA + MOVE A,[1_<.RPCNT+NETCHN>] + JRST CNTSG +] +] + +; HERE TO PROCESS INTERRUPTS + +DOINT: SKIPE INTHLD ; GLOBAL LOCK ON INTS + JRST @LCKINT + SETOM INTHLD ; DONT LET IT HAPPEN AGAIN + PUSH P,INTFLG +DOINTE: SKIPE ONINT ; ANY FUDGE? + XCT ONINT ; YEAH, TRY ONE + EXCH 0,LCKINT ; RELATIVIZE PC IF FROM RSUBR + PUSH P,0 ; AND SAVE + ANDI 0,-1 + CAMG 0,PURTOP + CAMGE 0,VECBOT + JRST DONREL + SUBI 0,(M) ; M IS BASE REG + HLL 0,(P) ; GET FLAGS + TLO 0,M ; INDEX IT OFF M + EXCH 0,(P) ; AND RESTORE TO STACK +DONREL: EXCH 0,LCKINT ; GET BACK SAVED 0 + SETZM INTFLG ;DISABLE + AOS -1(P) ;INCR SAVED FLAG + +;NOW SAVE WORKING ACS + + PUSHJ P,SAVACS + HLRZ A,-1(P) ; HACK FUNNYNESS FOR MPV/ILOPR + SKIPE A + SETZM -1(P) ; REALLY DISABLED + +DIRQ: MOVE A,PIRQ ;NOW SATRT PROCESSING + JFFO A,FIRQ ;COUNT BITS AND GO + MOVE A,PIRQ2 ;1ST DONE, LOOK AT 2ND + JFFO A,FIRQ2 + +INTDN1: SKIPN GCHAPN ; SKIP IF MUST DO GC INT + JRST .+3 + SETZM GCHAPN + PUSHJ P,INTOGC ; AND INTERRUPT + + PUSHJ P,RESTAC + +IFN ITS,[ + .SUSET [.SPICLR,,[0]] ; DISABLE INTS +] + POP P,LCKINT + POP P,INTFLG + SETZM INTHLD ; RE-ENABLE THE WORLD +IFN ITS,[ + EXCH 0,LCKINT + HRRI 0,@0 ; EFFECTIVIZE THE ADDRESS + TLZ 0,37 ; KILL IND AND INDEX + EXCH 0,LCKINT + .DISMIS LCKINT +] +IFE ITS, JRST @LCKINT +FIRQ: PUSHJ P,GETBIT ;SET UP THE BIT TO CLOBBER IN PIRQ + ANDCAM A,PIRQ ;CLOBBER IT + ADDI B,36. ;OFSET INTO TABLE + JRST XIRQ ;GO EXECUTE + +FIRQ2: PUSHJ P,GETBIT ;PREPARE TO CLOBBER BIT + ANDCAM A,PIRQ2 ;CLOBBER IT + ADDI B,71. ;AGAIN OFFSET INTO TABLE +XIRQ: + CAIE B,21 ;PDL OVERFLOW? + JRST FHAND ;YES, HACK APPROPRIATELY + +PDL2: SKIPN A,PGROW + SKIPE A,TPGROW + JRST .+2 + JRST DIRQ ; NOTHING GROWING, FALSE ALARM + MOVEI B,PDLGRO_-6 ;GET GROWTH SPEC + DPB B,[111100,,-1(A)] ;STORE GROWTH SPEC +REAGC: MOVE C,[10.,,1] ; INDICATOR FOR AGC + SKIPE PGROW ; P IS GROWING + ADDI C,6 + SKIPE TPGROW ; TP IS GROWING + ADDI C,1 + PUSHJ P,AGC ;COLLECT GARBAGE + SETZM PGROW + SETZM TPGROW + AOJL A,REAGC ; IF NO CORE, RETRY + JRST DIRQ + +SAVACS: +IRP A,,[0,A,B,C,D,E] + PUSH TP,A!STO(PVP) + SETZM A!STO(PVP) ;NOW ZERO TYPE + PUSH TP,A + TERMIN + POPJ P, + +RESTAC: +IRP A,,[E,D,C,B,A,0] + POP TP,A + POP TP,A!STO(PVP) + TERMIN + POPJ P, + +; HERE TO DO GC INTERRUPT AND CLOSE ANY DEAD CHANNELS + +INTOGC: PUSH P,[N.CHNS-1] + MOVE A,TVP + ADD A,[CHNL1,,CHNL1] + PUSH TP,$TVEC + PUSH TP,A + +INTGC1: MOVE A,(TP) ; GET POINTER + SKIPN B,1(A) ; ANY CHANNEL? + JRST INTGC2 + HRRE 0,(A) ; INDICATOR + JUMPGE 0,INTGC2 + PUSH TP,$TCHAN + PUSH TP,B + MCALL 1,FCLOSE + + MOVE A,(TP) + +INTGC2: HLLZS (A) + ADD A,[2,,2] + MOVEM A,(TP) + SOSE (P) + JRST INTGC1 + + SUB P,[1,,1] + SUB TP,[2,,2] + PUSH TP,$TCHSTR + PUSH TP,CHQUOTE GC + PUSH TP,$TFLOAT ; PUSH ON TIME ARGUMENT + PUSH TP,GCTIM + PUSH TP,$TFIX ; PUSH ON THE CAUSE ARGUMENT + PUSH TP,GCCAUS + PUSH TP,$TATOM ; PUSH ON THE CALL ARGUMENT + MOVE A,GCCALL + PUSH TP,@GCALLR(A) + MCALL 4,INTERR + POPJ P, + + +GCALLR: 0 + MQUOTE BLOAT + MQUOTE GROW + MQUOTE LIST + MQUOTE VECTOR + MQUOTE SET + MQUOTE SETG + MQUOTE FREEZE + MQUOTE PURE-PAGE-LOADER + MQUOTE GC + MQUOTE INTERRUPT-HANDLER + MQUOTE NEWTYPE + + ; OLD "ON" SETS UP EVENT AND HANDLER + +MFUNCTION ON,SUBR + + ENTRY + + HLRE 0,AB ; 0=> -2*NUM OF ARGS + ASH 0,-1 ; TO -NUM + CAME 0,[-5] + JRST .+3 + MOVEI B,10(AB) ; LAST MUST BE CHAN OR LOC + PUSHJ P,CHNORL + ADDI 0,3 + JUMPG 0,TFA ; AT LEAST 3 + MOVEI A,0 ; SET UP IN CASE NO PROC + AOJG 0,ONPROC ; JUMP IF NONE + GETYP C,6(AB) ; CHECK IT + CAIE C,TPVP + JRST TRYFIX + MOVE A,7(AB) ; GET IT +ONPROC: PUSH P,A ; SAVE AS A FLAG + GETYP A,(AB) ; CHECK PREV EXISTANCE + PUSH P,0 + CAIN A,TATOM + JRST .+3 + CAIE A,TCHSTR + JRST WTYP1 + MOVEI B,(AB) ; FIND IT + PUSHJ P,FNDINT + POP P,0 ; REST NUM OF ARGS + JUMPN B,ON3 ; ALREADY THERE + SKIPE C ; SKIP IF NOTHING TO FLUSH + SUB TP,[2,,2] + PUSH TP,(AB) ; GET NAME + PUSH TP,1(AB) + PUSH TP,4(AB) + PUSH TP,5(AB) + MOVEI A,2 ; # OF ARGS TO EVENT + AOJG 0,ON1 ; JUMP IF NO LAST ARG + PUSH TP,10(AB) + PUSH TP,11(AB) + ADDI A,1 +ON1: ACALL A,EVENT + +ON3: PUSH TP,A + PUSH TP,B + PUSH TP,2(AB) ; NOW FCN + PUSH TP,3(AB) + MOVEI A,3 ; NUM OF ARGS + SKIPN (P) + SOJA A,ON2 ; NO PROC + PUSH TP,$TPVP + PUSH TP,7(AB) +ON2: ACALL A,HANDLER + JRST FINIS + + +TRYFIX: SKIPN A,7(AB) + CAIE C,TFIX + JRST WRONGT + JRST ONPROC + +; ROUTINE TO BUILD AN EVENT + +MFUNCTION EVENT,SUBR + + ENTRY + + HLRZ 0,AB + CAIN 0,-2 ; IF JUST 1 + JRST RE.EVN ; COULD BE EVENT + CAIL 0,-3 ; MUST BE AT LEAST 2 ARGS + JRST TFA + GETYP A,2(AB) ; 2ND ARG MUST BE FIXED POINT PRIORITY + CAIE A,TFIX + JRST WTYP2 + GETYP A,(AB) ; FIRST ARG SHOULD BE CHSTR + CAIN A,TATOM ; ALLOW ACTUAL ATOM + JRST .+3 + CAIE A,TCHSTR + JRST WTYP1 + CAIL 0,-5 + JRST GOTRGS + CAIG 0,-7 + JRST TMA + MOVEI B,4(AB) + PUSHJ P,CHNORL ; CHANNEL OR LOCATIVE (PUT ON STACK) + +GOTRGS: MOVEI B,(AB) ; NOW TRY TO FIND HEADER FOR THIS INTERRUPT + PUSHJ P,FNDINT ; CALL INTERNAL HACKER + JUMPN B,FINIS ; ALREADY ONE OF THIS NAME + PUSH P,C + JUMPE C,.+3 ; GET IT OFF STACK + POP TP,B + POP TP,A + PUSHJ P,MAKINT ; MAKE ONE FOR ME + MOVSI 0,TFIX + MOVEM 0,INTPRI(B) ; SET UP PRIORITY + MOVE 0,3(AB) + MOVEM 0,INTPRI+1(B) +CH.SPC: POP P,C ; GET CODE BACK + SKIPGE C + PUSHJ P,DO.SPC ; DO ANY SPECIAL HACKS + JRST FINIS + +RE.EVN: GETYP 0,(AB) + CAIE 0,TINTH + JRST TFA ; ELSE SAY NOT ENOUGH + MOVE B,1(AB) ; GET IT + SETZM ISTATE+1(B) ; MAKE SURE ENABLED + SETZB D,C + GETYP A,INAME(B) ; CHECK FOR CHANNEL + CAIN A,TCHAN ; SKIP IF NOT + HRROI C,SS.CHA ; SET UP CHANNEL HACK + HRLZ E,INTPRI(B) ; GET POSSIBLE READ/WRITE BITS + TLNE E,.WRMON+.RDMON ; SKIP IF NOT MONITORS + PUSHJ P,GETNM1 + JUMPL C,RE.EV1 + MOVE B,INAME+1(B) ; CHECK FOR SPEC + PUSHJ P,SPEC1 + MOVE B,1(AB) ; RESTORE IHEADER +RE.EV1: PUSH TP,INAME(B) + PUSH TP,INAME+1(B) + PUSH P,C + MOVSI C,TATOM + PUSH TP,$TATOM + SKIPN D + MOVE D,MQUOTE INTERRUPT + PUSH TP,D + MOVE A,INAME(B) + MOVE B,INAME+1(B) ; GET IT + PUSHJ P,IGET ; LOOK FOR IT + JUMPN B,FINIS ; RETURN IT + MOVE A,(TB) + MOVE B,1(TB) + POP TP,D + POP TP,C + PUSH TP,(AB) + PUSH TP,1(AB) + PUSHJ P,IPUT ; REESTABLISH IT + MOVE A,(AB) + MOVE B,1(AB) + JRST CH.SPC + + +; FUNCTION TO GENERATE A HANDLER FOR A GIVEN INTERRUPT + +MFUNCTION HANDLER,SUBR + + ENTRY + + HLRZ 0,AB + CAIL 0,-2 ; MUST BE 2 OR MORE ARGS + JRST TFA + GETYP A,(AB) + CAIE A,TINTH ; EVENT? + JRST WTYP1 + GETYP A,2(AB) + CAIN 0,-4 ; IF EXACTLY 2 + CAIE A,THAND ; COULD BE HANDLER + JRST CHEVNT + + MOVE B,3(AB) ; GET IT + SKIPN IPREV+1(B) ; SKIP IF ALREADY IN USE + JRST HNDOK + MOVE D,1(AB) ; GET EVENT + SKIPN D,IHNDLR+1(D) ; GET FIRST HANDLER + JRST BADHND + CAMN D,B ; IS THIS IT? + JRST HFINIS ; YES, ALREADY "HANDLED" + MOVE D,INXT+1(D) ; GO TO NEXT HANDLER + JUMPN D,.-3 +BADHND: PUSH TP,$TATOM + PUSH TP,EQUOTE HANDLER-ALREADY-IN-USE + JRST CALER1 + +CHEVNT: CAIG 0,-7 ; SKIP IF LESS THAN 4 + JRST TMA + PUSH TP,$TPVP ; SLOT FOR PROCESS + PUSH TP,[0] + CAIE 0,-6 ; IF 3, LOOK FOR PROC + JRST NOPROC + GETYP 0,4(AB) + CAIE 0,TPVP + JRST WTYP3 + MOVE 0,5(AB) + MOVEM 0,(TP) + +NOPROC: PUSHJ P,APLQ + JRST NAPT + PUSHJ P,MHAND ; MAKE THE HANDLER + MOVE 0,1(TB) ; GET PROCESS + MOVEM 0,INTPRO+1(B) ; AND PUT IT INTO HANDLER + MOVSI 0,TPVP ; SET UP TYPE + MOVEM 0,INTPRO(B) + MOVE 0,2(AB) ; SET UP FUNCTION + MOVEM 0,INTFCN(B) + MOVE 0,3(AB) + MOVEM 0,INTFCN+1(B) + +HNDOK: MOVE D,1(AB) ; PICK UP EVEENT + MOVE E,IHNDLR+1(D) ; GET POINTER TO HANDLERS + MOVEM B,IHNDLR+1(D) ; PUT NEW ONE IN + MOVSI 0,TINTH ; GET INT HDR TYPE + MOVEM 0,IPREV(B) ; INTO BACK POINTER + MOVEM D,IPREV+1(B) ; AND POINTER ITSELF + MOVEM E,INXT+1(B) ; NOW NEXT POINTER + MOVSI 0,THAND ; NOW HANDLER TYPE + MOVEM 0,IHNDLR(D) ; SET TYPE IN HEADER + MOVEM 0,INXT(B) + JUMPE E,HFINIS ; JUMP IF HEADER WAS EMPTY + MOVEM 0,IPREV(E) ; FIX UP ITS PREV + MOVEM B,IPREV+1(E) +HFINIS: MOVSI A,THAND + JRST FINIS + + + +; FUNCTIONS TO SET TIME LIMITS FOR REALTIME AND RUNTIME INTS + +MFUNCTION RUNTIMER,SUBR + + ENTRY 1 + + GETYP 0,(AB) + JFCL 10,.+1 + MOVE A,1(AB) + CAIE 0,TFIX + JRST RUNT1 + IMUL A,[245761.] + JRST RUNT2 + +RUNT1: CAIE 0,TFLOAT + JRST WTYP1 + FMPR A,[245760.62] + MULI A,400 ; FIX IT + TSC A,A + ASH B,(A)-243 + MOVE A,B +RUNT2: JUMPL A,OUTRNG ; NOT FOR NEG # + JFCL 10,OUTRNG + .SUSET [.SRTMR,,A] + MOVE A,(AB) + MOVE B,1(AB) + JRST FINIS + +MFUNCTION REALTIMER,SUBR + + ENTRY 1 + + JFCL 10,.+1 + GETYP 0,(AB) + MOVE A,1(AB) + CAIE 0,TFIX + JRST REALT1 + IMULI A,60. ; TO 60THS OF SEC + JRST REALT2 + +REALT1: CAIE 0,TFLOAT + JRST WTYP1 + FMPRI A,(60.0) + MULI A,400 + TSC A,A + ASH B,(A)-243 + MOVE A,B + +REALT2: JUMPL A,OUTRNG + JFCL 10,OUTRNG + MOVE B,[200000,,A] + .REALT B, + JFCL + MOVE A,(AB) + MOVE B,1(AB) + JRST FINIS + +; FUNCTIONS TO ENABLE AND DISABLE INTERRUPTS + +MFUNCTION %ENABL,SUBR,ENABLE + + PUSHJ P,GTEVNT + SETZM ISTATE+1(B) + JRST FINIS + +MFUNCTION %DISABL,SUBR,DISABLE + + + PUSHJ P,GTEVNT + SETOM ISTATE+1(B) + JRST FINIS + +GTEVNT: ENTRY 1 + GETYP 0,(AB) + CAIE 0,TINTH + JRST WTYP1 + MOVE A,(AB) + MOVE B,1(AB) + POPJ P, + +DO.SPC: HRRZ C,INTBL(C) ; POINT TO SPECIAL CODE + HLRZ 0,AB ; - TWO TIMES NUM ARGS + PUSHJ P,(C) ; CALL ROUTINE + JUMPE E,CPOPJ ; NO BITS TO ENABLE, LEAVE +IFE ITS,[ + PUSH TP,A + PUSH TP,B + MOVE B,1(TB) ; CHANNEL + MOVE 0,CHANNO(B) + MOVEM 0,(E) ; SAVE IN TABLE + MOVEI E,(E) + SUBI E,NETJFN-NETCHN + MOVE A,0 ; SETUP FOR MTOPR + MOVEI B,24 + MOVSI C,(E) + TLO C,770000 ; DONT SETUP INR/INS + MTOPR + MOVEI 0,1 + MOVNS E + LSH 0,35.(E) + IORM 0,MASK1 + MOVE B,MASK1 + MOVEI A,MFORK + AIC + + POP TP,B + POP TP,A + POPJ P, ; ***** TEMP ****** +] +IFN ITS,[ + CAILE E,35. ; SKIP IF 1ST WORD BIT + JRST SETW2 + LSH 0,-1(E) + + IORM 0,MASK1 ; STORE IN PROTOTYPE MASK + .SUSET [.SMASK,,MASK1] + POPJ P, + +SETW2: LSH 0,-36.(E) + IORM 0,MASK2 ; SET UP PROTO MASK2 + .SUSET [.SMSK2,,MASK2] + POPJ P, +] + +; ROUTINE TO CHECK FOR CHANNEL OR LOCATIVE + +CHNORL: GETYP A,(B) ; GET TYPE + CAIN A,TCHAN ; IF CHANNEL + JRST CHNWIN + PUSH P,0 + PUSHJ P,LOCQ ; ELSE LOOCATIVE + JRST WRONGT + POP P,0 +CHNWIN: PUSH TP,(B) + PUSH TP,1(B) + POPJ P, + +; SUBROUTINE TO FIND A HANDLER OF A GIVEN NAME + +FNDINT: PUSHJ P,FNDNM + JUMPE B,CPOPJ + PUSHJ P,SPEC1 ; COULD BE FUNNY + +INTASO: PUSH P,C ; C<0 IF SPECIAL + PUSH TP,A + PUSH TP,B + MOVSI C,TATOM + SKIPN D ; COULD BE CHANGED FOR MONITOR + MOVE D,MQUOTE INTERRUPT + PUSH TP,C + PUSH TP,D + PUSHJ P,IGET + MOVE D,(TP) + SUB TP,[2,,2] + POP P,C ; AND RESTOR SPECIAL INDICATOR + SKIPE B ; IF FOUND + SUB TP,[2,,2] ; REMOVE CRUFT +CPOPJ: POPJ P, ; AND RETURN + +; CHECK FOR SPECIAL INTERNAL INTERRUPT HACK + +SPEC1: MOVSI C,-SPECLN ; BUILD AOBJN PNTR +SPCLOP: CAME B,@SPECIN(C) ; SKIP IF SPECIAL + AOBJN C,.-1 ; UNTIL EXHAUSTED + JUMPGE C,.+3 + SKIPE E,FNDTBL(C) + JRST (E) + MOVEI 0,-1(TB) ; SEE IF OK + CAIE 0,(TP) + JRST TMA + POPJ P, + +; ROUTINE TO CREATE A NEW INTERRUPT (INTERNAL ONLY--NOT ITS FLAVOR) + +MAKINT: JUMPN C,GOTATM ; ALREADY HAVE NAME, GET THING + MOVEI B,(AB) ; POINT TO STRING + PUSHJ P,CSTAK ; CHARS TO STAKC + MOVE B,INTOBL+1(TVP) + PUSHJ P,INSRTX + MOVE D,MQUOTE INTERRUPT +GOTATM: PUSH TP,$TINTH ; MAKE SLOT FOR HEADER BLOCK + PUSH TP,[0] + PUSH TP,A + PUSH TP,B ; SAVE ATOM + PUSH TP,$TATOM + PUSH TP,D + MOVEI A,IHDRLN*2 + PUSHJ P,GIBLOK + MOVE A,-3(TP) ; GET NAME AND STORE SAME + MOVEM A,INAME(B) + MOVE A,-2(TP) + MOVEM A,INAME+1(B) + SETZM ISTATE+1(B) + MOVEM B,-4(TP) ; STASH HEADER + POP TP,D + POP TP,C + EXCH B,(TP) + MOVSI A,TINTH + EXCH A,-1(TP) ; INTERNAL PUT CALL + PUSHJ P,IPUT + POP TP,B + POP TP,A + POPJ P, + +; FIND NAME OF INTERRUPT + +FNDNM: GETYP A,(B) ; TYPE + CAIE A,TCHSTR ; IF STRING + JRST FNDATM ; DONT HAVE ATOM, OTHERWISE DO + PUSHJ P,IILOOK + JRST .+2 +FNDATM: MOVE B,1(B) + SETZB C,D ; PREVENT LOSSAGE LATER + MOVSI A,TATOM + +; THE NEXT 2 INSTRUCTIONS ARE A KLUDGE TO GET THE RIGHT ERROR ATOM + + CAMN B,IMQUOTE ERROR + MOVE B,MQUOTE ERROR,ERROR,INTRUP + POPJ P, + +IILOOK: PUSHJ P,CSTAK ; PUT CHRS ON STACK + MOVE B,INTOBL+1(TVP) + JRST ILOOKC ; LOOK IT UP + +; ROUTINE TO MAKE A HANDLER BLOCK + +MHAND: MOVEI A,IHANDL*2 + JRST GIBLOK ; GET BLOCK + +; HERE TO GET CHANNEL FOR "CHAR" INTERRUPT + +GETCHN: GETYP 0,(TB) ; GET TYPE + CAIE 0,TCHAN ; CHANNL IS WINNER + JRST WRONGT + MOVE A,(TB) ; USE THE CHANNEL TO NAME THE INTERRUPT + MOVE B,1(TB) + SKIPN CHANNO(B) ; SKIP IF WINNING CHANNEL + JRST CBDCHN ; LOSER + POPJ P, + +LOCGET: GETYP 0,(TB) ; TYPE + CAIN 0,TCHAN ; SKIP IF LOCATIVE + JRST WRONGT + MOVE D,B + MOVE A,(TB) + MOVE B,1(TB) ; GET LOCATIVE + POPJ P, + +; FINAL MONITOR SETUP ROUTINES + +S.RMON: SKIPA E,[.RDMON,,] +S.WMON: MOVSI E,.WRMON + PUSH TP,A + PUSH TP,B + HLRM E,INTPRI(B) ; SAVE BITS + MOVEI B,(TB) ; POINT TO LOCATIVE + HRRZ A,FSAV(TB) + CAIN A,OFF + MOVSI D,(ANDCAM E,) ; KILL INST + CAIN A,EVENT + MOVSI D,(IORM E,) + PUSHJ P,SMON ; GO DO IT + POP TP,B + POP TP,A + MOVEI E,0 + POPJ P, + + +; SPECIAL SETUP ROUTINES FOR INITIAL INTERRUPTS + +IFN ITS,[ +S.CHAR: MOVE E,1(TB) ; GET CHANNEL + MOVE E,CHANNO(E) + ADDI E,36. ; GET CORRECT MASK BIT +ONEBIT: MOVEI 0,1 ; BIT FOR INT TO RET + POPJ P, +] +IFE ITS,[ +S.CHAR: MOVE E,1(TB) + MOVE 0,RDEVIC(E) + ILDB 0,0 ; 1ST CHAR + PUSH P,A + CAIE 0,"N ; NET ? + JRST S.CHA1 + + MOVEI A,0 + HRRZ 0,CHANNO(E) + MOVE E,[-NNETS,,NETJFN] + CAMN 0,(E) + JRST S.CHA2 + SKIPN (E) + MOVE A,E ; REMEMBER WHERE + AOBJN E,.-5 + TLNN A,-1 + FATAL NO MORE NETWORK + MOVE E,A +S.CHA1: MOVEI E,0 +S.CHA2: POP P,A + POPJ P, +] + + +; SPECIAL FOR CLOCK + +S.DOWN: SKIPA E,[7] +S.CLOK: MOVEI E,13. ; FOR NOW JUST GET BIT # + JRST ONEBIT + +S.PAR: MOVEI E,28. + JRST ONEBIT + +; RUNTIME AND REALTIME INTERRUPTS + +S.RUNT: SKIPA E,[34.] +S.REAL: MOVEI E,35. + JRST ONEBIT + +S.IOC: SKIPA E,[9.] ; IO CHANNEL ERROR +S.PURE: MOVEI E,26. + JRST ONEBIT + +; MPV AND ILOPR + +S.MPV: SKIPA E,[14.] ; BIT POS +S.ILOP: MOVEI E,6 + JRST ONEBIT + +; HERE TO TURN ALL INFERIOR INTS + +S.INF: MOVEI E,36.+16.+2 ; START OF BITS + MOVEI 0,37 ; 8 BITS WORTH + POPJ P, + + +; HERE TO HANDLE ITS INTERRUPTS + +FHAND: SKIPN D,EXTINT(B) ; SKIP IF HANDLERS ARE POSSIBLE + JRST DIRQ + JRST (D) + +IFN ITS,[ +; SPECIAL CHARACTER HANDLERS + +HCHAR: MOVEI D,CHNL0+1(TVP) + ADDI D,(B) ; POINT TO CHANNEL SLOT + ADDI D,(B) + SKIPN D,-72.(D) ; PICK UP CHANNEL + JRST IPCGOT ;WELL, IT GOTTA BEE THE THE IPC THEN + PUSH TP,$TCHAN + PUSH TP,D + LDB 0,[600,,STATUS(D)] ; GET DEVICE CODE + CAILE 0,2 ; SKIP IF A TTY + JRST HNET ; MAYBE NETWORK CHANNEL + CAMN D,TTICHN+1(TVP) + SKIPN NOTTY + JRST HCHR11 + MOVE B,D ; CHAN TO B + PUSHJ P,TTYOP2 ; RE-GOBBLE TTY + MOVE D,(TP) +HCHR11: MOVE D,CHANNO(D) ; GET ITS CHANNEL + PUSH P,D ; AND SAVE IT + .CALL HOWMNY ; GET # OF CHARS + MOVEI B,0 ; IF TTY GONE, NO CHARS +RECHR: ADDI B,1 ; BUMP BY ONE FOR SOSG + MOVEM B,CHNCNT(D) ; AND SAVE + IORM A,PIRQ2 ; LEAVE THE INT ON + +CHRLOO: MOVE D,(P) ; GET CHNNAEL NO. + SOSG CHNCNT(D) ; GET COUNT + JRST CHRDON + + MOVE B,(TP) + MOVE D,BUFRIN(B) ; GET EXTRA BUFFER + XCT IOIN2(D) ; READ CHAR + PUSH TP,$TCHSTR + PUSH TP,CHQUOTE CHAR + PUSH TP,$TCHRS ; SAVE CHAR FOR CALL + PUSH TP,A + PUSH TP,$TCHAN ; SAVE CHANNEL + PUSH TP,B + PUSHJ P,INCHAR ; PUT CHAR IN USERS BUFFER + MCALL 3,INTERRUPT ; RUN THE HANDLERS + JRST CHRLOO ; AND LOOP + +CHRDON: .CALL HOWMNY + MOVEI B,0 + MOVEI A,1 ; SET FOR PI WORD CLOBBER + LSH A,(D) + JUMPG B,RECHR ; ANY MORE? + ANDCAM A,PIRQ2 + SUB P,[1,,1] + SUB TP,[2,,2] + JRST DIRQ + + + +; HERE FOR NET CHANNEL INTERRUPT + +HNET: CAIE 0,26 ; NETWORK? + JRST HSTYET ; HANDLE PSEUDO TTY ETC. + PUSH TP,$TATOM + PUSH TP,MQUOTE CHAR,CHAR,INTRUP + PUSH TP,$TUVEC + PUSH TP,BUFRIN(D) + PUSH TP,$TCHAN + PUSH TP,D + MOVE B,D ; CHAN TO B + PUSHJ P,INSTAT ; UPDATE THE NETWRK STATE + MCALL 3,INTERRUPT + SUB TP,[2,,2] + JRST DIRQ + +HSTYET: PUSH TP,$TATOM + PUSH TP,MQUOTE CHAR,CHAR,INTRUP + PUSH TP,$TCHAN + PUSH TP,D + MCALL 2,INTERRUPT + SUB TP,[2,,2] + JRST DIRQ + +] +CBDCHN: PUSH TP,$TATOM + PUSH TP,EQUOTE BAD-CHANNEL + JRST CALER1 + +IFN ITS,[ + +HCLOCK: PUSH TP,$TCHSTR + PUSH TP,CHQUOTE CLOCK + MCALL 1,INTERRUPT + JRST DIRQ + +HRUNT: PUSH TP,$TATOM + PUSH TP,MQUOTE RUNT,RUNT,INTRUP + MCALL 1,INTERRUPT + JRST DIRQ + +HREAL: PUSH TP,$TATOM + PUSH TP,MQUOTE REALT,REALT,INTRUP + MCALL 1,INTERRUPT + JRST DIRQ + +HPAR: MOVE A,MQUOTE PARITY,PARITY,INTRUP + JRST HMPV1 + +HMPV: MOVE A,MQUOTE MPV,MPV,INTRUP + JRST HMPV1 + +HILOPR: MOVE A,MQUOTE ILOPR,ILOPR,INTRUP + JRST HMPV1 + +HPURE: MOVE A,MQUOTE PURE,PURE,INTRUP +HMPV1: PUSH TP,$TATOM + PUSH TP,A + PUSH P,LCKINT ; SAVE LOCN + PUSH TP,$TATOM + PUSH TP,A + PUSH TP,$TWORD + PUSH TP,LCKINT + MCALL 2,EMERGENCY + POP P,A + MOVE C,(TP) + SUB TP,[2,,2] + JUMPN B,DIRQ + + PUSH TP,$TATOM + PUSH TP,EQUOTE DANGEROUS-INTERRUPT-NOT-HANDLED + PUSH TP,$TATOM + PUSH TP,C + PUSH TP,$TWORD + PUSH TP,A + MCALL 3,ERROR + JRST DIRQ + + + +; HERE TO HANDLE SYS DOWN INTERRUPT + +HDOWN: PUSH TP,$TATOM + PUSH TP,MQUOTE SYSDOWN,SYSDOWN,INTRUP + .DIETI A, ; HOW LONG? + PUSH TP,$TFIX + PUSH TP,A + PUSH P,A ; FOR MESSAGE + MCALL 2,INTERRUPT + POP P,A + JUMPN B,DIRQ + .SUSET [.RTTY,,B] ; DO WE NOW HAVE A TTY AT ALL? + JUMPL B,DIRQ ; DONT HANG AROUND + PUSH P,A + MOVEI B,[ASCIZ / +Excuse me, SYSTEM going down in /] + SKIPG (P) ; SKIP IF REALLY GOING DOWN + MOVEI B,[ASCIZ / +Excuse me, SYSTEM has been REVIVED! +/] + PUSHJ P,MSGTYP + POP P,B + JUMPE B,DIRQ + IDIVI B,30. ; TO SECONDS + IDIVI B,60. ; A/ SECONDS B/ MINUTES + JUMPE B,NOMIN + PUSH P,C + PUSHJ P,DECOUT + MOVEI B,[ASCIZ / minutes /] + PUSHJ P,MSGTYP + POP P,B + JRST .+2 +NOMIN: MOVEI B,(C) + PUSHJ P,DECOUT + MOVEI B,[ASCIZ / seconds. +/] + PUSHJ P,MSGTYP + JRST DIRQ + +; TWO DIGIT DEC OUT FROM B/ + +DECOUT: IDIVI B,10. + JUMPE B,DECOU1 ; NO TEN + MOVEI A,60(B) + PUSHJ P,MTYO +DECOU1: MOVEI A,60(C) + JRST MTYO + +; HERE TO HANDLE I/O CHANNEL ERRORS + +HIOC: .SUSET [.RAPRC,,A] ; CONTAINS CHANNEL OF MOST RECENT LOSSAGE + LDB A,[330400,,A] ; GET CHAN # + MOVEI C,(A) ; COPY + PUSH TP,$TATOM ; PUSH ERROR + PUSH TP,EQUOTE FILE-SYSTEM-ERROR + + PUSH TP,$TCHAN + ASH C,1 ; GET CHANNEL + ADDI C,CHNL0+1(TVP) ; GET CHANNEL VECTOR + PUSH TP,(C) + LSH A,23. ; DO A .STATUS + IOR A,[.STATUS A] + XCT A + PUSHJ P,GFALS ; GEN NAMED FALSE + PUSH TP,A + PUSH TP,B + PUSH TP,$TATOM + PUSH TP,MQUOTE IOC,IOC,INTRUP + + PUSH TP,A + PUSH TP,B + PUSH TP,-7(TP) + PUSH TP,-7(TP) + MCALL 3,EMERGENCY + JUMPN B,DIRQ1 ; JUMP IF HANDLED + MCALL 3,ERROR + JRST DIRQ + +DIRQ1: SUB TP,[6,,6] + JRST DIRQ + +; HANDLE INFERIOR KNOCKING AT THE DOOR + +HINF: SUBI B,36.+16.+2 ; CONVERT TO INF # + PUSH TP,$TATOM + PUSH TP,MQUOTE INFERIOR,INFERIOR,INTRUP + PUSH TP,$TFIX + PUSH TP,B + MCALL 2,INTERRUPT + JRST DIRQ +] +IFE ITS,[ + +; HERE FOR TENEX INTS (FIRST CUT) + +HCNTLG: MOVEI A,7 + JRST HCNGS + +HCNTLS: MOVEI A,23 + +HCNGS: PUSH TP,$TATOM + PUSH TP,MQUOTE CHAR,CHAR,INTRUP + PUSH TP,$TCHRS + PUSH TP,A + PUSH TP,$TCHAN + PUSH TP,TTICHN+1(TVP) + MCALL 3,INTERRUPT + JRST DIRQ + +HNET: MOVE A,NETJFN-NINT+NNETS(B) + JUMPE A,DIRQ + ASH A,1 + ADDI A,CHNL0+1(TVP) + MOVE B,(A) + PUSH TP,$TATOM + PUSH TP,MQUOTE CHAR,CHAR,INTRUP + PUSH TP,$TUVEC + PUSH TP,BUFRIN(B) + PUSH TP,$TCHAN + PUSH TP,B + PUSHJ P,INSTAT + MCALL 3,INTERRUPT + JRST DIRQ +] + + +MFUNCTION OFF,SUBR + ENTRY + + JUMPGE AB,TFA + HLRZ 0,AB + GETYP A,(AB) ; ARG TYPE + MOVE B,1(AB) ; AND VALUE + CAIN A,TINTH ; HEADER, GO HACK + JRST OFFHD ; QUEEN OF HEARTS + CAIN A,TATOM + JRST .+3 + CAIE A,TCHSTR + JRST TRYHAN ; MAYBE INDIVIDUAL HANDLER + CAIN 0,-2 ; MORE THAN 1 ARG? + JRST OFFAC1 ; NO, GO ON + CAIG 0,-5 ; CANT BE MORE THAN 2 + JRST TMA + MOVEI B,2(AB) ; POINT TO 2D + PUSHJ P,CHNORL +OFFAC1: MOVEI B,(AB) + PUSHJ P,FNDINT + JUMPGE B,NOHAN1 ; NOT HANDLED + +OFFH1: PUSH P,C ; SAVE C FOR BIT CLOBBER + MOVSI C,TATOM + SKIPN D + MOVE D,MQUOTE INTERRUPT + MOVE A,INAME(B) + MOVE B,INAME+1(B) + PUSHJ P,IREMAS + SKIPE B ; IF NO ASSOC, DONT SMASH + SETOM ISTATE+1(B) ; DISABLE IN CASE QUEUED + POP P,C ; SPECIAL? + JUMPGE C,FINIS ; NO, DONE + + HRRZ C,INTBL(C) ; POINT TO SPECIAL CODE + PUSHJ P,(C) ; GO TO SAME + JUMPE E,OFINIS ; DONE +IFN ITS,[ + CAILE E,35. ; SKIP IF 1ST WORD + JRST CLRW2 ; CLOBBER 2D WORD BIT + LSH 0,-1(E) ; POSITION BIT + ANDCAM 0,MASK1 ; KILL BIT + .SUSET [.SMASK,,MASK1] +] +IFE ITS,[ + MOVE D,B + SETZM (E) + MOVEI E,(E) + SUBI E,NETJFN-NETCHN + MOVEI 0,1 + MOVNS E + LSH 0,35.(E) + ANDCAM 0,MASK1 + MOVEI A,MFORK + SETCM B,MASK1 + DIC + ANDCAM 0,PIRQ ; JUST IN CASE + MOVE B,D +] +OFINIS: MOVSI A,TINTH + JRST FINIS + +IFN ITS,[ +CLRW2: LSH 0,-36.(E) ; POS BIT FOR 2D WORD + ANDCAM 0,MASK2 + .SUSET [.SMSK2,,MASK2] + JRST OFINIS +] + +TRYHAN: CAIE A,THAND ; HANDLER? + JRST WTYP1 + CAIE 0,-2 + JRST TMA + GETYP 0,IPREV(B) ; GET TYPE OF PREV + MOVE A,INXT+1(B) + MOVE C,IPREV+1(B) + MOVE D,IPREV(B) + CAIE 0,THAND + JRST DOHEAD ; PREV HUST BE HDR + MOVEM A,INXT+1(C) + JRST .+2 +DOHEAD: MOVEM A,IHNDLR+1(C) ; INTO HDR + JUMPE A,OFFINI + MOVEM D,IPREV(A) + MOVEM C,IPREV+1(A) +OFFINI: SETZM IPREV+1(B) + SETZM INXT+1(B) + MOVSI A,THAND + JRST FINIS + +OFFHD: CAIE 0,-2 + JRST TMA + PUSHJ P,GETNMS ; GET INFOR ABOUT INT + JUMPE C,OFFH1 + PUSH TP,INAME(B) + PUSH TP,INAME+1(B) + JRST OFFH1 + +GETNMS: GETYP A,INAME(B) ; CHECK FOR SPECIAL + SETZB C,D + CAIN A,TCHAN + HRROI C,SS.CHA + PUSHJ P,LOCQ ; LOCATIVE? + JRST CHGTNM + + MOVEI B,INAME(B) ; POINT TO LOCATIVE + MOVSI D,(MOVE E,) + PUSHJ P,SMON ; GET MONITOR + MOVE B,1(AB) +GETNM1: HRROI C,SS.WMO ; ASSUME WRITE + TLNN E,.WRMON + HRROI C,SS.RMO + MOVE D,MQUOTE WRITE,WRITE,INTRUP + TLNN E,.WRMON + MOVE D,MQUOTE READ,READ,INTRUP + POPJ P, + +CHGTNM: JUMPL C,CPOPJ + MOVE B,INAME+1(B) + PUSHJ P,SPEC1 + MOVE B,1(AB) ; RESTORE IHEADER + POPJ P, + +; EMERGENCY, CANT DEFER ME!! + +MQUOTE INTERRUPT + +EMERGENCY: + PUSH P,. + JRST INTERR+1 + +MFUNCTION INTERRUPT,SUBR + + PUSH P,[0] + + ENTRY + + SETZM INTHLD ; RE-ENABLE THE WORLD + JUMPGE AB,TFA + MOVE B,1(AB) ; GET HANDLER/NAME + GETYP A,(AB) ; CAN BE HEADER OR NAME + CAIN A,TINTH ; SKIP IF NOT HEADER + JRST GTHEAD + CAIN A,TATOM + JRST .+3 + CAIE A,TCHSTR ; SKIP IF CHAR STRING + JRST WTYP1 + MOVEI B,(AB) ; LOOK UP NAME + PUSHJ P,FNDNM ; GET NAME + JUMPE B,IFALSE + MOVEI D,0 + CAMN B,MQUOTE CHAR,CHAR,INTRUP + PUSHJ P,CHNGT1 + CAME B,MQUOTE READ,READ,INTRUP + CAMN B,MQUOTE WRITE,WRITE,INTRUP + PUSHJ P,GTLOC1 + PUSHJ P,INTASO + JUMPE B,IFALSE + +GTHEAD: SKIPE ISTATE+1(B) ; ENABLED? + JRST IFALSE ; IGNORE COMPLETELY + MOVE A,INTPRI+1(B) ; GET PRIORITY OF INTERRUPT + CAMLE A,CURPRI ; SEE IF MUST QUEU + JRST SETPRI ; MAY RUN NOW + SKIPE (P) ; SKIP IF DEFER OK + JRST DEFERR + MOVEM A,(P) + PUSH TP,$TINTH ; SAVE HEADER + PUSH TP,B + MOVEI A,1 ; SAVE OTHER ARGS +PSHARG: ADD AB,[2,,2] + JUMPGE AB,QUEU1 ; GO MAKE QUEU ENTRY + PUSH TP,(AB) + PUSH TP,1(AB) + AOJA A,PSHARG +QUEU1: PUSHJ P,IEVECT ; GET VECTOR + PUSH TP,$TVEC + PUSH TP,[0] ; WILL HOLD QUEUE HEADER + PUSH TP,A + PUSH TP,B + + POP P,A ; RESTORE PRIORITY + + MOVE B,QUEUES+1(TVP) ; GET INTERRUPT QUEUES + MOVEI D,0 + JUMPGE B,GQUEU ; MAKE A QUEUE HDR + +NXTQU: CAMN A,1(B) ; GOT PRIORITY? + JRST ADDQU ; YES, ADD TO THE QUEU + CAMG A,1(B) ; SKIP IF SPOT NOT FOUND + JRST GQUEU + MOVE D,B + MOVE B,3(B) ; GO TO NXT QUEUE + JUMPL B,NXTQU + +GQUEU: PUSH TP,$TVEC ; SAVE NEXT POINTER + PUSH TP,D + PUSH TP,$TFIX + PUSH TP,A ; SAVE PRIORITY + PUSH TP,$TVEC + PUSH TP,B + PUSH TP,$TLIST + PUSH TP,[0] + PUSH TP,$TLIST + PUSH TP,[0] + MOVEI A,4 + PUSHJ P,IEVECT + MOVE D,(TP) ; NOW SPLICE + SUB TP,[2,,2] + JUMPN D,GQUEU1 + MOVEM B,QUEUES+1(TVP) + JRST .+2 +GQUEU1: MOVEM B,3(D) + +ADDQU: MOVEM B,-2(TP) ; SAVE QUEU HDR + POP TP,D + POP TP,C + PUSHJ P,INCONS ; CONS IT + MOVE C,(TP) ;GET QUEUE HEADER + SKIPE D,7(C) ; IF END EXISTS + HRRM B,(D) ; SPLICE + MOVEM B,7(C) + SKIPN 5(C) ; SKIP IF START EXISTS + MOVEM B,5(C) + +IFINI: MOVSI A,TATOM + MOVE B,MQUOTE T + JRST FINIS + +SETPRI: EXCH A,CURPRI + MOVEM A,(P) + + PUSH TP,$TAB ; PASS AB TO HANDLERS + PUSH TP,AB + + PUSHJ P,RUNINT ; RUN THE HANDLERS + POP P,A ; UNQUEU ANY WAITERS + PUSHJ P,UNQUEU + + JRST IFINI + +; HERE TO UNQUEUE WAITING INTERRUPTS + +UNQUEU: PUSH P,A ; SAVE NEW LEVEL + +UNQUE1: MOVE A,(P) ; TARGET LEVEL + CAMLE A,CURPRI ; CHECK RUG NOT PULLED OUT + JRST UNDONE + SKIPE B,QUEUES+1(TVP) + CAML A,1(B) ; RIGHT LEVEL? + JRST UNDONE ; FINISHED + + SKIPN C,5(B) ; ON QUEUEU? + JRST UNXQ + HRRZ D,(C) ; CDR THE LIST + MOVEM D,5(B) + SKIPN D ; SKIP IF NOT LAST + SETZM 7(B) ; CLOBBER END POINTER + MOVE A,1(B) ; GET THIS PRIORITY LEVEL + MOVEM A,CURPRI ; MAKE IT THE CURRENT ONE + MOVE D,1(C) ; GET SAVED VECTOR OF INF + + MOVE B,1(D) ; INT HEADER + PUSH TP,$TVEC + PUSH TP,D ; AND ARGS + + PUSHJ P,RUNINT ; RUN THEM + JRST UNQUE1 + +UNDONE: POP P,CURPRI ; SET CURRENT LEVEL + MOVE A,CURPRI + POPJ P, + +UNXQ: MOVE B,3(B) ; GO TO NEXT QUEUE + MOVEM B,QUEUES+1(TVP) + JRST UNQUE1 + + + +; SUBR TO CHANGE INTERRUPT LEVEL + +MFUNCTION INTLEV,SUBR,[INT-LEVEL] + ENTRY + JUMPGE AB,RETLEV ; JUST RETURN CURRENT + GETYP A,(AB) + CAIE A,TFIX + JRST WTYP1 ; LEVEL IS FIXED + SKIPGE A,1(AB) + JRST OUTRNG" + CAMN A,CURPRI ; DIFFERENT? + JRST RETLEV ; NO RETURN + PUSH P,CURPRI + CAMG A,CURPRI ; SKIP IF NO UNQUEUE NEEDED + PUSHJ P,UNQUEU + MOVEM A,CURPRI ; SAVE + POP P,A + SKIPA B,A +RETLEV: MOVE B,CURPRI + MOVSI A,TFIX + JRST FINIS + +RUNINT: PUSH TP,$THAND ; SAVE HANDLERS LIST + PUSH TP,IHNDLR+1(B) + + SKIPN ISTATE+1(B) ; SKIP IF DISABLED + SKIPN B,(TP) + JRST SUBTP4 +NXHND: MOVEM B,(TP) ; SAVE CURRENT HDR + MOVE A,-2(TP) ; SAVE ARG POINTER + PUSHJ P,CHSWAP ; SEE IF MUST SWAP + PUSH TP,[0] + PUSH TP,[0] + MOVEI C,1 ; COUNT ARGS + PUSH TP,$TSP + PUSH TP,SP + MOVE D,PVP + ADD D,[1STEPR,,1STEPR] + PUSH TP,BNDV + PUSH TP,D + PUSH TP,$TPVP + PUSH TP,[0] + MOVE E,TP + PUSH TP,INTFCN(B) + PUSH TP,INTFCN+1(B) + ADD A,[2,,2] + JUMPGE A,DO.HND + PUSH TP,(A) + PUSH TP,1(A) + AOJA C,.-4 +DO.HND: PUSH P,C + PUSHJ P,SPECBE ; BIND 1 STEP FLAG + POP P,C + ACALL C,INTAPL + MOVE SP,-4(TP) + MOVE C,(TP) ; RESET 1 STEP + MOVEM C,1STEPR+1(PVP) + SUB TP,[6,,6] + PUSHJ P,CHUNSW + CAMN E,PVP + SUB TP,[4,,4] ; NO PROCESS CHANGE, POP JUNK + CAMN E,PVP + JRST .+4 + MOVE D,TPSTO+1(E) + SUB D,[4,,4] + MOVEM D,TPSTO+1(E) ; FIXUP HIS STACK +DO.H1: GETYP A,A ; CHECK FOR A DISMISS + CAIN A,TDISMI + JRST SUBTP4 + MOVE B,(TP) ; TRY FOR NEXT HANDLER + SKIPE B,INXT+1(B) + JRST NXHND +SUBTP4: SUB TP,[4,,4] + POPJ P, + +MFUNCTION INTAPL,SUBR,[RUNINT] + JRST APPLY + + +NOHAND: JUMPE C,NOHAN1 + PUSH TP,$TATOM + PUSH TP,EQUOTE INTERNAL-INTERRUPT +NOHAN1: PUSH TP,(AB) + PUSH TP,1(AB) + PUSH TP,$TATOM + PUSH TP,EQUOTE NOT-HANDLED + SKIPE A,C + MOVEI A,1 + ADDI A,2 + JRST CALER + +DEFERR: PUSH TP,$TATOM + PUSH TP,EQUOTE ATTEMPT-TO-DEFER-UNDEFERABLE-INTERRUPT + PUSH TP,$TINTH + PUSH TP,B + PUSH TP,$TATOM + PUSH TP,MQUOTE INTERRUPT + MCALL 3,RERR ; FORCE REAL ERROR + JRST FINIS + +; FUNCTION TO DISMISS AN INTERRUPT TO AN ARBITRARY ACTIVATION + +MFUNCTION DISMISS,SUBR + + HLRZ 0,AB + JUMPGE AB,TFA + CAIGE 0,-6 + JRST TMA + MOVNI D,1 + CAIE 0,-6 + JRST DISMI3 + GETYP 0,4(AB) + CAIE 0,TFIX + JRST WTYP + SKIPGE D,5(AB) + JRST OUTRNG + +DISMI3: MOVEI A,(TB) + +DISMI0: HRRZ B,FSAV(A) + HRRZ C,PCSAV(A) + CAIE B,INTAPL + JRST DISMI1 + + MOVE E,OTBSAV(A) + MOVEI 0,(A) ; SAVE FRAME + MOVEI A,DISMI2 + HRRM A,PCSAV(E) ; GET IT BACK HERE + MOVE A,(AB) + MOVE B,1(AB) + MOVE C,TPSAV(E) + MOVEM A,-7(C) + MOVEM B,-6(C) + MOVEI C,0 + CAMGE AB,[-3,,] + MOVEI C,2(AB) + MOVE B,0 ; DEST FRAME + JUMPL D,.+3 + MOVE A,PSAV(E) ; NOW MUNG SAVED INT LEVEL + MOVEM D,-1(A) ; ZAP YOUR MUNGED + PUSHJ P,CHUNW ; CHECK ON UNWINDERS + JRST FINIS ; FALL DOWN + +DISMI1: MOVEI E,(A) + HRRZ A,OTBSAV(A) + JUMPN A,DISMI0 + + MOVE A,(AB) + MOVE B,1(AB) + + PUSH TP,A + PUSH TP,B + SKIPGE A,D + JRST .+4 + CAMG A,CURPRI + PUSHJ P,UNQUEU + MOVEM A,CURPRI + CAML AB,[-3,,] + JRST .+5 + PUSH TP,2(AB) + PUSH TP,3(AB) + MCALL 2,ERRET + JRST FINIS + + POP TP,B + POP TP,A + JRST FINIS + +DISMI2: MOVE C,(TP) + MOVEM C,1STEPR+1(PVP) + MOVE SP,-4(TP) + SUB TP,[6,,6] + PUSHJ P,CHUNSW ; UNDO ANY PROCESS HACKING + MOVE C,TP + CAME E,PVP ; SWAPED? + MOVE C,TPSTO+1(E) + MOVE D,-1(C) + MOVE 0,(C) + SUB TP,[4,,4] + SUB C,[4,,4] ; MAYBE FIXUP OTHER STACK + CAME E,PVP + MOVEM C,TPSTO+1(E) + PUSH TP,D + PUSH TP,0 + PUSH TP,A + PUSH TP,B + MOVE A,-1(P) ; SAVED PRIORITY + CAMG A,CURPRI + PUSHJ P,UNQUEU + MOVEM A,CURPRI + SKIPN -1(TP) + JRST .+3 + MCALL 2,ERRET + JRST FINIS + + SUB TP,[4,,4] + MOVSI A,TDISMI + MOVE B,MQUOTE T + JRST DO.H1 + +CHNGT1: HLRE B,AB + SUBM AB,B + GETYP 0,-2(B) + CAIE 0,TCHAN + JRST WTYP3 + MOVE B,-1(B) + MOVSI A,TCHAN + POPJ P, + +GTLOC1: GETYP A,2(AB) + PUSHJ P,LOCQ + JRST WTYP2 + MOVE D,B ; RET ATOM FOR ASSOC + MOVE A,2(AB) + MOVE B,3(AB) + POPJ P, + ; MONITOR CHECKERS + +MONCH0: HLLZ 0,(B) ; POTENTIAL MONITORS +MONCH: TLZ 0,TYPMSK ; KILL TYPE + IOR C,0 ; IN NEW TYPE + PUSH P,0 + MOVEI 0,(B) + CAIL 0,HIBOT + JRST PURERR + POP P,0 + TLNN 0,.WRMON ; SKIP IF WRITE MONIT + POPJ P, + +; MONITOR IS ON, INVOKE HANDLER + + PUSH TP,A ; SAVE OBJ + PUSH TP,B + PUSH TP,C + PUSH TP,D ; SAVE DATUM + MOVSI C,TATOM ; PREPARE TO FIND IT + MOVE D,MQUOTE WRITE,WRITE,INTRUP + PUSHJ P,IGET + JUMPE B,MONCH1 ; NOT FOUND IGNORE FOR NOW + PUSH TP,A ; START SETTING UP CALL + PUSH TP,B + PUSH TP,-5(TP) + PUSH TP,-5(TP) + PUSH TP,-5(TP) + PUSH TP,-5(TP) + PUSHJ P,FRMSTK ; PUT FRAME ON STAKC + MCALL 4,EMERGE ; DO IT +MONCH1: POP TP,D + POP TP,C + POP TP,B + POP TP,A + HLLZ 0,(B) ; UPDATE MONITORS + TLZ 0,TYPMSK + IOR C,0 + POPJ P, + +; NOW FOR READ MONITORS + +RMONC0: HLLZ 0,(B) +RMONCH: TLNN 0,.RDMON + POPJ P, + PUSH TP,A + PUSH TP,B + MOVSI C,TATOM + MOVE D,MQUOTE READ,READ,INTRUP + PUSHJ P,IGET + JUMPE B,RMONC1 + PUSH TP,A + PUSH TP,B + PUSH TP,-3(TP) + PUSH TP,-3(TP) + PUSHJ P,FRMSTK ; PUT FRAME ON STACK + MCALL 3,EMERGE +RMONC1: POP TP,B + POP TP,A + POPJ P, + +; PUT THE CURRENT FRAME ON THE STACK + +FRMSTK: PUSHJ P,MAKACT + HRLI A,TFRAME + PUSH TP,A + PUSH TP,B + POPJ P, + +; HERE TO COMPLAIN ABOUT ATTEMPTS TO MUNG PURE CODE + +PURERR: PUSH TP,$TATOM + PUSH TP,EQUOTE ATTEMPT-TO-MUNG-PURE-STRUCTURE + PUSH TP,A + PUSH TP,B + MOVEI A,2 + JRST CALER + +; PROCESS SWAPPING CODE + +CHSWAP: MOVE E,PVP ; GET CURRENT + POP P,0 + SKIPE D,INTPRO+1(B) ; SKIP IF NO PROCESS GIVEN + CAMN D,PVP ; SKIP IF DIFFERENT + JRST PSHPRO + + PUSHJ P,SWAPIT ; DO SWAP + +PSHPRO: PUSH TP,$TPVP + PUSH TP,E + JRST @0 + +CHUNSW: MOVE E,PVP ; RET OLD PROC + MOVE D,-2(TP) ; GET SAVED PROC + CAMN D,PVP ; SWAPPED? + POPJ P, + +SWAPIT: PUSH P,0 + MOVE 0,PSTAT+1(D) ; CHECK STATE + CAIE 0,RESMBL + JRST NOTRES + MOVEM 0,PSTAT+1(PVP) + MOVEI 0,RUNING + MOVEM 0,PSTAT+1(D) ; SAVE NEW STATE + POP P,0 + POP P,C + JRST SWAP" + + +;SUBROUTINE TO GET BIT FOR CLOBBERAGE + +GETBIT: MOVNS B ;NEGATE + MOVSI A,400000 ;GET THE BIT + LSH A,(B) ;SHIFT TO POSITION + POPJ P, ;AND RETURN + +;HERE TO HANDLE PDL OVERFLOW. ASK FOR A GC + +IPDLOV: +IFN ITS,[ + MOVEM A,TSINT ;SAVE INT WORD +] + + SKIPE GCFLG ;IS GC RUNNING? + JRST GCPLOV ;YES, COMPLAIN GROSSLY + + MOVEI A,200000 ;GET BIT TO CLOBBER + IORM A,PIRQ ;LEAVE A MESSAGE FOR HIGHER LEVEL + + EXCH P,GCPDL ;GET A WINNING PDL + HRRZ B,TSINTR ;GET POINTER TO LOSING INSTRUCTION + SKIPG GCPDL ; SKIP IF NOT P + LDB B,[270400,,-1(B)] ;GET AC FIELD + SKIPL GCPDL ; SKIP IF P + MOVEI B,P + MOVEI A,(B) ;COPY IT + LSH A,1 ;TIMES 2 + ADDI A,0STO(PVP) ;POINT TO THIS ACS CURRENT TYPE + HLRZ A,(A) ;GET THAT TYPE INTO A + CAIN B,P ;IS IT P + MOVEI B,GCPDL ;POINT TO SAVED P + + CAIN B,B ;OR IS IT B ITSELF + MOVEI B,TSAVB + CAIN B,A ;OR A + MOVEI B,TSAVA + + CAIN B,C ;OR C + MOVEI B,1(P) ;C WILL BE ON THE STACK + + PUSH P,C + PUSH P,A + + MOVE A,(B) ;GET THE LOSING POINTER + MOVEI C,(A) ;AND ISOLATE RH + + CAMG C,VECTOP ;CHECK IF IN GC SPACE + CAMG C,VECBOT + JRST NOGROW ;NO, COMPLAIN + +; FALL THROUGH + + + HLRZ C,A ;GET -LENGTH + SUBI A,-1(C) ;POINT TO A DOPE WORD + POP P,C ;RESTORE TYPE INTO C + PUSH P,D ; SAVE FOR GROWTH HACKER + MOVEI D,0 + CAIN C,TPDL ; POIN TD TO APPROPRIATE DOPE WORD + MOVEI D,PGROW + CAIN C,TTP + MOVEI D,TPGROW + JUMPE D,BADPDL ; IF D STILL 0, THIS PDL IS WEIRD + MOVEI A,PDLBUF(A) ; POINT TO ALLEGED REAL DOPE WORD + SKIPN (D) ; SKIP IF PREVIOUSLY BLOWN + MOVEM A,(D) ; CLOBBER IN + CAME A,(D) ; MAKE SURE IT IS THE SAME + JRST PDLOSS + POP P,D ; RESTORE D + + +PNTRHK: MOVE C,(B) ;RESTORE PDL POINTER + SUB C,[PDLBUF,,0] ;FUDGE THE POINTER + MOVEM C,(B) ;AND STORE IT + + POP P,C ;RESTORE THE WORLD + EXCH P,GCPDL ;GET BACK ORIG PDL +IFN ITS,[ + MOVE A,TSINT ;RESTORE INT WORD + + JRST IMPCH ;LOOK FOR MORE INTERRUPTS +] +IFE ITS, JRST GCQUIT + +TPOVFL: SETOM INTFLG ;SIMULATE PDL OVFL + PUSH P,A + MOVEI A,200000 ;TURN ON THE BIT + IORM A,PIRQ + SUB TP,[PDLBUF,,0] ;HACK STACK POINTER + HLRE A,TP ;FIND DOPEW + SUBM TP,A ;POINT TO DOPE WORD + MOVEI A,1(A) ; ZERO LH AND POINT TO DOPEWD + SKIPN TPGROW + HRRZM A,TPGROW + CAME A,TPGROW ; MAKE SURE WINNAGE + JRST PDLOSS + POP P,A + POPJ P, + + +; GROW CORE IF PDL OVERFLOW DURING GC + +GCPLOV: MOVE A,P.TOP ; GET TOP OF IMPURE + ASH A,-10. ; TO BLOCKS + EXCH P,GCPDL ; NEED A PDL TO CALL P.CORE + ADDI A,1 ; GO TO NEXT BLOCK +GRECOR: PUSHJ P,P.CORE ; GET CORE + JRST SLPCOR ; HANG GETTING THE CORE + EXCH P,GCPDL ; BPDLS BACK + ADD P,[-2000,,0] +IFE ITS, JRST GCQUIT +IFN ITS,[ + MOVE A,TSINT + JRST IMPCH + + +SLPCOR: MOVEI B,1 + .SLEEP B, + JRST GRECOR + +] + +IFN ITS,[ + +;HERE TO HANDLE LOW-LEVEL CHANNELS + + +CHNACT: SKIPN GCFLG ;GET A WINNING PDL + EXCH P,GCPDL + ANDI A,177777 ;ISOLATE CHANNEL BITS + PUSH P,0 ;SAVE + +CHNA1: MOVEI B,0 ;BIT COUNTER + JFFO A,.+2 ;COUNT + JRST CHNA2 + SUBI B,35. ;NOW HAVE CHANNEL + MOVMS B ;PLUS IT + MOVEI 0,1 + LSH 0,(B) + ANDCM A,0 + MOVEI 0,(B) ; COPY TO 0 + LSH 0,23. ;POSITION FOR A .STATUS + IOR 0,[.STATUS 0] + XCT 0 ;DO IT + ANDI 0,77 ;ISOLATE DEVICE + CAILE 0,2 + JRST CHNA1 + +PMIN4: MOVE 0,B ; CHAN TO 0 + .ITYIC 0, ; INTO 0 + JRST .+2 ; DONE, GO ON + JRST PMIN4 + SETZM GCFLCH ; LEAVE GC MODE + JRST CHNA1 + +CHNA2: POP P,0 + SKIPN GCFLG + EXCH P,GCPDL + JRST GCQUIT + +HOWMNY: SETZ + SIXBIT /LISTEN/ + D + 402000,,B +] + +MFUNCTION GASCII,SUBR,ASCII + ENTRY 1 + + GETYP A,(AB) + CAIE A,TCHRS + JRST TRYNUM + + MOVE B,1(AB) + MOVSI A,TFIX + JRST FINIS + +TRYNUM: CAIE A,TFIX + JRST WTYP1 + SKIPGE B,1(AB) ;GET NUMBER + JRST TOOBIG + CAILE B,177 ;CHECK RANGE + JRST TOOBIG + MOVSI A,TCHRS + JRST FINIS + +TOOBIG: PUSH TP,$TATOM + PUSH TP,EQUOTE ARGUMENT-OUT-OF-RANGE + JRST CALER1 + + +;HERE IF PDL OVERFLOW DURING GARBAGE COLLECTION + +BADPDL: FATAL NON PDL OVERFLOW + +NOGROW: FATAL PDL OVERFLOW ON NON EXPANDABLE PDL + +PDLOSS: FATAL PDL OVEFLOW BUFFER EXHAUSTED + +DLOSER: PUSH P,LOSRS(B) + MOVE A,TSAVA + MOVE B,TSAVB + POPJ P, + +LOSRS: IMPV + ILOPR + IOC + IPURE + + +;MEMORY PROTECTION INTERRUPT + +IOC: FATAL IO CHANNEL ERROR IN GARBAGE COLLECTOR +IMPV: FATAL MPV IN GARBAGE COLLECTOR + +IPURE: FATAL PURE WRITE IN GARBAGE COLLECTOR +ILOPR: FATAL ILLEGAL OPEREATION IN GARBAGE COLLECTOR + +IFN ITS,[ + +;SUBROUTINE TO BE CALLED AT INITIALIZE TIME TO SETUP INTS + +INTINT: SETZM CHNCNT + MOVE A,[CHNCNT,,CHNCNT+1] + BLT A,CHNCNT+16. + SETZM INTFLG + .SUSET [.SPICLR,,[-1]] + MOVE A,MASK1 ;SET MASKS + MOVE B,MASK2 + .SETM2 A, ;SET BOTH MASKS + MOVSI A,TVEC + MOVEM A,QUEUES(TVP) + SETZM QUEUES+1(TVP) ;UNQUEUE ANY OLD INTERRUPTS + SETZM CURPRI + POPJ P, +] +IFE ITS,[ + +; INITIALIZE TENEX INTERRUPT SYSTEM + +INTINT: CIS ; CLEAR THE INT WORLD + SETZM INTFLG ; IN CASE RESTART + MOVSI A,TVEC ; FIXUP QUEUES + MOVEM A,QUEUES(TVP) + SETZM QUEUES+1(TVP) + SETZM CURPRI ; AND PRIORITY LEVEL + MOVEI A,MFORK ; TURN ON MY INTERRUPTS + MOVE B,[LEVTAB,,CHNTAB] ; POINT TO TABLES + SIR ; TELL SYSTEM ABOUT THEM + MOVE B,MASK1 ; SET UP FOR INT BITS + AIC ; TURN THEM ON + MOVSI A,7 ; CNTL G AND CHANNEL 0 + ATI ; ACTIVATE IT + MOVE A,[23,,1] ; CNTL S AND CHANNEL 1 + ATI ; ACTIVATE IT + MOVEI A,MFORK ; DO THE ENABLE + EIR + POPJ P, +] + + +; CNTL-G HANDLER + +MFUNCTION QUITTER,SUBR + + ENTRY 2 + GETYP A,(AB) + CAIE A,TCHRS + JRST WTYP1 + GETYP A,2(AB) + CAIE A,TCHAN + JRST WTYP2 + MOVE B,1(AB) + MOVE A,(AB) + CAIN B,^S ; HANDLE CNTL-S + JRST RETLIS + CAIE B,7 + JRST FINIS + + PUSHJ P,CLEAN ; CLEAN UP I/O CHANNELS + PUSH TP,$TATOM + PUSH TP,EQUOTE CONTROL-G? + MCALL 1,ERROR + JRST FINIS + +RETLIS: MOVEI D,(TB) ; FIND A LISTEN OR ERROR TO RET TO + +RETLI1: HRRZ A,OTBSAV(D) + HRRZ C,FSAV(A) ; CHECK FUNCTION + CAIE C,LISTEN + CAIN C,ERROR ; FOUND? + JRST FNDHIM ; YES, GO TO SAME + CAIN C,ERROR% ; FUNNY ERROR + JRST FNDHIM + CAIN C,TOPLEV ; NO ERROR/LISTEN + JRST FINIS + MOVEI D,(A) + JRST RETLI1 + +FNDHIM: PUSH TP,$TTB + PUSH TP,D + PUSHJ P,CLEAN + MOVE B,(TP) ; NEW FRAME + SUB TP,[2,,2] + MOVEI C,0 + PUSHJ P,CHUNW ; UNWIND? + MOVSI A,TATOM + MOVE B,MQUOTE T + JRST FINIS + +CLEAN: MOVE B,3(AB) ; GET IN CHAN + PUSHJ P,RRESET + MOVE B,3(AB) ; CHANNEL BAKC + MOVE C,BUFRIN(B) + SKIPN C,ECHO(C) ; GET ECHO + JRST CLUNQ +IFN ITS,[ + MOVEI A,2 + CAMN C,[PUSHJ P,MTYO] + JRST TYONUM + LDB A,[270400,,C] +TYONUM: LSH A,23. + IOR A,[.RESET] + XCT A +] +IFE ITS,[ + MOVEI A,101 ; OUTPUT JFN + CFOBF +] + +CLUNQ: SETZB A,CURPRI + JRST UNQUEU + + +IMPURE +ONINT: 0 ; INT FUDGER +IFN ITS,[ +;RANDOM IMPURE CRUFT NEEDED +CHNCNT: BLOCK 16. ; # OF CHARS IN EACH CHANNEL + +TSAVA: 0 +TSAVB: 0 +PIRQ: 0 ;HOLDS REQUEST BITS FOR 1ST WORD +PIRQ2: 0 ;SAME FOR WORD 2 +PCOFF: 0 +MASK1: 1200,,220540 ;FIRST MASK +MASK2: 0 ;SECOND THEREOF +CURPRI: 0 ; CURRENT PRIORITY +] +IFE ITS,[ +NETJFN: BLOCK NNETS +MASK1: CHNMSK +TSINTR: +P1: 0 ; PC INT LEVEL 1 +P2: 0 ; PC INT LEVEL 2 +P3: 0 ; PC INT LEVEL 3 +CURPRI: 0 +TSAVA: 0 +TSAVB: 0 +PIRQ: 0 +PIRQ2: 0 +] +PURE + +END + \ No newline at end of file