2 SHARP MZ-3500 Emulator 'EmuZ-3500'
4 Author : Takeda.Toshiya
11 #include "../../emu.h"
12 #include "../device.h"
20 #include "../pcm1bit.h"
21 #include "../upd1990a.h"
22 #include "../upd7220.h"
23 #include "../upd765a.h"
27 #include "../debugger.h"
33 // ----------------------------------------------------------------------------
35 // ----------------------------------------------------------------------------
37 VM::VM(EMU* parent_emu) : emu(parent_emu)
40 first_device = last_device = NULL;
41 dummy = new DEVICE(this, emu); // must be 1st device
42 event = new EVENT(this, emu); // must be 2nd device
45 io = new IO(this, emu);
46 fdc = new UPD765A(this, emu);
47 cpu = new Z80(this, emu);
48 main = new MAIN(this, emu);
51 sio = new I8251(this, emu);
52 pit = new I8253(this, emu);
53 pio = new I8255(this, emu);
54 subio = new IO(this, emu);
55 pcm = new PCM1BIT(this, emu);
56 rtc = new UPD1990A(this, emu);
57 gdc_chr = new UPD7220(this, emu);
58 gdc_gfx = new UPD7220(this, emu);
59 subcpu = new Z80(this, emu);
60 sub = new SUB(this, emu);
63 event->set_context_cpu(cpu);
64 event->set_context_cpu(subcpu);
65 event->set_context_sound(pcm);
68 fdc->set_context_irq(main, SIG_MAIN_INTFD, 1);
69 fdc->set_context_drq(main, SIG_MAIN_DRQ, 1);
70 fdc->set_context_index(main, SIG_MAIN_INDEX, 1);
73 sio->set_context_rxrdy(subcpu, SIG_CPU_NMI, 1);
76 // i8253 ch.0 -> i8251 txc,rxc
77 pit->set_context_ch1(pcm, SIG_PCM1BIT_SIGNAL, 1);
78 pit->set_context_ch2(pit, SIG_I8253_GATE_1, 1);
79 pit->set_constant_clock(0, 2450000);
80 pit->set_constant_clock(1, 2450000);
81 pit->set_constant_clock(2, 2450000);
83 // mz3500sm p.78,80,81
84 // i8255 pa0-pa7 -> printer data
85 pio->set_context_port_b(rtc, SIG_UPD1990A_STB, 0x01, 0);
86 pio->set_context_port_b(rtc, SIG_UPD1990A_C0, 0x02, 0);
87 pio->set_context_port_b(rtc, SIG_UPD1990A_C1, 0x04, 0);
88 pio->set_context_port_b(rtc, SIG_UPD1990A_C2, 0x08, 0);
89 pio->set_context_port_b(rtc, SIG_UPD1990A_DIN, 0x10, 0);
90 pio->set_context_port_b(rtc, SIG_UPD1990A_CLK, 0x20, 0);
91 pio->set_context_port_b(main, SIG_MAIN_SRDY, 0x40, 0);
92 pio->set_context_port_b(sub, SIG_SUB_PIO_PM, 0x80, 0); // P/M: CG Selection
93 pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_DC, 0x01, 0);
94 pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_STC, 0x02, 0);
95 pio->set_context_port_c(sub, SIG_SUB_KEYBOARD_ACKC, 0x04, 0);
96 // i8255 pc3 <- intr (not use ???)
97 pio->set_context_port_c(pcm, SIG_PCM1BIT_MUTE, 0x10, 0);
98 // i8255 pc5 -> printer strobe
99 // i8255 pc6 <- printer ack
100 pio->set_context_port_c(sub, SIG_SUB_PIO_OBF, 0x80, 0);
103 rtc->set_context_dout(sub, SIG_SUB_RTC_DOUT, 1);
105 gdc_chr->set_vram_ptr(sub->get_vram_chr(), 0x1000);
106 sub->set_sync_ptr_chr(gdc_chr->get_sync());
107 sub->set_ra_ptr_chr(gdc_chr->get_ra());
108 sub->set_cs_ptr_chr(gdc_chr->get_cs());
109 sub->set_ead_ptr_chr(gdc_chr->get_ead());
111 gdc_gfx->set_vram_ptr(sub->get_vram_gfx(), 0x20000);
112 sub->set_sync_ptr_gfx(gdc_gfx->get_sync());
113 sub->set_ra_ptr_gfx(gdc_gfx->get_ra());
114 sub->set_cs_ptr_gfx(gdc_gfx->get_cs());
115 sub->set_ead_ptr_gfx(gdc_gfx->get_ead());
118 subcpu->set_context_busack(main, SIG_MAIN_SACK, 1);
120 main->set_context_cpu(cpu);
121 main->set_context_subcpu(subcpu);
122 main->set_context_fdc(fdc);
124 sub->set_context_main(main);
125 sub->set_ipl(main->get_ipl());
126 sub->set_common(main->get_common());
129 io->set_iomap_range_rw(0xec, 0xef, main); // reset int0
130 io->set_iomap_range_rw(0xf4, 0xf7, fdc); // fdc: f4h,f6h = status, f5h,f7h = data
131 io->set_iomap_range_rw(0xf8, 0xfb, main); // mfd interface
132 io->set_iomap_range_rw(0xfc, 0xff, main); // memory mpaper
135 subio->set_iomap_range_rw(0x00, 0x0f, sub); // int0 to main (set flipflop)
136 subio->set_iomap_range_rw(0x10, 0x1f, sio);
137 subio->set_iomap_range_rw(0x20, 0x2f, pit);
138 subio->set_iomap_range_rw(0x30, 0x3f, pio);
139 subio->set_iomap_range_r(0x40, 0x4f, sub); // input port
140 subio->set_iomap_range_w(0x50, 0x5f, sub); // crt control i/o
141 subio->set_iomap_range_rw(0x60, 0x6f, gdc_gfx);
142 subio->set_iomap_range_rw(0x70, 0x7f, gdc_chr);
145 cpu->set_context_mem(main);
146 cpu->set_context_io(io);
147 cpu->set_context_intr(main);
149 cpu->set_context_debugger(new DEBUGGER(this, emu));
152 subcpu->set_context_mem(sub);
153 subcpu->set_context_io(subio);
154 subcpu->set_context_intr(sub);
156 subcpu->set_context_debugger(new DEBUGGER(this, emu));
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_2DD);
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) {
200 // set busreq of sub cpu
201 subcpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
209 double VM::frame_rate()
211 return event->frame_rate();
214 // ----------------------------------------------------------------------------
216 // ----------------------------------------------------------------------------
219 DEVICE *VM::get_cpu(int index)
223 } else if(index == 1) {
230 // ----------------------------------------------------------------------------
232 // ----------------------------------------------------------------------------
234 void VM::draw_screen()
239 int VM::access_lamp()
241 uint32 status = fdc->read_signal(0);
242 return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
245 // ----------------------------------------------------------------------------
247 // ----------------------------------------------------------------------------
249 void VM::initialize_sound(int rate, int samples)
251 // init sound manager
252 event->initialize_sound(rate, samples);
255 pcm->init(rate, 8000);
258 uint16* VM::create_sound(int* extra_frames)
260 return event->create_sound(extra_frames);
263 int VM::sound_buffer_ptr()
265 return event->sound_buffer_ptr();
268 // ----------------------------------------------------------------------------
270 // ----------------------------------------------------------------------------
272 void VM::key_down(int code, bool repeat)
277 void VM::key_up(int code)
282 // ----------------------------------------------------------------------------
284 // ----------------------------------------------------------------------------
286 void VM::open_disk(int drv, _TCHAR* file_path, int offset)
288 fdc->open_disk(drv, file_path, offset);
291 void VM::close_disk(int drv)
293 fdc->close_disk(drv);
296 bool VM::disk_inserted(int drv)
298 return fdc->disk_inserted(drv);
303 return event->now_skip();
306 void VM::update_config()
308 for(DEVICE* device = first_device; device; device = device->next_device) {
309 device->update_config();