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 }