2 MITSUBISHI Electric MULTI8 Emulator 'EmuLTI8'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
17 #include "../hd46505.h"
24 #include "../upd765a.h"
25 //#include "../ym2203.h"
26 #include "../ay_3_891x.h"
30 #include "../debugger.h"
41 using MULTI8::DISPLAY;
44 using MULTI8::KEYBOARD;
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu)
54 first_device = last_device = NULL;
55 dummy = new DEVICE(this, emu); // must be 1st device
56 event = new EVENT(this, emu); // must be 2nd device
57 dummy->set_device_name(_T("1st Dummy"));
59 beep = new BEEP(this, emu);
60 crtc = new HD46505(this, emu);
61 sio = new I8251(this, emu);
62 pit = new I8253(this, emu);
63 pio = new I8255(this, emu);
64 pic = new I8259(this, emu);
65 io = new IO(this, emu);
66 fdc = new UPD765A(this, emu);
67 fdc->set_context_noise_seek(new NOISE(this, emu));
68 fdc->set_context_noise_head_down(new NOISE(this, emu));
69 fdc->set_context_noise_head_up(new NOISE(this, emu));
70 psg = new AY_3_891X(this, emu);
72 //fdc->set_context_debugger(new DEBUGGER(this, emu));
73 //beep->set_context_debugger(new DEBUGGER(this, emu));
74 psg->set_context_debugger(new DEBUGGER(this, emu));
76 cpu = new Z80(this, emu);
78 cmt = new CMT(this, emu);
79 display = new DISPLAY(this, emu);
80 floppy = new FLOPPY(this, emu);
81 kanji = new KANJI(this, emu);
82 key = new KEYBOARD(this, emu);
83 memory = new MEMORY(this, emu);
86 event->set_context_cpu(cpu);
87 event->set_context_sound(beep);
88 event->set_context_sound(psg);
89 event->set_context_sound(fdc->get_context_noise_seek());
90 event->set_context_sound(fdc->get_context_noise_head_down());
91 event->set_context_sound(fdc->get_context_noise_head_up());
93 crtc->set_context_vsync(pio, SIG_I8255_PORT_A, 0x20);
94 sio->set_context_out(cmt, SIG_CMT_OUT);
95 pit->set_context_ch1(pit, SIG_I8253_CLOCK_2, 1);
96 pit->set_context_ch1(pic, SIG_I8259_CHIP0 | SIG_I8259_IR5, 1);
97 pit->set_context_ch2(pic, SIG_I8259_CHIP0 | SIG_I8259_IR6, 1);
98 pit->set_constant_clock(0, CPU_CLOCKS >> 1);
99 pit->set_constant_clock(1, CPU_CLOCKS >> 1);
100 pio->set_context_port_b(display, SIG_DISPLAY_I8255_B, 0xff, 0);
101 pio->set_context_port_c(memory, SIG_MEMORY_I8255_C, 0xff, 0);
102 pic->set_context_cpu(cpu);
103 fdc->set_context_irq(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
104 fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
105 psg->set_context_port_a(cmt, SIG_CMT_REMOTE, 2, 0);
106 psg->set_context_port_a(pio, SIG_I8255_PORT_A, 2, 1);
107 psg->set_context_port_a(beep, SIG_BEEP_ON, 8, 1);
109 cmt->set_context_sio(sio);
110 display->set_vram_ptr(memory->get_vram());
111 display->set_regs_ptr(crtc->get_regs());
112 floppy->set_context_fdc(fdc);
113 kanji->set_context_pio(pio);
114 memory->set_context_pio(pio);
117 cpu->set_context_mem(memory);
118 cpu->set_context_io(io);
119 cpu->set_context_intr(pic);
121 cpu->set_context_debugger(new DEBUGGER(this, emu));
125 io->set_iomap_range_rw(0x00, 0x01, key);
126 io->set_iomap_range_rw(0x18, 0x19, psg);
127 io->set_iomap_range_rw(0x1c, 0x1d, crtc);
128 io->set_iomap_range_rw(0x20, 0x21, sio);
129 io->set_iomap_range_rw(0x24, 0x27, pit);
130 io->set_iomap_range_rw(0x28, 0x2b, pio);
131 io->set_iomap_alias_rw(0x2c, pic, I8259_ADDR_CHIP0 | 0);
132 io->set_iomap_alias_rw(0x2d, pic, I8259_ADDR_CHIP0 | 1);
133 io->set_iomap_range_rw(0x30, 0x37, display);
134 io->set_iomap_range_rw(0x40, 0x41, kanji);
135 io->set_iomap_range_rw(0x70, 0x71, fdc);
136 io->set_iomap_range_rw(0x72, 0x74, floppy);
137 io->set_iomap_single_w(0x78, memory);
139 // initialize all devices
140 #if defined(__GIT_REPO_VERSION)
141 set_git_repo_version(__GIT_REPO_VERSION);
143 initialize_devices();
145 for(int i = 0; i < 4; i++) {
146 fdc->set_drive_type(i, DRIVE_TYPE_2D);
152 // delete all devices
153 for(DEVICE* device = first_device; device;) {
154 DEVICE *next_device = device->next_device;
157 device = next_device;
161 DEVICE* VM::get_device(int id)
163 for(DEVICE* device = first_device; device; device = device->next_device) {
164 if(device->this_device_id == id) {
171 // ----------------------------------------------------------------------------
172 // drive virtual machine
173 // ----------------------------------------------------------------------------
178 for(DEVICE* device = first_device; device; device = device->next_device) {
188 double VM::get_frame_rate()
190 return event->get_frame_rate();
193 // ----------------------------------------------------------------------------
195 // ----------------------------------------------------------------------------
198 DEVICE *VM::get_cpu(int index)
207 // ----------------------------------------------------------------------------
209 // ----------------------------------------------------------------------------
211 void VM::draw_screen()
213 display->draw_screen();
216 // ----------------------------------------------------------------------------
218 // ----------------------------------------------------------------------------
220 void VM::initialize_sound(int rate, int samples)
222 // init sound manager
223 event->initialize_sound(rate, samples);
226 beep->initialize_sound(rate, 2400, 8000);
227 psg->initialize_sound(rate, 3579545, samples, 0, 0);
230 uint16_t* VM::create_sound(int* extra_frames)
232 return event->create_sound(extra_frames);
235 int VM::get_sound_buffer_ptr()
237 return event->get_sound_buffer_ptr();
240 #ifdef USE_SOUND_VOLUME
241 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
244 psg->set_volume(1, decibel_l, decibel_r);
246 beep->set_volume(0, decibel_l, decibel_r);
248 fdc->get_context_noise_seek()->set_volume(0, decibel_l, decibel_r);
249 fdc->get_context_noise_head_down()->set_volume(0, decibel_l, decibel_r);
250 fdc->get_context_noise_head_up()->set_volume(0, decibel_l, decibel_r);
255 // ----------------------------------------------------------------------------
257 // ----------------------------------------------------------------------------
259 bool VM::get_caps_locked()
261 return key->get_caps_locked();
264 bool VM::get_kana_locked()
266 return key->get_kana_locked();
269 // ----------------------------------------------------------------------------
271 // ----------------------------------------------------------------------------
273 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
275 fdc->open_disk(drv, file_path, bank);
278 void VM::close_floppy_disk(int drv)
280 fdc->close_disk(drv);
283 bool VM::is_floppy_disk_inserted(int drv)
285 return fdc->is_disk_inserted(drv);
288 void VM::is_floppy_disk_protected(int drv, bool value)
290 fdc->is_disk_protected(drv, value);
293 bool VM::is_floppy_disk_protected(int drv)
295 return fdc->is_disk_protected(drv);
298 uint32_t VM::is_floppy_disk_accessed()
300 return fdc->read_signal(0);
303 void VM::play_tape(int drv, const _TCHAR* file_path)
305 cmt->play_tape(file_path);
308 void VM::rec_tape(int drv, const _TCHAR* file_path)
310 cmt->rec_tape(file_path);
313 void VM::close_tape(int drv)
318 bool VM::is_tape_inserted(int drv)
320 return cmt->is_tape_inserted();
323 bool VM::is_frame_skippable()
325 return event->is_frame_skippable();
328 void VM::update_config()
330 for(DEVICE* device = first_device; device; device = device->next_device) {
331 device->update_config();
335 double VM::get_current_usec()
337 if(event == NULL) return 0.0;
338 return event->get_current_usec();
341 uint64_t VM::get_current_clock_uint64()
343 if(event == NULL) return (uint64_t)0;
344 return event->get_current_clock_uint64();
347 #define STATE_VERSION 5
349 bool VM::process_state(FILEIO* state_fio, bool loading)
351 if(!(VM_TEMPLATE::process_state_core(state_fio, loading, STATE_VERSION))) {
354 // Machine specified.