bsx.v 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 02:43:54 02/06/2011
  7. // Design Name:
  8. // Module Name: bsx
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21. module bsx(
  22. input clkin,
  23. input reg_oe,
  24. input reg_we,
  25. input [23:0] snes_addr,
  26. input [7:0] reg_data_in,
  27. output [7:0] reg_data_out,
  28. input [7:0] reg_reset_bits,
  29. input [7:0] reg_set_bits,
  30. output [14:0] regs_out,
  31. input pgm_we,
  32. input [14:0] regs_in,
  33. input use_bsx,
  34. output data_ovr,
  35. output flash_writable
  36. );
  37. wire [3:0] reg_addr = snes_addr[19:16]; // 00-0f:5000-5fff
  38. wire [4:0] base_addr = snes_addr[4:0]; // 88-9f -> 08-1f
  39. wire [15:0] flash_addr = snes_addr[15:0];
  40. reg flash_ovr_r;
  41. reg flash_we_r;
  42. reg [16:0] flash_cmd0;
  43. reg [24:0] flash_cmd5555;
  44. wire cart_enable = (use_bsx) && ((snes_addr[23:12] & 12'hf0f) == 12'h005);
  45. wire base_enable = (use_bsx) && (!snes_addr[22] && (snes_addr[15:0] >= 16'h2188)
  46. && (snes_addr[15:0] <= 16'h219f));
  47. wire flash_enable = (snes_addr[23:16] == 8'hc0);
  48. wire is_flash_special_address = (flash_addr == 16'h0002
  49. || flash_addr == 16'h5555
  50. || flash_addr == 16'h2aaa
  51. || flash_addr == 16'h0000
  52. || (flash_addr >= 16'hff00 && flash_addr <= 16'hff13));
  53. wire flash_ovr = (use_bsx) && (flash_enable & flash_ovr_r) && is_flash_special_address;
  54. assign flash_writable = (use_bsx) && flash_enable && flash_we_r && !is_flash_special_address;
  55. assign data_ovr = cart_enable | base_enable | flash_ovr;
  56. reg [5:0] reg_oe_sreg;
  57. always @(posedge clkin) reg_oe_sreg <= {reg_oe_sreg[4:0], reg_oe};
  58. wire reg_oe_falling = (reg_oe_sreg[5:0] == 6'b100000);
  59. wire reg_oe_rising = (reg_oe_sreg[5:0] == 6'b000001);
  60. reg [1:0] reg_we_sreg;
  61. always @(posedge clkin) reg_we_sreg <= {reg_we_sreg[0], reg_we};
  62. wire reg_we_rising = (reg_we_sreg[1:0] == 2'b01);
  63. reg [1:0] pgm_we_sreg;
  64. always @(posedge clkin) pgm_we_sreg <= {pgm_we_sreg[0], pgm_we};
  65. wire pgm_we_rising = (pgm_we_sreg[1:0] == 2'b01);
  66. reg [15:0] regs_tmpr;
  67. reg [14:0] regs_outr;
  68. reg [7:0] reg_data_outr;
  69. reg [7:0] base_regs[31:8];
  70. reg [4:0] bsx_counter;
  71. reg [7:0] flash_vendor_data[7:0];
  72. assign regs_out = regs_outr;
  73. assign reg_data_out = reg_data_outr;
  74. initial begin
  75. regs_tmpr <= 16'b0_000000100000000;
  76. regs_outr <= 15'b000000100000000;
  77. bsx_counter <= 0;
  78. base_regs[8] <= 0;
  79. base_regs[9] <= 0;
  80. base_regs[10] <= 0;
  81. base_regs[11] <= 8'h9f;
  82. base_regs[12] <= 8'h10;
  83. base_regs[13] <= 8'h9f;
  84. base_regs[14] <= 0;
  85. base_regs[15] <= 0;
  86. base_regs[16] <= 0;
  87. base_regs[17] <= 8'h9f;
  88. base_regs[18] <= 8'h01;
  89. base_regs[19] <= 8'h9f;
  90. base_regs[20] <= 0;
  91. base_regs[21] <= 0;
  92. base_regs[22] <= 8'h02;
  93. base_regs[23] <= 8'hff;
  94. base_regs[24] <= 8'h80;
  95. base_regs[25] <= 8'h01;
  96. base_regs[26] <= 0;
  97. base_regs[27] <= 0;
  98. base_regs[28] <= 0;
  99. base_regs[29] <= 0;
  100. base_regs[30] <= 0;
  101. base_regs[31] <= 0;
  102. flash_vendor_data[3'h0] <= 8'h4d;
  103. flash_vendor_data[3'h1] <= 8'h00;
  104. flash_vendor_data[3'h2] <= 8'h50;
  105. flash_vendor_data[3'h3] <= 8'h00;
  106. flash_vendor_data[3'h4] <= 8'h00;
  107. flash_vendor_data[3'h5] <= 8'h00;
  108. flash_vendor_data[3'h6] <= 8'h2a;
  109. flash_vendor_data[3'h7] <= 8'h00;
  110. flash_ovr_r <= 1'b0;
  111. flash_we_r <= 1'b0;
  112. end
  113. always @(posedge clkin) begin
  114. if(reg_oe_falling) begin
  115. if(cart_enable)
  116. reg_data_outr <= {regs_outr[reg_addr], 7'b0};
  117. else if(base_enable) begin
  118. case(base_addr)
  119. 5'b10010: begin
  120. if(bsx_counter < 18) begin
  121. bsx_counter <= bsx_counter + 1;
  122. case (bsx_counter)
  123. 5:
  124. reg_data_outr <= 8'h1;
  125. 6:
  126. reg_data_outr <= 8'h1;
  127. 10:
  128. reg_data_outr <= 8'd42;
  129. 11:
  130. reg_data_outr <= 8'd30;
  131. 12:
  132. reg_data_outr <= 8'd18;
  133. default:
  134. reg_data_outr <= 8'h0;
  135. endcase
  136. end else begin
  137. reg_data_outr <= 8'h0;
  138. bsx_counter <= 0;
  139. end
  140. end
  141. 5'b10011:
  142. reg_data_outr <= base_regs[base_addr] & 8'h3f;
  143. default:
  144. reg_data_outr <= base_regs[base_addr];
  145. endcase
  146. end else if (flash_enable) begin
  147. casex (flash_addr)
  148. 16'h0002:
  149. reg_data_outr <= 8'h80;
  150. 16'h5555:
  151. reg_data_outr <= 8'h80;
  152. 16'b1111111100000xxx:
  153. reg_data_outr <= flash_vendor_data[flash_addr&16'h0007];
  154. default:
  155. reg_data_outr <= 8'h00;
  156. endcase
  157. end
  158. end else if(pgm_we_rising) begin
  159. regs_tmpr[8:1] <= (regs_tmpr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0];
  160. regs_outr[8:1] <= (regs_outr[8:1] | reg_set_bits[7:0]) & ~reg_reset_bits[7:0];
  161. end else if(reg_we_rising && cart_enable) begin
  162. if(reg_addr == 4'he && reg_data_in[7])
  163. regs_outr <= regs_tmpr | 16'b0100000000000000;
  164. else
  165. regs_tmpr[reg_addr] <= reg_data_in[7];
  166. end else if(reg_we_rising && base_enable) begin
  167. case(base_addr)
  168. 5'b10001: begin
  169. bsx_counter <= 0;
  170. base_regs[base_addr] <= reg_data_in;
  171. end
  172. 5'b01111: begin
  173. base_regs[base_addr-1] <= base_regs[base_addr]-(base_regs[base_addr-1] >> 1);
  174. base_regs[base_addr] <= base_regs[base_addr] >> 1;
  175. end
  176. default:
  177. base_regs[base_addr] <= reg_data_in;
  178. endcase
  179. end else if(reg_we_rising && flash_enable) begin
  180. case(flash_addr)
  181. 16'h0000: begin
  182. flash_cmd0 <= {flash_cmd0[7:0], reg_data_in};
  183. if(flash_cmd0[7:0] == 8'h38 && reg_data_in == 8'hd0)
  184. flash_ovr_r <= 1;
  185. end
  186. 16'h5555: begin
  187. flash_cmd5555 <= {flash_cmd5555[15:0], reg_data_in};
  188. if(flash_cmd5555[15:0] == 16'haa55) begin
  189. case (reg_data_in)
  190. 8'hf0: begin
  191. flash_ovr_r <= 0;
  192. flash_we_r <= 0;
  193. end
  194. 8'ha0: begin
  195. flash_ovr_r <= 1;
  196. flash_we_r <= 1;
  197. end
  198. 8'h70: begin
  199. flash_we_r <= 0;
  200. end
  201. endcase
  202. end
  203. end
  204. 16'h2aaa: begin
  205. flash_cmd5555 <= {flash_cmd5555[15:0], reg_data_in};
  206. end
  207. endcase
  208. end
  209. end
  210. endmodule