{LispMiscDayBreak.mc, Last changed by Lichtenberg, 20-Jun-85 15:24:29

	Converted to Lisp  by MPL, 20-Jun-85 15:24:29

	Based on MiscDicentra by HGM, November 1983

DayBreak specific portion of Misc.mc }

{ 	Copyright (C) 1984, 1985 by Xerox Corporation.  All rights reserved.}

{timer addresses and commands}

Set[T1Count, 41];
Set[T2Count, 42];
Set[T012Control, 43]; {** This SET is also in dbMoreLisp.mc **}
Set[T12Latch, 0DC];


{  The following opcodes are defined here:

	DOVEMISC 0     Read input word    Stk effect  0
	DOVEMISC 1     Write output word  Stk effect -1
	DOVEMISC 2     Write MP Code      Stk effect  0
	DOVEMISC 3     Read Timer*        Stk effect  0
	DOVEMISC 4     Byte Swap TOS      Stk effect  0
	DOVEMISC 5     LOCKMEM            Stk effect -3
	DOVEMISC 6     NOTIFYIOP          Stk effect  0
	DOVEMISC 7     SetWakeupBits      Stk effect  0

}




@DOVEMISC: Rio ← TOS,   opcode[71'b], c1;
	rhRio ← Rio LRot0, c2;
	Rio ← TOS, c3;
	, c1;
	Xbus ← ib,  XDisp, c2;
	DISP4[DoveMiscs], c3;
	
DoveMiscOut: PC ← PC + 1, GOTO[IB.nop], c1, at[L3.WriteMP, 10, DoveMiscOut];



{*****************************************************************************
	INPUT	Input
*****************************************************************************}


	IO ← [rhRio, Rio+0], 			c1, at[0,10,DoveMiscs];
	TOSH ← 0, c2;
	TOS ← MD, GOTO[DoveMiscOut], c3;


{*****************************************************************************
	OUTPUT	Output
*****************************************************************************}


	MAR ← [rhS, S + 0], c1, at[1,10,DoveMiscs];
	S ← S - 2, c2;
	TT ← MD, c3;
	
	IO ← [rhRio, Rio+0], c1;
	MDR ← TT, c2;
	GOTO[DoveMiscOut], c3;


{*****************************************************************************
	 Write maintenance panel
*****************************************************************************}


@WRITEMP:	TT ← uMaintPanel,L3 ← L3.WriteMP, {maint panel code}	c1, at[2,10,DoveMiscs];
WriteMPEntry:
	rhTT ← uIORgnHigh, TT ← rIORgn + TT,			c2;
	TOS ← TOS LRot8, {must byteswap}			c3;

	MAR ← [rhTT, TT + 0],					c1;
	MDR ← TOS,						c2;
	TT ← TT + 1, {maint panel down-notify mask}		c3;

	MAR ← [rhTT, TT + 0],					c1;
	Noop,							c2;
	TOS ← MD, 						c3;

 {TOS contains notify mask}
	MAR ← [rhIOP, rIOP + 0], SetLOCK,			c1;
	SetMPIntIOP,						c2;
	TOS ← TOS or MD, ClrLOCK,				c3;

	MAR ← [rhIOP, rIOP + 0], ClrMPIntIOP,			c1;
	MDR ← TOS, L3Disp,					c2;
	RET[DoveMiscOut], c3;



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

{Read Interval timer}
@RRIT:	rhRio ← T012Control,		c1, at[3,10,DoveMiscs];
	Rx ← 0, 			c2;
	L3 ← L3.RRIT,		c3;

{ The two halves of the counter are synchronized by a latch command given to the 8254 control register.  The counts are correct and synchronized to the command, not to when the counters are read. }
  
ReadTimer:
	IO ← [rhRio, 0], {Control Register}			c1;
	MDR ← T12Latch, {Latching the counts}			c2;
	rhRio ← T2Count,					c3;

{ read timer two, higher 16 bits }

	IO ← [rhRio, 0], {Cnt 2 LSB}				c1;
	TT ← 0FF,						c2;
	Q ← MD and TT, {mask high byte}				c3;

	IO ← [rhRio, 0], {Cnt 2 MSB}				c1;
	rhRio ← T1Count,					c2;
	TOS ← MD and TT, {mask high byte}			c3;

{ read timer one, lower 16 bits, and finish higher (interlaced instructions)}

	IO ← [rhRio, 0], {Cnt 1 LSB}				c1;
	TOS ← TOS LRot8 or Q, {combine timer 2 bytes}		c2;
	Q ← MD and TT, {mask high byte}				c3;

	IO ← [rhRio, 0], {Cnt 1 MSB}				c1;
	TOS ← 0 - TOS, {down count},				c2;
	TT ← MD and TT, {mask high byte}				c3;

	TT ← TT LRot8 or Q, {combine timer 1 bytes}		c1;
	TT ← 1 - TT, {down count, carries at 1}			c2;
	Ybus ← TT or Rx, NZeroBr, {timing glitch when TT is 0}	c3;

	uClockBits ← 0, BRANCH[$,RITOut], 			c1;
	Rx ← 1, {need only one repeat}				c2;
	rhRio ← T012Control, GOTO[ReadTimer],			c3;
	

RITOut: uClockLow ← TT,L3Disp, c2;
	uClockHigh ← TOS,  RET[DoveMiscOut], c3;
	

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

@BYTESWAP:
	TOS ← TOS LRot8, c1, at[4,10,DoveMiscs];
	L2←L2.0,  c2;
	TOSH ← smallpl, GOTO[DoveMiscOut], c3;


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

{@LOCKMEM: [operation, offset, value, mask] RETURNS [result]}
{ignore mask, since we have hardware lock}
{T is loaded with value for operation}
{TT is loaded with offset into IORegion, whose base address is in [uIORgnHigh, rIORgn]}
{lower three bits of operation used for dispatch}
Set[lock.add,08];
Set[lock.and,09];
Set[lock.or,0A];
Set[lock.xchg,0B];
Set[lock.wrIfNil,0C];

{ Lisp calling params:

		TOS --> Operation 
		TOS-1 --> Offset
		TOS-2 --> Value
		TOS-3 --> Mask
		
 }

@LOCKMEM:

	MAR ← [rhS, S + 0], c1, at[5,10,DoveMiscs];
	S ← S - 2, c2;
	TT ← MD, c3;   {TT = Offset}

	MAR ← [rhS, S + 0], c1;
	S ← S - 2, c2;
	Rx ← MD, c3;   {Rx = Value}
	
	MAR ← [rhS, S + 0], c1;
	stackP ← 0, c2;
	TOSH ← MD, c3;   {TOSH = Mask}

	S ← S - 2, c1;
	STK ← TOS, c2;
	rhTT ← uIORgnHigh, TT ← rIORgn + TT, {assume no carry}	c3;

	MAR ← [rhTT, TT + 0], SetLOCK, Xbus ← STK {operation}, XDisp,	c1;
	DISP4[LockMemOp,08],				c2;
LockAdd:
	TOS ← MD, ClrLOCK,					c3, at[lock.add,10,LockMemOp];

	MAR ← [rhTT, TT + 0],					c1;
	MDR ← TOS ← Rx + TOS, GOTO[LockMemOut], c2;

LockAnd:
	Rx ← Rx and MD, ClrLOCK, GOTO[LockMemStore],		c3, at[lock.and,10,LockMemOp];
LockOr:
	Rx ← Rx or MD, ClrLOCK, GOTO[LockMemStore],		c3, at[lock.or,10,LockMemOp];

LockMemStore:
	MAR ← [rhTT, TT + 0],					c1;
LockMemStore2:
	  MDR ←  Rx, GOTO[LockMemOut],	c2;

LockXChg:
	TOS ← MD, ClrLOCK,					c3, at[lock.xchg,10,LockMemOp];

	MAR ← [rhTT, TT + 0],					c1;
	MDR ← Rx, GOTO[LockMemOut],	c2;

LockWrIfNil:
	TOS ← MD,						c3, at[lock.wrIfNil,10,LockMemOp];

	Noop, {necessary because of timing constraints}		c1;
	Noop, {ditto}						c2;
	Ybus ← TOS, ZeroBr, ClrLOCK,				c3;

	MAR ← [rhTT, TT + 0], BRANCH[$,LockMemStore2],		c1;
	MDR ← TOS {must write to clear lock}, GOTO[LockMemOut],	c2;
	
LockMemOut:  TOSH ← smallpl, GOTO[DoveMiscOut], c3;


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

@NOTIFYIOP: {TOS contains notify mask}
	MAR ← [rhIOP, rIOP + 0], SetLOCK,			c1, at[6,10,DoveMiscs];
	SetMPIntIOP,						c2;
	TOS ← TOS or MD, ClrLOCK,				c3;

	MAR ← [rhIOP, rIOP + 0], ClrMPIntIOP,			c1;
	MDR ← TOS,						c2;
	GOTO[DoveMiscOut], c3;

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

@SetWakeupBits:
	TT ← uWP,  MesaIntRq,				c1, at[07,10,DoveMiscs];
	TT ← TT or TOS,						c2;
	uWP ← TT,  GOTO[DoveMiscOut], 		c3;


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