OSDN Git Service

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