OSDN Git Service

[VM][FM7] WIP: Implementing correct subsystem.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 15 Mar 2015 19:44:31 +0000 (04:44 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Sun, 15 Mar 2015 19:44:31 +0000 (04:44 +0900)
source/src/vm/fm7/display.cpp
source/src/vm/fm7/fm7.cpp
source/src/vm/fm7/fm7_mainio.cpp
source/src/vm/fm7/fm7_mainio.h
source/src/vm/fm7/fm7_mainmem.cpp
source/src/vm/mc6809.cpp

index bbc5b5e..6c7dba3 100644 (file)
@@ -79,7 +79,7 @@ void DISPLAY::reset(void)
 
        register_event(this, EVENT_FM7SUB_VSTART, 1.0 * 1000.0, false, &vstart_event_id);   
        register_event(this, EVENT_FM7SUB_DISPLAY_NMI, 20000.0, true, &nmi_event_id); // NEXT CYCLE_
-       subcpu->reset();
+//     subcpu->reset();
 }
 
 void DISPLAY::update_config(void)
@@ -326,24 +326,33 @@ uint8 DISPLAY::get_dpalette(uint32 addr)
 
 void DISPLAY::halt_subcpu(void)
 {
-       if(!(sub_run) || (vram_wait)) subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
-       halt_count = 0;
+       if(!(sub_run)) {
+               printf("SUB HALT\n");
+               if(halt_count == 0) subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
+               halt_count++;
+       }
+       if(halt_count >= 0x7ffffff0) halt_count = 0x7ffffff0; 
+       if(halt_count <= 0) halt_count = 0; 
 }
 
 void DISPLAY::go_subcpu(void)
 {
-       if((sub_run) && !(vram_wait)) subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
-       halt_count = 0;
+       if((sub_run) && (halt_count > 0)) {
+               printf("SUB RUN\n");
+               halt_count--;
+               if(halt_count == 0) subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
+       }
+       if(halt_count < 0) halt_count = 0;
 }
 
 void DISPLAY::enter_display(void)
 {
+       bool tmpf;
        if(is_cyclesteal) {
                vram_wait = false;
                return;
        }
        vram_wait = true;
-       halt_subcpu();
 }
 
 void DISPLAY::leave_display(void)
@@ -355,15 +364,21 @@ void DISPLAY::leave_display(void)
 void DISPLAY::halt_subsystem(void)
 {
        sub_run = false;
-       halt_subcpu();
-       mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x00, 0x01); // BUSY
+       if(!sub_run) {
+               halt_subcpu();
+               mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
+       }
 }
 
 void DISPLAY::restart_subsystem(void)
 {
        sub_run = true;
-       go_subcpu();
-       mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
+       if(sub_run) {
+               go_subcpu();
+//             mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
+       }
+//     go_subcpu();
+//     mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01); // BUSY
 }
 
 //SUB:D408:R
@@ -384,7 +399,7 @@ void DISPLAY::reset_crtflag(void)
 uint8 DISPLAY::acknowledge_irq(void)
 {
        this->do_irq(false);
-       if(!sub_run) mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01);
+       mainio->write_signal(FM7_MAINIO_SUB_BUSY, 0x01, 0x01);
        return 0xff;
 }
 
@@ -769,7 +784,7 @@ void DISPLAY::event_callback(int event_id, int err)
                        usec = 39.5;
                        if(display_mode == DISPLAY_MODE_8_400L) usec = 30.0;
                        register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
-                       if(vram_accessflag) enter_display();
+                       enter_display();
                        break;
                case EVENT_FM7SUB_HBLANK:
                        hblank = true;
