OSDN Git Service

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