Browse Source

FPGA: region override (patch register $213f)

ikari 12 years ago
parent
commit
5a3e935a3e
4 changed files with 102 additions and 23 deletions
  1. 11 7
      verilog/sd2snes/address.v
  2. 22 0
      verilog/sd2snes/main.ucf
  3. 63 14
      verilog/sd2snes/main.v
  4. 6 2
      verilog/sd2snes/mcu_cmd.v

+ 11 - 7
verilog/sd2snes/address.v

@@ -19,9 +19,10 @@
 //////////////////////////////////////////////////////////////////////////////////
 module address(
   input CLK,
-  input [3:0] featurebits,  // peripheral enable/disable
+  input [7:0] featurebits,  // peripheral enable/disable
   input [2:0] MAPPER,       // MCU detected mapper
   input [23:0] SNES_ADDR,   // requested address from SNES
+  input [7:0] SNES_PA,      // peripheral address from SNES
   output [23:0] ROM_ADDR,   // Address to request from SRAM0
   output ROM_SEL,           // enable SRAM0 (active low)
   output IS_SAVERAM,        // address/CS mapped as SRAM?
@@ -35,14 +36,16 @@ module address(
   input [14:0] bsx_regs,
   output dspx_enable,
   output dspx_dp_enable,
-  output dspx_a0
+  output dspx_a0,
+  output r213f_enable
 );
 
 parameter [2:0]
   FEAT_DSPX = 0,
   FEAT_ST0010 = 1,
   FEAT_SRTC = 2,
-  FEAT_MSU1 = 3
+  FEAT_MSU1 = 3,
+  FEAT_213F = 4
 ;
 
 wire [23:0] SRAM_SNES_ADDR;
@@ -223,10 +226,6 @@ assign dspx_a0 = featurebits[FEAT_DSPX]
                  ?SNES_ADDR[0]
                  :1'b1;
 
-//reg [7:0] dspx_dp_enable_r;
-//initial dspx_dp_enable_r = 8'b00000000;
-//always @(posedge CLK) dspx_dp_enable_r <= {dspx_dp_enable_r[6:0], dspx_dp_enable_w};
-//assign dspx_dp_enable = &dspx_dp_enable_r[5:2];
 assign dspx_dp_enable = dspx_dp_enable_w;
 
 reg [5:0] dspx_enable_r;
@@ -234,5 +233,10 @@ initial dspx_enable_r = 6'b000000;
 always @(posedge CLK) dspx_enable_r <= {dspx_enable_r[4:0], dspx_enable_w};
 assign dspx_enable = &dspx_enable_r[5:2];
 
+wire r213f_enable_w = (SNES_PA == 8'h3f);
+reg [5:0] r213f_enable_r;
+initial r213f_enable_r = 6'b000000;
+always @(posedge CLK) r213f_enable_r <= {r213f_enable_r[4:0], r213f_enable_w};
+assign r213f_enable = &r213f_enable_r[5:2] & featurebits[FEAT_213F];
 
 endmodule

+ 22 - 0
verilog/sd2snes/main.ucf

@@ -460,6 +460,28 @@ NET "SNES_READ" LOC = P115;
 NET "SNES_REFRESH" LOC = P155;
 NET "SNES_WRITE" LOC = P94;
 
+NET "SNES_PA[0]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[0]" LOC = P90;
+NET "SNES_PA[1]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[1]" LOC = P93;
+NET "SNES_PA[2]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[2]" LOC = P86;
+NET "SNES_PA[3]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[3]" LOC = P87;
+NET "SNES_PA[4]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[4]" LOC = P81;
+NET "SNES_PA[5]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[5]" LOC = P85;
+NET "SNES_PA[6]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[6]" LOC = P152;
+NET "SNES_PA[7]" IOSTANDARD = LVCMOS33;
+NET "SNES_PA[7]" LOC = P154;
+
+NET "SNES_PARD" IOSTANDARD = LVCMOS33;
+NET "SNES_PARD" LOC = P149;
+NET "SNES_PAWR" IOSTANDARD = LVCMOS33;
+NET "SNES_PAWR" LOC = P150;
+
 NET "SPI_MISO" LOC = P72;
 
 

+ 63 - 14
verilog/sd2snes/main.v

@@ -35,6 +35,10 @@ module main(
   output SNES_DATABUS_DIR,
   input SNES_SYSCLK,
 
+  input [7:0] SNES_PA,
+  input SNES_PARD,
+  input SNES_PAWR,
+  
   /* SRAM signals */
   /* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */
   inout [15:0] ROM_DATA,
@@ -124,7 +128,7 @@ wire [15:0] dspx_dat_data;
 wire [10:0] dspx_dat_addr;
 wire dspx_dat_we;
 
-wire [3:0] featurebits;
+wire [7:0] featurebits;
 
 wire [23:0] MAPPED_SNES_ADDR;
 wire ROM_ADDR0;
@@ -321,7 +325,8 @@ mcu_cmd snes_mcu_cmd(
   .featurebits_out(featurebits),
   .mcu_rrq(MCU_RRQ),
   .mcu_wrq(MCU_WRQ),
-  .mcu_rq_rdy(MCU_RDY)
+  .mcu_rq_rdy(MCU_RDY),
+  .region_out(mcu_region)
 );
 
 wire [7:0] DCM_STATUS;
@@ -334,17 +339,29 @@ my_dcm snes_dcm(
   .STATUS(DCM_STATUS)
 );
 
+my_dcm snes_dcm2(
+  .CLKIN(SNES_SYSCLK),
+  .CLKFX(SYSCLK2),
+  .RST(DCM_RST)
+);
+
 assign DCM_RST=0;
 
+reg [5:0] SNES_PARDr;
 reg [5:0] SNES_READr;
 reg [5:0] SNES_WRITEr;
 reg [5:0] SNES_CPU_CLKr;
 
+wire SNES_PARD_start = (SNES_PARDr == 6'b111110);
 wire SNES_RD_start = (SNES_READr == 6'b111110);
 wire SNES_WR_start = (SNES_WRITEr == 6'b111110);
 wire SNES_cycle_start = (SNES_CPU_CLKr[5:0] == 6'b000001);
 wire SNES_cycle_end = (SNES_CPU_CLKr[5:0] == 6'b111110);
 
+always @(posedge SYSCLK2) begin
+  SNES_PARDr <= {SNES_PARDr[4:0], SNES_PARD};
+end
+
 always @(posedge CLK2) begin
   SNES_READr <= {SNES_READr[4:0], SNES_READ};
   SNES_WRITEr <= {SNES_WRITEr[4:0], SNES_WRITE};
@@ -356,6 +373,7 @@ address snes_addr(
   .MAPPER(MAPPER),
   .featurebits(featurebits),
   .SNES_ADDR(SNES_ADDR), // requested address from SNES
+  .SNES_PA(SNES_PA),
   .ROM_ADDR(MAPPED_SNES_ADDR),   // Address to request from SRAM (active low)
   .ROM_SEL(ROM_SEL),     // which SRAM unit to access
   .IS_SAVERAM(IS_SAVERAM),
@@ -373,7 +391,8 @@ address snes_addr(
   //uPD77C25
   .dspx_enable(dspx_enable),
   .dspx_dp_enable(dspx_dp_enable),
-  .dspx_a0(DSPX_A0)
+  .dspx_a0(DSPX_A0),
+  .r213f_enable(r213f_enable)
 );
 
 parameter MODE_SNES = 1'b0;
@@ -414,11 +433,23 @@ assign BSX_SNES_DATA_IN = SNES_DATA;
 reg [7:0] SNES_DINr;
 reg [7:0] ROM_DOUTr;
 
-assign SNES_DATA = (!SNES_READ) ? (srtc_enable ? SRTC_SNES_DATA_OUT
+reg [7:0] r213fr;
+reg r213f_forceread;
+reg [2:0] r213f_delay;
+reg [1:0] r213f_state;
+initial r213fr = 8'h55;
+initial r213f_forceread = 0;
+initial r213f_state = 2'b01;
+initial r213f_delay = 3'b011;
+
+
+assign SNES_DATA = (r213f_enable & (!SNES_PARD ^ r213f_forceread)) ? r213fr
+                   :(!SNES_READ ^ r213f_forceread)
+                                ? (srtc_enable ? SRTC_SNES_DATA_OUT
                                   :dspx_enable ? DSPX_SNES_DATA_OUT
-											 :dspx_dp_enable ? DSPX_SNES_DATA_OUT
-											 :msu_enable ? MSU_SNES_DATA_OUT
-											 :bsx_data_ovr ? BSX_SNES_DATA_OUT
+                                  :dspx_dp_enable ? DSPX_SNES_DATA_OUT
+                                  :msu_enable ? MSU_SNES_DATA_OUT
+                                  :bsx_data_ovr ? BSX_SNES_DATA_OUT
                                   :SNES_DINr /*(ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8])*/) : 8'bZ;
 
 reg [3:0] ST_MEM_DELAYr;
@@ -446,14 +477,14 @@ assign MCU_RDY = RQ_MCU_RDYr;
 always @(posedge CLK2) begin
   if(MCU_RRQ) begin
     MCU_RD_PENDr <= 1'b1;
-	 RQ_MCU_RDYr <= 1'b0;
+    RQ_MCU_RDYr <= 1'b0;
   end else if(MCU_WRQ) begin
     MCU_WR_PENDr <= 1'b1;
-	 RQ_MCU_RDYr <= 1'b0;
+    RQ_MCU_RDYr <= 1'b0;
   end else if(STATE & (ST_MCU_RD_END | ST_MCU_WR_END)) begin
     MCU_RD_PENDr <= 1'b0;
-	 MCU_WR_PENDr <= 1'b0;
-	 RQ_MCU_RDYr <= 1'b1;
+    MCU_WR_PENDr <= 1'b0;
+    RQ_MCU_RDYr <= 1'b1;
   end
 end
 
@@ -470,7 +501,7 @@ always @(posedge CLK2) begin
 		  ROM_ADDRr <= MAPPED_SNES_ADDR;
 		  if(MCU_RD_PENDr) STATE <= ST_MCU_RD_ADDR;
 		  else if(MCU_WR_PENDr) STATE <= ST_MCU_WR_ADDR;
-        else STATE <= ST_IDLE;
+      else STATE <= ST_IDLE;
 		end
 		ST_SNES_RD_ADDR: begin
 		  STATE <= ST_SNES_RD_WAIT;
@@ -564,7 +595,22 @@ always @(posedge CLK2) begin
 		  STATE <= ST_IDLE;
 		end
 
-	 endcase
+    endcase
+  end
+end
+
+always @(posedge SYSCLK2) begin
+  if(SNES_PARD_start & r213f_enable) begin
+    r213f_forceread <= 1'b1;
+    r213f_delay <= 3'b001;
+    r213f_state <= 2'b10;
+  end else if(r213f_state == 2'b10) begin
+    r213f_delay <= r213f_delay - 1;
+    if(r213f_delay == 3'b000) begin
+      r213f_forceread <= 1'b0;
+      r213f_state <= 2'b01;
+      r213fr <= {SNES_DATA[7:5], mcu_region, SNES_DATA[3:0]};
+    end
   end
 end
 
@@ -595,12 +641,15 @@ assign SNES_DATABUS_OE = (dspx_enable | dspx_dp_enable) ? 1'b0 :
                          msu_enable ? 1'b0 :
                          bsx_data_ovr ? (SNES_READ & SNES_WRITE) :
                          srtc_enable ? (SNES_READ & SNES_WRITE) :
+                         r213f_enable & !SNES_PARD ? 1'b0 :
                          ((IS_ROM & SNES_CS)
                           |(!IS_ROM & !IS_SAVERAM & !IS_WRITABLE & !IS_FLASHWR)
                           |(SNES_READ & SNES_WRITE)
                          );
 
-assign SNES_DATABUS_DIR = !SNES_READ ? 1'b1 : 1'b0;
+assign SNES_DATABUS_DIR = (!SNES_READ | (!SNES_PARD & r213f_enable))
+                           ? 1'b1 ^ r213f_forceread
+                           : 1'b0;
 
 assign IRQ_DIR = 1'b0;
 assign SNES_IRQ = 1'bZ;

+ 6 - 2
verilog/sd2snes/mcu_cmd.v

@@ -91,8 +91,9 @@ module mcu_cmd(
   output reg dspx_reset_out,
 
   // feature enable
-  output reg [3:0] featurebits_out,
+  output reg [7:0] featurebits_out,
   
+  output reg region_out,
   // SNES sync/clk
   input snes_sysclk
 );
@@ -101,6 +102,7 @@ initial begin
   dspx_pgm_addr_out = 11'b00000000000;
   dspx_dat_addr_out = 10'b0000000000;
   dspx_reset_out = 1'b1;
+  region_out = 0;
 end
 
 wire [31:0] snes_sysclk_freq;
@@ -342,7 +344,9 @@ always @(posedge clk) begin
       8'hec: // release DSPx reset
         dspx_reset_out <= 1'b0;
       8'hed:
-        featurebits_out <= param_data[3:0];
+        featurebits_out <= param_data;
+      8'hee:
+        region_out <= param_data[0];
     endcase
   end
 end