OSDN Git Service

[VM][UI][Qt] General : Merge upstream 2015-08-01.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmr30 / fmr30.cpp
1 /*
2         FUJITSU FMR-30 Emulator 'eFMR-30'
3
4         Author : Takeda.Toshiya
5         Date   : 2008.12.29 -
6
7         [ virtual machine ]
8 */
9
10 #include "fmr30.h"
11 #include "../../emu.h"
12 #include "../device.h"
13 #include "../event.h"
14
15 #include "../i8237.h"
16 #include "../i8251.h"
17 #include "../i8253.h"
18 #include "../i8259.h"
19 #include "../i286.h"
20 #include "../io.h"
21 #include "../mb8877.h"
22 #include "../sn76489an.h"
23
24 #ifdef USE_DEBUGGER
25 #include "../debugger.h"
26 #endif
27
28 #include "../fmr50/bios.h"
29 #include "cmos.h"
30 #include "floppy.h"
31 #include "keyboard.h"
32 #include "memory.h"
33 #include "rtc.h"
34 //#include "scsi.h"
35 #include "serial.h"
36 #include "system.h"
37 #include "timer.h"
38
39 // ----------------------------------------------------------------------------
40 // initialize
41 // ----------------------------------------------------------------------------
42
43 VM::VM(EMU* parent_emu) : emu(parent_emu)
44 {
45         // create devices
46         first_device = last_device = NULL;
47         dummy = new DEVICE(this, emu);  // must be 1st device
48         event = new EVENT(this, emu);   // must be 2nd device
49         
50         dma = new I8237(this, emu);
51         sio_kb = new I8251(this, emu);  // keyboard
52         sio_sub = new I8251(this, emu); // sub display
53         sio_ch1 = new I8251(this, emu); // RS-232C ch.1
54         sio_ch2 = new I8251(this, emu); // RS-232C ch.2
55         pit = new I8253(this, emu);
56         pic = new I8259(this, emu);
57         cpu = new I286(this, emu);
58         io = new IO(this, emu);
59         fdc = new MB8877(this, emu);
60         psg = new SN76489AN(this, emu);
61         
62         bios = new BIOS(this, emu);
63         cmos = new CMOS(this, emu);
64         floppy = new FLOPPY(this, emu);
65         keyboard = new KEYBOARD(this, emu);
66         memory = new MEMORY(this, emu);
67         rtc = new RTC(this, emu);
68 //      scsi = new SCSI(this, emu);
69         serial = new SERIAL(this, emu);
70         system = new SYSTEM(this, emu);
71         timer = new TIMER(this, emu);
72         
73         // set contexts
74         event->set_context_cpu(cpu);
75         event->set_context_sound(psg);
76         
77         dma->set_context_memory(memory);
78         dma->set_context_ch0(fdc);
79 //      dma->set_context_ch1(scsi);
80         sio_kb->set_context_rxrdy(serial, SIG_SERIAL_RXRDY_KB, 1);
81         sio_kb->set_context_txrdy(serial, SIG_SERIAL_TXRDY_KB, 1);
82         sio_sub->set_context_rxrdy(serial, SIG_SERIAL_RXRDY_SUB, 1);
83         sio_sub->set_context_txrdy(serial, SIG_SERIAL_TXRDY_SUB, 1);
84         sio_ch1->set_context_rxrdy(serial, SIG_SERIAL_RXRDY_CH1, 1);
85         sio_ch1->set_context_txrdy(serial, SIG_SERIAL_TXRDY_CH1, 1);
86         sio_ch2->set_context_rxrdy(serial, SIG_SERIAL_RXRDY_CH2, 1);
87         sio_ch2->set_context_txrdy(serial, SIG_SERIAL_TXRDY_CH2, 1);
88         pit->set_context_ch0(timer, SIG_TIMER_CH0, 1);
89         pit->set_context_ch1(timer, SIG_TIMER_CH1, 1);
90         pit->set_constant_clock(0, 1000000);
91         pit->set_constant_clock(1, 1000000);
92         pic->set_context_cpu(cpu);
93 //      fdc->set_context_drq(dma, SIG_I8237_CH0, 1);
94         fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
95         
96         bios->set_context_mem(memory);
97         bios->set_context_io(io);
98         bios->set_cmos_ptr(cmos->get_cmos());
99         bios->set_vram_ptr(memory->get_vram());
100         bios->set_cvram_ptr(memory->get_cvram());
101         bios->set_kvram_ptr(memory->get_kvram());
102         floppy->set_context_fdc(fdc);
103         floppy->set_context_pic(pic);
104         keyboard->set_context_sio(sio_kb);
105         memory->set_context_cpu(cpu);
106         memory->set_context_dma(dma);
107         rtc->set_context_pic(pic);
108 //      scsi->set_context_dma(dma, SIG_I8237_CH1);
109 //      scsi->set_context_pic(pic, SIG_I8259_CHIP1 | SIG_I8259_IR2);
110         serial->set_context_pic(pic);
111         serial->set_context_sio(sio_kb, sio_sub, sio_ch1, sio_ch2);
112         timer->set_context_pic(pic);
113         
114         // cpu bus
115         cpu->set_context_mem(memory);
116         cpu->set_context_io(io);
117         cpu->set_context_intr(pic);
118         cpu->set_context_bios(bios);
119 #ifdef SINGLE_MODE_DMA
120         cpu->set_context_dma(dma);
121 #endif
122 #ifdef USE_DEBUGGER
123         cpu->set_context_debugger(new DEBUGGER(this, emu));
124 #endif
125         
126         // i/o bus
127         io->set_iomap_range_rw(0x00, 0x07, rtc);
128         io->set_iomap_range_rw(0x08, 0x09, sio_kb);
129         io->set_iomap_range_rw(0x0a, 0x0b, serial);
130         io->set_iomap_range_rw(0x10, 0x11, sio_sub);
131         io->set_iomap_range_rw(0x12, 0x13, serial);
132         io->set_iomap_single_r(0x18, system);
133         io->set_iomap_range_rw(0x1d, 0x1e, memory);
134         io->set_iomap_range_r(0x20, 0x21, system);
135         io->set_iomap_single_rw(0x26, memory);
136         io->set_iomap_range_rw(0x30, 0x33, fdc);
137         io->set_iomap_range_rw(0x34, 0x36, floppy);
138         io->set_iomap_single_w(0x40, psg);
139         io->set_iomap_range_rw(0x42, 0x43, timer);
140         io->set_iomap_range_rw(0x46, 0x47, system);
141         io->set_iomap_range_rw(0x60, 0x61, sio_ch1);
142         io->set_iomap_range_rw(0x62, 0x66, serial);
143         io->set_iomap_range_rw(0x70, 0x71, sio_ch2);
144         io->set_iomap_range_rw(0x72, 0x76, serial);
145         io->set_iomap_alias_rw(0x100, pic, I8259_ADDR_CHIP0 | 0);
146         io->set_iomap_alias_rw(0x101, pic, I8259_ADDR_CHIP0 | 1);
147         io->set_iomap_alias_rw(0x108, pic, I8259_ADDR_CHIP1 | 0);
148         io->set_iomap_alias_rw(0x10a, pic, I8259_ADDR_CHIP1 | 1);
149         io->set_iomap_range_rw(0x110, 0x11f, dma);
150         io->set_iomap_range_w(0x120, 0x123, memory);
151         io->set_iomap_range_rw(0x130, 0x133, pit);
152 //      io->set_iomap_range_rw(0x2f0, 0x2f3, scsi);
153         io->set_iomap_range_rw(0x300, 0x30f, memory);
154         io->set_iomap_range_rw(0xc000, 0xdfff, cmos);
155         io->set_iomap_single_rw(0xff00, system);
156         
157         // initialize all devices
158         for(DEVICE* device = first_device; device; device = device->next_device) {
159                 device->initialize();
160         }
161         for(int i = 0; i < MAX_DRIVE; i++) {
162                 bios->set_disk_handler(i, fdc->get_disk_handler(i));
163         }
164 }
165
166 VM::~VM()
167 {
168         // delete all devices
169         for(DEVICE* device = first_device; device;) {
170                 DEVICE *next_device = device->next_device;
171                 device->release();
172                 delete device;
173                 device = next_device;
174         }
175 }
176
177 DEVICE* VM::get_device(int id)
178 {
179         for(DEVICE* device = first_device; device; device = device->next_device) {
180                 if(device->this_device_id == id) {
181                         return device;
182                 }
183         }
184         return NULL;
185 }
186
187 // ----------------------------------------------------------------------------
188 // drive virtual machine
189 // ----------------------------------------------------------------------------
190
191 void VM::reset()
192 {
193         // reset all devices
194         for(DEVICE* device = first_device; device; device = device->next_device) {
195                 device->reset();
196         }
197         // temporary fix...
198         for(DEVICE* device = first_device; device; device = device->next_device) {
199                 device->reset();
200         }
201         
202         // set devices
203         sio_kb->write_signal(SIG_I8251_DSR, 1, 1);
204         sio_sub->write_signal(SIG_I8251_DSR, 0, 0);
205 }
206
207 void VM::run()
208 {
209         event->drive();
210 }
211
212 // ----------------------------------------------------------------------------
213 // debugger
214 // ----------------------------------------------------------------------------
215
216 #ifdef USE_DEBUGGER
217 DEVICE *VM::get_cpu(int index)
218 {
219         if(index == 0) {
220                 return cpu;
221         }
222         return NULL;
223 }
224 #endif
225
226 // ----------------------------------------------------------------------------
227 // draw screen
228 // ----------------------------------------------------------------------------
229
230 void VM::draw_screen()
231 {
232         memory->draw_screen();
233 }
234
235 int VM::access_lamp()
236 {
237         uint32 status = fdc->read_signal(0) | bios->read_signal(0);
238         return (status & 0x10) ? 4 : (status & (1 | 4)) ? 1 : (status & (2 | 8)) ? 2 : 0;
239 }
240
241 // ----------------------------------------------------------------------------
242 // soud manager
243 // ----------------------------------------------------------------------------
244
245 void VM::initialize_sound(int rate, int samples)
246 {
247         // init sound manager
248         event->initialize_sound(rate, samples);
249         
250         // init sound gen
251         psg->init(rate, 125000, 10000);
252 }
253
254 uint16* VM::create_sound(int* extra_frames)
255 {
256         return event->create_sound(extra_frames);
257 }
258
259 int VM::sound_buffer_ptr()
260 {
261         return event->sound_buffer_ptr();
262 }
263
264 // ----------------------------------------------------------------------------
265 // notify key
266 // ----------------------------------------------------------------------------
267
268 void VM::key_down(int code, bool repeat)
269 {
270         keyboard->key_down(code);
271 }
272
273 void VM::key_up(int code)
274 {
275         keyboard->key_up(code);
276 }
277
278 // ----------------------------------------------------------------------------
279 // user interface
280 // ----------------------------------------------------------------------------
281
282 void VM::open_disk(int drv, _TCHAR* file_path, int bank)
283 {
284         fdc->open_disk(drv, file_path, bank);
285         floppy->change_disk(drv);
286 }
287
288 void VM::close_disk(int drv)
289 {
290         fdc->close_disk(drv);
291 }
292
293 bool VM::disk_inserted(int drv)
294 {
295         return fdc->disk_inserted(drv);
296 }
297
298 void VM::set_disk_protected(int drv, bool value)
299 {
300         fdc->set_disk_protected(drv, value);
301 }
302
303 bool VM::get_disk_protected(int drv)
304 {
305         return fdc->get_disk_protected(drv);
306 }
307
308 bool VM::now_skip()
309 {
310         return event->now_skip();
311 }
312
313 void VM::update_config()
314 {
315         for(DEVICE* device = first_device; device; device = device->next_device) {
316                 device->update_config();
317         }
318 }
319
320 #define STATE_VERSION   1
321
322 void VM::save_state(FILEIO* state_fio)
323 {
324         state_fio->FputUint32(STATE_VERSION);
325         
326         for(DEVICE* device = first_device; device; device = device->next_device) {
327                 device->save_state(state_fio);
328         }
329 }
330
331 bool VM::load_state(FILEIO* state_fio)
332 {
333         if(state_fio->FgetUint32() != STATE_VERSION) {
334                 return false;
335         }
336         for(DEVICE* device = first_device; device; device = device->next_device) {
337                 if(!device->load_state(state_fio)) {
338                         return false;
339                 }
340         }
341         return true;
342 }
343