PageRenderTime 76ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/verilog/sd2snes/address.v

https://bitbucket.org/Coto88/sd2snes
V | 290 lines | 290 code | 0 blank | 0 comment | 0 complexity | 12b42820a166bfcd921b1801779dbf04 MD5 | raw file
Possible License(s): GPL-2.0
  1. `timescale 1 ns / 1 ns
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company: Rehkopf
  4. // Engineer: Rehkopf
  5. //
  6. // Create Date: 01:13:46 05/09/2009
  7. // Design Name:
  8. // Module Name: address
  9. // Project Name:
  10. // Target Devices:
  11. // Tool versions:
  12. // Description: Address logic w/ SaveRAM masking
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Additional Comments:
  18. //
  19. //////////////////////////////////////////////////////////////////////////////////
  20. module address(
  21. input CLK,
  22. input [7:0] featurebits_in, // peripheral enable/disable
  23. input [2:0] MAPPER, // MCU detected mapper
  24. input [23:0] SNES_ADDR, // requested address from SNES
  25. input [7:0] SNES_PA, // peripheral address from SNES
  26. input SNES_ROMSEL, // ROMSEL from SNES
  27. output [23:0] ROM_ADDR, // Address to request from SRAM0
  28. output ROM_HIT, // enable SRAM0
  29. output IS_SAVERAM, // address/CS mapped as SRAM?
  30. output IS_ROM, // address mapped as ROM?
  31. output IS_WRITABLE, // address somehow mapped as writable area?
  32. input [23:0] SAVERAM_MASK,
  33. input [23:0] ROM_MASK,
  34. input map_unlock,
  35. output msu_enable,
  36. // output usb_enable,
  37. output dma_enable,
  38. output srtc_enable,
  39. output use_bsx,
  40. output bsx_tristate,
  41. input [14:0] bsx_regs,
  42. output dspx_enable,
  43. output dspx_dp_enable,
  44. output dspx_a0,
  45. output r213f_enable,
  46. output snescmd_enable,
  47. output nmicmd_enable,
  48. output return_vector_enable,
  49. output branch1_enable,
  50. output branch2_enable,
  51. output exe_enable,
  52. input [8:0] bs_page_offset,
  53. input [9:0] bs_page,
  54. input bs_page_enable
  55. );
  56. parameter [2:0]
  57. FEAT_DSPX = 0,
  58. FEAT_ST0010 = 1,
  59. FEAT_SRTC = 2,
  60. FEAT_MSU1 = 3,
  61. FEAT_213F = 4,
  62. FEAT_SNESUNLOCK = 5,
  63. //FEAT_USB1 = 6,
  64. FEAT_DMA1 = 7
  65. ;
  66. // local flops to improve timing
  67. reg [7:0] featurebits;
  68. reg [7:0] MAPPER_DEC;
  69. integer i;
  70. always @(posedge CLK) begin
  71. featurebits <= featurebits_in;
  72. for (i = 0; i < 8; i = i + 1) MAPPER_DEC[i] <= (MAPPER == i);
  73. end
  74. wire [23:0] SRAM_SNES_ADDR;
  75. /* currently supported mappers:
  76. Index Mapper
  77. 000 HiROM
  78. 001 LoROM
  79. 010 ExHiROM (48-64Mbit)
  80. 011 BS-X
  81. 110 brainfuck interleaved 96MBit Star Ocean =)
  82. 111 menu (ROM in upper SRAM)
  83. */
  84. /* HiROM: SRAM @ Bank 0x30-0x3f, 0xb0-0xbf
  85. Offset 6000-7fff */
  86. assign IS_ROM = ((!SNES_ADDR[22] & SNES_ADDR[15])
  87. |(SNES_ADDR[22]));
  88. assign IS_SAVERAM = (~map_unlock & SAVERAM_MASK[0])
  89. &(featurebits[FEAT_ST0010]
  90. ?((SNES_ADDR[22:19] == 4'b1101)
  91. & &(~SNES_ADDR[15:12])
  92. & SNES_ADDR[11])
  93. :((MAPPER_DEC[3'b000]
  94. || MAPPER_DEC[3'b010]
  95. || MAPPER_DEC[3'b110])
  96. ? (!SNES_ADDR[22]
  97. & SNES_ADDR[21]
  98. & &SNES_ADDR[14:13]
  99. & !SNES_ADDR[15]
  100. )
  101. /* LoROM: SRAM @ Bank 0x70-0x7d, 0xf0-0xff
  102. * Offset 0000-7fff for ROM >= 32 MBit, otherwise 0000-ffff */
  103. :(MAPPER_DEC[3'b001])
  104. ? (&SNES_ADDR[22:20]
  105. & (~SNES_ROMSEL)
  106. & (~SNES_ADDR[15] | ~ROM_MASK[21])
  107. )
  108. /* BS-X: SRAM @ Bank 0x10-0x17 Offset 5000-5fff */
  109. :(MAPPER_DEC[3'b011])
  110. ? ((SNES_ADDR[23:19] == 5'b00010)
  111. & (SNES_ADDR[15:12] == 4'b0101)
  112. )
  113. /* Menu mapper: 8Mbit "SRAM" @ Bank 0xf0-0xff (entire banks!) */
  114. :(MAPPER_DEC[3'b111])
  115. ? (&SNES_ADDR[23:20])
  116. : 1'b0));
  117. // give the patch free reign over $F0-$FF banks
  118. assign IS_PATCH = map_unlock & (&SNES_ADDR[23:20]);
  119. /* BS-X has 4 MBits of extra RAM that can be mapped to various places */
  120. // LoROM: A23 = r03/r04 A22 = r06 A21 = r05 A20 = 0 A19 = d/c
  121. // HiROM: A23 = r03/r04 A22 = d/c A21 = r06 A20 = r05 A19 = 0
  122. wire [2:0] BSX_PSRAM_BANK = {bsx_regs[6], bsx_regs[5], 1'b0};
  123. wire [2:0] SNES_PSRAM_BANK = bsx_regs[2] ? SNES_ADDR[21:19] : SNES_ADDR[22:20];
  124. wire BSX_PSRAM_LOHI = (bsx_regs[3] & ~SNES_ADDR[23]) | (bsx_regs[4] & SNES_ADDR[23]);
  125. wire BSX_IS_PSRAM = BSX_PSRAM_LOHI
  126. & (( IS_ROM & (SNES_PSRAM_BANK == BSX_PSRAM_BANK)
  127. &(SNES_ADDR[15] | bsx_regs[2])
  128. &(~(SNES_ADDR[19] & bsx_regs[2])))
  129. | (bsx_regs[2]
  130. ? (SNES_ADDR[22:21] == 2'b01 & SNES_ADDR[15:13] == 3'b011)
  131. : (~SNES_ROMSEL & &SNES_ADDR[22:20] & ~SNES_ADDR[15]))
  132. );
  133. //reg BSX_IS_PSRAM_r;
  134. //always @(posedge CLK) BSX_IS_PSRAM_r <= BSX_IS_PSRAM;
  135. wire BSX_IS_CARTROM = ((bsx_regs[7] & (SNES_ADDR[23:22] == 2'b00))
  136. |(bsx_regs[8] & (SNES_ADDR[23:22] == 2'b10)))
  137. & SNES_ADDR[15];
  138. wire BSX_HOLE_LOHI = (bsx_regs[9] & ~SNES_ADDR[23]) | (bsx_regs[10] & SNES_ADDR[23]);
  139. wire BSX_IS_HOLE = BSX_HOLE_LOHI
  140. & (bsx_regs[2] ? (SNES_ADDR[21:20] == {bsx_regs[11], 1'b0})
  141. : (SNES_ADDR[22:21] == {bsx_regs[11], 1'b0}));
  142. // $1E-$1F:5000-5FFF -> $F9:E000-FFFF
  143. //assign IS_USB = featurebits[FEAT_USB1] && ({SNES_ADDR[23:17],1'b0,SNES_ADDR[15:12],12'h000} == 24'h1E5000);
  144. assign bsx_tristate = (MAPPER_DEC[3'b011]) & ~BSX_IS_CARTROM & ~BSX_IS_PSRAM & BSX_IS_HOLE;
  145. assign IS_WRITABLE = IS_SAVERAM
  146. |IS_PATCH // allow writing of the patch region
  147. //|IS_USB
  148. //|(map_unlock & ~SNES_ROMSEL) // allow writing of the ROM in the PATCH region. FIXME: this may break DMAs from ROM to WRAM
  149. |((MAPPER_DEC[3'b011]) & BSX_IS_PSRAM);
  150. wire [23:0] BSX_ADDR = bsx_regs[2] ? {1'b0, SNES_ADDR[22:0]}
  151. : {2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]};
  152. /* BSX regs:
  153. Index Function
  154. 1 0=map flash to ROM area; 1=map PRAM to ROM area
  155. 2 1=HiROM; 0=LoROM
  156. 3 1=Mirror PRAM @60-6f:0000-ffff
  157. 5 1=DO NOT mirror PRAM @40-4f:0000-ffff
  158. 6 1=DO NOT mirror PRAM @50-5f:0000-ffff
  159. 7 1=map BSX cartridge ROM @00-1f:8000-ffff
  160. 8 1=map BSX cartridge ROM @80-9f:8000-ffff
  161. */
  162. assign SRAM_SNES_ADDR = IS_PATCH
  163. ? SNES_ADDR
  164. //: IS_USB
  165. //? (24'hF9E000 + {SNES_ADDR[16],SNES_ADDR[11:0]})
  166. : ((MAPPER_DEC[3'b000])
  167. ?(IS_SAVERAM
  168. ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]}
  169. & SAVERAM_MASK)
  170. : ({1'b0, SNES_ADDR[22:0]} & ROM_MASK))
  171. :(MAPPER_DEC[3'b001])
  172. ?(IS_SAVERAM
  173. ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[14:0]}
  174. & SAVERAM_MASK)
  175. : ({2'b00, SNES_ADDR[22:16], SNES_ADDR[14:0]}
  176. & ROM_MASK))
  177. :(MAPPER_DEC[3'b010])
  178. ?(IS_SAVERAM
  179. ? 24'hE00000 + ({SNES_ADDR[20:16], SNES_ADDR[12:0]}
  180. & SAVERAM_MASK)
  181. : ({1'b0, !SNES_ADDR[23], SNES_ADDR[21:0]}
  182. & ROM_MASK))
  183. :(MAPPER_DEC[3'b011])
  184. ?( IS_SAVERAM
  185. ? 24'hE00000 + {SNES_ADDR[18:16], SNES_ADDR[11:0]}
  186. : BSX_IS_CARTROM
  187. ? (24'h800000 + ({SNES_ADDR[22:16], SNES_ADDR[14:0]} & 24'h0fffff))
  188. : BSX_IS_PSRAM
  189. ? (24'h400000 + (BSX_ADDR & 24'h07FFFF))
  190. : bs_page_enable
  191. ? (24'h900000 + {bs_page,bs_page_offset})
  192. : (BSX_ADDR & 24'h0fffff)
  193. )
  194. :(MAPPER_DEC[3'b110])
  195. ?(IS_SAVERAM
  196. ? 24'hE00000 + ((SNES_ADDR[14:0] - 15'h6000)
  197. & SAVERAM_MASK)
  198. :(SNES_ADDR[15]
  199. ?({1'b0, SNES_ADDR[23:16], SNES_ADDR[14:0]})
  200. :({2'b10,
  201. SNES_ADDR[23],
  202. SNES_ADDR[21:16],
  203. SNES_ADDR[14:0]}
  204. )
  205. )
  206. )
  207. :(MAPPER_DEC[3'b111])
  208. ?(IS_SAVERAM
  209. ? SNES_ADDR
  210. : (({1'b0, SNES_ADDR[22:0]} & ROM_MASK)
  211. + 24'hC00000)
  212. )
  213. : 24'b0);
  214. // when unlocked provide a bank at the top of SRAM. Note that unlock has a delay after we exit the handler
  215. // so there is a possibility we'll read these addresses instead of ROM. It would be safer to put this in an
  216. // unused address that is unmapped
  217. assign ROM_ADDR = SRAM_SNES_ADDR;
  218. assign ROM_HIT = IS_ROM | IS_WRITABLE | bs_page_enable;
  219. assign msu_enable = featurebits[FEAT_MSU1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2000));
  220. //assign usb_enable = featurebits[FEAT_USB1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff8) == 16'h2010));
  221. assign dma_enable = featurebits[FEAT_DMA1] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfff0) == 16'h2020));
  222. assign use_bsx = (MAPPER_DEC[3'b011]);
  223. assign srtc_enable = featurebits[FEAT_SRTC] & (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hfffe) == 16'h2800));
  224. assign exe_enable = (!SNES_ADDR[22] && ((SNES_ADDR[15:0] & 16'hffff) == 16'h2C00)); // requires USB write to enable
  225. // DSP1 LoROM: DR=30-3f:8000-bfff; SR=30-3f:c000-ffff
  226. // or DR=60-6f:0000-3fff; SR=60-6f:4000-7fff
  227. // DSP1 HiROM: DR=00-0f:6000-6fff; SR=00-0f:7000-7fff
  228. assign dspx_enable =
  229. featurebits[FEAT_DSPX]
  230. ?((MAPPER_DEC[3'b001])
  231. ?(ROM_MASK[20]
  232. ?(SNES_ADDR[22] & SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15])
  233. :(~SNES_ADDR[22] & SNES_ADDR[21] & SNES_ADDR[20] & SNES_ADDR[15])
  234. )
  235. :(MAPPER_DEC[3'b000])
  236. ?(~SNES_ADDR[22] & ~SNES_ADDR[21] & ~SNES_ADDR[20] & ~SNES_ADDR[15]
  237. & &SNES_ADDR[14:13])
  238. :1'b0)
  239. :featurebits[FEAT_ST0010]
  240. ?(SNES_ADDR[22] & SNES_ADDR[21] & ~SNES_ADDR[20] & &(~SNES_ADDR[19:16]) & ~SNES_ADDR[15])
  241. :1'b0;
  242. assign dspx_dp_enable = featurebits[FEAT_ST0010]
  243. &(SNES_ADDR[22:19] == 4'b1101
  244. && SNES_ADDR[15:11] == 5'b00000);
  245. assign dspx_a0 = featurebits[FEAT_DSPX]
  246. ?((MAPPER_DEC[3'b001]) ? SNES_ADDR[14]
  247. :(MAPPER_DEC[3'b000]) ? SNES_ADDR[12]
  248. :1'b1)
  249. : featurebits[FEAT_ST0010]
  250. ? SNES_ADDR[0]
  251. : 1'b1;
  252. assign r213f_enable = featurebits[FEAT_213F] & (SNES_PA == 8'h3f);
  253. // snescmd covers $2A00-$2FFF. This overlaps with at least one hardware cheat device address range.
  254. assign snescmd_enable = ({SNES_ADDR[22], SNES_ADDR[15:11]} == 6'b0_00101) && (SNES_ADDR[10:9] != 2'b00);
  255. assign nmicmd_enable = (SNES_ADDR == 24'h002BF2);
  256. assign return_vector_enable = (SNES_ADDR == 24'h002A5A);
  257. assign branch1_enable = (SNES_ADDR == 24'h002A13);
  258. assign branch2_enable = (SNES_ADDR == 24'h002A4D);
  259. endmodule