{MemScan.mc, HGM,  3-Apr-85 20:44:50}

	Reserve[0F5F, 0FFF]; {section used by the CP Kernel }
	SetTask[0]; StartAddress[Go];

RegDef[address, R, 1];  {Word within bank}
  RegDef[rhAddr, RH, 1];
RegDef[addres2, R, 2];
  RegDef[rhAdr2, RH, 2];
  
RegDef[found, R, 4];

RegDef[toAddr, R, 5];
RegDef[toAddrHi, RH, 5];

RegDef[errorCount, R, 6];
RegDef[temp, R, 7];

RegDef[lastBank, R, 0A]; {Must be power of 2}

RegDef[reason, U, 20]; {0 => error, 1 => done}

RegDef[toData, U, 40];
RegDef[toCommand, U, 41];


Set[Setup0, 0];
Set[Setup1, 1];
Set[Setup2, 2];
Set[Setup3, 3];
Set[Setup4, 4];
Set[Setup5, 5];
Set[Setup6, 6];
Set[Setup7, 7];
Set[Setup8, 8];
Set[Setup9, 9];
Set[SetupA, 0A];
Set[SetupB, 0B];
Set[SetupC, 0C];
Set[SetupD, 0D];

Set[Fetch0, 0];
Set[Fetch1, 1];
Set[Fetch2, 2];
Set[Fetch3, 3];
Set[Fetch4, 4];
Set[Fetch5, 5];

Set[Info0, 0];
Set[Info1, 1];

Trap:	temp ← RRot1 ErrnIBnStkp, ClrIntErr, CANCELBR[$, 0F],	c1, at[0];
	Xbus ← temp LRot0, XwdDisp,				c2;
	DISP2[TrapType],					c3;
	
Parity:	GOTO[GoToGo],						c1, at[0,4,TrapType];
Init:	GOTO[GoToGo],						c1, at[1,4,TrapType];
Stack:	GOTO[GoToGo],						c1, at[2,4,TrapType];
IB:	GOTO[GoToGo],						c1, at[3,4,TrapType];

GoToGo:
	Noop,							c2;
	Noop, GOTO[Go],						c3;

Go:	rhAddr ← 0,						c1;
	Noop,							c2;
	Noop,							c3;

{Setup Misc Board to Interrupt on XACK Timeout}
	rhAdr2 ← 4, {Misc CIO Chip}				c1;
	addres2 ← 090,						c2;
	addres2 ← addres2 LRot8, {9000}				c3;

	temp  ← addres2 + 0, L0 ← Setup0, {Master Control}	c1;
	Q ← 1, CALL[Setup], {Reset}				c2;
	Noop,							c3, at[Setup0, 10, SetupRet];

	temp  ← addres2 + 0, L0 ← Setup1, {Master Control}	c1;
	Q ← 00, CALL[Setup], {Clear Reset}			c2;
	Noop,							c3, at[Setup1, 10, SetupRet];

	temp  ← addres2 + 0, L0 ← Setup2, {Master Control}	c1;
	Q ← 080, CALL[Setup], {MIE}				c2;
	Noop,							c3, at[Setup2, 10, SetupRet];

	temp  ← addres2 + 20, L0 ← Setup3, {Port A Mode}		c1;
	Q ← 0, CALL[Setup], {Bit Port}				c2;
	Noop,							c3, at[Setup3, 10, SetupRet];

	temp  ← addres2 + 23, L0 ← Setup5, {Port A Direction}	c1;
	Q ← 0FF, CALL[Setup], {All Bits Input}			c2;
	Noop,							c3, at[Setup5, 10, SetupRet];

	temp  ← addres2 + 0E, L0 ← Setup6, {Port B Data}		c1;
	Q ← 0F, CALL[Setup], {Disable all outputs}		c2;
	Noop,							c3, at[Setup6, 10, SetupRet];

	temp  ← addres2 + 2B, L0 ← Setup7, {Port B Direction}	c1;
	Q ← 0F0, CALL[Setup], {Output on low 4 bits}		c2;
	Noop,							c3, at[Setup7, 10, SetupRet];

	temp  ← addres2 + 1, L0 ← Setup8, {Master Config Control}	c1;
	Q ← 084, CALL[Setup], {Enable Ports A+B}		c2;
	Noop,							c3, at[Setup8, 10, SetupRet];

	temp  ← addres2 + 2C, L0 ← Setup9, {Port B Special IO}	c1;
	Q ← 40, CALL[Setup], {ONEs Catcher for TOXack}		c2;
	Noop,							c3, at[Setup9, 10, SetupRet];

	temp  ← addres2 + 2D, L0 ← SetupA, {Port B Polarity}	c1;
	Q ← 40, CALL[Setup],					c2;
	Noop,							c3, at[SetupA, 10, SetupRet];

	temp  ← addres2 + 2F, L0 ← SetupB, {Port B Mask}		c1;
	Q ← 40, CALL[Setup],					c2;
	Noop,							c3, at[SetupB, 10, SetupRet];

	temp  ← addres2 + 09, L0 ← SetupC, {Port B Command}	c1;
	Q ← 0C0, CALL[Setup], {Set Interrupt Enable}		c2;
	Noop,							c3, at[SetupC, 10, SetupRet];

	temp  ← addres2 + 28, L0 ← Setup4, {Port B Mode}		c1;
	Q ← 4, CALL[Setup], {Bit Port, OR Matcher}		c2;
	Noop,							c3, at[Setup4, 10, SetupRet];

	ExtCtrl ← 5, {Init Incr, Zero, UnBlank}			c1;
	ClrIntErr,						c2;
	GOTO[MainLoop],						c3;

	
{------------------------------------------------------------------------------------}
MainLoop:
	rhAddr ← 0, address ← 0,				c1;
	Noop,							c2;
