{MiscDicentra.mc, HGM, 18-Feb-84 23:31:10

Dicentra specific portion of Misc.mc, HGM, 13-Oct-82 20:52:53}


{*****************************************************************************
	INPUT, OUTPUT, and variants, L2 setup in Misc.mc
*****************************************************************************}

@INPUT:	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[00,10,ESC8n];
	IO ← [rhRio, Rio+0], push, GOTO[Ra],			c1, at[00,10,IOSetupRet];

@INPUTEVEN:
	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[0C,10,ESC8n];
	IO ← [rhRio, Rio+0], push, BHEN, GOTO[Ra],		c1, at[0C,10,IOSetupRet];

@INPUTODD:
	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[0E,10,ESC8n];
	IO ← [rhRio, Rio+0], push, BHEN, ADR0, GOTO[Ra],	c1, at[0E,10,IOSetupRet];

@OUTPUT:
	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[01,10,ESC8n];
	IO ← [rhRio, Rio+0], GOTO[Wb],				c1, at[01,10,IOSetupRet];

@OUTPUTEVEN:
	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[0D,10,ESC8n];
	IO ← [rhRio, Rio+0], BHEN, GOTO[Wb],			c1, at[0D,10,IOSetupRet];

@OUTPUTODD:
	rhRio ← TOS LRot0, CALL[IOSetup],			c1, at[0F,10,ESC8n];
	IO ← [rhRio, Rio+0], BHEN, ADR0, GOTO[Wb],		c1, at[0F,10,IOSetupRet];


IOSetup:
	Rio ← STK, pop, L2Disp,					c2;
	T ← STK, pop, DISP4[IOSetupRet],			c3;

{*****************************************************************************
	WR - Write Registers
*****************************************************************************}

{YETCH.  Pilot wants to smash the clock.}
@WRIT:	pop,							c1, at[5,10,ESC7n];
	IBDisp, GOTO[SLa],					c2;


{Write maintaince panel}
@WRMP:	uMP ← TOS, L0 ← 0E,					c1, at[7,10,ESC7n];
	T ← TOS + 1, CALL[PNIP],				c2;

	TOS ← STK, pop, IBDisp, GOTO[DISPNIonly],		c2, at[0E, 10, PNIPRet];


{*****************************************************************************
	RR - Read Registers
*****************************************************************************}

{Read Interval timer}
@RRIT:	Rio ← u9000,						c1, at[0D,10,ESC7n];
	rhRio ← 4, push, {Misc CIO}				c2;
	push,							c3;

{Yetch.  There is no way to synchronize the 2 halves of the clock.  Thus:
  1) Read high bits, 2) Read low bits, 3) Read high bits again.
  If the high bits changed, try again.}
  
ReadClockAgain:
	IO ← [rhRio, Rio + 0B], {Counter 2 Cntrl}		c1;
	MDR ← 0C, {RCC and GCB}					c2;
	Q ← Rio + 10,						c3;

	IO ← [rhRio, Q + 02], {Cnt 2 MSB}			c1;
	Noop,							c2;
	TOS ← MD,						c3;

	IO ← [rhRio, Q + 03], {Cnt 2 LSB}			c1;
	TOS ← TOS LRot8,					c2;
	TOS ← TOS or MD,					c3;

	IO ← [rhRio, Rio + 0A], {Counter 1 Cntrl}		c1;
	MDR ← 0C, {RCC and GCB}					c2;
	TOS ← ~TOS,						c3;

	IO ← [rhRio, Q + 00], {Cnt 1 MSB}			c1;
	Noop,							c2;
	T ← MD,							c3;

	IO ← [rhRio, Q + 01], {Cnt 1 LSB}			c1;
	T ← T LRot8,						c2;
	T ← T or MD,						c3;

	IO ← [rhRio, Rio + 0B], {Counter 2 Cntrl}		c1;
	MDR ← 0C, {RCC and GCB}					c2;
	STK ← ~T,						c3;

	IO ← [rhRio, Q + 02], {Cnt 2 MSB}			c1;
	Noop,							c2;
	T ← MD,							c3;

	IO ← [rhRio, Q + 03], {Cnt 2 LSB}			c1;
	T ← T LRot8,						c2;
	T ← T or MD,						c3;

	T ← ~T,							c1;
	[] ← TOS xor T, ZeroBr,					c2;
	BRANCH[ReadClockAgain, ClockOK],			c3;
	
