1 /**
2  * DCPU-16 computer hardware
3  *
4  * See_Also:
5  *  http://pastebin.com/raw.php?i=Q4JvQvnM
6  */
7 module dcpu.hardware;
8 
9 /+
10 public import dcpu.machine, dcpu.cpu;
11 
12 abstract class Hardware {
13 private:
14   long n_bus_ticks_60hz;/// Number of bus clock ticks need to do a event at 60Hz
15   bool f_floor_ceil;    /// do floor or ceil to calc n_bus_ticks
16   long count_ticks;     /// Count bus clock ticks
17   
18 protected:
19   bool f_hwi;           /// Has at least one time receive a hardware interrupt
20   static enum BaseFreq = 60; // Base frecuency
21   
22   static uint id;        /// Hardware ID
23   static ushort ver;     /// Hardware Version
24   static uint vendor;    /// Hardware manufacturer
25 
26 public:
27   
28   /**
29    * Sets Hardware ID, version and vendor
30    * It must be override by new hardware
31    */
32   static this() {
33     id     = 0;
34     ver    = 0;
35     vendor = 0;
36   }
37 
38   /// Returns the LSB from Device ID
39   static ushort id_lsb () @property {
40     return cast(ushort)(id & 0xFFFF);
41   }
42 
43   /// Returns the MSB from Device ID
44   static ushort id_msb () @property {
45     return cast(ushort)(id >> 16);
46   }
47 
48   /// Returns the LSB from Device Vendor
49   static ushort vendor_lsb () @property {
50     return cast(ushort)(vendor & 0xFFFF);
51   }
52 
53   /// Returns the MSB from Device Vendor
54   static ushort vendor_msb () @property {
55     return cast(ushort)(vendor >> 16);
56   }
57 
58   /// Returns the Device Version
59   static ushort dev_ver() @property {
60     return ver;
61   }
62 
63   /**
64    * What to do when the emulation start
65    */
66   void init() {
67     f_hwi = false;
68   }
69 
70   /**
71    * What to do when the emualtion end
72    */
73   void end() {
74     
75   }
76 
77   /**
78    * What to do when a Hardware interrupt to this hardware, has receive
79    * Params:
80    *  state   = CPU editable actual state
81    *  ram     = RAM of the machine
82    */
83   void interrupt(ref CpuInfo state, ref ushort[0x10000] ram) {
84     f_hwi = true;
85   }
86 
87   /**
88    * What to do each bus clock tick (at 100 khz)
89    * Params:
90    *  state   = CPU editable actual state
91    *  cpu     = CPU
92    *  ram     = RAM of the machine
93    */
94   void bus_clock_tick(ref CpuInfo state, ref DCpu cpu, ref ushort[0x10000] ram) {
95     import std.math;
96     debug {
97       import std.stdio;
98     }
99     if (f_hwi) {
100       debug {
101         stderr.writeln("Bus Tick: ",count_ticks);
102       }
103       if (++count_ticks >= n_bus_ticks_60hz) { // Do 60Hz tick event
104         if (f_floor_ceil) { // Round up or down to try be more acurrate to 60Hz (aprox 60,006hz)
105           n_bus_ticks_60hz = cast(long)floor(100000.0 / BaseFreq);
106         } else {
107           n_bus_ticks_60hz = cast(long)ceil(100000.0 / BaseFreq);
108         }
109         f_floor_ceil = !f_floor_ceil;
110         tick_60hz(state, cpu, ram);
111         count_ticks = 0;
112       }
113     }
114   }
115 
116   /**
117    * What to do each clock tick (at 60 hz)
118    * Params:
119    *  state   = CPU editable actual state
120    *  cpu     = CPU
121    *  ram     = RAM of the machine
122    */
123   void tick_60hz(ref CpuInfo state, ref DCpu cpu, ref ushort[0x10000] ram) {
124     
125   }
126 
127   
128 }
129 +/
130