@@ -856,13 +871,12 @@ void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
                        if(flag) {
                                if(sub_run) halt_subsystem();
                        } else {
-                               if(!sub_run) {
-                                       restart_subsystem();
-                                       if(subcpu_resetreq) {
-                                               vram_wrote = true;
-                                               subcpu->reset();
-                                               subcpu_resetreq = false;
-                                       }
+                               if(sub_run) return;   
+                               restart_subsystem();
+                               if(subcpu_resetreq) {
+                                       vram_wrote = true;
+                                       subcpu->reset();
+                                       subcpu_resetreq = false;
                                }
                        }
                        break;
@@ -1228,7 +1242,11 @@ void DISPLAY::write_data8(uint32 addr, uint32 data)
                                reset_vramaccess();
                                break;
                        case 0x0a:
-                               set_subbusy();
+                               if(data != 0) {
+                                       set_subbusy();
+                               } else {
+                                       reset_subbusy();
+                               }
                                break;
                        case 0x0d:
                                keyboard->write_signal(SIG_FM7KEY_SET_INSLED, 0x00, 0x01);
@@ -1242,10 +1260,10 @@ void DISPLAY::write_data8(uint32 addr, uint32 data)
 #endif
                                tmp_offset_point = (tmp_offset_point & 0x00ff) | rval;
                                offset_changed = !offset_changed;
-                               //if(offset_changed) {
+                               if(offset_changed) {
                                        offset_point = tmp_offset_point;
                                        vram_wrote = true;
-                               //}
+                               }
                                break;
                        case 0x0f:
 #if defined(_FM77AV_VARIANTS)
@@ -1256,10 +1274,10 @@ void DISPLAY::write_data8(uint32 addr, uint32 data)
 #endif
                                tmp_offset_point = (tmp_offset_point & 0x7f00) | rval;
                                offset_changed = !offset_changed;
-                               //if(offset_changed) {
+                               if(offset_changed) {
                                        offset_point = tmp_offset_point;
                                        vram_wrote = true;
-                               //}
+                               }
                                break;
                        default:
                                break;
index 8365f51..3a1c431 100644 (file)
@@ -245,15 +245,24 @@ void VM::update_config()
 #if !defined(_FM8)
        switch(config.cpu_type){
                case 0:
-                       event->set_cpu_clock(maincpu, MAINCLOCK_NORMAL);
-                       event->set_cpu_clock(subcpu,  SUBCLOCK_NORMAL);
+                       event->set_secondary_cpu_clock(maincpu, MAINCLOCK_NORMAL);
+                       if((config.dipswitch & 0x01) == 0) {
+                               event->set_secondary_cpu_clock(subcpu,  SUBCLOCK_NORMAL / 3);
+                       } else {
+                               event->set_secondary_cpu_clock(subcpu,  SUBCLOCK_NORMAL);
+                       }
                        break;
                case 1:
-                       event->set_cpu_clock(maincpu, MAINCLOCK_SLOW);
-                       event->set_cpu_clock(subcpu,  SUBCLOCK_SLOW);
+                       event->set_secondary_cpu_clock(maincpu, MAINCLOCK_SLOW);
+                       if((config.dipswitch & 0x01) == 0) {
+                               event->set_secondary_cpu_clock(subcpu,  SUBCLOCK_SLOW / 3);
+                       } else {
+                               event->set_secondary_cpu_clock(subcpu,  SUBCLOCK_SLOW);
+                       }
                        break;
        }
 #endif
+
        for(DEVICE* device = first_device; device; device = device->next_device) {
                device->update_config();
        }
index 33b4d58..1810fd1 100644 (file)
 
 void FM7_MAINIO::initialize(void)
 {
-#if defined(_FM8)
-       clock_fast = false;
-#else
-       clock_fast = true;
-#endif
-       //      connect_fdc = true;
        event_beep = -1;
        event_timerirq = -1;
        bootmode = config.boot_mode & 3;
-       register_event(this, EVENT_TIMERIRQ_ON, 4069.0 / 2.0, true, &event_timerirq); // TIMER IRQ
 #if defined(_FM77AV_VARIANTS)
        opn_psg_77av = true;
 #else
@@ -40,8 +33,8 @@ void FM7_MAINIO::reset(void)
        event_beep = -1;
        beep_snd = true;
        beep_flag = false;
-       register_event(this, EVENT_TIMERIRQ_ON, 4069.0 / 2.0, true, &event_timerirq); // TIMER IRQ
-       if(connect_fdc) fdc->reset();
+       extdet_neg = false;
+   
        stat_romrammode = true;
        bootmode = config.boot_mode & 3;
        if(bootmode == 0) { // IF BASIC BOOT THEN ROM
@@ -49,14 +42,35 @@ void FM7_MAINIO::reset(void)
        } else { // ELSE RAM
                stat_romrammode = false;
        }
+   
+       clock_fast = false;
+       if(config.cpu_type == 0) clock_fast = true;
+   
        pcm1bit->write_signal(SIG_PCM1BIT_MUTE, 0x01, 0x01);
        pcm1bit->write_signal(SIG_PCM1BIT_ON, 0x00, 0x01);
+   
        psg_data = 0;
        psg_cmdreg = 0;
        psg_address = 0;
        connect_opn = connect_whg = connect_thg = false;
        if(opn_psg_77av) connect_opn = true;
 
+       irqmask_reg0 = 0x00;
+       // FD03
+       irqmask_mfd = false;
+       irqmask_timer = false;
+       irqmask_printer = false;
+       irqmask_keyboard = false;
+       irqstat_reg0 = 0xff;
+       // FD04
+       //firq_break_key = false; // bit1, ON = '0'.
+       firq_sub_attention = false; // bit0, ON = '0'.
+       // FD05
+       sub_busy = false;
+       extdet_neg = false;
+       sub_haltreq = false;
+       sub_cancel = false; // bit6 : '1' Cancel req.
+
        switch(config.sound_device_type) {
                case 0:
                        break;
@@ -87,11 +101,130 @@ void FM7_MAINIO::reset(void)
                        connect_opn = true;
                        break;
        }
+       // Init OPN/PSG.
+       // Parameters from XM7.
+       for (i = 0; i < 14; i++) {
+               if (i == 7) {
+                       for(j = 0; j < 3; j++) {
+                               opn[j]->write_io8(0, i);
+                               opn[j]->write_io8(1, 0xff);
+                       }
+                       psg->write_io8(0, i);
+                       psg->write_io8(1, 0xff);
+               } else {
+                       for(j = 0; j < 3; j++) {
+                               opn[j]->write_io8(0, i);
+                               opn[j]->write_io8(1, 0x0);
+                       }
+                       psg->write_io8(0, i);
+                       psg->write_io8(1, 0x0);
+               }
+       }
+   
+       /* MUL,DT */
+       for (i = 0x30; i < 0x40; i++) {
+               if ((i & 0x03) == 3) {
+                       continue;
+               }
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, i);
+                       opn[j]->write_io8(1, 0x0);
+               }
+               psg->write_io8(0, i);
+               psg->write_io8(1, 0x0);
+       }
+
+       /* TL=$7F */
+       for (i = 0x40; i < 0x50; i++) {
+               if ((i & 0x03) == 3) {
+                       continue;
+               }
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, i);
+                       opn[j]->write_io8(1, 0x7f);
+               }
+               psg->write_io8(0, i);
+               psg->write_io8(1, 0x7f);
+       }
+
+       /* AR=$1F */
+       for (i = 0x50; i < 0x60; i++) {
+               if ((i & 0x03) == 3) {
+                       continue;
+               }
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, i);
+                       opn[j]->write_io8(1, 0x1f);
+               }
+               psg->write_io8(0, i);
+               psg->write_io8(1, 0x1f);
+       }
+
+       /* Others */
+       for (i = 0x60; i < 0xb4; i++) {
+               if ((i & 0x03) == 3) {
+                       continue;
+               }
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, i);
+                       opn[j]->write_io8(1, 0x00);
+               }
+               psg->write_io8(0, i);
+               psg->write_io8(1, 0x00);
+       }
+
+       /* SL,RR */
+       for (i = 0x80; i < 0x90; i++) {
+               if ((i & 0x03) == 3) {
+                       continue;
+               }
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, i);
+                       opn[j]->write_io8(1, 0xff);
+               }
+               psg->write_io8(0, i);
+               psg->write_io8(1, 0xff);
+       }
+
+       /* Key Off */
+       for (i = 0; i < 3; i++) {
+               for(j = 0; j < 3; j++) {
+                       opn[j]->write_io8(0, 0x28);
+                       opn[j]->write_io8(1, i);
+               }
+               psg->write_io8(0, 0x28);
+               psg->write_io8(1, i);
+       }
+
+       /* Mode */
+       for(j = 0; j < 3; j++) {
+               opn[j]->write_io8(0, 0x27);
+               opn[j]->write_io8(1, 0);
+       }
+       psg->write_io8(0, 0x27);
+       psg->write_io8(1, 0);
+  
+   
        nmi_count = 0;
        irq_count = 0;
        firq_count = 0;
