{File name TMyBusExt.mc Description: DandeLion Interlisp Emulator Bus Extension Author: Purcell Created: 31-May-84 16:45:34 } { purcell 3-Jun-85 23:03:10 add long delays in bus} { by don 24-Mar-85 11:40:24 deleted spurious output at tail of input/writes added extra arg for BusCtl command added u for mBusAddrM {fZ = 3} added u for orig alpha changed stack reads to STK saved L {instead of PV} fixed page fault exits fixed normal exits reallocated u regs changed loading of rhTT from uVirtH } {INPUT: TOSH _ smallpl, DISP4[MiscIn], c1, at[0D,10, MiscDisp];} { (\PCBLT (alpha op) VIRTUALADDR PCADDRH PCADDRL COUNT) L3Disp values initialized to alpha byte 1,2 bit data size: 0=word, 1=byte, 2=reversed bytes, 3=nibble 4 bit 0=output, 1=input 8 bit extra states 0 read/output word 1,9 read/output bytes 2,A read/output bytes reversed 3,7,B,F read/output nibbles 4 input/write word 5,D input/write bytes 6,E input/write bytes reversed } {L} RegDef[rAddr, R, 3]; {pc bus address low 16 bits} {TOSH} RegDef[rDataIn, R, 1]; {TT} RegDef[rDataOut, R, 2]; {rDataOut not needed during cross so alias with and use TT} {Rx real TOS word count remaining (end input/write at 0; end read/output at -1)(fetch from virt+TOS-1) Q used by mapping routine } RegDef[uPPsave, U, 0CE];{unused u reg} RegDef[uxx3, U, 43];{fZ=3} RegDef[uAlpha, U, 4B];{any temp} RegDef[uVirtL, U, 27];{TT} RegDef[uVirtH, U, 4A];{any temp} RegDef[uBusCtl, U, 52];{fZ=2} RegDef[uAddr, U, 33];{rAddr}{fZ=3} RegDef[uDataOut, U, 42];{fZ=2} {RegDef[UrL, U, 3B]; {rA = L, fZ = _RH}} {L0 unused L1 Fix {L1.None} {L2 0=normal, 1=test loop // unused} L3 phase and op} { orig alpha: == operation 0 read/output word 1 read/output bytes 2 read/output bytes reversed 3 read/output nibbles 4 input/write word 5 input/write bytes 6 input/write bytes reversed TOS count{16 bits} STK-0 bus control word STK-1 low base address out{16 bits} STK-2 mBusAddrM{16 bits} STK-3 virt addr of buffer{24 bits} STK-5 operation{3 bits} Regs: L saved into UrL TOS remaining count T temp Rx temp TT temp UrL _ L uPPsave last write to PP uVirtL buffer addr lo uAddr Bus addr uBusCtl Control to Bus uDataOut data out } { in new version of Misc.mc @ESC: Xbus _ ibHigh, XDisp, c1, opcode[370'b]; ESCx: TT _ ib, XDisp, push, DISP4[ESCHi], c2; PC _ PC + 1, STK _ TOS, pop, DISP4[ESC8n], c3, at[8,10,ESCHi]; } { this replaces @BANDBLT } PCBKW: at[3,10,ESC8n], FloatNop, L1 _ L1.None, c1; UrL _ L, L2 _ 0, c2; Rx _ 0FF + 1, c3; Q _ uPPsave, c1; PPort _ Q and ~Rx, c2; FloatNop, c3; {seventh arg in TOS} Rx _ STK, pop, c1;{sixth arg} uBusCtl _ Rx, c2; , c3; rAddr _ STK, pop, c1;{fifth arg} Rx _ STK, pop, c2;{fourth arg} uxx3 _ Rx, c3; Rx _ STK, pop, c1;{third arg} uVirtH _ Rx, c2; Rx _ STK, pop, c3;{second arg} uVirtL _ Rx, c1; Rx _ STK, pop, c2;{first arg} uAlpha _ Rx, c3; Rx{2*TOS} _ TOS LShift1, c1; FLTimes.WA.WB{% fZ=3}, Float.M, Xbus{mBusAddrM} _ uxx3, c2; , c3; {TT=rDataOut=virtL} pcA4: Xbus _ uAlpha, XDisp, c1; rDataIn{4*TOS} _ Rx LShift1, DISP4[pcAdd, 0C], c2; rAddr _ rAddr + TOS, GOTO[pcArg], c3, at[0C, 10, pcAdd];{word addressing} rAddr _ rAddr + Rx{2*TOS}, GOTO[pcArg], c3, at[0D, 10, pcAdd];{byte addressing} rAddr _ rAddr + Rx{2*TOS}, GOTO[pcArg], c3, at[0E, 10, pcAdd];{byte reversed} rAddr _ rAddr + rDataIn{4*TOS}, GOTO[pcArg], c3, at[0F, 10, pcAdd];{nibble addressing} pcArg: rAddr _ rAddr -1, c1; uAddr _ rAddr, Rx _ 0{force remap}, c2; Xbus _ uAlpha, XDisp, c3; pcBCtl: Float.L, Xbus{mBusAddrL} _ uAddr, BRANCH[pcBOut, pcBIn, 0B], c1; pcBIn: {T{TOSH} _ T{TOSH} or 1, }GOTO[pcCtlj], c2; {set mBusCtl for reads} pcBOut: {T{TOSH} _ T{TOSH} or 2, }GOTO[pcCtlj], c2; {set mBusCtl for writes} pcCtlj: {uBusCtl _ T{TOSH}}, c3; Xbus _ uAlpha, XDisp, c1; Float.M, Xbus{mBusCtl} _ uBusCtl, L3 _ 0, {L3 _ alpha} DISP4[pcBlk], c2; {pcRead subroutine; return to pcReadRet+L3, use uAddr, update uAddr, read virt+TOS-1} pcRead: MAR _ Rx _ [rhRx, Rx-1], BRANCH[$, pcDn2], c1; rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, L3Disp, BRANCH[$, pcRcr, 1], c2; pcRead3: uAddr _ rAddr, rDataOut _ MD, RET[pcReadRet], c3; {pcBus subroutine: return to pcBusRet+L3, used both for input and output; rDataIn ignored on output} pcBus2: Noop, c2; pcBus3: uAddr _ rAddr, c3; uDataOut _ rDataOut, c1;{% good for 5; ok others ?} Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, c2; pcBus: Noop, c3; pcBus1: Noop, CANCELBR[$, 3], c1; Noop, c2; {%P 3-Jun-85 23:02:25} { Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2;} Ybus _ rDataIn, Xbus _ PPort, XwdDisp{9(,10)}, c3; Q _ rDataIn or FloatResult, L3Disp, BRANCH[$, pcWait, 1], c1; rDataIn _ Q, Float.L, Xbus{mBusOData} _ uDataOut, {RET[pcBusRet{%T}],} BRANCH[pcBRo, pcBRi, 0B], c2; pcWait: Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, CANCELBR[pcBus, 0F], c2; pcBus3CH: uAddr _ rAddr, c3; uDataOut _ rDataOut, c1;{% good for 5; ok others ?} Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, c2; {%P 3-Jun-85 23:02:25} pcBusCH: Noop, c3; { Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3; Noop, c1; Noop, c2; Noop, c3;} pcBus1CH: Ybus _ TOS - 1, ZeroBr, CANCELBR[$, 3], c1; BRANCH[$, pcskipit], c2; Ybus _ rDataIn, Xbus _ PPort, XwdDisp{9(,10)}, c3; Q _ rDataIn or FloatResult, L3Disp, BRANCH[$, pcWaitCH, 1], c1; rDataIn _ Q, Float.L, Xbus{mBusOData} _ uDataOut, {RET[pcBusRet{%T}],} BRANCH[pcBRo, pcBRi, 0B], c2; pcBRo: Ybus _ 2, YDisp, L3Disp, GOTO[pcBR] c3; pcBRi: Ybus _ rDataIn and 2, YDisp, L3Disp, GOTO[pcBR] c3; pcBR: L3Disp, BRANCH[zBit1, $, 0D], c1; Noop, RET[pcBusRet], c2; zBit1: Xbus _ TIData,{%T} RET[pcBusRet], c2; pcWaitCH: Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, CANCELBR[pcBusCH, 0F], c2; pcskipit: Ybus _ rDataIn, Xbus _ PPort, XwdDisp{9(,10)}, c3; Q _ rDataIn or FloatResult, L3Disp, BRANCH[$, pcWaitCHs, 1], c1; rDataIn _ Q, FloatNop{turn off mBusIData}, {RET[pcBusRet{%T}],} BRANCH[pcBRo, pcBRi, 0B], c2; pcWaitCHs: Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, CANCELBR[pcBusCH, 0F], c2; {0: Block Read/Output Words}{uAddr=rAddr=last, TOS=cnt} CALL[pcRead], c3, at[0, 10, pcBlk]; pcOW: TOS _ TOS -1, CarryBr, c1, at[0, 10, pcReadRet]; uDataOut _ rDataOut, BRANCH[pcDn, pcBus, 0E], c2; Noop, CALL[pcRead], c3, at[0, 10, pcBusRet], c3; {1: Block Read/Output Bytes} CALL[pcRead], c3, at[1, 10, pcBlk]; pcOB: TOS _ TOS -1, CarryBr, L3 _ 9, c1, at[1, 10, pcReadRet]; uDataOut _ rDataOut, BRANCH[pcDn, pcBus, 0E], c2; rDataOut _ rDataOut LRot8, L3 _ 1, c3, at[9, 10, pcBusRet]; pcOBB: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, GOTO[pcBus2], c1; CALL[pcRead], c3, at[1, 10, pcBusRet], c3; {2: Block Read/Output Bytes Reversed} Ybus _ TOS, ZeroBr, CALL[pcRead], c3, at[2, 10, pcBlk]; pcOBr: rDataOut _ rDataOut LRot8, c1, at[2, 10, pcReadRet]; uDataOut _ rDataOut, L3 _ 0A, c2; TOS _ TOS-1, Xbus _ PPort, XwdDisp{9(,10)}, GOTO[pcBus1], c3; {TOS was tested for zero at Read} rDataOut _ rDataOut LRot8, L3 _ 2, c3, at[0A, 10, pcBusRet]; pcOBBr: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, GOTO[pcBus2], c1; Ybus _ TOS, ZeroBr, , CALL[pcRead], c3, at[2, 10, pcBusRet], c3; {3: Block Read/Output Nibbles} CALL[pcRead], c3, at[3, 10, pcBlk]; pcON: TOS _ TOS -1, CarryBr, L3 _ 7, c1, at[3, 10, pcReadRet]; uDataOut _ rDataOut, BRANCH[pcDn, pcBus, 0E], c2; rDataOut _ rDataOut LRot12, L3 _ 0B, c3, at[7, 10, pcBusRet]; pcONN: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, GOTO[pcBus2], c1; rDataOut _ rDataOut LRot12, L3 _ 0F, c3, at[0B, 10, pcBusRet]; pcONNN: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, GOTO[pcBus2], c1; rDataOut _ rDataOut LRot12, L3 _ 3, c3, at[0F, 10, pcBusRet]; pcONNNN: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, GOTO[pcBus2], c1; Noop, CALL[pcRead], c3, at[3, 10, pcBusRet], c3; pcInPipeStart: uAddr _ rAddr, c1; Float.L, Xbus{mBusOData} _ uDataOut, c2; Float.L, Xbus{mBusAddrL} _ uAddr, c3; rAddr _ rAddr -1, Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, c1; uAddr _ rAddr, rDataIn _ 0, GOTO[pcBus], c2; {4: Block Input/Write Words} rAddr _ rAddr -1, c3, at[4, 10, pcBlk]; pcInPipeStartCH: uAddr _ rAddr, c1; Float.L, Xbus{mBusOData} _ uDataOut, c2; Float.L, Xbus{mBusAddrL} _ uAddr, c3; rAddr _ rAddr -1, Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, c1; uAddr _ rAddr, rDataIn _ 0, GOTO[pcBusCH], c2; pcIW: TOS _ TOS -1, NZeroBr, c1, at[4, 10, pcWriteRet]; uAddr _ rAddr, rDataIn _ 0, BRANCH[pcDnCH, pcBusCH, 0E], c2; rDataIn _ rDataIn, CALL[pcWrite], c3, at[4, 10, pcBusRet]; pcWrite: {% T test bit 1} Ybus _ rDataIn, YDisp, c1; BRANCH[zeroBit1, $, 0D], c2; Noop, GOTO[pcWrite1], c3; zeroBit1: Xbus _ TStatus, GOTO[pcWrite1], c3; pcWrite1: MAR _ Rx _ [rhRx, Rx-1], c1; pcWrite2: MDR _ rDataIn, Float.L, Xbus{mBusAddrL} _ uAddr, L3Disp, BRANCH[$, pcWcr, 1], c2; rAddr _ rAddr -1, Xbus _ FloatResult{mBusIData}, FLFloatA{fZ=2}, Float.L, RET[pcWriteRet], c3; {5: Block Input/Write Bytes} rAddr _ rAddr -1, GOTO[pcInPipeStart], c3, at[5, 10, pcBlk]; rDataIn _ rDataIn {and 0F}, L3 _ 0D, c3, at[5, 10, pcBusRet]; pcIBB: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, c1; rDataIn _ rDataIn LRot8, GOTO[pcBus3CH], c2; rDataIn _ rDataIn LRot8, CALL[pcWrite], c3, at[0D, 10, pcBusRet]; pcIB: TOS _ TOS -1, NZeroBr, L3 _ 5, c1, at[0D, 10, pcWriteRet]; uAddr _ rAddr, rDataIn _ 0, BRANCH[pcDn, pcBus, 0E], c2; {6: Block Input/Write Bytes Reversed} rAddr _ rAddr -1, GOTO[pcInPipeStart], c3, at[6, 10, pcBlk]; rDataIn _ rDataIn {and 0F}, L3 _ 0E, c3, at[6, 10, pcBusRet]; pcIBBr: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, c1; rDataIn _ rDataIn LRot8, GOTO[pcBus3CH], c2; rDataIn _ rDataIn LRot0, CALL[pcWrite], c3, at[0E, 10, pcBusRet]; pcIBr: TOS _ TOS -1, NZeroBr, L3 _ 6, c1, at[0E, 10, pcWriteRet]; uAddr _ rAddr, rDataIn _ 0, BRANCH[pcDn, pcBus, 0E], c2; {Exceptions} {Remap to Virt+TOS-1}{don't fault if TOS=0} pcWcr: Noop, CANCELBR[pcCr, 0F], c3; pcRcr: rAddr _ rAddr +1, CANCELBR[pcCr, 0F], c3; pcCr: TOS _ TOS -1, CarryBr, c1; TT _ uVirtL, BRANCH[pcCz, pcCnz], c2; pcCz: rhTT _ uVirtH, GOTO[pcMp], c3; pcCnz: TT _ TT + TOS, CarryBr, c3; rhTT _ uVirtH, BRANCH[pcnoInc, pcInc], c1; pcnoInc: , c2; GOTO[pcMp], c3; pcInc: Q _ rhTT+1, LOOPHOLE[byteTiming], c2; rhTT _ Q LRot0, GOTO[pcMp], c3; pcMp: Map _ Q _ [rhTT, TT], c1; TOS _ TOS + 1, c2; Rx _ rhRx _ MD, XwdDisp, c3; Map _ Q _ [rhTT, TT], DISP2[pcFault], c1; MDR _ Rx or 0B0, GOTO[beWMapb], c2, at[0,4,pcFault]; MDR _ Rx or 0B0, GOTO[beWMapb], c2, at[1,4,pcFault]; beWMapb: L3Disp, c3; pcMpD: MAR _ Rx _ [rhRx, TT+0], BRANCH[pcRead2, pcWrite2, 0B], c1; pcRead2: rAddr _ rAddr -1, Float.L, Xbus{mBusAddrL} _ uAddr, L3Disp, GOTO[pcRead3], c2; {% fix ups} pcFault: T _ qWriteProtect, GOTO[beWMapX], c2, at[2,4,pcFault]; T _ qPageFault, GOTO[beWMapX], c2, at[3,4,pcFault]; beWMapX: {push stack back = 6 push's} Q _ uPPsave, push, c3; PPort _ Q, push, c1; L _ UrL, push, c2; PC _ PC - 1, push, c3; push, c1; L1Disp, push, GOTO[WTrap], c2; {exits} pcDnCH: GOTO[pcDn1], c3; pcDn2: , CANCELBR[$, 2], c2; pcDn: , c3; pcDn1: L _ UrL, CANCELBR[$, 3], c1; Rx _ uPPsave, IBDisp, c2; PPort _ Rx, DISPNI[OpTable], c3; { E N D }