OSDN Git Service

[VM][EVENT][DEVICE] Add new APIs for recording sound.
[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 DLL_PREFIX_I 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 #endif  
28         memset(this_device_name, 0x00, sizeof(this_device_name));
29         strncpy(this_device_name, "Base Device", 128 - 1);
30         prev_device = vm->last_device;
31         next_device = NULL;
32         if(vm->first_device == NULL) {
33                 // this is the first device
34                 vm->first_device = this;
35                 this_device_id = 0;
36         } else {
37                 // this is not the first device
38                 vm->last_device->next_device = this;
39                 this_device_id = vm->last_device->this_device_id + 1;
40         }
41         vm->last_device = this;
42         
43         // primary event manager
44         event_manager = NULL;
45 }
46
47 //DEVICE::~DEVICE(void)
48 //{
49 //}
50
51
52 void DEVICE::release()
53 {
54 }
55
56 uint32_t DEVICE::read_io8(uint32_t addr)
57 {
58 #ifdef IOBUS_RETURN_ADDR
59                 return (addr & 1 ? addr >> 8 : addr) & 0xff;
60 #else
61                 return 0xff;
62 #endif
63 }
64
65
66 // Sound input functions
67
68 void DEVICE::clear_sound_in_source(int bank)
69 {
70         if(event_manager == NULL) {
71                 event_manager = vm->first_device->next_device;
72         }
73         event_manager->clear_sound_in_source(bank);
74 }
75
76 // this function may be before (or after) initialize().
77 int DEVICE::add_sound_in_source(int rate, int samples, int channels)
78 {
79         if(event_manager == NULL) return -1;
80         return event_manager->add_sound_in_source(rate, samples, channels);
81 }
82
83 // this function may be before (or after) initialize().
84 int DEVICE::release_sound_in_source(int bank)
85 {
86         if(event_manager == NULL) return -1;
87         return event_manager->release_sound_in_source(bank);
88 }
89         
90 bool DEVICE::is_sound_in_source_exists(int bank)
91 {
92         if(event_manager == NULL) {
93                 event_manager = vm->first_device->next_device;
94         }
95         return event_manager->is_sound_in_source_exists(bank);
96 }
97
98 int DEVICE::increment_sound_in_passed_data(int bank, double passed_usec)
99 {
100         if(event_manager == NULL) {
101                 return 0;
102         }
103         return event_manager->increment_sound_in_passed_data(bank, passed_usec);
104 }
105
106 int DEVICE::get_sound_in_buffers_count()
107 {
108         if(event_manager == NULL) {
109                 event_manager = vm->first_device->next_device;
110         }
111         return event_manager->get_sound_in_buffers_count();
112 }
113
114 int DEVICE::get_sound_in_samples(int bank)
115 {
116         if(event_manager == NULL) {
117                 event_manager = vm->first_device->next_device;
118         }
119         return event_manager->get_sound_in_samples(bank);
120 }
121
122 int DEVICE::get_sound_in_rate(int bank)
123 {
124         if(event_manager == NULL) {
125                 event_manager = vm->first_device->next_device;
126         }
127         return event_manager->get_sound_in_rate(bank);
128 }
129
130 int DEVICE::get_sound_in_channels(int bank)
131 {
132         if(event_manager == NULL) {
133                 event_manager = vm->first_device->next_device;
134         }
135         return event_manager->get_sound_in_channels(bank);
136 }
137
138 // this function may be before (or after) initialize().
139 int16_t* DEVICE::get_sound_in_buf_ptr(int bank)
140 {
141         if(event_manager == NULL) return NULL;
142         return event_manager->get_sound_in_buf_ptr(bank);
143 }
144
145 int DEVICE::write_sound_in_buffer(int bank, int32_t* src, int samples)
146 {
147         if(event_manager == NULL) {
148                 event_manager = vm->first_device->next_device;
149         }
150         return event_manager->write_sound_in_buffer(bank, src, samples);
151 }
152
153 // Add sampled values to sample buffer;value may be -32768 to +32767.
154 // this function may be before (or after) initialize().
155 int DEVICE::get_sound_in_latest_data(int bank, int32_t* dst, int expect_channels)
156 {
157         if(event_manager == NULL) return 0;
158         return event_manager->get_sound_in_latest_data(bank, dst, expect_channels);
159 }
160
161 int DEVICE::get_sound_in_data(int bank, int32_t* dst, int expect_samples, int expect_rate, int expect_channels)
162 {
163         if(event_manager == NULL) return -1;
164         return event_manager->get_sound_in_data(bank, dst, expect_samples, expect_rate, expect_channels);
165 }
166
167 int DEVICE::get_event_manager_id()
168 {
169         if(event_manager == NULL) {
170                 event_manager = vm->first_device->next_device;
171         }
172         return event_manager->this_device_id;
173 }
174 bool DEVICE::is_primary_cpu(DEVICE* device)
175 {
176         if(event_manager == NULL) {
177                 event_manager = vm->first_device->next_device;
178         }
179         return event_manager->is_primary_cpu(device);
180 }
181 void DEVICE::update_extra_event(int clock)
182 {
183         if(event_manager == NULL) {
184                 event_manager = vm->first_device->next_device;
185         }
186         event_manager->update_extra_event(clock);
187 }
188 void DEVICE::register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id)
189 {
190         if(event_manager == NULL) {
191                 event_manager = vm->first_device->next_device;
192         }
193         event_manager->register_event(device, event_id, usec, loop, register_id);
194 }
195
196 void DEVICE::register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id)
197 {
198         if(event_manager == NULL) {
199                 event_manager = vm->first_device->next_device;
200         }
201         event_manager->register_event_by_clock(device, event_id, clock, loop, register_id);
202 }
203
204 void DEVICE::cancel_event(DEVICE* device, int register_id)
205 {
206         if(event_manager == NULL) {
207                 event_manager = vm->first_device->next_device;
208         }
209         event_manager->cancel_event(device, register_id);
210 }
211 void DEVICE::register_frame_event(DEVICE* device)
212 {
213         if(event_manager == NULL) {
214                 event_manager = vm->first_device->next_device;
215         }
216         event_manager->register_frame_event(device);
217 }
218 void DEVICE::register_vline_event(DEVICE* device)
219 {
220         if(event_manager == NULL) {
221                 event_manager = vm->first_device->next_device;
222         }
223         event_manager->register_vline_event(device);
224 }
225 uint32_t DEVICE::get_event_remaining_clock(int register_id)
226 {
227         if(event_manager == NULL) {
228                 event_manager = vm->first_device->next_device;
229         }
230         return event_manager->get_event_remaining_clock(register_id);
231 }
232
233 double DEVICE::get_event_remaining_usec(int register_id)
234 {
235         if(event_manager == NULL) {
236                 event_manager = vm->first_device->next_device;
237         }
238         return event_manager->get_event_remaining_usec(register_id);
239 }
240
241 uint32_t DEVICE::get_current_clock()
242 {
243         if(event_manager == NULL) {
244                 event_manager = vm->first_device->next_device;
245         }
246         return event_manager->get_current_clock();
247 }
248
249 uint32_t DEVICE::get_passed_clock(uint32_t prev)
250 {
251         if(event_manager == NULL) {
252                 event_manager = vm->first_device->next_device;
253         }
254         return event_manager->get_passed_clock(prev);
255 }
256
257 double DEVICE::get_passed_usec(uint32_t prev)
258 {
259         if(event_manager == NULL) {
260                 event_manager = vm->first_device->next_device;
261         }
262         return event_manager->get_passed_usec(prev);
263 }
264
265 uint32_t DEVICE::get_passed_clock_since_vline()
266 {
267         if(event_manager == NULL) {
268                 event_manager = vm->first_device->next_device;
269         }
270         return event_manager->get_passed_clock_since_vline();
271 }
272
273 double DEVICE::get_passed_usec_since_vline()
274 {
275         if(event_manager == NULL) {
276                 event_manager = vm->first_device->next_device;
277         }
278         return event_manager->get_passed_usec_since_vline();
279 }
280
281 int DEVICE::get_cur_vline()
282 {
283         if(event_manager == NULL) {
284                 event_manager = vm->first_device->next_device;
285         }
286         return event_manager->get_cur_vline();
287 }
288
289 int DEVICE::get_cur_vline_clocks()
290 {
291         if(event_manager == NULL) {
292                 event_manager = vm->first_device->next_device;
293         }
294         return event_manager->get_cur_vline_clocks();
295 }
296
297 uint32_t DEVICE::get_cpu_pc(int index)
298 {
299         if(event_manager == NULL) {
300                 event_manager = vm->first_device->next_device;
301         }
302         return event_manager->get_cpu_pc(index);
303 }
304
305 void DEVICE::request_skip_frames()
306 {
307         if(event_manager == NULL) {
308                 event_manager = vm->first_device->next_device;
309         }
310         event_manager->request_skip_frames();
311 }
312
313 void DEVICE::set_frames_per_sec(double frames)
314 {
315         if(event_manager == NULL) {
316                 event_manager = vm->first_device->next_device;
317         }
318         event_manager->set_frames_per_sec(frames);
319 }
320
321 void DEVICE::set_lines_per_frame(int lines)
322 {
323                 if(event_manager == NULL) {
324                         event_manager = vm->first_device->next_device;
325                 }
326                 event_manager->set_lines_per_frame(lines);
327 }
328
329 int DEVICE::get_lines_per_frame()
330 {
331         if(event_manager == NULL) {
332                 event_manager = vm->first_device->next_device;
333         }
334         return event_manager->get_lines_per_frame();
335 }
336
337 // Force render sound immediately when device's status has changed.
338 // You must call this after you changing registers (or anything).
339 // If has problems, try set_realtime_render.
340 // See mb8877.cpp and ym2203.cpp. 
341 // -- 20161010 K.O
342 void DEVICE::touch_sound(void)
343 {
344         if(event_manager == NULL) {
345                 event_manager = vm->first_device->next_device;
346         }
347         event_manager->touch_sound();
348 }
349 // Force render per 1 sample automatically.
350 // See pcm1bit.cpp .
351 // -- 20161010 K.O
352 void DEVICE::set_realtime_render(DEVICE *device, bool flag)
353 {
354         if(event_manager == NULL) {
355                 event_manager = vm->first_device->next_device;
356         }
357         if(device != event_manager) event_manager->set_realtime_render(device, flag);
358 }
359
360 void DEVICE::set_device_name(const _TCHAR *format, ...)
361 {
362         if(format != NULL) {
363                 va_list ap;
364                 _TCHAR buffer[1024];
365                 
366                 va_start(ap, format);
367                 my_vstprintf_s(buffer, 1024, format, ap);
368                 va_end(ap);
369
370                 my_tcscpy_s(this_device_name, 128, buffer);
371 #ifdef _USE_QT
372                 emu->get_osd()->set_vm_node(this_device_id, buffer);
373 #endif
374         }
375 }
376
377 void DEVICE::out_debug_log(const char *fmt, ...)
378 {
379 #if defined(_USE_QT)
380         if(p_logger == NULL) return;
381         char strbuf[4096];
382         va_list ap;
383         
384         va_start(ap, fmt);
385         vsnprintf(strbuf, 4095, fmt, ap);
386         p_logger->debug_log(CSP_LOG_DEBUG, this_device_id + CSP_LOG_TYPE_VM_DEVICE_0, "%s", strbuf);
387         va_end(ap);
388 #else
389         char strbuf[4096];
390         va_list ap;
391
392         va_start(ap, fmt);
393         vsnprintf(strbuf, 4095, fmt, ap);
394         emu->out_debug_log("%s", strbuf);
395         va_end(ap);
396 #endif
397 }
398
399 void DEVICE::force_out_debug_log(const char *fmt, ...)
400 {
401         char strbuf[4096];
402         va_list ap;
403
404         va_start(ap, fmt);
405         vsnprintf(strbuf, 4095, fmt, ap);
406         emu->force_out_debug_log("%s", strbuf);
407         va_end(ap);
408 }
409
410 // debugger
411 bool DEVICE::is_cpu()
412 {
413         return false;
414 }
415 bool DEVICE::is_debugger()
416 {
417         return false;
418 }
419 bool DEVICE::is_debugger_available()
420 {
421         return false;
422 }
423 void *DEVICE::get_debugger()
424 {
425         return NULL;
426 }
427 uint32_t DEVICE::get_debug_prog_addr_mask()
428 {
429         return 0;
430 }
431
432 uint32_t DEVICE::get_debug_data_addr_mask()
433 {
434         return 0;
435 }
436
437 uint64_t DEVICE::get_debug_data_addr_space()
438 {
439         // override this function when memory space is not (2 << n)
440         return (uint64_t)get_debug_data_addr_mask() + 1;
441 }
442 void DEVICE::write_debug_data8(uint32_t addr, uint32_t data)
443 {
444 //              write_data8(addr, data);
445 }
446 uint32_t DEVICE::read_debug_data8(uint32_t addr)
447 {
448 //              return read_data8(addr);
449         return 0xff;
450 }
451 void DEVICE::write_debug_data16(uint32_t addr, uint32_t data)
452 {
453         write_debug_data8(addr, data & 0xff);
454         write_debug_data8(addr + 1, (data >> 8) & 0xff);
455 }
456 uint32_t DEVICE::read_debug_data16(uint32_t addr)
457 {
458         uint32_t val = read_debug_data8(addr);
459         val |= read_debug_data8(addr + 1) << 8;
460         return val;
461 }
462 void DEVICE::write_debug_data32(uint32_t addr, uint32_t data)
463 {
464         write_debug_data16(addr, data & 0xffff);
465         write_debug_data16(addr + 2, (data >> 16) & 0xffff);
466 }
467 uint32_t DEVICE::read_debug_data32(uint32_t addr)
468 {
469         uint32_t val = read_debug_data16(addr);
470         val |= read_debug_data16(addr + 2) << 16;
471         return val;
472 }
473 void DEVICE::write_debug_io8(uint32_t addr, uint32_t data)
474 {
475 //              write_io8(addr, data);
476 }
477 uint32_t DEVICE::read_debug_io8(uint32_t addr)
478 {
479 //              return read_io8(addr);
480         return 0xff;
481 }
482 void DEVICE::write_debug_io16(uint32_t addr, uint32_t data)
483 {
484         write_debug_io8(addr, data & 0xff);
485         write_debug_io8(addr + 1, (data >> 8) & 0xff);
486 }
487 uint32_t DEVICE::read_debug_io16(uint32_t addr)
488 {
489         uint32_t val = read_debug_io8(addr);
490         val |= read_debug_io8(addr + 1) << 8;
491         return val;
492 }
493 void DEVICE::write_debug_io32(uint32_t addr, uint32_t data)
494 {
495         write_debug_io16(addr, data & 0xffff);
496         write_debug_io16(addr + 2, (data >> 16) & 0xffff);
497 }
498 uint32_t DEVICE::read_debug_io32(uint32_t addr)
499 {
500         uint32_t val = read_debug_io16(addr);
501         val |= read_debug_io16(addr + 2) << 16;
502         return val;
503 }
504 bool DEVICE::write_debug_reg(const _TCHAR *reg, uint32_t data)
505 {
506         return false;
507 }
508 uint32_t DEVICE::read_debug_reg(const _TCHAR *reg)
509 {
510         return 0;
511 }
512 bool DEVICE::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
513 {
514         return false;
515 }
516 int DEVICE::debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
517 {
518         return 0;
519 }
520 /*
521         These functions are used for debugging non-cpu device
522         Insert debugger between standard read/write functions and these functions for checking breakpoints
523
524         void DEVICE::write_data8(uint32_t addr, uint32_t data)
525         {
526                 if(debugger != NULL && debugger->now_device_debugging) {
527                         // debugger->mem = this;
528                         // debugger->mem->write_via_debugger_data8(addr, data)
529                         debugger->write_via_debugger_data8(addr, data);
530                 } else {
531                         this->write_via_debugger_data8(addr, data);
532                 }
533         }
534         void DEVICE::write_via_debugger_data8(uint32_t addr, uint32_t data)
535         {
536                 // write memory
537         }
538 */
539
540 void DEVICE::write_via_debugger_data8(uint32_t addr, uint32_t data)
541 {
542 }
543 uint32_t DEVICE::read_via_debugger_data8(uint32_t addr)
544 {
545         return 0xff;
546 }
547 void DEVICE::write_via_debugger_data16(uint32_t addr, uint32_t data)
548 {
549 }
550 uint32_t DEVICE::read_via_debugger_data16(uint32_t addr)
551 {
552         return 0xffff;
553 }
554 void DEVICE::write_via_debugger_data32(uint32_t addr, uint32_t data)
555 {
556 }
557 uint32_t DEVICE::read_via_debugger_data32(uint32_t addr)
558 {
559         return 0xffffffff;
560 }
561 void DEVICE::write_via_debugger_data8w(uint32_t addr, uint32_t data, int* wait)
562 {
563 }
564 uint32_t DEVICE::read_via_debugger_data8w(uint32_t addr, int* wait)
565 {
566         return 0xff;
567 }
568 void DEVICE::write_via_debugger_data16w(uint32_t addr, uint32_t data, int* wait)
569 {
570 }
571 uint32_t DEVICE::read_via_debugger_data16w(uint32_t addr, int* wait)
572 {
573         return 0xffff;
574 }
575 void DEVICE::write_via_debugger_data32w(uint32_t addr, uint32_t data, int* wait)
576 {
577 }
578 uint32_t DEVICE::read_via_debugger_data32w(uint32_t addr, int* wait)
579 {
580         return 0xffffffff;
581 }
582 void DEVICE::write_via_debugger_io8(uint32_t addr, uint32_t data)
583 {
584 }
585 uint32_t DEVICE::read_via_debugger_io8(uint32_t addr)
586 {
587         return 0xff;
588 }
589 void DEVICE::write_via_debugger_io16(uint32_t addr, uint32_t data)
590 {
591 }
592 uint32_t DEVICE::read_via_debugger_io16(uint32_t addr)
593 {
594         return 0xffff;
595 }
596 void DEVICE::write_via_debugger_io32(uint32_t addr, uint32_t data)
597 {
598 }
599 uint32_t DEVICE::read_via_debugger_io32(uint32_t addr)
600 {
601         return 0xffffffff;
602 }
603 void DEVICE::write_via_debugger_io8w(uint32_t addr, uint32_t data, int* wait)
604 {
605 }
606 uint32_t DEVICE::read_via_debugger_io8w(uint32_t addr, int* wait)
607 {
608         return 0xff;
609 }
610 void DEVICE::write_via_debugger_io16w(uint32_t addr, uint32_t data, int* wait)
611 {
612 }
613 uint32_t DEVICE::read_via_debugger_io16w(uint32_t addr, int* wait)
614 {
615         return 0xffff;
616 }
617 void DEVICE::write_via_debugger_io32w(uint32_t addr, uint32_t data, int* wait)
618 {
619 }
620 uint32_t DEVICE::read_via_debugger_io32w(uint32_t addr, int* wait)
621 {
622         return 0xffffffff;
623 }
624
625
626 const _TCHAR *DEVICE::get_lib_common_vm_version(void)
627 {
628 #if defined(__LIBRARY_NAME)
629         return (const _TCHAR *)__LIBRARY_NAME;
630 #else
631         return (const _TCHAR *)"\0";
632 #endif  
633 }