memory.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /* sd2snes - SD card based universal cartridge for the SNES
  2. Copyright (C) 2009-2010 Maximilian Rehkopf <otakon@gmx.net>
  3. AVR firmware portion
  4. Inspired by and based on code from sd2iec, written by Ingo Korb et al.
  5. See sdcard.c|h, config.h.
  6. FAT file system access based on code by ChaN, Jim Brain, Ingo Korb,
  7. see ff.c|h.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; version 2 of the License only.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. memory.c: RAM operations
  19. */
  20. #include "config.h"
  21. #include "uart.h"
  22. #include "fpga.h"
  23. #include "crc.h"
  24. #include "crc32.h"
  25. #include "ff.h"
  26. #include "fileops.h"
  27. #include "spi.h"
  28. #include "fpga_spi.h"
  29. #include "led.h"
  30. #include "smc.h"
  31. #include "memory.h"
  32. #include "snes.h"
  33. #include "timer.h"
  34. #include "rle.h"
  35. #include "diskio.h"
  36. #include "snesboot.h"
  37. #include "msu1.h"
  38. #include <string.h>
  39. char* hex = "0123456789ABCDEF";
  40. extern snes_romprops_t romprops;
  41. void sram_hexdump(uint32_t addr, uint32_t len) {
  42. static uint8_t buf[16];
  43. uint32_t ptr;
  44. for(ptr=0; ptr < len; ptr += 16) {
  45. sram_readblock((void*)buf, ptr+addr, 16);
  46. uart_trace(buf, 0, 16);
  47. }
  48. }
  49. void sram_writebyte(uint8_t val, uint32_t addr) {
  50. set_mcu_addr(addr);
  51. FPGA_SELECT();
  52. FPGA_TX_BYTE(0x98); /* WRITE */
  53. FPGA_TX_BYTE(val);
  54. FPGA_TX_BYTE(0x00); /* dummy */
  55. FPGA_DESELECT();
  56. }
  57. uint8_t sram_readbyte(uint32_t addr) {
  58. set_mcu_addr(addr);
  59. FPGA_SELECT();
  60. FPGA_TX_BYTE(0x88); /* READ */
  61. FPGA_TX_BYTE(0x00); /* dummy */
  62. uint8_t val = FPGA_TXRX_BYTE(0x00);
  63. FPGA_DESELECT();
  64. return val;
  65. }
  66. void sram_writeshort(uint16_t val, uint32_t addr) {
  67. set_mcu_addr(addr);
  68. FPGA_SELECT();
  69. FPGA_TX_BYTE(0x98); /* WRITE */
  70. FPGA_TX_BYTE(val&0xff);
  71. FPGA_TX_BYTE((val>>8)&0xff);
  72. FPGA_TX_BYTE(0x00); /* dummy */
  73. FPGA_DESELECT();
  74. }
  75. void sram_writelong(uint32_t val, uint32_t addr) {
  76. set_mcu_addr(addr);
  77. FPGA_SELECT();
  78. FPGA_TX_BYTE(0x98); /* WRITE */
  79. FPGA_TX_BYTE(val&0xff);
  80. FPGA_TX_BYTE((val>>8)&0xff);
  81. FPGA_TX_BYTE((val>>16)&0xff);
  82. FPGA_TX_BYTE((val>>24)&0xff);
  83. FPGA_TX_BYTE(0x00);
  84. FPGA_DESELECT();
  85. }
  86. uint16_t sram_readshort(uint32_t addr) {
  87. set_mcu_addr(addr);
  88. FPGA_SELECT();
  89. FPGA_TX_BYTE(0x88);
  90. FPGA_TX_BYTE(0x00);
  91. uint32_t val = FPGA_TXRX_BYTE(0x00);
  92. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8);
  93. FPGA_DESELECT();
  94. return val;
  95. }
  96. uint32_t sram_readlong(uint32_t addr) {
  97. set_mcu_addr(addr);
  98. FPGA_SELECT();
  99. FPGA_TX_BYTE(0x88);
  100. FPGA_TX_BYTE(0x00);
  101. uint32_t val = FPGA_TXRX_BYTE(0x00);
  102. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8);
  103. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<16);
  104. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<24);
  105. FPGA_DESELECT();
  106. return val;
  107. }
  108. void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
  109. set_mcu_addr(addr);
  110. FPGA_SELECT();
  111. FPGA_TX_BYTE(0x88);
  112. FPGA_TX_BYTE(0x00);
  113. uint16_t i=0;
  114. while(i<count) {
  115. uint32_t val = (uint32_t)FPGA_TXRX_BYTE(0x00)<<24;
  116. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<16);
  117. val |= ((uint32_t)FPGA_TXRX_BYTE(0x00)<<8);
  118. val |= FPGA_TXRX_BYTE(0x00);
  119. buf[i++] = val;
  120. }
  121. FPGA_DESELECT();
  122. }
  123. void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
  124. uint16_t count=size;
  125. uint8_t* tgt = buf;
  126. set_mcu_addr(addr);
  127. FPGA_SELECT();
  128. FPGA_TX_BYTE(0x88); /* READ */
  129. FPGA_TX_BYTE(0x00); /* dummy */
  130. while(count--) {
  131. *(tgt++) = FPGA_TXRX_BYTE(0x00);
  132. }
  133. FPGA_DESELECT();
  134. }
  135. void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
  136. uint16_t count=size;
  137. uint8_t* src = buf;
  138. set_mcu_addr(addr);
  139. FPGA_SELECT();
  140. FPGA_TX_BYTE(0x98); /* WRITE */
  141. while(count--) {
  142. FPGA_TX_BYTE(*src++);
  143. }
  144. FPGA_TX_BYTE(0x00); /* dummy */
  145. FPGA_DESELECT();
  146. }
  147. uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
  148. UINT bytes_read;
  149. DWORD filesize;
  150. UINT count=0;
  151. tick_t ticksstart, ticks_total=0;
  152. ticksstart=getticks();
  153. printf("%s\n", filename);
  154. if(flags & LOADROM_WITH_RESET) set_mcu_ovr(1);
  155. file_open(filename, FA_READ);
  156. if(file_res) {
  157. uart_putc('?');
  158. uart_putc(0x30+file_res);
  159. return 0;
  160. }
  161. filesize = file_handle.fsize;
  162. smc_id(&romprops);
  163. set_mcu_addr(base_addr);
  164. f_lseek(&file_handle, romprops.offset);
  165. for(;;) {
  166. ff_sd_offload=1;
  167. sd_offload_tgt=0;
  168. bytes_read = file_read();
  169. if (file_res || !bytes_read) break;
  170. if(!(count++ % 512)) {
  171. uart_putc('.');
  172. }
  173. }
  174. file_close();
  175. set_mapper(romprops.mapper_id);
  176. printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
  177. ticks_total=getticks()-ticksstart;
  178. printf("%u ticks total\n", ticks_total);
  179. if(romprops.mapper_id==3) {
  180. printf("BSX Flash cart image\n");
  181. printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n");
  182. load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000);
  183. printf("Type: %02x\n", romprops.header.destcode);
  184. set_bsx_regs(0xc0, 0x3f);
  185. uint16_t rombase;
  186. if(romprops.header.ramsize & 1) {
  187. rombase = 0xff00;
  188. // set_bsx_regs(0x36, 0xc9);
  189. } else {
  190. rombase = 0x7f00;
  191. // set_bsx_regs(0x34, 0xcb);
  192. }
  193. sram_writebyte(0x33, rombase+0xda);
  194. sram_writebyte(0x00, rombase+0xd4);
  195. sram_writebyte(0xfc, rombase+0xd5);
  196. set_fpga_time(0x0220110301180530LL);
  197. }
  198. if(romprops.has_dspx) {
  199. printf("DSPx game. Loading firmware image %s...\n", romprops.necdsp_fw);
  200. if(romprops.has_st0010) {
  201. load_dspx(romprops.necdsp_fw, 1);
  202. } else {
  203. load_dspx(romprops.necdsp_fw, 0);
  204. if(file_res && romprops.necdsp_fw == DSPFW_1) {
  205. load_dspx(DSPFW_1B, 0);
  206. }
  207. }
  208. if(file_res) {
  209. snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.necdsp_fw);
  210. }
  211. }
  212. uint32_t rammask;
  213. uint32_t rommask;
  214. while(filesize > (romprops.romsize_bytes + romprops.offset)) {
  215. romprops.romsize_bytes <<= 1;
  216. }
  217. if(romprops.header.ramsize == 0) {
  218. rammask = 0;
  219. } else {
  220. rammask = romprops.ramsize_bytes - 1;
  221. }
  222. rommask = romprops.romsize_bytes - 1;
  223. printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
  224. set_saveram_mask(rammask);
  225. set_rom_mask(rommask);
  226. readled(0);
  227. if(flags & LOADROM_WITH_SRAM) {
  228. if(romprops.ramsize_bytes) {
  229. strcpy(strrchr((char*)filename, (int)'.'), ".srm");
  230. printf("SRM file: %s\n", filename);
  231. load_sram(filename, SRAM_SAVE_ADDR);
  232. } else {
  233. printf("No SRAM\n");
  234. }
  235. }
  236. printf("check MSU...");
  237. if(msu1_check(filename)) {
  238. romprops.fpga_features |= FEAT_MSU1;
  239. romprops.has_msu1 = 1;
  240. }
  241. printf("done\n");
  242. romprops.fpga_features |= FEAT_SRTC;
  243. fpga_set_features(romprops.fpga_features);
  244. if(flags & LOADROM_WITH_RESET) {
  245. set_mcu_ovr(0);
  246. fpga_dspx_reset(1);
  247. snes_reset(1);
  248. delay_ms(10);
  249. snes_reset(0);
  250. fpga_dspx_reset(0);
  251. }
  252. return (uint32_t)filesize;
  253. }
  254. uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
  255. set_mcu_addr(base_addr);
  256. UINT bytes_read;
  257. DWORD filesize;
  258. file_open(filename, FA_READ);
  259. filesize = file_handle.fsize;
  260. if(file_res) return 0;
  261. for(;;) {
  262. ff_sd_offload=1;
  263. sd_offload_tgt=0;
  264. bytes_read = file_read();
  265. if (file_res || !bytes_read) break;
  266. }
  267. file_close();
  268. return (uint32_t)filesize;
  269. }
  270. uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
  271. set_mcu_addr(base_addr);
  272. UINT bytes_read;
  273. DWORD filesize;
  274. file_open(filename, FA_READ);
  275. filesize = file_handle.fsize;
  276. if(file_res) return 0;
  277. for(;;) {
  278. bytes_read = file_read();
  279. if (file_res || !bytes_read) break;
  280. FPGA_SELECT();
  281. FPGA_TX_BYTE(0x98);
  282. for(int j=0; j<bytes_read; j++) {
  283. FPGA_TX_BYTE(file_buf[j]);
  284. }
  285. FPGA_TX_BYTE(0x00); /* dummy tx */
  286. FPGA_DESELECT();
  287. }
  288. file_close();
  289. return (uint32_t)filesize;
  290. }
  291. uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
  292. uint8_t data;
  293. set_mcu_addr(base_addr);
  294. DWORD filesize;
  295. file_open(filename, FA_READ);
  296. filesize = file_handle.fsize;
  297. if(file_res) return 0;
  298. FPGA_SELECT();
  299. FPGA_TX_BYTE(0x98);
  300. for(;;) {
  301. data = rle_file_getc();
  302. if (file_res || file_status) break;
  303. FPGA_TX_BYTE(data);
  304. }
  305. FPGA_TX_BYTE(0x00); /* dummy tx */
  306. FPGA_DESELECT();
  307. file_close();
  308. return (uint32_t)filesize;
  309. }
  310. uint32_t load_bootrle(uint32_t base_addr) {
  311. uint8_t data;
  312. set_mcu_addr(base_addr);
  313. DWORD filesize = 0;
  314. rle_mem_init(bootrle, sizeof(bootrle));
  315. FPGA_SELECT();
  316. FPGA_TX_BYTE(0x98);
  317. for(;;) {
  318. data = rle_mem_getc();
  319. if(rle_state) break;
  320. FPGA_TX_BYTE(data);
  321. filesize++;
  322. }
  323. FPGA_TX_BYTE(0x00); /* dummy tx */
  324. FPGA_DESELECT();
  325. return (uint32_t)filesize;
  326. }
  327. void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
  328. uint32_t count = 0;
  329. uint32_t num = 0;
  330. FPGA_DESELECT();
  331. file_open(filename, FA_CREATE_ALWAYS | FA_WRITE);
  332. if(file_res) {
  333. uart_putc(0x30+file_res);
  334. }
  335. while(count<sram_size) {
  336. set_mcu_addr(base_addr+count);
  337. FPGA_SELECT();
  338. FPGA_TX_BYTE(0x88); /* read */
  339. FPGA_TX_BYTE(0x00); /* dummy */
  340. for(int j=0; j<sizeof(file_buf); j++) {
  341. file_buf[j] = FPGA_TXRX_BYTE(0x00);
  342. count++;
  343. }
  344. FPGA_DESELECT();
  345. num = file_write();
  346. if(file_res) {
  347. uart_putc(0x30+file_res);
  348. }
  349. }
  350. file_close();
  351. }
  352. uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
  353. uint8_t data;
  354. uint32_t count;
  355. uint32_t crc;
  356. crc=0;
  357. crc_valid=1;
  358. set_mcu_addr(base_addr);
  359. FPGA_SELECT();
  360. FPGA_TX_BYTE(0x88);
  361. FPGA_TX_BYTE(0x00);
  362. for(count=0; count<size; count++) {
  363. data = FPGA_TXRX_BYTE(0x00);
  364. if(get_snes_reset()) {
  365. crc_valid = 0;
  366. break;
  367. }
  368. crc += crc32_update(crc, data);
  369. }
  370. FPGA_DESELECT();
  371. return crc;
  372. }
  373. uint8_t sram_reliable() {
  374. uint16_t score=0;
  375. uint32_t val;
  376. uint8_t result = 0;
  377. /*while(score<SRAM_RELIABILITY_SCORE) {
  378. if(sram_readlong(SRAM_SCRATCHPAD)==val) {
  379. score++;
  380. } else {
  381. set_pwr_led(0);
  382. score=0;
  383. }
  384. } */
  385. for(uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++) {
  386. val=sram_readlong(SRAM_SCRATCHPAD);
  387. if(val==0x12345678) {
  388. score++;
  389. /* } else {
  390. dprintf("i=%d val=%08lX\n", i, val); */
  391. }
  392. }
  393. if(score<SRAM_RELIABILITY_SCORE) {
  394. result = 0;
  395. /* dprintf("score=%d\n", score); */
  396. } else {
  397. result = 1;
  398. }
  399. rdyled(result);
  400. return result;
  401. }
  402. void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
  403. set_mcu_addr(base_addr);
  404. FPGA_SELECT();
  405. FPGA_TX_BYTE(0x98);
  406. for(uint32_t i=0; i<len; i++) {
  407. FPGA_TX_BYTE(val);
  408. }
  409. FPGA_TX_BYTE(0x00);
  410. FPGA_DESELECT();
  411. }
  412. uint64_t sram_gettime(uint32_t base_addr) {
  413. set_mcu_addr(base_addr);
  414. FPGA_SELECT();
  415. FPGA_TX_BYTE(0x88);
  416. FPGA_TX_BYTE(0x00);
  417. uint8_t data;
  418. uint64_t result = 0LL;
  419. /* 1st nibble is the century - 10 (binary)
  420. 4th nibble is the month (binary)
  421. all other fields are BCD */
  422. for(int i=0; i<12; i++) {
  423. data = FPGA_TXRX_BYTE(0x00);
  424. data &= 0xf;
  425. switch(i) {
  426. case 0:
  427. result = (result << 4) | ((data / 10) + 1);
  428. result = (result << 4) | (data % 10);
  429. break;
  430. case 3:
  431. result = (result << 4) | ((data / 10));
  432. result = (result << 4) | (data % 10);
  433. break;
  434. default:
  435. result = (result << 4) | data;
  436. }
  437. }
  438. FPGA_DESELECT();
  439. return result & 0x00ffffffffffffffLL;
  440. }
  441. void load_dspx(const uint8_t *filename, uint8_t st0010) {
  442. UINT bytes_read;
  443. DWORD filesize;
  444. uint16_t word_cnt;
  445. uint8_t wordsize_cnt = 0;
  446. uint16_t sector_remaining = 0;
  447. uint16_t sector_cnt = 0;
  448. uint16_t pgmsize = 2048;
  449. uint16_t datsize;
  450. uint32_t pgmdata = 0;
  451. uint16_t datdata = 0;
  452. if(st0010) {
  453. datsize = 1536;
  454. } else {
  455. datsize = 1024;
  456. }
  457. file_open((uint8_t*)filename, FA_READ);
  458. filesize = file_handle.fsize;
  459. if(file_res) {
  460. printf("Could not read %s: error %d\n", filename, file_res);
  461. return;
  462. }
  463. fpga_reset_dspx_addr();
  464. for(word_cnt = 0; word_cnt < pgmsize;) {
  465. if(!sector_remaining) {
  466. bytes_read = file_read();
  467. sector_remaining = bytes_read;
  468. sector_cnt = 0;
  469. }
  470. pgmdata = (pgmdata << 8) | file_buf[sector_cnt];
  471. sector_cnt++;
  472. wordsize_cnt++;
  473. sector_remaining--;
  474. if(wordsize_cnt == 3){
  475. wordsize_cnt = 0;
  476. word_cnt++;
  477. fpga_write_dspx_pgm(pgmdata);
  478. }
  479. }
  480. wordsize_cnt = 0;
  481. if(st0010) {
  482. file_seek(0xc000);
  483. sector_remaining = 0;
  484. }
  485. for(word_cnt = 0; word_cnt < datsize;) {
  486. if(!sector_remaining) {
  487. bytes_read = file_read();
  488. sector_remaining = bytes_read;
  489. sector_cnt = 0;
  490. }
  491. datdata = (datdata << 8) | file_buf[sector_cnt];
  492. sector_cnt++;
  493. wordsize_cnt++;
  494. sector_remaining--;
  495. if(wordsize_cnt == 2){
  496. wordsize_cnt = 0;
  497. word_cnt++;
  498. fpga_write_dspx_dat(datdata);
  499. }
  500. }
  501. fpga_reset_dspx_addr();
  502. file_close();
  503. }