*----------------------------------------------------------------------------
Title[AltoEtherEmu.Mc...January 9, 1981 11:38 AM...Taft];
* Emulator-level microcode for operating Dorado Ethernet
*----------------------------------------------------------------------------


*----------------------------------------------------------------------------
* Emulator Task -- SIO instruction
*----------------------------------------------------------------------------
Set[XTask, IP[EMU]];
* Emulator mode
TopLevel;
DontKnowRBase;

* Get here with the SIO control bits in Stack.
* Alto and Mesa emulators here at the end of SIO emulation after
* first processing control bits for any other devices (e.g., Trident).
ESIO:
T← EControl;
Stack← (Stack) AND (3C);* Mask Ethernet control bits
T← A0, TIOA← T, Branch[SIONop, ALU=0]; * Select control register

* Control bits nonzero. Must first reset the hardware and tasks.
* Addressing constraints require one instruction between the conditional
* Branch (above) and the CALL, and the CALLs must leave FF free.
TaskingOff;
Call[EResI];* Reset input
Call[EResO];* Reset output
T← A0, BDispatch← Stack;* Dispatch on function bits

SIO0:
TaskingOn, Branch[SIO0], DispTable[4, 7, 4]; * Dispatch 0 can’t happen

* 01 -- Start transmitter
T← TurnOnTx, Branch[SIOStart];* Enable output wakeups

* 10 -- Start receiver
T← TurnOnRx, Branch[SIOStart];* Enable input wakeups

* 11 -- Reset interface
T← ECmdBits, Branch[SIOReset];* Manufacture "abort" status

SIOStart:
T← A0, Output← T, Branch[SIONop];

SIOReset:
T← T XOR (CmdAbort);
Call[EPost];* Post it (must leave FF free)
T← A0;

* 00 -- Noop, just return Ethernet address.
* Note that this is the tail of the other 3 cases. T=0 here
SIONop:
Stack← InputNoPE;* Read status
PD← Stack, TIOA← T;* TIOA← 0
Stack← RSH[Stack, 10],* Right-justify Ethernet address
Branch[.+2, ALU=0];* Branch if status word entirely zero
Stack&-1← (Stack&-1) OR (77400C), IFUJump[0]; * 177 .. Ethernet addr

* Apparently no Ethernet interface installed.
* Alto software expects to see 77777 in this case.
Stack&-1← 77777C, IFUJump[0];

*----------------------------------------------------------------------------
* Ethernet Boot
*----------------------------------------------------------------------------

* The emulator branches here after doing all other initialization.
* When the Breath of Life packet has been received, we branch to
* the emulator main loop.

KnowRBase[AEmRegs];

EBoot:
T← A0, MemBase← ECBR;* Address page 1
Store← EBLoc, DBuf← T;* EBLoc← 0 (interrupt bit mask)
ETemp← (Store← EOCLoc)-1, DBuf← T; * EOCLoc← 0 (output count)
ETemp← (Store← ETemp)-1, DBuf← 1C; * EIPLoc← 1 (input pointer)
Store← ETemp, DBuf← 400C;* EICLoc← 400 (input count)
ETemp← EHLoc;
Store← ETemp, DBuf← 377C;* EHLoc← 377 (host address)
T← EControl;
TIOA← T;
TaskingOff;* Reset input hardware and microcode
Call[EResI];
TaskingOn;

* Loop to await Breath of Life packet.
* Turn on receiver, wait for a packet to arrive. If an OK receiver status
* is posted and the packet type is Breath of Life, set the PC to 3 and
* start the emulator.
EBLoop:
ETemp← A0, MemBase← ECBR;* Address page 1
EBLoo1:
T← (Store← EPLoc), DBuf← ETemp;* EPLoc← 0 (post location)
Fetch← T, T← TurnOnRx;* Fetch to prime MD for wait loop
Output← T;* Turn on receiver

Fetch← EPLoc, T← (PD← MD);* Wait for EPLoc to go nonzero
T← T-(377C), Branch[.-1, ALU=0]; * Test for OK receiver status
T← 202C, Branch[EBLoo1, ALU#0];
MemBase← MDS;* Address page 0
Fetch← 2S;* Fetch word 2 (packet type)
T← T+(400C);* T← 602 = typeBreathOfLife
PD← T-MD;
Branch[EBLoop, ALU#0];* Loop if type is wrong
T← 3C, Branch[Start];* Start emulator at location 3