OSDN Git Service

[VM][FM7] Add skelton of ALU.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 2 Mar 2015 09:04:44 +0000 (18:04 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Mon, 2 Mar 2015 09:04:44 +0000 (18:04 +0900)
source/src/vm/fm7/display.cpp

index e6ef2a4..4c78685 100644 (file)
@@ -29,23 +29,31 @@ void DISPLAY::getvram(uint32 *pvram, uint32 pitch)
        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;
+         offset = offset_point & 0x7fe0;
        }
 #else
-       offset = offset_point & 0x7fff;
+       offset = offset_point & 0x7fe0;
 #endif
-       if(display_mode != DISPLAY_MODE_8_400L) offset = offset & 0x3fff;
-       
+       if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_400L_TEXT)) {
+               planesize = 0x8000;
+       } else if((display_mode == DISPLAY_MODE_8_200L) || (display_mode == DISPLAY_MODE_8_200L_TEXT)) {
+               offset = offset & 0x3fff;
+       } else if((display_mode == DISPLAY_MODE_4096) || (display_mode == DISPLAY_MODE_256k)) {
+               planesize = 0x2000;
+               offset = offset & 0x1fff;
+       } else {
+               return;
+       }
        
        if(!crtflag) {
          // Set blank
                PutBlank(p, height);
-       } else if((display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_200L)) {
+       } else if((display_mode == DISPLAY_MODE_8_200L) || (display_mode == DISPLAY_MODE_8_200L_TEXT) ||
+                 (display_mode == DISPLAY_MODE_8_400L) || (display_mode == DISPLAY_MODE_8_400L_TEXT)) {
                for(y = 0; y < height; y++) {
                        p = &pvram[y * pitch];
                        if(((y < window_low) && (y > window_high)) || (!window_opened)) {
@@ -55,7 +63,9 @@ void DISPLAY::getvram(uint32 *pvram, uint32 pitch)
                                                                digital_palette, planesize, offset, multimode_dispmask);
                        }
                }
-       } else if(display_mode == DISPLAY_MODE_4096) {
+       }
+#if defined(_FM77AV_VARIANTS)
+       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)) {
@@ -65,7 +75,9 @@ void DISPLAY::getvram(uint32 *pvram, uint32 pitch)
                                                                   offset, analog_palette, multimode_dispmask);
                        }
                }
-       } else { // 256k
+       }
+#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       else { // 256k
                for(y = 0; y < height; y++) {
                        p = &pvram[y * pitch];
                        if(((y < window_low) && (y > window_high)) || (!window_opened)) {
@@ -75,7 +87,9 @@ void DISPLAY::getvram(uint32 *pvram, uint32 pitch)
                                                                   multimode_dispmask);
                        }
                }
-       }      
+       }
+#endif // _FM77AV40
+#endif //_FM77AV_VARIANTS
 }
 
 void DISPLAY::set_multimode(uint8 val)
@@ -238,27 +252,27 @@ void DISPLAY::set_miscreg(uint8 val)
 {
   
 #if defined(_FM77AV40) || defined(_FM77AV40EX) || || defined(_FM77AV40SX)
-  nmi_enable = ((val & 0x80) == 0) ? true : false;
+       nmi_enable = ((val & 0x80) == 0) ? true : false;
 #endif
 #if defined(_FM77AV_VARIANTS)
-  if((val & 0x40) == 0) {
-    if(display_page != 0) {
-      redrawreq();
-    }
-    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);
+       if((val & 0x40) == 0) {
+               if(display_page != 0) {
+                 redrawreq();
+               }
+               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)
@@ -305,7 +319,7 @@ void DISPLAY::reset_crtflag(void)
 //SUB:D402:R
 uint8 DISPLAY::cancel_irq(void)
 {
-       this->write_signal(SIG_FM7_SUB_CANCEL, 0x01, 0x01);
+       mainio->write_signal(SIG_FM7_SUB_CANCEL, 0x01, 0x01);
        return 0xff;
 }
 
@@ -363,17 +377,20 @@ void DISPLAY::set_monitor_bank(uint8 var)
 void DISPLAY::event_callback(int event_id, int err)
 {
        double usec;
+       uint64 haltclocks;
        bool f;
        switch(event_id) {
                case EVENT_FM7SUB_DISPLAY_HALT:
+                       if(is_cyclesteal || !(vram_cpuaccess)) break;
                        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_
+                       haltclocks =  2; // is this right?
+                       register_event(this, EVENT_FM7SUB_DISPLAY_RUN, haltclocks, false, &halt_event_id); // NEXT CYCLE_
                        break;
                case EVENT_FM7SUB_DISPLAY_RUN:
+                       if(is_cyclesteal || !(vram_cpuaccess)) break;
                        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_
+                       haltclocks =  1; // is this right?
+                       register_event(this, EVENT_FM7SUB_DISPLAY_RUN, haltclocks, false, &halt_event_id); // NEXT CYCLE_
                        break;
                case EVENT_FM7SUB_DISPLAY_NMI: // per 20.00ms
                        subcpu->write_signal(SIG_CPU_NMI, 0x01, 0x01);
@@ -382,7 +399,7 @@ void DISPLAY::event_callback(int event_id, int err)
                        hblank = false;
                        usec = 39.5;
                        if(is_400line) usec = 30.0;
-                       register_event(this, EVENT_FM7SUB_HBLANK, usec, false, NULL); // NEXT CYCLE_
+                       register_event(this, EVENT_FM7SUB_HBLANK, usec, false, &hblank_event_id); // NEXT CYCLE_
                        break;
                case EVENT_FM7SUB_HBLANK:
                        hblank = true;
@@ -396,7 +413,7 @@ void DISPLAY::event_callback(int event_id, int err)
                                if(displine < 200) f = true;
                        }
                        if(f) {
-                               register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_
+                               register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
                        } else {
                                // Vblank?
                                vblank = true;
@@ -406,7 +423,7 @@ void DISPLAY::event_callback(int event_id, int err)
                                } else {
                                        usec = 0.51 * 1000.0;
                                }
-                               register_event(this, EVENT_FM7SUB_VSYNC, usec, false, NULL); // NEXT CYCLE_
+                               register_event(this, EVENT_FM7SUB_VSYNC, usec, false, &vsync_event_id); // NEXT CYCLE_
                        }
                        break;
                case EVENT_FM7SUB_VSTART: // Call first.
@@ -419,7 +436,7 @@ void DISPLAY::event_callback(int event_id, int err)
                        } else {
                                usec = 24.0;
                        }
