OSDN Git Service

[FM7][DISPLAY] Force SYNC submemory and mainmemory to SUBCPU.
[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         event_beep = -1;
18         event_timerirq = -1;
19         bootmode = config.boot_mode & 3;
20 #if defined(_FM77AV_VARIANTS)
21         opn_psg_77av = true;
22 #else
23         opn_psg_77av = false;
24 #endif
25 }
26
27 void FM7_MAINIO::reset(void)
28 {
29         int i, j;
30         uint8 data;
31         if(event_beep >= 0) cancel_event(this, event_beep);
32         if(event_timerirq >= 0) cancel_event(this, event_timerirq);
33         event_beep = -1;
34         beep_snd = true;
35         beep_flag = false;
36         extdet_neg = false;
37    
38         stat_romrammode = true;
39         bootmode = config.boot_mode & 3;
40         if(bootmode == 0) { // IF BASIC BOOT THEN ROM
41                 stat_romrammode = true;
42         } else { // ELSE RAM
43                 stat_romrammode = false;
44         }
45    
46         clock_fast = false;
47         if(config.cpu_type == 0) clock_fast = true;
48    
49         pcm1bit->write_signal(SIG_PCM1BIT_MUTE, 0x01, 0x01);
50         pcm1bit->write_signal(SIG_PCM1BIT_ON, 0x00, 0x01);
51    
52         psg_data = 0;
53         psg_cmdreg = 0;
54         psg_address = 0;
55         connect_opn = connect_whg = connect_thg = false;
56         if(opn_psg_77av) connect_opn = true;
57
58         irqmask_reg0 = 0x00;
59         // FD03
60         irqmask_mfd = false;
61         irqmask_timer = false;
62         irqmask_printer = false;
63         irqmask_keyboard = false;
64         irqstat_reg0 = 0xff;
65         // FD04
66         //firq_break_key = false; // bit1, ON = '0'.
67         firq_sub_attention = false; // bit0, ON = '0'.
68         // FD05
69         sub_busy = false;
70         extdet_neg = false;
71         sub_cancel = false; // bit6 : '1' Cancel req.
72
73         switch(config.sound_device_type) {
74                 case 0:
75                         break;
76                 case 1:
77                         connect_opn = true;
78                         break;
79                 case 2:
80                         connect_whg = true;
81                         break;
82                 case 3:
83                         connect_whg = true;
84                         connect_opn = true;
85                         break;
86                 case 4:
87                         connect_thg = true;
88                         break;
89                 case 5:
90                         connect_thg = true;
91                         connect_opn = true;
92                         break;
93                 case 6:
94                         connect_thg = true;
95                         connect_whg = true;
96                         break;
97                 case 7:
98                         connect_thg = true;
99                         connect_whg = true;
100                         connect_opn = true;
101                         break;
102         }
103         // Init OPN/PSG.
104         // Parameters from XM7.
105         for (i = 0; i < 14; i++) {
106                 if (i == 7) {
107                         for(j = 0; j < 3; j++) {
108                                 opn[j]->write_io8(0, i);
109                                 opn[j]->write_io8(1, 0xff);
110                         }
111                         psg->write_io8(0, i);
112                         psg->write_io8(1, 0xff);
113                 } else {
114                         for(j = 0; j < 3; j++) {
115                                 opn[j]->write_io8(0, i);
116                                 opn[j]->write_io8(1, 0x0);
117                         }
118                         psg->write_io8(0, i);
119                         psg->write_io8(1, 0x0);
120                 }
121         }
122    
123         /* MUL,DT */
124         for (i = 0x30; i < 0x40; i++) {
125                 if ((i & 0x03) == 3) {
126                         continue;
127                 }
128                 for(j = 0; j < 3; j++) {
129                         opn[j]->write_io8(0, i);
130                         opn[j]->write_io8(1, 0x0);
131                 }
132                 psg->write_io8(0, i);
133                 psg->write_io8(1, 0x0);
134         }
135
136         /* TL=$7F */
137         for (i = 0x40; i < 0x50; i++) {
138                 if ((i & 0x03) == 3) {
139                         continue;
140                 }
141                 for(j = 0; j < 3; j++) {
142                         opn[j]->write_io8(0, i);
143                         opn[j]->write_io8(1, 0x7f);
144                 }
145                 psg->write_io8(0, i);
146                 psg->write_io8(1, 0x7f);
147         }
148
149         /* AR=$1F */
150         for (i = 0x50; i < 0x60; i++) {
151                 if ((i & 0x03) == 3) {
152                         continue;
153                 }
154                 for(j = 0; j < 3; j++) {
155                         opn[j]->write_io8(0, i);
156                         opn[j]->write_io8(1, 0x1f);
157                 }
158                 psg->write_io8(0, i);
159                 psg->write_io8(1, 0x1f);
160         }
161
162         /* Others */
163         for (i = 0x60; i < 0xb4; i++) {
164                 if ((i & 0x03) == 3) {
165                         continue;
166                 }
167                 for(j = 0; j < 3; j++) {
168                         opn[j]->write_io8(0, i);
169                         opn[j]->write_io8(1, 0x00);
170                 }
171                 psg->write_io8(0, i);
172                 psg->write_io8(1, 0x00);
173         }
174
175         /* SL,RR */
176         for (i = 0x80; i < 0x90; i++) {
177                 if ((i & 0x03) == 3) {
178                         continue;
179                 }
180                 for(j = 0; j < 3; j++) {
181                         opn[j]->write_io8(0, i);
182                         opn[j]->write_io8(1, 0xff);
183                 }
184                 psg->write_io8(0, i);
185                 psg->write_io8(1, 0xff);
186         }
187
188         /* Key Off */
189         for (i = 0; i < 3; i++) {
190                 for(j = 0; j < 3; j++) {
191                         opn[j]->write_io8(0, 0x28);
192                         opn[j]->write_io8(1, i);
193                 }
194                 psg->write_io8(0, 0x28);
195                 psg->write_io8(1, i);
196         }
197
198         /* Mode */
199         for(j = 0; j < 3; j++) {
200                 opn[j]->write_io8(0, 0x27);
201                 opn[j]->write_io8(1, 0);
202         }
203         psg->write_io8(0, 0x27);
204         psg->write_io8(1, 0);
205   
206    
207         nmi_count = 0;
208         irq_count = 0;
209         firq_count = 0;
210    
211         fdc_statreg = 0x00;
212         fdc_cmdreg = 0x00;
213         fdc_trackreg = 0x00;
214         fdc_sectreg = 0x00;
215         fdc_datareg = 0x00;
216         fdc_headreg = 0x00;
217         fdc_drvsel = 0x00;
218         fdc_motor = false;
219         fdc_drq = false;
220         fdc_irq = false;
221         irqstat_fdc = 0;
222         if(connect_fdc) extdet_neg = true;
223    
224         register_event(this, EVENT_TIMERIRQ_ON, 4069.0 / 2.0, true, &event_timerirq); // TIMER IRQ
225
226         //maincpu->reset();
227 }
228
229
230 void FM7_MAINIO::set_clockmode(uint8 flags)
231 {
232         if(flags == FM7_MAINCLOCK_SLOW) {
233                 clock_fast = false;
234         } else {
235                 clock_fast = true;
236         }
237 }
238
239 uint8 FM7_MAINIO::get_clockmode(void)
240 {
241         if(clock_fast) return FM7_MAINCLOCK_SLOW;
242         return FM7_MAINCLOCK_HIGH;
243 }
244
245
246 uint8 FM7_MAINIO::get_port_fd00(void)
247 {
248         uint8 ret           = 0b01111110;
249         if(kbd_bit8)   ret |= 0b10000000;
250         if(clock_fast) ret |= 0b00000001;
251         return ret;
252 }
253   
254 void FM7_MAINIO::set_port_fd00(uint8 data)
255 {
256        drec->write_signal(SIG_DATAREC_OUT, data, 0x01);
257        drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
258 }
259    
260 uint8 FM7_MAINIO::get_port_fd02(void)
261 {
262         uint8 ret;
263         // Still unimplemented printer.
264         ret = (cmt_indat) ? 0xff : 0x7f; // CMT 
265         return ret;
266 }
267
268 void FM7_MAINIO::set_port_fd02(uint8 val)
269 {
270         irqmask_reg0 = val;
271         if((val & 0b00010000) != 0) {
272                 irqmask_mfd = false;
273         } else {
274                 irqmask_mfd = true;
275         }
276         if((val & 0b00000100) != 0) {
277                 irqmask_timer = false;
278         } else {
279                 irqmask_timer = true;
280         }
281         if((val & 0b00000010) != 0) {
282                 irqmask_printer = false;
283         } else {
284                 irqmask_printer = true;
285         }
286         if((val & 0b00000001) != 0) {
287                 irqmask_keyboard = false;
288         } else {
289                 irqmask_keyboard = true;
290         }
291         return;
292 }
293
294
295 uint32 FM7_MAINIO::get_keyboard(void)
296 {
297         uint32 kbd_data = (uint32) kbd_bit7_0;
298         kbd_data &= 0x0ff;
299         if(kbd_bit8) kbd_data |= 0x0100;
300         return kbd_data;
301 }
302
303
304 void FM7_MAINIO::set_beep(uint32 data) // fd03
305 {
306         beep_flag = ((data & 0xc0) != 0);
307         pcm1bit->write_signal(SIG_PCM1BIT_MUTE, ~data, 0b00000001);
308         if(beep_flag) {
309                 beep_snd = true;
310                 if(event_beep < 0) register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
311                 pcm1bit->write_signal(SIG_PCM1BIT_SIGNAL, 1, 1);
312                 pcm1bit->write_signal(SIG_PCM1BIT_ON, 1, 1);
313         } else {
314                 if(event_beep >= 0) cancel_event(this, event_beep);
315                 event_beep = -1;
316                 pcm1bit->write_signal(SIG_PCM1BIT_SIGNAL, 0, 1);
317                 pcm1bit->write_signal(SIG_PCM1BIT_ON, 0, 1);
318         }
319         if((data & 0x40) != 0) {
320                 // BEEP ON, after 205ms, BEEP OFF.  
321                 register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
322         }
323 }
324
325 void FM7_MAINIO::set_irq_timer(bool flag)
326 {
327         uint8 backup = irqstat_reg0;
328         if(flag) {
329                 irqstat_reg0 &= 0b11111011;
330                 if(!irqmask_timer && ((backup & 0b00000100) != 0)) do_irq(true);
331         } else {
332                 irqstat_reg0 |= 0b00000100;
333                 do_irq(false);
334         }
335         //printf("IRQ TIMER: %d MASK=%d\n", flag, irqmask_timer);
336 }
337
338 void FM7_MAINIO::set_irq_printer(bool flag)
339 {
340         uint8 backup = irqstat_reg0;
341         if(flag) {
342                 irqstat_reg0 &= 0b11111101;
343                 if(!irqmask_printer && ((backup & 0b00000010) != 0)) do_irq(true);
344         } else {
345                 irqstat_reg0 |= 0b00000010;
346                 do_irq(false);
347         }
348 }
349
350 void FM7_MAINIO::set_irq_keyboard(bool flag)
351 {
352         uint8 backup = irqstat_reg0;
353         if(flag) {
354                 irqstat_reg0 &= 0b11111110;
355                 if(!irqmask_keyboard && ((backup & 0b00000001) != 0)) do_irq(true);
356         } else {
357                 irqstat_reg0 |= 0b00000001;
358                 do_irq(false);
359         }
360 }
361
362 void FM7_MAINIO::set_irq_mfd(bool flag)
363 {
364         fdc_irq = flag;
365         if(flag &&  connect_fdc) {
366                 irqstat_fdc |= 0b01000000;
367         }
368         if((flag == false) && connect_fdc){
369                 irqstat_fdc &= 0b10111111;
370         }
371         if(!irqmask_mfd) do_irq(flag);
372         return;
373 }
374
375 void FM7_MAINIO::set_drq_mfd(bool flag)
376 {
377   //    fdc_irq = flag;
378         if(flag &&  connect_fdc) {
379                 irqstat_fdc |= 0b10000000;
380         }
381         if((flag == false) && connect_fdc){
382                 irqstat_fdc &= 0b01111111;
383         }
384         //if(!irqmask_mfd) do_irq(flag);
385         return;
386 }
387
388
389 void FM7_MAINIO::set_keyboard(uint32 data)
390 {
391         if((data & 0x100) != 0){
392                 kbd_bit8 = true;
393         } else {
394                 kbd_bit8 = false;
395         }
396         kbd_bit7_0 = (data & 0xff);
397 }
398
399
400 void FM7_MAINIO::do_irq(bool flag)
401 {
402         if(flag) {
403                 if(irq_count >= 0x7ffffffe) {
404                         irq_count = 0x7ffffffe;
405                         return;
406                 }
407                 irq_count++;
408                 if(irq_count <= 1) maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
409         } else {
410                 if(irq_count <= 0) {
411                         irq_count = 0;
412                         return;
413                 }
414                 irq_count--;
415                 if(irq_count == 0) maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
416         }
417 }
418
419 void FM7_MAINIO::do_firq(bool flag)
420 {
421         if(flag) {
422                 if(firq_count >= 0x7ffffffe) {
423                         firq_count = 0x7ffffffe;
424                         return;
425                 }
426                 firq_count++;
427                 if(firq_count <= 1) maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
428         } else {
429                 if(firq_count <= 0) {
430                         firq_count = 0;
431                         return;
432                 }
433                 firq_count--;
434                 if(firq_count == 0) maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
435         }
436 }
437
438 void FM7_MAINIO::do_nmi(bool flag)
439 {
440         if(flag) {
441                 if(nmi_count >= 0x7ffffffe) {
442                         nmi_count = 0x7ffffffe;
443                         return;
444                 }
445                 nmi_count++;
446                 if(nmi_count <= 1) maincpu->write_signal(SIG_CPU_NMI, 1, 1);
447         } else {
448                 if(nmi_count <= 0) {
449                         nmi_count = 0;
450                         return;
451                 }
452                 nmi_count--;
453                 if(nmi_count == 0) maincpu->write_signal(SIG_CPU_NMI, 0, 1);
454         }
455 }
456
457
458 void FM7_MAINIO::set_break_key(bool pressed)
459 {
460         firq_break_key = pressed;
461         do_firq(pressed);
462 }
463 void FM7_MAINIO::set_sub_attention(bool flag)
464 {
465         firq_sub_attention = flag;
466         do_firq(flag); 
467 }
468   
469
470 uint8 FM7_MAINIO::get_fd04(void)
471 {
472         uint8 val = 0b01111100;
473         if(sub_busy)            val |= 0b10000000;
474         if(!firq_break_key)     val |= 0b00000010;
475         if(!firq_sub_attention) val |= 0b00000001;
476         if(firq_sub_attention) {
477                 firq_sub_attention = false;
478         }
479         return val;
480 }
481
482 void FM7_MAINIO::set_fd04(uint8 val)
483 {
484         // NOOP?
485 }
486
487   // FD05
488  uint8 FM7_MAINIO::get_fd05(void)
489 {
490         uint8 val = 0b01111110;
491         if(sub_busy)    val |= 0b10000000;
492         if(!extdet_neg) val |= 0b00000001;
493         return val;
494 }
495
496  void FM7_MAINIO::set_fd05(uint8 val)
497 {
498         subcpu->write_signal(SIG_CPU_BUSREQ, val, 0b10000000);
499 //      display->write_signal(SIG_DISPLAY_HALT,   val, 0b10000000);
500         display->write_signal(SIG_FM7_SUB_CANCEL, val, 0b01000000);
501 #ifdef WITH_Z80
502         if((val & 0b00000001) != 0) {
503                 maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
504                 //z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
505         } else {
506                 maincpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
507                 //z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
508         }
509 #endif
510 }
511
512
513
514 void FM7_MAINIO::set_extdet(bool flag)
515 {
516         extdet_neg = flag;
517 }
518
519 void FM7_MAINIO::set_psg(uint8 val)
520 {
521         if(opn_psg_77av) return set_opn(0, val); // 77AV ETC
522         psg_data = val;
523         switch(psg_cmdreg){
524                 case 0: // High inpedance
525                         break;
526                 case 1: // Read Data
527                         break;
528                 case 2: // Write Data
529                         printf("PSG WRITE 2 DATA %02x to REG ADDR=%02x\n", psg_data, psg_address);
530                         psg->write_io8(0, psg_address & 0x0f);
531                         psg->write_io8(1, psg_data);
532                         //psg->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
533                         break;
534                 case 3: // Register address
535                         psg_address = val & 0x0f;
536                         //psg->write_io8(0, psg_address & 0x0f);
537                         break;
538         }
539 }
540
541 uint8 FM7_MAINIO::get_psg(void)
542 {
543         uint8 val = 0xff;
544         if(opn_psg_77av) {
545                 return get_opn(0);
546         }
547         switch(psg_cmdreg) {
548                 case 0:
549                   //val = 0xff;
550                   //    break;
551                 case 1:
552                 case 2:
553                 case 3:
554                         val = psg_data;
555                         break;
556         }
557         return val;
558 }
559
560 /*
561  * $fd0d : After 77AV, this is OPN.
562  */
563 void FM7_MAINIO::set_psg_cmd(uint8 cmd)
564 {
565         if(opn_psg_77av) {
566                 set_opn_cmd(0, cmd);
567                 return;
568         }
569         uint32 mask[16] = { // Parameter is related by XM7. Thanks Ryu.
570                 0xff, 0x0f, 0xff, 0x0f,
571                 0xff, 0x0f, 0x1f, 0xff,
572                 0x1f, 0x1f, 0x1f, 0xff,
573                 0xff, 0x0f, 0xff, 0xff
574         };
575         psg_cmdreg = (uint8)(cmd & 0b00000011);
576         switch(psg_cmdreg) {
577                 case 0:
578                         break;
579                 case 1:
580                         psg->write_io8(0, psg_address & 0x0f);
581                         psg_data = psg->read_io8(1); // & mask[psg_address];
582                         printf("PSG READ DATA %02x from REG ADDR=%02x\n", psg_data, psg_address);
583                         break;
584                 case 2:
585                         printf("PSG WRITE DATA %02x to REG ADDR=%02x\n", psg_data, psg_address);
586                         psg->write_io8(0, psg_address & 0x0f);
587                         psg->write_io8(1, psg_data);
588                         //psg->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
589                         break;
590                 case 3:
591                         psg_address = psg_data & 0x0f;
592                         //psg->write_io8(0, psg_address & 0x0f);
593                         printf("PSG REG ADDR=%02x\n", psg_address);
594                         break;
595                 default:
596                         break;
597         }
598    
599         return;
600 }
601
602
603
604
605 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
606 void FM7_MAINIO::write_kanjiaddr_hi(uint8 addr)
607 {
608         if(!connect_kanjiroml1) return;
609         kaddress_hi = addr;
610         return;
611 }
612
613 void FM7_MAINIO::write_kanjiaddr_lo(uint8 addr)
614 {
615         if(!connect_kanjiroml1) return;
616         kaddress_lo = addr;
617         return;
618 }
619
620 uint8 FM7_MAINIO::read_kanjidata_left(void)
621 {
622         uint32 addr;
623     
624         if(!connect_kanjiroml1) return 0xff;
625         addr = ((uint32)kaddress_hi << 8) | (uint32)kaddress_lo;
626         addr = addr << 1;
627         if(kanjiclass1) {
628                 return kanjiclass1->read_data8(addr);
629         } else {
630                 return 0xff;
631         }
632 }
633
634 uint8 FM7_MAINIO::read_kanjidata_right(void)
635 {
636         uint32 addr;
637     
638         if(!connect_kanjiroml1) return 0xff;
639         addr = ((uint32)kaddress_hi << 8) | (uint32)kaddress_lo;
640         addr = (addr << 1) | 1;
641         if(kanjiclass1) {
642                 return kanjiclass1->read_data8(addr);
643         } else {
644                 return 0xff;
645         }
646 }
647
648 #ifdef _FM77AV_VARIANTS
649 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
650 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8 addr)
651 {
652         if(!connect_kanjiroml2) return;
653         kaddress_hi_l2 = addr;
654         return;
655 }
656
657 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8 addr)
658 {
659         if(!connect_kanjiroml2) return;
660         kaddress_lo_l2 = addr;
661         return;
662 }
663
664 uint8 FM7_MAINIO::read_kanjidata_left_l2(void)
665 {
666         uint32 addr;
667     
668         if(!connect_kanjiroml2) return 0xff;
669         addr = ((uint32)kaddress_hi_l2 << 8) | (uint32)kaddress_lo_l2;
670         addr = addr << 1;
671         if(kanjiclass2) {
672                 return kanjiclass2->read_data8(addr);
673         } else {
674                 return 0xff;
675         }
676 }
677
678 uint8 FM7_MAINIO::read_kanjidata_right_l2(void)
679 {
680         uint32 addr;
681     
682         if(!connect_kanjiroml2) return 0xff;
683         addr = ((uint32)kaddress_hi_l2 << 8) | (uint32)kaddress_lo_l2;
684         addr = (addr << 1) | 0x01;
685         if(kanjiclass2) {
686                 return kanjiclass2->read_data8(addr);
687         } else {
688                 return 0xff;
689         }
690 }
691 #endif
692 // OPN
693 // Write to FD16, same as 
694 void FM7_MAINIO::set_opn(int index, uint8 val)
695 {
696         //printf("OPN %d WRITE %02x \n", index, val);
697         if((index > 2) || (index < 0)) return;
698         if((index == 0) && (!connect_opn)) return;
699         if((index == 1) && (!connect_whg)) return;
700         if((index == 2) && (!connect_thg)) return;
701    
702         if(opn[index] == NULL) return;
703    
704         opn_data[index] = val;
705         switch(opn_cmdreg[index]){
706                 case 0: // High inpedance
707                         break;
708                 case 1: // Read Data
709                         //opn[index]->write_io8(0, opn_address[index]);
710                         //opn_data[index] = opn[index]->read_io8(1);
711                         break;
712                 case 2: // Write Data
713                         printf("OPN %d WRITE DATA %02x to REG ADDR=%02x\n", index, val, opn_address[index]);
714                         opn[index]->write_io8(0, opn_address[index]);
715                         opn[index]->write_io8(1, val & 0x00ff);
716                         //opn[index]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
717                         break;
718                 case 3: // Register address
719                         opn_address[index] = val & 0xff;
720                         //opn[index]->write_io8(0, opn_address[index]);
721                         //printf("OPN %d REG ADDR=%02x\n", index, opn_address[index]);
722                         if((val > 0x2c) && (val < 0x30)) {
723                                 opn_data[index] = 0;
724                                 opn[index]->write_io8(0, opn_address[index]);
725                                 opn[index]->write_io8(1, 0);
726                         }
727                         break;
728            
729         }
730 }
731
732 uint32 FM7_MAINIO::update_joystatus(int index)
733 {
734         uint32 *joybuf = p_emu->joy_buffer();
735         uint32 val = 0xff;
736         if((joybuf[index] & 0x01) != 0) val &= ~0x01;  
737         if((joybuf[index] & 0x02) != 0) val &= ~0x02;  
738         if((joybuf[index] & 0x04) != 0) val &= ~0x04;  
739         if((joybuf[index] & 0x08) != 0) val &= ~0x08;
740         if((joybuf[index] & 0x10) != 0) val &= ~0x10;  
741         if((joybuf[index] & 0x20) != 0) val &= ~0x20;  
742         if((joybuf[index] & 0x40) != 0) val &= ~0x10;  
743         if((joybuf[index] & 0x80) != 0) val &= ~0x20;  
744         return val;
745 }
746
747 uint8 FM7_MAINIO::get_opn(int index)
748 {
749         uint8 val = 0xff;
750         if((index > 2) || (index < 0)) return 0xff;
751         if((index == 0) && (!connect_opn)) return 0xff;
752         if((index == 1) && (!connect_whg)) return 0xff;
753         if((index == 2) && (!connect_thg)) return 0xff;
754    
755         if(opn[index] == NULL) return 0xff;
756    
757         if(opn_cmdreg[index] == 0b00001001) {
758                 //printf("OPN: JOY PORT ADDR=%02x\n", opn_address[index]);
759                 // Read Joystick
760                 if(opn_address[index] == 0x0e) {
761                         joyport_a = update_joystatus(0);
762                         joyport_b = update_joystatus(1);
763                         opn[index]->write_io8(0, 0x0f);
764                         val = opn[index]->read_io8(1);
765                         //printf("JOY: A=%02x B=%02x Reg15=%02x\n", val, joyport_a, joyport_b); 
766                         if((val & 0x20) == 0x20) return joyport_a;
767                         if((val & 0x50) == 0x50) return joyport_b;
768                         return 0xff;
769                 }
770                 return 0x00;
771         }
772         if(opn_cmdreg[index] == 0b00000100) {
773                 // Read Status
774                 opn_stat[index] = opn[index]->read_io8(0) & 0x03;
775                 return opn_stat[index];
776         }
777         switch(opn_cmdreg[index]) {
778                 case 0:
779                   //val = 0xff;
780                   //break;
781                 case 1:
782                 case 2:
783                 case 3:
784                         val = opn_data[index];
785                         break;
786         }
787         return val;
788 }
789   /*
790    * $fd16?
791    */
792 void FM7_MAINIO::set_opn_cmd(int index, uint8 cmd)
793 {
794         if((index > 2) || (index < 0)) return;
795         if((index == 0) && (!connect_opn)) return;
796         if((index == 1) && (!connect_whg)) return;
797         if((index == 2) && (!connect_thg)) return;
798         uint32 mask[16] = { // Parameter is related by XM7. Thanks Ryu.
799                 0xff, 0x0f, 0xff, 0x0f,
800                 0xff, 0x0f, 0x1f, 0xff,
801                 0x1f, 0x1f, 0x1f, 0xff,
802                 0xff, 0x0f, 0xff, 0xff
803         };
804         opn_cmdreg[index] = cmd & 0b00001111;
805         switch(opn_cmdreg[index]) {
806                 case 0:
807                         break;
808                 case 1:
809                   //if(opn_address[index] > 0x0f) {
810                   //            opn_data[index] = 0xff;
811                   //            break;
812                   //    }
813                         opn[index]->write_io8(0, opn_address[index]);
814                         opn_data[index] = opn[index]->read_io8(1) & mask[opn_address[index]];
815                         printf("OPN %d READ DATA %02x from REG ADDR=%02x\n", index, opn_data[index], opn_address[index]);
816                         break;
817                 case 2:
818                         printf("OPN %d WRITE DATA %02x to REG ADDR=%02x\n", index, opn_data[index], opn_address[index]);
819                         //if(((opn_address[index] > 0x0d) && (opn_address[index] < 0x27)) ||
820                         //   ((opn_address[index] > 0x28) && (opn_address[index] < 0x2d))) break;
821                         opn[index]->write_io8(0, opn_address[index]);
822                         opn[index]->write_io8(1, opn_data[index]);
823                         //opn[index]->write_signal(SIG_YM2203_MUTE, 0x00, 0x01); // Okay?
824                         break;
825                 case 3:
826                         opn_address[index] = opn_data[index];
827                         printf("OPN %d REG ADDR=%02x\n", index, opn_address[index]);
828                         //opn[index]->write_io8(0, opn_address[index]);
829                         if((opn_data[index] > 0x2c) && (opn_data[index] < 0x30)) {
830                                 opn_data[index] = 0;
831                                 opn[index]->write_io8(0, opn_address[index]);
832                                 opn[index]->write_io8(1, 0);
833                         }
834                         break;
835                 default:
836                         break;
837         }
838    
839         //printf("OPN %d SET REG ADDR=%02x\n", index, opn_cmdreg[index]);
840         return;
841 }
842
843
844
845 void FM7_MAINIO::write_signal(int id, uint32 data, uint32 mask)
846 {
847         bool val_b;
848         val_b = ((data & mask) != 0);
849   
850         switch(id) {
851                 case FM7_MAINIO_CLOCKMODE: // fd00
852                         if(val_b) {
853                                 clock_fast = true;
854                         } else {
855                                 clock_fast = false;
856                         }
857                         {
858                                 uint32 clocks;
859                                 uint32 subclocks;
860 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
861                                 if(mmr_enabled) {
862                                         if(mmr_fast) {
863                                                 if(clock_fast) {
864                                                         clocks = 2016000; // Hz
865                                                 } else {
866                                                         clocks = 1230502; // (2016 * 1095 / 1794)[KHz]
867                                                 }
868                                         } else {
869                                                 if(clock_fast) {
870                                                         clocks = 1565000; // Hz
871                                                 } else {
872                                                         clocks =  955226; // (1565 * 1095 / 1794)[KHz]
873                                                 }
874                                         }
875                                 } else {
876                                         if(clock_fast) {
877                                                 clocks = 1794000; // Hz 
878                                         } else {
879                                                 clocks = 1095000; // Hz
880                                         }
881                                 }
882 #else // 7/8
883                                 if(clock_fast) {
884                                         clocks = 1794000; // Hz 
885                                 } else {
886                                         clocks = 1095000; // Hz
887                                 }
888 #endif
889                                 if(clock_fast) {
890                                         subclocks = 2000000; // Hz
891                                 } else {
892                                         subclocks =  999000; // Hz
893                                 }
894                                 p_vm->set_cpu_clock(this->maincpu, clocks);
895                                 p_vm->set_cpu_clock(this->subcpu,  subclocks);
896                         }
897                         break;
898                 case FM7_MAINIO_CMT_RECV: // FD02
899                         cmt_indat = val_b ^ cmt_invert;
900                         break;
901                 case FM7_MAINIO_CMT_INVERT: // FD02
902                         cmt_invert = val_b;
903                         break;
904                 case FM7_MAINIO_TIMERIRQ: //
905                         set_irq_timer(val_b);
906                         break;
907                 case FM7_MAINIO_LPTIRQ: //
908                         set_irq_printer(val_b);
909                         break;
910                 case FM7_MAINIO_KEYBOARDIRQ: //
911                         set_irq_keyboard(val_b);
912                         break;
913                 case FM7_MAINIO_PUSH_KEYBOARD:
914                         set_keyboard(data & 0x1ff);
915                         break;
916                         // FD04
917                 case FM7_MAINIO_PUSH_BREAK:
918                         set_break_key(val_b);
919                         break;
920                 case FM7_MAINIO_SUB_ATTENTION:
921                         set_sub_attention(val_b);
922                         break;
923                         // FD05
924                 case FM7_MAINIO_SUB_BUSY:
925                         sub_busy = val_b;
926                         break;
927                 case FM7_MAINIO_EXTDET:
928                         extdet_neg = !val_b;
929                         break;
930                 case FM7_MAINIO_BEEP:
931                   //beep_flag = true;
932                         if(event_beep < 0) register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
933                         pcm1bit->write_signal(SIG_PCM1BIT_ON, 1, 1);
934                         register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
935                         break;
936                 case FM7_MAINIO_JOYPORTA_CHANGED:
937                         joyport_a = data & mask;
938                         break;
939                 case FM7_MAINIO_JOYPORTB_CHANGED:
940                         joyport_b = data & mask;
941                         break;
942                 case FM7_MAINIO_PSG_IRQ:
943                         break;
944                 case FM7_MAINIO_OPN_IRQ:
945                         intstat_opn = val_b;
946                         do_irq(val_b);
947                         break;
948                 case FM7_MAINIO_WHG_IRQ:
949                         intstat_whg = val_b;
950                         do_irq(val_b);
951                         break;
952                 case FM7_MAINIO_THG_IRQ:
953                         intstat_thg = val_b;
954                         do_irq(val_b);
955                         break;
956                 case FM7_MAINIO_FDC_DRQ:
957                         set_drq_mfd(val_b);
958                         break;
959                 case FM7_MAINIO_FDC_IRQ:
960                         set_irq_mfd(val_b);
961                         break;
962         }
963         
964 }
965
966
967 uint8 FM7_MAINIO::fdc_getdrqirq(void)
968 {
969         return irqstat_fdc;
970 }
971
972  uint8 FM7_MAINIO::get_irqstat_fd03(void)
973 {
974         uint8 val;
975         bool extirq = false;
976         
977         extirq = fdc_irq | intstat_opn | intstat_whg | intstat_thg;
978         
979         //extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
980         if(extirq) {
981                 irqstat_reg0 &= 0b11110111;
982                 //do_irq(false);
983         } else {
984                 irqstat_reg0 |= 0b00001000;
985         }
986         set_irq_timer(false);
987         set_irq_printer(false);
988         val = irqstat_reg0;
989         return val;
990 }
991
992 uint8 FM7_MAINIO::get_extirq_fd17(void)
993 {
994         uint8 val = 0xff;
995         if(intstat_opn)   val &= 0b11110111;
996         if(intstat_mouse) val &= 0b11111011;
997         //if(intstat_opn || intstat_mouse) do_irq(false);
998         return val;
999 }
1000
1001 void FM7_MAINIO::set_ext_fd17(uint8 data)
1002 {
1003         if((data & 0b00000100) != 0) {
1004                 mouse_enable = true;
1005         } else {
1006                 mouse_enable = false;
1007         }
1008    
1009 }
1010
1011
1012 uint8 FM7_MAINIO::get_extirq_whg(void)
1013 {
1014         uint8 val = 0xff;
1015         if(intstat_whg) val &= ~0x08;
1016         return val;
1017 }
1018
1019 uint8 FM7_MAINIO::get_extirq_thg(void)
1020 {
1021         uint8 val = 0xff;
1022         if(intstat_thg) val &= ~0x08;
1023         return val;
1024 }
1025
1026
1027 /* FDD */
1028
1029 void FM7_MAINIO::set_fdc_cmd(uint8 val)
1030 {
1031         if(!connect_fdc) return;
1032         fdc_cmdreg = val;
1033         fdc->write_io8(0, val & 0x00ff);
1034 }
1035
1036 uint8 FM7_MAINIO::get_fdc_stat(void)
1037 {
1038         if(!connect_fdc) return 0xff;
1039         //this->write_signal(FM7_MAINIO_FDC_IRQ, 0, 1);
1040         fdc_statreg =  fdc->read_io8(0);
1041         return fdc_statreg;
1042 }
1043
1044 void FM7_MAINIO::set_fdc_track(uint8 val)
1045 {
1046         if(!connect_fdc) return;
1047         // if mode is 2DD and type-of-image = 2D then val >>= 1;
1048         fdc_trackreg = val;
1049         fdc->write_io8(1, val & 0x00ff);
1050 }
1051
1052 uint8 FM7_MAINIO::get_fdc_track(void)
1053 {
1054         if(!connect_fdc) return 0xff;
1055         fdc_trackreg = fdc->read_io8(1);
1056         return fdc_trackreg;
1057 }
1058
1059 void FM7_MAINIO::set_fdc_sector(uint8 val)
1060 {
1061         if(!connect_fdc) return;
1062         fdc_sectreg = val;
1063         fdc->write_io8(2, val & 0x00ff);
1064 }
1065
1066 uint8 FM7_MAINIO::get_fdc_sector(void)
1067 {
1068         if(!connect_fdc) return 0xff;
1069         fdc_sectreg = fdc->read_io8(2);
1070         return fdc_sectreg;
1071 }
1072   
1073 void FM7_MAINIO::set_fdc_data(uint8 val)
1074 {
1075         if(!connect_fdc) return;
1076         fdc_datareg = val;
1077         fdc->write_io8(3, val & 0x00ff);
1078 }
1079
1080 uint8 FM7_MAINIO::get_fdc_data(void)
1081 {
1082         if(!connect_fdc) return 0xff;
1083         fdc_datareg = fdc->read_io8(3);
1084         return fdc_datareg;
1085 }
1086
1087 uint8 FM7_MAINIO::get_fdc_motor(void)
1088 {
1089         uint8 val = 0x00;
1090         if(!connect_fdc) return 0xff;
1091         if(fdc_motor) val = 0x80;
1092         val = val | (fdc_drvsel & 0x03);
1093         return val;
1094 }
1095   
1096 void FM7_MAINIO::set_fdc_fd1c(uint8 val)
1097 {
1098         if(!connect_fdc) return;
1099         fdc_headreg = (val & 0x01) | 0xfe;
1100         fdc->write_signal(SIG_MB8877_SIDEREG, val, 0x01);
1101 }
1102
1103 uint8 FM7_MAINIO::get_fdc_fd1c(void)
1104 {
1105         if(!connect_fdc) return 0xff;
1106         return fdc_headreg;
1107 }
1108
1109 void FM7_MAINIO::set_fdc_fd1d(uint8 val)
1110 {
1111         if(!connect_fdc) return;
1112         if((val & 0x80) != 0) {
1113                 fdc_motor = true;
1114         } else {
1115                 fdc_motor = false;
1116         }
1117         //      fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x07);
1118         fdc->write_signal(SIG_MB8877_DRIVEREG, val, 0x03);
1119         fdc->write_signal(SIG_MB8877_MOTOR, val, 0x80);
1120         fdc_drvsel = val;
1121 }
1122    
1123 uint32 FM7_MAINIO::read_signal(uint32 addr)
1124 {
1125         uint32 retval = 0xffffffff;
1126         switch(addr) {
1127         }
1128         return retval;
1129 }
1130
1131 uint32 FM7_MAINIO::read_data8(uint32 addr)
1132 {
1133         if(addr == FM7_MAINIO_IS_BASICROM) {
1134                 uint32 retval = 0;
1135                 if(stat_bootsw_basic) retval = 0xffffffff;
1136                 return retval;
1137         } else if(addr == FM7_MAINIO_BOOTMODE) {
1138                 uint32 retval = bootmode & 0x03;
1139 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
1140                 if(bootram) retval = 4;
1141 #endif
1142                 return retval;
1143         } else if(addr == FM7_MAINIO_READ_FD0F) {
1144                 if(stat_romrammode) return 0xffffffff;
1145                 return 0;
1146         } else if(addr == FM7_MAINIO_CLOCKMODE) {
1147                 return (uint32)get_clockmode();
1148         }
1149 #if defined(HAS_MMR)    
1150         else if(addr == FM7_MAINIO_MMR_ENABLED) {
1151                 uint32 retval = (mmr_enabled) ? 0xffffffff:0x00000000;
1152                 return retval;
1153         } else if(addr == FM7_MAINIO_WINDOW_ENABLED) {
1154                 uint32 retval = (window_enabled) ? 0xffffffff:0x00000000;
1155                 return retval;
1156         } else if(addr == FM7_MAINIO_MMR_SEGMENT) {
1157                 uint32 retval = (uint32) mmr_segment;
1158                 return retval;
1159         } else if((addr >= FM7_MAINIO_MMR_BANK) &&  (addr < (FM7_MAINIO_MMR_BANK + 64))) {
1160                 uint32 retval = (uint32)mmr_table[addr - FM7_MAINIO_MMR_BANK];
1161                 return retval;
1162         }
1163 #endif
1164 #if defined(_FM77AV_VARIANTS)
1165         else if(addr == FM7_MAINIO_INITROM_ENABLED) {
1166         }
1167 #endif
1168 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1169         else if(addr == FM7_MAINIO_EXTBANK) {
1170         } else if(addr == FM7_MAINIO_EXTROM) {
1171         }
1172 #endif
1173         //addr = addr & 0xff; //
1174         //      printf("Main I/O READ: %04x\n", addr);
1175         switch(addr) {
1176                 case 0x00: // FD00
1177                 case 0x100: // D400 (SUB)
1178                         return (uint32) get_port_fd00();
1179                         break;
1180                 case 0x01: // FD01
1181                 case 0x101: // D401
1182                         display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 0, 1);
1183                         set_irq_keyboard(false);
1184                         return (uint32) kbd_bit7_0;
1185                         break;
1186                 case 0x02: // FD02
1187                         return (uint32) get_port_fd02();
1188                         break;
1189                 case 0x03: // FD03
1190                         return (uint32) get_irqstat_fd03();
1191                         break;
1192                 case 0x04: // FD04
1193                         return (uint32) get_fd04();
1194                         break;
1195                 case 0x05: // FD05
1196                         return (uint32) get_fd05();
1197                         break;
1198                 case 0x06: // RS-232C
1199                 case 0x07:
1200                         return 0xff;
1201                         break;
1202                 case 0x08: // Light pen
1203                 case 0x09:
1204                 case 0x0a:
1205                         return 0xff;
1206                         break;
1207                 case 0x0d:
1208                         return 0xff;
1209                         break;
1210                 case 0x0e:
1211                         return (uint32) get_psg();
1212                         break;
1213                 case 0x0f: // FD0F
1214                         read_fd0f();
1215                         return 0x00ff;
1216                         break;
1217                 case 0x15: // OPN CMD
1218                         return (uint32) 0xff;
1219                         break;
1220                 case 0x16: // OPN DATA
1221                         return (uint32) get_opn(0);
1222                         break;
1223                 case 0x17:
1224                         return (uint32) get_extirq_fd17();
1225                         break;
1226                 case 0x18: // FDC: STATUS
1227                         return (uint32) get_fdc_stat();
1228                         break;
1229                 case 0x19: // FDC: Track
1230                         return (uint32) get_fdc_track();
1231                         break;
1232                 case 0x1a: // FDC: Sector
1233                         return (uint32) get_fdc_sector();
1234                         break;
1235                 case 0x1b: // FDC: Data
1236                         return (uint32) get_fdc_data();
1237                         break;
1238                 case 0x1c:
1239                         return (uint32) get_fdc_fd1c();
1240                         break;
1241                 case 0x1d:
1242                         return (uint32) get_fdc_motor();
1243                         break;
1244                 case 0x1f:
1245                         return (uint32) fdc_getdrqirq();
1246                         break;
1247                 case 0x22: // Kanji ROM
1248                         return (uint32) read_kanjidata_left();
1249                         break;
1250                 case 0x23: // Kanji ROM
1251                         return (uint32) read_kanjidata_right();
1252                         break;
1253 #if defined(_FM77AV_VARIANTS)
1254                 case 0x2e: // Kanji ROM Level2
1255                         return (uint32) read_kanjidata_left_l2();
1256                         break;
1257                 case 0x2f: // Kanji ROM Level2
1258                         return (uint32) read_kanjidata_right_l2();
1259                         break;
1260 #endif
1261                 case 0x37: // Multi page
1262                         return (uint32)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
1263                         break;
1264                 case 0x45: // WHG CMD
1265                         return (uint32) 0xff;
1266                         break;
1267                 case 0x46: // WHG DATA
1268                         return (uint32) get_opn(1);
1269                         break;
1270                 case 0x47:
1271                         return (uint32) get_extirq_whg();
1272                         break;
1273                 case 0x51: // THG CMD
1274                         return (uint32) 0xff;
1275                         break;
1276                 case 0x52: // THG DATA
1277                         return (uint32) get_opn(2);
1278                         break;
1279                 case 0x53:
1280                         return (uint32) get_extirq_thg();
1281                         break;
1282                 default:
1283                         break;
1284         }
1285         if((addr < 0x40) && (addr >= 0x38)) {
1286                 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
1287                 return (uint32) display->read_data8(addr);
1288         }
1289         // Another:
1290         return 0xff;
1291 }
1292
1293 void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
1294 {
1295         if(addr == FM7_MAINIO_BOOTMODE) {
1296                 bootmode = data & 0x03;
1297                 return;
1298         } else if(addr == FM7_MAINIO_CLOCKMODE) {
1299                 set_clockmode((uint8)data);
1300                 return;
1301         }
1302         addr = addr & 0xff; //
1303         data = data & 0xff;
1304         switch(addr) {
1305                 case 0x00: // FD00
1306                         set_port_fd00((uint8)data);
1307                         return;
1308                         break;
1309                 case 0x01: // FD01
1310                         // set_lptdata_fd01((uint8)data);
1311                         break;
1312                 case 0x02: // FD02
1313                         set_port_fd02((uint8)data);
1314                         break;
1315                 case 0x03: // FD03
1316                         set_beep(data);
1317                         break;
1318                 case 0x04: // FD04
1319                         // set_flags_fd04(data);
1320                         break;
1321                 case 0x05: // FD05
1322                         set_fd05((uint8)data);
1323                         break;
1324                 case 0x06: // RS-232C
1325                 case 0x07:
1326                         break;
1327                 case 0x08: // Light pen
1328                 case 0x09:
1329                 case 0x0a:
1330                         break;
1331                 case 0x0d:
1332                         set_psg_cmd(data);
1333                         break;
1334                 case 0x0e:
1335                         set_psg(data);
1336                         break;
1337                 case 0x0f: // FD0F
1338                         write_fd0f();
1339                         break;
1340                 case 0x15: // OPN CMD
1341                         set_opn_cmd(0, data);
1342                         break;
1343                 case 0x16: // OPN DATA
1344                         set_opn(0, data);
1345                         break;
1346                 case 0x17:
1347                         set_ext_fd17((uint8)data);
1348                         break;
1349                 case 0x18: // FDC: COMMAND
1350                         set_fdc_cmd((uint8)data);
1351                         break;
1352                 case 0x19: // FDC: Track
1353                         set_fdc_track((uint8)data);
1354                         break;
1355                 case 0x1a: // FDC: Sector
1356                         set_fdc_sector((uint8)data);
1357                         break;
1358                 case 0x1b: // FDC: Data
1359                         set_fdc_data((uint8)data);
1360                         break;
1361                 case 0x1c:
1362                         set_fdc_fd1c((uint8)data);
1363                         break;
1364                 case 0x1d:
1365                         set_fdc_fd1d((uint8)data);
1366                         break;
1367                 case 0x1f: // ??
1368                         return;
1369                         break;
1370                 case 0x20: // Kanji ROM
1371                         write_kanjiaddr_hi((uint8)data);
1372                         break;
1373                 case 0x21: // Kanji ROM
1374                         write_kanjiaddr_lo((uint8)data);
1375                         break;
1376 #if defined(_FM77AV_VARIANTS)
1377                 case 0x2c: // Kanji ROM
1378                         write_kanjiaddr_hi_l2((uint8)data);
1379                         break;
1380                 case 0x2d: // Kanji ROM
1381                         write_kanjiaddr_lo_l2((uint8)data);
1382                         break;
1383 #endif
1384                 case 0x37: // Multi page
1385                         display->write_signal(SIG_FM7_SUB_MULTIPAGE, data, 0x00ff);
1386                         break;
1387                 case 0x45: // WHG CMD
1388                         set_opn_cmd(1, data);
1389                         break;
1390                 case 0x46: // WHG DATA
1391                         set_opn(1, data);
1392                         break;
1393                 case 0x47:
1394                         break;
1395                 case 0x51: // THG CMD
1396                         set_opn_cmd(2, data);
1397                         break;
1398                 case 0x52: // THG DATA
1399                         set_opn(2, data);
1400                         break;
1401                 case 0x53:
1402                         break;
1403 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
1404                 case 0x93:
1405                         if((data & 0x01) == 0) {
1406                                 boot_ram = false;
1407                         } else {
1408                                 boot_ram = true;
1409                         }         
1410                         if((data & 0x40) == 0) {
1411                                 window_enabled = false;
1412                         } else {
1413                                 window_enabled = true;
1414                         }         
1415                         if((data & 0x80) == 0) {
1416                                 mmr_enabled = false;
1417                         } else {
1418                                 mmr_enabled = true;
1419                         }
1420                         break;
1421 #endif
1422                 default:
1423                         break;
1424         }
1425         if((addr < 0x40) && (addr >= 0x38)) {
1426                 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1427                 display->write_data8(addr, (uint8)data);
1428                 return;
1429         }       // Another:
1430         return;
1431 }
1432
1433 void FM7_MAINIO::event_callback(int event_id, int err)
1434 {
1435 //      printf("MAIN EVENT id=%d\n", event_id);
1436         switch(event_id) {
1437                 case EVENT_BEEP_OFF:
1438                         beep_flag = false;
1439                         beep_snd = false;
1440                         if(event_beep >= 0) cancel_event(this, event_beep);
1441                         event_beep = -1;
1442                         pcm1bit->write_signal(SIG_PCM1BIT_ON, 0, 1);
1443                         break;
1444                 case EVENT_BEEP_CYCLE:
1445                         beep_snd = !beep_snd;
1446                         pcm1bit->write_signal(SIG_PCM1BIT_SIGNAL, beep_snd ? 1 : 0, 1);
1447                         break;
1448                 case EVENT_UP_BREAK:
1449                         set_break_key(false);
1450                         break;
1451                 case EVENT_TIMERIRQ_ON:
1452                         set_irq_timer(true);
1453                         //register_event(this, EVENT_TIMERIRQ_OFF, 2035.0 / 2.0, false, NULL); // TIMER OFF
1454                         break;
1455                 case EVENT_TIMERIRQ_OFF:
1456                         set_irq_timer(false);
1457                         //register_event(this, EVENT_TIMERIRQ_ON, 2035, false, NULL); // TIMER ON
1458                         break;
1459                 default:
1460                         break;
1461         }
1462 }
1463
1464