1 /**
2 Copyright: Copyright (c) 2013-2014 Andrey Penechko.
3 License: a$(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 
8 module emulator.dcpu.dcpu;
9 
10 import std.algorithm : fill;
11 
12 import emulator.dcpu.devices.idevice;
13 import emulator.dcpu.updatequeue;
14 import emulator.utils.ringbuffer;
15 import emulator.utils.undoproxy;
16 
17 @safe:
18 
19 struct DcpuRegisters
20 {
21 	union
22 	{
23 		ushort[12] array;
24 		struct
25 		{
26 			ushort a;  //0
27 			ushort b;  //1
28 			ushort c;  //2
29 			ushort x;  //3
30 			ushort y;  //4
31 			ushort z;  //5
32 			ushort i;  //6
33 			ushort j;  //7
34 			ushort sp; //8
35 			ushort pc; //9
36 			ushort ex; //10
37 			ushort ia; //11
38 		}
39 	}
40 
41 	ulong cycles; /// cycles done by DCPU.
42 	ulong instructions; /// instructions done by DCPU.
43 
44 	bool queueInterrupts = false;
45 }
46 
47 struct DcpuMemory
48 {
49 	ushort[0x10000] mem;
50 }
51 
52 struct Dcpu
53 {
54 	UndoableStruct!(DcpuRegisters, ushort) regs;
55 	UndoableStruct!(DcpuMemory, ushort) mem;
56 
57 	uint clockSpeed = 100_000; //Hz
58 
59 	RingBuffer!(ushort, 256) intQueue;
60 	UpdateQueue!Dcpu* updateQueue;
61 	IDevice!Dcpu[ushort] devices;
62 	private ushort nextHardwareId = 0;
63 
64 	bool isBurning = false;
65 	bool isRunning = false;
66 
67 	size_t imageSize;
68 
69 	ushort numDevices() @property @trusted
70 	{
71 		return cast(ushort)devices.length;
72 	}
73 
74 	ushort attachDevice(IDevice!Dcpu device) // TODO: checks
75 	{
76 		devices[nextHardwareId] = device;
77 		return nextHardwareId++;
78 	}
79 
80 	void reset()
81 	{
82 		regs.reset();
83 		mem.reset();
84 
85 		intQueue.clear();
86 
87 		devices = null;
88 		nextHardwareId = 0;
89 
90 		isBurning = false;
91 		updateQueue.queries = null;
92 	}
93 }
94