ER[PISYS]; *I = 99 + 32 DATA IM ENTRIES *RIGHT BANK ALLOCATION *10 DISK CHECKSUM REGISTERS, THEN RVN[RTEMP]; RVN[RTEMP1]; RVN[ICTR]; RVN[OLDPC]; RVN[REFADR]; RVN[RPGRT]; RVN[RPGRT2]; RVN[RPGRT3]; *LEFT BANK ALLOCATION *20 AC'S, THEN LVN[LTEMP]; LVN[LEFADR]; LVN[LPGRT]; LVN[LPGRT2]; LVN[LPGRT3]; LV[-1L,777777 777777]; %SCRATCH MEMORY ALLOCATION WORDS 0-17 AND 400-777 ARE NOT ADDRESSABLE EXCEPT BY USING THE Y REGISTER. WORDS 0-43 HOLD VALUES 2^N WHERE N = THE LOCATION. WORDS 0-327 HOLD CONSTANTS, 330-376 HOLD VARIABLES. WORDS 400-600 ARE USED BY THE DISK DRIVER MICROCODE TO KEEP TRACK OF THE STATE OF THE 8 DISK UNITS. EACH UNIT GETS A BLOCK OF 20B WORDS. 600-643 INTTAB; 644-652 IONTAB; WORD 17 OF EACH DISK BLOCK FOR INSTRUCTION COUNTERS, WORD 16 FOR EVENT COUNTERS. WORD 15 FOR BLISP STATE DISPATCH % SM[IOTD,653]; *IO DISPATCH TABLE FOR OPCODES 700 AND 712 SM[BLDISP,677]; *BLISP OPCODE DISPATCH SM[BLOPXT,713]; *BLISP OPCODE EXTENSION *! MAXC1 ONLY SM[CHKTAB,753]; *CHECKER CONTROL TABLE *! *~ MAXC2 ONLY SM[CHKTAB,752]; *CHECKER CONTROL TABLE *~ SM[KCOMS,766]; *DISK COMMAND TRIPLE DISPATCH TO 777 TARGET[SLC]; %THIS TABLE IS USED TO CONVERT INTEGER I INTO 2^I. THIS IS NEEDED TO CONVERT DEVICE NUMBERS INTO DEVICE BIT MASKS. ALSO, MOST OF THE ONE BIT NUMBERS ARE USED ELSEWHERE IN THE MICROCODE. % 1V; 2V; 4V; 10V; 20V; 40V; 100V; 200V; 400V; 1000V; 2000V; 4000V; 10000V; 20000V; 40000V; 100000V; SV[200000S,200000]; SV[400000S,400000]; SV[1 000000S,1 000000]; SV[2 000000S,2 000000]; SV[4 000000S, 4 000000]; SV[10 000000S,10 000000]; SV[20 000000S,20 000000]; SV[40 000000S,40 000000]; SV[100 000000S,100 000000]; SV[200 000000S,200 000000]; SV[400 000000S,400 000000]; SV[1000 000000S,1000 000000]; SV[2000 000000S,2000 000000]; SV[4000 000000S,4000 000000]; SV[10000 000000S,10000 000000]; SV[20000 000000S,20000 000000]; SV[40000 000000S,40000 000000]; SV[100000 000000S,100000 000000]; SV[200000 000000S,200000 000000]; SV[400000 000000S,400000 000000]; %TABLE OF L.H.'S FOR "WPC" USED BY "LENTER". B[0,10] HOLD THE CYCLE VALUE FOR POSITIONING THE CURRENT BYTE; B[11,14] HOLD 1 (LOADED INTO AC); B[16,20] HOLD A COUNT WHICH OVERFLOWS INTO THE INDIRECT BIT ON ADVANCING FROM BYTE 4 TO BYTE 0 OF THE NEXT WORD; B[21,22] HOLD THE LOW BITS OF PC FOR THE PREVIOUS BYTE. MUST BE BOUNDARY OF 4. % B4TAB: 33037 000000V; 22044 000000V; 11051 000000V; 56 000000V; SV[-1S,777777 777777]; *CONSTANTS USED EITHER IN PISYS OR IN MORE THAN ONE OTHER FILE MC[NOVA&H,NOVA,H]; MC[PICYCLE&K,PICYCLE,K]; MC[PIACTIVE&G,PIACTIVE,G]; MC[PIACTIVE&MICRO,PIACTIVE,MICRO]; MC[NOVA&MICRO&H,NOVA,MICRO,H]; MC[UM&J,UM,J]; MC[UM&J&K,UM,J,K]; SM[G,IP[1S]]; ***DEPARAMETERIZED TO MERGE IDENTICAL CONSTANTS SM[H,IP[2S]]; *** SM[J,IP[4S]]; *** SM[K,IP[10S]]; *** SM[IENABLE,IP[100S]]; *** SM[MICRO,IP[200S]]; *** MC[TFLAGSPI,UM,XCTN]; MC[INCMP&K,INCMP,K]; ***KLUDGES SO THAT MICROCODE DOESN'T HAVE TO BE ASSEMBLED IN SERIES MC[CFM&UM&G,CFM,UM,G]; *USED BY SLH AND CONT MC[BIS&MD0&MD1&MD2&J,MD0,MD1,MD2,BIS,J]; *USED BY CONT MC[MD2&G,MD2,G]; *USED BY MAP, BLISP SM[OVF,IP[400000 000000S]]; ***USED BY "ARITH" AND "IOCOM" SM[FOVF,IP[40000 000000S]]; ***USED BY "IOCOM" MC[FINTS,OVF,FOVF,PDOVF]; MC[LOGF&K,LOGF,K]; *INTER-PROCESSOR COMMUNICATION LOCATIONS. *SM[SWICH,IP[0S]]; *WORD FOR SIMULATED DATA SWITCHES *SM[LITES,IP[1S]]; *FOR OUTPUT TO SIMULATED LIGHTS %SM[MTBS,IP[3S]]; *POINTS AT NVIO COMMUNICATION BLOCK (NOT PRESENTLY USED): (0) TMC CONO WORD (1) MAXC INPUT MAGTAPE WORD COUNT (2) NVCHKA ARG FOR NVIO BUGCHK'S (3) MAGTAPE STATUS INPUT (4) MTAC1 NOT USED BY MICROCODE (5,10) PAGE CROSSING REMAP WORDS BITS 0:17 PREVIOUS PAGE, 20:37 NEW PAGE (11) TODCLK (12) CDVS (13) NVIO BUGCHK POINTER (14,23) MAGTAPE STATUS WORDS (24) PSCAN (25) MEMORY ERRORS AS READ BY HARDWARE (26,31) MCA INPUT BUFFER (BEGIN, MAXC READ, NOVA WRITE, END) (32,35) MCA OUTPUT BUFFER (BEGIN, NOVA READ, MAXC WRITE, END) (36,76) MCA BYTES OUTPUT BY MAXC (77,137) MCA BYTES OUTPUT BY NOVA (140) NVIO FREE STORAGE (141,240) MCA HOST TRANSLATION TABLE (241,264) FLASHING REGISTER CAPTION (80 8-BIT BYTES) (265,271) FLASHING REGISTER POINTERS (272) PUP INPUT BUFFER POINTER (273) PUP OUTPUT BUFFER POINTER (274) IMP INPUT BUFFER POINTER (275) IMP OUTPUT BUFFER POINTER (276) IMP STATUS IN % SM[DLSBS,IP[4S]];*POINTS TO 104 WORD BLOCK: MUST NOT CROSS PAGE BOUNDARY %(0) OUTPUT DONE BIT WORD (2) DO-OUTPUT BIT WORD (3) DO-INPUT BIT WORD 100-WORD IN-OUT BUFFER % SM[MAXNV,IP[5S]]; *BIT TABLE FOR SIGNALS FROM MAXC TO NOVA %BITS IN MAXNV (NOT USED BY MICROCODE EXCEPT I/O RESET REQUEST): (37) PUP BEGIN OUTPUT (36) PUP BEGIN INPUT (35) MAXC INTERRUPT CHANGE DEVICE SPEED (34) IMP BEGIN INPUT (33) MAXC INTERRUPT MCA OUTPUT (32) IMP BEGIN OUTPUT (27) MAXC INTERRUPT CONO TMC REQUEST (25) MAXC INTERRUPT DLS OUTPUT REQUEST (24) MAXC INTERRUPT I/O RESET REQUEST % SM[NVMAX,IP[6S]]; *BIT WORD FOR SIGNALS FROM NOVA TO MAXC *7 = PROGRAM STARTING ADDRESS FOR CONSOLE "START" TARGET[ILC]; *5, 11, 12, AND 13 ARE INITIALIZED BY KINT. *MICROPROCESSOR SOMETIMES CRASHES AT 0 AND 1 ON FUNNY INTERRUPTS REPEAT[2,ILC[(BRKP[1], FRZBALUBC, CALL[SCRASH])]]; PPQ: P_P+Q, RETURN; *BLISP UPQ: Q_P OR Q, FRZBALUBC, INHINT, RETURN; CLRPQ: Q_P AND NOT Q, FRZBALUBC, INHINT, RETURN; IM[ILC,6]; PQORP: RTEMP_P_P OR Q, FRZBALUBC, RETURN; QNQ: Q_NOT Q, RETURN; *ARITH PMDR: P_MDR, FRZBALUBC, RETURN; *MAP, MAIN, BLISP IM[ILC,14]; QL1: Q LSH 1, FRZBALUBC, RETURN; *BLISP PMQ: P_P-Q, Q_RTEMP, RETURN; *BLISP, MAP %"SPUNT" CALLED FOR A SOFT HALT. ;P TO MIDAS PROCEEDS SAFELY. "SCRASH" CALLED FOR A HARD HALT. ;P IS A NO-OP AFTER A CRASH. THE CONCEPT BEHIND PUNT AND CRASH IS THAT A NAIVE USER SHOULD BE ABLE TO WALK UP AND OPTIMISTICALLY TYPE ;P WITH A REASONABLE HOPE OF RESTARTING THE SYSTEM AND NO CHANCE AT ALL OF MAKING THINGS WORSE. "START" (LOCATION 23) LOADS PC FROM MAIN 7 AND RUNS. "RESET" (LOCATION 21) PERFORMS A PROCESSOR RESET, CLEARING THE MAP, APR, AND PI SYSTEM, BUT NOT CHANGING THE PC NOR SENDING IORESET TO THE NOVA. "RESET" FINISHES AT "PUNT" WITH "START" ON THE STACK. "INIT" CHECKS OUT THE MICROPROCESSOR AND MICROCODE WITH WHATEVER STUFF IS AVAILABLE, PUNTING IF EVERYTHING IS OK, CRASHING IF SOMETHING IS FOUND TO BE WRONG. % SCRASH: LPGRT3_P, P_400000S, DGOTO[.+1]; B_P_P-1, GOTO[.,ALU>=0]; P_LPGRT3, BRKP[1], FRZBALUBC, GOTO[.]; *NVIO KNOWS RESET=21 RESET: INHINT, LPGRT3_P, Q_SSRC[LOGT], CALL[PRESC]; *PRESERVE LOGT SSINK[LOGT], BQ, CALL[SPUNT]; *NVIO KNOWS START=23 START: READ_7S, CALL[RETN]; SSINK[PC], MDR, GOTO[REMAPPC]; *=PC_MDR (BYPASS FORWARD REF. PROBLEM) INIT: Q_A0, AC_10S, CALL[CHECK]; *SLOW PUNT TO LET DISK TRANSFERS FINISH (CLOBBERS BALUBC, LPGRT3) SPUNT: LPGRT3_P, P_400000S, DGOTO[.+1]; B_P_P-1, GOTO[.,ALU>=0]; P_LPGRT3, FRZBALUBC, BRKP[1], RETURN; %THE PARAMETERS WHICH CAN BE CHANGED BY "SLOC" ARE ASSIGNED LOCATIONS IN THE SM TABLE BEGINNING AT "SLMIC" AND ARE ENUMERATED BELOW. THESE VARIABLES, INTCONDH, PISTAT, MICINTS, NOTFCOND, APRPIMCOND, APRLEV, THE 44 "INTTAB" ENTRIES, AND 7 "IONTAB" ENTRIES ARE RESTORED FROM AN IM TABLE CALLED "GOTAB" WHENEVER THE CONSOLE "RESET" FUNCTION IS EXECUTED. % SV[RESCNT,23]; *RESTORE COUNT - 1 = SLOC LENGTH + 10 - 1 SM[SLOCLOW,IP[14S]]; *SLOC TABLE LENGTH SLC[GOTAB: E1[ILC]]; *ORIGIN OF IM TABLE SET[SLMIC,IP[VSLC]]; *ORIGIN OF SM TABLE *ORIGIN OF IM TABLE W[0,0,571,0,0,3000]; SVN[TSTAT]; SVN[MBASE]; W[0,2,0,0,0,4000]; SVN[SPT]; SVN[CST]; W[0,0,70,0,0,71]; SVN[MLTRAP]; SVN[PSWITCH]; W[0,0,1000,0,3,4000]; SVN[JSYST]; SVN[LOGT]; W[0,0,0,0,0,0]; SVN[ST]; SVN[SNIL]; W[0,0,0,0,0,0]; SVN[SKPRGLM]; SVN[TYPTAB]; *THE 10 VARIABLES BELOW ARE ALSO RESTORED BY RESET W[0,0,22,0,0,0]; SVN[INTCONDH]; *NOVA&H=22 SVN[MICINTS]; *0 W[7777,5777,7777,2200,0,0]; SVN[NOTFCOND]; *NMC[PDOVF] SVN[APRPIMCOND]; *MC[NXM,POWFB] W[0,0,0,0,0,7]; SVN[APRLEV]; *0 SVN[@ICTR]; *POINTER TO CURRENT INSTRUCTION COUNTER SM[EVCTR,16]; *EVENT COUNTERS STORED IN WORD 16 OF EACH DISK BLOCK *0 NO. TIMES MAP LOADED *1 COUNT OF CALLS TO "PIX" SM[YICTR,17]; *INSTRUCTION COUNTERS STORED IN WORD 17 OF EACH DISK BLOCK W[0,0,0,0,0,0]; SVN[PISTAT]; SVN[RESV]; *RESERVE LOCATION SVN[PC]; *PROGRAM COUNTER SVN[STEMP]; SVN[STEMP1]; %WHEN AN INTERRUPT BEGINS AT SOME PRIORITY LEVEL, A MICROCODED ROUTINE IS EXECUTED FIRST. NO HIGHER PRIORITY INTERRUPTS OCCUR UNTIL THE PDP-10 PORTION OF THE INTERRUPT ROUTINE IS ENTERED THROUGH A PI CYCLE. ALSO, WHEN TWO DEVICES ARE ASSIGNED THE SAME PRIORITY, THE ONE WITH THE RIGHTMOST BIT ASSIGNMENT (SMALLEST DEVICE NUMBER) IS SERVICED FIRST. THE MICROCODE MAINTAINS TWO SM TABLES: "IONTABX"+1 POINTS TO A SEVEN-WORD TABLE WHOSE ENTRIES CONTAIN ONES IN THE BIT POSITIONS CORRESPONDING TO DEVICES ASSIGNED TO THE PRIORITY LEVEL (WORD 0 IS FOR PRIORITY 1, WORD 1 FOR PRIORITY 2, ETC.); "INTTAB" POINTS TO A 44-WORD TABLE WHOSE ENTRIES CONTAIN A 1-BIT FLAG, AN 11-BIT MICROADDRESS, AND 24-BIT PARAMETER. THE BIT POSITIONS IN MICINTS AND IN NVMAX ALSO CORRESPOND TO THESE DEVICES. THE FLAG=0 WILL SET G=1 ON INTERRUPTS AND SIGNALS "PICYC" NOT TO CLEAR THE INTERRUPT REQUEST IN MICINTS. THE DEVICE NUMBERS AND INTERPRETATION ARE GIVEN BELOW: 0-7 DISKS KPISV (AUTOMATIC DISMISSAL) 10 CLOCK CPICYC (MANUAL DISMISSAL) 11 MAGTAPE CPICYC 12 UNUSED CPICYC 13 DLS PICYC (AUTODISMISSING) 14 IMP INPUT DONE PICYC 15 IMP OUTPUT DONE PICYC 16 PUP INPUT DONE PICYC 17 PUP OUTPUT DONE PICYC 20-25 UNUSED PICYC 26 PUSHDOWN OVERFLOW CPICYC 27 UNUSED PICYC 30-36 MANUAL INTERRUPTS 7-1 PICYC 37 POWER FAILURE CPICYC 40 FLOATING OVERFLOW CPICYC 41 PARITY CPICYC 42 MEMORY TIMEOUT CPICYC 43 OVERFLOW CPICYC "PICYC" EXECUTES A PICYCLE AT THE ADDRESS CONTAINED IN THE 24-BIT PARAMETER IN "INTTAB" POINTED TO BY "STEMP1", DISMISSING THE REQUEST IFF G=1. **K = 1 FOR XCT, G=1 IFF SIGN BIT FROM INTTAB=0. TIMING = M + 6 I = 6 % PICYC: Q_X_STEMP1; SETSF[UM&J], Y_Q, P_A1, XMASK; Q_P+1, P_MICINTS, INHINT; Q_P AND NOT Q, CLEARF[TFLAGSPI], INHINT, CALL[KPIS1,G=1]; MAPVA_Q_SY, P_777777R, ACFS; REFADR_P_P AND Q, SETF[PICYCLE&K], AC_NULL, GOTO[XCT]; %"KPISV" IS ENTERED FROM THE PI SYSTEM CODE WHEN A DISK INTERRUPT IS SERVICED. "STEMP1" CONTAINS A POINTER TO THE ENTRY FOR THE DEVICE IN "INTTAB". SO [STEMP1]-[INTTAB]-1 = [STEMP1]-600 = [STEMP1] AND 7 = UNIT NUMBER. "KPISV" IS RESPONSIBLE FOR STORING THE CURRENT DISK ADDRESS (ONLY THE CURRENT SECTOR, PACK, AND ARM POSITION NEED BE CORRECT) AT [KBLK] +2 AND FOR EXITING TO A PDP-10 SERVICE ROUTINE VIA A PICYCLE. EACH DISK UNIT SHOULD BE ASSIGNED BY THE PDP-10 TO A DIFFERENT INTERRUPT LOCATION (BUT PROBABLY THE SAME PRIORITY LEVEL). THE REASON WHY SOME STUFF IN THE SECTOR MICROINTERRUPT SERVICE ROUTINE IS NOT DONE BY "KPISV" (SUCH AS INCREMENTING THE SECTOR) IS THAT WE ENVISION PDP-10 PROGRAMS MANUALLY INITIATING DISK INTERRUPTS TO ACCOMPLISH COMMAND SETUP WHEN NEW REQUESTS ARRIVE, AND IF THE "KPISV" ROUTINE WERE INCREMENTING THE SECTOR, IT WOULD HAVE DIFFICULTY DISTINGUISHING BETWEEN A MANUALLY INITIATED INTERRUPT AND A REAL SECTOR INTERRUPT. THE PDP-10 DISK INTERRUPT SERVICE ROUTINE SHOULD 0 [KBLK+1] AFTER A COMMAND COMPLETION SO THAT MANUALLY INITIATED INTERRUPTS DON'T ATTEMPT TO CLEANUP THAT COMMAND AGAIN. **MUST NOT CLOBBER G (LEAVE IT =1 FOR PICYC) I = 5 % KPISV: Q_STEMP1, P_A1, BAMASK[3]; *KNOW INTTAB=600 YKPTR_X_P AND Q; *KNOW DISKS ARE DEVICES 0 TO 7 P_SSRC[KBLK]; P_P+1, MDR_SSRC[KA]; WRITE_P+1, INHINT, GOTO[PICYC]; SM[INTTAB,IP[600S]]; *INTTAB STARTS AT 600 (MUST BE BOUNDARY OF 100) SV[IONTABX,643]; *IONTAB STARTS AT 644 SV[IMINTT,IP[ILC]]; **THESE ARE PARAMETERIZED IN THE NOVA SOFTWARE AND EASY TO CHANGE SET[CPICYC,ADD[4000,IP[PICYC]]]; REPEAT[4,ILC[W[IP[KPISV],0,0,IP[KPISV],0,0]]]; MP[CLKB,33]; SV[CLKDV,610]; *APR CLOCK = DEVICE 10B SM[DLSDV,IP[13S]]; SM[DLSINT,IP[4000S]]; *DATA LINE SCANNER OR CONSOLE TTY INT. *CLOCK (10), MAGTAPE (11), --- (12), DLS (13) W[CPICYC,0,0,CPICYC,0,0]; W[CPICYC,0,0,IP[PICYC],0,0]; *IMP INPUT DONE (14), IMP OUTPUT DONE (15), PUP INPUT DONE (16), *PUP OUTPUT DONE (17), MCA INPUT DONE (20), (21-25 ALSO) REPEAT[5,ILC[W[IP[PICYC],0,0,IP[PICYC],0,0]]]; *PUSHDOWN OVERFLOW (26) AND UNASSIGNED (27) W[CPICYC,0,0,IP[PICYC],0,0]; SV[PDLDV,626]; *PUSHDOWN OVERFLOW W[IP[PICYC],0,56,IP[PICYC],0,54]; *MANUAL INTS. 7 AND 6 W[IP[PICYC],0,52,IP[PICYC],0,50]; *5 AND 4 W[IP[PICYC],0,46,IP[PICYC],0,44]; *3 AND 2 W[IP[PICYC],0,42,CPICYC,0,0]; *1 AND POWER FAILURE W[CPICYC,0,0,CPICYC,0,0]; *FLOATING OVERFLOW AND PARITY ERROR W[CPICYC,0,0,CPICYC,0,0]; *NON-EXISTENT MEMORY AND OVERFLOW SV[APRINTS,760020 000400]; *OVF, NXM, FOVF, PARITY, POWFB, PDOVF, CLKB SM[OVFDV,IP[IONTABX]]; *OVERFLOW (CONSOLE HALT) *IONTAB INITIALIZATION W[100,0,0,40,0,0]; W[20,0,0,10,0,0]; W[4,0,0,2,0,0]; W[1,0,0,0,0,0]; %THE "IREAD" AND "ILOAD" ROUTINES TRANSFER A BLOCK OF WORDS FROM IM TO SM OR FROM SM TO IM. ILOAD ISN'T USED CURRENTLY. ILOAD: Q_SY, INCY, GOTO[.+1]; NPC_P, GOTO[RETN,X<0]; I_Q, DGOTO[.+1], INHINT; *IM[0,43] Q_SY, INCY, GOTO[.+1]; NPC_P, DECX; I_Q, DGOTO[ILOAD], P_P+1; *IM[44,107] WASTE AN INSTRUCTION AFTER EACH READING OF IM BECAUSE OF PROBLEM WHEN DATA FROM IM SELECTS IM AS A BUS SOURCE OR DESTINATION. CALLED WITH IM ADDRESS IN P, COUNT - 1 OF SM REGISTERS TO FILL IN X, POINTER TO SM BLOCK IN Y I = 9 % *! MAXC1 ONLY IREAD0: Q_P, DECX, RETURN[X<0]; SY_Q, INCY, P_LTEMP, RETURN[X<0]; IREAD: NPC_MDR_P; P_I, DGOTO[.+1], LTEMP_P+1, INHINT; *IM[0,43] INHINT, GOTO[.+1]; *MUST BE NO-OP NPC_MDR, DECX, GOTO[.+1]; *NOT SURE WHETHER GOTO HERE IS NECESSARY P_I, DGOTO[.+1], Q_P; *IM[44,107] INHINT, GOTO[.+1]; *MUST BE NO-OP SY_Q, INCY, GOTO[IREAD0], INHINT; *! *~ MAXC2 ONLY IREAD: NPC_Q_P, DECX, GOTO[RETN,X<0]; I, DGOTO[.+1], P_P+1, INHINT; *EREG_IM[0,43] MDR_EREG, GOTO[.+1]; SY_MDR, INCY; NPC_Q, DECX, GOTO[RETN,X<0]; I, DGOTO[.+1]; *EREG_IM[44,107] MDR_EREG, GOTO[.+1]; SY_MDR, INCY, GOTO[IREAD]; *~ *SOME SHORT COMMON SUBROUTINES *I = 2 QF1: Q_1S, FRZBALUBC, RETURN; *BLISP QPQ: Q_P+Q, RETURN; *KINT %MAXC CHECKS FOR INTERRUPTS IN EXACTLY THOSE PLACES WHERE THE PDP-10 DOES. EACH POSSIBLE CAUSE OF AN INTERRUPT IS REPRESENTED BY A "1" IN F, SO THE CHECK IS ACCOMPLISHED BY THE FOLLOWING SEQUENCE: SETSF[INTCONDH]; GOTO[PI,H=1]; INTCONDH CONTAINS THE NOVA FLAG, THE MICRO FLAG UNLESS NO INTERRUPTS ARE POSSIBLE, AND THE VARIOUS APR AND PI INTERRUPT CONDITIONS WHEN THEY ARE INDIVIDUALLY POSSIBLE. INTCONDH IS CONSTRUCTED BY "CONINTCOND" FROM PISTAT (WHICH CONTAINS THE P.I.-IN-PROGRESS BITS) AND NOTFCOND (WHICH CONTAINS A 0 IN EVERY FLAG THAT SHOULD BE TESTED FOR AN INTERRUPT) AND THE FLAG PIACTIVE. CONINTCOND IS CALLED WHEN INTERRUPTS ARE INITIATED OR TERMINATED, CHANNELS ENABLED/DISABLED, OR PI LEVELS OR THE PI SYSTEM TURNED ON/OFF. TIMING = AT LEAST 5 CYCLES FOR INTERRUPTED INSTRUCTION OR MORE IF IT INTERRUPTED DURING INDIRECTION + 9 + (R IF NOVA=1) + [IF PIACTIVE=1, (4 + 4 * NO. LEVELS PASSED OVER IF NO NEW INT. TAKES PLACE) ELSE (5 * LEVEL NO. + DEVICE NO. + 14 + (5 IF LEVEL # 1)) IF A NEW INTERRUPT TAKES PLACE] I = 25 % *ENTER HERE FROM MAIN OR INDIRECT LOOP WITH PC IN LTEMP PI: P_PC, GOTO[.+1]; *HERE FROM MAIN TO DECREMENT PC BEFORE CHECK PI1: P_P-1, Q_777777R, SETSF[NOVA&H], DGOTO[REMAPPC]; P_NOTFCOND, Q_P AND Q, CALL[PIX]; %CALL HERE FROM INTERPRETERS WITH PC IN Q NOTFCOND IN P AFTER SETSF[NOVA&H]. INTERRUPTS ARE ((MICINTS U [NVMAX]) AND (NOT FINTS)) U (F AND FINTS). LOOK AT [NVMAX] ONLY IF NOVA=1. MUST NOT CLOBBER K & LEAVE H=0 IF RETURNS. CLOBBERS LPGRT, LPGRT3, RPGRT, SETS UP STEMP1, PUTS 100 IN LPGRT2 FOR DSI1. % PIX: OLDPC_PC_Q, GOTO[PI2,H=0]; RMW_NVMAX, INHINT; *! MAXC1 ONLY Q_P, P_NOT F; RPGRT_NOT P AND NOT Q, P_(MDR) U (MICINTS); *! *~ MAXC2 ONLY Q_P, P_FLAGS; P_(MDR) U (MICINTS), RPGRT_P AND NOT Q; *~ P_P AND Q, Q_RPGRT, WRESTART, B_MDR, CLEARF[NOVA&MICRO&H], DGOTO[PI3]; *CONSOLE "STOP" MDR_NULL, CALL[SPUNT,B<0], SETSF[PIACTIVE&G], INHINT; *! MAXC1 ONLY PI2: Q_NOT F, CLEARF[MICRO]; LPGRT2_NOT P AND NOT Q, Q_MICINTS, INHINT; Q_LPGRT2, P_P AND Q, SETSF[PIACTIVE&G], DGOTO[.+2]; *DGOTO=INHINT *! *~ MAXC2 ONLY PI2: Q_FLAGS, CLEARF[MICRO]; LPGRT2_NOT P AND Q, Q_MICINTS, INHINT; *HAVE TO TOUCH MDR BECAUSE OF STOP LOGIC PROBLEM AT PI5+2 *DGOTO = INHINT HERE Q_LPGRT2, P_P AND Q, B_MDR, SETSF[PIACTIVE&G], DGOTO[.+2]; *~ *HERE WITH INTERRUPT REQUESTS IN P OR Q. SAVE THEM IN MICINTS. USE RPGRT *FOR INTERRUPT IN PROGRESS MASK, LPGRT3 FOR INT. REQS. ON PI LEVEL BEING *CONSIDERED, LPGRT2 TO HOLD THE CONSTANT 100 FOR LATER. PI3: YKPTR_1S, Q_P OR Q, INHINT, CALL[EVINC]; *COUNT CALLS TO "PIX" MICINTS_Q, RETURN[G=0], P_(10L) LSH [3], A0; Q_LPGRT2_P, FRZBALUBC, P_PISTAT; Y_IONTABX, LPGRT_P, FRZBALUBC, GOTO[PI5]; *LOOP THROUGH THE 7 ENTRIES OF IONTAB UNTIL EITHER A PI LEVEL AT WHICH AN *INTERRUPT IS IN PROGRESS IS FOUND (A BIT IN PISTAT WILL BE 1) OR UNTIL *(MICINTS AND IONTAB[LEVEL])#0. PISTAT CONTAINS 1'S IN (35,43) FOR INTS. *IN PROG. (1,7), 1'S IN (26,34) FOR LEVELS OFF (1,7) P_SY, P AND Q, RETURN[ALU#0]; Q_MICINTS, RPGRT_Q, CALL[ZEROP,ALU#0]; LPGRT3_P AND Q, P_PISTAT, Q_(RPGRT) RSH 1, RETURN[ALU=0]; *PISTAT IN P, 100 IN Q AT ENTRY, LEAVE X=0 FOR DSI1 PI5: GOTO[.-3,ALU=0], PQ RCY [7], P AND Q, X_NULL, INCY; *HERE WITH APPROPRIATE INTERRUPT BITS IN LPGRT3, PISTAT BIT IN RPGRT Y_INTTAB, Q_RPGRT, P_LPGRT; MDR_P OR Q, Q_LPGRT3, SETSF[G], DECY; PISTAT_P_MDR, Q RSH 1, INCY, GOTO[.,Q EVEN]; *LEAVE ADDRESS OF MICROCODED PART OF INTERRUPT ROUTINE (NORMALLY "PICYC") *ON STACK AND RECONSTRUCT INTERRUPT CONDITIONS. LEAVE G=1 IFF SIGN BIT *IN INTTAB ENTRY = 0. STACK_SY, Q_LPGRT2; POP, STEMP1_Y, GOTO[DSI1]; %CALL HERE FROM JRST 10,E. CLOBBERS LPGRT, RPGRT, LPGRT2, AND MDR TIMING = 1 + 2*PI LEVEL TURNED ON + CONINTCOND TIMING I = 23 % DISMISINT: P_A1, BAMASK[6], SETSF[PIACTIVE&G], X_NULL; P_PISTAT, LPGRT2_Q_P+1; LPGRT_P AND Q, DGOTO[.,Q EVEN]; GOTO[.+1,ALU#0], Q RSH 1, MDR_NOVA&H, RPGRT_P AND NOT Q; Q_RPGRT, A0, SETF[MICRO]; P_PISTAT_Q, Q_ICTR, FRZBALUBC, GOTO[DSI2,G=1]; CONINT0: INTCONDH_MDR, ICTR_Q, FRZBALUBC, RETURN; *A0 FOR JRST %"CONINTCOND" IS ENTERED FROM "SPILEV" (WHEN A DEVICE CHANGES PRIORITY) AND WHEN PIACTIVE OR PI LEVELS ARE TURNED ON OR OFF, "DSI1" FROM "PI", AND "DSI2" FROM "DISMISINT". WANT TO CHECK "NOVA" FLAG EVEN WHEN NO INTERRUPTS ARE POSSIBLE SO THAT THE CLOCK, HALT, NONXMEM, PARITY, POWER FAILURE, ETC. SIGNALS FROM THE NOVA CAN BE PICKED UP. THESE MAY BE TESTED BY THE PROGRAM. THERE ISN'T ANY REASON TO CHECK "MICRO" HOWEVER. SETUP @ICTR TO POINT TO THE CURRENT PI LEVEL. "RPGRT", "LPGRT2", X, Y, AND MDR ARE CLOBBERED. TIMING = 4 IF PIACTIVE = 0, ELSE 15 + 3*PI LEVEL % CONINTCOND: SETSF[PIACTIVE&G], P_A1, BAMASK[6], X_NULL; LPGRT2_P+1, P_PISTAT, DGOTO[CONINT0,G=0]; DSI1: MDR_NOVA&H, Q_ICTR, A0; *FALL THROUGH OR ENTER HERE WITH 100 IN LPGRT2, WITH PISTAT IN P, *WITH NOVA&H IN MDR DSI2: Q_ICTR, YKPTR_@ICTR; RPGRT_P, YICTR_Q, Q_LPGRT2; *SAVE OLD INSTRUCTION COUNTER P AND Q, PQ RCY [7], Y_IONTABX, BAMASK[7]; *END TEST AT DSI3+2 DOESN'T WORK FOR PI LEVEL 1 LPGRT2_P, INCY, GOTO[DSI3,ALU=0]; DSI5: YKPTR_@ICTR_X; Q_YICTR, A0, GOTO[CONINT0]; *LOOP STARTS AT DSI3 WITH LEVELS OFF IN P AND LPGRT2[35,43], WITH PISTAT IN *LPGRT, WITH 100 IN Q, NOVA&H IN MDR, POINTER TO IONTAB IN Y, 0 IN X INCY, P_LPGRT2, GOTO[DSI4,ALU>=0]; DSI3: P AND Q, P_RPGRT, SAMASK[7], Q RSH 1; P-Q, P_MDR, INCX, GOTO[.-2,ALU#0]; MDR_(P) U (SY), INCY, GOTO[DSI3,ALU<0], P_LPGRT2; DSI4: Q_MDR; Q_(NOT Q) U (NOTFCOND); MDR_(NOT Q) U (NOVA&MICRO&H), GOTO[DSI5]; %"SPILEV" IS CALLED WITH A PRIORITY LEVEL IN P, A MASK OF DEVICES TO BE ASSIGNED TO THAT LEVEL IN Q, AND A MASK OF DEVICES TO BE ASSIGNED TO PI LEVEL 0 IN RPGRT3. RPGRT3 MUST CONTAIN 1'S IN ALL BITS WHERE Q HAS THEM. CLOBBERS LPGRT, LPGRT2 CALLED BY CONO APR, CONO PI, SEVERAL JMC'S, SETPIA. TIMING = 27 CYCLES (- 1 CYCLE IF P=0) I = 6 % SPILEV: Q_Y_IONTABX, LPGRT_Q, DGOTO[6]; LPGRT2_P+Q, INCY, X_NPC, GOTO[.+3]; CALL[UPQ,ALU=0], Q_NOT P AND Q, P_LPGRT, DECX; SY_Q, INCY, GOTO[CONINTCOND,X<0]; P_LPGRT2, Q_Y, SETF[MICRO]; P#Q, P_RPGRT3, Q_SY, GOTO[.-3]; %"SETPARAM" ACCEPTS A POINTER TO AN "INTTAB" ENTRY IN Y AND A 24-BIT PARAMETER IN "RTEMP". IT CHANGES THE INTERRUPT PARAMETER VALUE FOR THAT DEVICE. TIMING = 4 CYCLES I = 3 % SETPARAM: P_A1, BAMASK[30], Q_SY; Q_NOT P AND Q, P_RTEMP, SAMASK[30], CALL[UPQ]; SY_Q, RETURN;