123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- `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
|