// VMemB.bcpl. D* virtual memory package // Last modified March 19, 1985 6:38 PM by Bill van Melle // Last modified December 13, 1984 11:50 AM by Bill van Melle // Gutted November 19, 1984 5:34 PM by Bill van Melle // Last modified May 25, 1983 10:58 AM by Bill van Melle // Last modified March 14, 1983 5:31 PM by Bill van Melle // Last modified February 4, 1983 10:33 PM by Bill van Melle // Major pruning December 16, 1982 10:27 PM by Bill van Melle // Last modified May 17, 1982 1:58 PM by Bill van Melle get "LispBcpl.decl" get "Stats.decl" get "VMem.decl" get "Streams.d" external // SUBRS [ PageFault // (lvPtr) MOREVMEMFILE // (filepage) WRITEMAPSUBR // (vp rp flags) LISPFINISH // () returns to Alto exec // other entries IGetBase // (offset) IPutBase // (offset, val) LookupPage // (vp) RemapMemory // () cleans up on exit WriteSwapBuf // () writes any dirty page out to vmem ] external [ // OS procedures CallSwat; Zero // fpr LISPFINISH: CreateDiskStream; PositionPage; FileLength; ReadBlock; Closes // Other procs used LispCleanup; LoadRam; Fault; MachineType; DeImplementedSubr BP; VP; VP2 IndexedPageIO; SmallUnbox @BGetBase; @BPutBase; MkSmallPos; EqNIL; EmUnbox // Raid procs Ws; Wo; RaidReset; PrintPtr; RAIDCode // Statics realPageTableSetup; memAvailTable; FirstRealPageNo // exported noFaultFlg; SwapBuf; SwapBufVp; SwapBufFileP; SwapBufDirty lvAbortFlag // OS LispFmap; @RMSK @lvNIL; @lvKT; @MiscSTATSbase insideRaid; EmulatorSpace LastRealPageNo // fpr LISPFINISH: PupZoneStart; PupZoneLength; altoUcodeFp; uCodeLoaded // Other external VMem procs (from VmemA.asm) ReadFlags // (VP) -> oldflags ReadRP // (VP) -> RP SetFlags // (VP, RP, flags) ] static [ @Bpt; @BptSegment; BptSize; @BufVp; @BufRP @RPoffset; LispFmap realPageTableSetup = false memAvailTable FirstRealPageNo SwapBuf SwapBufVp = 0 SwapBufFileP = 0 SwapBufDirty = false ] let PageFault(lvPtr, ac2) = valof // page fault handler [ let vp = VP(lvPtr) if vp ne SwapBufVp then [ let flags = ReadFlags(vp) test (flags & VACANT) ne VACANT ifso resultis RAIDCode("Fault on resident page", lvPtr, true) ifnot [ let filep = LookupPage(vp) test filep ifso [ if not insideRaid then RAIDCode("Non-Raid fault inside Bcpl. ^N to continue", lvPtr) if vp ne SwapBufVp then ReadSwapBuf(vp, filep) ] ifnot InvalidAddr (lvPtr) ] ] if (@ac2)!2 gr Fault then SwapBufDirty = true // write fault ac2!4 = EmulatorSpace // adjust reference to point at core buffer ac2!5 = ((ac2!5) & RMSK) + SwapBuf resultis lvPtr ] and ReadSwapBuf(vp, filep) be [ if SwapBufDirty then WriteSwapBuf() IndexedPageIO(LispFmap, filep, SwapBuf, 1, false) SwapBufVp = vp SwapBufFileP = filep SwapBufDirty = false ] and WriteSwapBuf() be [ if SwapBufDirty then IndexedPageIO(LispFmap, SwapBufFileP, SwapBuf, 1, true) SwapBufDirty = false ] and InvalidAddr (lvPtr) be [ if insideRaid then [ Ws ("Invalid address: ") PrintPtr (lvPtr!0, lvPtr!1) RaidReset() ] RAIDCode("Invalid address", lvPtr, true) ] repeat and LookupPage(vp) = valof [ // Returns page in vmem file or 0 if the page does not exist compileif (not BigAddressSpace) then [ if (vp𢋠) ne 0 then InvalidVP(vp) ] let pmpE = BGetBase(PMTspace, PMTbase + vp<