-                       register_event(this, EVENT_FM7SUB_HDISP, usec, false, NULL); // NEXT CYCLE_
+                       register_event(this, EVENT_FM7SUB_HDISP, usec, false, &hdisp_event_id); // NEXT CYCLE_
                        break;
                case EVENT_FM7SUB_VSYNC:
                        vblank = true;
@@ -429,7 +446,7 @@ void DISPLAY::event_callback(int event_id, int err)
                        } else {
                                usec = 1.91 * 1000.0;
                        }
-                       register_event(this, EVENT_FM7SUB_VSTART, usec, false, NULL); // NEXT CYCLE_
+                       register_event(this, EVENT_FM7SUB_VSTART, usec, false, &vstart_event_id); // NEXT CYCLE_
                        break;
        }
 }
@@ -440,17 +457,19 @@ void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
        switch(id) {
                case SIG_FM7_SUB_HALT:
                        if(flag) {
-                               halt_subsystem();
+                               if(sub_run) halt_subsystem();
                        } else {
-                               if(!sub_run) restart_subsytem();
-                               if(subcpu_resetreq) {
-                                 subcpu->reset();
-                                 subcpu_resetreq = false;
+                               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);
+                       if((flag) && (sub_run)) subcpu->write_signal(SIG_CPU_IRQ, 1, 1);
                        break;
 #if defined(_FM77AV_VARIANTS)
                case SIG_FM7_SUB_BANK: // Main: FD13
@@ -482,8 +501,224 @@ void DISPLAY::write_signal(int id, uint32 data, uint32 mask)
                case SIG_FM7_SUB_APALETTE_DATA_B:
                        set_apalette_b(data & 0xff);
                        break;
+               case SIG_FM7_SET_SUBMEM_ADDR:
+                       submem_addr = data & 0xffff;
+                       break;
+               case SIG_FM7_SET_SUBMEM_DATA:
+                       submem->write_signal(SIG_FM7_MEM_WRITE, data, 0xff);
+                       break;
 #endif // _FM77AV_VARIANTS
+               case SIG_FM7_SET_SHAREDMEM_ADDR:
+                       sharedmem_addr = (data >> 1) & 0x7f;
+                       break;
+               case SIG_FM7_SET_SHAREDMEM_DATA:
+                       submem->write_signal(SIG_FM7_SHAREDMEM_WRITE, data, 0xff);
+                       break;
+               case SIG_FM7_SUB_SET_OFFSET_HI:
+                       if(is_400line) { // 400line
+                               data = data & 0x7f;
+                       } else {
+                               data = data & 0x3f;
+                       }
+                       offset_point &= 0x00ff;
+                       offset_point = offset_point | (data << 8);
+                       break;
+               case SIG_FM7_SUB_SET_OFFSET_LO:
+                       if(!offset_77av) { // 400line
+                               data = data & 0xe0;
+                       }
+                       offset_point &= 0xff00;
+                       offset_point = offset_point | data;
+                       break;
                default:
                        break;
        }
 }
