OSDN Git Service

[VM][FMTOWNS][JOYSTICK][MOUSE] Re-Implement mouse.Still not working.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fmtowns / fmtowns.cpp
1 /*
2         FUJITSU FM-Towns Emulator 'eFMTowns'
3
4         Author : Kyuma Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2016.12.28 -
6
7         [ virtual machine ]
8         History: 
9                 2016-12-28 Copy from eFMR-50.
10 */
11
12 #include "fmtowns.h"
13 #include "../../emu.h"
14 #include "../device.h"
15 #include "../event.h"
16
17 //#include "../hd46505.h"
18 #include "../i8251.h"
19 #include "../i8253.h"
20 #include "../i8259.h"
21
22 #include "../i386_np21.h"
23 //#include "../i386.h"
24
25 #include "../io.h"
26 #include "../mb8877.h"
27 #include "../msm58321.h"
28 #include "../noise.h"
29 #include "../pcm1bit.h"
30 #include "../harddisk.h"
31 #include "../scsi_hdd.h"
32 #include "./towns_scsi_host.h"
33 #include "../upd71071.h"
34
35 #include "./cdrom.h"
36 #include "./crtc.h"
37 #include "./dictionary.h"
38 #include "./dmac.h"
39 #include "./towns_memory.h"
40 #include "./sprite.h"
41 #include "./sysrom.h"
42 #include "./vram.h"
43
44 // Electric Volume
45 //#include "mb87078.h"
46 //YM-2612 "OPN2"
47 //#include "../ym2612.h"
48 //RF5C68 PCM
49 #include "rf5c68.h"
50 //AD7820 ADC
51 #include "ad7820kr.h"
52 #include "ym2612.h"
53 // 80387?
54
55 #ifdef USE_DEBUGGER
56 #include "../debugger.h"
57 #endif
58
59 #include "./adpcm.h"
60 //#include "./cdc.h"
61 #include "./floppy.h"
62 #include "./fontroms.h"
63 #include "./joystick.h"
64 #include "./joypad_2btn.h"
65 #include "./joypad_6btn.h"
66 #include "./keyboard.h"
67 #include "./mouse.h"
68 #include "./msdosrom.h"
69 #include "./scsi.h"
70 #include "./serialrom.h"
71 #include "./timer.h"
72 #include "./iccard.h"
73
74 #include "./planevram.h"
75
76 // ----------------------------------------------------------------------------
77 // initialize
78 // ----------------------------------------------------------------------------
79 using FMTOWNS::ADPCM;
80 //using FMTOWNS::CDC;
81 using FMTOWNS::DICTIONARY;
82 using FMTOWNS::FLOPPY;
83 using FMTOWNS::FONT_ROMS;
84 using FMTOWNS::JOYSTICK;
85 using FMTOWNS::JOYPAD_2BTN;
86 using FMTOWNS::JOYPAD_6BTN;
87
88 using FMTOWNS::KEYBOARD;
89 using FMTOWNS::MOUSE;
90 using FMTOWNS::MSDOSROM;
91 using FMTOWNS::SCSI;
92 using FMTOWNS::SERIAL_ROM;
93 using FMTOWNS::SYSROM;
94 using FMTOWNS::TIMER;
95 using FMTOWNS::TOWNS_ICCARD;
96
97 using FMTOWNS::TOWNS_CDROM;
98 using FMTOWNS::TOWNS_CRTC;
99 using FMTOWNS::TOWNS_DMAC;
100 using FMTOWNS::TOWNS_MEMORY;
101 using FMTOWNS::TOWNS_SCSI_HOST;
102 using FMTOWNS::TOWNS_SPRITE;
103 using FMTOWNS::TOWNS_VRAM;
104 using FMTOWNS::PLANEVRAM;
105
106
107 VM::VM(EMU_TEMPLATE* parent_emu) : VM_TEMPLATE(parent_emu)
108 {
109 /*
110         Machine ID & CPU ID
111
112         FMR-50FD/HD/LT  0xF8
113         FMR-50FX/HX     0xE0
114         FMR-50SFX/SHX   0xE8
115         FMR-50LT        0xF8
116         FMR-50NBX       0x28
117         FMR-50NB        0x60
118         FMR-50NE/T      0x08
119         FMR-CARD        0x70
120
121         80286           0x00
122         80386           0x01
123         80386SX         0x03
124         80486           0x02
125 */
126         
127         // create devices
128         first_device = last_device = NULL;
129         dummy = new DEVICE(this, emu);  // must be 1st device
130         event = new EVENT(this, emu);   // must be 2nd device
131 #if defined(_USE_QT)
132         dummy->set_device_name(_T("1st Dummy"));
133         event->set_device_name(_T("EVENT"));
134 #endif  
135
136         cpu = new I386(this, emu);
137 #if defined(_USE_QT)
138   #if defined(HAS_I386)
139         cpu->set_device_name(_T("CPU(i386)"));
140   #elif defined(HAS_I486)
141         cpu->set_device_name(_T("CPU(i486)"));
142   #elif defined(HAS_PENTIUM)
143         cpu->set_device_name(_T("CPU(Pentium)"));
144   #endif
145 #endif  
146
147         io = new IO(this, emu);
148         
149         crtc = new TOWNS_CRTC(this, emu);
150         cdrom = new TOWNS_CDROM(this, emu);
151
152         memory = new TOWNS_MEMORY(this, emu);
153         vram = new TOWNS_VRAM(this, emu);
154         sprite = new TOWNS_SPRITE(this, emu);
155         sysrom = new SYSROM(this, emu);
156         msdosrom = new MSDOSROM(this, emu);
157         fontrom = new FONT_ROMS(this, emu);
158         dictionary = new DICTIONARY(this, emu);
159 #if defined(HAS_20PIX_FONTS)
160         fontrom_20pix = new FONT_ROM_20PIX(this, emu);
161 #endif
162         serialrom = new SERIAL_ROM(this, emu);
163
164         adpcm = new ADPCM(this, emu);
165 //      mixer = new MIXER(this, emu); // Pseudo mixer.
166
167         planevram = new PLANEVRAM(this, emu);
168         
169         adc = new AD7820KR(this, emu);
170         rf5c68 = new RF5C68(this, emu);
171 //      e_volume[0] = new MB87878(this, emu);
172 //      e_volume[1] = new MB87878(this, emu);
173         
174         sio = new I8251(this, emu);
175         pit0 = new I8253(this, emu);
176         pit1 = new I8253(this, emu);
177         pic = new I8259(this, emu);
178         fdc = new MB8877(this, emu);
179         rtc = new MSM58321(this, emu);
180         beep = new PCM1BIT(this, emu);
181         opn2 = new YM2612(this, emu);
182
183         seek_sound = new NOISE(this, emu);
184         head_up_sound = new NOISE(this, emu);
185         head_down_sound = new NOISE(this, emu);
186         
187 //      scsi_host = new TOWNS_SCSI_HOST(this, emu);
188         scsi_host = new SCSI_HOST(this, emu);
189         
190         for(int i = 0; i < 7; i++) {
191                 scsi_hdd[i] = NULL;
192         }       
193 #if defined(USE_HARD_DISK)
194         for(int i = 0; i < USE_HARD_DISK; i++) {
195                 scsi_hdd[i] = new SCSI_HDD(this, emu);
196                 scsi_hdd[i]->set_device_name(_T("SCSI Hard Disk Drive #%d"), i + 1);
197                 scsi_hdd[i]->scsi_id = i ;
198                 scsi_hdd[i]->set_disk_handler(0, new HARDDISK(emu));
199                 scsi_hdd[i]->set_context_interface(scsi_host);
200                 my_sprintf_s(scsi_hdd[i]->vendor_id, 9, "FUJITSU");
201                 my_sprintf_s(scsi_hdd[i]->product_id, 17, "SCSI-HDD");
202                 scsi_host->set_context_target(scsi_hdd[i]);
203         }
204 #endif
205         dma = new TOWNS_DMAC(this, emu);
206         extra_dma = new TOWNS_DMAC(this, emu);
207
208         floppy = new FLOPPY(this, emu);
209         keyboard = new KEYBOARD(this, emu);
210         joystick = new JOYSTICK(this, emu);
211         scsi = new SCSI(this, emu);
212         timer = new TIMER(this, emu);
213
214         iccard1 = new TOWNS_ICCARD(this, emu);
215 #if 0
216         iccard2 = new TOWNS_ICCARD(this, emu);
217 #else
218         iccard2 = NULL;
219 #endif
220         for(int i = 0; i < 2; i++) {
221                 joypad_2btn[i] = new JOYPAD_2BTN(this, emu);
222                 joypad_6btn[i] = new JOYPAD_6BTN(this, emu);
223                 mouse[i] = new MOUSE(this, emu);
224         }
225
226         uint16_t machine_id = 0x0100; // FM-Towns1
227         uint16_t cpu_id = 0x0001;     // i386DX
228         uint32_t cpu_clock = 16000 * 1000; // 16MHz
229 #if defined(_FMTOWNS1_2ND_GEN)
230         machine_id = 0x0200;   // 1F/2F/1H/2H
231 #elif defined(_FMTOWNS_UX_VARIANTS)
232         machine_id = 0x0300;   // UX10/20/40
233         cpu_id = 0x0003;       // i386SX
234 #elif defined(_FMTOWNS1_3RD_GEN)
235         machine_id = 0x0400;  // 10F/20F.40H/80H
236 #elif defined(_FMTOWNS2_CX_VARIANTS)
237         machine_id = 0x0500;  // CX10/20/30/40
238 #elif defined(_FMTOWNS_UG_VARIANTS)
239         machine_id = 0x0600;  // UG10/20/40/80
240         cpu_id = 0x0003;      // i386SX
241         cpu_clock = 20000 * 1000; // 20MHz
242 #elif defined(_FMTOWNS_HR_VARIANTS)
243         machine_id = 0x0700;
244         cpu_id = 0x0002;      // i486SX
245         cpu_clock = 20000 * 1000; // 20MHz
246 #elif defined(_FMTOWNS_HG_VARIANTS)
247         machine_id = 0x0800;
248         cpu_clock = 20000 * 1000; // 20MHz
249 #elif defined(_FMTOWNS_SG_VARIANTS)
250         machine_id = 0x0800; // OK?
251 #elif defined(_FMTOWNS_SR_VARIANTS)
252         machine_id = 0x0700; // OK?
253         cpu_id = 0x0002;      // i486SX
254         cpu_clock = 20000 * 1000; // 20MHz
255 #elif defined(_FMTOWNS_UR_VARIANTS)
256         machine_id = 0x0900;  // UR10/20/40/80
257         cpu_id = 0x0002;      // i486DX
258         cpu_clock = 20000 * 1000; // ToDo: Correct frequency.
259 #elif defined(_FMTOWNS_MA_VARIANTS)
260         machine_id = 0x0b00; // OK?
261         cpu_id = 0x0002;      // i486SX
262         cpu_clock = 33000 * 1000; // 33MHz
263 #elif defined(_FMTOWNS_ME_VARIANTS)
264         machine_id = 0x0d00; // OK?
265         cpu_id = 0x0002;      // i486SX
266         cpu_clock = 25000 * 1000; // 25MHz
267 #elif defined(_FMTOWNS_MF_VARIANTS)
268         machine_id = 0x0f00; // OK?
269         cpu_id = 0x0002;      // i486SX
270         cpu_clock = 33000 * 1000; // 33MHz
271 #elif defined(_FMTOWNS_MX_VARIANTS)
272         machine_id = 0x0c00; // OK?
273         cpu_id = 0x0002;      // i486DX (With FPU?)
274         cpu_clock = 66000 * 1000; // 66MHz
275 #elif defined(_FMTOWNS_HC_VARIANTS)
276         // 20210227 K.O
277         // From FMTowns::MachineID()  of TSUGARU,
278         // git 83d4ec2309ac9fcbb8c01f26061ff0d49c5321e4.
279         machine_id = 0x1100; // OK?
280         cpu_id = 0x0002;      // Pentium (With FPU?)
281         cpu_clock = 50000 * 1000; // ToDo: Correctness frequency.
282 #else
283         // ToDo: Pentium Model (After HB).
284
285 #endif
286
287         event->set_frames_per_sec(FRAMES_PER_SEC);
288         event->set_lines_per_frame(LINES_PER_FRAME);
289         
290         set_machine_type(machine_id, cpu_id);
291         // set contexts
292         event->set_context_cpu(cpu, cpu_clock);
293
294         adc_in_ch = -1;
295         line_in_ch = -1;
296         modem_in_ch = -1;
297         mic_in_ch = -1;
298
299         // Use pseudo mixer instead of event.Due to using ADC.
300 #if 0
301         line_mix_ch = -1;
302         modem_mix_ch = -1;
303         mic_mix_ch = -1;
304         //line_mix_ch = mixer->set_context_sound(line_in);
305         //modem_mix_ch = mixer->set_context_sound(modem_in);
306         //mic_mix_ch = mixer->set_context_sound(mic_in);
307         beep_mix_ch = mixer->set_context_sound(beep);
308         pcm_mix_ch  = mixer->set_context_sound(rf5c68);
309         opn2_mix_ch = mixer->set_context_sound(opn2);
310         cdc_mix_ch = mixer->set_context_sound(cdrom);
311         mixer->set_interpolate_filter_freq(pcm_mix_ch, 4000); // channel, freq; disable if freq <= 0.
312         event->set_context_sound(mixer);
313 #else
314         // Temporally not use mixer.
315         event->set_context_sound(beep);
316         event->set_context_sound(opn2);
317         event->set_context_sound(rf5c68);
318         event->set_context_sound(cdrom);
319 #endif
320         fdc->set_context_noise_seek(seek_sound);
321         fdc->set_context_noise_head_down(head_down_sound);
322         fdc->set_context_noise_head_up(head_up_sound);
323         event->set_context_sound(seek_sound);
324         event->set_context_sound(head_down_sound);
325         event->set_context_sound(head_up_sound);
326         
327 #ifdef USE_DEBUGGER
328         pit0->set_context_debugger(new DEBUGGER(this, emu));
329         pit1->set_context_debugger(new DEBUGGER(this, emu));
330 #endif  
331         pit0->set_context_ch0(timer, SIG_TIMER_CH0, 1);
332         pit0->set_context_ch1(timer, SIG_TIMER_CH1, 1);
333         pit0->set_context_ch2(beep,  SIG_PCM1BIT_SIGNAL, 1);
334         pit0->set_constant_clock(0, 307200);
335         pit0->set_constant_clock(1, 307200);
336         pit0->set_constant_clock(2, 307200);
337         pit1->set_constant_clock(0, 1229900);
338         pit1->set_constant_clock(1, 1229900);
339         pit1->set_constant_clock(2, 1229900);
340 //      pic->set_context_cpu(cpu);
341         pic->set_context_cpu(memory);
342         fdc->set_context_irq(floppy, SIG_FLOPPY_IRQ, 1);
343         rtc->set_context_data(timer, SIG_TIMER_RTC, 0x0f, 0);
344         rtc->set_context_busy(timer, SIG_TIMER_RTC_BUSY, 0x80);
345         scsi_host->set_context_irq(scsi, SIG_SCSI_IRQ, 1);
346         scsi_host->set_context_drq(scsi, SIG_SCSI_DRQ, 1);
347         scsi_host->set_context_drq(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1);
348         
349         dma->set_context_memory(memory);
350         dma->set_context_ch0(fdc);
351         dma->set_context_ch1(scsi_host);
352         //dma->set_context_ch2(printer);
353         dma->set_context_ch3(cdrom);
354         dma->set_context_tc1(scsi, SIG_SCSI_EOT, 0xffffffff);
355         dma->set_context_tc3(cdrom, SIG_TOWNS_CDROM_DMAINT, 0xffffffff);
356         dma->set_context_ack3(cdrom, SIG_TOWNS_CDROM_DMAACK, 0xffffffff);
357         
358         dma->set_context_ube1(scsi_host, SIG_SCSI_16BIT_BUS, 0x02);
359         
360         dma->set_context_child_dma(extra_dma);
361         
362         floppy->set_context_fdc(fdc);
363         
364         sprite->set_context_vram(vram); 
365         sprite->set_context_font(fontrom);
366         sprite->set_context_crtc(crtc);
367 #ifdef USE_DEBUGGER
368         sprite->set_context_debugger(new DEBUGGER(this, emu));
369 #endif
370         
371         vram->set_context_sprite(sprite);
372         vram->set_context_crtc(crtc);
373         
374         planevram->set_context_vram(vram);
375         planevram->set_context_sprite(sprite);
376         planevram->set_context_crtc(crtc);
377         
378         crtc->set_context_sprite(sprite);
379         crtc->set_context_vram(vram);
380         crtc->set_context_font(fontrom);
381
382         //e_volume[0]->set_context_ch0(line_in, MB87878_VOLUME_LEFT);
383         //e_volume[0]->set_context_ch1(line_in, MB87878_VOLUME_RIGHT);
384         //e_volume[0]->set_context_ch2(NULL, MB87878_VOLUME_LEFT);
385         //e_volume[0]->set_context_ch3(NULL, MB87878_VOLUME_RIGHT);
386 //      e_volume[1]->set_context_ch0(cdrom, MB87878_VOLUME_LEFT);
387 //      e_volume[1]->set_context_ch1(cdrom, MB87878_VOLUME_RIGHT);
388         //e_volume[1]->set_context_ch2(mic, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT);
389         //e_volume[1]->set_context_ch3(modem, MB87878_VOLUME_LEFT | MB87878_VOLUME_RIGHT);
390         
391         memory->set_context_cpu(cpu);
392         memory->set_context_dmac(dma);
393         memory->set_context_vram(vram);
394         memory->set_context_planevram(planevram);
395         memory->set_context_crtc(crtc);
396         memory->set_context_system_rom(sysrom);
397         memory->set_context_msdos(msdosrom);
398         memory->set_context_dictionary(dictionary);
399         memory->set_context_font_rom(fontrom);
400         memory->set_context_timer(timer);
401         memory->set_context_serial_rom(serialrom);
402         memory->set_context_sprite(sprite);
403         memory->set_context_pcm(rf5c68);
404         memory->set_context_iccard(iccard1, 0);
405         memory->set_context_iccard(iccard2, 1);
406
407         adpcm->set_context_opn2(opn2);
408         adpcm->set_context_rf5c68(rf5c68);
409         adpcm->set_context_adc(adc);
410
411         rf5c68->set_context_interrupt_boundary(adpcm, SIG_ADPCM_WRITE_INTERRUPT, 0xffffffff);
412 #ifdef USE_DEBUGGER
413         rf5c68->set_context_debugger(new DEBUGGER(this, emu));
414 #endif
415         opn2->set_context_irq(adpcm, SIG_ADPCM_OPX_INTR, 0xffffffff);
416         
417         adc->set_sample_rate(19200);
418         adc->set_sound_bank(-1);
419         adc->set_context_interrupt(adpcm, SIG_ADPCM_ADC_INTR, 0xffffffff); 
420         
421         scsi->set_context_dma(dma);
422         scsi->set_context_host(scsi_host);
423         scsi->set_context_pic(pic);
424         timer->set_context_pcm(beep);
425         timer->set_context_rtc(rtc);
426         timer->set_context_halt_line(cpu, SIG_CPU_HALTREQ, 0xffffffff);
427
428         for(int i = 0; i < 2; i++) {
429                 // type =
430                 // 0: Towns PAD 2buttons
431                 // 1: Towns PAD 6buttons
432                 // 2: Towns MOUSE
433                 // 3: Analog Pad (reserved)
434                 // 4: Libble Rabble stick (reserved)
435                 joystick->set_context_joystick(i, joypad_2btn[i]);
436                 joystick->set_context_joystick(i, joypad_6btn[i]);
437                 joystick->set_context_joystick(i, mouse[i]);
438         }
439 #ifdef USE_DEBUGGER
440         joystick->set_context_debugger(new DEBUGGER(this, emu));
441 #endif
442         // ToDo: Selective by config.
443         for(int i = 0; i < 2; i++) {
444                 joypad_2btn[i]->set_context_pad_num(i);
445                 joypad_2btn[i]->set_context_parent_port(i, joystick, 0, 0xff);
446                 joypad_2btn[i]->set_negative_logic(true);
447                 joypad_2btn[i]->set_enable(true);
448         }
449         for(int i = 0; i < 2; i++) {
450                 joypad_6btn[i]->set_context_pad_num(i);
451                 joypad_6btn[i]->set_context_parent_port(i, joystick, 0, 0xff);
452                 joypad_6btn[i]->set_negative_logic(true);
453                 joypad_6btn[i]->set_enable(false);
454         }
455         for(int i = 0; i < 2; i++) {
456                 mouse[i]->set_context_pad_num(i);
457                 mouse[i]->set_context_parent_port(i, joystick, 0, 0xff);
458                 mouse[i]->set_negative_logic(false);
459                 mouse[i]->set_enable(false);
460         }
461         joystick->set_using_pad(0, -1);
462         joystick->set_using_pad(1, -1);
463
464         // cpu bus
465         cpu->set_context_mem(memory);
466         cpu->set_context_io(io);
467         cpu->set_context_intr(pic);
468         cpu->set_context_dma(dma);
469         cpu->set_context_bios(NULL);
470         cpu->set_context_extreset(memory, SIG_FMTOWNS_NOTIFY_RESET, 0xffffffff);
471 #ifdef USE_DEBUGGER
472         cpu->set_context_debugger(new DEBUGGER(this, emu));
473 #endif
474         // Interrupts
475         // IRQ0  : TIMER
476         // IRQ1  : KEYBOARD
477         // IRQ2  : USART (ToDo)
478         // IRQ3  : EXTRA USART (ToDo)
479         // IRQ4  : EXTRA I/O (Maybe not implement)
480         // IRQ5  : EXTRA I/O (Maybe not implement)
481         // IRQ6  : FDC
482         // IRQ7  : Deisy chain (to IRQ8 - 15)
483         timer->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR0, 0xffffffff);
484         keyboard->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR1, 0xffffffff);
485         floppy->set_context_intr_line(pic, SIG_I8259_CHIP0 | SIG_I8259_IR6, 0xffffffff);
486         
487         // IRQ8  : SCSI (-> scsi.cpp)
488         // IRQ9  : CDC/CDROM
489         // IRQ10 : EXTRA I/O (Maybe not implement)
490         // IRQ11 : VSYNC
491         // IRQ12 : PRINTER (ToDo)
492         // IRQ13 : ADPCM AND OPN2 (Route to adpcm.cpp)
493         // IRQ14 : EXTRA I/O (Maybe not implement)
494         // IRQ15 : RESERVED.
495         cdrom->set_context_mpuint_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR1, 0xffffffff);
496         crtc->set_context_vsync(pic, SIG_I8259_CHIP1 | SIG_I8259_IR3, 0xffffffff);
497         adpcm->set_context_intr_line(pic, SIG_I8259_CHIP1 | SIG_I8259_IR5, 0xffffffff);
498
499         // DMA0  : FDC/DRQ
500         // DMA1  : SCSI (-> scsi.cpp)
501         // DMA2  : PRINTER (ToDo)
502         // DMA3  : CDC/CDROM
503         // EXTRA DMA0 : EXTRA SLOT (Maybe not implement)
504         // EXTRA DMA1 : Reserved
505         // EXTRA DMA2 : Reserved
506         // EXTRA DMA3 : Reserved
507         fdc->set_context_drq(dma, SIG_UPD71071_CH0, 1);
508         fdc->set_context_drq(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1);
509         cdrom->set_context_drq_line(dma, SIG_UPD71071_CH3, 0xff);
510         cdrom->set_context_drq_line(keyboard, SIG_KEYBOARD_BOOTSEQ_END, 1);
511
512         // NMI0 : KEYBOARD (RAS)
513         // NMI1 : Extra SLOT (Maybe not implement)
514         keyboard->set_context_nmi_line(memory, SIG_CPU_NMI, 0xffffffff);
515
516         cdrom->set_context_dmac(dma);
517         // For Debugging, will remove 20200822 K.O
518         cdrom->set_context_cpu(cpu);
519
520         // i/o bus
521         io->set_iowait_range_rw(0x0000, 0xffff, 6); // ToDo: May variable wait.
522                 
523         io->set_iomap_alias_rw (0x0000, pic, I8259_ADDR_CHIP0 | 0);
524         io->set_iomap_alias_rw (0x0002, pic, I8259_ADDR_CHIP0 | 1);
525         io->set_iomap_alias_rw (0x0010, pic, I8259_ADDR_CHIP1 | 0);
526         io->set_iomap_alias_rw (0x0012, pic, I8259_ADDR_CHIP1 | 1);
527         
528         io->set_iomap_range_rw (0x0020, 0x0025, memory);
529         io->set_iomap_range_rw (0x0026, 0x0027, timer);  // Freerun counter
530         io->set_iomap_single_rw(0x0028, memory);
531         
532         io->set_iomap_range_r  (0x0030, 0x0031, memory);        // cpu id / machine id
533         io->set_iomap_single_rw(0x0032, memory);        // serial rom (routed from memory)
534         io->set_iomap_single_r (0x0034, scsi);  // ENABLE/ UNABLE to WORD DMA for SCSI
535
536         io->set_iomap_alias_rw(0x0040, pit0, 0);
537         io->set_iomap_alias_rw(0x0042, pit0, 1);
538         io->set_iomap_alias_rw(0x0044, pit0, 2);
539         io->set_iomap_alias_rw(0x0046, pit0, 3);
540         io->set_iomap_alias_rw(0x0050, pit1, 0);
541         io->set_iomap_alias_rw(0x0052, pit1, 1);
542         io->set_iomap_alias_rw(0x0054, pit1, 2);
543         io->set_iomap_alias_rw(0x0056, pit1, 3);
544         
545         io->set_iomap_single_rw(0x0060, timer); // Beep and interrupts register
546         io->set_iomap_single_rw(0x0068, timer); // Interval timer register2 (after Towns 10F).
547         io->set_iomap_single_rw(0x006a, timer); // Interval timer register2 (after Towns 10F).
548         io->set_iomap_single_rw(0x006b, timer); // Interval timer register2 (after Towns 10F).
549         io->set_iomap_single_rw(0x006c, timer); // 1uS wait register (after Towns 10F).
550         
551         io->set_iomap_single_rw(0x0070, timer); // RTC DATA
552         io->set_iomap_single_w (0x0080, timer); // RTC COMMAND
553         
554         io->set_iomap_range_rw (0x00a0, 0x00af, dma);
555         io->set_iomap_range_rw (0x00b0, 0x00bf, extra_dma);
556         
557         io->set_iomap_single_rw(0x00c0, memory);   // CACHE CONTROLLER
558         io->set_iomap_single_rw(0x00c2, memory);   // CACHE CONTROLLER
559         
560         io->set_iomap_alias_rw (0x0200, fdc, 0);  // STATUS/COMMAND
561         io->set_iomap_alias_rw (0x0202, fdc, 1);  // TRACK
562         io->set_iomap_alias_rw (0x0204, fdc, 2);  // SECTOR
563         io->set_iomap_alias_rw (0x0206, fdc, 3);  // DATA
564         io->set_iomap_single_rw(0x0208, floppy);  // DRIVE STATUS / DRIVE CONTROL
565         io->set_iomap_single_rw(0x020c, floppy);  // DRIVE SELECT
566         io->set_iomap_single_r (0x020d, floppy);  // FDDVEXT (after HG/HR).
567         io->set_iomap_single_rw(0x020e, floppy);  // Towns drive SW
568         
569         io->set_iomap_range_rw (0x0400, 0x0404, memory); // System Status
570 //      io->set_iomap_range_rw (0x0406, 0x043f, memory); // Reserved
571         
572         io->set_iomap_range_rw(0x0440, 0x0443, crtc); // CRTC
573         io->set_iomap_range_rw(0x0448, 0x044f, crtc); // VIDEO OUT (CRTC)
574         
575         io->set_iomap_range_rw(0x0450, 0x0452, sprite); // SPRITE
576         
577         io->set_iomap_single_rw(0x0458, vram);         // VRAM ACCESS CONTROLLER (ADDRESS)
578         io->set_iomap_range_rw (0x045a, 0x045b, vram); // VRAM ACCESS CONTROLLER (DATA)
579         
580         io->set_iomap_single_rw(0x0480, memory); //  MEMORY REGISTER
581         io->set_iomap_single_rw(0x0484, dictionary); // Dictionary
582         
583         io->set_iomap_alias_r(0x48a, iccard1, 0); //
584         //io->set_iomap_alias_rw(0x490, memory_card); // After Towns2
585         //io->set_iomap_alias_rw(0x491, memory_card); // After Towns2
586         
587         io->set_iomap_range_rw(0x04c0, 0x04c6, cdrom); // CDROM
588         io->set_iomap_range_r (0x04cc, 0x04cd, cdrom); // CDROM
589         // PAD, Sound
590
591         io->set_iomap_single_r(0x04d0, joystick); // Pad1
592         io->set_iomap_single_r(0x04d2, joystick); // Pad 2
593         io->set_iomap_single_w(0x04d6, joystick); // Pad out
594
595         io->set_iomap_single_rw(0x04d5, adpcm); // mute 
596         // OPN2(YM2612)
597         io->set_iomap_alias_rw(0x04d8, opn2, 0); // STATUS(R)/Addrreg 0(W)
598         io->set_iomap_alias_w (0x04da, opn2, 1);  // Datareg 0(W)
599         io->set_iomap_alias_w (0x04dc, opn2, 2);  // Addrreg 1(W)
600         io->set_iomap_alias_w (0x04de, opn2, 3);  // Datareg 1(W)
601         // Electrical volume
602 //      io->set_iomap_alias_rw(0x04e0, e_volume[0], 0);
603 //      io->set_iomap_alias_rw(0x04e1, e_volume[0], 1);
604 //      io->set_iomap_alias_rw(0x04e2, e_volume[1], 0);
605 //      io->set_iomap_alias_rw(0x04e3, e_volume[1], 1);
606
607         // ADPCM
608         io->set_iomap_range_rw(0x04e7, 0x04ec, adpcm); // A/D SAMPLING DATA REG 
609         io->set_iomap_range_rw(0x04f0, 0x04f8, rf5c68); // A/D SAMPLING DATA REG 
610
611         io->set_iomap_single_rw(0x05c0, memory); // NMI MASK
612         io->set_iomap_single_r (0x05c2, memory);  // NMI STATUS
613         io->set_iomap_single_r (0x05c8, sprite); // TVRAM EMULATION
614         io->set_iomap_single_w (0x05ca, crtc); // VSYNC INTERRUPT
615         
616         io->set_iomap_single_rw(0x05e0, memory); // Hidden MEMORY WAIT REGISTER from AB.COM (Towns 1/2)
617         io->set_iomap_single_rw(0x05e2, memory); // Hidden MEMORY WAIT REGISTER from AB.COM (After Towns 1H/1F/2H/2F )
618         io->set_iomap_single_rw(0x05e8, memory); // RAM capacity register.(later Towns1H/2H/1F/2F).
619         io->set_iomap_single_rw(0x05ec, memory); // RAM Wait register , ofcially after Towns2, but exists after Towns1H.
620         io->set_iomap_single_r (0x05ed, memory); // Maximum clock register (After HR/HG).
621         io->set_iomap_single_rw(0x05ee, vram);   // VRAM CACHE CONTROLLER
622         
623         io->set_iomap_single_rw(0x0600, keyboard);
624         io->set_iomap_single_rw(0x0602, keyboard);
625         io->set_iomap_single_rw(0x0604, keyboard);
626
627         //io->set_iomap_single_rw(0x0800, printer);
628         //io->set_iomap_single_rw(0x0802, printer);
629         //io->set_iomap_single_rw(0x0804, printer);
630         
631         io->set_iomap_alias_rw (0x0a00, sio, 0);
632         io->set_iomap_alias_rw (0x0a02, sio, 1);
633 //      io->set_iomap_single_r (0x0a04, serial);
634 //      io->set_iomap_single_r (0x0a06, serial);
635 //      io->set_iomap_single_w (0x0a08, serial);
636 //      io->set_iomap_single_rw(0x0a0a, modem);
637         
638         io->set_iomap_single_rw(0x0c30, scsi);
639         io->set_iomap_single_rw(0x0c32, scsi);
640         io->set_iomap_single_r (0x0c34, scsi);
641
642         io->set_iomap_range_rw (0x3000, 0x3fff, dictionary); // CMOS
643         
644         io->set_iomap_range_rw (0xfd90, 0xfda0, crtc);  // Palette and CRTC
645         io->set_iomap_single_r (0xfda2, crtc);  // CRTC
646         io->set_iomap_single_rw(0xfda4, memory);        // memory
647         
648         io->set_iomap_range_rw (0xff80, 0xff83, planevram);     // MMIO
649         io->set_iomap_single_r (0xff84, planevram);     // MMIO
650         io->set_iomap_single_rw(0xff86, planevram);     // MMIO
651         io->set_iomap_single_rw(0xff88, memory);        // MMIO
652         io->set_iomap_range_rw (0xff94, 0xff99, memory);        // MMIO
653         io->set_iomap_range_r  (0xff9c, 0xff9d, memory);        // MMIO
654         io->set_iomap_single_rw(0xff9e, memory);        // MMIO
655         io->set_iomap_single_rw(0xffa0, planevram);     // MMIO
656         
657 //      io->set_iomap_range_w (0xff94, 0xff95, fontrom);
658 //      io->set_iomap_range_r (0xff96, 0xff97, fontrom);
659
660         // Vram allocation may be before initialize().
661         // initialize all devices
662 #if defined(__GIT_REPO_VERSION)
663         strncpy(_git_revision, __GIT_REPO_VERSION, sizeof(_git_revision) - 1);
664 #endif
665         // ToDo : Use config framework
666         int exram_size = config.current_ram_size;
667         if(exram_size < 1) {
668                 if(machine_id < 0x0200) { // Model1 - 2H
669                         exram_size = 6;
670                 } else if(machine_id == 0x0500) { // CX
671                         exram_size = 15;
672                 } else if(machine_id < 0x0700) {  // 10F,20H
673                         exram_size = 8;
674                 } else if(machine_id == 0x0800) { // HG
675                         exram_size = 15;
676                 } else { 
677                         exram_size = 31;
678                 }
679         }
680         if(exram_size < MIN_RAM_SIZE) {
681                 exram_size = MIN_RAM_SIZE;
682         }
683         
684         memory->set_extra_ram_size(exram_size);
685
686 #if defined(WITH_I386SX)
687         cpu->device_model = INTEL_80386;
688 #elif defined(WITH_I486SX)
689         cpu->device_model = INTEL_I486SX;
690 #elif defined(WITH_I486DX)
691         cpu->device_model = INTEL_I486DX;
692 #elif defined(WITH_PENTIUM)
693         cpu->device_model = INTEL_PENTIUM;
694 #else
695         // I386
696         cpu->device_model = INTEL_80386;
697 #endif  
698
699         for(DEVICE* device = first_device; device; device = device->next_device) {
700                 device->initialize();
701         }
702 //      cpu->set_address_mask(0xffffffff);
703 }
704
705 VM::~VM()
706 {
707         // delete all devices
708         for(DEVICE* device = first_device; device;) {
709                 DEVICE *next_device = device->next_device;
710 //              printf("DEVID=%d\n", device->this_device_id);
711                 device->release();
712                 delete device;
713                 device = next_device;
714         }
715 }
716
717 DEVICE* VM::get_device(int id)
718 {
719         for(DEVICE* device = first_device; device; device = device->next_device) {
720                 if(device->this_device_id == id) {
721                         return device;
722                 }
723         }
724         return NULL;
725 }
726
727 void VM::set_machine_type(uint16_t machine_id, uint16_t cpu_id)
728 {
729         if(memory != NULL) {
730                 memory->set_cpu_id(cpu_id);
731                 memory->set_machine_id(machine_id);
732         }
733         if(crtc != NULL) {
734                 crtc->set_cpu_id(cpu_id);
735                 crtc->set_machine_id(machine_id);
736         }
737         if(timer != NULL) {
738                 timer->set_cpu_id(cpu_id);
739                 timer->set_machine_id(machine_id);
740         }
741         if(cdrom != NULL) {
742                 cdrom->set_cpu_id(cpu_id);
743                 cdrom->set_machine_id(machine_id);
744         }
745         if(scsi != NULL) {
746                 scsi->set_cpu_id(cpu_id);
747                 scsi->set_machine_id(machine_id);
748         }
749         if(serialrom != NULL) {
750                 serialrom->set_cpu_id(cpu_id);
751                 serialrom->set_machine_id(machine_id);
752         }
753         if(floppy != NULL) {
754                 floppy->set_cpu_id(cpu_id);
755                 floppy->set_machine_id(machine_id);
756         }
757 #if defined(HAS_20PIX_FONTS)
758         if(fontrom_20pix != NULL) {
759                 fontrom_20pix->set_cpu_id(cpu_id);
760                 fontrom_20pix->set_machine_id(machine_id);
761         }
762 #endif
763         if(vram != NULL) {
764                 vram->set_cpu_id(cpu_id);
765                 vram->set_machine_id(machine_id);
766         }
767         
768 }               
769
770
771 // ----------------------------------------------------------------------------
772 // drive virtual machine
773 // ----------------------------------------------------------------------------
774
775 void VM::reset()
776 {
777         // reset all devices
778         boot_seq = false;
779         for(DEVICE* device = first_device; device; device = device->next_device) {
780                 device->reset();
781         }
782 //      cpu->set_address_mask(0xffffffff);
783 }
784
785 void VM::special_reset(int num)
786 {
787         // reset all devices
788         boot_seq = true;
789         
790         for(DEVICE* device = first_device; device; device = device->next_device) {
791                 device->reset();
792         }
793         keyboard->special_reset(num);
794
795 //      cpu->set_address_mask(0xffffffff);
796 }
797
798 void VM::run()
799 {
800         event->drive();
801 }
802
803 // ----------------------------------------------------------------------------
804 // debugger
805 // ----------------------------------------------------------------------------
806
807 #ifdef USE_DEBUGGER
808 DEVICE *VM::get_cpu(int index)
809 {
810         if(index == 0) {
811                 return cpu;
812         }
813         return NULL;
814 }
815 #endif
816
817 // ----------------------------------------------------------------------------
818 // draw screen
819 // ----------------------------------------------------------------------------
820
821 void VM::draw_screen()
822 {
823         crtc->draw_screen();
824 }
825
826 uint32_t VM::is_floppy_disk_accessed()
827 {
828         uint32_t val = fdc->read_signal(0);
829         if(boot_seq) {
830                 if(val != 0) {
831                         keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff);
832                         boot_seq = false;
833                 }
834         }
835         return val;
836 }
837
838 // ----------------------------------------------------------------------------
839 // soud manager
840 // ----------------------------------------------------------------------------
841
842 void VM::initialize_sound(int rate, int samples)
843 {
844         emu->lock_vm();
845         // init sound manager
846         event->initialize_sound(rate, samples);
847         
848         // init sound gen
849         beep->initialize_sound(rate, 8000);
850
851         // init OPN2
852         // MASTER CLOCK MAYBE 600KHz * 12 = 7200KHz .
853         // From FM-Towns Technical Databook (Rev.2), Page 201
854         opn2->initialize_sound(rate, (int)(600.0e3 * 12.0) , samples, 0.0, 0.0); 
855         //opn2->initialize_sound(rate, (int)(8000.0e3) , samples, 0.0, 0.0); 
856         //opn2->initialize_sound(rate, (int)(600.0e3 * 6.0) , samples, 0.0, 0.0); 
857
858         // init PCM
859         rf5c68->initialize_sound(rate, samples);
860         
861         // add_sound_in_source() must add after per initialize_sound().
862         adc_in_ch = event->add_sound_in_source(rate, samples, 2);
863         adc->set_sample_rate(19200);
864         adc->set_sound_bank(adc_in_ch);
865 #if 0   
866         mixer->set_context_out_line(adc_in_ch);
867         mixer->set_context_sample_out(adc_in_ch, rate, samples); // Must be 2ch.
868         // ToDo: Check recording sample rate & channels.
869         mic_in_ch = event->add_sound_in_source(rate, samples, 2);
870         mixer->set_context_mic_in(mic_in_ch, rate, samples);
871
872         line_in_ch = event->add_sound_in_source(rate, samples, 2);
873         mixer->set_context_line_in(line_in_ch, rate, samples);
874 #endif
875         emu->unlock_vm();
876 }
877
878 uint16_t* VM::create_sound(int* extra_frames)
879 {
880         return event->create_sound(extra_frames);
881 }
882
883 int VM::get_sound_buffer_ptr()
884 {
885         return event->get_sound_buffer_ptr();
886 }
887
888 void VM::clear_sound_in()
889 {
890         event->clear_sound_in_source(adc_in_ch);
891         event->clear_sound_in_source(mic_in_ch);
892         event->clear_sound_in_source(line_in_ch);
893         return;
894 }
895
896 int VM::get_sound_in_data(int ch, int32_t* dst, int expect_samples, int expect_rate, int expect_channels)
897 {
898         if(dst == NULL) return 0;
899         if(expect_samples <= 0) return 0;
900         int n_ch = -1;
901         switch(ch) {
902         case 0x00:
903                 n_ch = line_in_ch;
904                 break;
905         case 0x01:
906                 n_ch = mic_in_ch;
907                 break;
908         case 0x100:
909                 n_ch = adc_in_ch;
910                 break;
911         }
912         if(n_ch < 0) return 0;
913         int samples = event->get_sound_in_data(n_ch, dst, expect_samples, expect_rate, expect_channels);
914         return samples;
915 }
916
917 // Write to event's buffer
918 int VM::sound_in(int ch, int32_t* src, int samples)
919 {
920         if(ch < 0) return 0;
921         if(ch >= 2) return 0;
922         int n_ch = -1;
923         switch(ch) {
924         case 0x100:  // ADC in from MIXER, not connected.
925                 break;
926         case 0x00: // LINE
927                 n_ch = line_in_ch;
928                 break;
929         case 0x01: // MIC
930                 n_ch = mic_in_ch;
931                 break;
932         }
933         if(n_ch < 0) return 0;
934
935         int ss = 0;
936         {
937                 emu->lock_vm();
938                 ss =  event->write_sound_in_buffer(n_ch, src, samples);
939                 emu->unlock_vm();
940
941         }
942         return ss;
943 }
944
945 #if defined(USE_HARD_DISK)
946 void VM::open_hard_disk(int drv, const _TCHAR* file_path)
947 {
948         if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) {
949                 if(scsi_hdd[drv] != NULL) {
950                         scsi_hdd[drv]->open(0, file_path, 512);
951                 }
952         }
953 }
954
955 void VM::close_hard_disk(int drv)
956 {
957         if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) {
958                 if(scsi_hdd[drv] != NULL) {
959                         scsi_hdd[drv]->close(0);
960                 }
961         }
962 }
963
964 bool VM::is_hard_disk_inserted(int drv)
965 {
966         if((drv < USE_HARD_DISK) && (drv < 8) && (drv >= 0)) {
967                 if(scsi_hdd[drv] != NULL) {
968                         return scsi_hdd[drv]->mounted(0);
969                 }
970         }
971         return false;
972 }
973
974 uint32_t VM::is_hard_disk_accessed()
975 {
976         uint32_t status = 0;
977         
978         for(int drv = 0; drv < USE_HARD_DISK; drv++) {
979                 if(scsi_hdd[drv] != NULL) {
980                         if(scsi_hdd[drv]->accessed(0)) {
981                                 status |= 1 << drv;
982                         }
983                 }
984         }
985         if(boot_seq) {
986                 if(status != 0) {
987                         keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff);
988                         boot_seq = false;
989                 }
990         }
991         return status;
992 }
993 #endif // USE_HARD_DISK
994
995 void VM::open_compact_disc(int drv, const _TCHAR* file_path)
996 {
997         cdrom->open(file_path);
998 }
999
1000 void VM::close_compact_disc(int drv)
1001 {
1002         cdrom->close();
1003 }
1004
1005 bool VM::is_compact_disc_inserted(int drv)
1006 {
1007         return cdrom->mounted();
1008 }
1009
1010 uint32_t VM::is_compact_disc_accessed()
1011 {
1012         uint32_t status = cdrom->accessed();
1013         if(boot_seq) {
1014                 if(status != 0) {
1015                         keyboard->write_signal(SIG_KEYBOARD_BOOTSEQ_END, 0xffffffff, 0xffffffff);
1016                         boot_seq = false;
1017                 }
1018         }
1019         return status;
1020 }
1021
1022 #ifdef USE_SOUND_VOLUME
1023 void VM::set_sound_device_volume(int ch, int decibel_l, int decibel_r)
1024 {
1025 #ifndef HAS_LINEIN_SOUND
1026 //      if(ch >= 7) ch++;
1027 #endif
1028 #ifndef HAS_MIC_SOUND
1029 //      if(ch >= 8) ch++;
1030 #endif
1031 #ifndef HAS_MODEM_SOUND
1032 //      if(ch >= 9) ch++;
1033 #endif
1034 #ifndef HAS_2ND_ADPCM
1035 //      if(ch >= 10) ch++;
1036 #endif
1037 #if 0   
1038         if(ch == 0) { // BEEP
1039                 mixer->set_volume(beep_mix_ch, decibel_l, decibel_r);
1040         }
1041         else if(ch == 1) { // CD-ROM
1042                 //e_volume[1]->set_volume(0, decibel_l);
1043                 //e_volume[1]->set_volume(1, decibel_r);
1044                 mixer->set_volume(cdc_mix_ch, decibel_l, decibel_r);
1045         }
1046         else if(ch == 2) { // OPN2
1047                 mixer->set_volume(opn2_mix_ch, decibel_l, decibel_r);
1048         }
1049         else if(ch == 3) { // ADPCM
1050                 mixer->set_volume(pcm_mix_ch, decibel_l, decibel_r);
1051         }
1052         else if(ch == 4) { // LINE IN
1053                 //mixer->set_volume(line_mix_ch, decibel_l, decibel_r);
1054         } 
1055         else if(ch == 5) { // MIC
1056                 //mic->set_volume(0, (decibel_l + decibel_r) / 2);
1057         } 
1058         else if(ch == 6) { // MODEM
1059                 //modem->set_volume(0, (decibel_l + decibel_r) / 2);
1060         }
1061 #ifdef HAS_2ND_ADPCM
1062         else if(ch == 7) { // ADPCM
1063                 adpcm2->set_volume(0, decibel_l, decibel_r);
1064         }
1065 #endif
1066         else if(ch == 8) { // FDD
1067                 fdc->set_volume(0, decibel_l, decibel_r);
1068         }
1069         else if(ch == 9) { // HDD(ToDo)
1070                 fdc->set_volume(0, decibel_l, decibel_r);
1071         }       
1072 #else
1073         if(ch == 0) { // BEEP
1074                 beep->set_volume(0, decibel_l, decibel_r);
1075         }
1076         else if(ch == 1) { // CD-ROM
1077                 cdrom->set_volume(0, decibel_l, decibel_r);
1078         }       
1079         else if(ch == 2) { // OPN2
1080                 opn2->set_volume(0, decibel_l, decibel_r);
1081         }
1082         else if(ch == 3) { // ADPCM
1083                 rf5c68->set_volume(0, decibel_l, decibel_r);
1084         }
1085         else if(ch == 4) { // SEEK, HEAD UP / DOWN
1086                 seek_sound->set_volume(0, decibel_l, decibel_r);
1087                 head_up_sound->set_volume(0, decibel_l, decibel_r);
1088                 head_down_sound->set_volume(0, decibel_l, decibel_r);
1089         }
1090         
1091 #endif
1092 }
1093 #endif
1094
1095 // ----------------------------------------------------------------------------
1096 // notify key
1097 // ----------------------------------------------------------------------------
1098
1099 void VM::key_down(int code, bool repeat)
1100 {
1101         keyboard->key_down(code);
1102 }
1103
1104 void VM::key_up(int code)
1105 {
1106         keyboard->key_up(code);
1107 }
1108
1109 // ----------------------------------------------------------------------------
1110 // user interface
1111 // ----------------------------------------------------------------------------
1112 void VM::open_cart(int drv, const _TCHAR* file_path)
1113 {
1114         switch(drv) {
1115         case 0:
1116                 if(iccard1 != NULL) {
1117                         iccard1->open_cart(file_path);
1118                 }
1119                 break;
1120         case 1:
1121                 if(iccard2 != NULL) {
1122                         iccard2->open_cart(file_path);
1123                 }
1124                 break;
1125         }
1126 }
1127
1128 void VM::close_cart(int drv)
1129 {
1130         switch(drv) {
1131         case 0:
1132                 if(iccard1 != NULL) {
1133                         iccard1->close_cart();
1134                 }
1135                 break;
1136         case 1:
1137                 if(iccard2 != NULL) {
1138                         iccard2->close_cart();
1139                 }
1140                 break;
1141         }               
1142 }
1143
1144 bool VM::is_cart_inserted(int drv)
1145 {
1146         switch(drv) {
1147         case 0:
1148                 if(iccard1 != NULL) {
1149                         return iccard1->is_cart_inserted();
1150                 }
1151                 break;
1152         case 1:
1153                 if(iccard2 != NULL) {
1154                         return iccard2->is_cart_inserted();
1155                 }
1156                 break;
1157         }
1158         return false;
1159 }
1160
1161 void VM::open_floppy_disk(int drv, const _TCHAR* file_path, int bank)
1162 {
1163         
1164         fdc->open_disk(drv, file_path, bank);
1165         floppy->change_disk(drv);
1166 }
1167
1168 void VM::close_floppy_disk(int drv)
1169 {
1170         fdc->close_disk(drv);
1171 //      floppy->change_disk(drv);
1172 }
1173
1174 bool VM::is_floppy_disk_inserted(int drv)
1175 {
1176         return fdc->is_disk_inserted(drv);
1177 }
1178
1179 void VM::is_floppy_disk_protected(int drv, bool value)
1180 {
1181         fdc->is_disk_protected(drv, value);
1182 }
1183
1184 bool VM::is_floppy_disk_protected(int drv)
1185 {
1186         return fdc->is_disk_protected(drv);
1187 }
1188
1189 bool VM::is_frame_skippable()
1190 {
1191         return event->is_frame_skippable();
1192 }
1193
1194 void VM::update_config()
1195 {
1196         for(DEVICE* device = first_device; device; device = device->next_device) {
1197                 device->update_config();
1198         }
1199 }
1200
1201 double VM::get_current_usec()
1202 {
1203         if(event == NULL) return 0.0;
1204         return event->get_current_usec();
1205 }
1206
1207 uint64_t VM::get_current_clock_uint64()
1208 {
1209                 if(event == NULL) return (uint64_t)0;
1210                 return event->get_current_clock_uint64();
1211 }
1212
1213 #define STATE_VERSION   3
1214
1215 bool VM::process_state(FILEIO* state_fio, bool loading)
1216 {
1217         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1218                 return false;
1219         }
1220         for(DEVICE* device = first_device; device; device = device->next_device) {
1221                 // Note: typeid(foo).name is fixed by recent ABI.Not decr. 6.
1222                 // const char *name = typeid(*device).name();
1223                 //       But, using get_device_name() instead of typeid(foo).name() 20181008 K.O
1224                 const char *name = device->get_device_name();
1225                 int len = (int)strlen(name);
1226                 if(!state_fio->StateCheckInt32(len)) {
1227                         return false;
1228                 }
1229                 if(!state_fio->StateCheckBuffer(name, len, 1)) {
1230                         return false;
1231                 }
1232                 if(!device->process_state(state_fio, loading)) {
1233                         if(loading) {
1234                                 printf("Data loading Error: DEVID=%d\n", device->this_device_id);
1235                         }
1236                         return false;
1237                 }
1238         }
1239         // Machine specified.
1240         state_fio->StateValue(beep_mix_ch);
1241         state_fio->StateValue(cdc_mix_ch);
1242         state_fio->StateValue(opn2_mix_ch);
1243         state_fio->StateValue(pcm_mix_ch);
1244         state_fio->StateValue(line_mix_ch);
1245         state_fio->StateValue(modem_mix_ch);
1246         state_fio->StateValue(mic_mix_ch);
1247
1248         state_fio->StateValue(boot_seq);
1249         
1250         return true;
1251 }
1252