From 6b9acae5c2cf1e1b1e53cfd57d6936cfd152d16c Mon Sep 17 00:00:00 2001 From: ikari Date: Tue, 8 Feb 2011 00:51:49 +0100 Subject: [PATCH] BS-X support (FPGA) --- verilog/sd2snes/address.v | 46 +++- verilog/sd2snes/avr_cmd.v | 31 ++- verilog/sd2snes/bsx.v | 226 +++++++++++++++++ verilog/sd2snes/clk_test.v | 2 +- verilog/sd2snes/dac_test.v | 12 +- verilog/sd2snes/data.v | 9 +- verilog/sd2snes/dcm.v | 2 +- verilog/sd2snes/ipcore_dir/dac_buf.v | 2 +- verilog/sd2snes/ipcore_dir/dac_buf.xise | 311 +++++++++++++++++++++++- verilog/sd2snes/main.ucf | 3 +- verilog/sd2snes/main.v | 56 ++++- verilog/sd2snes/msu.v | 5 +- verilog/sd2snes/sd2snes.xise | 36 ++- 13 files changed, 708 insertions(+), 33 deletions(-) create mode 100644 verilog/sd2snes/bsx.v diff --git a/verilog/sd2snes/address.v b/verilog/sd2snes/address.v index 98ced2a..a6f7b40 100644 --- a/verilog/sd2snes/address.v +++ b/verilog/sd2snes/address.v @@ -28,13 +28,16 @@ module address( input MODE, // MCU(1) or SNES(0) ("bus phase") output IS_SAVERAM, // address/CS mapped as SRAM? output IS_ROM, // address mapped as ROM? + output IS_WRITABLE, // address somehow mapped as writable area? input [23:0] MCU_ADDR, // allow address to be set externally input ADDR_WRITE, output ROM_ADDR0, input [23:0] SAVERAM_MASK, input [23:0] ROM_MASK, input use_msu, - output msu_enable + output msu_enable, + output use_bsx, + input [14:0] bsx_regs ); wire [1:0] SRAM_BANK; @@ -46,6 +49,7 @@ wire [23:0] SRAM_ADDR_FULL; 000 HiROM 001 LoROM 010 ExHiROM (48-64Mbit) + 011 BS-X 110 brainfuck interleaved 96MBit Star Ocean =) 111 menu (ROM in upper SRAM) */ @@ -59,12 +63,15 @@ assign IS_ROM = ( (MAPPER == 3'b000) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) |(SNES_ADDR[22])) : (MAPPER == 3'b010) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) |(SNES_ADDR[22])) + : (MAPPER == 3'b011) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) + |(SNES_ADDR[22])) : (MAPPER == 3'b110) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) |(SNES_ADDR[22])) : (MAPPER == 3'b111) ? ((!SNES_ADDR[22] & SNES_ADDR[15]) |(SNES_ADDR[22])) : 1'b0); + assign IS_SAVERAM = ((MAPPER == 3'b000 || MAPPER == 3'b010 || MAPPER == 3'b110 || MAPPER == 3'b111) ? (!SNES_ADDR[22] & SNES_ADDR[21:20] & &SNES_ADDR[14:13] @@ -78,8 +85,35 @@ assign IS_SAVERAM = ((MAPPER == 3'b000 || MAPPER == 3'b010 || MAPPER == 3'b110 | & (SNES_ADDR[19:16] < 4'b1110) & !SNES_ADDR[15] & !SNES_CS) +/* BS-X: SRAM @ Bank 0x10-0x17 + Offset 5000-5fff */ + :(MAPPER == 3'b011) ? ((SNES_ADDR[23:19] == 5'b00010) + & (SNES_ADDR[15:12] == 4'b0101) + ) : 1'b0); + +assign IS_WRITABLE = IS_SAVERAM | ( + (MAPPER == 3'b011) + ? ( + (bsx_regs[3] && SNES_ADDR[23:20]==4'b0110) + |(!bsx_regs[5] && SNES_ADDR[23:20]==4'b0100) + |(!bsx_regs[6] && SNES_ADDR[23:20]==4'b0101) + |(SNES_ADDR[23:19] == 5'b01110) + |(SNES_ADDR[23:21] == 3'b001 && SNES_ADDR[15:13] == 3'b011)) + : 1'b0); + +/* BSX regs: + Index Function + 1 0=map flash to ROM area; 1=map PRAM to ROM area + 2 1=HiROM; 0=LoROM + 3 1=Mirror PRAM @60-6f:0000-ffff + 5 1=DO NOT mirror PRAM @40-4f:0000-ffff + 6 1=DO NOT mirror PRAM @50-5f:0000-ffff + 7 1=map BSX cartridge ROM @00-1f:8000-ffff + 8 1=map BSX cartridge ROM @80-9f:8000-ffff +*/ + assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR : ((MAPPER == 3'b000) ? (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) @@ -90,6 +124,15 @@ assign SRAM_ADDR_FULL = (MODE) ? MCU_ADDR :(MAPPER == 3'b010) ? (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) : ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]} & ROM_MASK)) + :(MAPPER == 3'b011) ? + (IS_SAVERAM ? 24'hE00000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]} + : IS_WRITABLE ? (24'h400000 + (SNES_ADDR & 24'h07FFFF)) + : ((bsx_regs[7] && SNES_ADDR[23:21] == 3'b000) + |(bsx_regs[8] && SNES_ADDR[23:21] == 3'b100)) + ? (24'h800000 + ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]} & 24'h0FFFFF)) + : ((bsx_regs[1] ? 24'h400000 : 24'h000000) + + bsx_regs[2] ? ({2'b00, SNES_ADDR[21:0]} & (ROM_MASK >> bsx_regs[1])) + : ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]} & (ROM_MASK >> bsx_regs[1])))) :(MAPPER == 3'b110) ? (IS_SAVERAM ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000) & SAVERAM_MASK) : (SNES_ADDR[15] ? ({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]}) @@ -106,5 +149,6 @@ assign ROM_SEL = 1'b0; // (MODE) ? CS_ARRAY[SRAM_BANK] : IS_SAVERAM ? 4'b1000 : assign ROM_ADDR0 = SRAM_ADDR_FULL[0]; //488888 assign msu_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000)); +assign use_bsx = (MAPPER == 3'b011); endmodule diff --git a/verilog/sd2snes/avr_cmd.v b/verilog/sd2snes/avr_cmd.v index 956c13d..801495b 100644 --- a/verilog/sd2snes/avr_cmd.v +++ b/verilog/sd2snes/avr_cmd.v @@ -71,6 +71,11 @@ module mcu_cmd( output [13:0] msu_ptr_out, output msu_reset_out, + // BS-X + output [7:0] bsx_regs_reset_out, + output [7:0] bsx_regs_set_out, + output bsx_regs_reset_we, + // SNES sync/clk input snes_sysclk ); @@ -102,6 +107,10 @@ reg [5:0] msu_status_reset_out_buf; reg msu_status_reset_we_buf; reg MSU_RESET_OUT_BUF; +reg [7:0] bsx_regs_set_out_buf; +reg [7:0] bsx_regs_reset_out_buf; +reg bsx_regs_reset_we_buf; + reg [31:0] SNES_SYSCLK_FREQ_BUF; reg [7:0] MCU_DATA_OUT_BUF; @@ -283,6 +292,19 @@ always @(posedge clk) begin 32'h4: MSU_RESET_OUT_BUF <= 1'b0; endcase + 8'he6: + case (spi_byte_cnt) + 32'h2: begin + bsx_regs_set_out_buf <= param_data[7:0]; + end + 32'h3: begin + bsx_regs_reset_out_buf <= param_data[7:0]; + bsx_regs_reset_we_buf <= 1'b1; + end + 32'h4: + bsx_regs_reset_we_buf <= 1'b0; + endcase + endcase end if (SD_DMA_NEXTADDR | (mcu_nextaddr & (cmd_data[7:5] == 3'h4) && (cmd_data[3]) && (spi_byte_cnt > (32'h1+cmd_data[4])))) begin @@ -301,9 +323,9 @@ always @(posedge clk) begin MCU_DATA_IN_BUF <= 8'hA5; else if (cmd_data[7:0] == 8'hF1) case (spi_byte_cnt[0]) - 1'b1: // buffer status + 1'b1: // buffer status (1st byte) MCU_DATA_IN_BUF <= {SD_DMA_STATUSr, DAC_STATUSr, MSU_STATUSr[6], 5'b0}; - 1'b0: // control status + 1'b0: // control status (2nd byte) MCU_DATA_IN_BUF <= {2'b0, MSU_STATUSr[5:0]}; endcase else if (cmd_data[7:0] == 8'hF2) @@ -389,6 +411,11 @@ assign msu_status_reset_out = msu_status_reset_out_buf; assign msu_status_set_out = msu_status_set_out_buf; assign msu_reset_out = MSU_RESET_OUT_BUF; assign msu_ptr_out = MSU_PTR_OUT_BUF; + +assign bsx_regs_reset_we = bsx_regs_reset_we_buf; +assign bsx_regs_reset_out = bsx_regs_reset_out_buf; +assign bsx_regs_set_out = bsx_regs_set_out_buf; + assign mcu_data_out = SD_DMA_STATUS ? SD_DMA_SRAM_DATA : MCU_DATA_OUT_BUF; assign mcu_mapper = MAPPER_BUF; assign mcu_sram_size = SRAM_SIZE_BUF; diff --git a/verilog/sd2snes/bsx.v b/verilog/sd2snes/bsx.v new file mode 100644 index 0000000..62cd0cc --- /dev/null +++ b/verilog/sd2snes/bsx.v @@ -0,0 +1,226 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: +// Engineer: +// +// Create Date: 02:43:54 02/06/2011 +// Design Name: +// Module Name: bsx +// Project Name: +// Target Devices: +// Tool versions: +// Description: +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module bsx( + input clkin, + input reg_oe, + input reg_we, + input [23:0] snes_addr, + input [7:0] reg_data_in, + output [7:0] reg_data_out, + input [7:0] reg_reset_bits, + input [7:0] reg_set_bits, + output [14:0] regs_out, + input pgm_we, + input [14:0] regs_in, + input use_bsx, + output data_ovr, + output flash_writable + ); + +wire [3:0] reg_addr = snes_addr[19:16]; // 00-0f:5000-5fff +wire [4:0] base_addr = snes_addr[4:0]; // 88-9f -> 08-1f +wire [15:0] flash_addr = snes_addr[15:0]; + +reg flash_ovr_r; +reg flash_we_r; +reg [16:0] flash_cmd0; +reg [24:0] flash_cmd5555; + +wire cart_enable = (use_bsx) && ((snes_addr[23:12] & 12'hf0f) == 12'h005); +wire base_enable = (use_bsx) && (!snes_addr[22] && (snes_addr[15:0] >= 16'h2188) + && (snes_addr[15:0] <= 16'h219f)); +wire flash_enable = (snes_addr[23:16] == 8'hc0); + +wire is_flash_special_address = (flash_addr == 16'h0002 + || flash_addr == 16'h5555 + || flash_addr == 16'h2aaa + || flash_addr == 16'h0000 + || (flash_addr >= 16'hff00 && flash_addr <= 16'hff13)); +wire flash_ovr = (use_bsx) && (flash_enable & flash_ovr_r) && is_flash_special_address; + +assign flash_writable = (use_bsx) && flash_enable && flash_we_r && !is_flash_special_address; +assign data_ovr = cart_enable | base_enable | flash_ovr; + +reg [5:0] reg_oe_sreg; +always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe}; +wire reg_oe_falling = (reg_oe_sreg[5:0] == 6'b100000); +wire reg_oe_rising = (reg_oe_sreg[5:0] == 6'b000001); + +reg [1:0] reg_we_sreg; +always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we}; +wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01); + +reg [1:0] pgm_we_sreg; +always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we}; +wire pgm_we_rising = (pgm_we_sreg[1:0] == 2'b01); + +reg [15:0] regs_tmpr; +reg [14:0] regs_outr; +reg [7:0] reg_data_outr; + +reg [7:0] base_regs[31:8]; +reg [4:0] bsx_counter; +reg [7:0] flash_vendor_data[7:0]; + +assign regs_out = regs_outr; +assign reg_data_out = reg_data_outr; + + +initial begin + regs_tmpr <= 16'b0_000000100000000; + regs_outr <= 15'b000000100000000; + bsx_counter <= 0; + base_regs[8] <= 0; + base_regs[9] <= 0; + base_regs[10] <= 0; + base_regs[11] <= 8'h9f; + base_regs[12] <= 8'h10; + base_regs[13] <= 8'h9f; + base_regs[14] <= 0; + base_regs[15] <= 0; + base_regs[16] <= 0; + base_regs[17] <= 8'h9f; + base_regs[18] <= 8'h01; + base_regs[19] <= 8'h9f; + base_regs[20] <= 0; + base_regs[21] <= 0; + base_regs[22] <= 8'h02; + base_regs[23] <= 8'hff; + base_regs[24] <= 8'h80; + base_regs[25] <= 8'h01; + base_regs[26] <= 0; + base_regs[27] <= 0; + base_regs[28] <= 0; + base_regs[29] <= 0; + base_regs[30] <= 0; + base_regs[31] <= 0; + flash_vendor_data[3'h0] <= 8'h4d; + flash_vendor_data[3'h1] <= 8'h00; + flash_vendor_data[3'h2] <= 8'h50; + flash_vendor_data[3'h3] <= 8'h00; + flash_vendor_data[3'h4] <= 8'h00; + flash_vendor_data[3'h5] <= 8'h00; + flash_vendor_data[3'h6] <= 8'h2a; + flash_vendor_data[3'h7] <= 8'h00; + flash_ovr_r <= 1'b0; + flash_we_r <= 1'b0; +end + + +always @(posedge clkin) begin + if(reg_oe_falling) begin + if(cart_enable) + reg_data_outr <= {regs_outr[reg_addr], 7'b0}; + else if(base_enable) begin + case(base_addr) + 5'b10010: begin + if(bsx_counter < 18) begin + bsx_counter <= bsx_counter + 1; + case (bsx_counter) + 5: + reg_data_outr <= 8'h1; + 6: + reg_data_outr <= 8'h1; + 10: + reg_data_outr <= 8'd42; + 11: + reg_data_outr <= 8'd30; + 12: + reg_data_outr <= 8'd18; + default: + reg_data_outr <= 8'h0; + endcase + end else begin + reg_data_outr <= 8'h0; + bsx_counter <= 0; + end + end + 5'b10011: + reg_data_outr <= base_regs[base_addr] & 8'h3f; + default: + reg_data_outr <= base_regs[base_addr]; + endcase + end else if (flash_enable) begin + casex (flash_addr) + 16'h0002: + reg_data_outr <= 8'h80; + 16'h5555: + reg_data_outr <= 8'h80; + 16'b1111111100000xxx: + reg_data_outr <= flash_vendor_data[flash_addr&16'h0007]; + default: + reg_data_outr <= 8'h00; + endcase + end + end else if(pgm_we_rising) begin + regs_tmpr[8:1] <= (regs_tmpr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0]; + regs_outr[8:1] <= (regs_outr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0]; + end else if(reg_we_rising && cart_enable) begin + if(reg_addr == 4'he && reg_data_in[7]) + regs_outr <= regs_tmpr | 16'b0100000000000000; + else + regs_tmpr[reg_addr] <= reg_data_in[7]; + end else if(reg_we_rising && base_enable) begin + case(base_addr) + 5'b10001: begin + bsx_counter <= 0; + base_regs[base_addr] <= reg_data_in; + end + 5'b01111: begin + base_regs[base_addr-1] <= base_regs[base_addr]-(base_regs[base_addr-1] >> 1); + base_regs[base_addr] <= base_regs[base_addr] >> 1; + end + default: + base_regs[base_addr] <= reg_data_in; + endcase + end else if(reg_we_rising && flash_enable) begin + case(flash_addr) + 16'h0000: begin + flash_cmd0 <= {flash_cmd0[7:0], reg_data_in}; + if(flash_cmd0[7:0] == 8'h38 && reg_data_in == 8'hd0) + flash_ovr_r <= 1; + end + 16'h5555: begin + flash_cmd5555 <= {flash_cmd5555[15:0], reg_data_in}; + if(flash_cmd5555[15:0] == 16'haa55) begin + case (reg_data_in) + 8'hf0: begin + flash_ovr_r <= 0; + flash_we_r <= 0; + end + 8'ha0: begin + flash_ovr_r <= 1; + flash_we_r <= 1; + end + 8'h70: begin + flash_we_r <= 0; + end + endcase + end + end + 16'h2aaa: begin + flash_cmd5555 <= {flash_cmd5555[15:0], reg_data_in}; + end + endcase + end +end + +endmodule diff --git a/verilog/sd2snes/clk_test.v b/verilog/sd2snes/clk_test.v index 10b54cf..2298062 100644 --- a/verilog/sd2snes/clk_test.v +++ b/verilog/sd2snes/clk_test.v @@ -39,7 +39,7 @@ always @(posedge clk) sysclk_sreg <= {sysclk_sreg[0], sysclk}; wire sysclk_rising = (sysclk_sreg == 2'b01); always @(posedge clk) begin - if(sysclk_counter < 90315789) begin + if(sysclk_counter < 92000000) begin sysclk_counter <= sysclk_counter + 1; if(sysclk_rising) sysclk_value <= sysclk_value + 1; end else begin diff --git a/verilog/sd2snes/dac_test.v b/verilog/sd2snes/dac_test.v index 982c7a9..9122850 100644 --- a/verilog/sd2snes/dac_test.v +++ b/verilog/sd2snes/dac_test.v @@ -60,8 +60,8 @@ dac_buf snes_dac_buf ( .addra(pgm_address), // Bus [10 : 0] .dina(pgm_data), // Bus [7 : 0] .clkb(clkin), - .addrb(dac_address), // Bus [9 : 0] - .doutb(dac_data)); // Bus [15 : 0] + .addrb(dac_address), // Bus [8 : 0] + .doutb(dac_data)); // Bus [31 : 0] reg [15:0] cnt; reg [15:0] smpcnt; @@ -72,8 +72,10 @@ reg [15:0] smpshift; reg [15:0] smpdata; assign mclk = cnt[2]; // mclk = clk/8 -assign lrck = cnt[10]; // lrck = mclk/256 -wire sclk = cnt[5]; // sclk = lrck*32 +//assign lrck = cnt[10]; // lrck = mclk/512 +//wire sclk = cnt[5]; // sclk = lrck*32 +assign lrck = cnt[8]; // lrck = mclk/128 +wire sclk = cnt[3]; // sclk = lrck*32 reg [2:0] lrck_sreg; reg [2:0] sclk_sreg; @@ -96,7 +98,7 @@ initial begin smpcnt = 16'b0; lrck_sreg = 2'b11; sclk_sreg = 1'b0; - dac_address_r = 11'b0; + dac_address_r = 10'b0; vol_valid = 1'b0; vol_latch_reg = 1'b0; vol_reg = 8'h0; diff --git a/verilog/sd2snes/data.v b/verilog/sd2snes/data.v index 1a18cb2..ae12ebf 100644 --- a/verilog/sd2snes/data.v +++ b/verilog/sd2snes/data.v @@ -37,7 +37,10 @@ module data( input ROM_ADDR0, output [7:0] MSU_DATA_IN, input [7:0] MSU_DATA_OUT, - input msu_enable + output [7:0] BSX_DATA_IN, + input [7:0] BSX_DATA_OUT, + input msu_enable, + input bsx_data_ovr ); reg [7:0] SNES_IN_MEM; @@ -48,8 +51,10 @@ reg [7:0] MCU_OUT_MEM; wire [7:0] FROM_ROM_BYTE; assign MSU_DATA_IN = SNES_DATA; +assign BSX_DATA_IN = SNES_DATA; -assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : (msu_enable ? MSU_DATA_OUT : SNES_OUT_MEM)); +assign SNES_DATA = SNES_READ ? 8'bZ : (!MCU_OVR ? 8'h00 : (msu_enable ? MSU_DATA_OUT : + bsx_data_ovr ? BSX_DATA_OUT : SNES_OUT_MEM)); assign FROM_ROM_BYTE = (ROM_ADDR0 ? ROM_DATA[7:0] : ROM_DATA[15:8]); diff --git a/verilog/sd2snes/dcm.v b/verilog/sd2snes/dcm.v index 6399370..36a2409 100644 --- a/verilog/sd2snes/dcm.v +++ b/verilog/sd2snes/dcm.v @@ -37,7 +37,7 @@ module my_dcm ( .CLKFX_DIVIDE(1), // Can be any integer from 1 to 32 .CLKFX_MULTIPLY(4), // Can be any integer from 2 to 32 .CLKIN_DIVIDE_BY_2("FALSE"), // TRUE/FALSE to enable CLKIN divide by two feature - .CLKIN_PERIOD(44.289), // Specify period of input clock + .CLKIN_PERIOD(43.478), // Specify period of input clock .CLKOUT_PHASE_SHIFT("NONE"), // Specify phase shift of NONE, FIXED or VARIABLE .CLK_FEEDBACK("NONE"), // Specify clock feedback of NONE, 1X or 2X .DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), // SOURCE_SYNCHRONOUS, SYSTEM_SYNCHRONOUS or diff --git a/verilog/sd2snes/ipcore_dir/dac_buf.v b/verilog/sd2snes/ipcore_dir/dac_buf.v index cd050d4..f84343f 100644 --- a/verilog/sd2snes/ipcore_dir/dac_buf.v +++ b/verilog/sd2snes/ipcore_dir/dac_buf.v @@ -62,7 +62,7 @@ output [31 : 0] doutb; .C_ADDRB_WIDTH(9), .C_ALGORITHM(1), .C_BYTE_SIZE(9), - .C_COMMON_CLK(0), + .C_COMMON_CLK(1), .C_DEFAULT_DATA("0"), .C_DISABLE_WARN_BHV_COLL(0), .C_DISABLE_WARN_BHV_RANGE(0), diff --git a/verilog/sd2snes/ipcore_dir/dac_buf.xise b/verilog/sd2snes/ipcore_dir/dac_buf.xise index f973c82..fd21580 100644 --- a/verilog/sd2snes/ipcore_dir/dac_buf.xise +++ b/verilog/sd2snes/ipcore_dir/dac_buf.xise @@ -36,29 +36,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + diff --git a/verilog/sd2snes/main.ucf b/verilog/sd2snes/main.ucf index 0afd06b..7d8c046 100644 --- a/verilog/sd2snes/main.ucf +++ b/verilog/sd2snes/main.ucf @@ -1,5 +1,6 @@ NET "CLKIN" TNM_NET = "CLKIN"; -TIMESPEC TS_CLKIN = PERIOD "CLKIN" 22.579 MHz HIGH 50 %; +TIMESPEC TS_CLKIN = PERIOD "CLKIN" 23 MHz HIGH 50 %; +//TIMESPEC TS_CLKIN = PERIOD "CLKIN" 21.5 MHz HIGH 50 %; NET "SNES_CS" IOSTANDARD = LVCMOS33; NET "SNES_READ" IOSTANDARD = LVCMOS33; NET "SNES_WRITE" IOSTANDARD = LVCMOS33; diff --git a/verilog/sd2snes/main.v b/verilog/sd2snes/main.v index 11ad4e4..0e6c09a 100644 --- a/verilog/sd2snes/main.v +++ b/verilog/sd2snes/main.v @@ -37,6 +37,7 @@ module main( input SNES_SYSCLK, /* SRAM signals */ + /* Bus 1: PSRAM, 128Mbit, 16bit, 70ns */ inout [15:0] ROM_DATA, output [22:0] ROM_ADDR, output ROM_CE, @@ -44,7 +45,14 @@ module main( output ROM_WE, output ROM_BHE, output ROM_BLE, - + + /* Bus 2: SRAM, 4Mbit, 8bit, 45ns */ + inout [7:0] RAM_DATA, + output [18:0] RAM_ADDR, + output RAM_CE, + output RAM_OE, + output RAM_WE, + /* MCU signals */ input SPI_MOSI, inout SPI_MISO, @@ -97,6 +105,14 @@ wire [7:0] MSU_SNES_DATA_OUT; wire [5:0] msu_status_reset_bits; wire [5:0] msu_status_set_bits; +wire [14:0] bsx_regs; +wire [14:0] bsx_regs_in; +wire [7:0] BSX_SNES_DATA_IN; +wire [7:0] BSX_SNES_DATA_OUT; +wire [7:0] bsx_regs_reset_bits; +wire [7:0] bsx_regs_set_bits; + + //wire SD_DMA_EN; //SPI_DMA_CTRL; sd_dma snes_sd_dma(.CLK(CLK2), @@ -150,7 +166,22 @@ msu snes_msu ( .msu_address_ext(msu_ptr_addr), .msu_address_ext_write(msu_addr_reset) ); - + +bsx snes_bsx(.clkin(CLK2), + .use_bsx(use_bsx), + .pgm_we(bsx_regs_reset_we), + .snes_addr(SNES_ADDR), + .reg_data_in(BSX_SNES_DATA_IN), + .reg_data_out(BSX_SNES_DATA_OUT), + .reg_oe(SNES_READ), + .reg_we(SNES_WRITE), + .regs_out(bsx_regs), + .reg_reset_bits(bsx_regs_reset_bits), + .reg_set_bits(bsx_regs_set_bits), + .data_ovr(bsx_data_ovr), + .flash_writable(IS_FLASHWR) + ); + spi snes_spi(.clk(CLK2), .MOSI(SPI_MOSI), .MISO(SPI_MISO), @@ -212,7 +243,10 @@ mcu_cmd snes_mcu_cmd( .msu_addressrq(msu_addressrq_out), .msu_trackrq(msu_trackrq_out), .msu_ptr_out(msu_ptr_addr), - .msu_reset_out(msu_addr_reset) + .msu_reset_out(msu_addr_reset), + .bsx_regs_set_out(bsx_regs_set_bits), + .bsx_regs_reset_out(bsx_regs_reset_bits), + .bsx_regs_reset_we(bsx_regs_reset_we) ); // dcm1: dfs 4x @@ -310,13 +344,17 @@ address snes_addr( .MODE(MODE), // MCU(1) or SNES(0) ("bus phase") .IS_SAVERAM(IS_SAVERAM), .IS_ROM(IS_ROM), + .IS_WRITABLE(IS_WRITABLE), .MCU_ADDR(MCU_ADDR), .ROM_ADDR0(ROM_ADDR0), .SAVERAM_MASK(SAVERAM_MASK), .ROM_MASK(ROM_MASK), //MSU-1 .use_msu(use_msu), - .msu_enable(msu_enable) + .msu_enable(msu_enable), + //BS-X + .use_bsx(use_bsx), + .bsx_regs(bsx_regs) ); wire SNES_READ_CYCLEw; @@ -342,7 +380,10 @@ data snes_data(.CLK(CLK2), .ROM_ADDR0(ROM_ADDR0), .MSU_DATA_IN(MSU_SNES_DATA_IN), .MSU_DATA_OUT(MSU_SNES_DATA_OUT), - .msu_enable(msu_enable) + .BSX_DATA_IN(BSX_SNES_DATA_IN), + .BSX_DATA_OUT(BSX_SNES_DATA_OUT), + .msu_enable(msu_enable), + .bsx_data_ovr(bsx_data_ovr) ); parameter MODE_SNES = 1'b0; @@ -558,7 +599,7 @@ end // When in MCU mode, enable SRAM_WE according to MCU programming // else enable SRAM_WE according to state&cycle assign ROM_WE = !MCU_OVR ? MCU_WRITE - : ((!IS_SAVERAM & !MODE) | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]); + : ((!IS_FLASHWR & !IS_WRITABLE & !MODE) | ROM_WE_ARRAY[{SNES_WRITE_CYCLE, MCU_WRITE_CYCLE}][STATEIDX]); // When in MCU mode, enable SRAM_OE whenever not writing // else enable SRAM_OE according to state&cycle @@ -578,7 +619,8 @@ assign ROM_BLE = !ROM_WE ? !ROM_ADDR0 : 1'b0; //assign SRAM_WE = !MCU_ENA ? MCU_WRITE : 1'b1; //assign SNES_DATABUS_OE = (!IS_SAVERAM & SNES_CS) | (SNES_READ & SNES_WRITE); -assign SNES_DATABUS_OE = msu_enable ? 1'b0 : ((IS_ROM & SNES_CS) | (!IS_ROM & !IS_SAVERAM) | (SNES_READ & SNES_WRITE)); +assign SNES_DATABUS_OE = msu_enable ? 1'b0 : + bsx_data_ovr ? 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_DATA_TO_MEM = SNES_DATA_TO_MEM_ARRAY[SNES_WRITE_CYCLE][STATEIDX]; diff --git a/verilog/sd2snes/msu.v b/verilog/sd2snes/msu.v index cbaeef9..23cd0d4 100644 --- a/verilog/sd2snes/msu.v +++ b/verilog/sd2snes/msu.v @@ -103,10 +103,9 @@ msu_databuf snes_msu_databuf ( .addrb(msu_address), // Bus [13 : 0] .doutb(msu_data)); // Bus [7 : 0] -reg [7:0] msu_regs [7:0]; - -reg [7:0] data_out_r; +// reg [7:0] data_out_r; reg [7:0] data_in_r; +reg [7:0] data_out_r; assign reg_data_out = data_out_r; always @(posedge clkin) data_in_r <= reg_data_in; diff --git a/verilog/sd2snes/sd2snes.xise b/verilog/sd2snes/sd2snes.xise index 25d999d..aa7ef54 100644 --- a/verilog/sd2snes/sd2snes.xise +++ b/verilog/sd2snes/sd2snes.xise @@ -70,12 +70,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -308,12 +334,12 @@ - - + + - + @@ -342,7 +368,7 @@ - + @@ -455,7 +481,7 @@ - +