OSDN Git Service

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