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 @@
-
+