* Definitions for Dorado Smalltalk Microcode
*Dorado Model 1, XM version
* last edited July 9, 1979 9:53 AM by Deutsch

* last edited June 28, 1982  9:52 AM by Haugeland
*  retyped June 4, 1981  9:18 AM  by Haugeland


Title[DSmallDefs.mc];


* Define RM regions
* registers with a comment *#n are known to the Nova code!!

M[rmre, set[!#1, !#2]];	* equate #1 to #2 as an RMRegion
M[rmrat, set[!#1, and[#2,360]] set[RBOUND,or[#2,17]] RM[RLC,#2]];  *Use a specified RM region
M[bre, BR[#1, IP[#2]]];   * equate #1 to #2 as a BR

M[MBC, MC[#1, #3] MSC[#2, #3]];   * Define a .c and .s together

M[DontKnowR, DontKnowRBase];	* i.e. force use of FF on stores

* SmallTalk names for Nava registers

  bre[AemMemBase, MDS];	**wsh
  rme[IReg, ETemp4];

SetRMRegion[Region14];
 RMRE[Saves, Region14];		*some nominal temps which must be safe across Nova calls
   Rvn[SavDisp];		*#62
   Rvn[SavSp];
   Rvn[SavPc];
   Rvn[SavR0];
   Rvn[SavR1];
RMRE[IfuState, Saves];
   Rvn[Pcb];		*#15 -- <0 if Pc is in IFU, >=0 if here
   Rvn[Caddr];			*#71 =CodeBr+Pcb/2, only validwhen pcb>=0
   Rvn[CodeBase];		*copy of CodeBr
   Rvn[ArecBase];		*copy of ArecBr
   Rvn[LocFrameBase];		*copy of LocFrameBr
   Rvn[TFrameBase];		*copy of TFrameBr
   Rvn[SelfBase];		*copy of SelfBr
   Rvn[ACoreBase];		*copy of ACoreBr
   Rvn[BCoreBase];		*copy of BCoreBr
   Rvn[SmtInset];

RMRAT[State, 0];	*Normal registers while running Smalltalk
	* must be at 0 for IFU setup (overlaps with Mesa registers)
   Rvn[StackP];		*#67
   Rvn[Top];		*#70 a cache for the top element of the stack, except after a POP
   Rvn[SupMod];		*#74
   Rvn[Name];		*#44
   Rvn[Ctxt];		*#76
   Rvn[Temp1];
   Rvn[Temp2];
   Rvn[Temp3];
   Rvn[Temp4];
   Rvn[Arg1];		*=AC0 (copied at Smalltalk entry and exit)
   Rvn[Mode];		*0 normally, 1 if last op was Smash
   Rvn[MinAt];		*#54
   Rvn[Aoop];		*#17
   Rvn[Boop];		*#65
   Rvn[Father];		*#53

SetRMRegion[Region15];
 RMRE[Links, Region15];
   Rvn[IvalLink];
   Rvn[IntnLink];
   Rvn[ILongLink];
   Rvn[RefCtLink];
   Rvn[AllocLink];
 RMRE[Hash, Links];		*private registers for Hash
   Rvn[Residue];
   Rvn[Rot0];
   Rvn[RotA];		*RotA is displacement from RotBase
   Rvn[RotBase];	*copy of RotBaseBr
   Rvn[RotCMsk];	*holds Rot size in words (160000 for XM, 170000 for non-XM)
   Rvn[Rot0Em];		*empty entry in Rot (=360)


* A temp--relative, so cannot be saved across UseR changes
 RvRel[MyTemp, 17];

* return addresses known as constants
MP[NIRetLoc, 75]; MC[NovaIvalRet.c, NIRetLoc];
MP[NHRetLoc, 71]; MC[NovaHashRet.c, NHRetLoc];

* set up dispatch addresses in IM
Set[Dispatch1, 4700];	*20-way dispatch (OpCodeDispatch)
Set[Dispatch2, 4600];	*10-way dispatch (OpsDispatch)
Set[Dispatch3, 6400];	*20-way dispatch on bits 8:11 (ByteTypeD)
Set[Dispatch4, 4100];	*20-way dispatch (PrimOpsDispatch)
Set[Dispatch5, 7260];	*10-way dispatch (ArithDispatch), must have 260 bits set
Set[Dispatch6, 3700];	*20-way dispatch (OMsgs)
Set[Dispatch7, 3600];	*10-way dispatch (DeltaDispatch)
Set[Dispatch8, 6000];	*10-way dispatch (Returns)
Set[Dispatch9, 5500];	*100-way dispatch (RRegs)
Set[Dispatch10, 4000];	*100-way dispatch (WRegs)
Set[Dispatch11, 5300];	*10-way dispatch (RedoDispatch)


*Define the Constants and Masks
MC[Rct1Bit.c, 20];		*RefCt 1-bit
MC[Rct8Bit.c, 200];		*RefCt 8-bit
MC[Rct14.c, 340];		*RefCt=14
MC[Rot0Nd.c, 0];		*Rot0 for new, not clean, Ref=1, not imm. (no bits on)
MC[Rot0Em.c, 360];		*empty entry in Rot
MC[RotCMsk.c, 160000];		*-Rot size in words (16000 for XM0

MC[ClnMsk.c, 177775];		*dirty mask--turns off clean (=2) bit
MC[RctMsk.c, 360];		*RefCt mask
MC[HkrMsk.c, 174000];		*Rot Hkr bit mask
MC[RpcBit.c, 400];		*Low bit of Rot Rpc field for inc-in-place
MC[ImmBit.c, 4];		*Immediate bit mask for Tor0
MC[MsInt.c, 174000];		*Min small integer oop
MC[Oop00.c, 176000];		*Oop of small integer 0
MC[OopM1.c, 175777];		*Oop of small integer -1
MC[MOop00.c, 2000];		*-(Oop of small integer 0)
MC[ResRpc.c, 177400];		*Rot Hkr-Rpc bit mask
MC[ResRpcImm.c, 177404];	*Rot Hkr-Rpc-Imm bit mask
MC[CptMsk.c, 100];		*Mask for is-pointer in Pmap
MC[IscMsk.c, 37];		*Mask for instance size in Pmap
MC[RciMsk.c, 177600];		*Real class part of Pmap
MBC[SenderF.c, SenderF.s, 0];	*Offset of sender field in arec
MBC[InstF.c, InstF.s, 1];	*ditto instance field
MBC[ClassF.c, ClassF.s, 2];	*ditto mclass field (no longer used)
MBC[CodeF.c, CodeF.s, 3];	*ditto code (method) field
MBC[TFrameF.c, TFrameF.s, 4];	*ditto tempframe field
MBC[PcF.c, PcF.s, 5];		*ditto saved Pc field
MBC[StackPF.c, StackPF.s, 6];	*ditto saved StackP field
MC[Octv.c, 24];			*ISC of first octave
MC[VarClsm400.c, 200];		*Class oop of first var-len class -400
MC[VarRci.c, 140000];		*Rci of first var-len class (doesn't need masking)
MC[NumCls.c, 4];		*Number class (i.e. Integer) oop
MC[ObjCls.c, 27];		*Nil class oop
MC[SprClsF.c, 5];		*Index of superclass field
MC[MDictF.c, 3];		*Index of message dictionary
MC[ClFree.c, 10];		*Offset of freelisthead in classes
MC[ClFree2.c, 21];		*ClFree of second class
MC[ClFree3.c, 33];		*ClFree of third class
MC[StmCls.c, 10];		*Stream class
MC[CntxCls.c, 2];		*Oop of class Context (see "Byte:")
MC[VecClsm400.c, 200];		*Vector class -400
MC[StrClsm400.c, 201];		*String class -400
MC[FalseOop.c, 2000];		*False oop
MC[TrueOopm1.c, 2000];		*True Oop -1
MC[ErrPrg.c, 3];		*Address of oop of error method
MC[PrimTabLoc.c, 100];		*Primitive table location??
MC[SelfLoc.c, 101];		*Self location (for primitives)
MC[AllOnes.c, 177777];		*-1
MC[PrapPcm400.c, 127];		*Nova trap PC loc -400


*Base register assignments

*Following must be accessible to IFU
BRX[ArecBr, 0];			*#60
BRX[LocFrameBr, 1];		*#66
BRX[TFrameBr, 2];		*#72
BRX[SelfBr, 3];			*#73
bre[CodeBr, CODE];		* Code base, BR 37

* rest need not be accessible to IFU
BR[CoreBaseBr, 17];		*#14
BR[PmBaseBr, 16];		*#55
BR[RotBaseBr, 15];		*#56 **END of Rot**
BR[NamesBr, 14];
BR[ACoreBr, 4];			*#52
BR[BCoreBr, 5];			*#63

* BR 35 is availbale

*** IFU definitions

* IFUn[opcode,MemBase,Addr,N,sign,PA];
M[IFU1, IFUREG[#1,1,#2,!State,#3,#4,#5,#6]];
M[IFU2, IFUREG[#1,2,#2,!State,#3,#4,#5,#6]];
M[IFUJ1, IFUJMP[#1,1,#2,!State,#3,#4]];
M[IFUP1, IFUPAUSE[#1,1,#2,!State,#3,#4,#5,#6]];
M[IFUP2, IFUPAUSE[#1,2,#2,!State,#3,#4,#5,#6]];

M[mifu, set[=,0] repeat[#2, (#3, set[==,add[=,#1]]) set[=,add[=,1]]]];

INSSET[1,1];