OSDN Git Service

[VM][FM7] Passed compilation excepts keyboard.cpp.
[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
12 #include "fm7_mainio.h"
13
14
15 void FM7_MAINIO::initialize(void)
16 {
17 #if defined(_FM8)
18         clock_fast = false;
19 #else
20         clock_fast = true;
21 #endif
22    
23 }
24
25 void FM7_MAINIO::set_clockmode(uint8 flags)
26 {
27         if(flags == FM7_MAINCLOCK_SLOW) {
28                 clock_fast = false;
29         } else {
30                 clock_fast = true;
31         }
32 }
33
34 uint8 FM7_MAINIO::get_clockmode(void)
35 {
36         if(clock_fast) return FM7_MAINCLOCK_SLOW;
37         return FM7_MAINCLOCK_HIGH;
38 }
39
40
41 uint8 FM7_MAINIO::get_port_fd00(void)
42 {
43         uint8 ret = 0;
44         if(kbd_bit8) ret |= 0x80;
45         if(clock_fast) ret |= 0x01;
46         return ret;
47 }
48   
49 void FM7_MAINIO::set_port_fd00(uint8 data)
50 {
51        drec->write_signal(SIG_DATAREC_OUT, data, 0x01);
52        drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
53 }
54    
55 uint8 FM7_MAINIO::get_port_fd02(void)
56 {
57         uint8 ret;
58         // Still unimplemented printer.
59         ret = (cmt_indat) ? 0x80 : 0x00; // CMT 
60         return ret;
61 }
62
63 void FM7_MAINIO::set_port_fd02(uint8 val)
64 {
65         irqmask_reg0 = val;
66         if((val & 0b00010000) != 0) {
67                 irqmask_mfd = false;
68         } else {
69                 irqmask_mfd = true;
70         }
71         if((val & 0b00000100) != 0) {
72                 irqmask_timer = false;
73         } else {
74                 irqmask_timer = true;
75         }
76         if((val & 0b00000010) != 0) {
77                 irqmask_printer = false;
78         } else {
79                 irqmask_printer = true;
80         }
81         if((val & 0b00000001) != 0) {
82                 irqmask_keyboard = false;
83         } else {
84                 irqmask_keyboard = true;
85         }
86         return;
87 }
88
89
90 uint32 FM7_MAINIO::get_keyboard(void)
91 {
92         uint32 kbd_data = (uint32) kbd_bit7_0;
93         kbd_data &= 0x0ff;
94         if(kbd_bit8) kbd_data |= 0x0100;
95         return kbd_data;
96 }
97
98 void FM7_MAINIO::do_irq(bool flag)
99 {
100         if(flag) {
101                 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
102         } else {
103                 maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
104         }
105 }
106
107
108 void FM7_MAINIO::set_beep(uint32 data) // fd03
109 {
110         beep->write_signal(SIG_BEEP_ON, data, 0b11000000);
111         beep->write_signal(SIG_BEEP_MUTE, data , 0b00000001);
112         if((data & 0x40) != 0) {
113                 // BEEP ON, after 205ms, BEEP OFF.  
114                 register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
115         }
116 }
117
118 void FM7_MAINIO::set_irq_timer(bool flag)
119 {
120         if(flag && !irqmask_timer) {
121                 irqstat_reg0 &= 0b11111011;
122                 do_irq(true);
123                 return;
124         }
125         //
126         if(flag == false) {
127                 irqstat_reg0 |= 0b00000100;
128         }
129         do_irq(false);
130 }
131
132 void FM7_MAINIO::set_irq_printer(bool flag)
133 {
134         if(flag && !irqmask_printer) {
135                 irqstat_reg0 &= 0b11111101;
136                 do_irq(true);
137                 return;
138         }
139         if(flag == false) {
140                 irqstat_reg0 |= 0b00000010;
141         }
142         do_irq(false);
143 }
144
145 void FM7_MAINIO::set_irq_keyboard(bool flag)
146 {
147         if(flag && !irqmask_keyboard) {
148                 irqstat_reg0 &= 0b11111110;
149                 do_irq(true);
150                 return;
151         }
152         if(flag == false) {
153                 irqstat_reg0 |= 0b00000001;
154         }
155         do_irq(false);
156 }
157
158 void FM7_MAINIO::set_irq_mfd(bool flag)
159 {
160         fdc_irq = flag;
161         if(flag && !irqmask_mfd && connect_fdc) {
162                 irqstat_fdc |= 0b01000000;
163                 do_irq(true);
164                 return;
165         }
166         if((flag == false) && connect_fdc){
167                 irqstat_fdc &= 0b10111111;
168         }
169         return;
170 }
171
172
173  void FM7_MAINIO::set_keyboard(uint32 data)
174 {
175         if((data & 0x100) != 0){
176                 kbd_bit8 = true;
177         } else {
178                 kbd_bit8 = false;
179         }
180         kbd_bit7_0 = (data & 0xff);
181 }
182
183 void FM7_MAINIO::do_firq(bool flag)
184 {
185         if(flag) {
186                 maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
187         } else {
188                 maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
189         }      
190 }
191
192 void FM7_MAINIO::set_break_key(bool pressed)
193 {
194         firq_break_key = pressed;
195         do_firq(pressed);
196 }
197 void FM7_MAINIO::set_sub_attention(bool flag)
198 {
199         firq_sub_attention = flag;
200         do_firq(flag); 
201 }
202   
203
204 uint8 FM7_MAINIO::get_fd04(void)
205 {
206         uint8 val = 0b11111100;
207         if(!firq_break_key)     val |= 0b00000010;
208         if(!firq_sub_attention) val |= 0b00000001;
209         return val;
210 }
211
212 void FM7_MAINIO::set_fd04(uint8 val)
213 {
214         // NOOP?
215 }
216
217   // FD05
218  uint8 FM7_MAINIO::get_fd05(void)
219 {
220         uint8 val = 0b01111110;
221         if(sub_busy)    val |= 0b10000000;
222         if(!extdet_neg) val |= 0b00000001;
223 }
224
225  void FM7_MAINIO::set_fd05(uint8 val)
226 {
227         display->write_signal(SIG_FM7_SUB_HALT, val, 0b10000000);
228         display->write_signal(SIG_FM7_SUB_CANCEL, val, 0b01000000);
229         if((val & 0b10000000) == 0) {
230                 sub_haltreq = false;
231         } else {
232                 sub_haltreq = true;
233         }
234         if((val & 0b00000001) != 0) {
235                 maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
236                 //z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
237         } else {
238                 maincpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
239                 //z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
240         }
241 }
242
243
244
245 void FM7_MAINIO::set_extdet(bool flag)
246 {
247         extdet_neg = flag;
248 }
249
250 void FM7_MAINIO::set_psg(uint8 val)
251 {
252         if(psg == NULL) return set_opn(val, 0); // 77AV ETC
253         switch(psg_cmdreg & 0x03){
254                 case 0: // High inpedance
255                         return;
256                         break;
257                 case 1: // Read Data
258                         //psg_data = psg->read_io8(1);
259                         break;
260                 case 2: // Write Data
261                         psg->write_io8(1, val & 0x00ff);
262                         psg->write_signal(SIG_YM2203_MUTE, 0x01, 0x01); // Okay?
263                         break;
264                 case 3: // Register address
265                         psg_address = val & 0x0f;
266                         psg->write_io8(0, psg_address);
267                         break;
268         }
269 }
270
271 uint8 FM7_MAINIO::get_psg(void)
272 {
273         uint8 val = 0xff;
274         if(psg == NULL) return get_opn(0); // 77AV ETC
275         switch(psg_cmdreg & 0x03) {
276                 case 0:
277                         val = 0xff;
278                         break;
279                 case 1:
280                         val = psg->read_io8(1);
281                         psg_data = val & 0x00ff;
282                         break;
283                 case 2:
284                         val = 0xff; // Write conflict
285                         break;
286                 case 3:
287                         val = psg->read_io8(1);
288                         psg_address = val;
289                         break;
290         }
291         return val;
292 }
293
294 /*
295  * $fd0d : After 77AV, this is OPN.
296  */
297 void FM7_MAINIO::set_psg_cmd(uint32 cmd)
298 {
299         if(opn_psg_77av) {
300                 set_opn_cmd(cmd);
301                 return;
302         }
303         psg_cmdreg = (uint8)(cmd & 0b00000011);
304         return;
305 }
306
307 uint8 FM7_MAINIO::get_psg_cmd(void)
308 {
309         if(opn_psg_77av) return get_opn_cmd(); 
310         return ((psg_cmdreg & 0b00000011) | 0b11111100);
311 }
312
313
314
315 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
316 void FM7_MAINIO::write_kanjiaddr_hi(uint8 addr)
317 {
318         if(!connect_kanjiroml1) return;
319         kaddress_hi = addr;
320         return;
321 }
322
323 void FM7_MAINIO::write_kanjiaddr_lo(uint8 addr)
324 {
325         if(!connect_kanjiroml1) return;
326         kaddress_lo = addr;
327         return;
328 }
329
330 uint8 FM7_MAINIO::read_kanjidata_left(void)
331 {
332         uint32 addr;
333     
334         if(!connect_kanjiroml1) return 0xff;
335         addr = ((kaddress_hi & 0xff) * 256) + (kaddress_lo * 0xff);
336         addr = addr * 2;
337         if(kanjiclass1) {
338                 return kanjiclass1->read_data8(addr);
339         } else {
340                 return 0xff;
341         }
342 }
343
344 uint8 FM7_MAINIO::read_kanjidata_right(void)
345 {
346         uint32 addr;
347     
348         if(!connect_kanjiroml1) return 0xff;
349         addr = ((kaddress_hi & 0xff) * 256) + (kaddress_lo * 0xff);
350         addr = addr * 2 + 1;
351         if(kanjiclass1) {
352                 return kanjiclass1->read_data8(addr);
353         } else {
354                 return 0xff;
355         }
356 }
357
358 #ifdef _FM77AV_VARIANTS
359 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
360 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8 addr)
361 {
362         if(!connect_kanjiroml2) return;
363         kaddress_hi_l2 = addr;
364         return;
365 }
366
367 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8 addr)
368 {
369         if(!connect_kanjiroml2) return;
370         kaddress_lo_l2 = addr;
371         return;
372 }
373
374 uint8 FM7_MAINIO::read_kanjidata_left_l2(void)
375 {
376         uint32 addr;
377     
378         if(!connect_kanjiroml2) return 0xff;
379         addr = ((kaddress_hi_l2 & 0xff) * 256) + (kaddress_lo_l2 * 0xff);
380         addr = addr * 2;
381         if(kanjiclass2) {
382                 return kanjiclass2->read_data8(addr);
383         } else {
384                 return 0xff;
385         }
386 }
387
388 uint8 FM7_MAINIO::read_kanjidata_right_l2(void)
389 {
390         uint32 addr;
391     
392         if(!connect_kanjiroml2) return 0xff;
393         addr = ((kaddress_hi_l2 & 0xff) * 256) + (kaddress_lo_l2 * 0xff);
394         addr = addr * 2 + 1;
395         if(kanjiclass2) {
396                 return kanjiclass2->read_data8(addr);
397         } else {
398                 return 0xff;
399         }
400 }
401 #endif
402 // OPN
403 // Write to FD16, same as 
404 void FM7_MAINIO::set_opn(uint8 val, int index)
405 {
406         switch(index) {
407                 case 0: // OPN
408                         if(!connect_opn) return;
409                         break;
410                 case 1: // WHG
411                         if(!connect_whg) return;
412                         break;
413                 case 2: // THG
414                         if(!connect_thg) return;
415                         break;
416                 default:
417                         return;
418                         break;
419         }
420         if((opn_cmdreg[index] & 0b00001000) != 0) {
421                 // Read Joystick
422                 return;
423         }
424         if((opn_cmdreg[index] & 0b00000100) != 0) {
425                 // Read Status
426                 return;
427         }
428         switch(opn_cmdreg[index] & 0x03){
429                 case 0: // High inpedance
430                         return;
431                         break;
432                 case 1: // Read Data
433                         //psg_data = psg->read_io8(1);
434                         break;
435                 case 2: // Write Data
436                         opn_data[index] = val & 0x00ff;
437                         opn[index]->write_io8(1, val & 0x00ff);
438                         opn[index]->write_signal(SIG_YM2203_MUTE, 0x01, 0x01); // Okay?
439                         break;
440                 case 3: // Register address
441                         opn_address[index] = val & 0x0f;
442                         opn[index]->write_io8(0, psg_address);
443                         break;
444         }
445 }
446
447  uint8 FM7_MAINIO::get_opn(int index)
448 {
449         uint8 val = 0xff;
450         switch(index) {
451                 case 0: // OPN
452                         if(!connect_opn) return val;
453                         break;
454                 case 1: // WHG
455                         if(!connect_whg) return val;
456                         break;
457                 case 2: // THG
458                         if(!connect_thg) return val;
459                         break;
460                 default:
461                         return val;
462                         break;
463         }
464         if((opn_cmdreg[index] & 0b00001000) != 0) {
465                 // Read Joystick
466                 val = opn[index]->read_io8(1); // opn->joystick?
467                 opn_data[index] = val & 0x00ff;
468                 return val;
469         }
470         if((opn_cmdreg[index] & 0b00000100) != 0) {
471                 // Read Status
472                 val = opn[index]->read_io8(0);
473                 opn_stat[index] = val & 0x00ff;
474                 return val;
475         }
476         switch(opn_cmdreg[index] & 0x03) {
477                 case 0:
478                         val = 0xff;
479                         break;
480                 case 1:
481                         val = opn[index]->read_io8(1);
482                         opn_data[index] = val & 0x00ff;
483                         break;
484                 case 2:
485                         val = 0xff; // Write conflict
486                         break;
487                 case 3:
488                         val = opn[index]->read_io8(1);
489                         opn_address[index] = val;
490                         break;
491         }
492         return val;
493 }
494   /*
495    * $fd16?
496    */
497 void FM7_MAINIO::set_opn_cmd(uint32 cmd)
498 {
499         if(!connect_opn) return;
500         opn_cmdreg[0] = (uint8)(cmd & 0b00001111);
501         return;
502 }
503
504 uint8 FM7_MAINIO::get_opn_cmd(void)
505 {
506         if(!connect_opn) return 0xff;
507         return ((opn_cmdreg[0] & 0b00001111) | 0b11110000);
508 }
509
510
511 void FM7_MAINIO::write_signal(int id, uint32 data, uint32 mask)
512 {
513         bool val_b;
514         val_b = ((data & mask) != 0);
515   
516         switch(id) {
517                 case FM7_MAINIO_CLOCKMODE: // fd00
518                         if(val_b) {
519                                 clock_fast = true;
520                         } else {
521                                 clock_fast = false;
522                         }
523                         {
524                                 uint32 clocks;
525                                 uint32 subclocks;
526 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
527                                 if(mmr_enabled) {
528                                         if(mmr_fast) {
529                                                 if(clock_fast) {
530                                                         clocks = 2016000; // Hz
531                                                 } else {
532                                                         clocks = 1230502; // (2016 * 1095 / 1794)[KHz]
533                                                 }
534                                         } else {
535                                                 if(clock_fast) {
536                                                         clocks = 1565000; // Hz
537                                                 } else {
538                                                         clocks =  955226; // (1565 * 1095 / 1794)[KHz]
539                                                 }
540                                         }
541                                 } else {
542                                         if(clock_fast) {
543                                                 clocks = 1794000; // Hz 
544                                         } else {
545                                                 clocks = 1095000; // Hz
546                                         }
547                                 }
548 #else // 7/8
549                                 if(clock_fast) {
550                                         clocks = 1794000; // Hz 
551                                 } else {
552                                         clocks = 1095000; // Hz
553                                 }
554 #endif
555                                 if(clock_fast) {
556                                         subclocks = 2000000; // Hz
557                                 } else {
558                                         subclocks =  999000; // Hz
559                                 }
560                                 p_vm->set_cpu_clock(this->maincpu, clocks);
561                                 p_vm->set_cpu_clock(this->subcpu,  subclocks);
562                         }
563                         break;
564                 case FM7_MAINIO_CMT_RECV: // FD02
565                         cmt_indat = val_b ^ cmt_invert;
566                         break;
567                 case FM7_MAINIO_CMT_INVERT: // FD02
568                         cmt_invert = val_b;
569                         break;
570                 case FM7_MAINIO_TIMERIRQ: //
571                         set_irq_timer(val_b);
572                         break;
573                 case FM7_MAINIO_LPTIRQ: //
574                         set_irq_printer(val_b);
575                         break;
576                 case FM7_MAINIO_KEYBOARDIRQ: //
577                         set_irq_keyboard(val_b);
578                         break;
579                 case FM7_MAINIO_PUSH_KEYBOARD:
580                         set_keyboard(data & 0x1ff);
581                         break;
582                         // FD04
583                 case FM7_MAINIO_PUSH_BREAK:
584                         set_break_key(val_b);
585                         break;
586                 case FM7_MAINIO_SUB_ATTENTION:
587                         set_sub_attention(val_b);
588                         break;
589                         // FD05
590                 case FM7_MAINIO_SUB_BUSY:
591                         sub_busy = val_b;
592                         break;
593                 case FM7_MAINIO_EXTDET:
594                         extdet_neg = !val_b;
595                         break;
596                 case FM7_MAINIO_BEEP:
597                         beep->write_signal(SIG_BEEP_ON, data, mask);
598                         register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
599                         break;
600                 case FM7_MAINIO_OPNPORTA_CHANGED:
601                         opnport_a = data & mask;
602                         break;
603                 case FM7_MAINIO_OPNPORTB_CHANGED:
604                         opnport_a = data & mask;
605                         break;
606                 case FM7_MAINIO_PSG_IRQ:
607                         break;
608                 case FM7_MAINIO_OPN_IRQ:
609                         intstat_opn = val_b;
610                         do_irq(val_b);
611                         break;
612                 case FM7_MAINIO_WHG_IRQ:
613                         intstat_whg = val_b;
614                         do_irq(val_b);
615                         break;
616                 case FM7_MAINIO_THG_IRQ:
617                         intstat_thg = val_b;
618                         do_irq(val_b);
619                         break;
620                 case FM7_MAINIO_FDC_DRQ:
621                         fdc_drq = val_b;
622                         if(fdc_drq) {
623                                 irqstat_fdc |= 0b10000000;
624                         } else {
625                                 irqstat_fdc &= 0b01111111;
626                         }
627                         set_irq_mfd(val_b);
628                         break;
629                 case FM7_MAINIO_FDC_IRQ:
630                         fdc_irq = val_b;
631                         if(val_b) {
632                                 irqstat_fdc |= 0b01000000;
633                         } else {
634                                 irqstat_fdc &= 0b10111111;
635                         }
636                         set_irq_mfd(val_b);
637                         break;
638         }
639         
640 }
641
642
643 uint8 FM7_MAINIO::fdc_getdrqirq(void)
644 {
645         return irqstat_fdc;
646 }
647
648  uint8 FM7_MAINIO::get_irqstat_fd03(void)
649 {
650         uint8 val = 0b11111000;
651         bool extirq = false;
652         
653         extirq = intstat_opn | intstat_mouse | fdc_irq;
654         extirq = extirq | intstat_thg | intstat_whg;
655         //extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
656         if(extirq) val &= 0b11110111;
657         val &= irqstat_reg0;
658         return val;
659 }
660
661 uint8 FM7_MAINIO::get_extirq_fd17(void)
662 {
663         uint8 val = 0xff;
664         if(intstat_opn)   val &= 0b11110111;
665         if(intstat_mouse) val &= 0b11111011;
666         return val;
667 }
668
669 void FM7_MAINIO::set_ext_fd17(uint8 data)
670 {
671         if((data & 0b00000100) != 0) {
672                 mouse_enable = true;
673         } else {
674                 mouse_enable = false;
675         }
676    
677 }
678
679 /* FDD */
680
681 void FM7_MAINIO::set_fdc_stat(uint8 val)
682 {
683         if(fdc == NULL) return;
684         fdc_statreg = val;
685         fdc->write_io8(0, val & 0x00ff);
686 }
687
688 uint8 FM7_MAINIO::get_fdc_stat(void)
689 {
690         if(fdc == NULL) return 0xff;
691         this->write_signal(FM7_MAINIO_FDC_IRQ, 0, 1);
692         fdc_statreg =  fdc->read_io8(0);
693         return fdc_statreg;
694 }
695
696 void FM7_MAINIO::set_fdc_track(uint8 val)
697 {
698         if(fdc == NULL) return;
699         // if mode is 2DD and type-of-image = 2D then val >>= 1;
700         fdc_trackreg = val;
701         fdc->write_io8(1, val & 0x00ff);
702 }
703
704 uint8 FM7_MAINIO::get_fdc_track(void)
705 {
706         if(fdc == NULL) return 0xff;
707         fdc_trackreg = fdc->read_io8(1);
708         return fdc_trackreg;
709 }
710
711 void FM7_MAINIO::set_fdc_sector(uint8 val)
712 {
713         if(fdc == NULL) return;
714         fdc_sectreg = val;
715         fdc->write_io8(2, val & 0x00ff);
716 }
717
718 uint8 FM7_MAINIO::get_fdc_sector(void)
719 {
720         if(fdc == NULL) return 0xff;
721         fdc_sectreg = fdc->read_io8(2);
722         return fdc_sectreg;
723 }
724   
725 void FM7_MAINIO::set_fdc_data(uint8 val)
726 {
727         if(!connect_fdc) return;
728         fdc_datareg = val;
729         fdc->write_io8(3, val & 0x00ff);
730 }
731
732 uint8 FM7_MAINIO::get_fdc_data(void)
733 {
734         if(!connect_fdc) return 0xff;
735         fdc_datareg = fdc->read_io8(3);
736         return fdc_datareg;
737 }
738
739 uint8 FM7_MAINIO::get_fdc_motor(void)
740 {
741         uint8 val = 0x00;
742         if(fdc == NULL) return 0xff;
743         if(fdc_motor) val = 0x80;
744         val = val | (fdc_drvsel & 0x03);
745         return val;
746 }
747   
748 void FM7_MAINIO::set_fdc_fd1c(uint8 val)
749 {
750         if(fdc == NULL) return;
751         fdc_headreg = (val & 0x01) | 0xfe;
752         fdc->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
753 }
754
755 uint8 FM7_MAINIO::get_fdc_fd1c(void)
756 {
757         if(fdc == NULL) return 0xff;
758         return fdc_headreg;
759 }
760
761 void FM7_MAINIO::set_fdc_fd1d(uint8 val)
762 {
763         if(fdc == NULL) return;
764         if((val & 0x80) != 0) {
765                 fdc_motor = true;
766         } else {
767                 fdc_motor = false;
768         }
769         fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x07);
770         fdc->write_signal(SIG_MB8877_MOTOR, val, 0x80);
771         fdc_drvsel = val;
772 }
773    
774 uint32 FM7_MAINIO::read_signal(uint32 addr)
775 {
776         uint32 retval = 0xffffffff;
777         switch(addr) {
778         }
779         return retval;
780 }
781
782 uint32 FM7_MAINIO::read_data8(uint32 addr)
783 {
784         if(addr == FM7_MAINIO_IS_BASICROM) {
785                 uint32 retval = 0;
786                 if(stat_bootsw_basic) retval = 0xffffffff;
787                 return retval;
788         } else if(addr == FM7_MAINIO_BOOTMODE) {
789                 uint32 retval = bootmode & 0x03;
790 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
791                 if(bootram) retval = 4;
792 #endif
793                 return retval;
794         } else if(addr == FM7_MAINIO_READ_FD0F) {
795                 if(stat_romrammode) return 0xffffffff;
796                 return 0;
797         } else if(addr == FM7_MAINIO_CLOCKMODE) {
798                 return (uint32)get_clockmode();
799         }
800 #if defined(HAS_MMR)    
801         else if(addr == FM7_MAINIO_MMR_ENABLED) {
802                 uint32 retval = (mmr_enabled) ? 0xffffffff:0x00000000;
803                 return retval;
804         } else if(addr == FM7_MAINIO_WINDOW_ENABLED) {
805                 uint32 retval = (window_enabled) ? 0xffffffff:0x00000000;
806                 return retval;
807         } else if(addr == FM7_MAINIO_MMR_SEGMENT) {
808                 uint32 retval = (uint32) mmr_segment;
809                 return retval;
810         } else if((addr >= FM7_MAINIO_MMR_BANK) &&  (addr < (FM7_MAINIO_MMR_BANK + 64))) {
811                 uint32 retval = (uint32)mmr_table[addr - FM7_MAINIO_MMR_BANK];
812                 return retval;
813         }
814 #endif
815 #if defined(_FM77AV_VARIANTS)
816         else if(addr == FM7_MAINIO_INITROM_ENABLED) {
817         }
818 #endif
819 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
820         else if(addr == FM7_MAINIO_EXTBANK) {
821         } else if(addr == FM7_MAINIO_EXTROM) {
822         }
823 #endif
824         //addr = addr & 0xff; //
825         switch(addr) {
826                 case 0x00: // FD00
827                 case 0x100: // D400 (SUB)
828                         return (uint32) get_port_fd00();
829                         break;
830                 case 0x01: // FD01
831                 case 0x101: // D401
832                         return (uint32) kbd_bit7_0;
833                         break;
834                 case 0x02: // FD02
835                         return (uint32) get_port_fd02();
836                         break;
837                 case 0x03: // FD03
838                         return (uint32) get_irqstat_fd03();
839                         break;
840                 case 0x04: // FD04
841                         return (uint32) get_fd04();
842                         break;
843                 case 0x05: // FD05
844                         return (uint32) get_fd05();
845                         break;
846                 case 0x06: // RS-232C
847                 case 0x07:
848                         return 0xff;
849                         break;
850                 case 0x08: // Light pen
851                 case 0x09:
852                 case 0x0a:
853                         return 0xff;
854                         break;
855                 case 0x0d:
856                         return (uint32) get_psg_cmd();
857                         break;
858                 case 0x0e:
859                         return (uint32) get_psg();
860                         break;
861                 case 0x0f: // FD0F
862                         read_fd0f();
863                         return 0x00ff;
864                         break;
865                 case 0x15: // OPN CMD
866                         return (uint32) get_opn_cmd();
867                         break;
868                 case 0x16: // OPN DATA
869                         return (uint32) get_opn(0);
870                         break;
871                 case 0x17:
872                         return (uint32) get_extirq_fd17();
873                         break;
874                 case 0x18: // FDC: STATUS
875                         return (uint32) get_fdc_stat();
876                         break;
877                 case 0x19: // FDC: Track
878                         return (uint32) get_fdc_track();
879                         break;
880                 case 0x1a: // FDC: Sector
881                         return (uint32) get_fdc_sector();
882                         break;
883                 case 0x1b: // FDC: Data
884                         return (uint32) get_fdc_data();
885                         break;
886                 case 0x1c:
887                         return (uint32) get_fdc_fd1c();
888                         break;
889                 case 0x1d:
890                         return (uint32) get_fdc_motor();
891                         break;
892                 case 0x1f:
893                         return (uint32) irqstat_fdc;
894                         break;
895                 case 0x22: // Kanji ROM
896                         return (uint32) read_kanjidata_left();
897                         break;
898                 case 0x23: // Kanji ROM
899                         return (uint32) read_kanjidata_right();
900                         break;
901 #if defined(_FM77AV_VARIANTS)
902                 case 0x2e: // Kanji ROM Level2
903                         return (uint32) read_kanjidata_left_l2();
904                         break;
905                 case 0x2f: // Kanji ROM Level2
906                         return (uint32) read_kanjidata_right_l2();
907                         break;
908 #endif
909                 case 0x37: // Multi page
910                         return (uint32)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
911                         break;
912                 default:
913                         break;
914         }
915         if((addr < 0x40) && (addr >= 0x38)) {
916                 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
917                 return (uint32) display->read_data8(addr);
918         }
919         // Another:
920         return 0xff;
921 }
922
923 void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
924 {
925         if(addr == FM7_MAINIO_BOOTMODE) {
926                 bootmode = data & 0x03;
927                 return;
928         } else if(addr == FM7_MAINIO_CLOCKMODE) {
929                 set_clockmode((uint8)data);
930                 return;
931         }
932         addr = addr & 0xff; //
933         data = data & 0xff;
934
935         switch(addr) {
936                 case 0x00: // FD00
937                         set_port_fd00((uint8)data);
938                         return;
939                         break;
940                 case 0x01: // FD01
941                         // set_lptdata_fd01((uint8)data);
942                         break;
943                 case 0x02: // FD02
944                         set_port_fd02((uint8)data);
945                         break;
946                 case 0x03: // FD03
947                         set_beep(data);
948                         break;
949                 case 0x04: // FD04
950
951                         // set_flags_fd04(data);
952                         break;
953                 case 0x05: // FD05
954                         set_fd05((uint8)data);
955                         break;
956                 case 0x06: // RS-232C
957                 case 0x07:
958                         break;
959                 case 0x08: // Light pen
960                 case 0x09:
961                 case 0x0a:
962                         break;
963                 case 0x0d:
964                         set_psg_cmd((uint8)data);
965                         break;
966                 case 0x0e:
967                         set_psg((uint8)data);
968                         break;
969                 case 0x0f: // FD0F
970                         write_fd0f();
971                         break;
972                 case 0x15: // OPN CMD
973                         set_opn_cmd((uint8)data);
974                         break;
975                 case 0x16: // OPN DATA
976                         set_opn(0, (uint8)data);
977                         break;
978                 case 0x17:
979                         set_ext_fd17((uint8)data);
980                         break;
981                 case 0x18: // FDC: STATUS
982                         set_fdc_stat((uint8)data);
983                         break;
984                 case 0x19: // FDC: Track
985                         set_fdc_track((uint8)data);
986                         break;
987                 case 0x1a: // FDC: Sector
988                         set_fdc_sector((uint8)data);
989                         break;
990                 case 0x1b: // FDC: Data
991                         set_fdc_data((uint8)data);
992                         break;
993                 case 0x1c:
994                         set_fdc_fd1c((uint8)data);
995                         break;
996                 case 0x1d:
997                         set_fdc_fd1d((uint8)data);
998                         break;
999                 case 0x1f: // ??
1000                         return;
1001                         break;
1002                 case 0x20: // Kanji ROM
1003                         write_kanjiaddr_hi((uint8)data);
1004                         break;
1005                 case 0x21: // Kanji ROM
1006                         write_kanjiaddr_lo((uint8)data);
1007                         break;
1008 #if defined(_FM77AV_VARIANTS)
1009                 case 0x2c: // Kanji ROM
1010                         write_kanjiaddr_hi_l2((uint8)data);
1011                         break;
1012                 case 0x2d: // Kanji ROM
1013                         write_kanjiaddr_lo_l2((uint8)data);
1014                         break;
1015 #endif
1016                 case 0x37: // Multi page
1017                         display->write_signal(SIG_FM7_SUB_MULTIPAGE, data, 0x00ff);
1018                         break;
1019 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
1020                 case 0x93:
1021                         if((data & 0x01) == 0) {
1022                                 boot_ram = false;
1023                         } else {
1024                                 boot_ram = true;
1025                         }         
1026                         if((data & 0x40) == 0) {
1027                                 window_enabled = false;
1028                         } else {
1029                                 window_enabled = true;
1030                         }         
1031                         if((data & 0x80) == 0) {
1032                                 mmr_enabled = false;
1033                         } else {
1034                                 mmr_enabled = true;
1035                         }
1036                         break;
1037 #endif
1038                 default:
1039                         break;
1040         }
1041         if((addr < 0x40) && (addr >= 0x38)) {
1042                 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1043                 display->write_data8(addr, (uint8)data);
1044                 return;
1045         }       // Another:
1046         return;
1047 }
1048
1049 void FM7_MAINIO::event_callback(int event_id, int err)
1050 {
1051         switch(event_id) {
1052                 case EVENT_BEEP_OFF:
1053                         beep->write_signal(SIG_BEEP_ON, 0x00, 0x01);
1054                         break;
1055                 default:
1056                         break;
1057         }
1058 }
1059
1060