2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
18 #include "csp_logger.h"
19 #define USE_DEVICE_NAME
22 #if defined(USE_SHARED_DLL)
23 #include "libcpu_newdev/device.h"
26 // max devices connected to the output port
30 #define SIG_CPU_IRQ 101
31 #define SIG_CPU_FIRQ 102
32 #define SIG_CPU_NMI 103
33 #define SIG_CPU_BUSREQ 104
34 #define SIG_CPU_DEBUG 105
36 #define SIG_PRINTER_DATA 201
37 #define SIG_PRINTER_STROBE 202
38 #define SIG_PRINTER_RESET 203
39 #define SIG_PRINTER_BUSY 204
40 #define SIG_PRINTER_ACK 205
41 #define SIG_PRINTER_SELECT 206
43 #define SIG_SCSI_DAT 301
44 #define SIG_SCSI_BSY 302
45 #define SIG_SCSI_CD 303
46 #define SIG_SCSI_IO 304
47 #define SIG_SCSI_MSG 305
48 #define SIG_SCSI_REQ 306
49 #define SIG_SCSI_SEL 307
50 #define SIG_SCSI_ATN 308
51 #define SIG_SCSI_ACK 309
52 #define SIG_SCSI_RST 310
61 DEVICE(VM* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu)
69 strncpy(this_device_name, "Base Device", 128);
70 prev_device = vm->last_device;
72 if(vm->first_device == NULL) {
73 // this is the first device
74 vm->first_device = this;
77 // this is not the first device
78 vm->last_device->next_device = this;
79 this_device_id = vm->last_device->this_device_id + 1;
81 vm->last_device = this;
83 // primary event manager
86 //ToDo: Will implement real destructor per real classes and below destructor decl. with "virtual".
87 // This makes warning:
88 //"deleting object of polymorphic class type 'DEVICE' which has non-virtual
89 // destructor might cause undefined behavior [-Wdelete-non-virtual-dtor]".
92 virtual void initialize() { /* osd = emu->get_osd(); */ /* Initializing VM must be after initializing OSD. */ }
93 virtual void release() {}
95 virtual void update_config() {}
96 virtual void save_state(FILEIO* state_fio) {}
97 virtual bool load_state(FILEIO* state_fio)
103 virtual void reset() {}
104 virtual void special_reset()
109 // NOTE: the virtual bus interface functions for 16/32bit access invite the cpu is little endian.
110 // if the cpu is big endian, you need to implement them in the virtual machine memory/io classes.
113 virtual void write_data8(uint32_t addr, uint32_t data) {}
114 virtual uint32_t read_data8(uint32_t addr)
118 virtual void write_data16(uint32_t addr, uint32_t data)
120 write_data8(addr, data & 0xff);
121 write_data8(addr + 1, (data >> 8) & 0xff);
123 virtual uint32_t read_data16(uint32_t addr)
125 uint32_t val = read_data8(addr);
126 val |= read_data8(addr + 1) << 8;
129 virtual void write_data32(uint32_t addr, uint32_t data)
131 write_data16(addr, data & 0xffff);
132 write_data16(addr + 2, (data >> 16) & 0xffff);
134 virtual uint32_t read_data32(uint32_t addr)
136 uint32_t val = read_data16(addr);
137 val |= read_data16(addr + 2) << 16;
140 virtual void write_data8w(uint32_t addr, uint32_t data, int* wait)
143 write_data8(addr, data);
145 virtual uint32_t read_data8w(uint32_t addr, int* wait)
148 return read_data8(addr);
150 virtual void write_data16w(uint32_t addr, uint32_t data, int* wait)
153 write_data8w(addr, data & 0xff, &wait_l);
154 write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h);
155 *wait = wait_l + wait_h;
157 virtual uint32_t read_data16w(uint32_t addr, int* wait)
160 uint32_t val = read_data8w(addr, &wait_l);
161 val |= read_data8w(addr + 1, &wait_h) << 8;
162 *wait = wait_l + wait_h;
165 virtual void write_data32w(uint32_t addr, uint32_t data, int* wait)
168 write_data16w(addr, data & 0xffff, &wait_l);
169 write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
170 *wait = wait_l + wait_h;
172 virtual uint32_t read_data32w(uint32_t addr, int* wait)
175 uint32_t val = read_data16w(addr, &wait_l);
176 val |= read_data16w(addr + 2, &wait_h) << 16;
177 *wait = wait_l + wait_h;
180 virtual uint32_t fetch_op(uint32_t addr, int *wait)
182 return read_data8w(addr, wait);
184 virtual void write_dma_data8(uint32_t addr, uint32_t data)
186 write_data8(addr, data);
188 virtual uint32_t read_dma_data8(uint32_t addr)
190 return read_data8(addr);
192 virtual void write_dma_data16(uint32_t addr, uint32_t data)
194 write_data16(addr, data);
196 virtual uint32_t read_dma_data16(uint32_t addr)
198 return read_data16(addr);
200 virtual void write_dma_data32(uint32_t addr, uint32_t data)
202 write_data32(addr, data);
204 virtual uint32_t read_dma_data32(uint32_t addr)
206 return read_data32(addr);
208 virtual void write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
210 write_data8w(addr, data, wait);
212 virtual uint32_t read_dma_data8w(uint32_t addr, int* wait)
214 return read_data8w(addr, wait);
216 virtual void write_dma_data16w(uint32_t addr, uint32_t data, int* wait)
218 write_data16w(addr, data, wait);
220 virtual uint32_t read_dma_data16w(uint32_t addr, int* wait)
222 return read_data16w(addr, wait);
224 virtual void write_dma_data32w(uint32_t addr, uint32_t data, int* wait)
226 write_data32w(addr, data, wait);
228 virtual uint32_t read_dma_data32w(uint32_t addr, int* wait)
230 return read_data32w(addr, wait);
234 virtual void write_io8(uint32_t addr, uint32_t data) {}
235 virtual uint32_t read_io8(uint32_t addr)
237 #ifdef IOBUS_RETURN_ADDR
238 return (addr & 1 ? addr >> 8 : addr) & 0xff;
243 virtual void write_io16(uint32_t addr, uint32_t data)
245 write_io8(addr, data & 0xff);
246 write_io8(addr + 1, (data >> 8) & 0xff);
248 virtual uint32_t read_io16(uint32_t addr)
250 uint32_t val = read_io8(addr);
251 val |= read_io8(addr + 1) << 8;
254 virtual void write_io32(uint32_t addr, uint32_t data)
256 write_io16(addr, data & 0xffff);
257 write_io16(addr + 2, (data >> 16) & 0xffff);
259 virtual uint32_t read_io32(uint32_t addr)
261 uint32_t val = read_io16(addr);
262 val |= read_io16(addr + 2) << 16;
265 virtual void write_io8w(uint32_t addr, uint32_t data, int* wait)
268 write_io8(addr, data);
270 virtual uint32_t read_io8w(uint32_t addr, int* wait)
273 return read_io8(addr);
275 virtual void write_io16w(uint32_t addr, uint32_t data, int* wait)
278 write_io8w(addr, data & 0xff, &wait_l);
279 write_io8w(addr + 1, (data >> 8) & 0xff, &wait_h);
280 *wait = wait_l + wait_h;
282 virtual uint32_t read_io16w(uint32_t addr, int* wait)
285 uint32_t val = read_io8w(addr, &wait_l);
286 val |= read_io8w(addr + 1, &wait_h) << 8;
287 *wait = wait_l + wait_h;
290 virtual void write_io32w(uint32_t addr, uint32_t data, int* wait)
293 write_io16w(addr, data & 0xffff, &wait_l);
294 write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
295 *wait = wait_l + wait_h;
297 virtual uint32_t read_io32w(uint32_t addr, int* wait)
300 uint32_t val = read_io16w(addr, &wait_l);
301 val |= read_io16w(addr + 2, &wait_h) << 16;
302 *wait = wait_l + wait_h;
305 virtual void write_dma_io8(uint32_t addr, uint32_t data)
307 write_io8(addr, data);
309 virtual uint32_t read_dma_io8(uint32_t addr)
311 return read_io8(addr);
313 virtual void write_dma_io16(uint32_t addr, uint32_t data)
315 write_io16(addr, data);
317 virtual uint32_t read_dma_io16(uint32_t addr)
319 return read_io16(addr);
321 virtual void write_dma_io32(uint32_t addr, uint32_t data)
323 write_io32(addr, data);
325 virtual uint32_t read_dma_io32(uint32_t addr)
327 return read_io32(addr);
329 virtual void write_dma_io8w(uint32_t addr, uint32_t data, int* wait)
331 write_io8w(addr, data, wait);
333 virtual uint32_t read_dma_io8w(uint32_t addr, int* wait)
335 return read_io8w(addr, wait);
337 virtual void write_dma_io16w(uint32_t addr, uint32_t data, int* wait)
339 write_io16w(addr, data, wait);
341 virtual uint32_t read_dma_io16w(uint32_t addr, int* wait)
343 return read_io16w(addr, wait);
345 virtual void write_dma_io32w(uint32_t addr, uint32_t data, int* wait)
347 write_io32w(addr, data, wait);
349 virtual uint32_t read_dma_io32w(uint32_t addr, int* wait)
351 return read_io32w(addr, wait);
355 virtual void write_memory_mapped_io8(uint32_t addr, uint32_t data)
357 write_io8(addr, data);
359 virtual uint32_t read_memory_mapped_io8(uint32_t addr)
361 return read_io8(addr);
363 virtual void write_memory_mapped_io16(uint32_t addr, uint32_t data)
365 write_memory_mapped_io8(addr, data & 0xff);
366 write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff);
368 virtual uint32_t read_memory_mapped_io16(uint32_t addr)
370 uint32_t val = read_memory_mapped_io8(addr);
371 val |= read_memory_mapped_io8(addr + 1) << 8;
374 virtual void write_memory_mapped_io32(uint32_t addr, uint32_t data)
376 write_memory_mapped_io16(addr, data & 0xffff);
377 write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff);
379 virtual uint32_t read_memory_mapped_io32(uint32_t addr)
381 uint32_t val = read_memory_mapped_io16(addr);
382 val |= read_memory_mapped_io16(addr + 2) << 16;
385 virtual void write_memory_mapped_io8w(uint32_t addr, uint32_t data, int* wait)
388 write_memory_mapped_io8(addr, data);
390 virtual uint32_t read_memory_mapped_io8w(uint32_t addr, int* wait)
393 return read_memory_mapped_io8(addr);
395 virtual void write_memory_mapped_io16w(uint32_t addr, uint32_t data, int* wait)
398 write_memory_mapped_io8w(addr, data & 0xff, &wait_l);
399 write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_h);
400 *wait = wait_l + wait_h;
402 virtual uint32_t read_memory_mapped_io16w(uint32_t addr, int* wait)
405 uint32_t val = read_memory_mapped_io8w(addr, &wait_l);
406 val |= read_memory_mapped_io8w(addr + 1, &wait_h) << 8;
407 *wait = wait_l + wait_h;
410 virtual void write_memory_mapped_io32w(uint32_t addr, uint32_t data, int* wait)
413 write_memory_mapped_io16w(addr, data & 0xffff, &wait_l);
414 write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
415 *wait = wait_l + wait_h;
417 virtual uint32_t read_memory_mapped_io32w(uint32_t addr, int* wait)
420 uint32_t val = read_memory_mapped_io16w(addr, &wait_l);
421 val |= read_memory_mapped_io16w(addr + 2, &wait_h) << 16;
422 *wait = wait_l + wait_h;
436 output_t item[MAX_OUTPUT];
439 virtual void initialize_output_signals(outputs_t *items)
443 virtual void register_output_signal(outputs_t *items, DEVICE *device, int id, uint32_t mask, int shift)
445 int c = items->count++;
446 items->item[c].device = device;
447 items->item[c].id = id;
448 items->item[c].mask = mask;
449 items->item[c].shift = shift;
451 virtual void register_output_signal(outputs_t *items, DEVICE *device, int id, uint32_t mask)
453 int c = items->count++;
454 items->item[c].device = device;
455 items->item[c].id = id;
456 items->item[c].mask = mask;
457 items->item[c].shift = 0;
459 virtual void write_signals(outputs_t *items, uint32_t data)
461 for(int i = 0; i < items->count; i++) {
462 output_t *item = &items->item[i];
463 int shift = item->shift;
464 uint32_t val = (shift < 0) ? (data >> (-shift)) : (data << shift);
465 uint32_t mask = (shift < 0) ? (item->mask >> (-shift)) : (item->mask << shift);
466 item->device->write_signal(item->id, val, mask);
469 virtual void write_signal(int id, uint32_t data, uint32_t mask) {}
470 virtual uint32_t read_signal(int ch)
476 virtual void set_context_intr(DEVICE* device, uint32_t bit) {}
477 virtual void set_context_child(DEVICE* device) {}
479 // interrupt device to device
480 virtual void set_intr_iei(bool val) {}
482 // interrupt device to cpu
483 virtual void set_intr_line(bool line, bool pending, uint32_t bit) {}
485 // interrupt cpu to device
486 virtual uint32_t get_intr_ack()
490 virtual void notify_intr_reti() {}
491 virtual void notify_intr_ei() {}
494 virtual void do_dma() {}
497 virtual int run(int clock)
499 // when clock == -1, run one opecode
500 return (clock == -1 ? 1 : clock);
502 virtual void set_extra_clock(int clock) {}
503 virtual int get_extra_clock()
507 virtual uint32_t get_pc()
511 virtual uint32_t get_next_pc()
517 virtual bool bios_call_far_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
521 virtual bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
525 virtual bool bios_ret_z80(uint16_t PC, pair_t* af, pair_t* bc, pair_t* de, pair_t* hl, pair_t* ix, pair_t* iy, uint8_t* iff1) {
529 const _TCHAR *get_device_name(void)
531 return (const _TCHAR *)this_device_name;
535 DEVICE* event_manager;
537 virtual void set_context_event_manager(DEVICE* device)
539 event_manager = device;
541 virtual int get_event_manager_id()
543 if(event_manager == NULL) {
544 event_manager = vm->first_device->next_device;
546 return event_manager->this_device_id;
548 virtual void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id)
550 if(event_manager == NULL) {
551 event_manager = vm->first_device->next_device;
553 event_manager->register_event(device, event_id, usec, loop, register_id);
555 virtual void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id)
557 if(event_manager == NULL) {
558 event_manager = vm->first_device->next_device;
560 event_manager->register_event_by_clock(device, event_id, clock, loop, register_id);
562 virtual void cancel_event(DEVICE* device, int register_id)
564 if(event_manager == NULL) {
565 event_manager = vm->first_device->next_device;
567 event_manager->cancel_event(device, register_id);
569 virtual void register_frame_event(DEVICE* device)
571 if(event_manager == NULL) {
572 event_manager = vm->first_device->next_device;
574 event_manager->register_frame_event(device);
576 virtual void register_vline_event(DEVICE* device)
578 if(event_manager == NULL) {
579 event_manager = vm->first_device->next_device;
581 event_manager->register_vline_event(device);
583 virtual uint32_t get_event_remaining_clock(int register_id)
585 if(event_manager == NULL) {
586 event_manager = vm->first_device->next_device;
588 return event_manager->get_event_remaining_clock(register_id);
590 virtual double get_event_remaining_usec(int register_id)
592 if(event_manager == NULL) {
593 event_manager = vm->first_device->next_device;
595 return event_manager->get_event_remaining_usec(register_id);
597 virtual uint32_t get_current_clock()
599 if(event_manager == NULL) {
600 event_manager = vm->first_device->next_device;
602 return event_manager->get_current_clock();
604 virtual uint32_t get_passed_clock(uint32_t prev)
606 if(event_manager == NULL) {
607 event_manager = vm->first_device->next_device;
609 return event_manager->get_passed_clock(prev);
611 virtual double get_passed_usec(uint32_t prev)
613 if(event_manager == NULL) {
614 event_manager = vm->first_device->next_device;
616 return event_manager->get_passed_usec(prev);
618 virtual uint32_t get_cpu_pc(int index)
620 if(event_manager == NULL) {
621 event_manager = vm->first_device->next_device;
623 return event_manager->get_cpu_pc(index);
625 virtual void request_skip_frames()
627 if(event_manager == NULL) {
628 event_manager = vm->first_device->next_device;
630 event_manager->request_skip_frames();
632 virtual void set_frames_per_sec(double frames)
634 if(event_manager == NULL) {
635 event_manager = vm->first_device->next_device;
637 event_manager->set_frames_per_sec(frames);
639 virtual void set_lines_per_frame(int lines)
641 if(event_manager == NULL) {
642 event_manager = vm->first_device->next_device;
644 event_manager->set_lines_per_frame(lines);
646 // Force reder sound immediately when device's status has changed.
647 // You must call this after you changing registers (or enything).
648 // If has problems, try set_realtime_render.
649 // See mb8877.cpp and ym2203.cpp.
651 virtual void touch_sound(void)
653 if(event_manager == NULL) {
654 event_manager = vm->first_device->next_device;
656 event_manager->touch_sound();
658 // Force render per 1 sample automatically.
661 virtual void set_realtime_render(DEVICE* device, bool flag = true)
663 if(event_manager == NULL) {
664 event_manager = vm->first_device->next_device;
666 if(device != event_manager) event_manager->set_realtime_render(device, flag);
668 virtual void set_realtime_render(bool flag)
670 set_realtime_render(this, flag);
672 virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) {}
675 virtual void event_callback(int event_id, int err) {}
676 virtual void event_pre_frame() {} // this event is to update timing settings
677 virtual void event_frame() {}
678 virtual void event_vline(int v, int clock) {}
679 virtual void event_hsync(int v, int h, int clock) {}
682 virtual void mix(int32_t* buffer, int cnt) {}
683 virtual void set_volume(int ch, int decibel_l, int decibel_r) {} // +1 equals +0.5dB (same as fmgen)
684 virtual void set_device_name(const _TCHAR *format, ...)
690 va_start(ap, format);
691 my_vstprintf_s(buffer, 1024, format, ap);
694 my_tcscpy_s(this_device_name, 128, buffer);
696 emu->get_osd()->set_vm_node(this_device_id, buffer);
700 virtual void out_debug_log(const char *fmt, ...)
706 vsnprintf(strbuf, 4095, fmt, ap);
707 emu->out_debug_log("%s", strbuf);
710 virtual void force_out_debug_log(const char *fmt, ...)
716 vsnprintf(strbuf, 4095, fmt, ap);
717 emu->force_out_debug_log("%s", strbuf);
723 virtual void *get_debugger()
727 virtual uint32_t get_debug_prog_addr_mask()
731 virtual uint32_t get_debug_data_addr_mask()
735 virtual void write_debug_data8(uint32_t addr, uint32_t data) {}
736 virtual uint32_t read_debug_data8(uint32_t addr)
740 virtual void write_debug_data16(uint32_t addr, uint32_t data)
742 write_debug_data8(addr, data & 0xff);
743 write_debug_data8(addr + 1, (data >> 8) & 0xff);
745 virtual uint32_t read_debug_data16(uint32_t addr)
747 uint32_t val = read_debug_data8(addr);
748 val |= read_debug_data8(addr + 1) << 8;
751 virtual void write_debug_data32(uint32_t addr, uint32_t data)
753 write_debug_data16(addr, data & 0xffff);
754 write_debug_data16(addr + 2, (data >> 16) & 0xffff);
756 virtual uint32_t read_debug_data32(uint32_t addr)
758 uint32_t val = read_debug_data16(addr);
759 val |= read_debug_data16(addr + 2) << 16;
762 virtual void write_debug_io8(uint32_t addr, uint32_t data) {}
763 virtual uint32_t read_debug_io8(uint32_t addr)
767 virtual void write_debug_io16(uint32_t addr, uint32_t data)
769 write_debug_io8(addr, data & 0xff);
770 write_debug_io8(addr + 1, (data >> 8) & 0xff);
772 virtual uint32_t read_debug_io16(uint32_t addr)
774 uint32_t val = read_debug_io8(addr);
775 val |= read_debug_io8(addr + 1) << 8;
778 virtual void write_debug_io32(uint32_t addr, uint32_t data)
780 write_debug_io16(addr, data & 0xffff);
781 write_debug_io16(addr + 2, (data >> 16) & 0xffff);
783 virtual uint32_t read_debug_io32(uint32_t addr)
785 uint32_t val = read_debug_io16(addr);
786 val |= read_debug_io16(addr + 2) << 16;
789 virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data)
793 virtual void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) {}
794 virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
799 _TCHAR this_device_name[128];
805 #endif // USE_SHARED_DLL