{
file: <CoPilot>DLion>CedarB1.mc
Last edited:  9-Jan-87 11:14:56

Copyright (C) 1983, 1984, 1985, 1986, 1987 by Xerox Corporation.  All rights reserved.

This code goes into bank 1, but most opcodes which begin here complete in bank 0 CedarB0.mc.

Miscellaneous notes:
1) Debug LocalBlkZ (not presently used).
2) Consolidate the Cedar opcodes down into the group of 16 with RTMoveStatus and
  CRefType to save 16d mi; eliminate the short map opcodes and use their alpha
  values for the long map opcodes to save 32d mi; eliminate RTMoveStatus (= GCSetup,
  a remnant from Cedar4.4) and AssignRefNew which are useless to save 4d mi.
3) Make all opcodes except AssignRef and CRefType be minimal stack.
4) The ZCTObject should be consolidated by advancing bsiToFreeList from
  400'b to 10'b, bsiToSize to 110'b, sizeToBSI to 310'b, and fosTable to
  1000'b.  Half of the sizes in sizeToBSI are wasted because the restriction
  on NHPs and Refs being evel-aligned implies odd sizes can be increased to the
  next larger even size without cost; so AllocateObject could fetch the BSI at
  (Size+1)/2 in the sizeToBSI table saving 220'b words.
5) The FOSTableHash would be faster if zct.residueMask were already AND'ed with
  FOSTableLength-1.
6) Masking the type word to 14'd bits in CRefType is no longer useful (a remnant
 from Cedar 4.4.); AllocateObject presently does not mask its type argument,
  and the entire word containing the type is zeroed by FreeObject.
7) The fact that EnableMicrocode returns a version number is redundant with
  the version number returned by MicrocodeVersion; EnableMicrocode should
  be changed to not return a version number.
8) MicrocodeVersion should indicate the number of microstore banks, floating
  point hardware, encryption hardware; this information should be left in a
  register by Initial.
9) Since Refs are prohibited from being in the first 64k; a NIL check can be
  equivalent to the high word of the Ref = 0; this would result in considerable
  savings in AssignRef, where separate registers are used to hold NIL/notNil.
10) Make sure that simply OR'ing markingDecrements into the header word in
  CreateRef is ok (as opposed to first clearing the bit).
11) Implement FSQRT, open code MUL loop.
}

{protect "low cp", used by multi bank boot code}
{high cp, used by kernel, already protected in this bank by StartMesa.mc}

Reserve[1,07F];

{Handle misc groups 60b to 77b, 100'b to 117'b, and 140'b to 157'b.
The preceding microinstructions were:

@MISC:	Xbus ← ibHigh, XDisp,			c1, opcode 364'b;
	Rx ← ib, XDisp, push, DISP4[MiscHigh,8];
}

Misc3m:	STK ← TOS, pop, DISP4[Misc3n],		c3, at[3, 10, MiscHigh];
Misc4m:	STK ← TOS, pop, DISP4[Misc4n],		c3, at[4, 10, MiscHigh];
Misc6m:	STK ← TOS, pop, DISP4[Misc6n],		c3, at[6, 10, MiscHigh];

