OSDN Git Service

[VM] Add vm_template.h . This class, VM_TEMPLATE:: must be mother of VM:: .See fm7...
[csp-qt/common_source_project-fm7.git] / source / src / vm / libcpu_newdev / device.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : Takeda.Toshiya
5         Date   : 2006.08.18 -
6
7         [ device base class ]
8 */
9
10 #include "common.h"
11 #include "../vm.h"
12 #include "../..//emu.h"
13 #include "device.h"
14 #if defined(_USE_QT)
15 #include "../qt/gui/csp_logger.h"
16 extern CSP_Logger *csp_logger;
17 #endif
18
19 DEVICE::DEVICE(VM_TEMPLATE* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu)
20 {
21         vm = parent_vm;
22         emu = parent_emu;
23
24         osd = emu->get_osd();
25 #if defined(_USE_QT)
26         p_logger = csp_logger;
27         state_entry = NULL;
28 #endif  
29         memset(this_device_name, 0x00, sizeof(this_device_name));
30         strncpy(this_device_name, "Base Device", 128 - 1);
31         prev_device = vm->last_device;
32         next_device = NULL;
33         if(vm->first_device == NULL) {
34                 // this is the first device
35                 vm->first_device = this;
36                 this_device_id = 0;
37         } else {
38                 // this is not the first device
39                 vm->last_device->next_device = this;
40                 this_device_id = vm->last_device->this_device_id + 1;
41         }
42         vm->last_device = this;
43         
44         // primary event manager
45         event_manager = NULL;
46 }
47
48 //DEVICE::~DEVICE(void)
49 //{
50 //}
51
52
53 void DEVICE::release()
54 {
55         if(state_entry != NULL) delete state_entry;
56         state_entry = NULL;
57 }
58
59 uint32_t DEVICE::read_io8(uint32_t addr)
60 {
61 #ifdef IOBUS_RETURN_ADDR
62                 return (addr & 1 ? addr >> 8 : addr) & 0xff;
63 #else
64                 return 0xff;
65 #endif
66 }
67
68 int DEVICE::get_event_manager_id()
69 {
70         if(event_manager == NULL) {
71                 event_manager = vm->first_device->next_device;
72         }
73         return event_manager->this_device_id;
74 }
75 void DEVICE::register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id)
76 {
77         if(event_manager == NULL) {
78                 event_manager = vm->first_device->next_device;
79         }
80         event_manager->register_event(device, event_id, usec, loop, register_id);
81 }
82
83 void DEVICE::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id)
84 {
85         if(event_manager == NULL) {
86                 event_manager = vm->first_device->next_device;
87         }
88         event_manager->register_event_by_clock(device, event_id, clock, loop, register_id);
89 }
90
91 void DEVICE::cancel_event(DEVICE* device, int register_id)
92 {
93         if(event_manager == NULL) {
94                 event_manager = vm->first_device->next_device;
95         }
96         event_manager->cancel_event(device, register_id);
97 }
98 void DEVICE::register_frame_event(DEVICE* device)
99 {
100         if(event_manager == NULL) {
101                 event_manager = vm->first_device->next_device;
102         }
103         event_manager->register_frame_event(device);
104 }
105 void DEVICE::register_vline_event(DEVICE* device)
106 {
107         if(event_manager == NULL) {
108                 event_manager = vm->first_device->next_device;
109         }
110         event_manager->register_vline_event(device);
111 }
112 uint32_t DEVICE::get_event_remaining_clock(int register_id)
113 {
114         if(event_manager == NULL) {
115                 event_manager = vm->first_device->next_device;
116         }
117         return event_manager->get_event_remaining_clock(register_id);
118 }
119
120 double DEVICE::get_event_remaining_usec(int register_id)
121 {
122         if(event_manager == NULL) {
123                 event_manager = vm->first_device->next_device;
124         }
125         return event_manager->get_event_remaining_usec(register_id);
126 }
127
128 uint32_t DEVICE::get_current_clock()
129 {
130         if(event_manager == NULL) {
131                 event_manager = vm->first_device->next_device;
132         }
133         return event_manager->get_current_clock();
134 }
135
136 uint32_t DEVICE::get_passed_clock(uint32_t prev)
137 {
138         if(event_manager == NULL) {
139                 event_manager = vm->first_device->next_device;
140         }
141         return event_manager->get_passed_clock(prev);
142 }
143
144 double DEVICE::get_passed_usec(uint32_t prev)
145 {
146         if(event_manager == NULL) {
147                 event_manager = vm->first_device->next_device;
148         }
149         return event_manager->get_passed_usec(prev);
150 }
151
152 uint32_t DEVICE::get_passed_clock_since_vline()
153 {
154         if(event_manager == NULL) {
155                 event_manager = vm->first_device->next_device;
156         }
157         return event_manager->get_passed_clock_since_vline();
158 }
159
160 double DEVICE::get_passed_usec_since_vline()
161 {
162         if(event_manager == NULL) {
163                 event_manager = vm->first_device->next_device;
164         }
165         return event_manager->get_passed_usec_since_vline();
166 }
167
168 int DEVICE::get_cur_vline()
169 {
170         if(event_manager == NULL) {
171                 event_manager = vm->first_device->next_device;
172         }
173         return event_manager->get_cur_vline();
174 }
175
176 int DEVICE::get_cur_vline_clocks()
177 {
178         if(event_manager == NULL) {
179                 event_manager = vm->first_device->next_device;
180         }
181         return event_manager->get_cur_vline_clocks();
182 }
183
184 uint32_t DEVICE::get_cpu_pc(int index)
185 {
186         if(event_manager == NULL) {
187                 event_manager = vm->first_device->next_device;
188         }
189         return event_manager->get_cpu_pc(index);
190 }
191
192 void DEVICE::request_skip_frames()
193 {
194         if(event_manager == NULL) {
195                 event_manager = vm->first_device->next_device;
196         }
197         event_manager->request_skip_frames();
198 }
199
200 void DEVICE::set_frames_per_sec(double frames)
201 {
202         if(event_manager == NULL) {
203                 event_manager = vm->first_device->next_device;
204         }
205         event_manager->set_frames_per_sec(frames);
206 }
207
208 void DEVICE::set_lines_per_frame(int lines)
209 {
210                 if(event_manager == NULL) {
211                         event_manager = vm->first_device->next_device;
212                 }
213                 event_manager->set_lines_per_frame(lines);
214 }
215
216 int DEVICE::get_lines_per_frame()
217 {
218         if(event_manager == NULL) {
219                 event_manager = vm->first_device->next_device;
220         }
221         return event_manager->get_lines_per_frame();
222 }
223
224 #include "../../statesub.h"
225
226 void DEVICE::decl_state()
227 {
228         state_entry = new csp_state_utils(1, this_device_id, (const _TCHAR *)this_device_name, p_logger);
229 }
230
231 void DEVICE::enter_decl_state(int version)
232 {
233         state_entry = new csp_state_utils(version, this_device_id, (const _TCHAR *)this_device_name, p_logger);
234 }
235
236 void DEVICE::enter_decl_state(int version, _TCHAR *name)
237 {
238         state_entry = new csp_state_utils(version, this_device_id, (const _TCHAR *)name, p_logger);
239 }
240
241 void DEVICE::leave_decl_state()
242 {
243 }
244 // Force render sound immediately when device's status has changed.
245 // You must call this after you changing registers (or anything).
246 // If has problems, try set_realtime_render.
247 // See mb8877.cpp and ym2203.cpp. 
248 // -- 20161010 K.O
249 void DEVICE::touch_sound(void)
250 {
251         if(event_manager == NULL) {
252                 event_manager = vm->first_device->next_device;
253         }
254         event_manager->touch_sound();
255 }
256 // Force render per 1 sample automatically.
257 // See pcm1bit.cpp .
258 // -- 20161010 K.O
259 void DEVICE::set_realtime_render(DEVICE *device, bool flag)
260 {
261         if(event_manager == NULL) {
262                 event_manager = vm->first_device->next_device;
263         }
264         if(device != event_manager) event_manager->set_realtime_render(device, flag);
265 }
266
267 void DEVICE::set_device_name(const _TCHAR *format, ...)
268 {
269         if(format != NULL) {
270                 va_list ap;
271                 _TCHAR buffer[1024];
272                 
273                 va_start(ap, format);
274                 my_vstprintf_s(buffer, 1024, format, ap);
275                 va_end(ap);
276
277                 my_tcscpy_s(this_device_name, 128, buffer);
278 #ifdef _USE_QT
279                 emu->get_osd()->set_vm_node(this_device_id, buffer);
280 #endif
281         }
282 }
283
284 void DEVICE::out_debug_log(const char *fmt, ...)
285 {
286 #if defined(_USE_QT)
287         if(p_logger == NULL) return;
288         char strbuf[4096];
289         va_list ap;
290         
291         va_start(ap, fmt);
292         vsnprintf(strbuf, 4095, fmt, ap);
293         p_logger->debug_log(CSP_LOG_DEBUG, this_device_id + CSP_LOG_TYPE_VM_DEVICE_0, "%s", strbuf);
294         va_end(ap);
295 #else
296         char strbuf[4096];
297         va_list ap;
298
299         va_start(ap, fmt);
300         vsnprintf(strbuf, 4095, fmt, ap);
301         emu->out_debug_log("%s", strbuf);
302         va_end(ap);
303 #endif
304 }
305
306 void DEVICE::force_out_debug_log(const char *fmt, ...)
307 {
308         char strbuf[4096];
309         va_list ap;
310
311         va_start(ap, fmt);
312         vsnprintf(strbuf, 4095, fmt, ap);
313         emu->force_out_debug_log("%s", strbuf);
314         va_end(ap);
315 }
316
317 // debugger
318 void *DEVICE::get_debugger()
319 {
320         return NULL;
321 }
322 uint32_t DEVICE::get_debug_prog_addr_mask()
323 {
324         return 0;
325 }
326
327 uint32_t DEVICE::get_debug_data_addr_mask()
328 {
329         return 0;
330 }
331
332 void DEVICE::write_debug_data8(uint32_t addr, uint32_t data)
333 {
334 }
335
336 uint32_t DEVICE::read_debug_data8(uint32_t addr)
337 {
338         return 0xff;
339 }
340
341 void DEVICE::write_debug_data16(uint32_t addr, uint32_t data)
342 {
343         write_debug_data8(addr, data & 0xff);
344         write_debug_data8(addr + 1, (data >> 8) & 0xff);
345 }
346
347 uint32_t DEVICE::read_debug_data16(uint32_t addr)
348 {
349                 uint32_t val = read_debug_data8(addr);
350                 val |= read_debug_data8(addr + 1) << 8;
351                 return val;
352 }
353
354 void DEVICE::write_debug_data32(uint32_t addr, uint32_t data)
355 {
356         write_debug_data16(addr, data & 0xffff);
357         write_debug_data16(addr + 2, (data >> 16) & 0xffff);
358 }
359
360 uint32_t DEVICE::read_debug_data32(uint32_t addr)
361 {
362         uint32_t val = read_debug_data16(addr);
363         val |= read_debug_data16(addr + 2) << 16;
364         return val;
365 }
366
367 void DEVICE::write_debug_io8(uint32_t addr, uint32_t data)
368 {
369 }
370
371 uint32_t DEVICE::read_debug_io8(uint32_t addr)
372 {
373         return 0xff;
374 }
375 void DEVICE::write_debug_io16(uint32_t addr, uint32_t data)
376 {
377         write_debug_io8(addr, data & 0xff);
378         write_debug_io8(addr + 1, (data >> 8) & 0xff);
379 }
380
381 uint32_t DEVICE::read_debug_io16(uint32_t addr)
382 {
383         uint32_t val = read_debug_io8(addr);
384         val |= read_debug_io8(addr + 1) << 8;
385         return val;
386 }
387
388 void DEVICE::write_debug_io32(uint32_t addr, uint32_t data)
389 {
390         write_debug_io16(addr, data & 0xffff);
391         write_debug_io16(addr + 2, (data >> 16) & 0xffff);
392 }
393
394 uint32_t DEVICE::read_debug_io32(uint32_t addr)
395 {
396         uint32_t val = read_debug_io16(addr);
397         val |= read_debug_io16(addr + 2) << 16;
398         return val;
399 }
400
401 bool DEVICE::write_debug_reg(const _TCHAR *reg, uint32_t data)
402 {
403         return false;
404 }
405
406 void DEVICE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
407 {
408 }
409
410 int DEVICE::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
411 {
412         return 0;
413 }
414