OSDN Git Service

[VM][FM7] Display sub system : more improve implement.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 24 Feb 2015 09:02:13 +0000 (18:02 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Tue, 24 Feb 2015 09:02:13 +0000 (18:02 +0900)
source/src/vm/fm7/display.cpp
source/src/vm/fm7/fm7_mainio.cpp

index 8bcc691..e6ef2a4 100644 (file)
@@ -18,76 +18,472 @@ extern "C" {
 
 DISPLAY::DISPLAY()
 {
-  initvramtbl_4096_vec();
+       initvramtbl_4096_vec();
 }
 
 void DISPLAY::getvram(uint32 *pvram, uint32 pitch)
 {
-  int y;
-  int height = (display_mode == DISPLAY_MODE_8_400L)? 400 : 200;
-  Uint32 *p;
-  Uint32 offset = 0x4000;
-  if(display_mode == DISPLAY_MODE_8_400L) offset = 0x8000;
+       int y;
+       int height = (display_mode == DISPLAY_MODE_8_400L) ? 400 : 200;
+       Uint32 *p;
+       Uint32 planesize = 0x4000;
+       uint32 offset;
+       
+       if(display_mode == DISPLAY_MODE_8_400L) planesize = 0x8000;
+#if defined(_FM77AV_VARIANTS)
+       if(offset_77av) {
+         offset = offset_point;
+       } else {
+         offset = offset_point & 0x7fff;
+       }
+#else
+       offset = offset_point & 0x7fff;
+#endif
+       if(display_mode != DISPLAY_MODE_8_400L) offset = offset & 0x3fff;
+       
+       
+       if(!crtflag) {
+         // Set blank
+               PutBlank(p, height);
+       } else if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_200L)) {
+               for(y = 0; y < height; y++) {
+                       p = &pvram[y * pitch];
+                       if(((y < window_low) && (y > window_high)) || (!window_opened)) {
+                               CreateVirtualVram8_Line(p, y, digital_palette, planesize, offset,multimode_dispmask);
+                       } else {
+                               CreateVirtualVram8_WindowedLine(p, y, window_xbegin, window_xend,
+                                                               digital_palette, planesize, offset, multimode_dispmask);
+                       }
+               }
+       } else if(display_mode == DISPLAY_MODE_4096) {
+               for(y = 0; y < height; y++) {
+                       p = &pvram[y * pitch];
+                       if(((y < window_low) && (y > window_high)) || (!window_opened)) {
+                               CreateVirtualVram4096_Line(p, y, offset, analog_palette, multimode_dispmask);
+                       } else {
+                               CreateVirtualVram4096_WindowedLine(p, y, window_xbegin, window_xend,
+                                                                  offset, analog_palette, multimode_dispmask);
+                       }
+               }
+       } else { // 256k
+               for(y = 0; y < height; y++) {
+                       p = &pvram[y * pitch];
+                       if(((y < window_low) && (y > window_high)) || (!window_opened)) {
+                               CreateVirtualVram256k_Line(p, y, offset, multimode_dispmask);
+                       } else {
+                               CreateVirtualVram256k_WindowedLine(p, y, offset, window_xbegin, window_xend,
+                                                                  multimode_dispmask);
+                       }
+               }
+       }      
+}
+
+void DISPLAY::set_multimode(uint8 val)
+{
+       multimode_accessmask = val & 0x07;
+       multimode_dispmask = (val & 0x70) >> 4;
+}
+
+uint8 DISPLAY::get_multimode(void)
+{
+       uint8 val = multimode_accessmask & 0x07;
+       val |= ((multimode_dispmask << 4) & 0x70);
+       return val;
+}
+
+uint8 DISPLAY::get_cpuaccessmask(void)
+{
+       return muitimode_accessmask & 0x07;
+}
+
+void DISPLAY::set_dpalette(uint32 addr, uint8 val)
+{
+       scrntype r, g, b;
+       addr &= 7;
+
+       dpalette_data[addr] = val | 0b11111000;
+       b =  ((val & 0x01) != 0x00)? 255 : 0x00;
+       r =  ((val & 0x02) != 0x00)? 255 : 0x00;
+       g =  ((val & 0x04) != 0x00)? 255 : 0x00;
+       dpalette_pixel[addr] = RGB_COLOR(r, g, b);
+}
+
+uint8 DISPLAY::get_dpalette(uint32 addr)
+{
+       uint8 data;
+       addr = addr & 7;
+       
+       data = dpalet_data[addr];
+       return data;
+}
+
+void DISPLAY::calc_apalette(uint32 index)
+{
+#if defined(_FM77AV_VARIANTS)
+       scrntype r, g, b;
+       r = (apalette_r[index] == 0)? 0 : apalette_r[index] << 4; // + 0x0f?
+       g = (apalette_g[index] == 0)? 0 : apalette_g[index] << 4; // + 0x0f?
+       b = (apalette_b[index] == 0)? 0 : apalette_b[index] << 4; // + 0x0f?
+       apalette_pixel[index] = RGB_COLOR(r, g, b);
+#endif
+}
+
+// FD34
+void DISPLAY::set_apalette_g(uint8 val)
+{
+#if defined(_FM77AV_VARIANTS)
+       uint32 index;
+       index = apalette_index & 0xfff;
+       apalette_g[index] = val & 0x0f;
+       calc_apalette(index);
+#endif
+}
+
+// FD33
+void DISPLAY::set_apalette_r(uint8 val)
+{
+#if defined(_FM77AV_VARIANTS)
+       uint32 index;
+       index = apalette_index & 0xfff;
+       apalette_r[index] = val & 0x0f;
+       calc_apalette(index);
+#endif
+}
+
+// FD32
+void DISPLAY::set_apalette_b(uint8 val)
+{
+#if defined(_FM77AV_VARIANTS)
+       uint32 index;
+       index = apalette_index & 0xfff;
+       apalette_b[index] = val & 0x0f;
+       calc_apalette(index);
+#endif
+}
+
+// FD30
+void DISPLAY::set_apalette_index_hi(uint8 val)
+{
+#if defined(_FM77AV_VARIANTS)
+       uint32 index = (uint32)val;
+       index &= 0x0f;
+       index <<= 8; // right?
+
+       apalette_index = (apalette_index & 0xff) | index;
+#endif
+}
+
+// FD31
+void DISPLAY::set_apalette_index_lo(uint8 val)
+{
+#if defined(_FM77AV_VARIANTS)
+       uint32 index = (uint32)val;
+       index &= 0xff;
+
+       apalette_index = (apalette_index & 0xf00) | index;
+#endif
+}
+
+//SUB:D409:R
+uint8 DISPLAY::set_vramaccess(void)
+{
+       vram_accessflag = true;
+       if(!is_cyclesteal) {
+               vram_cpuaccess = true;
+       } else {
+               vram_cpuaccess = false;
+               leave_display();
+       }
+       return 0xff;
+}
+
+//SUB:D409:W
+void DISPLAY::reset_vramaccess(void)
+{
+       vram_accessflag = false;
+       vram_cpuaccess = false;
+       leave_display();
+}
+
+//SUB:D40A:R
+uint8 DISPLAY::reset_subbusy(void)
+{
+       maincpu->write_signal(FM7_SUB_BUSY, 0x00, 0x01);
+       return 0xff;
+}
+
+//SUB:D40A:W
+void DISPLAY::set_subbusy(void)
+{
+       maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01);
+}
+
+//SUB:D430:R
+uint8 DISPLAY::get_miscreg(void)
+{
+       uint8 ret;
+#if defined(_FM77AV_VARIANTS)
+       ret = 0x00;
+       if(!hblank && !vblank) ret |= 0x80;
+       if(vsync) ret |= 0x40;
+       if(alu->read_signal(SIG_ALU_BUSY) == 0) ret |= 0x10;
+       if(subreset) ret |= 0x01;
+#else // 77 or older.
+       ret = 0xff;
+#endif
+       return ret;
+}
+//SUB:D430:W
+void DISPLAY::set_miscreg(uint8 val)
+{
   
-  if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_200L)) {
-    for(y = 0; y < height; y++) {
-      p = &pvram[y * pitch];
-      if(((y < window_low) && (y > window_high)) || (!window_opened)) {
-       CreateVirtualVram8_Line(p, y, digital_palette, offset, multimode_dispmask);
-      } else {
-       CreateVirtualVram8_WindowedLine(p, y, window_xbegin, window_xbegin, digital_palette, offset, multimode_dispmask);
-      }
-    }
-  } else if(display_mode == DISPLAY_MODE_4096) {
-    for(y = 0; y < height; y++) {
-      p = &pvram[y * pitch];
-      if(((y < window_low) && (y > window_high)) || (!window_opened)) {
-       CreateVirtualVram4096_Line(p, y, analog_palette, multimode_dispmask);
-      } else {
-       CreateVirtualVram4096_WindowedLine(p, y, window_xbegin, window_xbegin, analog_palette, multimode_dispmask);
-      }
+#if defined(_FM77AV40) || defined(_FM77AV40EX) || || defined(_FM77AV40SX)
+  nmi_enable = ((val & 0x80) == 0) ? true : false;
+#endif
+#if defined(_FM77AV_VARIANTS)
+  if((val & 0x40) == 0) {
+    if(display_page != 0) {
+      redrawreq();
     }
-  } else { // 256k
-    for(y = 0; y < height; y++) {
-      p = &pvram[y * pitch];
-      if(((y < window_low) && (y > window_high)) || (!window_opened)) {
-       CreateVirtualVram256k_Line(p, y, multimode_dispmask);
-      } else {
-       CreateVirtualVram256k_WindowedLine(p, y, window_xbegin, window_xbegin, multimode_dispmask);
-      }
+    display_page = 0;
+  } else {
+        if(display_page == 0) {
+      redrawreq();
     }
-  }      
+    display_page = 1;
+  }
+  active_page = ((val & 0x20) == 0) ? 0 : 1;
+  if((val & 0x04) == 0) {
+    offset_77av = false;
+  } else {
+    offset_77av = true;
+  }
+  submem->write_signal(SIG_FM7SUBMEM_CGROM, val, 0x03);
+#endif
+}
+void DISPLAY::enter_display(void)
+{
+       if(vram_cpuaccess) {
+               vram_wait = true;
+               subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
+       }
+}
+
+void DISPLAY::leave_display(void)
+{
+       vram_wait = false;
+       if(sub_run) {
+               subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
+       }
+}
+
+void DISPLAY::halt_subsystem(void)
+{
+       sub_run = false;
+       subcpu->write_signal(SIG_CPU_BUSREQ, 0x01, 0x01);
+       maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01); // BUSY
+}
+
+void DISPLAY::restart_subsystem(void)
+{
+       sub_run = true;
+       if(!vram_wait) subcpu->write_signal(SIG_CPU_BUSREQ, 0x00, 0x01);
+}
+
+//SUB:D408:R
+void DISPLAY::set_crtflag(void)
+{
+       crt_flag = true;
+}
+
+//SUB:D408:W
+void DISPLAY::reset_crtflag(void)
+{
+       crt_flag = false;
 }
 
