% File: MemInit.mc

Edit by Jim Frandeen March 5, 1980 11:16 AM Delete Includes for Integration Procedure
Edit by Johnsson February 3, 1980 2:00 PM
%

TITLE[MemInit];

OnPage[InitialPage];
SETTASK[0];

RV[xmad0,22]; *base register
RV[xmad1,23];
RV[xmbuf0,24]; *quadword buffer for XMap and PFetch4
RV[rbuf0,24];
RV[xmbuf1,25];
RV[rbuf1,25];
RV[xmbuf2,26];
RV[rbuf2,26];
RV[xmbuf3,27];
RV[rbuf3,27];
RV[wbuf0,30]; *quadword buffer for PStore4
RV[wbuf1,31];
RV[wbuf2,32];
RV[wbuf3,33];
RV[rlink0,34]; *subroutine return link
RV[MapEntry,35]; *current map location
RV[ZPage,35]; *page being cleared
RV[RealPage,36]; *current real storage page
RV[ZWord,36];
RV[PageCount,37]; *count of available real pages in system
RV[CompFlag,40];


*Failure codes
MC[NotEnoughMemory,275];
MC[BadMap,276];

IMAP:
CompFlag ← (zero)-1,goto[imCompx];
imAloop:
T ← (CompFlag) xor (T);
xmbuf0 ← T, call[imWriteMap];
T ← MapEntry;
T ← (CompFlag) xor (T), call[imReadMap];
MapEntry ← T ← (MapEntry) + 1;
goto[imAloop,nocarry];
MapEntry ← 140000C;
imRloop:
T ← MapEntry;
T ← (CompFlag) xor (T), call[imReadMap];
MapEntry ← T ← (MapEntry) + 1;
lu ← CompFlag, goto[imRloop,nocarry];
goto[.+2,ALU=0], CompFlag ← (zero);
imCompx:
goto[imAloop], MapEntry ← T ← 140000C;


RealPage ← (10000C); *max real page +1
MapEntry ← 140000C; *carries beyond max VM cause ALUCY
PageCount ← 0C;
rlink0 ← FFaultAdd; *location in fault handler
stkp ← rlink0;

*fill first quadword of each real page with its page number and some constants.
*go through real memory backwards so that hole in 96k modules will not
*screw up non-hole banks.

wbuf1 ← 326C; *random constant
wbuf2 ← 134000C;
wbuf3 ← (zero) ;
imFloop:
RealPage ← T ← (RealPage)-1;
xmbuf0 ← T, goto[.+2,ALU>=0];
T ← RealPage ← 170000C, goto[imTloop];
wbuf0 ← T;
call[imWriteMap];
PStore4[xmad0,wbuf0,0], goto[imFloop];

*during this phase, we sweep upward through real storage and the map, and
*use any real pages discovered.

imTloop:
xmbuf0 ← T;
xmbuf0 ← (xmbuf0) and not (70000C), call[imWriteMap]; *set base reg to point to MapEntry,
*set MapEntry to point to RealPage. Set all map flags off.
nop;
call[.+2], stack ← (Stack) or (100000c);*turn on fault handler
imFault:
goto[imPageBad], stack ← (Stack) and not (100000c); *get here on a fault - turn off fault handler
PFetch4[xmad0,rbuf0,0]; *fetch. Will cause fault if page is bad
T ← rbuf0;
lu ← (ldf[RealPage,4,14]) xor (T);
goto[.+2, ALU = 0], stack ← (Stack) and not (100000c);*turn off fault handler
goto[imPageBad]; *page number didn’t compare
T ← (rbuf1) xor (326C); *a final check against constants
rbuf2 ← (rbuf2) xor (134000C);
T ← (rbuf2) or (T);
T ← (rbuf3) or (T);
dblgoto[imPageGood, imPageBad, ALU=0];

imPageGood:
MapEntry ← (MapEntry) + 1;
PageCount ← (PageCount) + 1;
imPageBad: T ← RealPage ← (RealPage) + 1;
goto[imTloop, nocarry]; *done with all of real memory?
wbuf1 ← 0C; *clear wbuf1 in preparation for core zap.
imMarkVacant:
xmbuf0 ← 60000C; *page vacant
Call[imWriteMap];
MapEntry ← (MapEntry) + 1;
T ← PageCount, goto[imMarkVacant, nocarry]; *done with all map entries?

imCoreZap:
wbuf3 ← 0C;
wbuf2 ← 0c;
Zpage ← T;

imZapLoop:
ZPage ← (ZPage) -1;
T ← lhmask[ZPage], goto[imDone, ALU<0];
xmad1 ← T; *set up a base register for the page
T ← lsh[Zpage,10];
xmad0 ← T;
ZWord ← 400C, call[imZPloop];

imZPloop:
Zword ← T ← (Zword) - (4C);
goto[imZapLoop, ALU<0];
PStore4[xmad0, wbuf0], return;

imDone:
lu ← (PageCount) -(400c); *don’t try to run with less than 64K
T ← NotEnoughMemory, goto[InitFail, ALU<0];
goto[MemInitDone];


*SUBROUTINE imWriteMap writes the data in xmbuf0
*into map location MapEntry
imWriteMap:
T ← (MapEntry) and not (140000C);
xmad1 ← T;
xmad1 ← (xmad1) and not (377C);
T ← lsh[MapEntry,10];
xmad0 ← T;
Xmap[xmad0,xmbuf0,0];
xmbuf0 ← xmbuf0, return; *interlock

*SUBROUTINE imReadMap reads one entry from MapEntry
*into rbuf0, then compares it with (MapEntry xor CompFlag)
imReadMap:
xmbuf0 ← T, usectask;
T ← apc&apctask;
rlink0 ← T, call[imWriteMap];
T ← lsh[xmbuf3, 10]; *flags, card, blk.0 bits
rbuf0 ← T;
T ← (xmbuf1) and (377C);
rbuf0 ← (rbuf0) xor (T);
T ← MapEntry;
T ← (CompFlag) xor (T);
lu ← (rbuf0) xnor (T); *note, Map data is complemented, so we xnor
goto[imGoodEntry, ALU=0];
imBadMap:
T ← BadMap, goto[InitFail]; *Some map entry was bad

imGoodEntry:
apc&apctask ← rlink0;
return;

:END[MemInit];