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