-void set_multimode(uint8 val)
+//SUB:D402:R
+uint8 DISPLAY::cancel_irq(void)
 {
-  multimode_accessmask = val & 0x0f;
-  multimode_dispmask = (val & 0xf0) >> 4;
+       this->write_signal(SIG_FM7_SUB_CANCEL, 0x01, 0x01);
+       return 0xff;
 }
 
-uint8 get_multimode(void)
+//SUB:D403:R
+uint8 DISPLAY::beep(void)
 {
-  uint8 val = multimode_acdcessmask & 0x0f;
-  val |= ((multimode_dispmask << 4) & 0xf0);
-  return val;
+       mainio->write_signal(FM7_MAINIO_BEEP, 0x01, 0x01);
+       return 0xff; // True?
 }
 
-void set_dpalette(uint32 addr, uint8 val)
+
+// SUB:D404 : R 
+uint8 DISPLAY::attention_irq(void)
 {
-  addr &= 7;
+       mainio->write_signal(FM7_MAINIO_SUB_ATTENTION, 0x01, 0x01);
+       return 0xff;
+}
+
+// SUB:D405:W
+void DISPLAY::set_cyclesteal(uint8 val)
+{
+       val &= 0x01;
+       if(val != 0) {
+               is_cyclesteal = true;
+       } else {
+               is_cyclesteal = false;
+       }
+}
 
