OSDN Git Service

62c88490041038e62b68ec9c5d7e555aa04f584d
[csp-qt/common_source_project-fm7.git] / source / src / vm / mz5500 / mz5500.cpp
1 /*\r
2         SHARP MZ-5500 Emulator 'EmuZ-5500'\r
3 \r
4         Author : Takeda.Toshiya\r
5         Date   : 2008.04.10 -\r
6 \r
7         [ virtual machine ]\r
8 */\r
9 \r
10 #include "mz5500.h"\r
11 #include "../../emu.h"\r
12 #include "../device.h"\r
13 #include "../event.h"\r
14 \r
15 #include "../disk.h"\r
16 #include "../i8237.h"\r
17 #include "../i8255.h"\r
18 #include "../i8259.h"\r
19 #include "../i286.h"\r
20 #include "../io.h"\r
21 #include "../ls393.h"\r
22 #include "../rp5c01.h"\r
23 #include "../upd7220.h"\r
24 #include "../upd765a.h"\r
25 #include "../ym2203.h"\r
26 #include "../z80ctc.h"\r
27 #include "../z80sio.h"\r
28 \r
29 #ifdef USE_DEBUGGER\r
30 #include "../debugger.h"\r
31 #endif\r
32 \r
33 #include "display.h"\r
34 #include "keyboard.h"\r
35 #include "memory.h"\r
36 #include "sysport.h"\r
37 \r
38 // ----------------------------------------------------------------------------\r
39 // initialize\r
40 // ----------------------------------------------------------------------------\r
41 \r
42 VM::VM(EMU* parent_emu) : emu(parent_emu)\r
43 {\r
44         // create devices\r
45         first_device = last_device = NULL;\r
46         dummy = new DEVICE(this, emu);  // must be 1st device\r
47         event = new EVENT(this, emu);   // must be 2nd device\r
48         \r
49         dma = new I8237(this, emu);\r
50         pio = new I8255(this, emu);\r
51         pic = new I8259(this, emu);\r
52         cpu = new I286(this, emu);\r
53         io = new IO(this, emu);\r
54         div = new LS393(this, emu);\r
55         rtc = new RP5C01(this, emu);\r
56         gdc = new UPD7220(this, emu);\r
57         fdc = new UPD765A(this, emu);\r
58         psg = new YM2203(this, emu);    // AY-3-8912\r
59         ctc0 = new Z80CTC(this, emu);\r
60 #if defined(_MZ6500) || defined(_MZ6550)\r
61         ctc1 = new Z80CTC(this, emu);\r
62 #endif\r
63         sio = new Z80SIO(this, emu);\r
64         \r
65         display = new DISPLAY(this, emu);\r
66         keyboard = new KEYBOARD(this, emu);\r
67         memory = new MEMORY(this, emu);\r
68         sysport = new SYSPORT(this, emu);\r
69         \r
70         // set contexts\r
71         event->set_context_cpu(cpu);\r
72         event->set_context_sound(psg);\r
73         \r
74         dma->set_context_memory(memory);\r
75         dma->set_context_ch1(fdc);\r
76         pio->set_context_port_c(keyboard, SIG_KEYBOARD_INPUT, 3, 0);\r
77         pic->set_context_cpu(cpu);\r
78         div->set_context_2qb(ctc0, SIG_Z80CTC_TRIG_3, 1);\r
79 #if defined(_MZ6500) || defined(_MZ6550)\r
80         div->set_context_1qb(ctc1, SIG_Z80CTC_TRIG_0, 1);\r
81         div->set_context_2qb(ctc1, SIG_Z80CTC_TRIG_1, 1);\r
82         div->set_context_2qb(ctc1, SIG_Z80CTC_TRIG_2, 1);\r
83         div->set_context_2qd(ctc1, SIG_Z80CTC_TRIG_3, 1);\r
84 #endif\r
85         rtc->set_context_alarm(pic, SIG_I8259_IR0 | SIG_I8259_CHIP1, 1);\r
86         gdc->set_vram_ptr(memory->get_vram(), 0x80000);\r
87         gdc->set_context_vsync(pic, SIG_I8259_IR0 | SIG_I8259_CHIP0, 1);\r
88         fdc->set_context_irq(pic, SIG_I8259_IR1 | SIG_I8259_CHIP1, 1);\r
89         fdc->set_context_drq(dma, SIG_I8237_CH1, 1);\r
90         psg->set_context_port_a(pic, SIG_I8259_IR7 | SIG_I8259_CHIP0, 0x20, 0);\r
91         psg->set_context_port_a(pic, SIG_I8259_IR7 | SIG_I8259_CHIP1, 0x40, 0);\r
92         psg->set_context_port_a(memory, SIG_MEMORY_BANK, 0xe0, 0);\r
93         ctc0->set_context_intr(pic, SIG_I8259_IR5 | SIG_I8259_CHIP0);\r
94         ctc0->set_context_zc0(div, SIG_LS393_CLK, 1);\r
95         ctc0->set_context_zc1(sio, SIG_Z80SIO_TX_CLK_CH0, 1);\r
96         ctc0->set_context_zc1(sio, SIG_Z80SIO_RX_CLK_CH0, 1);\r
97         ctc0->set_context_zc2(sio, SIG_Z80SIO_TX_CLK_CH1, 1);\r
98         ctc0->set_context_zc2(sio, SIG_Z80SIO_RX_CLK_CH1, 1);\r
99 #if defined(_MZ6500) || defined(_MZ6550)\r
100         ctc0->set_context_child(ctc1);\r
101         ctc1->set_context_intr(pic, SIG_I8259_IR5 | SIG_I8259_CHIP0);\r
102 #endif\r
103         sio->set_context_intr(pic, SIG_I8259_IR1 | SIG_I8259_CHIP0);\r
104         \r
105         display->set_vram_ptr(memory->get_vram());\r
106         display->set_sync_ptr(gdc->get_sync());\r
107         display->set_ra_ptr(gdc->get_ra());\r
108         display->set_cs_ptr(gdc->get_cs());\r
109         display->set_ead_ptr(gdc->get_ead());\r
110         keyboard->set_context_pio(pio);\r
111         keyboard->set_context_pic(pic);\r
112         memory->set_context_cpu(cpu);\r
113         sysport->set_context_fdc(fdc);\r
114         sysport->set_context_ctc(ctc0);\r
115         sysport->set_context_sio(sio);\r
116         \r
117         // cpu bus\r
118         cpu->set_context_mem(memory);\r
119         cpu->set_context_io(io);\r
120         cpu->set_context_intr(pic);\r
121 #ifdef SINGLE_MODE_DMA\r
122         cpu->set_context_dma(dma);\r
123 #endif\r
124 #ifdef USE_DEBUGGER\r
125         cpu->set_context_debugger(new DEBUGGER(this, emu));\r
126 #endif\r
127         \r
128         // i/o bus\r
129         io->set_iomap_range_rw(0x00, 0x0f, dma);\r
130         io->set_iomap_range_rw(0x10, 0x1f, pio);\r
131         io->set_iomap_range_rw(0x20, 0x2f, fdc);\r
132         for(int i = 0x30; i < 0x40; i += 2) {\r
133                 io->set_iomap_alias_rw(i, pic, I8259_ADDR_CHIP0 | ((i >> 1) & 1));\r
134         }\r
135         for(int i = 0x40; i < 0x50; i += 2) {\r
136                 io->set_iomap_alias_rw(i, pic, I8259_ADDR_CHIP1 | ((i >> 1) & 1));\r
137         }\r
138         io->set_iomap_range_w(0x50, 0x5f, memory);\r
139         io->set_iomap_range_r(0x60, 0x6f, sysport);\r
140         io->set_iomap_range_w(0x70, 0x7f, sysport);\r
141 #if defined(_MZ6500) || defined(_MZ6550)\r
142         io->set_iomap_single_rw(0xcd, memory);\r
143 #endif\r
144         for(int i = 0x100; i < 0x110; i += 2) {\r
145                 io->set_iomap_alias_rw(i, gdc, (i >> 1) & 1);\r
146         }\r
147         io->set_iomap_range_rw(0x110, 0x17f, display);\r
148         io->set_iomap_range_rw(0x200, 0x20f, sio);\r
149         io->set_iomap_range_rw(0x210, 0x21f, ctc0);\r
150         io->set_iomap_range_rw(0x220, 0x22f, rtc);\r
151         for(int i = 0x230; i < 0x240; i++) {\r
152                 io->set_iomap_alias_rw(i, psg, ~i & 1);\r
153         }\r
154         io->set_iomap_range_r(0x240, 0x25f, sysport);\r
155         io->set_iomap_range_w(0x260, 0x26f, sysport);\r
156         io->set_iomap_range_r(0x270, 0x27f, sysport);\r
157         \r
158         // initialize all devices\r
159         for(DEVICE* device = first_device; device; device = device->next_device) {\r
160                 device->initialize();\r
161         }\r
162         for(int i = 0; i < 4; i++) {\r
163 #if defined(_MZ6500) || defined(_MZ6550)\r
164                 fdc->set_drive_type(i, DRIVE_TYPE_2HD);\r
165 #else\r
166                 fdc->set_drive_type(i, DRIVE_TYPE_2D);\r
167 #endif\r
168         }\r
169 }\r
170 \r
171 VM::~VM()\r
172 {\r
173         // delete all devices\r
174         for(DEVICE* device = first_device; device;) {\r
175                 DEVICE *next_device = device->next_device;\r
176                 device->release();\r
177                 delete device;\r
178                 device = next_device;\r
179         }\r
180 }\r
181 \r
182 DEVICE* VM::get_device(int id)\r
183 {\r
184         for(DEVICE* device = first_device; device; device = device->next_device) {\r
185                 if(device->this_device_id == id) {\r
186                         return device;\r
187                 }\r
188         }\r
189         return NULL;\r
190 }\r
191 \r
192 // ----------------------------------------------------------------------------\r
193 // drive virtual machine\r
194 // ----------------------------------------------------------------------------\r
195 \r
196 void VM::reset()\r
197 {\r
198         // reset all devices\r
199         for(DEVICE* device = first_device; device; device = device->next_device) {\r
200                 device->reset();\r
201         }\r
202 }\r
203 \r
204 void VM::special_reset()\r
205 {\r
206         // nmi\r
207         cpu->write_signal(SIG_CPU_NMI, 1, 1);\r
208         sysport->nmi_reset();\r
209 }\r
210 \r
211 void VM::run()\r
212 {\r
213         event->drive();\r
214 }\r
215 \r
216 double VM::frame_rate()\r
217 {\r
218         return event->frame_rate();\r
219 }\r
220 \r
221 // ----------------------------------------------------------------------------\r
222 // debugger\r
223 // ----------------------------------------------------------------------------\r
224 \r
225 #ifdef USE_DEBUGGER\r
226 DEVICE *VM::get_cpu(int index)\r
227 {\r
228         if(index == 0) {\r
229                 return cpu;\r
230         }\r
231         return NULL;\r
232 }\r
233 #endif\r
234 \r
235 // ----------------------------------------------------------------------------\r
236 // draw screen\r
237 // ----------------------------------------------------------------------------\r
238 \r
239 void VM::draw_screen()\r
240 {\r
241         display->draw_screen();\r
242 }\r
243 \r
244 int VM::access_lamp()\r
245 {\r
246         uint32 status = fdc->read_signal(0);\r
247         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;\r
248 }\r
249 \r
250 // ----------------------------------------------------------------------------\r
251 // soud manager\r
252 // ----------------------------------------------------------------------------\r
253 \r
254 void VM::initialize_sound(int rate, int samples)\r
255 {\r
256         // init sound manager\r
257         event->initialize_sound(rate, samples);\r
258         \r
259         // init sound gen\r
260         psg->init(rate, 4000000, samples, 0, 0);\r
261 }\r
262 \r
263 uint16* VM::create_sound(int* extra_frames)\r
264 {\r
265         return event->create_sound(extra_frames);\r
266 }\r
267 \r
268 int VM::sound_buffer_ptr()\r
269 {\r
270         return event->sound_buffer_ptr();\r
271 }\r
272 \r
273 // ----------------------------------------------------------------------------\r
274 // notify key\r
275 // ----------------------------------------------------------------------------\r
276 \r
277 void VM::key_down(int code, bool repeat)\r
278 {\r
279         keyboard->key_down(code);\r
280 }\r
281 \r
282 void VM::key_up(int code)\r
283 {\r
284 //      keyboard->key_up(code);\r
285 }\r
286 \r
287 // ----------------------------------------------------------------------------\r
288 // user interface\r
289 // ----------------------------------------------------------------------------\r
290 \r
291 void VM::open_disk(int drv, _TCHAR* file_path, int offset)\r
292 {\r
293         fdc->open_disk(drv, file_path, offset);\r
294 }\r
295 \r
296 void VM::close_disk(int drv)\r
297 {\r
298         fdc->close_disk(drv);\r
299 }\r
300 \r
301 bool VM::disk_inserted(int drv)\r
302 {\r
303         return fdc->disk_inserted(drv);\r
304 }\r
305 \r
306 bool VM::now_skip()\r
307 {\r
308         return event->now_skip();\r
309 }\r
310 \r
311 void VM::update_config()\r
312 {\r
313         for(DEVICE* device = first_device; device; device = device->next_device) {\r
314                 device->update_config();\r
315         }\r
316 }\r
317 \r