1 using System;
2 using System.Collections;
3
4 namespace cmsx.machine
5 {
6 public delegate void KernelShutdownFunc();
7
8 private KernelShutdownFunc kernelShutdownFunc;
9
10 public nothrow void SetKernelShutdownFunc(KernelShutdownFunc kernelShutdownFunc_)
11 {
12 kernelShutdownFunc = kernelShutdownFunc_;
13 }
14
15 private bool panicThrows = true;
16
17 public nothrow bool PanicThrows()
18 {
19 return panicThrows;
20 }
21
22 public void Panic(const string& message)
23 {
24 if (PanicThrows())
25 {
26 Clock.Instance().Stop();
27 if (cast<void*>(kernelShutdownFunc) != null)
28 {
29 kernelShutdownFunc();
30 }
31 throw Exception(message);
32 }
33 else
34 {
35 System.Console.WriteLine(message);
36 }
37 }
38
39 public class Machine
40 {
41 public enum Flags : byte
42 {
43 none = 0u,
44 verbose = 1u << 0u,
45 quiet = 1u << 1u,
46 debug = 1u << 2u,
47 runProgram = 1u << 3u,
48 install = 1u << 4u,
49 followExec = 1u << 5u,
50 sleepingWrite = 1u << 6u,
51 noReadahead = 1u << 7u
52 }
53 public static inline nothrow void SetFlag(Flags flag)
54 {
55 flags = cast<Flags>(flags | flag);
56 }
57 public static inline nothrow bool GetFlag(Flags flag)
58 {
59 return (flags & flag) != Flags.none;
60 }
61 public static inline nothrow void ResetFlag(Flags flag)
62 {
63 flags = cast<Flags>(flags & ~flag);
64 }
65 static Machine() : instance(new Machine())
66 {
67 }
68 suppress Machine(const Machine&);
69 suppress Machine(Machine&&);
70 suppress void operator=(const Machine&);
71 suppress void operator=(Machine&&);
72 public static nothrow Machine& Instance()
73 {
74 return *instance;
75 }
76 public void Run()
77 {
78 processor.Run();
79 }
80 public void Exit()
81 {
82 processor.Exit();
83 }
84 public void SetException(const ExceptionPtr& ex)
85 {
86 exceptionPtr = ex;
87 }
88 public ExceptionPtr GetException()
89 {
90 return exceptionPtr;
91 }
92 public inline nothrow Memory& GetMemory()
93 {
94 return memory;
95 }
96 public inline nothrow Processor& GetProcessor()
97 {
98 return processor;
99 }
100 public inline nothrow Registers& GetRegisters()
101 {
102 return processor.GetRegisters();
103 }
104 private Machine() : processor(*this), memory(*this)
105 {
106 InitInsts();
107 AddInst(new Trap());
108 AddInst(new Swym());
109 AddInst(new Ldb());
110 AddInst(new Ldbi());
111 AddInst(new Ldw());
112 AddInst(new Ldwi());
113 AddInst(new Ldt());
114 AddInst(new Ldti());
115 AddInst(new Ldo());
116 AddInst(new Ldoi());
117 AddInst(new Ldbu());
118 AddInst(new Ldbui());
119 AddInst(new Ldwu());
120 AddInst(new Ldwui());
121 AddInst(new Ldtu());
122 AddInst(new Ldtui());
123 AddInst(new Ldou());
124 AddInst(new Ldoui());
125 AddInst(new Ldht());
126 AddInst(new Ldhti());
127 AddInst(new Ldsf());
128 AddInst(new Ldsfi());
129 AddInst(new Stb());
130 AddInst(new Stbi());
131 AddInst(new Stw());
132 AddInst(new Stwi());
133 AddInst(new Stt());
134 AddInst(new Stti());
135 AddInst(new Sto());
136 AddInst(new Stoi());
137 AddInst(new Stbu());
138 AddInst(new Stbui());
139 AddInst(new Stwu());
140 AddInst(new Stwui());
141 AddInst(new Sttu());
142 AddInst(new Sttui());
143 AddInst(new Stou());
144 AddInst(new Stoui());
145 AddInst(new Stht());
146 AddInst(new Sthti());
147 AddInst(new Stsf());
148 AddInst(new Stsfi());
149 AddInst(new Stco());
150 AddInst(new Stcoi());
151 AddInst(new Add());
152 AddInst(new Addi());
153 AddInst(new Sub());
154 AddInst(new Subi());
155 AddInst(new Mul());
156 AddInst(new Muli());
157 AddInst(new Div());
158 AddInst(new Divi());
159 AddInst(new Addu());
160 AddInst(new Addui());
161 AddInst(new Subu());
162 AddInst(new Subui());
163 AddInst(new Mulu());
164 AddInst(new Mului());
165 AddInst(new Divu());
166 AddInst(new Divui());
167 AddInst(new I2Addu());
168 AddInst(new I2Addui());
169 AddInst(new I4Addu());
170 AddInst(new I4Addui());
171 AddInst(new I8Addu());
172 AddInst(new I8Addui());
173 AddInst(new I16Addu());
174 AddInst(new I16Addui());
175 AddInst(new Neg());
176 AddInst(new Negi());
177 AddInst(new Negu());
178 AddInst(new Negui());
179 AddInst(new Sl());
180 AddInst(new Sli());
181 AddInst(new Slu());
182 AddInst(new Slui());
183 AddInst(new Sr());
184 AddInst(new Sri());
185 AddInst(new Sru());
186 AddInst(new Srui());
187 AddInst(new Cmp());
188 AddInst(new Cmpi());
189 AddInst(new Cmpu());
190 AddInst(new Cmpui());
191 AddInst(new Csn());
192 AddInst(new Csni());
193 AddInst(new Csz());
194 AddInst(new Cszi());
195 AddInst(new Csp());
196 AddInst(new Cspi());
197 AddInst(new Csod());
198 AddInst(new Csodi());
199 AddInst(new Csnn());
200 AddInst(new Csnni());
201 AddInst(new Csnz());
202 AddInst(new Csnzi());
203 AddInst(new Csnp());
204 AddInst(new Csnpi());
205 AddInst(new Csev());
206 AddInst(new Csevi());
207 AddInst(new Zsn());
208 AddInst(new Zsni());
209 AddInst(new Zsz());
210 AddInst(new Zszi());
211 AddInst(new Zsp());
212 AddInst(new Zspi());
213 AddInst(new Zsod());
214 AddInst(new Zsodi());
215 AddInst(new Zsnn());
216 AddInst(new Zsnni());
217 AddInst(new Zsnz());
218 AddInst(new Zsnzi());
219 AddInst(new Zsnp());
220 AddInst(new Zsnpi());
221 AddInst(new Zsev());
222 AddInst(new Zsevi());
223 AddInst(new And());
224 AddInst(new Andi());
225 AddInst(new Or());
226 AddInst(new Ori());
227 AddInst(new Xor());
228 AddInst(new Xori());
229 AddInst(new Andn());
230 AddInst(new Andni());
231 AddInst(new Orn());
232 AddInst(new Orni());
233 AddInst(new Nand());
234 AddInst(new Nandi());
235 AddInst(new Nor());
236 AddInst(new Nori());
237 AddInst(new Nxor());
238 AddInst(new Nxori());
239 AddInst(new Mux());
240 AddInst(new Muxi());
241 AddInst(new Sadd());
242 AddInst(new Saddi());
243 AddInst(new Bdif());
244 AddInst(new Bdifi());
245 AddInst(new Wdif());
246 AddInst(new Wdifi());
247 AddInst(new Tdif());
248 AddInst(new Tdifi());
249 AddInst(new Odif());
250 AddInst(new Odifi());
251 AddInst(new Fadd());
252 AddInst(new Fsub());
253 AddInst(new Fmul());
254 AddInst(new Fdiv());
255 AddInst(new Fint());
256 AddInst(new Fcmp());
257 AddInst(new Fix());
258 AddInst(new Fixu());
259 AddInst(new Flot());
260 AddInst(new SFlot());
261 AddInst(new Floti());
262 AddInst(new SFloti());
263 AddInst(new Flotu());
264 AddInst(new SFlotu());
265 AddInst(new Flotui());
266 AddInst(new SFlotui());
267 AddInst(new Seth());
268 AddInst(new Setmh());
269 AddInst(new Setml());
270 AddInst(new Setl());
271 AddInst(new Inch());
272 AddInst(new Incmh());
273 AddInst(new Incml());
274 AddInst(new Incl());
275 AddInst(new Orh());
276 AddInst(new Ormh());
277 AddInst(new Orml());
278 AddInst(new Orl());
279 AddInst(new Andnh());
280 AddInst(new Andnmh());
281 AddInst(new Andnml());
282 AddInst(new Andnl());
283 AddInst(new Jmp());
284 AddInst(new Jmpb());
285 AddInst(new Go());
286 AddInst(new Goi());
287 AddInst(new Call());
288 AddInst(new Calli());
289 AddInst(new Ret());
290 AddInst(new Swym());
291 AddInst(new Bn());
292 AddInst(new Bnb());
293 AddInst(new Bz());
294 AddInst(new Bzb());
295 AddInst(new Bp());
296 AddInst(new Bpb());
297 AddInst(new Bod());
298 AddInst(new Bodb());
299 AddInst(new Bnn());
300 AddInst(new Bnnb());
301 AddInst(new Bnz());
302 AddInst(new Bnzb());
303 AddInst(new Bnp());
304 AddInst(new Bnpb());
305 AddInst(new Bev());
306 AddInst(new Bevb());
307 AddInst(new Pbn());
308 AddInst(new Pbnb());
309 AddInst(new Pbz());
310 AddInst(new Pbzb());
311 AddInst(new Pbp());
312 AddInst(new Pbpb());
313 AddInst(new Pbod());
314 AddInst(new Pbodb());
315 AddInst(new Pbnn());
316 AddInst(new Pbnnb());
317 AddInst(new Pbnz());
318 AddInst(new Pbnzb());
319 AddInst(new Pbnp());
320 AddInst(new Pbnpb());
321 AddInst(new Pbev());
322 AddInst(new Pbevb());
323 AddInst(new Get());
324 AddInst(new Put());
325 AddInst(new GetA());
326 AddInst(new GetAb());
327 }
328 public inline nothrow Instruction* GetInst(byte opCode) const
329 {
330 return instructions[opCode];
331 }
332 public nothrow ulong GetKernelRootPageAddress() const
333 {
334 return kernelRootPageAddress;
335 }
336 public nothrow void SetKernelRootPageAddress(ulong kernelRootPageAddress_)
337 {
338 kernelRootPageAddress = kernelRootPageAddress_;
339 }
340 private void InitInsts()
341 {
342 instructionList.Resize(256);
343 for (int i = 0; i < 256; ++i;)
344 {
345 byte opCode = cast<byte>(i);
346 AddInst(new Instruction(opCode));
347 }
348 }
349 private void AddInst(Instruction* inst)
350 {
351 instructionList[inst->opCode].Reset(inst);
352 instructions[inst->opCode] = inst;
353 }
354 private static UniquePtr<Machine> instance;
355 private static Flags flags;
356 private List<UniquePtr<Instruction>> instructionList;
357 private Instruction*[256] instructions;
358 private Processor processor;
359 private Memory memory;
360 private ulong kernelRootPageAddress;
361 private ExceptionPtr exceptionPtr;
362 }
363
364 public Machine& GetMachine()
365 {
366 return Machine.Instance();
367 }
368 }