-  dpalet[addr][0] = ((val & 0x01) != 0x00)? 0x01 : 0x00;
-  dpalet[addr][1] = ((val & 0x02) != 0x00)? 0x01 : 0x00;
-  dpalet[addr][2] = ((val & 0x04) != 0x00)? 0x01 : 0x00;
-  dpalet[addr][3] = ((val & 0x08) != 0x00)? 0x01 : 0x00;
+
+
+// Main: FD13
+void DISPLAY::set_monitor_bank(uint8 var)
+{
+#if defined(_FM77AV_VARIANTS)
+       if(is_77av40) {
+               if((var & 0x04) != 0) {
+                       submem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x01, 0x01);
+               } else {
+                       submem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x00, 0x01);
+                       submem->write_signal(SIG_FM7SUBMEM_MONITOR_ROM, (uint32)var, 0x03);
+               }
+               subrom_bank = var & 0x07;
+       } else {
+               mem->write_signal(SIG_FM7SUBMEM_MONITOR_RAM, 0x00, 0x01);
+               submem->write_signal(SIG_FM7SUBMEM_MONITOR_ROM, (uint32)var, 0x03);
+               subrom_bank = var & 0x03;
+       }
+       subcpu_resetreq = true;
+       maincpu->write_signal(FM7_SUB_BUSY, 0x01, 0x01);
+#endif
 }
 