PreReadLoop:
	Noop,							c3;
	
ReadLoop:
	MAR ← [rhAddr, address + 0], RawRef,			c1;
	Noop,							c2;
	found ← MD,						c3;
	
{Wait long enough for an Interrupt to strike.}
	Noop, c1; Noop, c2; Noop, c3;
	Noop, c1; Noop, c2; Noop, c3;
	Noop, c1; Noop, c2; Noop, c3;
	Noop, c1; Noop, c2; Noop, c3;

	Noop,							c1;
	MesaIntBr,						c2;
	BRANCH[$, MesaIntRead],					c3;
	
	Noop,							c1;
	address ← address + 1, CarryBr,				c2;
	BRANCH[ReadLoop, $],					c3;
	
NextBank:
	Noop,							c1;
	Q ← rhAddr + 1,						c2, LOOPHOLE[niblTiming];
	rhAddr ← Q LRot0,					c3;

	[] ← lastBank - Q, NegBr,				c1;
	Q ← 1, BRANCH[PreReadLoop, $],				c2;
	reason ← Q,						c3;

Done:	ExtCtrl ← 3, {Gets Bumped on rising edge} 		c1;
	ExtCtrl ← 7, 						c2;
	GOTO[MainLoop],						c3;

{------------------------------------------------------------------------------------}


MesaIntRead:
	reason ← 0,						c1;
	L1 ← Info1,						c2;
	CALL[Info],						c3;
	
	Q ← errorCount,						c1, at[Info1, 10, InfoRet];
	Q ← Q + 1,						c2;
	errorCount ← Q,						c3;

MesaIntIsProbablyAParityError:
	Noop,							c1;
	Noop,							c2;
	GOTO[Go],						c3;
	
FixThisWord:
	MAR ← [rhAddr, address + 0], RawRef,			c1;
	MDR ← found,						c2;
	Noop,							c3;

Fixed:	Noop,							c1;
	Noop,							c2;
	GOTO[Go],						c3;
{------------------------------------------------------------------------------------}

Info:
	rhAdr2 ← 4, {Misc CIO Chip}				c1;
	addres2 ← 090,						c2;
	addres2 ← addres2 LRot8, {9000}				c3;

	Q ← 05, L0 ← Fetch0, {RdTODatL}				c1;
	CALL[Fetch],						c2;
	toData ← temp,						c3, at[Fetch0, 10, FetchRet];

	Q ← 04, L0 ← Fetch1, {RdTODatH}				c1;
	CALL[Fetch],						c2;
	temp ← temp LRot8,						c3, at[Fetch1, 10, FetchRet];

	Q ← toData,						c1;
	temp ← temp or Q,						c2;
	toData ← temp,						c3;

	Q ← 03, L0 ← Fetch2, {RdTOCmd}				c1;
	CALL[Fetch],						c2;
	toCommand ← temp,						c3, at[Fetch2, 10, FetchRet];

	Q ← 00, L0 ← Fetch3, {RdTOAdrH}				c1;
	CALL[Fetch],						c2;
	toAddrHi ← temp LRot0,					c3, at[Fetch3, 10, FetchRet];

	Q ← 02, L0 ← Fetch4, {RdTOAdrL}				c1;
	CALL[Fetch],						c2;
	toAddr ← temp,						c3, at[Fetch4, 10, FetchRet];

	Q ← 01, L0 ← Fetch5, {RdTOAdrM}				c1;
	CALL[Fetch],						c2;
	temp ← temp LRot8,						c3, at[Fetch5, 10, FetchRet];

	Q ← toAddr,						c1;
	Q ← Q or temp, L1Disp,					c2;
	toAddr ← Q, DISP4[InfoRet],				c3;
	
{------------------------------------------------------------------------------------}

Setup:
	Noop,							c3;

	IO ← [rhAdr2, temp + 0], L0Disp,				c1;
	MDR ← Q, DISP4[SetupRet],				c2;

{------------------------------------------------------------------------------------}

Fetch:
	Noop,							c3;

	IO ← [rhAdr2, addres2 + 0E], {Port B Data}		c1;
	MDR ← Q + 8,						c2;
	Noop,							c3;

	IO ← [rhAdr2, addres2 + 0D], {Port A Data}		c1;
	Noop,							c2;
	temp ← MD,						c3;

	L0Disp,							c1;
	DISP4[FetchRet],					c2;

{------------------------------------------------------------------------------------}