{SDLC.mc, HGM,  4-Nov-84  3:01:52}

{Transmitter states.}
Set[TS.readyToSend, 0];
Set[TS.sendLeft, 1];
Set[TS.sendRight, 2];
Set[TS.waitingForEOP, 3];
Set[TS.readyToResend, 4];

{Receiver states.}
Set[RS.readyToRecv, 0];
Set[RS.skipping, 1];
Set[RS.recvLeft, 2];
Set[RS.recvRight, 3];
Set[RS.activeMask, 2]; {on => IOCB valid}

Set[IOCB.next, 0];
Set[IOCB.status, 1];
Set[IOCB.bufferLo, 2];
Set[IOCB.bufferHi, 3];
Set[IOCB.bytes, 4];
Set[IOCB.bytesLeft, 05];

{Scratch area for microcode}
Set[IOCB.fingerLo, 8];
Set[IOCB.fingerHi, 9];
Set[IOCB.mappedLo, 0A];
Set[IOCB.mappedHi, 0B];

Set[CSB.tState, 00];
Set[CSB.tIOCB, 01];
Set[CSB.tIOCBm, 02];
Set[CSB.tIOCBmh, 03];

Set[CSB.rState, 04];
Set[CSB.rIOCB, 05];
Set[CSB.rIOCBm, 06];
Set[CSB.rIOCBmh, 07];

Set[CSB.tUnder, 08];
Set[CSB.rNoBuffer, 0C];
Set[CSB.rAborted, 0D];
Set[CSB.rAbortIdle, 0E];
Set[CSB.rAbortEx, 0F];

Set[Bump.tUnder, 00]; {Odd}
Set[Bump.rNoBuffer, 01];
Set[Bump.rAborted, 02];
Set[Bump.rAbortIdle, 03];



{
We need to leave 6*400+200 ns (2.6 microseconds) between references to the SCC chip.
With a 16mhz Xtal, 6 clicks takes 2.25 microseconds and 7 clicks takes 2.6 microseconds.
Memory reads will take a bit longer.}

PhoneInterrupt: {SCCH+SCC ← [0,1000] before we get here}
	IO ← [SCCh, SCC+00], {Int Ack}			c1;
{0}	Q ← uPhoneCSB,					c2;
	temp ← MD,					c3;
	
	SCC ← LShift1 temp and ~07,			c1;
{1}	CSB ← SCC + Q,					c2;
	CSB ← CSB xor 10,				c3;

	Q ← SCC and 010,				c1;
{2}	SCCh ← temp LRot12, Ybus ← temp, YDisp,		c2;
	SCC ← Q or u9000, DISP4[SCCDisp, 9],		c3;
	

{Request to send next data byte}
TxTranByte:
	MAR ← [CSBh, CSB + CSB.tState],			c1, at[09, 10, SCCDisp];
{3}	Noop, CANCELBR[$, 0],				c2;
	state ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.tIOCBm],			c1;
{4}	Noop, CANCELBR[$, 0],				c2;
	IOCB ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.tIOCBmh],		c1;
{5}	Ybus ← state, CANCELBR[$, 0], YDisp,		c2;
	IOCBh ← MD, DISP3[TranData],			c3;


{Start sending new frame}
TxStart:
	IO ← [SCCh, SCC+00], {WR0}			c1, at[TS.readyToResend, 8, TranData];
{0}	MDR ← 080, {Reset Tx CRC}			c2;
	Noop,						c3;
	
	MAR ← [CSBh, CSB + CSB.tIOCB],			c1, at[TS.readyToSend, 8, TranData];
{1}	tempH ← 0, CANCELBR[$, 0],			c2;
	temp ← MD,					c3;

	Map ← [tempH, temp],				c1;
{2}	Q ← temp, ZeroBr,				c2;
	IOCBh ← IOCB ← MD, BRANCH[$, TxNothingToSend],	c3;

