ER[LISPM1]; *I = ? %(1) SEE <MAXC>BLISP.EARS FOR METAPROGRAMS AND OTHER DESCRIPTION (2) PDP-10 INTERPRETER MEMORY REFERENCE SUBROUTINES CANNOT BE USED FROM BYTE LISP BECAUSE THE PC IS ADVANCED BEFORE EXECUTION BY THE PDP-10, AFTERWARDS BY BYTE LISP. (3) TRAP INSTRUCTIONS FOR BYTE LISP OPERATIONS CAN ONLY BE JUMPA'S BECAUSE PUSHJ'S, JSR'S, OR JSYS'S MIGHT SUFFER A PAGE REFERENCE FAULT AND LOSE THE TWO EXTRA BITS OF PC NEEDED TO REMEMBER THE BYTE POSITION. HENCE, PC AND FLAGS FOR TRAP ARE LEFT IN 7. (4) THE DIAGNOSTIC FOR CHECKING OUT THIS MICROCODE IS <DIAGNOSTICS>BLDGA.SAV, WHICH RUNS IN EITHER USER OR MONITOR MODE. THE MAIN LOOP HAS FOUR ENTRIES: "GNBYT" RETURNS THE NEXT BYTE IN P AND ORIGINAL VALUE OF P IN Q, LEAVING K=0, J UNCHANGED; "XCTBYT" EXECUTES THE NEXT BYTE; JUMPS FINISH AT "JMP0" WITH DISPLACEMENT RELATIVE TO "PC" IN P-Q; JRSTF'S FROM PDP-10 MODE GOTO "LENTER". AT EXIT FROM THE MAIN LOOP: AC/ 1 X/ 11 G=H=J=0 FOR ONE-BYTE INSTRUCTIONS, G=H=GARBAGE FOR MULTI-BYTE K=BIS OPCODES 0-77: P/ 4 LOW BITS OF OPCODE, Q/ VP OPCODES 100-177: P/ 4 LOW BITS OF OPCODE, Q/CBS OPCODES 200-277: P/ 0,,PP-4 LOW OPCODE BITS-1, Q/ AC1 CONST (300-377): P/ 6 LOW OPCODE BITS, Q/ CBS FNn (400-477): P/ 4 LOW BITS OF OPCODE, Q/ NEXT 4 BITS OF OPCODE JMP (OPCODES 500-577): P/ 6 LOW BITS OF OPCODE, Q/ 20 EVEN OPCODES 600-676 TRAP AT LOCATIONS 200-237 ODD OPCODES 601-677 AND OPCODES 701-776 AS FOLLOWS: TWO-BYTE OPCODES: P/ NEXTBYTE, Q/ AC1 SINGLE-BYTE OPCODES: P/ AC1, Q/ AC1 UNDEFINED ODD OPCODES 601-677 TRAP TO MONITOR 41 WITH OPCODE IN 40[0,10] AND ADDRESS OF LAST MEMORY REFERENCE IN 40[22,43]. THE WORD CONTAINING THE INSTRUCTION BEING EXECUTED IS KEPT IN "INSTR". "PC" ALWAYS POINTS AT THE FIRST BYTE OF THE CURRENT INSTRUCTION. "WPC" ALWAYS POINTS AT THE LAST BYTE FETCHED BY "GNBYT" OR "XCTBYT" AND HAS STATE INFORMATION IN THE L.H. TO CONTROL THE SEQUENCING OF THE MAIN LOOP THROUGH THE FOUR BYTES IN THE WORD. TIMING FOR "GNBYT" = 3 + (4 + R IF BYTE 0) TIMING FOR "XCTBYT" = 8 + (2 + R IF BYTE 0) + (4 FOR OPCODES 0-277) + (2 FOR OPCODES 300-477) + (5 FOR ODD OPCODES 601-677) TIMING FOR "JMP" = 13 + R + 1 IF BACKWARDS INTERRUPTED INSTRUCTIONS WHICH CANNOT BE RESTARTED FROM THE BEGINNING SET THE "BIS" FLAG, LEAVE A CODE FOR THEIR PRESENT STATE IN THE "CBS" ACCUMULATOR, AND CALL THE "GOSTAT" ROUTINE NEAR THE BEGINNING OF THEIR EXECUTION. "GOSTAT" DISPATCHES THROUGH THE "BSTDSP" TABLE IF "BIS" IS SET. EXECUTION MAY BE INTERRUPTED BY A PAGE FAULT ON ANY MEMORY REFERENCE OR BY A PUSHDOWN OVERFLOW ON ANY PUSH OPERATION. CONSEQUENTLY, WHEN ANY MEMORY REFERENCE OCCURS, THE STATE OF THE INSTRUCTION MUST BE CONTAINED IN THE ACCUMULATORS. DURING EXECUTION, REGISTERS ARE USED AS FOLLOWS: CP/ CONTROL PUSH-DOWN STACK POINTER PP/ PARAMETER PUSH-DOWN STACK POINTER BR/ JUNK FOR SWAPPED CALLS (NOT TOUCHED BY MICROCODE) VP/ POINTS AT FIRST ARG OF CURRENT FRAME-1 CBS[22,43]/ ADDRESS OF ZEROTH CONSTANT IN POINTER AREA CBS[0]/ 0 IF ZEROTH CONSTANT IS IN LEFT HALF-WORD ELSE 1 CBS[1,5]/ "STATE" OF INSTRUCTION IF F[BIS]=1 CBS[6,11]/ "DEPTH" OF PROG/LAMBDA NESTING IN CURRENT FUNCTION CBSP/ USED AS DISPLACEMENT RELATIVE TO CBS WHEN GETTING POINTERS 1/ DUPLICATES 0(PP) IF AT LEAST ONE ITEM HAS BEEN PUSHED IN THE CURRENT FRAME % TARGET[ILC]; GNB0: P←Q; MAPVA←P←P+1, SAMASK[22], CALL[BXMEM]; WPC←Q, CALL[PMDR]; INSTR←P, BAMASK[11], PQ RCY [33], X←11S, Q←LTEMP, RETURN; GNBYT: P←XSPLIT←WPC, LTEMP←P, Q←10772 777777R; Q←P-Q-1, P←INSTR, X←11S, GOTO[GNB0,G=0]; WPC←Q, PQ RCY [Y], Q←LTEMP, XMASK, RETURN; XCTB2: P←Q, BAMASK[22], Q←1S, ICTR←P+1; *ENTER HERE FROM JRSTF TO MACHINE 1 WITH NEW PC IN P+Q LENTER: P←MAPVA←P+Q, Q←3 777777L, SETF[MD2]; LENTM: XREF, Q←P AND Q, P←777777S, GOTO[MILLEG,G=1]; *POSITION PC[20,21] IN LOW BITS OF OPCODE FIELD FOR XSPLIT← PC←Q, Q←NOT P AND Q, P←Q, BAMASK[22]; Q←(REFADR←P) U (XNLE), PQ RCY [33], GOTO[.+3,G=0]; LEFADR←Q, Q←XMQ, CALL[LOADMAP]; P←PC, Q←3 777777L, GOTO[LENTM]; *AC←1, X←11, Y←ADDRESS OF WPCT + PC[20,21] XSPLIT←(@WPCT) U (P), Q←REFADR; *Y←SHIFT COUNT FOR BYTE, P←OLD WPC VALUE P←FSPLIT←(Q) U (SY), Q←10772 777777R; Q←P-Q-1, P←MDR, SETSF[INTCONDH]; PQ RCY [Y], XMASK, INSTR←P, Q←700L, WPC←Q, CALL[BPI,H=1]; SPBYTE: Y←(P-Q-1) U (Q), SETSF[BIS&K]; *KNOW 2P HAS ALU VALUE=3, BLDISP IS AT 677 NPC←STACK←D, PQ RCY [6], AMASK[3], ROPCD←2P, GOTO[DECBYT,ALU<0]; RTEMP←A1, P←Q←LAC, SETSF[7S], CALL[GNBYT,B>=0]; OPXDIS: Y←P+Q, Q←(ROPCD) RSH 1, DGOTO[.-1]; NPC←STACK←SY, GOTO[FCALLX,Q EVEN]; *WRITE LAC AT P+Q+1 AND EXIT BWPPQ1X: MAPVA←P←P+Q+1, SAMASK[22], Q←LAC; BWRQX: WREF, MDR←Q, SETSF[J], REFADR←P, GOTO[MILLEG,G=1]; BWRQXX: Q←(P) U (WLE), GOTO[BWRX1,G=1]; XCTBYT: P←XSPLIT←WPC, Q←10772 777777R; XCTB1: Q←P-Q-1, P←ICTR, CLEARF[BIS&K], X←BIS&K, GOTO[XCTB2,G=0]; WPC←Q, INCX, ICTR←P+1, P←3 777777L; Q←P AND Q, P←INSTR, SETSF[INTCONDH], DGOTO[SPBYTE]; PC←Q, PQ RCY [Y], XMASK, Q←700L, CALL[BPI,H=1]; XCTBL: LAC←P AND Q, P←XSPLIT←WPC, Q←10772 777777R, GOTO[XCTB1]; *HAVE BYTE BEING INTERPRETED IN Q BLDSP: NPC←STACK←SY; RTEMP←A1, SETSF[7S], CALL[GNBYT,B>=0]; XBLDSP: NPC←STACK←SY, P←NOT P, Q←PP; MAPVA←P←P+Q, SAMASK[22], Q←LAC; *HERE FOR OPCODES 0-700 WITH DGOTO PENDING. *HAVE 11 IN X, 1 IN AC, 2*OPCODE IN ROPCD, LEFT 3 BITS OF OPCODE IN P. DECBYT: B←(3730S) U (P), P←(ROPCD) RSH [1], NPC←B, GOTO[.+1]; PQ RCY [4], AMASK[4], SETSF[7S], Q←677R, DGOTO[COPY1]; E[3730]; *JRST IS AT 3740 *MUST BE BOUNDARY OF 8. HAVE 3 OPCODE BITS IN P, ADDRESS OF BLDISP IN Q Y←P+Q, P←(ROPCD) RSH [1], SAMASK[4], Q←VP, GOTO[BLDSP]; *IVAR, LFNX, SETI, DSETI Y←P+Q, P←(ROPCD) RSH [1], SAMASK[4], Q←CBS, GOTO[BLDSP]; *SVAR, SSET, SDSET, FNX Y←P+Q, P←(ROPCD) RSH [1], SAMASK[4], GOTO[XBLDSP]; *XVAR, XSET, XDSET, LCALL (200-277) P←(ROPCD) RSH [1], AMASK[6], Q←CBS, CALL[GETCON]; *CONST (300-377) Q←P, P←(ROPCD) RSH [1], SAMASK[4], GOTO[FNOPC]; *FN0, FN1, FN2, FN3 P←(ROPCD) RSH [1], AMASK[6], Q←777777 777760S, GOTO[JMP]; *JMP (500-577) *EVEN OPCODES 600-677 TRAP, ODD DISPATCH P←(ROPCD) RSH [2], AMASK[5], Q←@BOPXT, GOTO[OPXDIS]; MILEG1: INSTR←P, P←Q, STACK←D, GOTO[UUOM]; TARGET[ILC]; *RETURN NEXT PC IN P, NOT FLAGS IN Q. P←ISPLIT←WPC, Q←10772 777777R AT CALL. ADVPC: P←P-Q-1, BAMASK[24], Q←(NOT F) U (NOTFLAGS&BIS), RETURN[G=1]; P←P+1, BAMASK[22], RETURN; *FCALLX ADVANCES PC BEFORE TRAP. HAVE TRAP DISPLACEMENT IN P. FCALLX: RTEMP←P, SETF[MD2&G], GOTO[.+1]; P←ISPLIT←WPC, Q←10772 777777R, CALL[ADVPC]; CBSP←P OR NOT Q, P←RTEMP, BAMASK[7], Q←200S; *SIMULATE JSP 7,ADDR MAPVA←P←P+Q, Q←1R, CLEARF[BIS&MD0&MD1&MD2&J], GOTO[REMAP1]; *FCALLY DOES NOT ADVANCE PC BEFORE TRAP FCALLY: RTEMP←P, P←PC, DGOTO[.-2]; SETF[MD2&G], Q←A1, CALL[ADVPC]; COPY1: P←LAC←P AND Q, GOTO[PPPUSH]; *DISPATCH TABLE FOR OPCODES 0-277 *SIGNIFICANT OPCODE BITS IN P, 0 IN LTEMP, G=H=J=0 *FIRST FOUR HAVE VP IN Q SI[BLDISP,0,IVAR,COPY1,SCRASH]; *LVAR SIS[BLDISP,1,GOSTAT,LFNX,SCRASH]; *LFNX SI[BLDISP,2,BWPPQ1X,SCRASH,SCRASH]; *LSET SI[BLDISP,3,BWPPQ1R,PPOP,SCRASH]; *LDSET *NEXT FOUR HAVE CBS IN Q SI[BLDISP,4,GETCON,IVAR,COPY1]; *SVAR SI[BLDISP,5,GETCON,SETR,XCTBYT]; *SSET SI[BLDISP,6,GETCON,SETR,PPOP1]; *SDSET SIS[BLDISP,7,GOSTAT,FNX,SCRASH]; *FNX *NEXT FOUR HAVE PP IN Q, MAPVA←P←(NOT 4 OPCODE BITS)+PP+1, SAMASK[22], Q←LAC *HAS BEEN DONE SI[BLDISP,10,BRMEM,COPY1,XCTBYT]; *XVAR SI[BLDISP,11,BWRQX,SCRASH,SCRASH]; *XSET SI[BLDISP,12,BWRQR,PPOP,SCRASH]; *XDSET SI[BLDISP,13,LCALL,SCRASH,SCRASH]; *LCALL *DISPATCH TABLE FOR ODD OPCODES 600-677 (EVEN OPCODES TRAP) *DISPATCH WITH -1 IN RTEMP, AC1 IN P AND IN Q SIS[BLOPXT,0,GTCON,IVAR,COPY1]; *SVARX SIS[BLOPXT,1,LVARX,IVAR,COPY1]; *LVARX SIS[BLOPXT,2,XVARX,IVAR,COPY1]; *XVARX SIS[BLOPXT,3,ARGX,ARGX1,CAR]; *ARG SIS[BLOPXT,4,GTCON,COPY1,SCRASH]; *CONSTX SIS[BLOPXT,5,GTCON,SETR,PPOP1]; *SDSETX SIS[BLOPXT,6,GTCON,SETR,XCTBYT]; *SSETX SIS[BLOPXT,7,LVARX,BWPPQ1R,PPOP]; *LDSETX SIS[BLOPXT,10,LVARX,BWPPQ1X,SCRASH]; *LSETX SIS[BLOPXT,11,XVARX,BWPPQ1R,PPOP]; *XDSETX SIS[BLOPXT,12,XVARX,BWPPQ1X,SCRASH]; *XSETX SIS[BLOPXT,13,GNBYT,JUMPXX,SCRASH]; *JUMPXX SI[BLOPXT,14,GETP,GETL1,GETL2]; *GETLIST SI[BLOPXT,15,BRMEM1,ASSOC,SCRASH]; *ASSOC SI[BLOPXT,16,UNBSP,IMUL,IREMN]; *ITIMES2 SI[BLOPXT,17,UNBSP,BIDIV,IQUOT]; *IQUOT SI[BLOPXT,20,UNBSP,BIDIV,IREMN]; *IREMN SI[BLOPXT,21,UNBOX,UNBOX1,IOR2]; *IOR2 SI[BLOPXT,22,UNBOX,UNBOX1,IXOR2]; *IXOR2 SI[BLOPXT,23,UNBSP,BLLSH,IREMN]; *BLSH SI[BLOPXT,24,UNBSP,BLASH,IREMN]; *BASH SI[BLOPXT,25,LDT,QZERO,IBOX1]; *NTYP *SI[BLOPXT,?,LENGTH,IBOX0,SCRASH]; *LENGTH (DEIMPLEMENTED--NO SPACE) *SI[BLOPXT,?,ZEROT,JCOND1,JNEQT]; *JNZERO *SI[BLOPXT,?,ZEROT,JCOND1,JEQT]; *JZERO REPEAT[12,XSLC[E1[UUOM] E2[60] E3[4061]]]; *NOTE: DIS DOES GNBYT, DI DOES NOT BEFORE TRIPLE DISPATCH *BYTE-LISP OPCODES (DUE TO KLUDGE AT "SPBYTE" USER OPCODE N MAPS INTO N+1 HERE) DI[701,PSSTK,3777,SCRASH]; *MINONE (USER OPCODE 702) DI[702,PSSTK,4000,SCRASH]; *ZERO DI[703,PSSTK,4001,SCRASH]; *ONE DI[704,PSSTK,4002,SCRASH]; *TWO DIS[705,SIC,3400,SCRASH]; *SIC DI[706,PSNIL,PPPSHX,SCRASH]; *NIL DI[707,PST,PPPSHX,SCRASH]; *T DI[710,PPPUSH,SCRASH,SCRASH]; *COPY DI[711,PPOP,SCRASH,SCRASH]; *POP *712 IS PDP-10 I/O DI[713,PPOP2,PPOP1,SCRASH] *POP2 DI[714,PPOP3,PPOP1,SCRASH]; *POP3 DI[715,UNBOX,FIXSP,SCRASH]; *VAG DI[716,UNBOX,UNBOX1,IPLUS2]; *IPLUS2 DI[717,UNBOX,UNBOX1,IDIF2]; *IDIF DI[720,UNBOX,UNBOX1,IAND2]; *IAND2 DI[721,UNBOX,QF1,IPLUS1]; *ADD1 DI[722,UNBOX,IPLUS1,SCRASH]; *SUB1 DM[DLC,723]; DLC[E1[UUOM] E2[60] E3[4061]]; *UNDEFINED DIS[724,GNBYT,BIND,BRET2]; *DBIND DIS[725,GNBYT,BIND,BRET1]; *BIND DI[726,ZEROP,UNBIND,FCALLX]; *UNBIND DI[727,BRETRN,FCALLX,SCRASH]; *RETURN DIS[730,BRETRN,XRETRN,SCRASH]; *XRETURN DIS[731,QNIL,JCOND1,JEQT]; *JUMP IF 0(PP) = NIL DIS[732,QNIL,JCOND1,JNEQT]; *JUMP IF 0(PP) # NIL DIS[733,BRMEM1,TEQ,JNEQT]; *JUMP IF 0(PP) # -1(PP) DIS[734,BRMEM1,TEQ,JEQT]; *JUMP IF 0(PP) = -1(PP) DIS[735,TATTYP,14,JNEQT]; *JUMP IF 0(PP) IS NOT AN ATOM DIS[736,TATTYP,14,JEQT]; *JUMP IF 0(PP) IS AN ATOM DIS[737,TTLIST,JNEQT,SCRASH]; *JUMP IF 0(PP) IS NOT A LIST DIS[740,TTLIST,JEQT,SCRASH]; *JUMP IF 0(PP) IS A LIST DIS[741,TATTYP,FLOATT,JNEQT]; *JNNUM DIS[742,TATTYP,FLOATT,JEQT]; *JNUM (TYPE .E. FLOATT TO SMALLT) DIS[743,TATTYP,22,JNEQT]; *JNFIXP DIS[744,TATTYP,22,JEQT]; *JFIXP (TYPE .E. FIXT TO SMALLT) DIS[745,GNBYT,TTYPE,JNEQT]; *JUMP IF 0(PP) IS NOT OF TYPE = NEXTBYTE DIS[746,GNBYT,TTYPE,JEQT]; *JUMP IF 0(PP) IS OF TYPE = NEXTBYTE DIS[747,UNBSP,TEH,JNEQT]; *JUMP IF -1(PP) .NE. 0(PP) DIS[750,UNBSP,TEH,JEQT]; *JUMP IF -1(PP) .E. 0(PP) DIS[751,UNBSP,TE,TGE]; *JUMP IF -1(PP) .GE. 0(PP) DIS[752,UNBSP,TE,TL]; *JUMP IF -1(PP) .L. 0(PP) DIS[753,UNBSP,TE,TG]; *JUMP IF -1(PP) .G. 0(PP) DIS[754,UNBSP,TE,TLE]; *JUMP IF -1(PP) .LE. 0(PP) DIS[755,JUMPX,JMP,SCRASH]; *JUMPX DI[756,BRMWPP,SWAP,SCRASH]; *SWAP DI[757,LAST,LAST1,SCRASH]; *LAST DI[760,BRMEM1,BFETCH,SCRASH]; *FETCHFIELD DI[761,BRMEM2,BRMEM1,STORE]; *REPLACEFIELD DI[762,BRMEM1,SETL,RPL]; *FRPLACD DI[763,BRMEM1,SETR,RPL]; *FRPLACA DI[764,RPLSUP,SETL,RPL]; *RPLACD DI[765,RPLSUP,SETR,RPL]; *RPLACA DI[766,GETP,GETP1,GETP2]; *GETP DI[767,READP,CDRP,CDR]; *CDDR DI[770,READP,IVAR,CDR]; *CDAR DI[771,READP,CDRP,CAR]; *CADR DI[772,READP,IVAR,CAR]; *CAAR DI[773,READP,CDR,SCRASH]; *CDR DI[774,READP,CAR,SCRASH]; *CAR DI[775,BRMEM1,FMEMB,SCRASH]; *FMEMB (USER OPCODE 776) SET[LASTOK,3730];