OSDN Git Service

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