-uint8 get_dpalette(uint32 addr)
+// Timing values from XM7 . Thanks Ryu.
+void DISPLAY::event_callback(int event_id, int err)
 {
-  uint8 data;
-  addr = addr & 7;
+       double usec;
+       bool f;
+       switch(event_id) {
+               case EVENT_FM7SUB_DISPLAY_HALT:
+                       enter_display();
+                       usec = (2000000.0 / 3.0) / this->event->frame_rate(); // is this right?
+                       register_event(this, EVENT_FM7SUB_DISPLAY_RUN, usec, false, NULL); // NEXT CYCLE_
+                       break;
+               case EVENT_FM7SUB_DISPLAY_RUN:
+                       leave_display();
+                       usec = (1000000.0 / 3.0) / this->event->frame_rate(); // is this right?
+                       register_event(this, EVENT_FM7SUB_DISPLAY_HALT, usec, false, NULL); // NEXT CYCLE_
+                       break;
+               case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
+                       subcpu->write_signal(SIG_CPU_NMI, 0x01, 0x01);
+                       break;
+               case EVENT_FM7SUB_HDISP:
+                       hblank = false;
+                       usec = 39.5;
+                       if(is_400line) usec = 30.0;
+                       register_event(this, EVENT_FM7SUB_HBLANK, usec, false, NULL); // NEXT CYCLE_
+                       break;
+               case EVENT_FM7SUB_HBLANK:
+                       hblank = true;
+                       f = false;
+                       displine++;
+                       if(is_400line) {
+                               usec = 11.0;
+                               if(displine < 400) f = true; 
+                       } else {
+                               usec = 24.0;
+                               if(displine < 200) f = true;
+                       }
+                       if(f) {
+                               register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_
+                       } else {
+                               // Vblank?
+                               vblank = true;
+                               vsync = true;
+                               if(is_400line) {
+                                       usec = 0.31 * 1000.0;
+                               } else {
+                                       usec = 0.51 * 1000.0;
+                               }
+                               register_event(this, EVENT_FM7SUB_VSYNC, usec, false, NULL); // NEXT CYCLE_
+                       }
+                       break;
+               case EVENT_FM7SUB_VSTART: // Call first.
+                       vblank = false;
+                       vsync = false;
+                       hblank = true;
+                       displine = 0;
+                       if(is_400line) {
+                               usec = 11.0;
+                       } else {
+                               usec = 24.0;
+                       }
+                       register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_
+                       break;
+               case EVENT_FM7SUB_VSYNC:
+                       vblank = true;
+                       vsync = false;
+                       if(is_400line) {
+                               usec = 0.98 * 1000.0;
+                       } else {
+                               usec = 1.91 * 1000.0;
+                       }
+                       register_event(this, EVENT_FM7SUB_VSTART, usec, false, NULL); // NEXT CYCLE_
+                       break;
+       }
+}
 