+                 
+// D410
+void DISPLAY::alu_write_cmdreg(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       alu->write_signal(SIG_FM7_ALU_CMDREG, data, 0x07);
+       alu->write_signal(SIG_FM7_ALU_MBITS, (data & 0x60) >> 5, 0x03);
+       alu->write_signal(SIG_FM7_ALU_EXEC, data, 0x80);
+}
+
+// D411
+void DISPLAY::alu_write_logical_color(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       alu->write_signal(SIG_FM7_ALU_LOGICAL_COLOR, data, 0x03);
+}
+
+// D412
+void DISPLAY::alu_write_mask_reg(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       alu->write_signal(SIG_FM7_ALU_WRITE_MASKREG, data, 0xff);
+       }
+
+// D413 - D41A
+void DISPLAY::alu_write_mask_reg(int addr, uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       addr = addr & 7;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       alu->write_signal(SIG_FM7_ALU_WRITE_CMPREG_ADDR, data, 0x07);
+}
+
+// D41B
+void DISPLAY::alu_write_disable_reg(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+  
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       data = data & 0x07 | 0x08;
+       alu->write_signal(SIG_FM7_ALU_BANK_DISABLE, data, 0xff);
+}
+
+// D41C - D41F
+void DISPLAY::alu_write_tilepaint_data(int addr, uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       switch(addr) {
+               case 0: // $D41C
+                       alu->write_signal(SIG_FM7_ALU_TILEPAINT_B, data, 0xff);
+                       break;
+               case 1: // $D41D
+                       alu->write_signal(SIG_FM7_ALU_TILEPAINT_R, data, 0xff);
+                       break;
+               case 2: // $D41E
+                       alu->write_signal(SIG_FM7_ALU_TILEPAINT_G, data, 0xff);
+                       break;
+               case 3: // xxxx
+                       //alu->write_signal(SIG_FM7_ALU_TILEPAINT_L, data, 0xff);
+                       alu->write_signal(SIG_FM7_ALU_TILEPAINT_L, 0xff, 0xff);
+                       break;
+       }
+}
+
+// D420
+void DISPLAY::alu_write_offsetreg_hi(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       uint32 addr;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       addr = alu->read_signal(SIG_FM7_ALU_OFFSET_REG); 
+       addr = addr & 0x00ff;
+       data <<= 8;
+       addr = addr | data;
+       alu->write_signal(SIG_FM7_ALU_OFFSET_REG, data, 0x1fff);
+}
+// D421
+void DISPLAY::alu_write_offsetreg_lo(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       uint32 addr;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       addr = alu->read_signal(SIG_FM7_ALU_OFFSET_REG); 
+       addr = addr & 0xff00;
+       addr = addr | data;
+       alu->write_signal(SIG_FM7_ALU_OFFSET_REG, data, 0x1fff);
+}
+
+// D422
+void DISPLAY::alu_write_linepattern_hi(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       uint32 addr;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       addr = alu->read_signal(SIG_FM7_ALU_LINEPATTERN_REG); 
+       addr = addr & 0x00ff;
+       data = data << 8;
+       addr = addr | data;
+       alu->write_signal(SIG_FM7_ALU_LINEPATTERN_REG, data, 0xffff);
+}
+
+// D423
+void DISPLAY::alu_write_linepattern_lo(uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       uint32 addr;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       addr = alu->read_signal(SIG_FM7_ALU_LINEPATTERN_REG); 
+       addr = addr & 0xff00;
+       addr = addr | data;
+       alu->write_signal(SIG_FM7_ALU_LINEPATTERN_REG, data, 0xffff);
+}
+
+// D424-D42B
+void DISPLAY::alu_write_line_position(int addr, uint8 val)
+{
+       bool busyflag;
+       uint32 data = (uint32)val;
+       busyflag = alu->read_signal(SIG_FM7_ALU_BUSYSTAT) ? true : false;
+       if(busyflag) return; // DISCARD
+       switch(addr) {
+               case 0:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_START_X_HIGH, data, 0x03); 
+                       break;
+               case 1:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_START_X_LOW, data, 0xff); 
+                       break;
+               case 2:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_START_Y_HIGH, data, 0x01); 
+                       break;
+               case 3:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_START_Y_LOW, data, 0xff); 
+                       break;
+               case 4:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_END_X_HIGH, data, 0x03); 
+                       break;
+               case 5:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_END_X_LOW, data, 0xff); 
+                       break;
+               case 6:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_END_Y_HIGH, data, 0x01); 
+                       break;
+               case 7:  
+                       alu->write_signal(SIG_FM7_ALU_LINEPOS_END_Y_LOW, data, 0xff); 
+                       break;
+       }
+}
+
+// D42E :  AV40
+void DISPLAY::select_sub_bank(uint8 val)
+{
+       submem->write_signal(SIG_FM7_SUBMEM_SELECT_KANJILEVEL2, val, 0x80);
+       submem->write_signal(SIG_FM7_SUBMEM_SELECT_BANK val, 0x1f);
+}
+
+// D42F
+void DISPLAY::select_vram_bank_av40(uint8 val)
+{
+       submem->write_signal(SIG_FM7_SUBMEM_AV40_SELECT_BANK val, 0x03);
+}
+
+
+