{UnimpOpcode is in CedarMisc.mc}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[00, 10, Misc3n]; {60b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[01, 10, Misc3n]; {61b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[02, 10, Misc3n]; {62b}
	{63b = RTMoveStatus = GCSetup, implemented}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[04, 10, Misc3n]; {64b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[05, 10, Misc3n]; {65b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[06, 10, Misc3n]; {66b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[07, 10, Misc3n]; {67b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[08, 10, Misc3n]; {70b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[09, 10, Misc3n]; {71b}
	{72b = CRefType, implemented, **PRODUCED BY COMPILER**}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0B, 10, Misc3n]; {73b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0C, 10, Misc3n]; {74b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0D, 10, Misc3n]; {75b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0E, 10, Misc3n]; {76b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0F, 10, Misc3n]; {77b}

	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[00, 10, Misc4n]; {100'b = LocalBlkZ}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[01, 10, Misc4n]; {101'b}
	{102'b = LongBlkZ}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[03, 10, Misc4n]; {103b}
	{104'b = MicrocodeVersion}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[05, 10, Misc4n]; {105b}
	{106'b is WriteL for Jim Gasbarro}
	{107'b is WriteM for Jim Gasbarro}
	{110'b is ReadL for Jim Gasbarro}
	{111'b is ReadM for Jim Gasbarro}
	{112'b is WriteMBus for Tim Diebert}
	{113'b is ReadMBus for Tim Diebert}
	{114'b is WritePCBus for Mick Lamming}
	{115'b is ReadPCBus for Mick Lamming}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0E, 10, Misc4n]; {116b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0F, 10, Misc4n]; {117b}

	{140b = ReclaimedRef}
	{141b = EnableMicrocode}
	{142b = DisableMicrocode}
	{143b = CreateRef}
	{144b = ReclaimableRef}
	{145b = AllocateObject}
	{146b = FreeObject}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[07, 10, Misc6n]; {147b}
	{150b = SM SetMap in CedarMisc.mc}
	{151b = SMF SetMapFlags in CedarMisc.mc}
	{152b = GMF GetMapFlags in CedarMisc.mc}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0B, 10, Misc6n]; {153b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0C, 10, Misc6n]; {154b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0D, 10, Misc6n]; {155b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0E, 10, Misc6n]; {156b}
	T ← Rx + 377'b + 1, GOTO[UnimpOpcode],	c1, at[0F, 10, Misc6n]; {157b}


{*************************************************************************
aRTMoveStatus (A noop for compatibility purposes)
	on entry
		TOS = msOperation
		STK = gcStateBank
	
	on exit
		stack is popped once
		TOS = 0
*************************************************************************}
aRTMoveStatus:
	pop, TOS ← 0,						c1, at[03, 10, Misc3n] {63'b};
MicVersion1:
	IBDisp,							c2;
	PC ← PC + 1, DISPNI[OpTable],				c3;


{*************************************************************************
aMicrocodeVersion
	no arguments
	on exit two words pushed onto the stack
	  TOS	Day of release as number of days since 1 January 1901
	  STK	Bits 0..3	Engineering no.:
		    4:		Dolphin
		    5:		Dorado
		    6:		Dandelion or Dandetiger
		    7:		Dicentra
		    8:		Daybreak
		    9:		Daisy
       		Bits 4..7	Version number (currently 0)
	Machine-dependent flags:
		Bit  8:		1 = Raven microcode instead of display
		Bit  9:		1 = Trident microcode instead of SAx000
		Bits 10..13:	Undefined
	Machine-independent flags
		Bit 14:		1 = have floating point microcode
		Bit 15:		1 = have Cedar microcode

Engineering number must range over all the machines which run or might run
a compatible instruction set.

Pilot time is a long cardinal equal to the number of seconds since midnight
1 January 1901; to convert to Pilot time, lengthen the result and multiply by 86,400.
1 Jan 1986 is 85 * 365 + 21 days = 31,046 days after 1 Jan 1901.

18 Nov 1986 is 31,046 + 31 (Jan) + 28 (Feb) + 31 (Mar) + 30 (Apr) + 31 (May) +
30 (June) + 31 (July) + 31 (Aug) + 30 (Sept) + 31 (Oct) + 18 = 31,046 + 322 =
31,368 = 32,768 - 1,024 - 256 - 128 + 8 = 100000'b - 2570'b = 75210'b = <172'b, 210'b>
9 Jan 1987 is 31,411 + 9 = 32768 - 1024 - 256 - 64 - 8 - 5 = 100000'b - 2515'b
= 75263'b = <172'b, 263'b>.

Config assembly switch interpretation (see StartMesa.mc):
	0 = standard SAx000 with display microcode
	1 = SAx000 with Raven microcode instead of display
	2 = Trident with display microcode
	3 = Trident with Raven microcode instead of display
	4 = MagTape
	5 = Trident magtape
	6 = Multiport
	7 = Dicentra
On 8/11/86 only configurations 0, 1, and 2 were built for Cedar, so configuration flags
are not allocated for the other configurations; however, the Config values are retained
for compatibility with Mesa product microcode.
*************************************************************************}
aMicVersion: {Misc 104'b}
	TOS ← 172'b, push,					c1, at[04, 10, Misc4n];
	TOS ← TOS LRot8, push,					c2;
	TOS ← TOS or 263'b,					c3;

Set[HighVerFlags, 140'b]; {High 8 bits of 60003'b + Config bits}
IfEqual[Config, 7, Set[HighVerFlags, 160'b],];
	T ← HighVerFlags,					c1;
	T ← T LRot8,						c2;
Set[LowVerFlags, 3'b]; {Sax000, display, have floating point microcode, have Cedar microcode}
IfEqual[Config, 1, Set[LowVerFlags, 203'b],];
IfEqual[Config, 2, Set[LowVerFlags, 103'b],];
	T ← T or LowVerFlags {Low 8 bits of 60003'b + Config bits},	c3;

	STK ← T, GOTO[MicVersion1],				c1;


{************************************************************************
Here begin the opcodes whose main implementation is in bank0.
One click is here; code continues in CedarB0.mc.
*************************************************************************}
@CRefType:  {Misc 72'b}
	Bank ← MSBank0, L0 ← L0.CRefT2,				c1, at[0A, 10, Misc3n];
	TT ← STK, L2 ← L2.CRefT1,				c2;
	[] ← TOS or STK, ZeroBr, GOTOABS[B0CRefType],		c3;

{When alpha is on a different page from the first opcode byte and that page is not in
storage, it is possible for ← ib to generate a refill trap; when this occurs, control must
still be in bank 1 and most state registers must not have been disturbed.  Because the
stack pointer is restored on an ib refill trap, the push and pop in the same click with
← ib below should be ok.  I think Rx and TT are sometimes smashed by the refill trap,
so they cannot be loaded in the first click below, but I am not sure; maybe the first click
is repeated following the refill trap.}
@AssignRef:
	Q ← ib, push,						c1, opcode[76'b];
NcAssignRefNew1:
	STK ← TOS, pop, Rx ← TOS + 1,				c2;
	T ← 76'b,						c3;
						
	Bank ← MSBank0,						c1;
	uNcTrapOffset ← T,					c2;
	[] ← uMicrocodeDisabled, ZeroBr, GOTOABS[B0AssignRef],	c3;
		

{Following behaves EXACTLY like AssignRef; separate trap not needed.  AssignRefNew historically
differed from AssignRef; now it is the same and useless, but the compiler still produces it.}
@AssignRefNew:
	Q ← ib, push, GOTO[NcAssignRefNew1],			c1, opcode[77'b];


{***************************************************************************
aEnableMicrocode
****************************************************************************}
@NcEnable: {misc 141'b}
	Bank ← MSBank0,						c1, at[01, 10, Misc6n];
	uZctHigh ← TOS,						c2;
	TT ← STK, GOTOABS[B0Enable],				c3;


{***************************************************************************
aDisableMicrocode
****************************************************************************}
@NcDisable: {misc 142'b}
	Bank ← MSBank0,						c1, at[02, 10, Misc6n];
	Noop,							c2;
	GOTOABS[B0Disable],					c3;

	
{***************************************************************************
aCreateRef
****************************************************************************}	
@CreateRef: {misc 143'b}
	Bank ← MSBank0, L0 ← L0.CR1,				c1, at[03, 10, Misc6n];
	T ← Rx + 377'b + 1,					c2; {400'b + 143'b}
RAR0:	[] ← uMicrocodeDisabled, ZeroBr, GOTOABS[B0CreateRef],	c3;


{***************************************************************************
aReclaimableRef
****************************************************************************}
@ReclaimableRef: {misc 144'b}
	Bank ← MSBank0, L0 ← L0.RAR1,				c1, at[04, 10, Misc6n];
	T ← Rx + 377'b + 1, GOTO[RAR0],				c2; {400'b + 144'b}



{***************************************************************************
aReclaimedRef
****************************************************************************}
@ReclaimedRef: {misc 140'b}
	Bank ← MSBank0,						c1, at[00, 10, Misc6n];
	T ← Rx + 377'b + 1,					c2; {400'b + 140'b}
	[] ← uMicrocodeDisabled, ZeroBr, GOTOABS[B0ReclaimedRef],	c3;


{****************************************************************************
AllocateObject is undebugged.
*****************************************************************************}
@AllocateObject: {misc 145'b}
	Bank ← MSBank0,						c1, at[05, 10, Misc6n];
	T ← Rx + 377'b + 1,					c2; {400'b + 145'b}
	[] ← uMicrocodeDisabled, ZeroBr, GOTOABS[B0AllocateObject],	c3;


{****************************************************************************
FreeObject is unimplemented
*****************************************************************************}
@FreeObject: {misc 146'b}
	Bank ← MSBank0,						c1, at[06, 10, Misc6n];
	T ← Rx + 377'b + 1,					c2; {400'b + 146'b}
	uNcTrapOffset ← T, GOTOABS[B0FreeObject],		c3;


{***************************************************************************
aLongBlkZ
  At entry:
  	TOS	Cardinal count of words to zero.
	STK	High part of Long pointer to block.
	STK-1	Low part of long pointer to block.
  The block is zeroed in reverse order to avoid state save and restore.  After each
  iteration the count (TOS) is decremented.
****************************************************************************}
@LongBlkZ:	{misc 102'b}
	Bank ← MSBank0, L1 ← L1.LBZ2,				c1, at[02, 10, Misc4n];
	Q ← rhTT ← STK,						c2;
	Rx ← TOS - 1, {CarryBr,} pop, GOTOABS[B0LongBlkZ],	c3;


{***************************************************************************
aLocalBlkZ
  At entry:
  	TOS	cardinal count of words in local frame to zero.  The frame
		starts at LOCAL + 4, so count + 4-1 is displacement of the
		last word.
  At return:  	The argument has been popped from the stack and the frame words are
		zeroed.
****************************************************************************}
{@LocalBlkZ:	{misc 100'b}
	Bank ← MSBank0,						c1, at[00, 10, Misc4n];
	rhTT ← UvMDS,						c2;
	TT ← UvL, GOTOABS[B0LocalBlkZ],				c3;
}


{***************************************************************************
aChecksum
  At entry:
  	TOS = uStack5 = srcHi
	STK = uStack4 = srcLo
	STK-1 = uStack3 = count
	STK-2 = uStack2 = csum
  At return:
  	The arguments have been replaced by the final checksum.

The 16-bit Pup checksum is initialized to zero; each 16-bit word in the block is ones-complement
added to the checksum; following each addition, the checksum is left-cycled 1.  A final result
of "minus one" (177777B) is converted to zero. 177777B is specifically defined to mean that
the Pup carries no checksum.
****************************************************************************}
@Checksum:
	Bank ← MSBank0, L0 ← L0.CSRem2,				c1, at[7, 10, Misc0n];
	rhTT ← TOS LRot0 {srcHi},				c2;
	TT ← STK {srcLo}, GOTOABS[B0CSum],			c3;



{Created by: Sturgis:  roughly 12-Dec-83
Fiala & Purcell, 19-Mar-85 10:06:37:	ReadL/M, WriteL/M for Gasbarro
Fiala 12-Jul-85: Absorb XCedarOpsA.mc and XCedarOpsB.mc into CedarB1.mc;
	eliminate HES's test opcodes.
Fiala 15-Jul-85 10:33:05: Cause AssignRefNew to execute the code for
	AssignRef since the opcodes are identical.
Fiala 18-Jul-85 10:51:17: Save TOS on the STK in AssignRef; use trap table
	for all unimplemented opcodes and traps; eliminate the preamble for
	AssignRef and CreateRef.
Fiala 22-Jul-85 14:59:38: Turn on CreateRef.
Fiala 23-Jul-85 15:48:37: Collapse 2 mi of EnableMicrocode from Bank 0 to bank 1.
Fiala 30-Jul-85  9:08:55: Add MicrocodeVersion opcode; move ReadL and ReadM
	for Gasbarro to avoid conflict with LocalBlkZ; enable ReclaimedRef and
	ReclaimableRef.
Fiala 26-Aug-85 16:56:20: Enable LongBlkZ, AllocateObject, and FreeObject opcodes.
Fiala 10-Apr-86 Replaced Rx by [] cosmetic edits and changed comments.
Fiala 22-Apr-86 13:33:13 Added Rx ← TOS + 1 in AssignRef entry; eliminate
	Add[Bank0, ...]" names.
Fiala 24-Apr-86 17:20:06 Common entry for ReclaimableRef and CreateRef.
Fiala 29-Apr-86 17:36:00 Removed useless T ← 0 in first mi of LongBlkZ.
Fiala 14-May-86 13:51:01 Removed the traps for the three map opcodes
	(150'b, 151'b, and 152'b)
Fiala 20-May-86 17:17:23 Changed the Bank ← 0 to be Bank ← MSBank0 to allow
	for MS controls.
Fiala  9-Jul-86 11:00:45: Added WriteMBus and ReadMBus opcodes for Tim Diebert.
Fiala 29-Jul-86 12:54:12: Added WriteIBMBus and ReadIBMBus opcodes and
	revised WriteMBus and ReadMBus.
Fiala  8-Aug-86 16:45:30: Put in common entry sequence for Read/Write
	MBus/IBMBus opcodes saving 3 mi.
Fiala 11-Aug-86 11:04:10: Added Raven and Trident bits for MicrocodeVersion opcode;
	changed "WriteIBMBus" to "WritePCBus" and "ReadIBMBus" to "ReadPCBus" in
	opcode names.
Fiala 19-Nov-86 18:12:00 Added config switch for Dicentra in MicrocodeVersion opcode;
	split the MBus and PCBus opcodes into a separate file MBusB1.mc.
Fiala  9-Jan-87 11:15:57 Changed date in MicrocodeVersion.
}