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
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(rL, regNum + 1u);
108 }
109 return localRegs[regNum];
110 }
111 }
112 public void Set(byte regNum, ulong 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(rL, regNum + 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 regNum, ulong value)
135 {
136 #assert(regNum >= 0u && regNum < 32u);
137 globalRegs[regNum] = value;
138 }
139 public string GetSpecialRegName(byte specialReg) const
140 {
141 Map<byte, string>.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.rQ, rq);
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.rQ, rq);
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.rQ, rq & ~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<byte, string> specialRegMap;
203 private Mutex interruptMutex;
204 }
205 }