{cycle memory for the side effects of MAR ←}
	MAR ← IOCB ← [IOCBh, temp + 0],			c1;
{3}	Noop,						c2;
	Noop,						c3;

	MAR ← [CSBh, CSB + CSB.tIOCBm],			c1;
{4}	MDR ← IOCB, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [CSBh, CSB + CSB.tIOCBmh],		c1;
{5}	MDR ← IOCBh, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	IO ← [SCCh, SCC+0A], {WR10}			c1;
{0}	MDR ← 084, {CRC←1, Abort on Underrun} 		c2;
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bufferHi],		c1;
{1}	Noop, CANCELBR[$, 0],				c2;
	tempH ← temp ← MD,				c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
{2}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bufferLo],		c1;
{3}	Noop, CANCELBR[$, 0],				c2;
	temp ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
{4}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	Map ← [tempH, temp],				c1;
{5}	Q ← temp, CANCELBR[$, 0],			c2;
	BufferH ← Buffer ← MD,				c3;

{cycle memory for the side effects of MAR ←}
	MAR ← Buffer ← [BufferH, temp + 0],		c1;
{6}	Noop,						c2;
	Noop,						c3;

TxStarting:
	IO ← [SCCh, SCC+00], {WR0}			c1;
{0}	MDR ← 0C0, {Reset EOM}				c2;
	Noop,						c3;
	
	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
{1}	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{2}	MDR ← Buffer, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bytes],		c1;
{3}	[] ← state, NegBr, CANCELBR[$, 0], {Flag from TxSent} c2;
	count ← MD, BRANCH[$, TxSendLeftByte],		c3;

{This is the first-on-the-chain path.  The driver has already sent the first byte.}
	Noop,						c1;
{4}	Noop,						c2;
	count ← count - 1, GOTO[TxSendRightByte], 	c3;

TxLeftByte:
	IO ← [SCCh, SCC+00], {RR0} L4 ← 01,		c1, at[TS.sendLeft, 8, TranData];
{0-3}	CALL[TxBufferSetup],				c2;

TxSendLeftByte:
	MAR ← [BufferH, Buffer + 0],			c1, at[01, 04, TxBufferRet];
{4}	state ← TS.sendRight,				c2;
	temp ← MD,					c3;
	
	temp ← temp LRot8,				c1;
{5}	count ← count - 1, NegBr,			c2;
	BRANCH[TxSendByte, TxEnd],			c3;


TxRightByte:
	IO ← [SCCh, SCC+00], {RR0} L4 ← 02,		c1, at[TS.sendRight, 8, TranData];
{0-3}	CALL[TxBufferSetup],				c2;
	
TxSendRightByte:
	MAR ← [BufferH, Buffer], Buffer ← Buffer + 1,	c1, at[02, 04, TxBufferRet];
{4}	state ← TS.sendLeft, BRANCH[$, TxNewPage, 1],	c2;
	temp ← MD, GOTO[TxSaveBuffer],			c3;
	
TxNewPage:
	temp ← MD,					c3;
	
	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
	Q ← 0FF + 1, CANCELBR[$, 0],			c2;
	Buffer ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
	Buffer ← Buffer + Q, CarryBr, CANCELBR[$, 0],	c2;
	BufferH ← MD, BRANCH[TxNoBankCross, $],	c3;

TxNewBank:
	Q ← BufferH,					c1;
	Q ← Q + 1,					c2;
	BufferH ← Q LRot0,				c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

TxNoBankCross:
	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
	MDR ← Buffer, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	Map ← [BufferH, Buffer],			c1;
	Noop,						c2;
	BufferH ← Buffer ← MD,				c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Buffer ← Buffer and ~0FF,			c3;

TxSaveBuffer:
	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{5}	MDR ← Buffer, count ← count - 1, NegBr, CANCELBR[$, 0],	c2, LOOPHOLE[wok];
	BRANCH[TxSendByte, TxEnd],			c3;

TxSendByte:
	IO ← [SCCh, SCC+08], {WR8}			c1;
{0}	MDR ← temp, {Transmit Data}			c2;
	Noop,						c3;