-  data = (dpalet[addr][0] & 0x01) | ((dpalet[addr][1] & 0x01) << 1) |
-         ((dpalet[addr][2] & 0x01) << 2) | ((dpalet[addr][3] & 0x01) << 3);
-  return data;
+void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
+{
+       bool flag = ((data & mask) != 0);
+       switch(id) {
+               case SIG_FM7_SUB_HALT:
+                       if(flag) {
+                               halt_subsystem();
+                       } else {
+                               if(!sub_run) restart_subsytem();
+                               if(subcpu_resetreq) {
+                                 subcpu->reset();
+                                 subcpu_resetreq = false;
+                               }
+                       }
+                       break;
+               case SIG_FM7_SUB_CANCEL:
+                       if((flag) && (sub_run)) subcpu->write_signal(SIG_CPU_IRQ, 1, 1);
+                       break;
+#if defined(_FM77AV_VARIANTS)
+               case SIG_FM7_SUB_BANK: // Main: FD13
+                       set_monitor_bank(data & 0xff);
+                       break;
+#endif // _FM77AV_VARIANTS
+               case SIG_FM7_SUB_DPALETTE_ADDR: // Main: FD38-FD3F
+                       dpalette_addr = data & 0x07;
+                       break;
+               case SIG_FM7_SUB_DPALETTE_DATA: // Main: FD38-FD3F
+                       set_dpalette(dpalette_addr, (uint8)data & 0x07);
+                       break;
+               case SIG_FM7_SUB_MULTIPAGE:
+                       set_multimode(data & 0xff);
+                       break;
+#if defined(_FM77AV_VARIANTS)
+               case SIG_FM7_SUB_APALETTE_ADDR_HI:
+                       set_apalette_index_hi(data & 0xff);
+                       break;
+               case SIG_FM7_SUB_APALETTE_ADDR_LO:
+                       set_apalette_index_lo(data & 0xff);
+                       break;
+               case SIG_FM7_SUB_APALETTE_DATA_R:
+                       set_apalette_r(data & 0xff);
+                       break;
+               case SIG_FM7_SUB_APALETTE_DATA_G:
+                       set_apalette_g(data & 0xff);
+                       break;
+               case SIG_FM7_SUB_APALETTE_DATA_B:
+                       set_apalette_b(data & 0xff);
+                       break;
+#endif // _FM77AV_VARIANTS
+               default:
+                       break;
+       }
 }
index b2a5616..856d2c3 100644 (file)
@@ -208,8 +208,8 @@ void FM7_MAINIO::set_beep(uint32 data) // fd03
        beep->write_signal(SIG_BEEP_MUTE, data , 0b00000001);
        if((data & 0x40) != 0) {
          //            beep->write_signal(SIG_BEEP_ON, 0b01000000, 0b01000000);
-               // BEEP ON, after 200ms, BEEP OFF.  
-               register_event(this, EVENT_BEEP_OFF, 200.0 * 1000.0, false, NULL); // NEXT CYCLE
+               // BEEP ON, after 205ms, BEEP OFF.  
+               register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
        }
 }
 
@@ -322,8 +322,8 @@ void FM7_MAINIO::set_fd04(uint8 val)
 
  void FM7_MAINIO::set_fd05(uint8 val)
 {
-       subio->write_signal(SIG_SUBIO_HALT, val, 0b10000000);
-       subio->write_signal(SIG_SUBIO_IRQ, val, 0b01000000);
+       display->write_signal(SIG_FM7_SUB_HALT, val, 0b10000000);
+       display->write_signal(SIG_FM7_SUB_CANCEL, val, 0b01000000);
        if((val & 0b10000000) == 0) {
                sub_haltreq = false;
        } else {
@@ -338,6 +338,8 @@ void FM7_MAINIO::set_fd04(uint8 val)
        }
 }
 
+
+
 void FM7_MAINIO::set_extdet(bool flag)
 {
        extdet_neg = flag;
@@ -622,6 +624,7 @@ void FM7_MAINIO::write_signals(int id, uint32 data, uint32 mask)
                        break;
                case FM7_MAINIO_BEEP:
                        beep->write_signal(SIG_BEEP_ON, data, mask);
+                       register_event(this, EVENT_BEEP_OFF, 205.0 * 1000.0, false, NULL); // NEXT CYCLE
                        break;
                case FM7_MAINIO_OPNPORTA_CHANGED:
                        opnport_a = data & mask;
@@ -670,6 +673,7 @@ void FM7_MAINIO::write_signals(int id, uint32 data, uint32 mask)
        
 }
 
+
 uint8 FM7_MAINIO::fdc_getdrqirq(void)
 {
        return irqstat_fdc;
@@ -996,6 +1000,18 @@ void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
        return;
 }
 
+void FM7_MAINIO::event_callback(int event_id, int err)
+{
+       switch(event_id) {
+               case EVENT_BEEP_OFF:
+                       beep->write_signal(SIG_BEEP_ON, 0x00, 0x01);
+                       break;
+               default:
+                       break;
+       }
+}
+
+
 void VM::connect_bus(void)
 {
        int i;
@@ -1069,3 +1085,4 @@ void VM::connect_bus(void)
        maincpu->set_context_mem(mainmem);
        subcpu->set_context_mem(submem);
 }  
+