ClockOK:
	GOTO[RRx], {in Misc.mc}					c1;
	

{-------------------------------------------------------------------------
	Dicentra Specific Additions
-------------------------------------------------------------------------}

@RawRead:
	rhRio ← TOS LRot0,					c1, at[04,10,ESC8n];
	Rio ← STK, pop,						c2;
	pop,							c3;

	MAR ← [rhRio, Rio+0], push, RawRef, GOTO[Ra], {In Read}	c1;

@RawWrite:
	rhRio ← TOS LRot0,					c1, at[05,10,ESC8n];
	Rio ← STK, pop,						c2;
	T ← STK, pop,						c3;

	MAR ← [rhRio, Rio+0], RawRef, GOTO[Wb],			c1;

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

@GetExternalStatus:
	T ← ExtStat, push,					c1, at[06,10,ESC8n];
	STK ← TOS, IBDisp, GOTO[PushT] {In LoadStore}		c2;
	
@SetExtCtrl:
	ExtCtrl ← TOS, push,					c1, at[07,10,ESC8n];
	STK ← TOS, pop,	IBDisp, GOTO[SLa], {In LoadStore}	c2;

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

@SetWakeupMask: {TOS has INT level, TOS-1 has mask}
	T ← TOS or 8,						c1, at[08,10,ESC8n];
	TT ← STK, pop,						c2;
	TOS ← STK, pop,						c3;

	Ybus ← T, AltUaddr,					c1;
	uInterruptMasks ← TT, IBDisp, GOTO[DISPNIonly],		c2;
	
{-------------------------------------------------------------------------}

@SetNxmExpected:
{TOS is BOOLEAN.  0 => Crash on NXM.  See MiscInterrupt in InterruptsDicentra.mc}
	Q ← TOS, push,						c1, at[09,10,ESC8n];
	uNxmExpected ← Q,					c2;
	STK ← TOS, pop,						c3;
	
	TOS ← STK, pop, GOTO[IBDispOnly],			c1;


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

@SetWakeupBits:
	T ← TOS, push, MesaIntRq,				c1, at[0A,10,ESC8n];
	STK ← TOS, pop,						c2;
	TOS ← STK, pop,						c3;

	T ← T or uWP,						c1;
	uWP ← T, IBDisp, GOTO[DISPNIonly],			c2;
	

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

@SetPhonelineCSB: {TOS+TOS-1 are LONG POINTER to CSB.  NIL to turn off.}
	tempH ← TOS LRot0,					c1, at[0B,10,ESC8n];
	temp ← STK, pop,					c2;
	TOS ← STK, pop,						c3;

	Map ← Q ← [tempH, temp or tempH],			c1;
	uPhoneFlag ← Q, {NIL => Don't use microcode}		c2;
	CSBh ← CSB ← MD,					c3;

{cycle memory for the side effects of MAR ←}
	MAR ← CSB ← [CSBh, temp + 0],				c1;
	uPhoneCSB ← CSB, IBDisp,				c2;
	uInts ← 0, DISPNI[OpTable], {Check interrupt again}	c3;

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

{Would you believe LoadBank?}

@LOADRAMJ:
	Bank ← TOS,						c1, at[2,10,ESC8n];
	TOS ← STK, pop, GOTOABS[BankSwitchingLoc],		c2;
{The next instruction to be executed will be in the new bank.}
	GOTO[NxtInstc1],					c3, at[BankSwitchingLoc];