TxSaveCountAndState:
	MAR ← [IOCBh, IOCB + IOCB.bytesLeft],		c1;
{1}	MDR ← count, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

TxSaveState:
	MAR ← [CSBh, CSB + CSB.tState],			c1;
{2}	MDR ← state, CANCELBR[PreAckInt, 0],		c2, LOOPHOLE[wok];



{Finish sending frame}
{It could underrun right now.  ????}
TxEnd:	IO ← [SCCh, SCC+0A], {WR10}			c1;
{0}	MDR ← 080, {Send CRC}				c2;
	Noop,						c3;
	
	IO ← [SCCh, SCC+00], {WR0}			c1;
{0}	MDR ← 028, {Reset Tx Int}			c2;
	state ← TS.waitingForEOP, GOTO[TxSaveState],	c3;


{Extra interrupt after packet has been sent.}
TxSent:	MAR ← [IOCBh, IOCB + IOCB.status],		c1, at[TS.waitingForEOP, 8, TranData];
{7}	MDR ← state ← state xor ~state, CANCELBR[$, 0],	c2, LOOPHOLE[wok];
	Q ← uWP,					c3;

TxNextBuffer:
	MAR ← [IOCBh, IOCB + IOCB.next],		c1;
{8}	Q ← Q or uIntPhone, CANCELBR[$, 0],		c2;
	temp ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.tIOCB],			c1;
{9}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	uWP ← Q, GOTO[TxStart],				c3;



TxBufferSetup:
	temp ← MD,					c3;
	
	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
{1}	Q ← temp and 040, CANCELBR[$, 0],		c2;
	BufferH ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{2}	[] ← Q, NZeroBr, CANCELBR[$, 0],		c2;
	Buffer ← MD, BRANCH[$, TxUnderrun],		c3;

	MAR ← [IOCBh, IOCB + IOCB.bytesLeft],		c1;
{3}	L4Disp, CANCELBR[$, 0],				c2;
	count ← MD, DISP2[TxBufferRet],			c3;

TxUnderrun:
	MAR ← [IOCBh, IOCB + IOCB.status],		c1;
{2}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	L4 ← Bump.tUnder,				c3;

{3-4}	MAR ← Q ← [CSBh, CSB + CSB.tUnder], CALL[BumpCSB], c1;

	Q ← uWP,					c1, at[Bump.tUnder, 10, BumpRet];
{5}	Q ← Q or uIntPhone,				c2;
	Noop,						c3;

	MAR ← [CSBh, CSB + CSB.tIOCB],			c1;
	MDR ← 0, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	uWP ← Q,					c3;

TxNothingToSend:
	IO ← [SCCh, SCC+00], {WR0}			c1;
{0}	MDR ← 028, {Reset Tx Int}			c2;
	state ← TS.readyToSend, GOTO[TxSaveState],	c3;



ExternalStatusChange:
	MAR ← [CSBh, CSB + CSB.rIOCBm],			c1, at[0B, 10, SCCDisp];
{3}	Noop, CANCELBR[$, 0],				c2;
	IOCB ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rIOCBmh],		c1;
{4}	Noop, CANCELBR[$, 0],				c2;
	IOCBh ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rState],			c1;
{5}	Noop, CANCELBR[$, 0],				c2;
	state ← MD,					c3;

	IO ← [SCCh, SCC+00], {RR0}			c1;
{0}	Noop,						c2;
	temp ← MD,					c3;
	
	IO ← [SCCh, SCC+00], {WR0}			c1;
{0}	MDR ← 010, {Reset Ext/Sts Int}			c2;
	Q ← 80,						c3;
	
	Q ← temp and Q, NZeroBr, {Abort}		c1;
{1}	Q ← CSB + CSB.rAbortEx, BRANCH[$, RxAbortedExt], c2;
	Q ← uInts, GOTO[AckInt],			c3;
	

	
{Grab next character of frame}
RxDataByte:
	MAR ← [CSBh, CSB + CSB.rState],			c1, at[0D, 10, SCCDisp];
{3}	Noop, CANCELBR[$, 0],				c2;
	state ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rIOCBm],			c1;
{4}	Noop, CANCELBR[$, 0],				c2;
	IOCB ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rIOCBmh],		c1;
{5}	Ybus ← state, CANCELBR[$, 0], YDisp,		c2;
	IOCBh ← MD, DISP3[RecvData],			c3;

