{ LispNoProlog.mc by don: 16-Apr-85 14:49:02 } { Copyright 1985 Xerox Corporation. All rights reserved. This is unpublished proprietary software and or documentation. Information contained here is proprietary to Xerox and is for Xerox internal use and is furnished to others only under a confidential disclosure agreement. } { Read a Prolog Pointer - 52d 64q Read a Prolog Tag - 53d 65q Write Pointer and Tag- 54d 66q Write Pointer and Zero Tag - 55d 67q Prolog Opcode Dispatch - 34d 42q } Set[L0.PrologOpFetch, 07]; { Lisp microcode of functions required by Prolog } { Read a Prolog Pointer 4 clicks} { tos contains UaddrLo,,UaddrHi as a smallp returns low 24 bits of contents } @PROLOGREADPTR: opcode[64'b], Xbus ← TOS LRot12, XDisp, L2 ← L2.ReadUHi, c1; Ybus ← TOS, AltUaddr, L2Disp, DISP4[ReadSomeU], c2; TT ← UPblock0, RET[ReadSomeUret], c*, at[00, 10, ReadSomeU]; TT ← UPblock1, RET[ReadSomeUret], c*, at[01, 10, ReadSomeU]; TT ← UPblock2, RET[ReadSomeUret], c*, at[02, 10, ReadSomeU]; TT ← UPblock3, RET[ReadSomeUret], c*, at[03, 10, ReadSomeU]; TT ← UPblock4, RET[ReadSomeUret], c*, at[04, 10, ReadSomeU]; TT ← UPblock5, RET[ReadSomeUret], c*, at[05, 10, ReadSomeU]; TT ← UPblock6, RET[ReadSomeUret], c*, at[06, 10, ReadSomeU]; TT ← UPblock7, RET[ReadSomeUret], c*, at[07, 10, ReadSomeU]; TT ← UPblock8, RET[ReadSomeUret], c*, at[08, 10, ReadSomeU]; TT ← UPblock9, RET[ReadSomeUret], c*, at[09, 10, ReadSomeU]; TT ← UPblockA, RET[ReadSomeUret], c*, at[0A, 10, ReadSomeU]; TT ← UPblockB, RET[ReadSomeUret], c*, at[0B, 10, ReadSomeU]; TT ← UPblockC, RET[ReadSomeUret], c*, at[0C, 10, ReadSomeU]; TT ← UPblockD, RET[ReadSomeUret], c*, at[0D, 10, ReadSomeU]; TT ← UPblockE, RET[ReadSomeUret], c*, at[0E, 10, ReadSomeU]; TT ← UPblockF, RET[ReadSomeUret], c*, at[0F, 10, ReadSomeU]; TOSH ← TT and 0FF, c1, at[L2.ReadUHi, 10, ReadSomeUret]; TOS ← TOS LRot8, c2; Xbus ← TOS LRot12, XDisp, L2 ← L2.ReadULo, c3; Ybus ← TOS, AltUaddr, L2Disp, DISP4[ReadSomeU], c1; { TT ← UPblockN, RET[ReadSomeUret], c*;} TOS ← TT, c3, at[L2.ReadULo, 10, ReadSomeUret]; PC ← PC + PC16, GOTO[IB.nop], c1; { Read a Prolog Tag 2 clicks } { tos contains UaddrLo,,UaddrHi as a smallp returns high 8 bits of contents as a smallp } @PROLOGREADTAG: opcode[65'b], Xbus ← TOS LRot12, XDisp, L2 ← L2.ReadUTag, c1; Ybus ← TOS, AltUaddr, L2Disp, DISP4[ReadSomeU], c2; { TT ← UPblockN, RET[ReadSomeUret], c*;} TOS ← TT and ~0FF, c1, at[L2.ReadUTag, 10, ReadSomeUret]; TOS ← TOS LRot8, L2 ← L2.0, IBDisp, GOTO[DNI.pc1], c2; { Write a Prolog Pointer and Tag 7 clicks } { tos contains 24 bit ptr to be stored tos-1 contains 8 bit tag to be stored as a smallp tos-2 contains UaddrLo,,UaddrHi as a smallp returns UaddrLo,,UaddrHi as a smallp } @PROLOGWRITETAGPTR: opcode[66'b], MAR ← [rhS, S + 0], c1; S ← S - 2, c2; TT ← MD{tag}, c3; TT ← TT and 0FF, c1; TT ← TT LRot8, c2; TOSH ← TT or TOSH, GOTO[@PROLOGWRITE0PTR], c3; { OPTIONAL for Lisp-Prolog-Emulator speed 5 clicks } { Write a Prolog Pointer and set Tag to zero } { tos contains low 24 bits to be stored tos-1 contains UaddrLo,,UaddrHi as a smallp returns UaddrLo,,UaddrHi as a smallp } @PROLOGWRITE0PTR: opcode[67'b], MAR ← [rhS, S + 0], c1; , c2; Rx ← MD{uaddrs}, c3; PWriteTail: Xbus ← Rx LRot12, XDisp, L2 ← L2.WriteUhi, c1; Ybus ← Rx, AltUaddr, L2Disp, DISP4[WriteSomeU], c2; UPblock0 ← TOSH, RET[WriteSomeUret], c*, at[00, 10, WriteSomeU]; UPblock1 ← TOSH, RET[WriteSomeUret], c*, at[01, 10, WriteSomeU]; UPblock2 ← TOSH, RET[WriteSomeUret], c*, at[02, 10, WriteSomeU]; UPblock3 ← TOSH, RET[WriteSomeUret], c*, at[03, 10, WriteSomeU]; UPblock4 ← TOSH, RET[WriteSomeUret], c*, at[04, 10, WriteSomeU]; UPblock5 ← TOSH, RET[WriteSomeUret], c*, at[05, 10, WriteSomeU]; UPblock6 ← TOSH, RET[WriteSomeUret], c*, at[06, 10, WriteSomeU]; UPblock7 ← TOSH, RET[WriteSomeUret], c*, at[07, 10, WriteSomeU]; UPblock8 ← TOSH, RET[WriteSomeUret], c*, at[08, 10, WriteSomeU]; UPblock9 ← TOSH, RET[WriteSomeUret], c*, at[09, 10, WriteSomeU]; UPblockA ← TOSH, RET[WriteSomeUret], c*, at[0A, 10, WriteSomeU]; UPblockB ← TOSH, RET[WriteSomeUret], c*, at[0B, 10, WriteSomeU]; UPblockC ← TOSH, RET[WriteSomeUret], c*, at[0C, 10, WriteSomeU]; UPblockD ← TOSH, RET[WriteSomeUret], c*, at[0D, 10, WriteSomeU]; UPblockE ← TOSH, RET[WriteSomeUret], c*, at[0E, 10, WriteSomeU]; UPblockF ← TOSH, RET[WriteSomeUret], c*, at[0F, 10, WriteSomeU]; TOSH ← TOS, c1, at[L2.WriteUhi, 10, WriteSomeUret]; Rx ← Rx LRot8, c2; Xbus ← Rx LRot12, XDisp, L2 ← L2.WriteUlo, c3; Ybus ← Rx, AltUaddr, L2Disp, DISP4[WriteSomeU], c1; { UPblockN ← TOSH, RET[ReadSomeUret], c*;} TOSH ← smallpl, c3, at[L2.WriteUlo, 10, WriteSomeUret]; PC ← PC + PC16, c1; TOS ← Rx LRot8, IBDisp, L2 ← L2.0, c2; S ← S - 2, L2 ← L2.0, DISPNI[OpTable], c3; { PrologOpDisp 14 clicks to Lisp execution / 10 clicks to Prolog area } { tos contains delta PrologPC as a smallp OR new PrologPC value uLMBbase contains real addr of Lisp{ #0 }/Microcode { =0 } table as (Bits 8 to 15,,Bits 0 to 7) of the 24 bit base address uSQtablebase contains real addr of base of SELECTQ arms table as (Bits 8 to 15,,Bits 0 to 7) of the 24 bit base address uSQbasehi, uSQbaselo contains virtual address of code base used by SQ offsets either jumps to Lisp code at appropriate arm or goes to EnterProlog never returns from Lisp returns from Prolog } @PROLOGOPFETCHPLUSOPDISP: opcode[42'b], Ybus ← TOSH xor smallpl, ZeroBr, c1; TT ← TOS, BRANCH[PrNewPC, PrDeltaPC], c2; PrNewPC: upVPClo ← TOS, L3 ← 0, c3; upLVPChi ← TOSH, GOTO[PrOPPcx], c1; PrDeltaPC: {TT ← (PrologPC + TOS)↑} TT ← upVPClo, L3 ← 0, c3; TOS ← TT + TOS, CarryBr, c1; TOSH ← upLVPChi, BRANCH[$, PrOPPcCar], c2; PrOpFen: TT ← TOS, c3; GOTO[PrOPPcx], c1; PrOPPcCar: TOSH ← TOSH + 1, c3; TT ← TOS, c1; PrOPPcx: upVPClo ← TOS, L0 ← L0.PrologOpFetch, c2;{update Prolog VPC low} rhTT ← TOSH LRot0, c3; Map ← [rhTT, TT], CANCELBR[$], c1; upLVPChi ← TOSH, L1 ← L1.NoFixes, c2;{update Prolog VPC high} rhRx ← Rx ← MD, ReadXRefBr, c3; MAR ← [rhRx, TOS + 0], ReadBRANCH[remapPrologPC, $], c1, at[L0.PrologOpFetch, 10, RxMapFixCaller]; Q ← upWriteMode, c2; TT ← MD or Q, c3; , c1; Q ← TT and 0FF,{ L3Disp,} c2; upN ← Q, GOTO[prepExuLisp], c3; prepExuLisp: {got here from a UI call or Careful, don't look at LMTable} TT ← TT LRot8, c1; rhRx ← Rx ← uSQtablebase, c2; GOTO[ExecuteLispVersion], c3; remapPrologPC: GOTO[RLxMapFix], c2; {PROLOGOPDISP: Ybus ← upPFcont, ZeroBr, c1; TT ← TT LRot8, BRANCH[Pr.PFentry.1, $], c2; rhRx ← Rx ← uLMBbase, c3; MAR ← [rhRx, TT + 0], c1;{fetch of lisp/ucode word} Ybus ← upDebug, ZeroBr, c2; Q ← MD, BRANCH[Prcareful, Prfast], c3; Prcareful: Ybus ← Q, ZeroBr, c1; Q ← Q + 1, CarryBr, BRANCH[LP.ucode, LP.lisp], c2; LP.ucode: BRANCH[LP.1.nocarry, LP.1.carry], c3; LP.1.nocarry: MAR ← [rhRx, TT + 0], c1; MDR ← Q, GOTO[EnterPrologC3], c2; LP.1.carry: {don't let ucode turn itself off} GOTO[EnterPrologC2], c1; Prfast: Ybus ← Q, ZeroBr, c1; Xbus ← 1, XDisp, BRANCH[LP.ucode, LP.lisp], c2; LP.lisp: rhRx ← Rx ← uSQtablebase, CANCELBR[ExecuteLispVersion], c3; Pr.PFentry.1: GOTO[EnterPrologC1], c3; } ExecuteLispVersion: {add 1 to Prolog PC for Lisp code} {S ← PV + 3 -- moved}, c1;{fix stack before going to Lisp code} Q ← TOS + 1, CarryBr, c2; upVPClo ← Q, BRANCH[PrLispEntryPCok, PrLispEntryPccar], c3; PrLispEntryPccar: , c1; Q ← TOSH + 1, c2; upLVPChi ← Q, c3; PrLispEntryPCok: MAR ← [rhRx, TT + 0], c1;{fetch byte offset of new PC} Q ← rhTT ← uSQbasehi, c2; Rx ← MD, L0 ← L0.ERefill, c3;{setup L0 for Refill} TT ← uSQbaselo, L1 ← L1.Refill, c1;{setup L1 for Refill} Rx ← RShift1 Rx, SE ← 0, YDisp, c2;{byte offset to word offset} TT ← TT + Rx, CarryBr, BRANCH[evenByte, oddByte, 0E], c3; evenByte: {new byte {pc16} 0} uPCCrossL ← 0, XC2npcDisp, BRANCH[Enofix, EfixrhTT], c1; Enofix: PC ← TT, BRANCH[EnopcwasO, EnopcwasE, 0E], c2; EnopcwasO: Cin ← pc16, GOTO[prrhTTok], c3;{toggle pc16} EnopcwasE: GOTO[prrhTTok], c3; oddByte: {new byte {pc16} 1} uPCCrossL ← 0, XC2npcDisp, BRANCH[Onofix, OfixrhTT], c1; Onofix: PC ← TT, BRANCH[OnopcwasO, OnopcwasE, 0E], c2; OnopcwasO: GOTO[prrhTTok], c3; OnopcwasE: Cin ← pc16, GOTO[prrhTTok], c3;{toggle pc16} EfixrhTT: PC ← TT, BRANCH[EfixpcwasO, EfixpcwasE, 0E], c2; EfixpcwasO: Cin ← pc16, GOTO[rhTTneedsfix], c3;{toggle pc16} EfixpcwasE: GOTO[rhTTneedsfix], c3; OfixrhTT: PC ← TT, BRANCH[OfixpcwasO, OfixpcwasE, 0E], c2; OfixpcwasO: GOTO[rhTTneedsfix], c3; OfixpcwasE: Cin ← pc16, GOTO[rhTTneedsfix], c3;{toggle pc16} rhTTneedsfix: Q ← rhTT, c1; Q ← Q + 1, c2; rhTT ← Q LRot0, GOTO[prrhTTok], c3; prrhTTok: UvChighL ← Q, c1; UvPCpageL ← TT, L0 ← L0.JRemap, c2; PC ← TT, c3; S ← S - 2, c1; uPCCrossL ← Q ← 0, c2; GOTO[UpdatePC], c3; { EnterProlog NOT AN OP-CODE } { first part of this runs in Lisp uCode, last part in Prolog uCode } { EnterPrologC2: , c2; EnterPrologC3: , c3; EnterPrologC1: {start by saving Lisp state } { upPC16 ← PC16 PC16 ← 0 upTOS ← TOS upTOSH ← TOSH upPV ← PV upPC ← PC upS ← S don't save rhPC -- need to remap PC at return to Lisp (page could be gone) } XC2npcDisp, c1; TT ← 1, BRANCH[prPC16is1, prPC16is0, 0E], c2; prPC16is1: upPC16 ← TT, Cin ← pc16, GOTO[PrPrep], c3; prPC16is0: upPC16 ← 0, GOTO[PrPrep], c3; PrPrep: upTOS ← TOS, c1; upTOSH ← TOSH, c2; upPV ← PV, c3; Bank ← PrologBank, c1; upPC ← PC, c2; upS ← S, CROSS[LispToProlog], c3; {-------------------------------------------------------------------------------} { Lisp part of ExitProlog } { arrive here from Prolog after saving prolog state } { restore lisp regs and continue } at[PrologToLisp], PrToLisp: TOS ← upVPClo, c1; TOSH ← upLVPChi, c2; PV ← upPV, c3; Ybus ← upPC16, ZeroBr, c1; PC ← upPC, BRANCH[PrSetPC16to1, PrSetPC16to0], c2; PrSetPC16to0: rhS ← nRhS, GOTO[PrPC16done], c3; PrSetPC16to1: rhS ← nRhS, Cin ← pc16, GOTO[PrPC16done], c3; PrPC16done: S ← upS, L1Disp, c1; rhPV ← nRhS, DISP4[PrologExitType], c2; { dispatch on exit type: Debug Careful GOTO[prepExuLisp] PageFault GOTO[PFault] Interrupt GOTO[LispInterrupt] PrUI unimplemented GOTO[ExecuteLispVersion] PrUI exception GOTO[ExecuteLispVersion] Heap Error Execute PrologOp 376'b } {-------------------------------------------------------------------------------} at[L1.PrInt, 10, PrologExitType], Rx ← KbdFXP, L2 ← 0, GOTO[PUNT], c3; {-------------------------------------------------------------------------------} at[L1.PrDebugC, 10, PrologExitType], , c3; PrCareful.Exit: TT ← upSave, c1; Q ← TT and 0FF, c2; upN ← Q, GOTO[prepExuLisp], c3; {-------------------------------------------------------------------------------} at[L1.PrPF, 10, PrologExitType], , c3; PrPF.Exit: , c1; L1 ← L1.NoFixes, c2; GOTO[PFault], c3; {-------------------------------------------------------------------------------} at[L1.PrUI, 10, PrologExitType], L3 ← 1, c3; PrUI.Exit: , c1; GOTO[PrOpFen], c2; {-------------------------------------------------------------------------------} at[L1.PrHeapErr, 10, PrologExitType], rhRx ← Rx ← uSQtablebase, c3; PrHeap.Exit: upPFcont ← 0, c1; TT ← 0FE, c2; GOTO[PrLispEntryPCok], c3;{execute op 376'b} {-------------------------------------------------------------------------------} at[L1.PrSink, 10, PrologExitType], Q ← upTemp, GOTO[sink1], c3;{9000 + Q to MP} {-------------------------------------------------------------------------------} } { E N D }