{ File name: GermSwap.mc Description: Code we can drive from Bermuda to move the germ! } {** this stuff is specific to PrincOps version! **} Set[MapRealAddrHigh, 4]; Set[MapRealAddrLow, 0]; Set[germPageHigh, 0]; Set[germPageLow, 1]; Set[cedarGermPageHigh, 3E]; Set[cedarGermPageLow, 2]; MacroDef[RtnBLT, at[#1,10,subrRet]]; Set[L0.vswap, 0E]; Set[L0.germExch, 0F]; {++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Well, We've got a problem here. PrincOps 3.0 expects the germ at .mv [3E, 0200] and PrincOps 4.0 expects the germ at .mv [00, 0100]. transferCount contains the # of pages we have to move and we have to move them from Map[0001] to Map[3E02] CoreInitial sets up map and leaves next available page (virtual) in topPage. Since everybody's been nice enough so far to move things around and play the game according the the PrincOps 4.0 rules (like Burdock), how about if we just swap the approprite map entries and leave everything as it already is? Well, that leaves a funny hole in VM at [00, 0100], So... So we do an even cuter swap put the germ where it belongs: [01, 3E02] <==> [01, 0001] move some pages back under .vm 0100 to be *nice* [01, (topPage-1)-transferCount] <==> [01, 0001] +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } mapGerm: rB ← germPageHigh ,c1; rB ← rB LRot8 ,c2; rB ← rB or germPageLow ,c3; {Map entry for 4.0 germ} rE ← cedarGermPageHigh ,c1; rE ← rE LRot8 ,c2; rE ← rE or cedarGermPageLow ,c3; {Map entry for 3.0 germ} rC ← transferCount ,c1; {number pages in germ} rErh ← MapRealAddrHigh {1}, c2; rBrh ← MapRealAddrHigh {1}, c3; looper: {Noop} ,c1; L0 ← L0.germExch ,c2; CALL[memSwap] ,c3; germExch: rB ← rB + 1 ,c1, RtnBLT[L0.germExch]; {make pages vacant} rC ← rC - 1, ZeroBr ,c2; rE ← rE + 1, BRANCH[looper, swipe] ,c3; { Now move a swatch of physical memory *present* in top vm to sit under where .vm 0100 used to be! } swipe: rB ← germPageHigh ,c1; rB ← rB LRot8 ,c2; rB ← rB or germPageLow ,c3; {Map entry for 4.0 germ} rC ← transferCount ,c1; {number pages in germ} rE ← topPage ,c2; rE ← rE - rC ,c3; {Map entry for 3.0 germ} looper2: Noop ,c1; L0 ← L0.vswap ,c2; CALL[memSwap] ,c3; vswap: rB ← rB + 1 ,c1, RtnBLT[L0.vswap]; {make pages vacant} rC ← rC - 1, ZeroBr ,c2; rE ← rE + 1, BRANCH[looper2, vswapdone] ,c3; vswapdone: Noop ,c1; { swaps two locations in memory, takes address in rE and rB, clobbers acR & rD } memSwap2: Noop ,c2; memSwap3: Noop ,c3; memSwap: MAR← [rErh, rE+0] ,c1; Noop ,c2; acR← MD ,c3; MAR← [rBrh, rB+0] ,c1; Noop ,c2; rD← MD ,c3; MAR← [rBrh, rB+0] ,c1; MDR← acR ,c2; Noop ,c3; MAR← [rErh, rE+0] ,c1; MDR← rD, pRet0 ,c2; RET[subrRet] ,c3; {the end...}