{Here comes a new frame}
RxStart:
	IO ← [SCCh, SCC+00], {RR0}			c1, at[RS.readyToRecv, 8, RecvData];
{0}	Noop,						c2;
	temp ← MD,					c3;

	Q ← temp and 80,				c1;
{1}	[] ← Q, NZeroBr, L4 ← Bump.rAbortIdle,		c2;
	BRANCH[$, RxAbortStray],			c3;

	MAR ← [CSBh, CSB + CSB.rIOCB],			c1;
{2}	tempH ← 0, CANCELBR[$, 0],			c2;
	temp ← MD,					c3;

	Map ← [tempH, temp],				c1;
{3}	Q ← temp, ZeroBr, L4 ← Bump.rNoBuffer,		c2;
	IOCBh ← IOCB ← MD, BRANCH[$, RxNoBuffer],	c3;

{cycle memory for the side effects of MAR ←}
	MAR ← IOCB ← [IOCBh, temp + 0],			c1;
{4}	Noop,						c2;
	Noop,						c3;

	MAR ← [CSBh, CSB + CSB.rIOCBm],			c1;
{5}	MDR ← IOCB, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [CSBh, CSB + CSB.rIOCBmh],		c1;
{6}	MDR ← IOCBh, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bufferHi],		c1;
{7}	Noop, CANCELBR[$, 0],				c2;
	tempH ← temp ← MD,				c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
{8}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bufferLo],		c1;
{9}	Noop, CANCELBR[$, 0],				c2;
	temp ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
{10}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	Map ← [tempH, temp],				c1;
{11}	Q ← temp, CANCELBR[$, 0],			c2;
	BufferH ← Buffer ← MD,				c3;

{cycle memory for the side effects of MAR ←}
	MAR ← Buffer ← [BufferH, temp + 0],		c1;
{12}	Noop,						c2;
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
{13}	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{14}	MDR ← Buffer, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.bytes],		c1;
{15}	Noop, CANCELBR[$, 0],				c2;
	count ← MD, GOTO[RxGrabLeftByte],		c3;

	
	
RxLeftByte:
	IO ← [SCCh, SCC+00], {RR0} L4 ← 00,		c1, at[RS.recvLeft, 8, RecvData];
{0-3}	CALL[RxBufferSetup],				c2;

RxGrabLeftByte:
	IO ← [SCCh, SCC+08], {RR8}			c1, at[00, 04, RxBufferRet];
{0}	Noop,						c2;
	temp ← MD,					c3;

{1}	count ← count - 1, NegBr,			c1;
	state ← RS.skipping, BRANCH[$, RxOverflowLeft],	c2;
	temp ← temp LRot8,				c3;
	
	MAR ← [BufferH, Buffer + 0],			c1;
{2}	MDR ← temp,					c2;
	state ← RS.recvRight,				c3;

RxSaveCountAndState:
	MAR ← [IOCBh, IOCB + IOCB.bytesLeft],		c1;
{3}	MDR ← count, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

RxSaveState:
	MAR ← [CSBh, CSB + CSB.rState],			c1;
{4}	MDR ← state, CANCELBR[PreAckInt, 0],		c2, LOOPHOLE[wok];


RxRightByte:
	IO ← [SCCh, SCC+00], {RR0} L4 ← 01,		c1, at[RS.recvRight, 8, RecvData];
{0-3}	CALL[RxBufferSetup],				c2;

