:TITLE[Lisp0.0mc, October 25, 1982 12:30 PM, van Melle]; * Alto mode instructions insert[DisplayDefs]; * Get WordsPerLine definition SetTask[0]; IMRESERVE[pgLisp0, IntfaceBase, IntfaceCnt]; LispInst: dispatch[PCF[IBUF], 14, 4], at[LispInstLoc]; disp[@@Mbix], CSkipData; * breakpoint, mbx[12]; * breakpoint, mbx[13]; * breakpoint, mbx[14]; * breakpoint, mbx[17]; @@Mbix: * Return to Lisp with value in Ac0,1 lspGenBrHi ← (INTERFACEspace), mbx[00]; lspGenBr ← (INTERFACEbase); PFetch1[lspGenBr, lspEp, 0]; * retrieve FX from Intfacepg T ← AC0; * move value to L0,1 for return lspL0 ← T; * need to get WW to see if a Lisp interrupt struck while we were in AltoLand (which would be masked out of ACTIVE) :IF[WindFlg]; T ← (R400) or (52c); * mds 452 = WW PFetch2[MDS, WW]; * fetch WW, ACTIVE :ENDIF; T ← AC1, task; lspL1 ← T; :IF[StatsMode]; T ← (StatsPointerLocation); PFetch1[MDS, lspStatsPtr]; * Get this fetch going, too :ENDIF; lspInstFlag ← (NormalState); MDSTypeBaseBrHi ← MDSTypeSpace; * for type tests MDSTypeBaseBr ← MDSTypeBase; :IF[WindFlg]; WW ← (WW) and not (100000c); * maybe don't need this T ← (ACTIVE) or (LispKeyMask); T ← (WW) and T; * Ignore masked-out interrupts NWW ← (NWW) or T, goto[mbi2, R<0]; * OR waiting interrupts into NWW, skip if ints off FreezeResult, call[CheckInterrupts]; * may need to set IntPending :ENDIF; mbi2: lspEpHi ← (StackSpace); * Setup constant registers T ← lspEpHi ← (lspEpHi) or (300c); * StackHi in left, error value lspStkBrHi ← T; * in right (for overflow case) lspTspHi ← T, loadpage[pgReturn]; lspStkBr ← 0c; onpage[pgReturn]; :IF[StatsMode]; lu ← lspStatsPtr; * Are stats on (this loc nonzero)? T ← lspEp, skip[alu#0]; lspStatsPtr ← (Zero) - 1; * set sign bit so we can test quickly :ELSE; T ← lspEp; :ENDIF; lspLN ← T, goto[lspRtn2]; * return to frame Ep @@InitLispRegs: AC1 ← 2000c, mbx[11]; LoadPageExternal[PNIPPage]; T ← (AC1) or (114c), callExternal[PNIPLoc]; * MP ← 1100d AC1 ← IP[FFault]c; Stkp ← AC1; * Address of Ffault T ← lspInstFlag ← 0c; Stack ← (Stack) or (1c); * let emulator handle pagefault Stack ← (Stack) and not (20000c); * Ignore H4 parity errors AC1 ← (RamRelease); AC1 ← (AC1) or (DolphinMcVersion), call[InitStore]; AC1 ← (MinBcplVersion), call[InitStore]; AC1 ← (MinLispVersion), call[InitStore]; AC1 ← (WordsPerLine), call[InitStore]; AC1 ← IP[StoragePages]c; Stkp ← AC1; PStore1[AC0, Stack], call[IncTRet]; AC1 ← 400c; AC1 ← (AC1) or (200c), call[InitStore]; * pages per module = 600 * for most Dolphins, the 48-bit NS host number is hiding in the high 32 bits * of ram location 7777. High word is constant zero. AC1 ← Zero, call[InitStore]; * Store zero T ← lspL0 ← 7400c; * low bits of T ← 0 lspL0 ← (lspL0) or (377c), call[ReadRamInit]; * L0 ← 7777 * Read 7777[0:15] PStore1[AC0, AC1, 7]; T ← 1c, call[ReadRamInit]; * Read 7777[16:31] PStore1[AC0, AC1, 10], goto[NoSkipStart]; InitStore: PStore1[AC0, AC1]; * Store AC1 at offset T from init vector IncTRet: T ← (Zero) + T + 1, return; * T ← T+1 ReadRamInit: * Return in AC0 the contents of location in LspL0, part by T APCTask&APC ← lspL0; ReadCS; T ← CSData, disptable[1,1,0]; * Even placement AC1 ← T, return; lspuPCTrace: * uPC trace, not on Dolphin return, mbx[15]; SkipStart: LoadPageExternal[nePage], gotoExternal[lneTaskSkpLoc]; NoSkipStart: LoadPageExternal[nePage], gotoExternal[lneTask1stLoc], at[FaultDisp, InBcplState!]; :IF[WithPilotBitBlt]; @@XBitBlt: * No alto bitblt loadpageExternal[xoPage], gotoExternal[lTrapLoc], mbx[16]; :ELSE; @@XBitBlt: * AC0 points at a bitblt table * AC3 holds 2*scanlines done PFetch1[AC0, AC2hi, 0], mbx[16]; T ← (PCF.WORD); PCB ← (PCB) + T; PCF ← RZero; * update PCB, PCF PFetch1[AC0, AC2, 1]; * get low pointer out of bbt * BitBlt needs Stkp pointing at 2*scanlines done, viz. AC3 lspL0 ← IP[AC3]c; Stkp ← lspL0; lspInstFlag ← (InAltoBitBltState); T ← rhmask[AC2hi]; * adjust the high pointer AC2hi ← (lsh[AC2hi, 10]) + T + 1; T ← (Cycle&PCXF) or (100000c), gotoExternal[lbbBitBltLoc]; bbPageFault: lspL1 ← 1c, goto[bbMExit], at[FaultDisp, InAltoBitBltState!]; lbbMesaInt: lspL1 ← 0c, goto[bbMExit], at[BBMesaIntLoc]; lbbMDone: lspL1 ← 2c, goto[bbMExit], at[BBMDoneLoc]; bbMExit: AC2hi ← 0c; * restore normal AC2hi lspInstFlag ← (NormalState); ***** T ← (ldf[Cycle&PCXF, 15, 2]) + T; T ← lspL1, gotoExternal[lBitBltDoneLoc]; * T ← skip distance :ENDIF; * XNOvaOps for accessing the virtual memory. These return skipping * on success, or not skipping if pagefault @@BGetBase: * AC0 ← GetBase(AC0,,AC1) nop, mbx[04]; * alloc constraint call[lspSetGBr]; PFetch1[lspGenBr, AC0, 0]; AC0 ← AC0, goto[SkipStart]; * wait for fault @@BGetBase32: * AC0,,AC1 ← GetBase32Bits(AC0,,AC1) nop, mbx[06]; * alloc constraint call[lspSetGBr]; PFetch1[lspGenBr, AC0, 0]; PFetch1[lspGenBr, AC1, 1]; AC1 ← AC1, goto[SkipStart]; @@BGetBasePtr: * AC0,,AC1 ← GetBasePtr(AC0,,AC1) nop, mbx[07]; * alloc constraint call[lspSetGBr]; PFetch1[lspGenBr, AC1, 1]; PFetch1[lspGenBr, AC0, 0]; AC0 ← (AC0) and (377c), goto[SkipStart]; @@BPutBase: * PutBase(AC0,,AC1, @AC2) PFetch1[AC2, lspL3, 3], mbx[05]; call[lspSetGBr]; PStore1[lspGenBr, lspL3, 0]; lspL3 ← lspL3, goto[SkipStart]; @@BPutBase32: * PutBase32Bits(AC0,,AC1, @@AC2) PFetch1[AC2, lspL3, 3], mbx[10]; T ← lspL3; PFetch1[MDS, lspL2], call[retLBL]; T ← (lspL3) + 1; PFetch1[MDS, lspL3]; call[lspSetGBr]; PStore2[lspGenBr, lspL2, 0]; lspL3 ← lspL3, goto[SkipStart]; lspSetGBr: * Load base reg LispGenBr from AC0,1 T ← rhmask[AC0]; lspGenBrHi ← T; lspGenBrHi ← (lsh[lspGenBrHi, 10]) + T + 1; T ← AC1; lspGenBr ← T, goto[retLBL]; * Wait for lspGenBr ← to finish * VMTransferPage(toVp, FromVp) ** moves 400b words from virtual address in ac1 to that in ac0 @@VMTransferPage: T ← lhmask[AC0], mbx[03]; lspL3 ← T; T ← lsh[AC0, 10]; lspL2 ← T; * L2,3 is base for page AC0 (dest) T ← lsh[AC1, 10]; lspGenBr ← T; T ← lhmask[AC1]; lspGenBrHi ← T; * lspGenBr is base for page AC1 (src) T ← lspLN ← 374c; * Counter/offset xmm: nop; * alloc constraint PFetch4[lspGenBr, XBuf], call[retLBL]; PStore4[lspL2, XBuf], call[retLBL]; T ← lspLN ← (lspLN) - (4c); goto[xmm, alu>=0]; goto[SkipStart]; * ReadFlags(Vp) -> Real Page, Flags (ref, -- , wp, dirty, ...) @@ReadFlags: Loadpage[pgMapOps], mbx[01]; * alloc constraint UseCTask, callp[xReadFlags]; * get Rp in AC0, Flags in T AC1 ← T, goto[NoSkipStart]; * Lisp instructions for the same thing @ReadFlags: lspUFN ← 161c, call[lspReadFlags], opcode[161]; PushTP5: * Flags were left in T Stack&+1 ← T, goto[nxiLBL]; @ReadRP: lspUFN ← 162c, call[lspReadFlags], opcode[162]; T ← AC0, goto[PushTP5]; * get RP, stuff it lspReadFlags: * Come here with lspUFN set appropriately * Return with Flags in T, RP in AC0, or else ufn out T ← Stack&-1; lu ← (Stack) - (smallpl); AC0 ← T, UseCtask, goto[xReadFlags, alu=0]; goto[ufnLBL]; * VP not smallpos? * Come here with VP in AC0, returns flags in T, RP in AC0 * UseCTask in calling instruction xReadFlags: T ← APC&APCTask; lspL5 ← T, call[XMapAC0]; * Get info in XBuf1,2,3 complemented T ← lsh[XBufFC, 10]; * flags T ← (rhmask[XBufRow]) or T; * Row address in RH XBuf ← (Zero) - 1; XBuf ← (XBuf) xor T; * XBuf ← ~T = flags,,old real page# nop; * is this needed? xmap[lspGenBr, XBuf, 0]; * Restore entry (XMap had changed it) XBuf ← XBuf; * is this needed? T ← (XBuf) and not (170000c); * Mask out flags to get Ac0 ← T; * AC0 ← real page# lu ← (XBuf) and (10000c); XBuf ← rsh[XBuf, 1], skip[alu=0]; * Rearrange flag bits: XBuf ← (XBuf) or (100000c); * Dolphin gives LOGSE,WP,DIRTY,REF * Lisp wants REF,--,WP,DIRTY APC&APCTask ← lspL5; T ← (XBuf) and (130000c), return; * T ← flags * SetFlags(Vp, RP, flags) @@SetFlags: PFetch1[AC2, XBuf1, 3], mbx[02]; * flags in XBuf1 T ← AC1, loadpage[pgMapOps]; * RP in XBuf XBuf ← T, callp[WriteMap2]; goto[NoSkipStart]; @WriteMap: loadpage[pgHStack], call[CheckElt3P5], opcode[163]; T ← Stack&-1, call[WriteMap1]; * Flags Pop2P5: StkState ← rsh[StkState, 2], goto[nxiLBL]; * Two pops WriteMap1: lu ← (Stack&-1) - (smallpl); XBuf1 ← T, skip[alu=0]; * XBuf1 ← flags lspUFN ← 163c, goto[ufnLBL]; * not smallpos T ← Stack&-1; lu ← (Stack&-1) - (smallpl); XBuf ← T, skip[alu=0]; * XBuf ← RP lspUFN ← 163c, goto[ufnLBL]; * not smallpos T ← Stack&-1; lu ← (Stack&+1) - (smallpl); AC0 ← T, skip[alu=0]; * AC0 ← VP lspUFN ← 163c, goto[ufnLBL]; * not smallpos WriteMap2: * Now have XBuf = RP, XBuf1 = Flags, AC0 = VP XBuf1 ← lsh[XBuf1, 1], skip[R>=0]; XBuf1 ← (XBuf1) or (10000c); * rearrange flags as needed T ← (XBuf1) and (70000c); XBuf ← (ldf[XBuf, 4, 14]) or T, goto[XMapAc0]; XmapAc0: * Call XMap for page in AC0 using XBuf T ← lhmask[AC0]; lspGenBrHi ← T; T ← lsh[AC0, 10]; lspGenBr ← T; nop; * is this needed? xmap[lspGenBr, XBuf, 0]; XBuf ← XBuf, UseCTask, goto[retLBL]; * Don't task while map is screwy :END[Lisp0];