OSDN Git Service

[VM][FM77AV][MB61VH010] Fix line putting.
[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_mainio.h"
12
13 #include "../mc6809.h"
14 #include "../z80.h"
15
16 #include "../datarec.h"
17
18 // TEST
19 //#include <SDL2/SDL.h>
20
21 void FM7_MAINIO::initialize(void)
22 {
23         int i;
24         event_beep = -1;
25         event_timerirq = -1;
26         bootmode = config.boot_mode & 3;
27 #if defined(_FM77AV_VARIANTS)
28         opn_psg_77av = true;
29 #else
30         //opn_psg_77av = true;
31         opn_psg_77av = false;
32 #endif
33 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
34         boot_ram = false;
35 #endif 
36 #if defined(_FM77AV_VARIANTS)
37         enable_initiator = true;
38 #endif
39 #ifdef HAS_MMR
40         mmr_enabled = false;
41         mmr_fast = false;
42         window_enabled = false;
43         mmr_segment = 0x00;
44         for(i = 0x00; i < 0x80; i++) mmr_table[i] = 0;
45         //      for(i = 0x00; i < 0x10; i++) mmr_table[i] = 0x30 + i;
46 #endif  
47 }
48
49 void FM7_MAINIO::reset(void)
50 {
51         int i, j;
52         uint8 data;
53         //if(event_beep >= 0) cancel_event(this, event_beep);
54         if(event_timerirq >= 0) cancel_event(this, event_timerirq);
55         event_beep = -1;
56         beep_snd = true;
57         beep_flag = false;
58         extdet_neg = false;
59    
60         stat_romrammode = true;
61         bootmode = config.boot_mode & 3;
62         if(bootmode == 0) { // IF BASIC BOOT THEN ROM
63                 stat_romrammode = true;
64         } else { // ELSE RAM
65                 stat_romrammode = false;
66         }
67 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
68         boot_ram = false;
69         kaddress.d = 0;
70 #endif 
71 #if defined(_FM77AV_VARIANTS)
72         mode320 = false;
73         sub_monitor_type = 0x00;
74 #endif
75         
76 #ifdef HAS_MMR
77         mmr_enabled = false;
78         mmr_fast = false;
79         window_enabled = false;
80 #endif
81         clock_fast = false;
82         if(config.cpu_type == 0) clock_fast = true;
83    
84         reset_sound();
85         
86         irqmask_reg0 = 0x00;
87         irqstat_bak = false;
88         firqstat_bak = false;
89         // FD03
90         irqmask_mfd = true;
91         irqmask_timer = true;
92         irqmask_printer = true;
93         irqmask_keyboard = true;
94         irqstat_reg0 = 0xff;
95         irqstat_timer = false;
96         irqstat_printer = false;
97         irqstat_keyboard = false;
98    
99         // FD04
100         //firq_break_key = false; // bit1, ON = '0'.
101         firq_sub_attention = false; // bit0, ON = '0'.
102         // FD05
103         extdet_neg = false;
104         sub_cancel = false; // bit6 : '1' Cancel req.
105
106         nmi_count = 0;
107         reset_fdc();
108    
109         register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
110         mainmem->reset();
111         //maincpu->reset();
112 }
113
114
115 void FM7_MAINIO::set_clockmode(uint8 flags)
116 {
117         if(flags == FM7_MAINCLOCK_SLOW) {
118                 clock_fast = false;
119         } else {
120                 clock_fast = true;
121         }
122 }
123
124 uint8 FM7_MAINIO::get_clockmode(void)
125 {
126         if(!clock_fast) return FM7_MAINCLOCK_SLOW;
127         return FM7_MAINCLOCK_HIGH;
128 }
129
130
131 uint8 FM7_MAINIO::get_port_fd00(void)
132 {
133         uint8 ret           = 0x7e; //0b01111110;
134         if(kbd_bit8)   ret |= 0x80; //0b10000000;
135         if(clock_fast) ret |= 0x01; //0b00000001;
136         return ret;
137 }
138   
139 void FM7_MAINIO::set_port_fd00(uint8 data)
140 {
141        drec->write_signal(SIG_DATAREC_OUT, data, 0x01);
142        drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
143 }
144    
145 uint8 FM7_MAINIO::get_port_fd02(void)
146 {
147         uint8 ret;
148         // Still unimplemented printer.
149         ret = (cmt_indat) ? 0xff : 0x7f; // CMT 
150         return ret;
151 }
152
153 void FM7_MAINIO::set_port_fd02(uint8 val)
154 {
155         irqmask_reg0 = val;
156         bool keyirq_bak = irqmask_keyboard;
157         bool timerirq_bak = irqmask_timer;
158         bool printerirq_bak = irqmask_printer;
159         bool mfdirq_bak = irqmask_mfd;
160         bool flag;
161         //      if((val & 0b00010000) != 0) {
162         if((val & 0x10) != 0) {
163         irqmask_mfd = false;
164         } else {
165                 irqmask_mfd = true;
166         }
167         if(mfdirq_bak != irqmask_mfd) {
168                 flag = irqstat_fdc;
169                 set_irq_mfd(flag);
170         }
171         //if((val & 0b00000100) != 0) {
172         if((val & 0x04) != 0) {
173                 irqmask_timer = false;
174         } else {
175                 irqmask_timer = true;
176         }
177         if(timerirq_bak != irqmask_timer) {
178                 flag = irqstat_timer;
179                 set_irq_timer(flag);
180         }
181         //if((val & 0b00000010) != 0) {
182         if((val & 0x02) != 0) {
183                 irqmask_printer = false;
184         } else {
185                 irqmask_printer = true;
186         }
187         if(printerirq_bak != irqmask_printer) {
188                 flag = irqstat_printer;
189                 set_irq_printer(flag);
190         }
191    
192         //if((val & 0b00000001) != 0) {
193         if((val & 0x01) != 0) {
194                 irqmask_keyboard = false;
195         } else {
196                 irqmask_keyboard = true;
197         }
198         if(keyirq_bak != irqmask_keyboard) {
199                 flag = irqstat_keyboard;
200                 flag = flag & !irqmask_keyboard;
201                 display->write_signal(SIG_FM7_SUB_KEY_FIRQ, flag ? 1 : 0, 1);
202                 //printf("KEYBOARD: Interrupted %d\n", flag);
203                 irqmask_keyboard = flag;
204                 do_irq(flag);
205         }
206    
207         return;
208 }
209
210
211 uint32 FM7_MAINIO::get_keyboard(void)
212 {
213         uint32 kbd_data = (uint32) kbd_bit7_0;
214         kbd_data &= 0x0ff;
215         if(kbd_bit8) kbd_data |= 0x0100;
216         return kbd_data;
217 }
218
219
220
221 void FM7_MAINIO::set_irq_timer(bool flag)
222 {
223         uint8 backup = irqstat_reg0;
224         if(flag && !(irqmask_timer)) {
225                 irqstat_reg0 &= ~0x04;
226                 irqstat_timer = true;      
227                 if(backup != irqstat_reg0) do_irq(true);
228         } else {
229                 irqstat_reg0 |= 0x04;
230                 irqstat_timer = false;     
231                 if(backup != irqstat_reg0) do_irq(false);
232         }
233         //printf("IRQ TIMER: %02x MASK=%d\n", irqstat_reg0, irqmask_timer);
234 }
235
236 void FM7_MAINIO::set_irq_printer(bool flag)
237 {
238         uint8 backup = irqstat_reg0;
239         if(flag && !(irqmask_printer)) {
240                 irqstat_reg0 &= ~0x02;
241                 irqstat_printer = true;    
242                 if(backup != irqstat_reg0) do_irq(true);
243         } else {
244                 irqstat_reg0 |= 0x02;
245                 irqstat_printer = false;           
246                 if(backup != irqstat_reg0) do_irq(false);
247         }
248 //      if(!irqmask_printer || !flag) do_irq(flag);
249 }
250
251 void FM7_MAINIO::set_irq_keyboard(bool flag)
252 {
253         uint8 backup = irqstat_reg0;
254         if(irqmask_keyboard) return;
255         if(flag) {
256                 irqstat_reg0 &= ~0x01;
257                 irqstat_keyboard = true;
258                 if(backup != irqstat_reg0) do_irq(true);
259         } else {
260                 //irqstat_reg0 &= 0b11111110;
261                 irqstat_reg0 |= 0x01;
262                 irqstat_keyboard = false;          
263                 if(backup != irqstat_reg0) do_irq(false);
264         }
265         //printf("MAIN: KEYBOARD: IRQ=%d\n", flag && !(irqmask_keyboard));
266 }
267
268 void FM7_MAINIO::set_keyboard(uint32 data)
269 {
270         if((data & 0x100) != 0){
271                 kbd_bit8 = true;
272         } else {
273                 kbd_bit8 = false;
274         }
275         kbd_bit7_0 = (data & 0xff);
276 }
277
278
279 void FM7_MAINIO::do_irq(bool flag)
280 {
281         bool intstat;
282         intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
283         intstat = intstat | irqstat_fdc;
284         intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
285         intstat = intstat | intstat_mouse;
286    
287         if(irqstat_bak == intstat) return;
288         //printf("%08d : IRQ: REG0=%02x FDC=%02x, stat=%d\n", SDL_GetTicks(), irqstat_reg0, irqstat_fdc, intstat);
289         if(intstat) {
290                 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
291         } else {
292                 maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
293         }
294         irqstat_bak = intstat;
295 }
296
297 void FM7_MAINIO::do_firq(bool flag)
298 {
299         bool firq_stat;
300         firq_stat = firq_break_key || firq_sub_attention; 
301         //printf("%08d : FIRQ: break=%d attn=%d stat = %d\n", SDL_GetTicks(), firq_break_key, firq_sub_attention, firq_stat);
302         //if(firqstat_bak == firq_stat) return;
303         if(firq_stat) {
304                 maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
305         } else {
306                 maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
307         }
308         firqstat_bak = firq_stat;
309 }
310
311 void FM7_MAINIO::do_nmi(bool flag)
312 {
313         if(flag) {
314                 if(nmi_count >= 0x7ff0) {
315                         nmi_count = 0x7ff0;
316                         return;
317                 }
318                 nmi_count++;
319                 if(nmi_count <= 1) maincpu->write_signal(SIG_CPU_NMI, 1, 1);
320         } else {
321                 if(nmi_count <= 0) {
322                         nmi_count = 0;
323                         return;
324                 }
325                 nmi_count--;
326                 if(nmi_count == 0) maincpu->write_signal(SIG_CPU_NMI, 0, 1);
327         }
328 }
329
330
331 void FM7_MAINIO::set_break_key(bool pressed)
332 {
333         firq_break_key = pressed;
334         do_firq(pressed);
335 }
336
337 void FM7_MAINIO::set_sub_attention(bool flag)
338 {
339         firq_sub_attention = flag;
340         do_firq(flag); 
341 }
342   
343
344 uint8 FM7_MAINIO::get_fd04(void)
345 {
346         uint8 val = display->read_signal(SIG_DISPLAY_BUSY) | ~0x03;
347         if(!firq_break_key)     val |= 0x02;
348         if(!firq_sub_attention) {
349                 val |= 0x01;
350         } else {
351                 set_sub_attention(false);   
352         }
353         return val;
354 }
355
356 void FM7_MAINIO::set_fd04(uint8 val)
357 {
358         // NOOP?
359 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
360         display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
361 #endif
362 }
363
364   // FD05
365  uint8 FM7_MAINIO::get_fd05(void)
366 {
367         uint8 val = display->read_signal(SIG_DISPLAY_BUSY) | ~0x81;
368         if(!extdet_neg) val |= 0x01;
369         return val;
370 }
371
372  void FM7_MAINIO::set_fd05(uint8 val)
373 {
374         display->write_signal(SIG_FM7_SUB_CANCEL, val, 0x40); // HACK
375         display->write_signal(SIG_DISPLAY_HALT,   val, 0x80);
376 #ifdef WITH_Z80
377         if((val & 0x01) != 0) {
378                 //maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
379                 //z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
380         } else {
381                 //maincpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
382                 //z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
383         }
384 #endif
385 }
386
387 void FM7_MAINIO::set_extdet(bool flag)
388 {
389         extdet_neg = flag;
390 }
391
392 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
393 void FM7_MAINIO::write_kanjiaddr_hi(uint8 addr)
394 {
395         if(!connect_kanjiroml1) return;
396         kaddress.b.h = addr;
397         return;
398 }
399
400 void FM7_MAINIO::write_kanjiaddr_lo(uint8 addr)
401 {
402         if(!connect_kanjiroml1) return;
403         kaddress.b.l = addr;
404         return;
405 }
406
407 uint8 FM7_MAINIO::read_kanjidata_left(void)
408 {
409         uint32 addr;
410     
411         if(!connect_kanjiroml1) return 0xff;
412         addr = kaddress.w.l;
413         addr = addr << 1;
414         //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
415         if(kanjiclass1) {
416                 return kanjiclass1->read_data8(addr);
417         } else {
418                 return 0xff;
419         }
420 }
421
422 uint8 FM7_MAINIO::read_kanjidata_right(void)
423 {
424         uint32 addr;
425     
426         if(!connect_kanjiroml1) return 0xff;
427         addr = kaddress.w.l;
428         addr = (addr << 1) + 1;
429         if(kanjiclass1) {
430                 return kanjiclass1->read_data8(addr);
431         } else {
432                 return 0xff;
433         }
434 }
435
436 #ifdef CAPABLE_KANJICLASS2
437 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
438 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8 addr)
439 {
440         if(!connect_kanjiroml2) return;
441         kaddress_l2.b.h = addr;
442         return;
443 }
444
445 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8 addr)
446 {
447         if(!connect_kanjiroml2) return;
448         kaddress_l2.b.l = addr;
449         return;
450 }
451
452 uint8 FM7_MAINIO::read_kanjidata_left_l2(void)
453 {
454         uint32 addr;
455     
456         if(!connect_kanjiroml2) return 0xff;
457         addr = kaddress.w.l;
458         addr = addr << 1;
459         if(kanjiclass2) {
460                 return kanjiclass2->read_data8(addr);
461         } else {
462                 return 0xff;
463         }
464 }
465
466 uint8 FM7_MAINIO::read_kanjidata_right_l2(void)
467 {
468         uint32 addr;
469     
470         if(!connect_kanjiroml2) return 0xff;
471         addr = kaddress_l2.w.l;
472         addr = (addr << 1) + 0x01;
473         if(kanjiclass2) {
474                 return kanjiclass2->read_data8(addr);
475         } else {
476                 return 0xff;
477         }
478 }
479 #endif
480
481
482
483 void FM7_MAINIO::write_signal(int id, uint32 data, uint32 mask)
484 {
485         bool val_b;
486         val_b = ((data & mask) != 0);
487   
488         switch(id) {
489                 case FM7_MAINIO_CLOCKMODE: // fd00
490                         if(val_b) {
491                                 clock_fast = true;
492                         } else {
493                                 clock_fast = false;
494                         }
495                         {
496                                 uint32 clocks;
497                                 uint32 subclocks;
498 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
499                                 if(mmr_enabled) {
500                                         if(mmr_fast) {
501                                                 if(clock_fast) {
502                                                         clocks = 2016000; // Hz
503                                                 } else {
504                                                         clocks = 1230502; // (2016 * 1095 / 1794)[KHz]
505                                                 }
506                                         } else {
507                                                 if(clock_fast) {
508                                                         clocks = 1565000; // Hz
509                                                 } else {
510                                                         clocks =  955226; // (1565 * 1095 / 1794)[KHz]
511                                                 }
512                                         }
513                                 } else {
514                                         if(clock_fast) {
515                                                 clocks = 1794000; // Hz 
516                                         } else {
517                                                 clocks = 1095000; // Hz
518                                         }
519                                 }
520 #else // 7/8
521                                 if(clock_fast) {
522                                         clocks = 1794000; // Hz 
523                                 } else {
524                                         clocks = 1095000; // Hz
525                                 }
526 #endif
527                                 if(clock_fast) {
528                                         subclocks = 2000000; // Hz
529                                 } else {
530                                         subclocks =  999000; // Hz
531                                 }
532                                 p_vm->set_cpu_clock(this->maincpu, clocks);
533                                 p_vm->set_cpu_clock(this->subcpu,  subclocks);
534                         }
535                         break;
536                 case FM7_MAINIO_CMT_RECV: // FD02
537                         cmt_indat = val_b ^ cmt_invert;
538                         break;
539                 case FM7_MAINIO_CMT_INVERT: // FD02
540                         cmt_invert = val_b;
541                         break;
542                 case FM7_MAINIO_TIMERIRQ: //
543                         set_irq_timer(val_b);
544                         break;
545                 case FM7_MAINIO_LPTIRQ: //
546                         set_irq_printer(val_b);
547                         break;
548                 case FM7_MAINIO_KEYBOARDIRQ: //
549                         set_irq_keyboard(val_b);
550                         break;
551                 case FM7_MAINIO_PUSH_KEYBOARD:
552                         set_keyboard(data & 0x1ff);
553                         break;
554                         // FD04
555                 case FM7_MAINIO_PUSH_BREAK:
556                         set_break_key(val_b);
557                         break;
558                 case FM7_MAINIO_SUB_ATTENTION:
559                         set_sub_attention(val_b);
560                         break;
561                         // FD05
562                 case FM7_MAINIO_SUB_BUSY:
563                         break;
564                 case FM7_MAINIO_EXTDET:
565                         extdet_neg = !val_b;
566                         break;
567                 case FM7_MAINIO_BEEP:
568                         set_beep_oneshot();
569                         break;
570                 case FM7_MAINIO_JOYPORTA_CHANGED:
571                         joyport_a = data & mask;
572                         break;
573                 case FM7_MAINIO_JOYPORTB_CHANGED:
574                         joyport_b = data & mask;
575                         break;
576                 case FM7_MAINIO_PSG_IRQ:
577                         break;
578                 case FM7_MAINIO_OPN_IRQ:
579                         if(!connect_opn) break;
580                         intstat_opn = val_b;
581                         do_irq(val_b);
582                         break;
583                 case FM7_MAINIO_WHG_IRQ:
584                         if(!connect_whg) break;
585                         intstat_whg = val_b;
586                         do_irq(val_b);
587                         break;
588                 case FM7_MAINIO_THG_IRQ:
589                         if(!connect_thg) break;
590                         intstat_thg = val_b;
591                         do_irq(val_b);
592                         break;
593                 case FM7_MAINIO_FDC_DRQ:
594                         set_drq_mfd(val_b);
595                         break;
596                 case FM7_MAINIO_FDC_IRQ:
597                         set_irq_mfd(val_b);
598                         break;
599                 case FM7_MAINIO_KANJI1_ADDR_HIGH:
600                         kaddress.b.h = data;
601                         break;
602                 case FM7_MAINIO_KANJI1_ADDR_LOW:
603                         kaddress.b.l = data;
604                         break;
605 #if defined(CAPABLE_KANJI_CLASS2)
606                 case FM7_MAINIO_KANJI2_ADDR_HIGH:
607                         kaddress_l2.b.h = data;
608                         break;
609                 case FM7_MAINIO_KANJI2_ADDR_LOW:
610                         kaddress_l2.b.l = data;
611                         break;
612 #endif
613         }
614         
615 }
616
617
618  uint8 FM7_MAINIO::get_irqstat_fd03(void)
619 {
620         uint8 val;
621         bool extirq = false;
622         
623         extirq = irqstat_fdc | intstat_opn | intstat_whg | intstat_thg;
624         
625         //extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
626         if(extirq) {
627                 irqstat_reg0 &= ~0x08;
628         } else {
629                 irqstat_reg0 |= 0x08;
630         }
631         val = irqstat_reg0 | 0xf0;
632         set_irq_timer(false);
633         set_irq_printer(false);
634         return val;
635 }
636
637 uint8 FM7_MAINIO::get_extirq_fd17(void)
638 {
639         uint8 val = 0xff;
640         if(intstat_opn)   val &= ~0x08;
641         if(intstat_mouse) val &= ~0x04;
642         //if(!intstat_opn && !intstat_mouse) do_irq(false);
643         return val;
644 }
645
646 void FM7_MAINIO::set_ext_fd17(uint8 data)
647 {
648         if((data & 0x04) != 0) {
649                 mouse_enable = true;
650         } else {
651                 mouse_enable = false;
652         }
653    
654 }
655 #if defined(_FM77AV_VARIANTS)
656 // FD12
657 uint8 FM7_MAINIO::subsystem_read_status(void)
658 {
659         uint8 retval;
660         retval = (display->read_signal(SIG_DISPLAY_MODE320) != 0) ? 0x40 : 0;
661         retval |= display->read_signal(SIG_DISPLAY_VSYNC);
662         retval |= display->read_signal(SIG_DISPLAY_DISPLAY);
663         retval |= ~0x43;
664         return retval;
665 }
666 #endif
667
668 uint32 FM7_MAINIO::read_signal(uint32 addr)
669 {
670         uint32 retval = 0xffffffff;
671         switch(addr) {
672         }
673         return retval;
674 }
675
676 uint32 FM7_MAINIO::read_data8(uint32 addr)
677 {
678         uint32 retval;
679         if(addr == FM7_MAINIO_IS_BASICROM) {
680                 retval = 0;
681                 if(stat_bootsw_basic) retval = 0xffffffff;
682                 return retval;
683         } else if(addr == FM7_MAINIO_BOOTMODE) {
684                 retval = bootmode & 0x03;
685 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
686                 if(boot_ram) retval = 4;
687 #endif
688                 return retval;
689         } else if(addr == FM7_MAINIO_READ_FD0F) {
690                 if(stat_romrammode) return 0xffffffff;
691                 return 0;
692         } else if(addr == FM7_MAINIO_CLOCKMODE) {
693                 return (uint32)get_clockmode();
694         }
695 #if defined(HAS_MMR)    
696         else if(addr == FM7_MAINIO_MMR_ENABLED) {
697                 retval = (mmr_enabled) ? 0xffffffff:0x00000000;
698                 return retval;
699         } else if(addr == FM7_MAINIO_WINDOW_ENABLED) {
700                 retval = (window_enabled) ? 0xffffffff:0x00000000;
701                 return retval;
702         } else if(addr == FM7_MAINIO_WINDOW_OFFSET) {
703                 retval = (uint32)window_offset;
704                 return retval;
705         } else if(addr == FM7_MAINIO_MMR_SEGMENT) {
706                 retval = (uint32) mmr_segment;
707                 return retval;
708         } else if((addr >= FM7_MAINIO_MMR_BANK) &&  (addr < (FM7_MAINIO_MMR_BANK + 16))) {
709 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
710                 retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 7) * 16];
711 #else   
712                 retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 3)  * 16] & 0x3f;
713 #endif
714                 return retval;
715         }
716 #endif
717 #if defined(_FM77AV_VARIANTS)
718         else if(addr == FM7_MAINIO_INITROM_ENABLED) {
719                 retval = (enable_initiator) ? 0xffffffff : 0x00000000;
720                 return retval;
721         } else if(addr == FM7_MAINIO_MODE320) {
722                 retval = display->read_signal(SIG_DISPLAY_MODE320);
723                 return retval;
724         } else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
725                 retval = sub_monitor_type & 0x03;
726                 return retval;
727         }  else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
728 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
729                 retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
730 #else
731                 retval = 0;
732 #endif
733                 return retval;
734         }
735 #endif
736 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
737         else if(addr == FM7_MAINIO_EXTBANK) {
738         } else if(addr == FM7_MAINIO_EXTROM) {
739         }
740 #endif
741         //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
742         addr = addr & 0xff;
743         retval = 0xff;
744 #if defined(HAS_MMR)
745         if((addr < 0x90) && (addr >= 0x80)) {
746 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
747                 return mmr_table[addr - 0x80 + mmr_segment * 16];
748 #else
749                 return mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16];
750 #endif    
751         }
752 #endif
753         //      if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
754         switch(addr) {
755                 case 0x00: // FD00
756                         retval = (uint32) get_port_fd00();
757                         break;
758                 case 0x01: // FD01
759                         display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 0, 1);
760                         set_irq_keyboard(false);
761                         retval = (uint32) kbd_bit7_0;
762                         break;
763                 case 0x02: // FD02
764                         retval = (uint32) get_port_fd02();
765                         break;
766                 case 0x03: // FD03
767                         retval = (uint32) get_irqstat_fd03();
768                         break;
769                 case 0x04: // FD04
770                         retval = (uint32) get_fd04();
771                         break;
772                 case 0x05: // FD05
773                         retval = (uint32) get_fd05();
774                         break;
775                 case 0x06: // RS-232C
776                 case 0x07:
777                         break;
778                 case 0x08: // Light pen
779                 case 0x09:
780                 case 0x0a:
781                         break;
782 #if defined(_FM77AV_VARIANTS)
783                 case 0x0b:
784                         retval = (bootmode == 0) ? 0xfe : 0xff;
785                         break;
786 #endif                  
787                 case 0x0e: // PSG DATA
788                         retval = (uint32) get_psg();
789                         //printf("PSG DATA READ val=%02x\n", retval);
790                         break;
791                 case 0x0f: // FD0F
792                         read_fd0f();
793                         retval = 0xff;
794                         break;
795 #if defined(_FM77AV_VARIANTS)
796                 case 0x12:
797                         retval = subsystem_read_status();  
798                         break;
799 #endif
800                 case 0x15: // OPN CMD
801                         //printf("OPN CMD READ \n");
802                         break;
803                 case 0x16: // OPN DATA
804                         retval = (uint32) get_opn(0);
805                         //printf("OPN DATA READ val=%02x\n", retval);
806                         break;
807                 case 0x17:
808                         retval = (uint32) get_extirq_fd17();
809                         break;
810                 case 0x18: // FDC: STATUS
811                         retval = (uint32) get_fdc_stat();
812                         //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc()); 
813                         break;
814                 case 0x19: // FDC: Track
815                         retval = (uint32) get_fdc_track();
816                         //printf("FDC: READ TRACK REG %02x\n", retval); 
817                         break;
818                 case 0x1a: // FDC: Sector
819                         retval = (uint32) get_fdc_sector();
820                         //printf("FDC: READ SECTOR REG %02x\n", retval); 
821                         break;
822                 case 0x1b: // FDC: Data
823                         retval = (uint32) get_fdc_data();
824                         break;
825                 case 0x1c:
826                         retval = (uint32) get_fdc_fd1c();
827                         //printf("FDC: READ HEAD REG %02x\n", retval); 
828                         break;
829                 case 0x1d:
830                         retval = (uint32) get_fdc_motor();
831                         //printf("FDC: READ MOTOR REG %02x\n", retval); 
832                         break;
833                 case 0x1f:
834                         retval = (uint32) fdc_getdrqirq();
835                         break;
836                 case 0x22: // Kanji ROM
837                         retval = (uint32) read_kanjidata_left();
838                         break;
839                 case 0x23: // Kanji ROM
840                         retval = (uint32) read_kanjidata_right();
841                         break;
842 #if defined(CAPABLE_KANJI_CLASS2)
843                 case 0x2e: // Kanji ROM Level2
844                         retval = (uint32) read_kanjidata_left_l2();
845                         break;
846                 case 0x2f: // Kanji ROM Level2
847                         retval = (uint32) read_kanjidata_right_l2();
848                         break;
849 #endif
850                 case 0x37: // Multi page
851                         //retval = (uint32)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
852                         break;
853                 case 0x45: // WHG CMD
854                         break;
855                 case 0x46: // WHG DATA
856                         retval = (uint32) get_opn(1);
857                         break;
858                 case 0x47:
859                         retval = (uint32) get_extirq_whg();
860                         break;
861                 case 0x51: // THG CMD
862                         break;
863                 case 0x52: // THG DATA
864                         retval = (uint32) get_opn(2);
865                         break;
866                 case 0x53:
867                         retval = (uint32) get_extirq_thg();
868                         break;
869 #if defined(HAS_MMR)
870                 case 0x93:
871                         retval = 0x3e;
872                         if(boot_ram) retval |= 0x01;
873                         if(window_enabled) retval |= 0x40;
874                         if(mmr_enabled) retval |= 0x80;
875                         break;
876 #endif
877                 default:
878                         //printf("MAIN: Read another I/O Addr=%08x\n", addr); 
879                         break;
880         }
881         if((addr < 0x40) && (addr >= 0x38)) {
882                 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
883                 return (uint32) display->read_data8(addr);
884         }
885         // Another:
886         return retval;
887 }
888
889 void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
890 {
891         bool flag;
892         if(addr == FM7_MAINIO_BOOTMODE) {
893                 bootmode = data & 0x03;
894                 return;
895         } else if(addr == FM7_MAINIO_CLOCKMODE) {
896                 set_clockmode((uint8)data);
897                 return;
898         }
899         //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
900         
901         data = data & 0xff;
902         addr = addr & 0xff;
903 #if defined(HAS_MMR)
904         if((addr < 0x90) && (addr >= 0x80)) {
905 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
906                 mmr_table[addr - 0x80 + mmr_segment * 16] = data;
907 #else
908                 mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16] = data & 0x3f;
909 #endif
910                 //printf("MMR: Write access segment=%02x addr=%02x page=%02x\n", mmr_segment, addr - 0x80, data);
911                 return;
912         }
913 #endif
914         switch(addr) {
915                 case 0x00: // FD00
916                         set_port_fd00((uint8)data);
917                         return;
918                         break;
919                 case 0x01: // FD01
920                         // set_lptdata_fd01((uint8)data);
921                         break;
922                 case 0x02: // FD02
923                         set_port_fd02((uint8)data);
924                         break;
925                 case 0x03: // FD03
926                         set_beep(data);
927                         break;
928                 case 0x04: // FD04
929                         // set_flags_fd04(data);
930                         break;
931                 case 0x05: // FD05
932                         set_fd05((uint8)data);
933                         break;
934                 case 0x06: // RS-232C
935                 case 0x07:
936                         break;
937                 case 0x08: // Light pen
938                 case 0x09:
939                 case 0x0a:
940                         break;
941                 case 0x0d:
942                         //printf("PSG CMD WRITE val=%02x\n", data);
943                         set_psg_cmd(data);
944                         break;
945                 case 0x0e:
946                         //printf("PSG DATA WRITE val=%02x\n", data);
947                         set_psg(data);
948                         break;
949                 case 0x0f: // FD0F
950                         write_fd0f();
951                         break;
952 #if defined(_FM77AV_VARIANTS)
953                 case 0x10:
954                         flag = enable_initiator;
955                         //printf("INITIATOR ENABLE = %02x\n", data);
956                         enable_initiator = ((data & 0x02) == 0) ? true : false;
957                         if(flag != enable_initiator) {
958                           mainmem->reset();
959                           //this->reset();
960                         }
961                         break;
962                 case 0x12:
963                         //mode320 = ((data & 0x40) != 0);
964                         display->write_signal(SIG_DISPLAY_MODE320, data,  0x40);
965                         break;
966                 case 0x13:
967                         display->write_signal(SIG_FM7_SUB_BANK, data, 0x07);
968                         break;
969 #endif
970                 case 0x15: // OPN CMD
971                         //printf("OPN CMD WRITE val=%02x\n", data);
972                         set_opn_cmd(0, data);
973                         break;
974                 case 0x16: // OPN DATA
975                         //printf("OPN DATA WRITE val=%02x\n", data);
976                         set_opn(0, data);
977                         break;
978                 case 0x17:
979                         set_ext_fd17((uint8)data);
980                         break;
981                 case 0x18: // FDC: COMMAND
982                         set_fdc_cmd((uint8)data);
983                         //printf("FDC: WRITE CMD %02x\n", data); 
984                         break;
985                 case 0x19: // FDC: Track
986                         set_fdc_track((uint8)data);
987                         //printf("FDC: WRITE TRACK REG %02x\n", data); 
988                         break;
989                 case 0x1a: // FDC: Sector
990                         set_fdc_sector((uint8)data);
991                         //printf("FDC: WRITE SECTOR REG %02x\n", data); 
992                         break;
993                 case 0x1b: // FDC: Data
994                         set_fdc_data((uint8)data);
995                         break;
996                 case 0x1c:
997                         set_fdc_fd1c((uint8)data);
998                         //printf("FDC: WRITE HEAD REG %02x\n", data); 
999                         break;
1000                 case 0x1d:
1001                         set_fdc_fd1d((uint8)data);
1002                         //printf("FDC: WRITE MOTOR REG %02x\n", data); 
1003                         break;
1004                 case 0x1f: // ??
1005                         return;
1006                         break;
1007                 case 0x20: // Kanji ROM
1008                 case 0x2c: // Kanji ROM(DUP)
1009                         write_kanjiaddr_hi((uint8)data);
1010 #if defined(CAPABLE_KANJI_CLASS2)
1011                         write_kanjiaddr_hi_l2((uint8)data);
1012 #endif
1013                         break;
1014                 case 0x21: // Kanji ROM
1015                 case 0x2d: // Kanji ROM(DUP)
1016                         write_kanjiaddr_lo((uint8)data);
1017 #if defined(CAPABLE_KANJI_CLASS2)
1018                         write_kanjiaddr_lo_l2((uint8)data);
1019 #endif
1020                         break;
1021 #if defined(_FM77AV_VARIANTS)
1022                 case 0x30:
1023                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
1024                         break;
1025                 case 0x31:
1026                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
1027                         break;
1028                 case 0x32:
1029                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
1030                         break;
1031                 case 0x33:
1032                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
1033                         break;
1034                 case 0x34:
1035                         display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
1036                         break;
1037 #endif
1038                 case 0x37: // Multi page
1039                         display->write_signal(SIG_FM7_SUB_MULTIPAGE, data, 0x00ff);
1040                         break;
1041                 case 0x45: // WHG CMD
1042                         set_opn_cmd(1, data);
1043                         break;
1044                 case 0x46: // WHG DATA
1045                         set_opn(1, data);
1046                         break;
1047                 case 0x47:
1048                         break;
1049                 case 0x51: // THG CMD
1050                         set_opn_cmd(2, data);
1051                         break;
1052                 case 0x52: // THG DATA
1053                         set_opn(2, data);
1054                         break;
1055                 case 0x53:
1056                         break;
1057 #if defined(HAS_MMR)
1058                 case 0x90:
1059 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1060                         mmr_segment = data & 7;
1061 #else
1062                         //                      printf("MMR SEGMENT: %02x\n", data & 3);
1063                         mmr_segment = data & 3;
1064 #endif                  
1065                         break;
1066                 case 0x92:
1067                         window_offset = data & 0x00ff;
1068                         break;
1069                 case 0x93:
1070                         if((data & 0x01) == 0) {
1071                                 boot_ram = false;
1072                         } else {
1073                                 boot_ram = true;
1074                         }         
1075                         if((data & 0x40) == 0) {
1076                                 window_enabled = false;
1077                         } else {
1078                                 window_enabled = true;
1079                         }         
1080                         if((data & 0x80) == 0) {
1081                                 mmr_enabled = false;
1082                         } else {
1083                                 mmr_enabled = true;
1084                         }
1085                         break;
1086 #endif
1087                 default:
1088                         //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data); 
1089                         break;
1090         }
1091         if((addr < 0x40) && (addr >= 0x38)) {
1092                 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1093                 display->write_data8(addr, (uint8)data);
1094                 return;
1095         }       // Another:
1096         return;
1097 }
1098
1099 void FM7_MAINIO::event_callback(int event_id, int err)
1100 {
1101 //      printf("MAIN EVENT id=%d\n", event_id);
1102         switch(event_id) {
1103                 case EVENT_BEEP_OFF:
1104                         event_beep_off();
1105                         break;
1106                 case EVENT_BEEP_CYCLE:
1107                         event_beep_cycle();
1108                         break;
1109                 case EVENT_UP_BREAK:
1110                         set_break_key(false);
1111                         break;
1112                 case EVENT_TIMERIRQ_ON:
1113                         if(!irqmask_timer) set_irq_timer(true);
1114                         //register_event(this, EVENT_TIMERIRQ_OFF, 10000.0 / (4.9152 * 2.0) , false, NULL); // TIMER IRQ
1115                         break;
1116                 case EVENT_TIMERIRQ_OFF:
1117                         if(!irqmask_timer) set_irq_timer(false);
1118                         //register_event(this, EVENT_TIMERIRQ_ON, 2035, false, NULL); // TIMER ON
1119                         break;
1120                 case EVENT_FD_MOTOR_ON:
1121                         set_fdc_motor(true);
1122                         break;
1123                 case EVENT_FD_MOTOR_OFF:
1124                         set_fdc_motor(false);
1125                         break;
1126                 default:
1127                         break;
1128         }
1129 }
1130
1131