2 EPSON QC-10 Emulator 'eQC-10'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
16 #include "../hd146818p.h"
22 #include "../pcm1bit.h"
23 #include "../upd7220.h"
24 #include "../upd765a.h"
26 #include "../z80sio.h"
29 #include "../debugger.h"
38 // ----------------------------------------------------------------------------
40 // ----------------------------------------------------------------------------
42 VM::VM(EMU* parent_emu) : emu(parent_emu)
45 first_device = last_device = NULL;
46 dummy = new DEVICE(this, emu); // must be 1st device
47 event = new EVENT(this, emu); // must be 2nd device
49 rtc = new HD146818P(this, emu);
50 dma0 = new I8237(this, emu);
51 dma1 = new I8237(this, emu);
52 pit0 = new I8253(this, emu);
53 pit1 = new I8253(this, emu);
54 pio = new I8255(this, emu);
55 pic = new I8259(this, emu);
56 io = new IO(this, emu);
57 pcm = new PCM1BIT(this, emu);
58 gdc = new UPD7220(this, emu);
59 fdc = new UPD765A(this, emu);
60 cpu = new Z80(this, emu);
61 sio = new Z80SIO(this, emu); // uPD7201
63 display = new DISPLAY(this, emu);
64 floppy = new FLOPPY(this, emu);
65 keyboard = new KEYBOARD(this, emu);
66 memory = new MEMORY(this, emu);
67 mfont = new MFONT(this, emu);
70 event->set_context_cpu(cpu);
71 event->set_context_sound(pcm);
73 rtc->set_context_intr(pic, SIG_I8259_IR2 | SIG_I8259_CHIP1, 1);
74 dma0->set_context_memory(memory);
75 dma0->set_context_ch0(fdc);
76 dma0->set_context_ch1(gdc);
77 #ifdef SINGLE_MODE_DMA
78 dma0->set_context_child_dma(dma1);
80 dma1->set_context_memory(memory);
81 pit0->set_context_ch0(memory, SIG_MEMORY_PCM, 1);
82 pit0->set_context_ch1(pic, SIG_I8259_IR5 | SIG_I8259_CHIP1, 1);
83 pit0->set_context_ch2(pic, SIG_I8259_IR1 | SIG_I8259_CHIP0, 1);
84 pit0->set_constant_clock(2, CPU_CLOCKS >> 1); // 1.9968MHz
85 pit1->set_context_ch0(pcm, SIG_PCM1BIT_SIGNAL, 1);
86 pit1->set_context_ch1(pit0, SIG_I8253_CLOCK_0, 1);
87 pit1->set_context_ch1(pit0, SIG_I8253_CLOCK_1, 1);
88 pit1->set_context_ch1(sio, SIG_Z80SIO_TX_CLK_CH0, 1);
89 pit1->set_context_ch1(sio, SIG_Z80SIO_RX_CLK_CH0, 1);
90 pit1->set_context_ch2(sio, SIG_Z80SIO_TX_CLK_CH1, 1);
91 pit1->set_context_ch2(sio, SIG_Z80SIO_RX_CLK_CH1, 1);
92 pit1->set_constant_clock(0, CPU_CLOCKS >> 1); // 1.9968MHz
93 pit1->set_constant_clock(1, CPU_CLOCKS >> 1); // 1.9968MHz
94 pit1->set_constant_clock(2, CPU_CLOCKS >> 1); // 1.9968MHz
95 pio->set_context_port_c(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 8, 0);
96 pic->set_context_cpu(cpu);
97 gdc->set_context_drq(dma0, SIG_I8237_CH1, 1);
98 gdc->set_vram_ptr(display->get_vram(), VRAM_SIZE);
99 // IR5 of I8259 #0 is from light pen
100 fdc->set_context_irq(pic, SIG_I8259_IR6 | SIG_I8259_CHIP0, 1);
101 fdc->set_context_irq(memory, SIG_MEMORY_FDC_IRQ, 1);
102 fdc->set_context_drq(dma0, SIG_I8237_CH0, 1);
103 sio->set_context_intr(pic, SIG_I8259_IR4 | SIG_I8259_CHIP0);
104 sio->set_context_send(0, keyboard, SIG_KEYBOARD_RECV);
105 // sio->set_tx_clock(0, 1200 * 16); // 1200 baud for keyboard
106 // sio->set_rx_clock(0, 1200 * 16); // clock is from 8253 ch1 (1.9968MHz/104)
107 // sio->set_tx_clock(1, 9600 * 16); // 9600 baud for RS-232C
108 // sio->set_rx_clock(1, 9600 * 16); // clock is from 8253 ch2 (1.9968MHz/13)
110 display->set_context_gdc(gdc);
111 display->set_sync_ptr(gdc->get_sync());
112 display->set_zoom_ptr(gdc->get_zoom());
113 display->set_ra_ptr(gdc->get_ra());
114 display->set_cs_ptr(gdc->get_cs());
115 display->set_ead_ptr(gdc->get_ead());
116 floppy->set_context_fdc(fdc);
117 floppy->set_context_mem(memory);
118 keyboard->set_context_sio(sio);
119 memory->set_context_pit(pit0);
120 memory->set_context_pcm(pcm);
121 memory->set_context_fdc(fdc);
122 mfont->set_context_pic(pic);
125 cpu->set_context_mem(memory);
126 cpu->set_context_io(io);
127 cpu->set_context_intr(pic);
128 #ifdef SINGLE_MODE_DMA
129 cpu->set_context_dma(dma0);
132 cpu->set_context_debugger(new DEBUGGER(this, emu));
136 io->set_iomap_range_rw(0x00, 0x03, pit0);
137 io->set_iomap_range_rw(0x04, 0x07, pit1);
138 io->set_iomap_alias_rw(0x08, pic, I8259_ADDR_CHIP0 | 0);
139 io->set_iomap_alias_rw(0x09, pic, I8259_ADDR_CHIP0 | 1);
140 io->set_iomap_alias_rw(0x0c, pic, I8259_ADDR_CHIP1 | 0);
141 io->set_iomap_alias_rw(0x0d, pic, I8259_ADDR_CHIP1 | 1);
142 io->set_iomap_alias_rw(0x10, sio, 0);
143 io->set_iomap_alias_rw(0x11, sio, 2);
144 io->set_iomap_alias_rw(0x12, sio, 1);
145 io->set_iomap_alias_rw(0x13, sio, 3);
146 io->set_iomap_range_rw(0x14, 0x17, pio);
147 io->set_iomap_range_rw(0x18, 0x1b, memory);
148 io->set_iomap_range_w(0x1c, 0x23, memory);
149 io->set_iomap_range_rw(0x2c, 0x2d, display);
150 io->set_iomap_range_r(0x30, 0x33, memory);
151 io->set_iomap_range_w(0x30, 0x33, floppy);
152 io->set_iomap_range_rw(0x34, 0x35, fdc);
153 io->set_iomap_range_rw(0x38, 0x3b, gdc);
154 io->set_iomap_range_rw(0x3c, 0x3d, rtc);
155 io->set_iomap_range_rw(0x40, 0x4f, dma0);
156 io->set_iomap_range_rw(0x50, 0x5f, dma1);
157 io->set_iomap_range_rw(0xfc, 0xfd, mfont);
159 // initialize all devices
160 for(DEVICE* device = first_device; device; device = device->next_device) {
161 device->initialize();
163 for(int i = 0; i < 4; i++) {
164 fdc->set_drive_type(i, DRIVE_TYPE_2D);
170 // delete all devices
171 for(DEVICE* device = first_device; device;) {
172 DEVICE *next_device = device->next_device;
175 device = next_device;
179 DEVICE* VM::get_device(int id)
181 for(DEVICE* device = first_device; device; device = device->next_device) {
182 if(device->this_device_id == id) {
189 // ----------------------------------------------------------------------------
190 // drive virtual machine
191 // ----------------------------------------------------------------------------
196 for(DEVICE* device = first_device; device; device = device->next_device) {
206 double VM::frame_rate()
208 return event->frame_rate();
211 // ----------------------------------------------------------------------------
213 // ----------------------------------------------------------------------------
216 DEVICE *VM::get_cpu(int index)
225 // ----------------------------------------------------------------------------
227 // ----------------------------------------------------------------------------
229 void VM::draw_screen()
231 display->draw_screen();
234 int VM::access_lamp()
236 uint32 status = fdc->read_signal(0);
237 return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
240 // ----------------------------------------------------------------------------
242 // ----------------------------------------------------------------------------
244 void VM::initialize_sound(int rate, int samples)
246 // init sound manager
247 event->initialize_sound(rate, samples);
250 pcm->init(rate, 4000);
253 uint16* VM::create_sound(int* extra_frames)
255 return event->create_sound(extra_frames);
258 int VM::sound_buffer_ptr()
260 return event->sound_buffer_ptr();
263 #ifdef USE_SOUND_VOLUME
264 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
267 pcm->set_volume(0, decibel_l, decibel_r);
272 // ----------------------------------------------------------------------------
274 // ----------------------------------------------------------------------------
276 void VM::key_down(int code, bool repeat)
278 keyboard->key_down(code);
281 void VM::key_up(int code)
283 keyboard->key_up(code);
286 // ----------------------------------------------------------------------------
288 // ----------------------------------------------------------------------------
290 void VM::open_disk(int drv, const _TCHAR* file_path, int bank)
292 fdc->open_disk(drv, file_path, bank);
295 void VM::close_disk(int drv)
297 fdc->close_disk(drv);
300 bool VM::disk_inserted(int drv)
302 return fdc->disk_inserted(drv);
305 void VM::set_disk_protected(int drv, bool value)
307 fdc->set_disk_protected(drv, value);
310 bool VM::get_disk_protected(int drv)
312 return fdc->get_disk_protected(drv);
317 return event->now_skip();
320 void VM::update_config()
322 for(DEVICE* device = first_device; device; device = device->next_device) {
323 device->update_config();
327 #define STATE_VERSION 1
329 void VM::save_state(FILEIO* state_fio)
331 state_fio->FputUint32(STATE_VERSION);
333 for(DEVICE* device = first_device; device; device = device->next_device) {
334 device->save_state(state_fio);
338 bool VM::load_state(FILEIO* state_fio)
340 if(state_fio->FgetUint32() != STATE_VERSION) {
343 for(DEVICE* device = first_device; device; device = device->next_device) {
344 if(!device->load_state(state_fio)) {