ER[CONT]; *I = 95 (94 ON MAXC2) TARGET[ILC]; %OPCODES 0 AND 40-77 ARE UUO'S WHICH TRAP TO MONITOR LOCATION 41 AFTER STORING THE OPCODE AND EFFECTIVE ADDRESS IN 40. UUO'S 1-37 TRAP TO USER LOCATIONS 40-41. UUO'S 110-113 AND 116-127 TRAP TO MONITOR 60-61 INSTEAD OF 40-41. BYTE LISP USES OPCODES FROM 700-777. **MONITOR UUO'S CAN'T HAVE INDIRECT ADDRESSING IN 41 OR IN 61 BECAUSE OF **INTERRUPT COMPUTATION OF UM PROBLEM TIMING = 4 + W + (1 FOR MONITOR UUO'S) + TRAP INSTRUCTION TIME I = 9 % SM[NOTFLAGS,IP[37 777777S]]; ***NOTE: CANNOT POP AND READ STACK CONCURRENTLY Q_WMQ, CALL[LOADMAP]; UUO: MAPVA_P_(REFADR_P) U (BLTWLE); WREF, Q_INSTR, LEFADR_P, AC_NULL, INHINT, CALL[SCRASH,G=1]; Q_(NOT Q) U (NOTFLAGS), GOTO[.-3,G=1], INHINT, P_LTEMP; MDR_P OR NOT Q, POP; MAPVA_P_STACK, A1, GOTO[XCT]; *J_UM FOR THE TRAP INSTRUCTION UUOU: SETSF[UM&J], LTEMP_P, P_STACK, GOTO[UUO]; *K=1 WILL PREVENT XCT FROM BEING INTERRUPTED (WHICH WOULD LOSE UM) *WORD SAVED IN 40 WILL BE OPCODE AND AC FIELD FROM "INSTR" ORED WITH P. UUOM: SETSF[UM&J&K], LTEMP_P, P_STACK; CLEARF[TFLAGSPI], GOTO[UUO]; IM[XXX,41]; *NEED ADDRESS=41 FOR SI AND DI MACROS *HALT IN USER MODE AND ILLEGAL I/O INSTRUCTIONS ARE ALSO TREATED AS OPCODE 0 UUO DI[0,UUOM,40,XXX]; *MONITOR UUO 0 REPEAT[37,DLC[E1[UUOU] E2[40] E3[4041]]]; *USER UUO'S (1-37) REPEAT[40,DLC[E1[UUOM] E2[40] E3[4041]]]; *MONITOR UUO'S (40-77) %700 IS FOR APR AND PI 712 FOR TTY AND --- 776 FOR UJMC 777 FOR JMC % %XCT HAS BEEN CHANGED SO THAT IN MONITOR MODE, IF THE AC FIELD IS #0, SOME MEMORY REFERENCES FOR THE INSTRUCTION BEING EXECUTED WILL BE FORCED TO USER MODE. THIS IS CONTROLLED BY THE XCT0, XCT1, XCT2, AND XCT3 FLAGS IN F, BUT IS TURNED OFF BY THE CFM FLAG. FORCED AC REFERENCES GO TO THE ACBASE STACK UNAFFECTED BY CFM BUT NOT WHEN UM=1. ON PAGER TRAPS AND PI CYCLES, J=UM. TIMING: 1 + R I = 9 % Q_XMQ, LEFADR_Q, CALL[LOADMAP]; *XREF DOESN'T CLOBBER H. PICYC JUMPS HERE WITH K=1, UUO WITH K=UM XCT: Q_AC, XREF, REFADR_P, GOTO[XAC,G=1], SETSF[INTCONDH]; 0Q RCY [22], Q_(P) U (XLE), GOTO[.-2,G=1]; Q_P, GOTO[XCTA,H=0]; XPI: GOTO[PI,K=0]; *"PTRAP" JUMPS IN HERE ALSO WITH XCT FLAGS IN Q XCTA: P_ICTR, STEMP_Q; SETF[STEMP], GOTO[XREMAP]; XAC: Q_LX, 0Q RCY [22], DGOTO[XCTA]; MDR_Q, Q_P, GOTO[XPI,H=1]; DI[256,XCT,SCRASH,SCRASH]; %JSYS IS ONE OF THE LEGAL INTERRUPT INSTRUCTIONS (JSR IS THE OTHER) AND SO IT MUST CHECK FOR J=1. WHEN J=1, THE UM FLAG SAVED IN LH OF PC WORD SHOULD BE 1. E > 777 INVOKES A USER JSYS. E < 1000 USES THE TABLE POINTED TO BY JSYST. PC AND FLAGS ARE SAVED AT THE LOCATION POINTED TO BY THE L.H. OF MEMORY, CONTROL IS GIVEN TO THE R.H. OF MEMORY. BIS, MD0, MD1, AND MD2 ARE CLEARED AFTER THE FLAGS ARE SAVED. ***CFM IS SET AFTER THE FLAGS ARE SAVED ON A MONITOR JSYS FROM MONITOR MODE. ***CFM IS CLEARED ON A MONITOR JSYS FROM USER MODE. TIMING: 9 + R + W + (2 IF MONITOR JSYS OR INTERRUPT INSTRUCTION) I = 11 % SM[UM,IP[10000 000000S]]; *** SM[CFM,IP[2000 000000S]]; *** ** TOP HALF OF OLDPC MUST BE 0 HERE. RETURN PC & FLAGS IN MDR, E IN P, 777 IN Q *! MAXC1 ONLY JSYS: P_OLDPC, Q_(NOT F) U (NOTFLAGS), GOTO[.+2,J=1]; MDR_P OR NOT Q, P_REFADR, BAMASK[22], Q_777L, RETURN; MDR_(P OR NOT Q) U (UM), P_REFADR, BAMASK[22], Q_777L, RETURN; *! *~ MAXC2 ONLY JSYS: P_REFADR, BAMASK[22], Q_777L, MDR_(TENF) U (PC), RETURN[J=0]; MDR_(MDR) U (UM), RETURN; *~ *NOW HAVE PC AND FLAGS IN MDR, E IN P, 777 IN Q JSYS0: P AND NOT Q, Q_MDR, SETSF[UM&J]; Q_JSYST, RTEMP_Q, GOTO[JSYS1,ALU#0]; *HERE IFF E<1000 CLEARF[UM], DGOTO[JSYS1]; MAPVA_P_P+Q, SETFC[CFM,J=0], GOTO[JSYS1,J=0]; Q_RMQ, CALL[LOADMAP]; JSYS1: RREF, P_(REFADR_P) U (RLE), CALL[RETN]; LEFADR_P, PC_P_MDR, GOTO[.-2,G=1]; PQ RCY [22], Q_RTEMP, CLEARF[BIS&MD0&MD1&MD2&J], GOTO[WQTOP]; DI[104,JSYS,JSYS0,SCRASH]; %JSR IS THE SECOND INSTRUCTION WHICH CAN BE USED IN AN INTERRUPT LOCATION. AS SUCH IT MUST SET THE UM FLAG IN THE PC WORD WHEN IT FINDS J=1. ALSO IT MUST CLEAR BIS AFTER SAVING THE FLAGS. JSR CAN BE SPEEDED UP BY 3 OR 4 CYCLES BY PROGRAMMING THE MEMORY REFERENCE IN LINE RATHER THAN JUMPING TO WREFQ. TIMING = M + W + 4 I = 2 % JSR: Q_P+1, P_MDR, CLEARF[BIS&MD0&MD1&MD2&J]; PC_Q, Q_P, P_REFADR, BAMASK[22], RETURN; DI[264,JSYS,JSR,WREFQ]; %THE AC REGISTER CONTROLS WHAT THE JRST DOES: 10: DISMISS INTERRUPT PRIVILEGED TRAP TO MONITOR LOCATION UUO40 4: HALT IF EXECUTED IN USER MODE 2: RESTORE FLAGS AS DESCRIBED BELOW 1: ENTER USER MODE WHEN FLAGS ARE RESTORED, THEY ARE RESTORED FROM THE LEFT HALF OF THE LAST WORD IN THE EFFECTIVE ADDRESS CALCULATION. THAT IS, FROM THE INDEX REGISTER, IF THE LAST THING WAS INDEXING, ELSE FROM THE INDIRECT WORD, ELSE FROM THE INSTRUCTION ITSELF. HOWEVER, FINAL INDEXING WILL NOT BE DONE IF THE LAST INDIRECT WORD (OR THE INSTRUCTION ITSELF, IF NO INDIRECTION) HAS MACHINE MODE FLAGS DIFFERENT FROM 0. TO PREPARE FOR THIS JRST BREAKS OUT OF THE MAIN LOOP AND SAVES THE INSTRUCTION IN "RTEMP", THEN JUMPS BACK TO THE MAIN LOOP FOR INDIRECT ADDRESS CALCULATION IF NECESSARY. THE MAIN LOOP CANNOT DO THIS WITHOUT BEING LENGTHENED BY ONE INSTRUCTION. THE UM FLAG CAN BE SET BUT NOT CLEARED BY JRST 2,E. USER IN-OUT HAS NOT BEEN IMPLEMENTED. WHEN HALT OR DISMISS INTERRUPT ARE GIVEN IN USER MODE NEITHER JUMPING NOR RESTORING FLAGS WILL TAKE PLACE. INSTEAD THE INSTRUCTION WILL TRAP TO THE LOCATION POINTED TO BY UUO40. IF AC ODD DO; UM_1; END; IF (T_AC RSH 1)=0 DO; PC_REFADR_E; GOTO[REMAPPC]; ELSEIF (T AND 6)#0 DO; IF (J_UM)=1 DO; STACK_DM 0; CLEARF[TFLAGSPI]; GOTO[UUO]; ELSEIF (T AND 2)#0 DO; HALT END; CALL[DISMISINT] IF (T AND 4)#0; GOTO[REMAPPC] IF (T AND 1)=0; END; CLEARF[FLAGS EXCEPT UM]; ISPLIT_RTEMP; IF MD0=MD1=MD2=0 AND X#0 DO; SETF[LINDX AND FLAGS]; ELSE DO; SETF[RTEMP AND FLAGS]; END; DISPATCH TO MACHINE THROUGH IM TABLE; I = 18 + 1/MACHINE MODE HERE + A FEW IN "PISYS" AT "DISMISINT" TIMING = M + 4 CYCLES FOR A JRST WITH AC=0 + 7 CYCLES + TIME FOR DISMISINT TO DISMISS AN INTERRUPT + 9 OR 10 CYCLES TO RESTORE THE FLAGS = M + 6 + W + R FOR A HALT OR JEN IN USER MODE % SV[FLAGSNOTUM,767740 000017]; *JUMP BACK TO MAIN LOOP TO DO INDIRECTION IF NECESSARY JIND: Q_INSTR, GOTO[INDLP,H=0]; RTEMP_Q, Q_AC, SETSF[UM&J&K], GOTO[JRST1], POP; *TO "JRST" WITH LAST MEM FETCH IN "RTEMP", E IN P, AC IN Q, UM IN J E[LASTOK]; *LASTOK MUST BE 4 X N SO DISPATCH IS AT BOUNDARY OF 4 *NEED BOTH J AND K = UM FOR UUO TRAP JRST: Q_AC, SETSF[UM&J&K]; JRST1: RPGRT_Q, Q RSH 1, SETFC[UM,Q ODD], CALL[AQQ,Q ODD]; *ENTER USER MODE MAPVA_LTEMP_P, Q_1R, GOTO[REMAP1,ALU=0]; P_(777L) LSH [1], Y_NULL, BAMASK[3], Q_(RPGRT) RSH 1; *P_6, Q_AC RSH 1 P AND Q, GOTO[JRST3,J=1], PQ RCY[0], SAMASK[2], STACK_D; ***DM76 GOTO[JRST3,ALU=0], P AND Q, P_4S; *MONITOR HALT OR DISMISS INTERRUPT FALLS THROUGH CALL[SPUNT,ALU#0]; *OLD PC+1 IN "PC", NEW PC IN "LTEMP" DGOTO[REMAPPC,Q EVEN], P AND Q, Q_LTEMP; CALL[DISMISINT,ALU#0], PC_Q, A0; *CLOBBERS LPGRT, RPGRT, LPGRT2, MDR *RESTORE FLAGS FROM FINAL WORD OF EFFECTIVE ADDRESS CALCULATION, BUT *FINAL INDEXING IS SUPPRESSED WHEN MD1&MD2 IN THE LAST INDIRECT ADDRESS *WORD (OR THE INSTRUCTION, IF NO INDIRECTION) ARE NON-0. JRST3: Q_RTEMP, P_NOTFLAGS, GOTO[JRST2,ALU#0]; *"DISMISINT" LEAVES ALU=0 AT RETURN JRST5: ISPLIT_Q, Q_NOT P AND Q, CLEARF[FLAGSNOTUM], CALL[SSTEMP]; NPC_(P) U (NPC), GOTO[JNEWM]; *DISPATCH TO MACHINE SELECTED BY MD1&MD2 RIGHT-JUSTIFIED IN P. *HAVE LAST MEM FETCH IN RTEMP, E IN LTEMP. MUST BE BOUNDARY OF 4. Q_NOT P AND Q, CALL[SSTEMP,X>=0]; *M0 = PDP-10 (RETURNS TO JNEWM+1) P_RTEMP, Q_A0, SETF[STEMP], GOTO[LENTER]; *M1 = BLISP *USER HALT = UUO 76. LTEMP_E, J_UM, STACK_DM 76 DONE ABOVE. JRST2: P_STACK, CLEARF[TFLAGSPI], GOTO[UUO]; *M2 UNDEFINED SSTEMP: STEMP_Q, QQ RCY [31], BAMASK[1], RETURN; *P[43]_MD2 TARGET[ILC]; *DGOTO[JRSTD+MD2] PENDING JNEWM: Q_LINDX, DECX, P_NOTFLAGS, DGOTO[.+1]; *POSTPONE MAPVA_P UNTIL AFTER UM IS SET SETF[STEMP], P_LTEMP, A1, GOTO[JUMPN]; DIS[254,JIND,JRST,SCRASH]; %JFCL JUMPS IF ANY OF THE FLAGS SELECTED BY AC IS SET AND CLEARS THE SELECTED FLAGS. TIMING = M + 7 I = 4 % JFCL: Q_(AC) U (20S), RTEMP_P, DGOTO[SSTEMP]; QQ RCY [4], Q_A0, CALL[UPQ]; JFCL1: SETSF[STEMP], Q_RTEMP, DGOTO[REMAPPC]; CLEARF[STEMP], GOTO[PCQ,G=1]; *PCQ IS WITH JRA CODE DI[255,JFCL,JFCL1,SCRASH]; %JSP PLACES FLAGS AND PC IN AC, CLEARS BIS, AND JUMPS TO E. TIMING = M + 2 I = 2 % *! MAXC1 ONLY JSP: P_OLDPC, Q_(NOT F) U (NOTFLAGS); LAC_P OR NOT Q, P_REFADR, CLEARF[BIS&MD0&MD1&MD2&J], GOTO[JUMPA]; *! *~ MAXC2 ONLY JSP: Q_(TENF) U (PC); LAC_Q, P_REFADR, CLEARF[BIS&MD0&MD1&MD2&J], GOTO[JUMPA]; *~ DI[265,JSP,REMAP1,SCRASH]; %JSA PLACES THE AC IN LOCATION E, E IN AC LEFT, AND PC IN AC RIGHT. THEN IT JUMPS TO E+1. THE FLAGS ARE NOT SAVED. BIS IS CLEARED. TIMING = M + 6 + W I = 4 % *MAKE SURE JSA AC,777777 STORES 0 IN L.H. OF PC. JSA: MDR_Q, P_P+1, BAMASK[22], Q_REFADR; RTEMP_P, PQ RCY [22], Q_PC; LAC_P OR Q, CLEARF[BIS&MD0&MD1&MD2&J], Q_RTEMP, P_MDR, DGOTO[WREFQ]; PC_Q, P_REFADR, BAMASK[22], Q_P; DI[266,JSA,SCRASH,SCRASH]; %JRA LOADS AC FROM THE LOCATION ADDRESSED BY AC LEFT AND JUMPS TO E. TIMING = M + R + 6 I = 3 % *CAN'T CHANGE PC YET BECAUSE OF POSSIBLE MAP FAULT JRA: RTEMP_P, QQ RCY [22], SAMASK[22], GOTO[JUMPA]; *TO MAPVA AND RARG JRA1: LAC_P, Q_RTEMP; PCQ: PC_MAPVA_P_BQ, AQ, Q_1R, GOTO[REMAP1]; *ENTER HERE FROM JFCL DI[267,JRA,RARG,JRA1]; %POP AND POPJ ACCEPT E IN "RTEMP", J=1, LAC IN P, 1 000001 IN Q. THEY RETURN UPDATED PUSHDOWN POINTER IN LAC, PDOVF SET IF NECESSARY. POPJ DOES NOT RESTORE THE FLAGS. POPJ TIMING = M + R + 5 POP TIMING = M + R + W + 5 I = 5 % SM[PDOVF,IP[20 000000S]]; POPJ: LAC_P-Q-NJ, PC_P_MDR; MAPVA_P_P, SAMASK[22], Q_1R, GOTO[REMAP1,J=1]; SETPDF: SETF[PDOVF], RETURN; DI[263,POPX,POPJ,REMAP1]; *POPJ POPY: LAC_P-Q-NJ, P_RTEMP, DGOTO[WTOP1]; MAPVA_P, CALL[SETPDF,J=0]; DI[262,POPX,POPY,SCRASH]; %PUSHJ HAS TO CHANGE THE PC AND AC BEFORE CHECKING FOR A MAP FAULT SO THAT THE INSTRUCTION WILL BE COMPLETED EXCEPT FOR THE WRITE IF A MAP LOADING TRAP OCCURS. PDOVF IS SET IF THE POINTER IN THE AC CROSSES 0 WHEN 1 000001 IS ADDED TO IT. NOTE THAT BECAUSE PUSHJ IS NOT A LEGAL INTERRUPT INSTRUCTION, THE J FLAG (REMEMBERING USER MODE) DOES NOT HAVE TO BE CHECKED AS IT WAS FOR JSR AND JSYS. BIS, MD0, MD1, AND MD2 ARE IS CLEARED. TIMING = M + 4 + W I = 6 % *! MAXC1 ONLY PUSHJ: P_(NOT F) U (NOTFLAGS), LTEMP_P, Q_OLDPC; MDR_NOT P OR Q, P_LAC, Q_(2 000002R) RSH 1, CLEARF[BIS&MD0&MD1&MD2&J]; *! *~ MAXC2 ONLY PUSHJ: LTEMP_P, MDR_(TENF) U (PC), P_Q, Q_(2 000002R) RSH 1; CLEARF[BIS&MD0&MD1&MD2&J]; *~ PUSHJ1: MAPVA_P_LAC_P+Q+J, Q_777777R; WREF, P_MDR, Q_LTEMP, REFADR_P AND Q, DGOTO[QTOLX,G=1]; PC_Q, Q_P, P_REFADR, CALL[SETPDF,J=1]; GOTO[WQTOP0]; DI[260,PUSHJ,SCRASH,SCRASH]; %PUSH BEGINS WITH [E] IN MDR, AC IN P, 1 000001 IN Q. IT INCREMENTS AC BY 1 000001, WRITES THE MEMORY DATA ONTO THE STACK, THEN SETS PDOVF IF THE STACK POINTER CROSSES 0. TIMING = M + R + W + 3 I = 2 % *! MAXC1 ONLY (BETTER) PUSH0: MAPVA_P_LAC_P+Q+J, Q_777777R, DGOTO[WREFQ]; P_REFADR_P AND Q, Q_MDR, SETFC[PDOVF,J=1], GOTO[WREFQ,J=1]; *! *~ MAXC2 ONLY PUSH0: P_LAC_P+Q+J, Q_777777R, DGOTO[WQTOP]; P_P AND Q, Q_MDR, SETFC[PDOVF,J=1], GOTO[WQTOP,J=1]; *~ DI[261,RTOMDR,PUSH0,SCRASH]; %JFFO LEAVES IN AC+1 A COUNT OF THE NUMBER OF LEADING ZEROES IN AC AND JUMPS TO E. HOWEVER, IF AC CONTAINS 0 IT DOES NOT JUMP. TIMING = M + 4 WHEN AC CONTAINS 0 = M + 7 + NO. LEADING ZEROES WHEN LEADING ONE IS IN L.H. = M + 9 + (NO. LEADING ZEROES - 18) WHEN LEADING ONE IS IN R.H. I = 7 % JFFO: MDR_P, P_LAC, SAMASK[22]; AQ, Y_NULL; P#Q, PQ RCY [22], STEMP_MDR, INCAC, GOTO[SETZ,ALU=0]; GOTO[.+2,ALU#0], AQ, Q LSH 1; *SKIP IF L.H. # 0 Q_P, Y_22S, GOTO[.-1]; INCY, GOTO[.,ALU>0], Q LSH 1, AQ, P_Y; LAC_P, P_MAPVA_STEMP, ACFS, Q_1R, GOTO[REMAP1]; DI[243,JFFO,SCRASH,SCRASH]; %THE JUMP CLASS INSTRUCTIONS JUMP TO E IF THE AC MEETS THE SPECIFIED CONDITION. TIMING = M + 2 + 1 IF NO JUMP -1 FOR JUMPA I = 7 TOTAL % SLC[PREMAP: E1[REMAPPC]]; JUMPC: AQ, NPC_PREMAP, RETURN; JUMPL: MAPVA_P, Q_1R, GOTO[REMAP1,ALU<0]; JUMPE: MAPVA_P, Q_1R, GOTO[REMAP1,ALU=0]; JUMPLE: MAPVA_P, Q_1R, GOTO[REMAP1,ALU<=0]; JUMPGE: MAPVA_P, Q_1R, GOTO[REMAP1,ALU>=0]; JUMPN: MAPVA_P, Q_1R, GOTO[REMAP1,ALU#0]; JUMPG: MAPVA_P, Q_1R, GOTO[REMAP1,ALU>0]; DI[320,REMAPPC,SCRASH,SCRASH]; DI[321,JUMPC,JUMPL,SCRASH]; DI[322,JUMPC,JUMPE,SCRASH]; DI[323,JUMPC,JUMPLE,SCRASH]; DI[324,XJMP,SCRASH,SCRASH]; DI[325,JUMPC,JUMPGE,SCRASH]; DI[326,JUMPC,JUMPN,SCRASH]; DI[327,JUMPC,JUMPG,SCRASH]; %AOBJP AND AOBJN BEGIN WITH AOBJ WHICH INCREMENTS THE AC BY 1 000001. TIMING = M + 3 + 1 IF IT JUMPS I = 2 TOTAL % **THESE DO NOT OVF, PC0, OR PC1 AOBJ: RTEMP_P, P_LAC, Q_1 000001S; LAC_P+Q, P_RTEMP, NPC_PREMAP, RETURN; DI[252,AOBJ,JUMPGE,SCRASH]; *AOBJP DI[253,AOBJ,JUMPL,SCRASH]; *AOBJN %THE AOJ AND SOJ GROUP OF INSTRUCTIONS INCREMENTS OR DECREMENTS THE AC AND JUMPS IF THE SPECIFIED CONDITION IS MET. OVERFLOW, CARRY0, AND CARRY1 ARE ALSO SET WHEN APPROPRIATE. TIMING = M + 3 + 1 IF NO JUMP FOR THE AOJ GROUP = M + 4 + 1 IF NO JUMP FOR THE SOJ GROUP I = 4 TOTAL % AOJC: LAC_P+Q, P_REFADR, SETOVPC01, NPC_PREMAP, RETURN; AOJS: P_1R, RETURN; AOJA: LAC_P+Q, SETOVPC01, P_REFADR, Q_1S, GOTO[REMAP1]; DI[340,AOJS,AOJC,REMAPPC]; DI[341,AOJS,AOJC,JUMPL]; DI[342,AOJS,AOJC,JUMPE]; DI[343,AOJS,AOJC,JUMPLE]; DI[344,AOJS,AOJA,SCRASH]; DI[345,AOJS,AOJC,JUMPGE]; DI[346,AOJS,AOJC,JUMPN]; DI[347,AOJS,AOJC,JUMPG]; SOJS: P_-1L, RETURN; DI[360,SOJS,AOJC,REMAPPC]; DI[361,SOJS,AOJC,JUMPL]; DI[362,SOJS,AOJC,JUMPE]; DI[363,SOJS,AOJC,JUMPLE]; DI[364,SOJS,AOJA,SCRASH]; DI[365,SOJS,AOJC,JUMPGE]; DI[366,SOJS,AOJC,JUMPN]; DI[367,SOJS,AOJC,JUMPG];