: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];