OSDN Git Service

[INITIAL] Import 20141226 version of http://homepage3.nifty.com/takeda-toshiya/common...
[csp-qt/common_source_project-fm7.git] / source / src / vm / hc40 / hc40.cpp
1 /*\r
2         EPSON HC-40 Emulator 'eHC-40'\r
3 \r
4         Author : Takeda.Toshiya\r
5         Date   : 2008.02.23 -\r
6 \r
7         [ virtual machine ]\r
8 */\r
9 \r
10 #include "hc40.h"\r
11 #include "../../emu.h"\r
12 #include "../device.h"\r
13 #include "../event.h"\r
14 \r
15 #include "../beep.h"\r
16 #include "../datarec.h"\r
17 #include "../tf20.h"\r
18 #include "../z80.h"\r
19 \r
20 #ifdef USE_DEBUGGER\r
21 #include "../debugger.h"\r
22 #endif\r
23 \r
24 #include "io.h"\r
25 #include "memory.h"\r
26 \r
27 // ----------------------------------------------------------------------------\r
28 // initialize\r
29 // ----------------------------------------------------------------------------\r
30 \r
31 VM::VM(EMU* parent_emu) : emu(parent_emu)\r
32 {\r
33         // create devices\r
34         first_device = last_device = NULL;\r
35         dummy = new DEVICE(this, emu);  // must be 1st device\r
36         event = new EVENT(this, emu);   // must be 2nd device\r
37         \r
38         beep = new BEEP(this, emu);\r
39         drec = new DATAREC(this, emu);\r
40         tf20 = new TF20(this, emu);\r
41         cpu = new Z80(this, emu);\r
42         \r
43         io = new IO(this, emu);\r
44         memory = new MEMORY(this, emu);\r
45         \r
46         // set contexts\r
47         event->set_context_cpu(cpu);\r
48         event->set_context_sound(beep);\r
49         \r
50         drec->set_context_out(io, SIG_IO_DREC, 1);\r
51         tf20->set_context_sio(io, SIG_IO_ART);\r
52         \r
53         io->set_context_cpu(cpu);\r
54         io->set_context_mem(memory, memory->get_ram());\r
55         io->set_context_tf20(tf20);\r
56         io->set_context_beep(beep);\r
57         io->set_context_drec(drec);\r
58         \r
59         // cpu bus\r
60         cpu->set_context_mem(memory);\r
61         cpu->set_context_io(io);\r
62         cpu->set_context_intr(io);\r
63 #ifdef USE_DEBUGGER\r
64         cpu->set_context_debugger(new DEBUGGER(this, emu));\r
65 #endif\r
66         \r
67         // initialize all devices\r
68         for(DEVICE* device = first_device; device; device = device->next_device) {\r
69                 device->initialize();\r
70         }\r
71 }\r
72 \r
73 VM::~VM()\r
74 {\r
75         // delete all devices\r
76         for(DEVICE* device = first_device; device;) {\r
77                 DEVICE *next_device = device->next_device;\r
78                 device->release();\r
79                 delete device;\r
80                 device = next_device;\r
81         }\r
82 }\r
83 \r
84 DEVICE* VM::get_device(int id)\r
85 {\r
86         for(DEVICE* device = first_device; device; device = device->next_device) {\r
87                 if(device->this_device_id == id) {\r
88                         return device;\r
89                 }\r
90         }\r
91         return NULL;\r
92 }\r
93 \r
94 // ----------------------------------------------------------------------------\r
95 // drive virtual machine\r
96 // ----------------------------------------------------------------------------\r
97 \r
98 void VM::reset()\r
99 {\r
100         // reset all devices\r
101         for(DEVICE* device = first_device; device; device = device->next_device) {\r
102                 device->reset();\r
103         }\r
104 }\r
105 \r
106 void VM::special_reset()\r
107 {\r
108         // system reset\r
109         for(DEVICE* device = first_device; device; device = device->next_device) {\r
110                 device->reset();\r
111         }\r
112         io->sysreset();\r
113 }\r
114 \r
115 void VM::run()\r
116 {\r
117         event->drive();\r
118 }\r
119 \r
120 // ----------------------------------------------------------------------------\r
121 // debugger\r
122 // ----------------------------------------------------------------------------\r
123 \r
124 #ifdef USE_DEBUGGER\r
125 DEVICE *VM::get_cpu(int index)\r
126 {\r
127         if(index == 0) {\r
128                 return cpu;\r
129         }\r
130         return NULL;\r
131 }\r
132 #endif\r
133 \r
134 // ----------------------------------------------------------------------------\r
135 // draw screen\r
136 // ----------------------------------------------------------------------------\r
137 \r
138 void VM::draw_screen()\r
139 {\r
140         io->draw_screen();\r
141 }\r
142 \r
143 int VM::access_lamp()\r
144 {\r
145         uint32 status = tf20->read_signal(0);\r
146         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;\r
147 }\r
148 \r
149 // ----------------------------------------------------------------------------\r
150 // soud manager\r
151 // ----------------------------------------------------------------------------\r
152 \r
153 void VM::initialize_sound(int rate, int samples)\r
154 {\r
155         // init sound manager\r
156         event->initialize_sound(rate, samples);\r
157         \r
158         // init sound gen\r
159         beep->init(rate, 1000, 8000);\r
160 }\r
161 \r
162 uint16* VM::create_sound(int* extra_frames)\r
163 {\r
164         return event->create_sound(extra_frames);\r
165 }\r
166 \r
167 int VM::sound_buffer_ptr()\r
168 {\r
169         return event->sound_buffer_ptr();\r
170 }\r
171 \r
172 // ----------------------------------------------------------------------------\r
173 // notify key\r
174 // ----------------------------------------------------------------------------\r
175 \r
176 void VM::key_down(int code, bool repeat)\r
177 {\r
178         io->key_down(code);\r
179 }\r
180 \r
181 void VM::key_up(int code)\r
182 {\r
183         io->key_up(code);\r
184 }\r
185 \r
186 // ----------------------------------------------------------------------------\r
187 // user interface\r
188 // ----------------------------------------------------------------------------\r
189 \r
190 void VM::open_disk(int drv, _TCHAR* file_path, int offset)\r
191 {\r
192         tf20->open_disk(drv, file_path, offset);\r
193 }\r
194 \r
195 void VM::close_disk(int drv)\r
196 {\r
197         tf20->close_disk(drv);\r
198 }\r
199 \r
200 bool VM::disk_inserted(int drv)\r
201 {\r
202         return tf20->disk_inserted(drv);\r
203 }\r
204 \r
205 void VM::play_tape(_TCHAR* file_path)\r
206 {\r
207         drec->play_tape(file_path);\r
208 }\r
209 \r
210 void VM::rec_tape(_TCHAR* file_path)\r
211 {\r
212         drec->rec_tape(file_path);\r
213 }\r
214 \r
215 void VM::close_tape()\r
216 {\r
217         drec->close_tape();\r
218 }\r
219 \r
220 bool VM::tape_inserted()\r
221 {\r
222         return drec->tape_inserted();\r
223 }\r
224 \r
225 bool VM::now_skip()\r
226 {\r
227         return event->now_skip();\r
228 }\r
229 \r
230 void VM::update_config()\r
231 {\r
232         for(DEVICE* device = first_device; device; device = device->next_device) {\r
233                 device->update_config();\r
234         }\r
235 }\r
236 \r