OSDN Git Service

6ced85bd484c901cf81a8ecc9fe6e3a8f0d05ff1
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / fm7_mainio.cpp
1 /*
2  * FM-7 Main I/O [fm7_mainio.h]
3  *
4  * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
5  * License: GPLv2
6  * History:
7  *   Jan 03, 2015 : Initial
8  *
9  */
10
11 #include "fm7.h"
12 #include "fm7_mainio.h"
13
14 #include "../mc6809.h"
15 #include "../z80.h"
16
17 #include "../datarec.h"
18 #if defined(HAS_DMA)
19 #include "hd6844.h"
20 #endif
21 #if defined(_FM8)
22 #include "bubblecasette.h"
23 #endif
24
25 FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
26 {
27         int i;
28         p_vm = parent_vm;
29         p_emu = parent_emu;
30 #if defined(_FM8)
31         opn[0] = NULL;
32 #else
33         for(i = 0; i < 4; i++) {
34                 opn[i] = NULL;
35         }
36 #endif
37         drec = NULL;
38         pcm1bit = NULL;
39         joystick = NULL;
40         fdc = NULL;
41         printer = NULL;
42         
43         kanjiclass1 = NULL;
44         kanjiclass2 = NULL;
45
46         display = NULL;
47         keyboard = NULL;
48         maincpu = NULL;
49         mainmem = NULL;
50         subcpu = NULL;
51 #ifdef WITH_Z80
52         z80 = NULL;
53 #endif  
54 #if defined(_FM8)
55         bubble_casette[0] = NULL;
56         bubble_casette[1] = NULL;
57 #endif  
58         // FD00
59         clock_fast = true;
60         lpt_strobe = false;  // bit6
61         lpt_slctin = false;  // bit7
62         // FD01
63         lpt_outdata = 0x00;
64         // FD02
65         cmt_indat = true; // bit7
66         cmt_invert = false; // Invert signal
67         irqstat_reg0 = 0xff;
68         
69         // FD04
70 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
71         defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) 
72         stat_kanjirom = true;    //  R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
73 #elif defined(_FM77_VARIANTS)
74         stat_fdmode_2hd = false; //  R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
75         stat_kanjirom = true;    //  R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
76         stat_400linecard = false;//  R/W : bit4, '0' = connected. FM-77 Only.
77 #endif  
78         firq_break_key = false; // bit1, ON = '0'.
79         firq_sub_attention = false; // bit0, ON = '0'.
80         intmode_fdc = false; // bit2, '0' = normal, '1' = SFD.
81         // FD05
82         extdet_neg = false;
83 #ifdef WITH_Z80
84         z80_sel = false;    // bit0 : '1' = Z80. Maybe only FM-7/77.
85 #endif
86         // FD06,07
87         intstat_syndet = false;
88         intstat_rxrdy = false;
89         intstat_txrdy = false;
90         irqstat_timer = false;
91         irqstat_printer = false;
92         irqstat_keyboard = false;
93         // FD0B
94         // FD0D
95         // FD0F
96         // FD15/ FD46 / FD51
97 #if defined(_FM8)
98         connect_psg = false;
99         {
100                 opn_address[0] = 0x00;
101                 opn_data[0] = 0x00;
102                 opn_cmdreg[0] = 0;
103         }
104 #else   
105         connect_opn = false;
106         connect_whg = false;
107         connect_thg = false;
108                 
109         for(i = 0; i < 3; i++) {
110                 opn_address[i] = 0x00;
111                 opn_data[i] = 0x00;
112                 opn_cmdreg[i] = 0;
113         }
114         intstat_whg = false;
115         intstat_thg = false;
116         // FD17
117         intstat_opn = false;
118         intstat_mouse = false;
119         mouse_enable = false;
120 #endif  
121         // FD18-FD1F
122         connect_fdc = false;
123         fdc_statreg = 0x00;
124         fdc_cmdreg = 0x00;
125         fdc_trackreg = 0x00;
126         fdc_sectreg = 0x00;
127         fdc_datareg = 0x00;
128         fdc_headreg = 0x00;
129         fdc_drvsel = 0x00;
130         fdc_motor = false;
131         irqstat_fdc = false;
132         irqreg_fdc = 0xff; //0b11111111;
133         irqmask_syndet = true;
134         irqmask_rxrdy = true;
135         irqmask_txrdy = true;
136         irqmask_mfd = true;
137         irqmask_timer = true;
138         irqmask_printer = true;
139         irqmask_keyboard = true;
140         irqstat_reg0 = 0xff;
141         
142   
143         irqreq_syndet = false;
144         irqreq_rxrdy = false;
145         irqreq_txrdy = false;
146         irqreq_printer = false;
147         irqreq_keyboard = false;
148
149         // FD20, FD21, FD22, FD23
150         connect_kanjiroml1 = false;
151 #if defined(_FM77AV_VARIANTS)
152         // FD2C, FD2D, FD2E, FD2F
153         connect_kanjiroml2 = false;
154 #endif          
155 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
156         boot_ram = false;
157 #endif
158
159 #if defined(HAS_DMA)
160         dmac = NULL;
161 #endif  
162         bootmode = config.boot_mode & 3;
163         memset(io_w_latch, 0xff, 0x100);
164         initialize_output_signals(&clock_status);
165         initialize_output_signals(&printer_reset_bus);
166         initialize_output_signals(&printer_strobe_bus);
167         initialize_output_signals(&printer_select_bus);
168 }
169
170 FM7_MAINIO::~FM7_MAINIO()
171 {
172 }
173
174
175 void FM7_MAINIO::initialize()
176 {
177         event_beep = -1;
178         event_beep_oneshot = -1;
179         event_timerirq = -1;
180         event_fdc_motor = -1;
181         lpt_type = config.printer_device_type;
182         fdc_cmdreg = 0x00;
183         
184 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
185         boot_ram = false;
186 # if defined(_FM77_VARIANTS)
187         stat_fdmode_2hd = false;
188         stat_kanjirom = true;
189         stat_400linecard = false;
190 #  if defined(_FM77L4)
191         stat_400linecard = true;
192 #  endif        
193 # endif 
194 #endif
195 #if defined(_FM77AV_VARIANTS)
196         reg_fd12 = 0xbc; // 0b10111100
197 #endif          
198         bootmode = config.boot_mode & 3;
199         reset_printer();
200 }
201
202 void FM7_MAINIO::reset()
203 {
204         if(event_beep >= 0) cancel_event(this, event_beep);
205         event_beep = -1;
206         if(event_beep_oneshot >= 0) cancel_event(this, event_beep_oneshot);
207         event_beep_oneshot = -1;
208         if(event_timerirq >= 0) cancel_event(this, event_timerirq);
209         beep_snd = true;
210         beep_flag = false;
211         register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
212         // Sound
213 #if defined(_FM77AV_VARIANTS)
214         hotreset = false;
215 #endif
216         // Around boot rom
217 #if defined(_FM77_VARIANTS)
218         boot_ram = false;
219 #elif defined(_FM77AV_VARIANTS)
220         boot_ram = true;
221 #endif
222         // FD05
223         sub_cancel = false; // bit6 : '1' Cancel req.
224         sub_halt = false; // bit6 : '1' Cancel req.
225         sub_cancel_bak = sub_cancel; // bit6 : '1' Cancel req.
226         sub_halt_bak = sub_halt; // bit6 : '1' Cancel req.
227         // FD02
228         cmt_indat = true; // bit7
229         cmt_invert = false; // Invert signal
230         lpt_det2 = true;
231         lpt_det1 = true;
232         lpt_type = config.printer_device_type;
233         reset_printer();
234         
235 #if defined(_FM77AV_VARIANTS)
236         sub_monitor_type = 0x00;
237 #endif
238         if(config.cpu_type == 0) {
239                 clock_fast = true;
240         } else {
241                 clock_fast = false;
242         }
243         this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
244    
245         // FD03
246         irqmask_syndet = true;
247         irqmask_rxrdy = true;
248         irqmask_txrdy = true;
249         irqmask_mfd = true;
250         irqmask_timer = true;
251         irqmask_printer = true;
252         irqmask_keyboard = true;
253         irqstat_reg0 = 0xff;
254         
255         intstat_syndet = false;
256         intstat_rxrdy = false;
257         intstat_txrdy = false;
258         irqstat_timer = false;
259         irqstat_printer = false;
260         irqstat_keyboard = false;
261   
262         irqreq_syndet = false;
263         irqreq_rxrdy = false;
264         irqreq_txrdy = false;
265         irqreq_printer = false;
266         irqreq_keyboard = false;
267         // FD00
268         drec->write_signal(SIG_DATAREC_MIC, 0x00, 0x01);
269         drec->set_remote(false);
270         reset_fdc();
271         reset_sound();
272         
273         // FD04
274         firq_break_key = (keyboard->read_signal(SIG_FM7KEY_BREAK_KEY) != 0x00000000); // bit1, ON = '0'.
275         set_sub_attention(false);       
276 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
277         defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX) 
278         stat_kanjirom = true;    //  R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
279 #elif defined(_FM77_VARIANTS)
280         stat_fdmode_2hd = false; //  R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
281         stat_kanjirom = true;    //  R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
282 #endif  
283         maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
284 #if defined(HAS_DMA)
285         intstat_dma = false;
286         dma_addr = 0;
287 #endif
288 #if defined(_FM77AV_VARIANTS)
289         reg_fd12 = 0xbc; // 0b10111100
290 #endif          
291 //#if defined(_FM8)
292 //      bubble_casette[0]->reset();
293 //      bubble_casette[1]->reset();
294 //#endif        
295
296
297 #if !defined(_FM8)
298         register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
299 #endif
300         bootmode = config.boot_mode & 3;
301         memset(io_w_latch, 0xff, 0x100);
302 }
303
304 void FM7_MAINIO::reset_printer()
305 {
306         lpt_slctin = false;
307         lpt_strobe = false;
308         // FD01
309         lpt_outdata = 0x00;
310         this->write_signals(&printer_strobe_bus, 0);
311         this->write_signals(&printer_select_bus, 0xffffffff);
312         this->write_signals(&printer_reset_bus, 0xffffffff);
313         register_event(this, EVENT_PRINTER_RESET_COMPLETED, 5.0 * 1000.0, false, NULL);
314         if(lpt_type == 0) {
315                 printer->write_signal(SIG_PRINTER_STROBE, 0x00, 0xff);
316         }
317         lpt_busy = false;
318         lpt_error_inv = true;
319         lpt_ackng_inv = true;
320         lpt_pe = false;
321
322 }
323
324 void FM7_MAINIO::set_clockmode(uint8_t flags)
325 {
326         bool f = clock_fast;
327         if((flags & FM7_MAINCLOCK_SLOW) != 0) {
328                 clock_fast = false;
329         } else {
330                 clock_fast = true;
331         }
332         if(f != clock_fast) {
333                 this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
334         }
335 }
336
337 uint8_t FM7_MAINIO::get_clockmode(void)
338 {
339         if(!clock_fast) return FM7_MAINCLOCK_SLOW;
340         return FM7_MAINCLOCK_HIGH;
341 }
342
343
344 uint8_t FM7_MAINIO::get_port_fd00(void)
345 {
346         uint8_t ret           = 0x7e; //0b01111110;
347 #if defined(_FM8)
348         ret = 0xfe;
349 #else   
350         if(keyboard->read_data8(0x00) != 0) ret |= 0x80; // High bit.
351 #endif  
352         if(clock_fast) ret |= 0x01; //0b00000001;
353         return ret;
354 }
355   
356 void FM7_MAINIO::set_port_fd00(uint8_t data)
357 {
358         drec->write_signal(SIG_DATAREC_MIC, data, 0x01);
359         drec->set_remote(((data & 0x02) != 0));
360         lpt_slctin = ((data & 0x80) == 0);
361         lpt_strobe = ((data & 0x40) != 0);
362         this->write_signals(&printer_strobe_bus, lpt_strobe ? 0xffffffff : 0);
363         this->write_signals(&printer_select_bus, lpt_slctin ? 0xffffffff : 0);
364         if((lpt_type == 0) && (lpt_slctin)) {
365                 printer->write_signal(SIG_PRINTER_STROBE, lpt_strobe ? 0xff : 0x00, 0xff);
366         }
367 }
368    
369 uint8_t FM7_MAINIO::get_port_fd02(void)
370 {
371         uint8_t ret;
372         bool ack_bak = lpt_ackng_inv;
373
374         ret = (cmt_indat) ? 0xff : 0x7f; // CMT
375         if(lpt_type == 0) {
376                 lpt_busy = (printer->read_signal(SIG_PRINTER_BUSY) != 0);
377                 lpt_error_inv = true;
378                 lpt_ackng_inv = (printer->read_signal(SIG_PRINTER_ACK) != 0);
379                 lpt_pe = false;
380         } else if((lpt_type == 1) || (lpt_type == 2)) {
381                 lpt_pe = (joystick->read_data8(lpt_type + 1) != 0); // check joy port;
382                 lpt_busy = true;
383                 lpt_error_inv = true;
384                 lpt_ackng_inv = true;
385         } else {
386                 lpt_busy = true;
387                 lpt_error_inv = true;
388                 lpt_ackng_inv = true;
389                 lpt_pe = true;
390         }
391         ret &= (lpt_busy)      ? 0xff : ~0x01;
392         ret &= (lpt_error_inv) ? 0xff : ~0x02;
393         ret &= (lpt_ackng_inv) ? 0xff : ~0x04;
394         ret &= (lpt_pe)        ? 0xff : ~0x08;
395         ret &= (lpt_det1)      ? 0xff : ~0x10;
396         ret &= (lpt_det2)      ? 0xff : ~0x20;
397         if((lpt_ackng_inv == true) && (ack_bak == false)) set_irq_printer(true);
398         return ret;
399 }
400
401 void FM7_MAINIO::set_port_fd02(uint8_t val)
402 {
403 #if !defined(_FM8)      
404         irqmask_reg0 = val;
405         bool syndetirq_bak = irqmask_syndet;
406         bool rxrdyirq_bak = irqmask_rxrdy;
407         bool txrdyirq_bak = irqmask_txrdy;
408         
409         bool keyirq_bak = irqmask_keyboard;
410         bool timerirq_bak = irqmask_timer;
411         bool printerirq_bak = irqmask_printer;
412         bool mfdirq_bak = irqmask_mfd;
413         
414         //      if((val & 0b00010000) != 0) {
415         if((val & 0x80) != 0) {
416                 irqmask_syndet = false;
417         } else {
418                 irqmask_syndet = true;
419         }
420         if(syndetirq_bak != irqmask_syndet) {
421                 set_irq_txrdy(irqreq_syndet);
422         }
423         if((val & 0x40) != 0) {
424                 irqmask_rxrdy = false;
425         } else {
426                 irqmask_rxrdy = true;
427         }
428 //      if(rxrdyirq_bak != irqmask_rxrdy) {
429 //              set_irq_rxrdy(irqreq_rxrdy);
430 //      }
431         if((val & 0x20) != 0) {
432                 irqmask_txrdy = false;
433         } else {
434                 irqmask_txrdy = true;
435         }
436 //      if(txrdyirq_bak != irqmask_txrdy) {
437         //              set_irq_txrdy(irqreq_txrdy);
438 //      }
439         
440         if((val & 0x10) != 0) {
441                 irqmask_mfd = false;
442         } else {
443                 irqmask_mfd = true;
444         }
445
446         if((val & 0x04) != 0) {
447                 irqmask_timer = false;
448         } else {
449                 irqmask_timer = true;
450         }
451 //      if(timerirq_bak != irqmask_timer) {
452 //              set_irq_timer(false);
453 //      }
454
455         if((val & 0x02) != 0) {
456                 irqmask_printer = false;
457         } else {
458                 irqmask_printer = true;
459         }
460 //      if(printerirq_bak != irqmask_printer) {
461 //              set_irq_printer(irqreq_printer);
462 //      }
463    
464         if((val & 0x01) != 0) {
465                 irqmask_keyboard = false;
466         } else {
467                 irqmask_keyboard = true;
468         }
469         if(keyirq_bak != irqmask_keyboard) {
470                 display->write_signal(SIG_FM7_SUB_KEY_MASK, irqmask_keyboard ? 1 : 0, 1); 
471                 set_irq_keyboard(irqreq_keyboard);
472         }
473 #endif  
474         return;
475 }
476
477 void FM7_MAINIO::set_irq_syndet(bool flag)
478 {
479         bool backup = intstat_syndet;
480         irqreq_syndet = flag;
481 #if defined(_FM8)
482         intstat_syndet = flag;
483 #else   
484         if(flag && !(irqmask_syndet)) {
485           //irqstat_reg0 &= ~0x80; //~0x20;
486                 intstat_syndet = true;     
487         } else {
488           //    irqstat_reg0 |= 0x80;
489                 intstat_syndet = false;    
490         }
491 #endif  
492         if(backup != intstat_syndet) do_irq();
493 }
494
495
496 void FM7_MAINIO::set_irq_rxrdy(bool flag)
497 {
498         bool backup = intstat_rxrdy;
499         irqreq_rxrdy = flag;
500 #if defined(_FM8)
501         intstat_rxrdy = flag;
502 #else   
503         if(flag && !(irqmask_rxrdy)) {
504           //irqstat_reg0 &= ~0x40; //~0x20;
505                 intstat_rxrdy = true;      
506         } else {
507           //irqstat_reg0 |= 0x40;
508                 intstat_rxrdy = false;     
509         }
510 #endif  
511         if(backup != intstat_rxrdy) do_irq();
512 }
513
514
515
516 void FM7_MAINIO::set_irq_txrdy(bool flag)
517 {
518         bool backup = intstat_txrdy;
519         irqreq_txrdy = flag;
520 #if defined(_FM8)
521         intstat_txrdy = flag;
522 #else   
523         if(flag && !(irqmask_txrdy)) {
524           //irqstat_reg0 &= ~0x20; //~0x20;
525                 intstat_txrdy = true;      
526         } else {
527           //irqstat_reg0 |= 0x20;
528                 intstat_txrdy = false;     
529         }
530 #endif  
531         if(backup != intstat_txrdy) do_irq();
532 }
533
534
535 void FM7_MAINIO::set_irq_timer(bool flag)
536 {
537 #if !defined(_FM8)
538         bool backup = irqstat_timer;
539         if(flag) {
540                 irqstat_reg0 &= 0xfb; //~0x04;
541                 irqstat_timer = true;      
542         } else {
543                 irqstat_reg0 |= 0x04;
544                 irqstat_timer = false;     
545         }
546         //if(backup != irqstat_timer) do_irq();
547         do_irq();
548 #endif  
549 }
550
551 void FM7_MAINIO::set_irq_printer(bool flag)
552 {
553 #if !defined(_FM8)
554         uint8_t backup = irqstat_reg0;
555         irqreq_printer = flag;
556         if(flag && !(irqmask_printer)) {
557                 irqstat_reg0 &= ~0x02;
558                 irqstat_printer = true;    
559         } else {
560                 irqstat_reg0 |= 0x02;
561                 irqstat_printer = false;           
562         }
563         do_irq();
564 #endif  
565 }
566
567 void FM7_MAINIO::set_irq_keyboard(bool flag)
568 {
569         //uint8_t backup = irqstat_reg0;
570         //printf("MAIN: KEYBOARD: IRQ=%d MASK=%d\n", flag ,irqmask_keyboard);
571         irqreq_keyboard = flag;
572         if(flag && !irqmask_keyboard) {
573                 irqstat_reg0 &= 0xfe;
574                 irqstat_keyboard = true;
575         } else {
576                 irqstat_reg0 |= 0x01;
577                 irqstat_keyboard = false;          
578         }
579         do_irq();
580 }
581
582
583 void FM7_MAINIO::do_irq(void)
584 {
585         bool intstat;
586 #if defined(_FM8)
587         intstat = intstat_txrdy | intstat_rxrdy | intstat_syndet;
588 #else   
589         intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
590         intstat = intstat | irqstat_fdc;
591         intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
592         intstat = intstat | intstat_txrdy | intstat_rxrdy | intstat_syndet;
593         intstat = intstat | intstat_mouse;
594 # if defined(HAS_DMA)
595         intstat = intstat | intstat_dma;
596 # endif
597 #endif  
598         //printf("%08d : IRQ: REG0=%02x FDC=%02x, stat=%d\n", SDL_GetTicks(), irqstat_reg0, irqstat_fdc, intstat);
599         if(intstat) {
600                 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
601         } else {
602                 maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
603         }
604 }
605
606 void FM7_MAINIO::do_firq(void)
607 {
608         bool firq_stat;
609         firq_stat = firq_break_key | firq_sub_attention;
610         if(firq_stat) {
611                 maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
612         } else {
613                 maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
614         }
615         p_emu->out_debug_log(_T("IO: do_firq(). BREAK=%d ATTN=%d"), firq_break_key ? 1 : 0, firq_sub_attention ? 1 : 0);
616
617 }
618
619 void FM7_MAINIO::do_nmi(bool flag)
620 {
621         maincpu->write_signal(SIG_CPU_NMI, flag ? 1 : 0, 1);
622 }
623
624
625 void FM7_MAINIO::set_break_key(bool pressed)
626 {
627         firq_break_key = pressed;
628         do_firq();
629 }
630
631 void FM7_MAINIO::set_sub_attention(bool flag)
632 {
633         firq_sub_attention = flag;
634         do_firq();
635 }
636   
637
638 uint8_t FM7_MAINIO::get_fd04(void)
639 {
640         uint8_t val = 0x00;
641         if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
642         if(!firq_break_key) val |= 0x02;
643         if(!firq_sub_attention) {
644                 val |= 0x01;
645         }
646 #if defined(_FM77_VARIANTS)
647         if(stat_fdmode_2hd) val |= 0x40;
648         if(stat_kanjirom)   val |= 0x20;
649         if(stat_400linecard) val |= 0x10;
650         if((display->read_signal(SIG_DISPLAY_EXTRA_MODE) & 0x04) != 0x00) val |= 0x04;
651 #else
652         val |= 0x7c;
653 #endif  
654         if(firq_sub_attention) {
655                 set_sub_attention(false);
656                 //printf("Attention \n");
657         }
658 #if defined(_FM77AV_VARIANTS)
659         if(hotreset) {
660                 if(mainmem->read_signal(FM7_MAINIO_INITROM_ENABLED) == 0) {
661                         set_break_key(false);
662                         hotreset = false;
663                 }
664         }
665 #endif
666         return val;
667 }
668
669 void FM7_MAINIO::set_fd04(uint8_t val)
670 {
671         // NOOP?
672 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
673         display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
674         stat_kanjirom = ((val & 0x20) != 0);
675 #elif defined(_FM77_VARIANTS)
676         display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
677         stat_fdmode_2hd  = ((val & 0x40) != 0);
678         stat_kanjirom    = ((val & 0x20) != 0);
679         stat_400linecard = ((val & 0x10) != 0);
680 #endif  
681 }
682
683   // FD05
684  uint8_t FM7_MAINIO::get_fd05(void)
685 {
686         uint8_t val = 0x7e;
687         if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
688         if(!extdet_neg) val |= 0x01;
689         return val;
690 }
691
692  void FM7_MAINIO::set_fd05(uint8_t val)
693 {
694         sub_cancel = ((val & 0x40) != 0) ? true : false;
695         sub_halt   = ((val & 0x80) != 0) ? true : false;
696         //if(sub_halt != sub_halt_bak) {
697                 display->write_signal(SIG_DISPLAY_HALT,  (sub_halt) ? 0xff : 0x00, 0xff);
698         //}
699         sub_halt_bak = sub_halt;
700
701         //if(sub_cancel != sub_cancel_bak) {
702                 display->write_signal(SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
703         //}
704         sub_cancel_bak = sub_cancel;
705 #ifdef WITH_Z80
706         if((val & 0x01) != 0) {
707                 maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
708                 z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
709         } else {
710                 maincpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
711                 z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
712         }
713 #endif
714 }
715
716 void FM7_MAINIO::set_extdet(bool flag)
717 {
718         extdet_neg = flag;
719 }
720
721 void FM7_MAINIO::write_fd0f(void)
722 {
723 #if defined(_FM8)
724         if((config.dipswitch & FM7_DIPSW_FM8_PROTECT_FD0F) != 0) {
725                 return;
726         }
727         bootmode = 1; // DOS : Where BUBBLE?
728         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
729         mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0, 0xffffffff);
730 #endif  
731         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
732 }
733 uint8_t FM7_MAINIO::read_fd0f(void)
734 {
735 #if defined(_FM8)
736         if((config.dipswitch & FM7_DIPSW_FM8_PROTECT_FD0F) != 0) {
737                 return 0xff;
738         }
739         bootmode = 0; // BASIC
740         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
741         mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0xffffffff, 0xffffffff);
742 #endif  
743         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
744         return 0xff;
745 }
746
747 bool FM7_MAINIO::get_rommode_fd0f(void)
748 {
749         return (mainmem->read_signal(FM7_MAINIO_PUSH_FD0F) == 0) ? false : true;
750 }
751
752
753 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
754 void FM7_MAINIO::write_kanjiaddr_hi(uint8_t addr)
755 {
756         if(!connect_kanjiroml1) return;
757 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
758     defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
759         if(!stat_kanjirom) return;
760 #endif  
761         kanjiclass1->write_data8(KANJIROM_ADDR_HI, addr);
762         return;
763 }
764
765 void FM7_MAINIO::write_kanjiaddr_lo(uint8_t addr)
766 {
767         if(!connect_kanjiroml1) return;
768 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
769     defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
770         if(!stat_kanjirom) return;
771 #endif  
772         kanjiclass1->write_data8(KANJIROM_ADDR_LO, addr);
773         return;
774 }
775
776 uint8_t FM7_MAINIO::read_kanjidata_left(void)
777 {
778         if(!connect_kanjiroml1) return 0xff;
779 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
780     defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
781         if(!stat_kanjirom) return 0xff;
782 #endif  
783         //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
784         if(kanjiclass1) {
785                 return kanjiclass1->read_data8(KANJIROM_DATA_HI);
786         } else {
787                 return 0xff;
788         }
789 }
790
791 uint8_t FM7_MAINIO::read_kanjidata_right(void)
792 {
793         if(!connect_kanjiroml1) return 0xff;
794 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
795     defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
796         if(!stat_kanjirom) return 0xff;
797 #endif  
798         if(kanjiclass1) {
799                 return kanjiclass1->read_data8(KANJIROM_DATA_LO);
800         } else {
801                 return 0xff;
802         }
803 }
804
805 #ifdef CAPABLE_KANJI_CLASS2
806 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
807 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8_t addr)
808 {
809         if(!connect_kanjiroml2) return;
810         if(!stat_kanjirom) return;
811         kanjiclass2->write_data8(KANJIROM_ADDR_HI, addr);
812         return;
813 }
814
815 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8_t addr)
816 {
817         if(!connect_kanjiroml2) return;
818         if(!stat_kanjirom) return;
819         kanjiclass2->write_data8(KANJIROM_ADDR_LO, addr);
820         
821         return;
822 }
823
824 uint8_t FM7_MAINIO::read_kanjidata_left_l2(void)
825 {
826         if(!connect_kanjiroml2) return 0xff;
827         if(!stat_kanjirom) return 0xff;
828         
829         if(kanjiclass2) {
830                 return kanjiclass2->read_data8(KANJIROM_DATA_HI);
831         } else {
832                 return 0xff;
833         }
834 }
835
836 uint8_t FM7_MAINIO::read_kanjidata_right_l2(void)
837 {
838         if(!connect_kanjiroml2) return 0xff;
839         if(!stat_kanjirom) return 0xff;
840         
841         if(kanjiclass2) {
842                 return kanjiclass2->read_data8(KANJIROM_DATA_LO);
843         } else {
844                 return 0xff;
845         }
846 }
847 #endif
848
849
850 uint32_t FM7_MAINIO::read_signal(int id)
851 {
852         uint32_t retval;
853         switch(id) {
854                 case FM7_MAINIO_KEYBOARDIRQ_MASK:
855                         retval = (irqmask_keyboard) ? 0xffffffff : 0x00000000;
856                         break;
857                 default:
858                         retval = 0xffffffff;
859                         break;
860         }
861         return retval;
862 }
863
864
865 void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
866 {
867         bool val_b;
868         val_b = ((data & mask) != 0);
869   
870         switch(id) {
871           //case SIG_FM7_SUB_HALT:
872           //    mainmem->write_signal(SIG_FM7_SUB_HALT, data, mask);
873           //            break;
874                 case FM7_MAINIO_CLOCKMODE: // fd00
875                         if(val_b) {
876                                 clock_fast = true;
877                         } else {
878                                 clock_fast = false;
879                         }
880                         this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
881                         break;
882                 case FM7_MAINIO_CMT_RECV: // FD02
883                         cmt_indat = val_b ^ cmt_invert;
884                         break;
885                 case FM7_MAINIO_CMT_INVERT: // FD02
886                         cmt_invert = val_b;
887                         break;
888                 case FM7_MAINIO_TIMERIRQ: //
889                         set_irq_timer(val_b);
890                         break;
891                 case FM7_MAINIO_LPTIRQ: //
892                         set_irq_printer(val_b);
893                         break;
894                 case FM7_MAINIO_LPT_BUSY:
895                         lpt_busy = val_b;
896                         break;
897                 case FM7_MAINIO_LPT_ERROR:
898                         lpt_error_inv = val_b;
899                         break;
900                 case FM7_MAINIO_LPT_ACK:
901                         {
902                                 bool f = lpt_ackng_inv;
903                                 lpt_ackng_inv = val_b;
904                                 if((lpt_ackng_inv == true) && (f == false)) set_irq_printer(true);
905                         }
906                         break;
907                 case FM7_MAINIO_LPT_PAPER_EMPTY:
908                         lpt_busy = val_b;
909                         break;
910                 case FM7_MAINIO_LPT_DET1:
911                         lpt_det1 = val_b;
912                         break;
913                 case FM7_MAINIO_LPT_DET2:
914                         lpt_det2 = val_b;
915                         break;
916                 case FM7_MAINIO_KEYBOARDIRQ: //
917                         set_irq_keyboard(val_b);
918                         break;
919                         // FD04
920                 case FM7_MAINIO_PUSH_BREAK:
921                         set_break_key(val_b);
922                         break;
923 #if defined(FM77AV_VARIANTS)    
924                 case FM7_MAINIO_HOT_RESET:
925                         hotreset = val_b;
926                         break;
927 #endif
928                 case FM7_MAINIO_SUB_ATTENTION:
929                         if(val_b) set_sub_attention(true);
930                         break;
931                         // FD05
932                 case FM7_MAINIO_EXTDET:
933                         extdet_neg = !val_b;
934                         break;
935                 case FM7_MAINIO_BEEP:
936                         set_beep_oneshot();
937                         break;
938                 case FM7_MAINIO_PSG_IRQ:
939                         break;
940 #if !defined(_FM8)                      
941                 case FM7_MAINIO_OPN_IRQ:
942                         if(!connect_opn) break;
943                         intstat_opn = val_b;
944                         do_irq();
945                         break;
946                 case FM7_MAINIO_WHG_IRQ:
947                         if(!connect_whg) break;
948                         intstat_whg = val_b;
949                         do_irq();
950                         break;
951                 case FM7_MAINIO_THG_IRQ:
952                         if(!connect_thg) break;
953                         intstat_thg = val_b;
954                         do_irq();
955                         break;
956 #endif                  
957                 case FM7_MAINIO_FDC_DRQ:
958                         set_drq_mfd(val_b);
959                         break;
960                 case FM7_MAINIO_FDC_IRQ:
961                         set_irq_mfd(val_b);
962                         break;
963 #if defined(HAS_DMA)
964                 case FM7_MAINIO_DMA_INT:
965                         intstat_dma = val_b;
966                         do_irq();
967                         break;
968 #endif
969 #if defined(_FM77AV_VARIANTS)
970                 case SIG_DISPLAY_DISPLAY:
971                         if(val_b) {
972                                 reg_fd12 |= 0x02;
973                         } else {
974                                 reg_fd12 &= ~0x02;
975                         }
976                         break;
977                 case SIG_DISPLAY_VSYNC:
978                         if(val_b) {
979                                 reg_fd12 |= 0x01;
980                         } else {
981                                 reg_fd12 &= ~0x01;
982                         }
983                         break;
984                 case SIG_DISPLAY_MODE320:
985                         if(val_b) {
986                                 reg_fd12 |= 0x40;
987                         } else {
988                                 reg_fd12 &= ~0x40;
989                         }
990                         break;
991 #endif                  
992         }
993 }
994
995
996  uint8_t FM7_MAINIO::get_irqstat_fd03(void)
997 {
998         uint8_t val;
999         bool extirq;
1000 #if !defined(_FM8)      
1001         extirq = irqstat_fdc | intstat_opn | intstat_whg | intstat_thg;
1002         extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
1003 # if defined(HAS_DMA)
1004         extirq = extirq | intstat_dma;
1005 # endif   
1006         if(extirq) {
1007                 irqstat_reg0 &= ~0x08;
1008         } else {
1009                 irqstat_reg0 |= 0x08;
1010         }
1011         val = irqstat_reg0 | 0xf0;
1012         // Not call do_irq() twice. 20151221 
1013         irqstat_timer = false;
1014         irqstat_printer = false;
1015         irqstat_reg0 |= 0x06;
1016         do_irq();
1017         //p_emu->out_debug_log(_T("IO: Check IRQ Status."));
1018         return val;
1019 #else
1020         return 0xff;
1021 #endif
1022 }
1023
1024 uint8_t FM7_MAINIO::get_extirq_fd17(void)
1025 {
1026         uint8_t val = 0xff;
1027 #if !defined(_FM8)      
1028         if(intstat_opn && connect_opn)   val &= ~0x08;
1029         if(intstat_mouse) val &= ~0x04;
1030 #endif
1031         return val;
1032 }
1033
1034 void FM7_MAINIO::set_ext_fd17(uint8_t data)
1035 {
1036 #if !defined(_FM8)
1037         if((data & 0x04) != 0) {
1038                 mouse_enable = true;
1039         } else {
1040                 mouse_enable = false;
1041         }
1042 #endif
1043 }
1044
1045 #if defined(_FM77AV_VARIANTS)
1046 // FD12
1047 uint8_t FM7_MAINIO::subsystem_read_status(void)
1048 {
1049         return reg_fd12;
1050 }
1051 #endif
1052
1053
1054 uint32_t FM7_MAINIO::read_io8(uint32_t addr)
1055 { // This is only for debug.
1056         addr = addr & 0xfff;
1057         if(addr < 0x100) {
1058                 return io_w_latch[addr];
1059         } else if(addr < 0x500) {
1060                 uint32_t ofset = addr & 0xff;
1061                 uint opnbank = (addr - 0x100) >> 8;
1062                 return opn_regs[opnbank][ofset];
1063         } else if(addr < 0x600) {
1064                 return mainmem->read_data8(addr - 0x500 + FM7_MAINIO_MMR_BANK);
1065         }
1066         return 0xff;
1067 }
1068
1069 uint32_t FM7_MAINIO::read_dma_io8(uint32_t addr)
1070 {
1071         return this->read_data8(addr & 0xff);
1072 }
1073
1074 uint32_t FM7_MAINIO::read_dma_data8(uint32_t addr)
1075 {
1076         return this->read_data8(addr & 0xff);
1077 }
1078
1079 uint32_t FM7_MAINIO::read_data8(uint32_t addr)
1080 {
1081         uint32_t retval;
1082         uint32_t mmr_segment;
1083         if(addr < FM7_MAINIO_IS_BASICROM) {   
1084                 addr = addr & 0xff;
1085                 retval = 0xff;
1086 #if defined(HAS_MMR)
1087                 if((addr < 0x90) && (addr >= 0x80)) {
1088                         mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1089 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1090      defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1091                         mmr_segment &= 0x07;
1092 # else             
1093                         mmr_segment &= 0x03;
1094 # endif
1095                         return mainmem->read_data8(addr - 0x80 + FM7_MAINIO_MMR_BANK + mmr_segment * 16);
1096                 }
1097 #endif
1098         //      if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
1099                 switch(addr) {
1100                 case 0x00: // FD00
1101                         retval = (uint32_t) get_port_fd00();
1102                         break;
1103                 case 0x01: // FD01
1104 #if !defined(_FM8)                      
1105                         retval = keyboard->read_data8(0x01) & 0xff;
1106 #endif                  
1107                         break;
1108                 case 0x02: // FD02
1109                         retval = (uint32_t) get_port_fd02();
1110                         break;
1111                 case 0x03: // FD03
1112 #if !defined(_FM8)
1113                         retval = (uint32_t) get_irqstat_fd03();
1114 #endif                  
1115                         break;
1116                 case 0x04: // FD04
1117                         retval = (uint32_t) get_fd04();
1118                         break;
1119                 case 0x05: // FD05
1120                         retval = (uint32_t) get_fd05();
1121                         break;
1122                 case 0x06: // RS-232C
1123                 case 0x07:
1124                         break;
1125                 case 0x08: // Light pen
1126                 case 0x09:
1127                 case 0x0a:
1128                         break;
1129 #if defined(_FM77AV_VARIANTS)
1130                 case 0x0b:
1131                         retval = ((config.boot_mode & 3) == 0) ? 0xfe : 0xff;
1132                         break;
1133 #endif                  
1134                 case 0x0e: // PSG DATA
1135                         retval = (uint32_t) get_psg();
1136                         //printf("PSG DATA READ val=%02x\n", retval);
1137                         break;
1138                 case 0x0f: // FD0F
1139                         read_fd0f();
1140                         retval = 0xff;
1141                         break;
1142 #if defined(_FM8)
1143                 case 0x10:
1144                 case 0x11:
1145                 case 0x12:
1146                 case 0x13:
1147                 case 0x14:
1148                 case 0x15:
1149                 case 0x16:
1150                 case 0x17:
1151                         retval = bubble_casette[0]->read_data8(addr);
1152                         break;
1153 #else                   
1154 #if defined(_FM77AV_VARIANTS)
1155                 case 0x12:
1156                         retval = subsystem_read_status();  
1157                         break;
1158 #endif
1159                         //printf("OPN CMD READ \n");
1160                         break;
1161                 case 0x16: // OPN DATA
1162                         retval = (uint32_t) get_opn(0);
1163                         break;
1164                 case 0x17:
1165                         retval = (uint32_t) get_extirq_fd17();
1166                         break;
1167 #endif                  
1168                 case 0x18: // FDC: STATUS
1169                         retval = (uint32_t) get_fdc_stat();
1170                         //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc()); 
1171                         break;
1172                 case 0x19: // FDC: Track
1173                         retval = (uint32_t) get_fdc_track();
1174                         //printf("FDC: READ TRACK REG %02x\n", retval); 
1175                         break;
1176                 case 0x1a: // FDC: Sector
1177                         retval = (uint32_t) get_fdc_sector();
1178                         //printf("FDC: READ SECTOR REG %02x\n", retval); 
1179                         break;
1180                 case 0x1b: // FDC: Data
1181                         retval = (uint32_t) get_fdc_data();
1182                         break;
1183                 case 0x1c:
1184                         retval = (uint32_t) get_fdc_fd1c();
1185                         //printf("FDC: READ HEAD REG %02x\n", retval); 
1186                         break;
1187                 case 0x1d:
1188                         retval = (uint32_t) get_fdc_motor();
1189                         //printf("FDC: READ MOTOR REG %02x\n", retval); 
1190                         break;
1191                 case 0x1e:
1192                         retval = (uint32_t) get_fdc_fd1e();
1193                         //printf("FDC: READ MOTOR REG %02x\n", retval); 
1194                         break;
1195                 case 0x1f:
1196                         retval = (uint32_t) fdc_getdrqirq();
1197                         break;
1198                 case 0x22: // Kanji ROM
1199                         retval = (uint32_t) read_kanjidata_left();
1200                         break;
1201                 case 0x23: // Kanji ROM
1202                         retval = (uint32_t) read_kanjidata_right();
1203                         break;
1204 #if defined(CAPABLE_KANJI_CLASS2)
1205                 case 0x2e: // Kanji ROM Level2
1206                         retval = (uint32_t) read_kanjidata_left_l2();
1207                         break;
1208                 case 0x2f: // Kanji ROM Level2
1209                         retval = (uint32_t) read_kanjidata_right_l2();
1210                         break;
1211 #endif
1212 #if !defined(_FM8)                      
1213                 case 0x37: // Multi page
1214                         //retval = (uint32_t)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
1215                         break;
1216                 case 0x45: // WHG CMD
1217                         break;
1218                 case 0x46: // WHG DATA
1219                         retval = (uint32_t) get_opn(1);
1220                         break;
1221                 case 0x47:
1222                         retval = (uint32_t) get_extirq_whg();
1223                         break;
1224                 case 0x51: // THG CMD
1225                         break;
1226                 case 0x52: // THG DATA
1227                         retval = (uint32_t) get_opn(2);
1228                         break;
1229                 case 0x53:
1230                         retval = (uint32_t) get_extirq_thg();
1231                         break;
1232 #endif                  
1233 #if defined(HAS_MMR)
1234                 case 0x93:
1235                         retval = 0x3e;
1236                         //retval = 0x00;
1237                         if(mainmem->read_signal(FM7_MAINIO_BOOTRAM_RW) != 0)     retval |= 0x01;
1238                         if(mainmem->read_signal(FM7_MAINIO_WINDOW_ENABLED) != 0) retval |= 0x40;
1239                         if(mainmem->read_signal(FM7_MAINIO_MMR_ENABLED) != 0)    retval |= 0x80;
1240                         break;
1241 #endif
1242 #if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1243                 case 0x95:
1244                         retval = 0x77;
1245                         if(mainmem->read_signal(FM7_MAINIO_FASTMMR_ENABLED) != 0) retval |= 0x08;
1246                         if(mainmem->read_signal(FM7_MAINIO_EXTROM)  != 0) retval |= 0x80;
1247                         break;
1248 #endif                  
1249 #if defined(HAS_DMA)
1250                 case 0x98:
1251                         retval = dma_addr;
1252                         break;
1253                 case 0x99:
1254                         retval = dmac->read_data8(dma_addr);
1255                         break;
1256 #endif                  
1257                 default:
1258                         break;
1259                 }
1260 #if !defined(_FM8)                      
1261                 if((addr < 0x40) && (addr >= 0x38)) {
1262                         addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
1263                         return (uint32_t) display->read_data8(addr);
1264                 }
1265 #endif          
1266                 // Another:
1267                 return retval;
1268         } else if(addr == FM7_MAINIO_CLOCKMODE) {
1269                 return (uint32_t)get_clockmode();
1270         }
1271 #if defined(_FM77AV_VARIANTS)
1272         else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
1273                 retval = sub_monitor_type & 0x03;
1274                 return retval;
1275         }  else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
1276 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1277     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1278                 retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
1279 #else
1280                 retval = 0;
1281 #endif
1282                 return retval;
1283         }
1284 #endif
1285         //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
1286    return 0xff;
1287 }
1288
1289 void FM7_MAINIO::write_dma_io8(uint32_t addr, uint32_t data)
1290 {
1291         this->write_data8(addr & 0xff, data);
1292 }
1293
1294 void FM7_MAINIO::write_dma_data8(uint32_t addr, uint32_t data)
1295 {
1296         this->write_data8(addr & 0xff, data);
1297 }
1298
1299
1300 void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
1301 {
1302         bool flag;
1303         uint32_t mmr_segment;
1304         if(addr < FM7_MAINIO_IS_BASICROM) {
1305                 addr = addr & 0xff;
1306                 io_w_latch[addr] = data;
1307 #if defined(HAS_MMR)
1308                 if((addr < 0x90) && (addr >= 0x80)) {
1309                         mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1310 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1311      defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1312                         mmr_segment &= 0x07;
1313 # else             
1314                         mmr_segment &= 0x03;
1315 # endif
1316                         mainmem->write_data8(FM7_MAINIO_MMR_BANK + mmr_segment * 16 + addr - 0x80, data);
1317                         return;
1318                 }
1319 #endif
1320                 switch(addr) {
1321                 case 0x00: // FD00
1322                         set_port_fd00((uint8_t)data);
1323                         return;
1324                         break;
1325                 case 0x01: // FD01
1326                         lpt_outdata = (uint8_t)data;
1327                         switch(lpt_type) {
1328                         case 0: // Write to file
1329                                 printer->write_signal(SIG_PRINTER_DATA, data, 0xff);
1330                                 break;
1331                         case 1:
1332                         case 2:
1333                                 joystick->write_data8(0x01, data);
1334                                 break;
1335                         }
1336                         break;
1337                 case 0x02: // FD02
1338                         set_port_fd02((uint8_t)data);
1339                         break;
1340                 case 0x03: // FD03
1341                         set_beep(data);
1342                         break;
1343                 case 0x04: // FD04
1344                         set_fd04(data);
1345                         break;
1346                 case 0x05: // FD05
1347                         set_fd05((uint8_t)data);
1348                         break;
1349                 case 0x06: // RS-232C
1350                 case 0x07:
1351                         break;
1352                 case 0x08: // Light pen
1353                 case 0x09:
1354                 case 0x0a:
1355                         break;
1356                 case 0x0d:
1357                         //printf("PSG CMD WRITE val=%02x\n", data);
1358                         set_psg_cmd(data);
1359                         break;
1360                 case 0x0e:
1361                         //printf("PSG DATA WRITE val=%02x\n", data);
1362                         set_psg(data);
1363                         break;
1364                 case 0x0f: // FD0F
1365                         write_fd0f();
1366                         break;
1367 #if defined(_FM8)
1368                 case 0x10:
1369                 case 0x11:
1370                 case 0x12:
1371                 case 0x13:
1372                 case 0x14:
1373                 case 0x15:
1374                 case 0x16:
1375                 case 0x17:
1376                         bubble_casette[0]->write_data8(addr, data);
1377                         break;
1378 #else                   
1379 #if defined(_FM77AV_VARIANTS)
1380                 case 0x10:
1381                         flag = ((data & 0x02) == 0) ? true : false;
1382                         mainmem->write_signal(FM7_MAINIO_INITROM_ENABLED, (flag) ? 0xffffffff : 0 , 0xffffffff);
1383                         break;
1384                 case 0x12:
1385                         display->write_signal(SIG_DISPLAY_MODE320, data,  0x40);
1386                         reg_fd12 &= ~0x40;
1387                         reg_fd12 |= (data & 0x40);
1388                         break;
1389                 case 0x13:
1390                         sub_monitor_type = data & 0x07;
1391                         display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
1392                         break;
1393 #endif
1394                 case 0x15: // OPN CMD
1395                         //printf("OPN CMD WRITE val=%02x\n", data);
1396                         set_opn_cmd(0, data);
1397                         break;
1398                 case 0x16: // OPN DATA
1399                         //printf("OPN DATA WRITE val=%02x\n", data);
1400                         set_opn(0, data);
1401                         break;
1402                 case 0x17:
1403                         set_ext_fd17((uint8_t)data);
1404                         break;
1405 #endif                  
1406                 case 0x18: // FDC: COMMAND
1407                         set_fdc_cmd((uint8_t)data);
1408                         //printf("FDC: WRITE CMD %02x\n", data); 
1409                         break;
1410                 case 0x19: // FDC: Track
1411                         set_fdc_track((uint8_t)data);
1412                         //printf("FDC: WRITE TRACK REG %02x\n", data); 
1413                         break;
1414                 case 0x1a: // FDC: Sector
1415                         set_fdc_sector((uint8_t)data);
1416                         //printf("FDC: WRITE SECTOR REG %02x\n", data); 
1417                         break;
1418                 case 0x1b: // FDC: Data
1419                         set_fdc_data((uint8_t)data);
1420                         break;
1421                 case 0x1c:
1422                         set_fdc_fd1c((uint8_t)data);
1423                         //printf("FDC: WRITE HEAD REG %02x\n", data); 
1424                         break;
1425                 case 0x1d:
1426                         set_fdc_fd1d((uint8_t)data);
1427                         //printf("FDC: WRITE MOTOR REG %02x\n", data); 
1428                         break;
1429                 case 0x1e:
1430                         set_fdc_fd1e((uint8_t)data);
1431                         break;
1432                 case 0x1f: // ??
1433                         return;
1434                         break;
1435                 case 0x20: // Kanji ROM
1436                         write_kanjiaddr_hi((uint8_t)data);
1437                         break;
1438                 case 0x2c: // Kanji ROM(DUP)
1439 #if defined(CAPABLE_KANJI_CLASS2)
1440                         write_kanjiaddr_hi_l2((uint8_t)data);
1441 #else                   
1442                         //write_kanjiaddr_hi((uint8_t)data);
1443 #endif
1444                         break;
1445                 case 0x21: // Kanji ROM
1446                         write_kanjiaddr_lo((uint8_t)data);
1447                         break;
1448                 case 0x2d: // Kanji ROM(DUP)
1449 #if defined(CAPABLE_KANJI_CLASS2)
1450                         write_kanjiaddr_lo_l2((uint8_t)data);
1451 #else
1452                         //write_kanjiaddr_lo((uint8_t)data);
1453 #endif
1454                         break;
1455 #if defined(CAPABLE_DICTROM)
1456                 case 0x2e: // 
1457                         mainmem->write_signal(FM7_MAINIO_EXTBANK, data, 0xff);
1458                         break;
1459 #endif                  
1460 #if defined(_FM77AV_VARIANTS)
1461                 case 0x30:
1462                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
1463                         break;
1464                 case 0x31:
1465                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
1466                         break;
1467                 case 0x32:
1468                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
1469                         break;
1470                 case 0x33:
1471                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
1472                         break;
1473                 case 0x34:
1474                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
1475                         break;
1476 #endif
1477 #if !defined(_FM8)                      
1478                 case 0x37: // Multi page
1479                         display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
1480                         break;
1481                 case 0x45: // WHG CMD
1482                         set_opn_cmd(1, data);
1483                         break;
1484                 case 0x46: // WHG DATA
1485                         set_opn(1, data);
1486                         break;
1487                 case 0x47:
1488                         break;
1489                 case 0x51: // THG CMD
1490                         set_opn_cmd(2, data);
1491                         break;
1492                 case 0x52: // THG DATA
1493                         set_opn(2, data);
1494                         break;
1495                 case 0x53:
1496                         break;
1497 #endif                  
1498 #if defined(HAS_MMR)
1499                 case 0x90:
1500 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1501     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1502                         mmr_segment = data & 7;
1503 #else
1504                         //                      printf("MMR SEGMENT: %02x\n", data & 3);
1505                         mmr_segment = data & 3;
1506 #endif                  
1507                         mainmem->write_data8(FM7_MAINIO_MMR_SEGMENT, (uint32_t)mmr_segment);
1508                         break;
1509                 case 0x92:
1510                         mainmem->write_data8(FM7_MAINIO_WINDOW_OFFSET, (uint32_t)(data & 0x00ff));
1511                         break;
1512                 case 0x93:
1513                         mainmem->write_signal(FM7_MAINIO_BOOTRAM_RW, data, 0x01);
1514                         mainmem->write_signal(FM7_MAINIO_WINDOW_ENABLED, data , 0x40);
1515                         //this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1516                         //mainmem->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1517                         mainmem->write_signal(FM7_MAINIO_MMR_ENABLED, data, 0x80);
1518                         //}
1519                         break;
1520 #endif
1521 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1522     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1523                 case 0x94:
1524                         mainmem->write_signal(FM7_MAINIO_MMR_EXTENDED, data, 0x80);
1525                         mainmem->write_signal(FM7_MAINMEM_REFRESH_FAST, data, 0x04);
1526                         mainmem->write_signal(FM7_MAINIO_WINDOW_FAST , data, 0x01);
1527
1528                         break;
1529 # if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1530                 case 0x95:
1531                         mainmem->write_signal(FM7_MAINIO_FASTMMR_ENABLED, data, 0x08);
1532                         mainmem->write_signal(FM7_MAINIO_EXTROM, data , 0x80);
1533                         break;
1534 # endif
1535 #endif                  
1536 #if defined(HAS_DMA)
1537                 case 0x98:
1538                         dma_addr = data & 0x1f;
1539                         break;
1540                 case 0x99:
1541                         dmac->write_data8(dma_addr, data);
1542                         //p_emu->out_debug_log(_T("IO: Wrote DMA %02x to reg %02x\n"), data, dma_addr);
1543                         break;
1544 #endif                  
1545                 default:
1546                         //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data); 
1547                         break;
1548                 }
1549 #if !defined(_FM8)                      
1550                 if((addr < 0x40) && (addr >= 0x38)) {
1551                         addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1552                         display->write_data8(addr, (uint8_t)data);
1553                         return;
1554                 }// Another:
1555 #endif          
1556                 return;
1557         } else if(addr == FM7_MAINIO_CLOCKMODE) {
1558                 set_clockmode((uint8_t)data);
1559                 return;
1560         }
1561         //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
1562 }
1563
1564 void FM7_MAINIO::event_callback(int event_id, int err)
1565 {
1566 //      printf("MAIN EVENT id=%d\n", event_id);
1567         switch(event_id) {
1568                 case EVENT_BEEP_OFF:
1569                         event_beep_off();
1570                         break;
1571                 case EVENT_BEEP_CYCLE:
1572                         event_beep_cycle();
1573                         break;
1574                 case EVENT_UP_BREAK:
1575                         set_break_key(false);
1576                         break;
1577 #if !defined(_FM8)
1578                 case EVENT_TIMERIRQ_ON:
1579                         //if(!irqmask_timer) set_irq_timer(true);
1580                         set_irq_timer(!irqmask_timer);
1581                         break;
1582 #endif                  
1583                 case EVENT_FD_MOTOR_ON:
1584                         set_fdc_motor(true);
1585                         event_fdc_motor = -1;
1586                         break;
1587                 case EVENT_FD_MOTOR_OFF:
1588                         set_fdc_motor(false);
1589                         event_fdc_motor = -1;
1590                         break;
1591                 case EVENT_PRINTER_RESET_COMPLETED:                     
1592                         this->write_signals(&printer_reset_bus, 0x00);
1593                         break;
1594                 default:
1595                         break;
1596         }
1597 }
1598
1599
1600 void FM7_MAINIO::update_config()
1601 {
1602         switch(config.cpu_type){
1603                 case 0:
1604                         clock_fast = true;
1605                         break;
1606                 case 1:
1607                         clock_fast = false;
1608                         break;
1609         }
1610         this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
1611 #if defined(_FM8)       
1612         // BASIC
1613         if(config.boot_mode == 0) {
1614                 mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0xffffffff, 0xffffffff);
1615         } else {
1616                 mainmem->write_signal(FM7_MAINIO_IS_BASICROM, 0, 0xffffffff);
1617         }
1618         mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, (config.boot_mode == 0) ? 1 : 0, 0x01);
1619         mainmem->write_signal(FM7_MAINIO_BOOTMODE, bootmode, 0xffffffff);
1620 #endif  
1621 }
1622
1623 void FM7_MAINIO::event_vline(int v, int clock)
1624 {
1625 }
1626
1627 #define STATE_VERSION 6
1628 void FM7_MAINIO::save_state(FILEIO *state_fio)
1629 {
1630         int ch;
1631         int addr;
1632         state_fio->FputUint32_BE(STATE_VERSION);
1633         state_fio->FputInt32_BE(this_device_id);
1634
1635         // Version 1
1636         {
1637                 for(addr = 0; addr < 0x100; addr++) state_fio->FputUint8(io_w_latch[addr]);
1638                 // FD00
1639                 state_fio->FputBool(clock_fast);
1640                 state_fio->FputBool(lpt_strobe);
1641                 state_fio->FputBool(lpt_slctin);
1642                 state_fio->FputBool(beep_flag);
1643                 state_fio->FputBool(beep_snd);
1644         
1645                 // FD01
1646                 state_fio->FputUint8(lpt_outdata);
1647                 // FD02
1648                 state_fio->FputBool(cmt_indat);
1649                 state_fio->FputBool(cmt_invert);
1650                 state_fio->FputBool(lpt_det2);
1651                 state_fio->FputBool(lpt_det1);
1652                 state_fio->FputBool(lpt_pe);
1653                 state_fio->FputBool(lpt_ackng_inv);
1654                 state_fio->FputBool(lpt_error_inv);
1655                 state_fio->FputUint8(irqmask_reg0);
1656                 
1657                 state_fio->FputBool(irqmask_syndet);
1658                 state_fio->FputBool(irqmask_rxrdy);
1659                 state_fio->FputBool(irqmask_txrdy);
1660                 state_fio->FputBool(irqmask_mfd);
1661                 state_fio->FputBool(irqmask_timer);
1662                 state_fio->FputBool(irqmask_printer);
1663                 state_fio->FputBool(irqmask_keyboard);
1664
1665                 state_fio->FputBool(irqreq_syndet);
1666                 state_fio->FputBool(irqreq_rxrdy);
1667                 state_fio->FputBool(irqreq_txrdy);
1668                 state_fio->FputBool(irqreq_printer);
1669                 state_fio->FputBool(irqreq_keyboard);
1670                 // FD03
1671                 state_fio->FputUint8(irqstat_reg0);
1672                 
1673                 state_fio->FputBool(irqstat_timer);
1674                 state_fio->FputBool(irqstat_printer);
1675                 state_fio->FputBool(irqstat_keyboard);
1676                 
1677                 // FD04
1678 #if defined(_FM77_VARIANTS)
1679                 state_fio->FputBool(stat_fdmode_2hd);
1680                 state_fio->FputBool(stat_kanjirom);
1681                 state_fio->FputBool(stat_400linecard);
1682 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1683       defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
1684                 state_fio->FputBool(stat_kanjirom);
1685 #endif
1686                 state_fio->FputBool(firq_break_key);
1687                 state_fio->FputBool(firq_sub_attention);
1688                 
1689                 state_fio->FputBool(intmode_fdc);
1690                 // FD05
1691                 state_fio->FputBool(extdet_neg);
1692                 state_fio->FputBool(sub_halt);
1693                 state_fio->FputBool(sub_cancel);
1694 #if defined(WITH_Z80)   
1695                 state_fio->FputBool(z80_sel);
1696 #endif  
1697                 // FD06, 07
1698                 state_fio->FputBool(intstat_syndet);
1699                 state_fio->FputBool(intstat_rxrdy);
1700                 state_fio->FputBool(intstat_txrdy);
1701
1702         // FD0B
1703         // FD0F
1704 #if defined(_FM8)
1705                 state_fio->FputBool(connect_psg);
1706 #else   
1707                 state_fio->FputBool(connect_opn);
1708                 state_fio->FputBool(connect_whg);
1709                 state_fio->FputBool(connect_thg);
1710                 
1711                 state_fio->FputBool(opn_psg_77av);
1712 #endif  
1713 #if defined(_FM8)
1714                 {
1715                         state_fio->FputUint32_BE(opn_address[0]);
1716                         state_fio->FputUint32_BE(opn_data[0]);
1717                         state_fio->FputUint32_BE(opn_stat[0]);
1718                         state_fio->FputUint32_BE(opn_cmdreg[0]);
1719                         state_fio->FputUint32_BE(opn_ch3mode[0]);
1720                 }
1721 #else           
1722                 for(ch = 0; ch < 4; ch++) {
1723                         state_fio->FputUint32_BE(opn_address[ch]);
1724                         state_fio->FputUint32_BE(opn_data[ch]);
1725                         state_fio->FputUint32_BE(opn_stat[ch]);
1726                         state_fio->FputUint32_BE(opn_cmdreg[ch]);
1727                         state_fio->FputUint32_BE(opn_ch3mode[ch]);
1728                 }
1729 #endif          
1730
1731                 state_fio->FputBool(intstat_opn);
1732                 state_fio->FputBool(intstat_mouse);
1733                 state_fio->FputBool(mouse_enable);
1734         
1735                 state_fio->FputBool(intstat_whg);
1736                 state_fio->FputBool(intstat_thg);
1737
1738         // FDC
1739                 state_fio->FputBool(connect_fdc);
1740                 state_fio->FputUint8(fdc_statreg);
1741                 state_fio->FputUint8(fdc_cmdreg);
1742                 state_fio->FputUint8(fdc_trackreg);
1743                 state_fio->FputUint8(fdc_sectreg);
1744                 state_fio->FputUint8(fdc_datareg);
1745                 state_fio->FputUint8(fdc_headreg);
1746                 state_fio->FputUint8(fdc_drvsel);
1747                 state_fio->FputUint8(irqreg_fdc);
1748                 state_fio->FputBool(fdc_motor);
1749                 state_fio->FputBool(irqstat_fdc);
1750                 // KANJI ROM
1751                 state_fio->FputBool(connect_kanjiroml1);
1752 #if defined(_FM77AV_VARIANTS)
1753                 state_fio->FputBool(connect_kanjiroml2);
1754         
1755                 state_fio->FputBool(boot_ram);
1756                 state_fio->FputBool(hotreset);
1757                 // FD13
1758                 state_fio->FputUint8(sub_monitor_type);
1759 #endif  
1760                 // MMR
1761         }
1762         //V2
1763         {
1764                 state_fio->FputInt32_BE(event_beep);
1765                 state_fio->FputInt32_BE(event_beep_oneshot);
1766                 state_fio->FputInt32_BE(event_timerirq);
1767         }               
1768         { // V3
1769                 state_fio->FputInt32_BE(event_fdc_motor);
1770 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
1771     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1772                 for(ch = 0; ch < 4; ch++) state_fio->FputUint8(fdc_drive_table[ch]);
1773                 state_fio->FputUint8(fdc_reg_fd1e);
1774 #endif  
1775 #if defined(HAS_DMA)
1776                 state_fio->FputBool(intstat_dma);
1777                 state_fio->FputUint8(dma_addr & 0x1f);
1778 #endif                  
1779 #if defined(_FM77AV_VARIANTS)
1780                 state_fio->FputUint8(reg_fd12);
1781 #endif          
1782         }               
1783 }
1784
1785 bool FM7_MAINIO::load_state(FILEIO *state_fio)
1786 {
1787         int ch;
1788         int addr;
1789         //bool stat = false;
1790         uint32_t version;
1791         
1792         version = state_fio->FgetUint32_BE();
1793         if(this_device_id != state_fio->FgetInt32_BE()) return false;
1794
1795         if(version >= 1) {
1796                 for(addr = 0; addr < 0x100; addr++) io_w_latch[addr] = state_fio->FgetUint8();
1797                 // FD00
1798                 clock_fast = state_fio->FgetBool();
1799                 lpt_strobe = state_fio->FgetBool();
1800                 lpt_slctin = state_fio->FgetBool();
1801                 beep_flag  = state_fio->FgetBool();
1802                 beep_snd = state_fio->FgetBool();
1803         
1804                 // FD01
1805                 lpt_outdata = state_fio->FgetUint8();
1806                 // FD02
1807                 cmt_indat = state_fio->FgetBool();
1808                 cmt_invert = state_fio->FgetBool();
1809                 lpt_det2 = state_fio->FgetBool();
1810                 lpt_det1 = state_fio->FgetBool();
1811                 lpt_pe = state_fio->FgetBool();
1812                 lpt_ackng_inv = state_fio->FgetBool();
1813                 lpt_error_inv = state_fio->FgetBool();
1814                 irqmask_reg0 = state_fio->FgetUint8();
1815
1816                 irqmask_syndet = state_fio->FgetBool();
1817                 irqmask_rxrdy = state_fio->FgetBool();
1818                 irqmask_txrdy = state_fio->FgetBool();
1819                 irqmask_mfd = state_fio->FgetBool();
1820                 irqmask_timer = state_fio->FgetBool();
1821                 irqmask_printer = state_fio->FgetBool();
1822                 irqmask_keyboard = state_fio->FgetBool();
1823
1824                 irqreq_syndet = state_fio->FgetBool();
1825                 irqreq_rxrdy = state_fio->FgetBool();
1826                 irqreq_txrdy = state_fio->FgetBool();
1827                 irqreq_printer = state_fio->FgetBool();
1828                 irqreq_keyboard = state_fio->FgetBool();
1829                 // FD03
1830                 irqstat_reg0 = state_fio->FgetUint8();
1831
1832                 irqstat_timer = state_fio->FgetBool();
1833                 irqstat_printer = state_fio->FgetBool();
1834                 irqstat_keyboard = state_fio->FgetBool();
1835         
1836                 // FD04
1837 #if defined(_FM77_VARIANTS)
1838                 stat_fdmode_2hd = state_fio->FgetBool();
1839                 stat_kanjirom = state_fio->FgetBool();
1840                 stat_400linecard = state_fio->FgetBool();
1841 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
1842       defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
1843                 stat_kanjirom = state_fio->FgetBool();
1844 #endif
1845                 firq_break_key = state_fio->FgetBool();
1846                 firq_sub_attention = state_fio->FgetBool();
1847                 
1848                 intmode_fdc = state_fio->FgetBool();
1849                 // FD05
1850                 extdet_neg = state_fio->FgetBool();
1851                 sub_halt = state_fio->FgetBool();
1852                 sub_cancel = state_fio->FgetBool();
1853 #if defined(WITH_Z80)   
1854                 z80_sel = state_fio->FgetBool();
1855 #endif  
1856                 // FD06, 07
1857                 intstat_syndet = state_fio->FgetBool();
1858                 intstat_rxrdy = state_fio->FgetBool();
1859                 intstat_txrdy = state_fio->FgetBool();
1860
1861                 // FD0B
1862                 // FD0F
1863 #if defined(_FM8)
1864                 connect_psg = state_fio->FgetBool();
1865 #else           
1866                 connect_opn = state_fio->FgetBool();
1867                 connect_whg = state_fio->FgetBool();
1868                 connect_thg = state_fio->FgetBool();
1869
1870                 opn_psg_77av = state_fio->FgetBool();
1871 #endif
1872 #if defined(_FM8)
1873                 {
1874                         opn_address[0] = state_fio->FgetUint32_BE();
1875                         opn_data[0] = state_fio->FgetUint32_BE();
1876                         opn_stat[0] = state_fio->FgetUint32_BE();
1877                         opn_cmdreg[0] = state_fio->FgetUint32_BE();
1878                         opn_ch3mode[0] = state_fio->FgetUint32_BE();
1879                 }
1880 #else           
1881                 for(ch = 0; ch < 4; ch++) {
1882                         opn_address[ch] = state_fio->FgetUint32_BE();
1883                         opn_data[ch] = state_fio->FgetUint32_BE();
1884                         opn_stat[ch] = state_fio->FgetUint32_BE();
1885                         opn_cmdreg[ch] = state_fio->FgetUint32_BE();
1886                         opn_ch3mode[ch] = state_fio->FgetUint32_BE();
1887                 }
1888 #endif
1889                 intstat_opn = state_fio->FgetBool();
1890                 intstat_mouse = state_fio->FgetBool();
1891                 mouse_enable = state_fio->FgetBool();
1892         
1893                 intstat_whg = state_fio->FgetBool();
1894                 intstat_thg = state_fio->FgetBool();
1895
1896                 // FDC
1897                 connect_fdc = state_fio->FgetBool();
1898                 fdc_statreg = state_fio->FgetUint8();
1899                 fdc_cmdreg = state_fio->FgetUint8();
1900                 fdc_trackreg = state_fio->FgetUint8();
1901                 fdc_sectreg = state_fio->FgetUint8();
1902                 fdc_datareg = state_fio->FgetUint8();
1903                 fdc_headreg = state_fio->FgetUint8();
1904                 fdc_drvsel = state_fio->FgetUint8();
1905                 irqreg_fdc = state_fio->FgetUint8();
1906                 fdc_motor = state_fio->FgetBool();
1907                 irqstat_fdc = state_fio->FgetBool();
1908
1909                 // KANJI ROM
1910                 connect_kanjiroml1 = state_fio->FgetBool();
1911 #if defined(_FM77AV_VARIANTS)
1912                 connect_kanjiroml2 = state_fio->FgetBool();
1913                 boot_ram = state_fio->FgetBool();
1914                 hotreset = state_fio->FgetBool();
1915                 // FD13
1916                 sub_monitor_type = state_fio->FgetUint8();
1917 #endif  
1918         }
1919         if(version >= 2) {
1920                 event_beep = state_fio->FgetInt32_BE();
1921                 event_beep_oneshot = state_fio->FgetInt32_BE();
1922                 event_timerirq = state_fio->FgetInt32_BE();
1923         }
1924         // V2
1925         if(version >= 3) { // V3
1926                 event_fdc_motor = state_fio->FgetInt32_BE();
1927 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
1928     defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1929                 for(ch = 0; ch < 4; ch++) fdc_drive_table[ch] = state_fio->FgetUint8();
1930                 fdc_reg_fd1e = state_fio->FgetUint8();
1931 #endif  
1932 #if defined(HAS_DMA)
1933                 intstat_dma = state_fio->FgetBool();
1934                 dma_addr = (uint32_t)(state_fio->FgetUint8() & 0x1f);
1935 #endif                  
1936 #if defined(_FM77AV_VARIANTS)
1937                 reg_fd12 = state_fio->FgetUint8();
1938 #endif          
1939         }
1940         if(version != STATE_VERSION) return false;
1941         return true;
1942 }
1943