From 5a3e935a3e314015f2c78ef9f26f58685150b7ce Mon Sep 17 00:00:00 2001 From: ikari Date: Sat, 14 Jan 2012 01:21:21 +0100 Subject: [PATCH] FPGA: region override (patch register $213f) --- verilog/sd2snes/address.v | 18 +++++---- verilog/sd2snes/main.ucf | 22 +++++++++++ verilog/sd2snes/main.v | 77 ++++++++++++++++++++++++++++++++------- verilog/sd2snes/mcu_cmd.v | 8 +++- 4 files changed, 102 insertions(+), 23 deletions(-) diff --git a/verilog/sd2snes/address.v b/verilog/sd2snes/address.v index 8b50fa1..c833d97 100644 --- a/verilog/sd2snes/address.v +++ b/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 diff --git a/verilog/sd2snes/main.ucf b/verilog/sd2snes/main.ucf index 7ed7b66..64577df 100644 --- a/verilog/sd2snes/main.ucf +++ b/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; diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 7d3fc6b..e63a5db 100644 --- a/verilog/sd2snes/main.v +++ b/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; diff --git a/verilog/sd2snes/mcu_cmd.v b/verilog/sd2snes/mcu_cmd.v index 0c843eb..4ccd9e8 100644 --- a/verilog/sd2snes/mcu_cmd.v +++ b/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