OSDN Git Service

2367d5496e9059da55a39920577c201448c2ddf4
[csp-qt/common_source_project-fm7.git] / source / src / vm / n5200 / n5200.cpp
1 /*
2         NEC N5200 Emulator 'eN5200'
3
4         Author : Takeda.Toshiya
5         Date   : 2009.06.03-
6
7         [ virtual machine ]
8 */
9
10 #include "n5200.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../beep.h"
16 #include "../i386.h"
17 #include "../i8237.h"
18 #include "../i8251.h"
19 #include "../i8253.h"
20 #include "../i8255.h"
21 #include "../i8259.h"
22 #include "../io.h"
23 #include "../upd1990a.h"
24 #include "../upd7220.h"
25 #include "../upd765a.h"
26
27 #include "display.h"
28 #include "floppy.h"
29 #include "keyboard.h"
30 #include "memory.h"
31 #include "system.h"
32
33 // ----------------------------------------------------------------------------
34 // initialize
35 // ----------------------------------------------------------------------------
36
37 VM::VM(EMU* parent_emu) : emu(parent_emu)
38 {
39         // create devices
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
43         
44         beep = new BEEP(this, emu);
45         cpu = new I386(this, emu);
46         dma = new I8237(this, emu);
47         sio_r = new I8251(this, emu);   // for rs232c
48         sio_k = new I8251(this, emu);   // for keyboard
49         pit = new I8253(this, emu);
50         pio_s = new I8255(this, emu);   // for system port
51         pio_p = new I8255(this, emu);   // for printer
52         pic = new I8259(this, emu);
53         io = new IO(this, emu);
54         rtc = new UPD1990A(this, emu);
55         gdc_c = new UPD7220(this, emu);
56         gdc_g = new UPD7220(this, emu);
57         fdc = new UPD765A(this, emu);
58         
59         display = new DISPLAY(this, emu);
60         floppy = new FLOPPY(this, emu);
61         keyboard = new KEYBOARD(this, emu);
62         memory = new MEMORY(this, emu);
63         system = new SYSTEM(this, emu);
64         
65         // set contexts
66         event->set_context_cpu(cpu);
67         event->set_context_sound(beep);
68         
69 //???   sio_r->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR4, 1);
70         sio_k->set_context_rxrdy(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 1);
71         sio_k->set_context_rst(keyboard, SIG_KEYBOARD_RST, 1);
72         sio_k->set_context_out(keyboard, SIG_KEYBOARD_RECV);
73         pit->set_context_ch0(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 1);
74         pit->set_constant_clock(0, 1996800);
75         pit->set_constant_clock(1, 300);        // ???
76         pit->set_constant_clock(2, 1996800);
77         pio_s->set_context_port_c(beep, SIG_BEEP_MUTE, 8, 0);
78         pic->set_context_cpu(cpu);
79         rtc->set_context_dout(pio_s, SIG_I8255_PORT_B, 1);
80         dma->set_context_memory(memory);
81         dma->set_context_ch2(fdc);      // 1MB
82         dma->set_context_ch3(fdc);      // 640KB
83         gdc_g->set_vram_ptr(memory->get_vram(), 0x20000);
84         fdc->set_context_irq(pic, SIG_I8259_IR6, 1);
85         fdc->set_context_drq(floppy, SIG_FLOPPY_DRQ, 1);
86         
87         display->set_context_pic(pic);
88         display->set_vram_ptr(memory->get_vram());
89         display->set_tvram_ptr(memory->get_tvram());
90         floppy->set_context_fdc(fdc);
91         floppy->set_context_dma(dma);
92         keyboard->set_context_sio(sio_k);
93         system->set_context_dma(dma);
94         
95         // cpu bus
96         cpu->set_context_mem(memory);
97         cpu->set_context_io(io);
98         cpu->set_context_intr(pic);
99         
100         // i/o bus
101         io->set_iomap_alias_w(0x00, pic, 0);
102         io->set_iomap_alias_w(0x02, pic, 1);
103         io->set_iomap_alias_w(0x08, pic, 2);
104         io->set_iomap_alias_w(0x0a, pic, 3);
105         io->set_iomap_alias_w(0x01, dma, 0);
106         io->set_iomap_alias_w(0x03, dma, 1);
107         io->set_iomap_alias_w(0x05, dma, 2);
108         io->set_iomap_alias_w(0x07, dma, 3);
109         io->set_iomap_alias_w(0x09, dma, 4);
110         io->set_iomap_alias_w(0x0b, dma, 5);
111         io->set_iomap_alias_w(0x0d, dma, 6);
112         io->set_iomap_alias_w(0x0f, dma, 7);
113         io->set_iomap_alias_w(0x11, dma, 8);
114         io->set_iomap_alias_w(0x13, dma, 9);
115         io->set_iomap_alias_w(0x15, dma, 0x0a);
116         io->set_iomap_alias_w(0x17, dma, 0x0b);
117         io->set_iomap_alias_w(0x19, dma, 0x0c);
118         io->set_iomap_alias_w(0x1b, dma, 0x0d);
119         io->set_iomap_alias_w(0x1d, dma, 0x0e);
120         io->set_iomap_alias_w(0x1f, dma, 0x0f);
121         io->set_iomap_single_w(0x20, rtc);
122         io->set_iomap_single_w(0x21, system);
123         io->set_iomap_single_w(0x23, system);
124         io->set_iomap_single_w(0x25, system);
125         io->set_iomap_single_w(0x27, system);
126         io->set_iomap_single_w(0x29, system);
127         io->set_iomap_alias_w(0x30, sio_r, 0);
128         io->set_iomap_alias_w(0x32, sio_r, 1);
129         io->set_iomap_alias_w(0x31, pio_s, 0);
130         io->set_iomap_alias_w(0x33, pio_s, 1);
131         io->set_iomap_alias_w(0x35, pio_s, 2);
132         io->set_iomap_alias_w(0x37, pio_s, 3);
133         io->set_iomap_single_w(0x3b, system);
134         io->set_iomap_alias_w(0x40, pio_p, 0);
135         io->set_iomap_alias_w(0x42, pio_p, 1);
136         io->set_iomap_alias_w(0x44, pio_p, 2);
137         io->set_iomap_alias_w(0x46, pio_p, 3);
138         io->set_iomap_alias_w(0x41, sio_k, 0);
139         io->set_iomap_alias_w(0x43, sio_k, 1);
140         io->set_iomap_single_w(0x50, system);
141         io->set_iomap_single_w(0x52, system);
142         io->set_iomap_alias_w(0x60, gdc_c, 0);
143         io->set_iomap_alias_w(0x62, gdc_c, 1);
144         io->set_iomap_single_w(0x64, display);
145         io->set_iomap_single_w(0x68, display);
146         io->set_iomap_single_w(0x6a, display);
147         io->set_iomap_single_w(0x6c, display);
148         io->set_iomap_single_w(0x70, display);
149         io->set_iomap_single_w(0x72, display);
150         io->set_iomap_single_w(0x74, memory);
151         io->set_iomap_single_w(0x76, display);
152         io->set_iomap_single_w(0x78, display);
153         io->set_iomap_single_w(0x7a, display);
154         io->set_iomap_alias_w(0x71, pit, 0);
155         io->set_iomap_alias_w(0x73, pit, 1);
156         io->set_iomap_alias_w(0x75, pit, 2);
157         io->set_iomap_alias_w(0x77, pit, 3);
158         io->set_iomap_single_w(0x92, floppy);
159         io->set_iomap_single_w(0x94, floppy);
160         io->set_iomap_alias_w(0xa0, gdc_g, 0);
161         io->set_iomap_alias_w(0xa2, gdc_g, 1);
162         io->set_iomap_single_w(0xa4, display);
163         io->set_iomap_single_w(0xa6, display);
164         io->set_iomap_single_w(0xa8, display);
165         io->set_iomap_single_w(0xaa, display);
166         io->set_iomap_single_w(0xac, display);
167         io->set_iomap_single_w(0xae, display);
168         io->set_iomap_single_w(0xca, floppy);
169         io->set_iomap_single_w(0xcc, floppy);
170         io->set_iomap_single_w(0xbe, floppy);
171         
172         io->set_iomap_alias_r(0x00, pic, 0);
173         io->set_iomap_alias_r(0x02, pic, 1);
174         io->set_iomap_alias_r(0x08, pic, 2);
175         io->set_iomap_alias_r(0x0a, pic, 3);
176         io->set_iomap_alias_r(0x01, dma, 0);
177         io->set_iomap_alias_r(0x03, dma, 1);
178         io->set_iomap_alias_r(0x05, dma, 2);
179         io->set_iomap_alias_r(0x07, dma, 3);
180         io->set_iomap_alias_r(0x09, dma, 4);
181         io->set_iomap_alias_r(0x0b, dma, 5);
182         io->set_iomap_alias_r(0x0d, dma, 6);
183         io->set_iomap_alias_r(0x0f, dma, 7);
184         io->set_iomap_alias_r(0x11, dma, 8);
185         io->set_iomap_alias_r(0x13, dma, 9);
186         io->set_iomap_alias_r(0x15, dma, 0x0a);
187         io->set_iomap_alias_r(0x17, dma, 0x0b);
188         io->set_iomap_alias_r(0x19, dma, 0x0c);
189         io->set_iomap_alias_r(0x1b, dma, 0x0d);
190         io->set_iomap_alias_r(0x1d, dma, 0x0e);
191         io->set_iomap_alias_r(0x1f, dma, 0x0f);
192         io->set_iomap_alias_r(0x30, sio_r, 0);
193         io->set_iomap_alias_r(0x32, sio_r, 1);
194         io->set_iomap_alias_r(0x31, pio_s, 0);
195         io->set_iomap_alias_r(0x33, pio_s, 1);
196         io->set_iomap_alias_r(0x35, pio_s, 2);
197         io->set_iomap_alias_r(0x37, pio_s, 3);
198         io->set_iomap_single_r(0x39, system);
199         io->set_iomap_alias_r(0x40, pio_p, 0);
200         io->set_iomap_alias_r(0x42, pio_p, 1);
201         io->set_iomap_alias_r(0x44, pio_p, 2);
202         io->set_iomap_alias_r(0x46, pio_p, 3);
203         io->set_iomap_alias_r(0x41, sio_k, 0);
204         io->set_iomap_alias_r(0x43, sio_k, 1);
205         io->set_iomap_alias_r(0x60, gdc_c, 0);
206         io->set_iomap_alias_r(0x62, gdc_c, 1);
207         io->set_iomap_alias_r(0x71, pit, 0);
208         io->set_iomap_alias_r(0x73, pit, 1);
209         io->set_iomap_alias_r(0x75, pit, 2);
210         io->set_iomap_single_r(0x90, floppy);
211         io->set_iomap_single_r(0x92, floppy);
212         io->set_iomap_single_r(0x94, floppy);
213         io->set_iomap_alias_r(0xa0, gdc_g, 0);
214         io->set_iomap_alias_r(0xa2, gdc_g, 1);
215         io->set_iomap_single_r(0xc8, floppy);
216         io->set_iomap_single_r(0xca, floppy);
217         io->set_iomap_single_r(0xcc, floppy);
218         io->set_iomap_single_r(0xbe, floppy);
219         
220         // initialize all devices
221         for(DEVICE* device = first_device; device; device = device->next_device) {
222                 device->initialize();
223         }
224 }
225
226 VM::~VM()
227 {
228         // delete all devices
229         for(DEVICE* device = first_device; device;) {
230                 DEVICE *next_device = device->next_device;
231                 device->release();
232                 delete device;
233                 device = next_device;
234         }
235 }
236
237 DEVICE* VM::get_device(int id)
238 {
239         for(DEVICE* device = first_device; device; device = device->next_device) {
240                 if(device->this_device_id == id) {
241                         return device;
242                 }
243         }
244         return NULL;
245 }
246
247 // ----------------------------------------------------------------------------
248 // drive virtual machine
249 // ----------------------------------------------------------------------------
250
251 void VM::reset()
252 {
253         // reset all devices
254         for(DEVICE* device = first_device; device; device = device->next_device) {
255                 device->reset();
256         }
257         
258         // initial device settings
259         sio_k->write_signal(SIG_I8251_DSR, 1, 1);               // DSR = 1
260         pio_s->write_io8(3, 0x92);
261         pio_s->write_signal(SIG_I8255_PORT_A, 0x04, 0xff);      // SW = FDD
262         pio_s->write_signal(SIG_I8255_PORT_B, 0xe1, 0xff);
263         pio_p->write_io8(3, 0x82);
264         pio_p->write_signal(SIG_I8255_PORT_B, 0x51, 0xff);
265         beep->write_signal(SIG_BEEP_ON, 1, 1);
266         beep->write_signal(SIG_BEEP_MUTE, 1, 1);
267 }
268
269 void VM::run()
270 {
271         event->drive();
272 }
273
274 // ----------------------------------------------------------------------------
275 // draw screen
276 // ----------------------------------------------------------------------------
277
278 void VM::draw_screen()
279 {
280         display->draw_screen();
281 }
282
283 uint32_t VM::get_access_lamp_status()
284 {
285         uint32_t status = fdc->read_signal(0);
286         return (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
287 }
288
289 // ----------------------------------------------------------------------------
290 // soud manager
291 // ----------------------------------------------------------------------------
292
293 void VM::initialize_sound(int rate, int samples)
294 {
295         // init sound manager
296         event->initialize_sound(rate, samples);
297         
298         // init sound gen
299         beep->initialize_sound(rate, 2400, 8000);
300 }
301
302 uint16_t* VM::create_sound(int* extra_frames)
303 {
304         return event->create_sound(extra_frames);
305 }
306
307 int VM::get_sound_buffer_ptr()
308 {
309         return event->get_sound_buffer_ptr();
310 }
311
312 #ifdef USE_SOUND_VOLUME
313 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
314 {
315         if(ch == 0) {
316                 beep->set_volume(0, decibel_l, decibel_r);
317         }
318 }
319 #endif
320
321 // ----------------------------------------------------------------------------
322 // notify key
323 // ----------------------------------------------------------------------------
324
325 void VM::key_down(int code, bool repeat)
326 {
327         keyboard->key_down(code);
328 }
329
330 void VM::key_up(int code)
331 {
332         keyboard->key_up(code);
333 //      emu->out_debug_log(_T("-----\n"));
334 }
335
336 // ----------------------------------------------------------------------------
337 // user interface
338 // ----------------------------------------------------------------------------
339
340 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
341 {
342         fdc->open_disk(drv, file_path, bank);
343 }
344
345 void VM::close_floppy_disk(int drv)
346 {
347         fdc->close_disk(drv);
348 }
349
350 bool VM::is_floppy_disk_inserted(int drv)
351 {
352         return fdc->is_disk_inserted(drv);
353 }
354
355 void VM::is_floppy_disk_protected(int drv, bool value)
356 {
357         fdc->is_disk_protected(drv, value);
358 }
359
360 bool VM::is_floppy_disk_protected(int drv)
361 {
362         return fdc->is_disk_protected(drv);
363 }
364
365 bool VM::is_frame_skippable()
366 {
367         return event->is_frame_skippable();
368 }
369
370 void VM::update_config()
371 {
372         for(DEVICE* device = first_device; device; device = device->next_device) {
373                 device->update_config();
374         }
375 }
376