2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
18 #include "csp_logger.h"
19 #define USE_DEVICE_NAME
22 #if defined(USE_DEVICES_SHARED_LIB)
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
60 DEVICE(VM* parent_vm, EMU* parent_emu) : vm(parent_vm), emu(parent_emu)
62 strncpy(this_device_name, "Base Device", 128);
63 prev_device = vm->last_device;
65 if(vm->first_device == NULL) {
66 // this is the first device
67 vm->first_device = this;
70 // this is not the first device
71 vm->last_device->next_device = this;
72 this_device_id = vm->last_device->this_device_id + 1;
74 vm->last_device = this;
76 // primary event manager
79 //ToDo: Will implement real destructor per real classes and below destructor decl. with "virtual".
80 // This makes warning:
81 //"deleting object of polymorphic class type 'DEVICE' which has non-virtual
82 // destructor might cause undefined behavior [-Wdelete-non-virtual-dtor]".
85 virtual void initialize() {}
86 virtual void release() {}
88 virtual void update_config() {}
89 virtual void save_state(FILEIO* state_fio) {}
90 virtual bool load_state(FILEIO* state_fio)
96 virtual void reset() {}
97 virtual void special_reset()
102 // NOTE: the virtual bus interface functions for 16/32bit access invite the cpu is little endian.
103 // if the cpu is big endian, you need to implement them in the virtual machine memory/io classes.
106 virtual void write_data8(uint32_t addr, uint32_t data) {}
107 virtual uint32_t read_data8(uint32_t addr)
111 virtual void write_data16(uint32_t addr, uint32_t data)
113 write_data8(addr, data & 0xff);
114 write_data8(addr + 1, (data >> 8) & 0xff);
116 virtual uint32_t read_data16(uint32_t addr)
118 uint32_t val = read_data8(addr);
119 val |= read_data8(addr + 1) << 8;
122 virtual void write_data32(uint32_t addr, uint32_t data)
124 write_data16(addr, data & 0xffff);
125 write_data16(addr + 2, (data >> 16) & 0xffff);
127 virtual uint32_t read_data32(uint32_t addr)
129 uint32_t val = read_data16(addr);
130 val |= read_data16(addr + 2) << 16;
133 virtual void write_data8w(uint32_t addr, uint32_t data, int* wait)
136 write_data8(addr, data);
138 virtual uint32_t read_data8w(uint32_t addr, int* wait)
141 return read_data8(addr);
143 virtual void write_data16w(uint32_t addr, uint32_t data, int* wait)
146 write_data8w(addr, data & 0xff, &wait_l);
147 write_data8w(addr + 1, (data >> 8) & 0xff, &wait_h);
148 *wait = wait_l + wait_h;
150 virtual uint32_t read_data16w(uint32_t addr, int* wait)
153 uint32_t val = read_data8w(addr, &wait_l);
154 val |= read_data8w(addr + 1, &wait_h) << 8;
155 *wait = wait_l + wait_h;
158 virtual void write_data32w(uint32_t addr, uint32_t data, int* wait)
161 write_data16w(addr, data & 0xffff, &wait_l);
162 write_data16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
163 *wait = wait_l + wait_h;
165 virtual uint32_t read_data32w(uint32_t addr, int* wait)
168 uint32_t val = read_data16w(addr, &wait_l);
169 val |= read_data16w(addr + 2, &wait_h) << 16;
170 *wait = wait_l + wait_h;
173 virtual uint32_t fetch_op(uint32_t addr, int *wait)
175 return read_data8w(addr, wait);
177 virtual void write_dma_data8(uint32_t addr, uint32_t data)
179 write_data8(addr, data);
181 virtual uint32_t read_dma_data8(uint32_t addr)
183 return read_data8(addr);
185 virtual void write_dma_data16(uint32_t addr, uint32_t data)
187 write_data16(addr, data);
189 virtual uint32_t read_dma_data16(uint32_t addr)
191 return read_data16(addr);
193 virtual void write_dma_data32(uint32_t addr, uint32_t data)
195 write_data32(addr, data);
197 virtual uint32_t read_dma_data32(uint32_t addr)
199 return read_data32(addr);
201 virtual void write_dma_data8w(uint32_t addr, uint32_t data, int* wait)
203 write_data8w(addr, data, wait);
205 virtual uint32_t read_dma_data8w(uint32_t addr, int* wait)
207 return read_data8w(addr, wait);
209 virtual void write_dma_data16w(uint32_t addr, uint32_t data, int* wait)
211 write_data16w(addr, data, wait);
213 virtual uint32_t read_dma_data16w(uint32_t addr, int* wait)
215 return read_data16w(addr, wait);
217 virtual void write_dma_data32w(uint32_t addr, uint32_t data, int* wait)
219 write_data32w(addr, data, wait);
221 virtual uint32_t read_dma_data32w(uint32_t addr, int* wait)
223 return read_data32w(addr, wait);
227 virtual void write_io8(uint32_t addr, uint32_t data) {}
228 virtual uint32_t read_io8(uint32_t addr)
230 #ifdef IOBUS_RETURN_ADDR
231 return (addr & 1 ? addr >> 8 : addr) & 0xff;
236 virtual void write_io16(uint32_t addr, uint32_t data)
238 write_io8(addr, data & 0xff);
239 write_io8(addr + 1, (data >> 8) & 0xff);
241 virtual uint32_t read_io16(uint32_t addr)
243 uint32_t val = read_io8(addr);
244 val |= read_io8(addr + 1) << 8;
247 virtual void write_io32(uint32_t addr, uint32_t data)
249 write_io16(addr, data & 0xffff);
250 write_io16(addr + 2, (data >> 16) & 0xffff);
252 virtual uint32_t read_io32(uint32_t addr)
254 uint32_t val = read_io16(addr);
255 val |= read_io16(addr + 2) << 16;
258 virtual void write_io8w(uint32_t addr, uint32_t data, int* wait)
261 write_io8(addr, data);
263 virtual uint32_t read_io8w(uint32_t addr, int* wait)
266 return read_io8(addr);
268 virtual void write_io16w(uint32_t addr, uint32_t data, int* wait)
271 write_io8w(addr, data & 0xff, &wait_l);
272 write_io8w(addr + 1, (data >> 8) & 0xff, &wait_h);
273 *wait = wait_l + wait_h;
275 virtual uint32_t read_io16w(uint32_t addr, int* wait)
278 uint32_t val = read_io8w(addr, &wait_l);
279 val |= read_io8w(addr + 1, &wait_h) << 8;
280 *wait = wait_l + wait_h;
283 virtual void write_io32w(uint32_t addr, uint32_t data, int* wait)
286 write_io16w(addr, data & 0xffff, &wait_l);
287 write_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
288 *wait = wait_l + wait_h;
290 virtual uint32_t read_io32w(uint32_t addr, int* wait)
293 uint32_t val = read_io16w(addr, &wait_l);
294 val |= read_io16w(addr + 2, &wait_h) << 16;
295 *wait = wait_l + wait_h;
298 virtual void write_dma_io8(uint32_t addr, uint32_t data)
300 write_io8(addr, data);
302 virtual uint32_t read_dma_io8(uint32_t addr)
304 return read_io8(addr);
306 virtual void write_dma_io16(uint32_t addr, uint32_t data)
308 write_io16(addr, data);
310 virtual uint32_t read_dma_io16(uint32_t addr)
312 return read_io16(addr);
314 virtual void write_dma_io32(uint32_t addr, uint32_t data)
316 write_io32(addr, data);
318 virtual uint32_t read_dma_io32(uint32_t addr)
320 return read_io32(addr);
322 virtual void write_dma_io8w(uint32_t addr, uint32_t data, int* wait)
324 write_io8w(addr, data, wait);
326 virtual uint32_t read_dma_io8w(uint32_t addr, int* wait)
328 return read_io8w(addr, wait);
330 virtual void write_dma_io16w(uint32_t addr, uint32_t data, int* wait)
332 write_io16w(addr, data, wait);
334 virtual uint32_t read_dma_io16w(uint32_t addr, int* wait)
336 return read_io16w(addr, wait);
338 virtual void write_dma_io32w(uint32_t addr, uint32_t data, int* wait)
340 write_io32w(addr, data, wait);
342 virtual uint32_t read_dma_io32w(uint32_t addr, int* wait)
344 return read_io32w(addr, wait);
348 virtual void write_memory_mapped_io8(uint32_t addr, uint32_t data)
350 write_io8(addr, data);
352 virtual uint32_t read_memory_mapped_io8(uint32_t addr)
354 return read_io8(addr);
356 virtual void write_memory_mapped_io16(uint32_t addr, uint32_t data)
358 write_memory_mapped_io8(addr, data & 0xff);
359 write_memory_mapped_io8(addr + 1, (data >> 8) & 0xff);
361 virtual uint32_t read_memory_mapped_io16(uint32_t addr)
363 uint32_t val = read_memory_mapped_io8(addr);
364 val |= read_memory_mapped_io8(addr + 1) << 8;
367 virtual void write_memory_mapped_io32(uint32_t addr, uint32_t data)
369 write_memory_mapped_io16(addr, data & 0xffff);
370 write_memory_mapped_io16(addr + 2, (data >> 16) & 0xffff);
372 virtual uint32_t read_memory_mapped_io32(uint32_t addr)
374 uint32_t val = read_memory_mapped_io16(addr);
375 val |= read_memory_mapped_io16(addr + 2) << 16;
378 virtual void write_memory_mapped_io8w(uint32_t addr, uint32_t data, int* wait)
381 write_memory_mapped_io8(addr, data);
383 virtual uint32_t read_memory_mapped_io8w(uint32_t addr, int* wait)
386 return read_memory_mapped_io8(addr);
388 virtual void write_memory_mapped_io16w(uint32_t addr, uint32_t data, int* wait)
391 write_memory_mapped_io8w(addr, data & 0xff, &wait_l);
392 write_memory_mapped_io8w(addr + 1, (data >> 8) & 0xff, &wait_h);
393 *wait = wait_l + wait_h;
395 virtual uint32_t read_memory_mapped_io16w(uint32_t addr, int* wait)
398 uint32_t val = read_memory_mapped_io8w(addr, &wait_l);
399 val |= read_memory_mapped_io8w(addr + 1, &wait_h) << 8;
400 *wait = wait_l + wait_h;
403 virtual void write_memory_mapped_io32w(uint32_t addr, uint32_t data, int* wait)
406 write_memory_mapped_io16w(addr, data & 0xffff, &wait_l);
407 write_memory_mapped_io16w(addr + 2, (data >> 16) & 0xffff, &wait_h);
408 *wait = wait_l + wait_h;
410 virtual uint32_t read_memory_mapped_io32w(uint32_t addr, int* wait)
413 uint32_t val = read_memory_mapped_io16w(addr, &wait_l);
414 val |= read_memory_mapped_io16w(addr + 2, &wait_h) << 16;
415 *wait = wait_l + wait_h;
429 output_t item[MAX_OUTPUT];
432 virtual void initialize_output_signals(outputs_t *items)
436 virtual void register_output_signal(outputs_t *items, DEVICE *device, int id, uint32_t mask, int shift)
438 int c = items->count++;
439 items->item[c].device = device;
440 items->item[c].id = id;
441 items->item[c].mask = mask;
442 items->item[c].shift = shift;
444 virtual void register_output_signal(outputs_t *items, DEVICE *device, int id, uint32_t mask)
446 int c = items->count++;
447 items->item[c].device = device;
448 items->item[c].id = id;
449 items->item[c].mask = mask;
450 items->item[c].shift = 0;
452 virtual void write_signals(outputs_t *items, uint32_t data)
454 for(int i = 0; i < items->count; i++) {
455 output_t *item = &items->item[i];
456 int shift = item->shift;
457 uint32_t val = (shift < 0) ? (data >> (-shift)) : (data << shift);
458 uint32_t mask = (shift < 0) ? (item->mask >> (-shift)) : (item->mask << shift);
459 item->device->write_signal(item->id, val, mask);
462 virtual void write_signal(int id, uint32_t data, uint32_t mask) {}
463 virtual uint32_t read_signal(int ch)
469 virtual void set_context_intr(DEVICE* device, uint32_t bit) {}
470 virtual void set_context_child(DEVICE* device) {}
472 // interrupt device to device
473 virtual void set_intr_iei(bool val) {}
475 // interrupt device to cpu
476 virtual void set_intr_line(bool line, bool pending, uint32_t bit) {}
478 // interrupt cpu to device
479 virtual uint32_t get_intr_ack()
483 virtual void notify_intr_reti() {}
484 virtual void notify_intr_ei() {}
487 virtual void do_dma() {}
490 virtual int run(int clock)
492 // when clock == -1, run one opecode
493 return (clock == -1 ? 1 : clock);
495 virtual void set_extra_clock(int clock) {}
496 virtual int get_extra_clock()
500 virtual uint32_t get_pc()
504 virtual uint32_t get_next_pc()
510 virtual bool bios_call_i86(uint32_t PC, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
514 virtual bool bios_int_i86(int intnum, uint16_t regs[], uint16_t sregs[], int32_t* ZeroFlag, int32_t* CarryFlag)
518 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) {
522 const _TCHAR *get_device_name(void)
524 return (const _TCHAR *)this_device_name;
528 DEVICE* event_manager;
530 virtual void set_context_event_manager(DEVICE* device)
532 event_manager = device;
534 virtual int get_event_manager_id()
536 if(event_manager == NULL) {
537 event_manager = vm->first_device->next_device;
539 return event_manager->this_device_id;
541 virtual void register_event(DEVICE* device, int event_id, double usec, bool loop, int* register_id)
543 if(event_manager == NULL) {
544 event_manager = vm->first_device->next_device;
546 event_manager->register_event(device, event_id, usec, loop, register_id);
548 virtual void register_event_by_clock(DEVICE* device, int event_id, uint64_t clock, bool loop, int* register_id)
550 if(event_manager == NULL) {
551 event_manager = vm->first_device->next_device;
553 event_manager->register_event_by_clock(device, event_id, clock, loop, register_id);
555 virtual void cancel_event(DEVICE* device, int register_id)
557 if(event_manager == NULL) {
558 event_manager = vm->first_device->next_device;
560 event_manager->cancel_event(device, register_id);
562 virtual void register_frame_event(DEVICE* device)
564 if(event_manager == NULL) {
565 event_manager = vm->first_device->next_device;
567 event_manager->register_frame_event(device);
569 virtual void register_vline_event(DEVICE* device)
571 if(event_manager == NULL) {
572 event_manager = vm->first_device->next_device;
574 event_manager->register_vline_event(device);
576 virtual uint32_t get_event_remaining_clock(int register_id)
578 if(event_manager == NULL) {
579 event_manager = vm->first_device->next_device;
581 return event_manager->get_event_remaining_clock(register_id);
583 virtual double get_event_remaining_usec(int register_id)
585 if(event_manager == NULL) {
586 event_manager = vm->first_device->next_device;
588 return event_manager->get_event_remaining_usec(register_id);
590 virtual uint32_t get_current_clock()
592 if(event_manager == NULL) {
593 event_manager = vm->first_device->next_device;
595 return event_manager->get_current_clock();
597 virtual uint32_t get_passed_clock(uint32_t prev)
599 if(event_manager == NULL) {
600 event_manager = vm->first_device->next_device;
602 return event_manager->get_passed_clock(prev);
604 virtual double get_passed_usec(uint32_t prev)
606 if(event_manager == NULL) {
607 event_manager = vm->first_device->next_device;
609 return event_manager->get_passed_usec(prev);
611 virtual uint32_t get_cpu_pc(int index)
613 if(event_manager == NULL) {
614 event_manager = vm->first_device->next_device;
616 return event_manager->get_cpu_pc(index);
618 virtual void request_skip_frames()
620 if(event_manager == NULL) {
621 event_manager = vm->first_device->next_device;
623 event_manager->request_skip_frames();
625 virtual void set_frames_per_sec(double frames)
627 if(event_manager == NULL) {
628 event_manager = vm->first_device->next_device;
630 event_manager->set_frames_per_sec(frames);
632 virtual void set_lines_per_frame(int lines)
634 if(event_manager == NULL) {
635 event_manager = vm->first_device->next_device;
637 event_manager->set_lines_per_frame(lines);
639 // Force reder sound immediately when device's status has changed.
640 // You must call this after you changing registers (or enything).
641 // If has problems, try set_realtime_render.
642 // See mb8877.cpp and ym2203.cpp.
644 virtual void touch_sound(void)
646 if(event_manager == NULL) {
647 event_manager = vm->first_device->next_device;
649 event_manager->touch_sound();
651 // Force render per 1 sample automatically.
654 virtual void set_realtime_render(DEVICE* device = this, bool flag)
656 if(event_manager == NULL) {
657 event_manager = vm->first_device->next_device;
659 if(device != event_manager) event_manager->set_realtime_render(device, flag);
661 virtual void update_timing(int new_clocks, double new_frames_per_sec, int new_lines_per_frame) {}
664 virtual void event_callback(int event_id, int err) {}
665 virtual void event_pre_frame() {} // this event is to update timing settings
666 virtual void event_frame() {}
667 virtual void event_vline(int v, int clock) {}
668 virtual void event_hsync(int v, int h, int clock) {}
671 virtual void mix(int32_t* buffer, int cnt) {}
672 virtual void set_volume(int ch, int decibel_l, int decibel_r) {} // +1 equals +0.5dB (same as fmgen)
673 virtual void set_device_name(const _TCHAR *format, ...)
679 va_start(ap, format);
680 my_vstprintf_s(buffer, 1024, format, ap);
683 my_tcscpy_s(this_device_name, 128, buffer);
685 emu->get_osd()->set_vm_node(this_device_id, buffer);
689 virtual void out_debug_log(const char *fmt, ...)
695 vsnprintf(strbuf, 4095, fmt, ap);
696 emu->out_debug_log("%s", strbuf);
702 virtual void *get_debugger()
706 virtual uint32_t get_debug_prog_addr_mask()
710 virtual uint32_t get_debug_data_addr_mask()
714 virtual void write_debug_data8(uint32_t addr, uint32_t data) {}
715 virtual uint32_t read_debug_data8(uint32_t addr)
719 virtual void write_debug_data16(uint32_t addr, uint32_t data)
721 write_debug_data8(addr, data & 0xff);
722 write_debug_data8(addr + 1, (data >> 8) & 0xff);
724 virtual uint32_t read_debug_data16(uint32_t addr)
726 uint32_t val = read_debug_data8(addr);
727 val |= read_debug_data8(addr + 1) << 8;
730 virtual void write_debug_data32(uint32_t addr, uint32_t data)
732 write_debug_data16(addr, data & 0xffff);
733 write_debug_data16(addr + 2, (data >> 16) & 0xffff);
735 virtual uint32_t read_debug_data32(uint32_t addr)
737 uint32_t val = read_debug_data16(addr);
738 val |= read_debug_data16(addr + 2) << 16;
741 virtual void write_debug_io8(uint32_t addr, uint32_t data) {}
742 virtual uint32_t read_debug_io8(uint32_t addr)
746 virtual void write_debug_io16(uint32_t addr, uint32_t data)
748 write_debug_io8(addr, data & 0xff);
749 write_debug_io8(addr + 1, (data >> 8) & 0xff);
751 virtual uint32_t read_debug_io16(uint32_t addr)
753 uint32_t val = read_debug_io8(addr);
754 val |= read_debug_io8(addr + 1) << 8;
757 virtual void write_debug_io32(uint32_t addr, uint32_t data)
759 write_debug_io16(addr, data & 0xffff);
760 write_debug_io16(addr + 2, (data >> 16) & 0xffff);
762 virtual uint32_t read_debug_io32(uint32_t addr)
764 uint32_t val = read_debug_io16(addr);
765 val |= read_debug_io16(addr + 2) << 16;
768 virtual bool write_debug_reg(const _TCHAR *reg, uint32_t data)
772 virtual void get_debug_regs_info(_TCHAR *buffer, size_t buffer_len) {}
773 virtual int debug_dasm(uint32_t pc, _TCHAR *buffer, size_t buffer_len)
778 _TCHAR this_device_name[128];
784 #endif //USE_DEVICES_SHARED_LIB