RxRecvRightByte:
	MAR ← [BufferH, Buffer + 0],			c1, at[01, 04, RxBufferRet];
{4}	count ← count - 1, NegBr,			c2;
	temp ← MD, BRANCH[$, RxOverflowRight],		c3;

	IO ← [SCCh, SCC+08], {RR8}			c1;
{0}	state ← RS.recvLeft,				c2;
	temp ← temp or MD,				c3;
	
	MAR ← [BufferH, Buffer], Buffer ← Buffer + 1,	c1;
{2}	MDR ← temp, BRANCH[$, RxNewPage, 1],		c2;
	GOTO[RxSaveBuffer],				c3;


RxNewPage: {Rats, write canceled}
	Noop,						c3;
	
	MAR ← [BufferH, Buffer + 0FF],			c1;
	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
	Q ← 0FF + 1, CANCELBR[$, 0],			c2;
	Buffer ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
	Buffer ← Buffer + Q, CarryBr, CANCELBR[$, 0],	c2;
	BufferH ← MD, BRANCH[RxNoBankCross, $],	c3;

RxNewBank:
	Q ← BufferH,					c1;
	Q ← Q + 1,					c2;
	BufferH ← Q LRot0,				c3;

	MAR ← [IOCBh, IOCB + IOCB.fingerHi],		c1;
	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

RxNoBankCross:
	MAR ← [IOCBh, IOCB + IOCB.fingerLo],		c1;
	MDR ← Buffer, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Noop,						c3;

	Map ← [BufferH, Buffer],			c1;
	Noop,						c2;
	BufferH ← Buffer ← MD,				c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
	MDR ← BufferH, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Buffer ← Buffer and ~0FF,			c3;

RxSaveBuffer:
	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{6}	MDR ← Buffer, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	GOTO[RxSaveCountAndState],			c3;



{Buffer ended before packet}
RxOverflowRight:
	Noop,						c1;
{-}	state ← RS.skipping,				c2;
RxOverflowLeft:
	temp ← 1, GOTO[RxNextBuffer],			c3;


RxNoBuffer:
	MAR ← Q ← [CSBh, CSB + CSB.rNoBuffer], CALL[BumpCSB], c1;

	MAR ← [CSBh, CSB + CSB.rState],			c1, at[Bump.rNoBuffer, 10, BumpRet];
{6}	MDR ← state ← RS.skipping, CANCELBR[$, 0],	c2, LOOPHOLE[wok];
	GOTO[RxDiscardDataByte],			c3;




RxSkipByte:
	IO ← [SCCh, SCC+00], {RR0}			c1, at[RS.skipping, 8, RecvData];
{0}	Noop,						c2;
	temp ← MD,					c3;
	
	Q ← temp and 80,				c1;
{1}	[] ← Q, NZeroBr,				c2;
	Q ← CSB + CSB.rAborted, BRANCH[$, RxAbortedSkip], c3;
	
RxDiscardDataByte:
	IO ← [SCCh, SCC+08], {RR8},			c1;
{0}	Q ← uInts,					c2;
	temp ← MD, GOTO[AckInt],			c3;


RxBufferSetup:
	temp ← MD,					c3;
	
	MAR ← [IOCBh, IOCB + IOCB.mappedHi],		c1;
{1}	Q ← temp and 80, CANCELBR[$, 0],		c2;
	BufferH ← MD,					c3;

	MAR ← [IOCBh, IOCB + IOCB.mappedLo],		c1;
{2}	[] ← Q, NZeroBr, CANCELBR[$, 0],		c2;
	Buffer ← MD, BRANCH[$, RxAborted],		c3;

	MAR ← [IOCBh, IOCB + IOCB.bytesLeft],		c1;
{3}	L4Disp, CANCELBR[$, 0],				c2;
	count ← MD, DISP2[RxBufferRet],			c3;


RxAborted:
	Q ← CSB + CSB.rAborted,				c1;
	Noop,						c2;
RxAbortedExt:
	Noop,						c3;