+   
+       fdc_statreg = 0x00;
+       fdc_cmdreg = 0x00;
+       fdc_trackreg = 0x00;
+       fdc_sectreg = 0x00;
+       fdc_datareg = 0x00;
+       fdc_headreg = 0x00;
+       fdc_drvsel = 0x00;
+       fdc_motor = false;
+       fdc_drq = false;
+       fdc_irq = false;
+       irqstat_fdc = 0;
+       if(connect_fdc) extdet_neg = true;
+   
+       register_event(this, EVENT_TIMERIRQ_ON, 4069.0 / 2.0, true, &event_timerirq); // TIMER IRQ
 
-//   maincpu->reset();
+       //maincpu->reset();
 }
 
 
index 9ee2c65..7935eff 100644 (file)
@@ -324,13 +324,6 @@ class FM7_MAINIO : public DEVICE {
                lpt_ackng_inv = false;
                lpt_error_inv = false;
                lpt_busy = false;
-               irqmask_reg0 = 0x00;
-               // FD03
-               irqmask_mfd = false;
-               irqmask_timer = false;
-               irqmask_printer = false;
-               irqmask_keyboard = false;
-               irqstat_reg0 = 0xff;
                // FD04
                stat_fdmode_2hd = false; //  R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
                stat_kanjirom = true;    //  R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
index 39d8255..3f49abf 100644 (file)
@@ -29,7 +29,7 @@ void FM7_MAINMEM::wait()
        if(waitfactor <= 0) return;
        waitcount++;
        if(waitcount >= waitfactor) {
-               maincpu->set_extra_clock(1);
+               if(maincpu != NULL) maincpu->set_extra_clock(1);
                waitcount = 0;
        }
 }
