1 using System;
  2 using System.Threading;
  3 
  4 namespace cmsx.machine
  5 {
  6     public const ulong trapXMask = 0x0000000000FF0000u;
  7     public const byte trapXShift = 16u;
  8     public const ulong trapYMask = 0x000000000000FF00u;
  9     public const byte trapYShift = 8u;
 10     public const ulong trapZMask = 0x00000000000000FFu;
 11     public const byte trapZShift = 0u;
 12 
 13     public const byte regAX = 255u;
 14     public const byte regBX = 254u;
 15     public const byte regCX = 253u;
 16     public const byte regDX = 252u;
 17     public const byte regEX = 251u;
 18     public const byte regSP = 250u;
 19     public const byte regFP = 249u;
 20     public const byte regIX = 248u;
 21     public const byte firstGlobalReg = 248u;
 22 
 23     public class Registers
 24     {
 25 //      register                           description                          S = saved, P = put
 26 // ===============================================================================================
 27         public const byte rA = 0u;
 28         public const byte rB = 1u;
 29         public const byte rC = 2u;
 30         public const byte rD = 3u;
 31         public const byte rE = 4u;
 32         public const byte rF = 5u;
 33         public const byte rG = 6u;
 34         public const byte rH = 7u;
 35         public const byte rI = 8u;
 36         public const byte rJ = 9u;
 37         public const byte rK = 10u;
 38         public const byte rL = 11u;
 39         public const byte rM = 12u;
 40         public const byte rN = 13u;
 41         public const byte rO = 14u;
 42         public const byte rP = 15u;
 43         public const byte rQ = 16u;
 44         public const byte rR = 17u;
 45         public const byte rS = 18u;
 46         public const byte rT = 19u;
 47         public const byte rU = 20u;
 48         public const byte rV = 21u;
 49         public const byte rW = 22u;
 50         public const byte rX = 23u;
 51         public const byte rY = 24u;
 52         public const byte rZ = 25u;
 53         public const byte rBB = 26u;
 54         public const byte rTT = 27u;
 55         public const byte rWW = 28u;
 56         public const byte rXX = 29u;
 57         public const byte rYY = 30u;
 58         public const byte rZZ = 31u;
 59 
 60         public nothrow Registers()
 61         {
 62             specialRegMap[rA] = "rA";
 63             specialRegMap[rB] = "rB";
 64             specialRegMap[rC] = "rC";
 65             specialRegMap[rD] = "rD";
 66             specialRegMap[rE] = "rE";
 67             specialRegMap[rF] = "rF";
 68             specialRegMap[rG] = "rG";
 69             specialRegMap[rH] = "rH";
 70             specialRegMap[rI] = "rI";
 71             specialRegMap[rJ] = "rJ";
 72             specialRegMap[rK] = "rK";
 73             specialRegMap[rL] = "rL";
 74             specialRegMap[rM] = "rM";
 75             specialRegMap[rN] = "rN";
 76             specialRegMap[rO] = "rO";
 77             specialRegMap[rP] = "rP";
 78             specialRegMap[rQ] = "rQ";
 79             specialRegMap[rR] = "rR";
 80             specialRegMap[rS] = "rS";
 81             specialRegMap[rT] = "rT";
 82             specialRegMap[rU] = "rU";
 83             specialRegMap[rV] = "rV";
 84             specialRegMap[rW] = "rW";
 85             specialRegMap[rX] = "rX";
 86             specialRegMap[rY] = "rY";
 87             specialRegMap[rZ] = "rZ";
 88             specialRegMap[rBB] = "rBB";
 89             specialRegMap[rTT] = "rTT";
 90             specialRegMap[rWW] = "rWW";
 91             specialRegMap[rXX] = "rXX";
 92             specialRegMap[rYY] = "rYY";
 93             specialRegMap[rZZ] = "rZZ";
 94         }
 95         public ulong Get(byte regNum)
 96         {
 97             ulong rg = GetSpecial(rG);
 98             if (regNum >= rg)
 99             {
100                 return globalRegs[regNum];
101             }
102             else
103             {
104                 ulong rl = GetSpecial(rL);
105                 if (regNum >= rl)
106                 {
107                     SetSpecial(rLregNum + 1u);
108                 }
109                 return localRegs[regNum];
110             }
111         }
112         public void Set(byte regNumulong value)
113         {
114             ulong rg = GetSpecial(rG);
115             if (regNum >= rg)
116             {
117                 globalRegs[regNum] = value;
118             }
119             else
120             {
121                 ulong rl = GetSpecial(rL);
122                 if (regNum >= rl)
123                 {
124                     SetSpecial(rLregNum + 1u);
125                 }
126                 localRegs[regNum] = value;
127             }
128         }
129         public ulong GetSpecial(byte regNum)
130         {
131             #assert(regNum >= 0u && regNum < 32u);
132             return globalRegs[regNum];
133         }
134         public void SetSpecial(byte regNumulong value)
135         {
136             #assert(regNum >= 0u && regNum < 32u);
137             globalRegs[regNum] = value;
138         }
139         public string GetSpecialRegName(byte specialReg) const
140         {
141             Map<bytestring>.ConstIterator it = specialRegMap.CFind(specialReg);
142             if (it != specialRegMap.CEnd())
143             {
144                 return it->second;
145             }
146             else
147             {
148                 return string();
149             }
150         }
151         public void SetInterrupt(ulong interruptBit)
152         {
153             LockGuard<Mutex> lock(interruptMutex);
154             ulong rq = GetSpecial(Registers.rQ);
155             rq = rq | interruptBit;
156             SetSpecial(Registers.rQrq);
157         }
158         public void ResetInterrupt(ulong interruptBit)
159         {
160             LockGuard<Mutex> lock(interruptMutex);
161             ulong rq = GetSpecial(Registers.rQ);
162             rq = rq & ~interruptBit;
163             SetSpecial(Registers.rQrq);
164         }
165         public ulong GetInterruptBits()
166         {
167             LockGuard<Mutex> lock(interruptMutex);
168             ulong rq = GetSpecial(Registers.rQ);
169             ulong rk = GetSpecial(Registers.rK);
170             SetSpecial(Registers.rQrq & ~rk);
171             return rq & rk;
172         }
173         public nothrow Mutex& GetInterruptMutex()
174         {
175             return interruptMutex;
176         }
177         public inline nothrow ulong GetPC() const
178         {
179             return pc;
180         }
181         public inline nothrow void SetPC(ulong pc_)
182         {
183             pc = pc_;
184         }
185         public nothrow string ToString() const
186         {
187             string s;
188             s.Append("pc=").Append(ToHexString(pc)).Append("\n");
189             s.Append("sp=").Append(ToHexString(Get(regSP))).Append("\n");
190             s.Append("fp=").Append(ToHexString(Get(regFP))).Append("\n");
191             s.Append("ix=").Append(ToHexString(Get(regIX))).Append("\n");
192             s.Append("ax=").Append(ToHexString(Get(regAX))).Append("\n");
193             s.Append("bx=").Append(ToHexString(Get(regBX))).Append("\n");
194             s.Append("cx=").Append(ToHexString(Get(regCX))).Append("\n");
195             s.Append("dx=").Append(ToHexString(Get(regDX))).Append("\n");
196             s.Append("ex=").Append(ToHexString(Get(regEX))).Append("\n");
197             return s;
198         }
199         private ulong[256] localRegs;
200         private ulong[256] globalRegs;
201         private ulong pc;
202         private Map<bytestring> specialRegMap;
203         private Mutex interruptMutex;
204     }
205 }