RxAbortedSkip:
	MAR ← [CSBh, CSB + CSB.rState], L4 ← Bump.rAborted, c1;
{4}	MDR ← state ← RS.readyToRecv, CANCELBR[$, 0],	c2, LOOPHOLE[wok];
	Noop,						c3;

	MAR ← Q ← [CSBh, Q + 0], CALL[BumpCSB],		c1;
	
	IO ← [SCCh, SCC+00], {WR0}			c1, at[Bump.rAborted, 10, BumpRet];
ResetExtStatus:
{0}	MDR ← 010, {Reset Ext/Sts Int} GOTO[PreAckInt],	c2;
	
RxAbortStray:
{2}	MAR ← Q ← [CSBh, CSB + CSB.rAbortIdle], CALL[BumpCSB], c1;
	
	IO ← [SCCh, SCC+00], {WR0} GOTO[ResetExtStatus],c1, at[Bump.rAbortIdle, 10, BumpRet];
	
		

{RecvChar is "special", hopefully it's the End of a frame}
RxSpecial:
	MAR ← [CSBh, CSB + CSB.rIOCBm],			c1, at[0F, 10, SCCDisp];
{3}	Noop, CANCELBR[$, 0],				c2;
	IOCB ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rIOCBmh],		c1;
{4}	Noop, CANCELBR[$, 0],				c2;
	IOCBh ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rState],			c1;
{5}	Noop, CANCELBR[$, 0],				c2;
	state ← MD,					c3;
	
	IO ← [SCCh, SCC+00], {RR0}			c1;
{0}	Noop,						c2;
	temp ← MD,					c3;
	
	IO ← [SCCh, SCC+01], {RR1}			c1;
{0}	temp ← temp LRot8,				c2;
	temp ← temp or MD,				c3;
	
	IO ← [SCCh, SCC+08], {RR8}			c1;
{0}	Noop,						c2;
	Xbus ← MD,					c3;
{Discard shifted last byte of the CRC.}

	IO ← [SCCh, SCC+00], {WR0}			c1;
{0}	MDR ← 030, {Reset Errs}				c2;
	Noop,						c3;
	
	[] ← state and RS.activeMask, ZeroBr,		c1;
{2}	BRANCH[$, RxSpecialNoBuffer],			c2;
	state ← RS.readyToRecv,	GOTO[RxNextBuffer],	c3;
	
RxSpecialNoBuffer:
	state ← RS.readyToRecv,	GOTO[RxSaveState],	c3;

	

{Store final status and chain to next recv buffer.
  state has new state (RS.skipping or RS.readyToRecv)
  temp has status}
RxNextBuffer:
	MAR ← [IOCBh, IOCB + IOCB.status],		c1;
{1}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	Q ← uWP,					c3;

	MAR ← [IOCBh, IOCB + IOCB.next],		c1;
{2}	Q ← Q or uIntPhone, CANCELBR[$, 0],		c2;
	temp ← MD,					c3;

	MAR ← [CSBh, CSB + CSB.rIOCB],			c1;
{3}	MDR ← temp, CANCELBR[$, 0],			c2, LOOPHOLE[wok];
	uWP ← Q, GOTO[RxSaveState],			c3;


PreAckInt:
	Q ← uInts,					c3;

AckInt:
	IO ← [SCCh, SCC+00], {WR0x}			c1;
{0}	MDR ← 38, {Reset Highest IUS}			c2;
	Q ← Q and ~u800,				c3;
	
	uInts ← Q,					c1;
{1}	temp ← u800,					c2;
	TT ← TT and ~temp, GOTO[NoPhoneInterrupt],	c3;
	
	
{-----------------------------------------------------------}

BumpCSB:
{1+}	CANCELBR[$, 0],					c2;
	temp ← MD,					c3;
	
	MAR ← [CSBh, Q + 0],				c1;
{2+}	MDR ← temp + 1, L4Disp,				c2;
	DISP4[BumpRet],					c3;