index 2b86c8c..601ef3e 100644 (file)
@@ -1208,10 +1208,10 @@ void MC6809::exg()
        uint8 tb;
 
        IMMBYTE(tb);
-       if((tb ^ (tb >> 4)) & 0x08) {
-               /* transfer $ff to both registers */
-               t1 = t2 = 0xffff;
-       } else {
+       //if((tb ^ (tb >> 4)) & 0x08) {
+       //      /* transfer $ff to both registers */
+       //      t1 = t2 = 0xffff;
+       //} else {
        switch((tb >> 4) & 15) {
                case  0: t1 = D;  break;
                case  1: t1 = X;  break;
@@ -1238,7 +1238,7 @@ void MC6809::exg()
                case 11: t2 = DP | 0xff00; break;
                default: t2 = 0xffff;
        }
-       }
+       //}
        switch((tb >> 4) & 15) {
                case  0: D = t2;  break;
                case  1: X = t2;  break;
@@ -1251,7 +1251,7 @@ void MC6809::exg()
                case 10: CC = (uint8)t2; break;
                case 11: DP = (uint8)t2; break;
        }
-       switch(tb&15) {
+       switch(tb & 15) {
                case  0: D = t1;  break;
                case  1: X = t1;  break;
                case  2: Y = t1;  break;
@@ -1272,10 +1272,10 @@ void MC6809::tfr()
        uint16 t;
 
        IMMBYTE(tb);
-       if((tb ^ (tb >> 4)) & 0x08) {
-               /* transfer $ff to register */
-               t = 0xffff;
-       } else {
+       //if((tb ^ (tb >> 4)) & 0x08) {
+       //      /* transfer $ff to register */
+       //      t = 0xffff;
+       //} else {
        switch((tb >> 4) & 15) {
                case  0: t = D;  break;
                case  1: t = X;  break;
@@ -1289,8 +1289,8 @@ void MC6809::tfr()
                case 11: t = DP | 0xff00; break;
                default: t = 0xffff;
        }
-       }
-       switch(tb&15) {
+       //}
+       switch(tb & 15) {
                case  0: D = t;  break;
                case  1: X = t;  break;
                case  2: Y = t;  break;