memory.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  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_WAIT_RDY();
  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_WAIT_RDY();
  62. uint8_t val = FPGA_RX_BYTE();
  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_WAIT_RDY();
  72. FPGA_TX_BYTE((val>>8)&0xff);
  73. FPGA_WAIT_RDY();
  74. FPGA_DESELECT();
  75. }
  76. void sram_writelong(uint32_t val, uint32_t addr) {
  77. set_mcu_addr(addr);
  78. FPGA_SELECT();
  79. FPGA_TX_BYTE(0x98); /* WRITE */
  80. FPGA_TX_BYTE(val&0xff);
  81. FPGA_WAIT_RDY();
  82. FPGA_TX_BYTE((val>>8)&0xff);
  83. FPGA_WAIT_RDY();
  84. FPGA_TX_BYTE((val>>16)&0xff);
  85. FPGA_WAIT_RDY();
  86. FPGA_TX_BYTE((val>>24)&0xff);
  87. FPGA_WAIT_RDY();
  88. FPGA_DESELECT();
  89. }
  90. uint16_t sram_readshort(uint32_t addr) {
  91. set_mcu_addr(addr);
  92. FPGA_SELECT();
  93. FPGA_TX_BYTE(0x88);
  94. FPGA_WAIT_RDY();
  95. uint32_t val = FPGA_RX_BYTE();
  96. FPGA_WAIT_RDY();
  97. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  98. FPGA_DESELECT();
  99. return val;
  100. }
  101. uint32_t sram_readlong(uint32_t addr) {
  102. set_mcu_addr(addr);
  103. FPGA_SELECT();
  104. FPGA_TX_BYTE(0x88);
  105. FPGA_WAIT_RDY();
  106. uint32_t val = FPGA_RX_BYTE();
  107. FPGA_WAIT_RDY();
  108. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  109. FPGA_WAIT_RDY();
  110. val |= ((uint32_t)FPGA_RX_BYTE()<<16);
  111. FPGA_WAIT_RDY();
  112. val |= ((uint32_t)FPGA_RX_BYTE()<<24);
  113. FPGA_DESELECT();
  114. return val;
  115. }
  116. void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
  117. set_mcu_addr(addr);
  118. FPGA_SELECT();
  119. FPGA_TX_BYTE(0x88);
  120. uint16_t i=0;
  121. while(i<count) {
  122. FPGA_WAIT_RDY();
  123. uint32_t val = (uint32_t)FPGA_RX_BYTE()<<24;
  124. FPGA_WAIT_RDY();
  125. val |= ((uint32_t)FPGA_RX_BYTE()<<16);
  126. FPGA_WAIT_RDY();
  127. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  128. FPGA_WAIT_RDY();
  129. val |= FPGA_RX_BYTE();
  130. buf[i++] = val;
  131. }
  132. FPGA_DESELECT();
  133. }
  134. void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
  135. uint16_t count=size;
  136. uint8_t* tgt = buf;
  137. set_mcu_addr(addr);
  138. FPGA_SELECT();
  139. FPGA_TX_BYTE(0x88); /* READ */
  140. while(count--) {
  141. FPGA_WAIT_RDY();
  142. *(tgt++) = FPGA_RX_BYTE();
  143. }
  144. FPGA_DESELECT();
  145. }
  146. void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
  147. uint16_t count=size;
  148. uint8_t* src = buf;
  149. set_mcu_addr(addr);
  150. FPGA_SELECT();
  151. FPGA_TX_BYTE(0x98); /* WRITE */
  152. while(count--) {
  153. FPGA_TX_BYTE(*src++);
  154. FPGA_WAIT_RDY();
  155. }
  156. FPGA_DESELECT();
  157. }
  158. uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
  159. UINT bytes_read;
  160. DWORD filesize;
  161. UINT count=0;
  162. tick_t ticksstart, ticks_total=0;
  163. ticksstart=getticks();
  164. printf("%s\n", filename);
  165. file_open(filename, FA_READ);
  166. if(file_res) {
  167. uart_putc('?');
  168. uart_putc(0x30+file_res);
  169. return 0;
  170. }
  171. filesize = file_handle.fsize;
  172. smc_id(&romprops);
  173. file_close();
  174. /* reconfigure FPGA if necessary */
  175. if(romprops.fpga_conf) {
  176. printf("reconfigure FPGA with %s...\n", romprops.fpga_conf);
  177. fpga_pgm((uint8_t*)romprops.fpga_conf);
  178. }
  179. set_mcu_addr(base_addr);
  180. file_open(filename, FA_READ);
  181. f_lseek(&file_handle, romprops.offset);
  182. for(;;) {
  183. ff_sd_offload=1;
  184. sd_offload_tgt=0;
  185. bytes_read = file_read();
  186. if (file_res || !bytes_read) break;
  187. if(!(count++ % 512)) {
  188. uart_putc('.');
  189. }
  190. }
  191. file_close();
  192. set_mapper(romprops.mapper_id);
  193. printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
  194. ticks_total=getticks()-ticksstart;
  195. printf("%u ticks total\n", ticks_total);
  196. if(romprops.mapper_id==3) {
  197. printf("BSX Flash cart image\n");
  198. printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n");
  199. load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000);
  200. printf("Type: %02x\n", romprops.header.destcode);
  201. set_bsx_regs(0xc0, 0x3f);
  202. uint16_t rombase;
  203. if(romprops.header.ramsize & 1) {
  204. rombase = 0xff00;
  205. // set_bsx_regs(0x36, 0xc9);
  206. } else {
  207. rombase = 0x7f00;
  208. // set_bsx_regs(0x34, 0xcb);
  209. }
  210. sram_writebyte(0x33, rombase+0xda);
  211. sram_writebyte(0x00, rombase+0xd4);
  212. sram_writebyte(0xfc, rombase+0xd5);
  213. set_fpga_time(0x0220110301180530LL);
  214. }
  215. if(romprops.has_dspx || romprops.has_cx4) {
  216. printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw);
  217. load_dspx(romprops.dsp_fw, romprops.fpga_features);
  218. /* fallback to DSP1B firmware if DSP1.bin is not present */
  219. if(file_res && romprops.dsp_fw == DSPFW_1) {
  220. load_dspx(DSPFW_1B, romprops.fpga_features);
  221. }
  222. if(file_res) {
  223. snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.dsp_fw);
  224. }
  225. }
  226. uint32_t rammask;
  227. uint32_t rommask;
  228. while(filesize > (romprops.romsize_bytes + romprops.offset)) {
  229. romprops.romsize_bytes <<= 1;
  230. }
  231. if(romprops.header.ramsize == 0) {
  232. rammask = 0;
  233. } else {
  234. rammask = romprops.ramsize_bytes - 1;
  235. }
  236. rommask = romprops.romsize_bytes - 1;
  237. printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
  238. set_saveram_mask(rammask);
  239. set_rom_mask(rommask);
  240. readled(0);
  241. if(flags & LOADROM_WITH_SRAM) {
  242. if(romprops.ramsize_bytes) {
  243. strcpy(strrchr((char*)filename, (int)'.'), ".srm");
  244. printf("SRM file: %s\n", filename);
  245. load_sram(filename, SRAM_SAVE_ADDR);
  246. } else {
  247. printf("No SRAM\n");
  248. }
  249. }
  250. printf("check MSU...");
  251. if(msu1_check(filename)) {
  252. romprops.fpga_features |= FEAT_MSU1;
  253. romprops.has_msu1 = 1;
  254. } else {
  255. romprops.has_msu1 = 0;
  256. }
  257. printf("done\n");
  258. romprops.fpga_features |= FEAT_SRTC;
  259. fpga_set_features(romprops.fpga_features);
  260. if(flags & LOADROM_WITH_RESET) {
  261. fpga_dspx_reset(1);
  262. snes_reset(1);
  263. delay_ms(10);
  264. snes_reset(0);
  265. fpga_dspx_reset(0);
  266. }
  267. return (uint32_t)filesize;
  268. }
  269. uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
  270. set_mcu_addr(base_addr);
  271. UINT bytes_read;
  272. DWORD filesize;
  273. file_open(filename, FA_READ);
  274. filesize = file_handle.fsize;
  275. if(file_res) return 0;
  276. for(;;) {
  277. ff_sd_offload=1;
  278. sd_offload_tgt=0;
  279. bytes_read = file_read();
  280. if (file_res || !bytes_read) break;
  281. }
  282. file_close();
  283. return (uint32_t)filesize;
  284. }
  285. uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
  286. set_mcu_addr(base_addr);
  287. UINT bytes_read;
  288. DWORD filesize;
  289. file_open(filename, FA_READ);
  290. filesize = file_handle.fsize;
  291. if(file_res) {
  292. printf("load_sram: could not open %s, res=%d\n", filename, file_res);
  293. return 0;
  294. }
  295. for(;;) {
  296. bytes_read = file_read();
  297. if (file_res || !bytes_read) break;
  298. FPGA_SELECT();
  299. FPGA_TX_BYTE(0x98);
  300. for(int j=0; j<bytes_read; j++) {
  301. FPGA_TX_BYTE(file_buf[j]);
  302. FPGA_WAIT_RDY();
  303. }
  304. FPGA_DESELECT();
  305. }
  306. file_close();
  307. return (uint32_t)filesize;
  308. }
  309. uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
  310. uint8_t data;
  311. set_mcu_addr(base_addr);
  312. DWORD filesize;
  313. file_open(filename, FA_READ);
  314. filesize = file_handle.fsize;
  315. if(file_res) return 0;
  316. FPGA_SELECT();
  317. FPGA_TX_BYTE(0x98);
  318. for(;;) {
  319. data = rle_file_getc();
  320. if (file_res || file_status) break;
  321. FPGA_TX_BYTE(data);
  322. FPGA_WAIT_RDY();
  323. }
  324. FPGA_DESELECT();
  325. file_close();
  326. return (uint32_t)filesize;
  327. }
  328. uint32_t load_bootrle(uint32_t base_addr) {
  329. uint8_t data;
  330. set_mcu_addr(base_addr);
  331. DWORD filesize = 0;
  332. rle_mem_init(bootrle, sizeof(bootrle));
  333. FPGA_SELECT();
  334. FPGA_TX_BYTE(0x98);
  335. for(;;) {
  336. data = rle_mem_getc();
  337. if(rle_state) break;
  338. FPGA_TX_BYTE(data);
  339. FPGA_WAIT_RDY();
  340. filesize++;
  341. }
  342. FPGA_DESELECT();
  343. return (uint32_t)filesize;
  344. }
  345. void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
  346. uint32_t count = 0;
  347. uint32_t num = 0;
  348. FPGA_DESELECT();
  349. file_open(filename, FA_CREATE_ALWAYS | FA_WRITE);
  350. if(file_res) {
  351. uart_putc(0x30+file_res);
  352. }
  353. while(count<sram_size) {
  354. set_mcu_addr(base_addr+count);
  355. FPGA_SELECT();
  356. FPGA_TX_BYTE(0x88); /* read */
  357. for(int j=0; j<sizeof(file_buf); j++) {
  358. FPGA_WAIT_RDY();
  359. file_buf[j] = FPGA_RX_BYTE();
  360. count++;
  361. }
  362. FPGA_DESELECT();
  363. num = file_write();
  364. if(file_res) {
  365. uart_putc(0x30+file_res);
  366. }
  367. }
  368. file_close();
  369. }
  370. uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
  371. uint8_t data;
  372. uint32_t count;
  373. uint32_t crc;
  374. crc=0;
  375. crc_valid=1;
  376. set_mcu_addr(base_addr);
  377. FPGA_SELECT();
  378. FPGA_TX_BYTE(0x88);
  379. for(count=0; count<size; count++) {
  380. FPGA_WAIT_RDY();
  381. data = FPGA_RX_BYTE();
  382. if(get_snes_reset()) {
  383. crc_valid = 0;
  384. break;
  385. }
  386. crc += crc32_update(crc, data);
  387. }
  388. FPGA_DESELECT();
  389. return crc;
  390. }
  391. uint8_t sram_reliable() {
  392. uint16_t score=0;
  393. uint32_t val;
  394. uint8_t result = 0;
  395. /*while(score<SRAM_RELIABILITY_SCORE) {
  396. if(sram_readlong(SRAM_SCRATCHPAD)==val) {
  397. score++;
  398. } else {
  399. set_pwr_led(0);
  400. score=0;
  401. }
  402. } */
  403. for(uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++) {
  404. val=sram_readlong(SRAM_SCRATCHPAD);
  405. if(val==0x12345678) {
  406. score++;
  407. } else {
  408. printf("i=%d val=%08lX\n", i, val);
  409. }
  410. }
  411. if(score<SRAM_RELIABILITY_SCORE) {
  412. result = 0;
  413. /* dprintf("score=%d\n", score); */
  414. } else {
  415. result = 1;
  416. }
  417. rdyled(result);
  418. return result;
  419. }
  420. void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
  421. set_mcu_addr(base_addr);
  422. FPGA_SELECT();
  423. FPGA_TX_BYTE(0x98);
  424. for(uint32_t i=0; i<len; i++) {
  425. FPGA_TX_BYTE(val);
  426. FPGA_WAIT_RDY();
  427. }
  428. FPGA_DESELECT();
  429. }
  430. uint64_t sram_gettime(uint32_t base_addr) {
  431. set_mcu_addr(base_addr);
  432. FPGA_SELECT();
  433. FPGA_TX_BYTE(0x88);
  434. uint8_t data;
  435. uint64_t result = 0LL;
  436. /* 1st nibble is the century - 10 (binary)
  437. 4th nibble is the month (binary)
  438. all other fields are BCD */
  439. for(int i=0; i<12; i++) {
  440. FPGA_WAIT_RDY();
  441. data = FPGA_RX_BYTE();
  442. data &= 0xf;
  443. switch(i) {
  444. case 0:
  445. result = (result << 4) | ((data / 10) + 1);
  446. result = (result << 4) | (data % 10);
  447. break;
  448. case 3:
  449. result = (result << 4) | ((data / 10));
  450. result = (result << 4) | (data % 10);
  451. break;
  452. default:
  453. result = (result << 4) | data;
  454. }
  455. }
  456. FPGA_DESELECT();
  457. return result & 0x00ffffffffffffffLL;
  458. }
  459. void load_dspx(const uint8_t *filename, uint8_t coretype) {
  460. UINT bytes_read;
  461. DWORD filesize;
  462. uint16_t word_cnt;
  463. uint8_t wordsize_cnt = 0;
  464. uint16_t sector_remaining = 0;
  465. uint16_t sector_cnt = 0;
  466. uint16_t pgmsize = 0;
  467. uint16_t datsize = 0;
  468. uint32_t pgmdata = 0;
  469. uint16_t datdata = 0;
  470. if(coretype & FEAT_ST0010) {
  471. datsize = 1536;
  472. pgmsize = 2048;
  473. } else if (coretype & FEAT_DSPX) {
  474. datsize = 1024;
  475. pgmsize = 2048;
  476. } else if (coretype & FEAT_CX4) {
  477. datsize = 0;
  478. pgmsize = 1024; /* Cx4 data ROM */
  479. } else {
  480. printf("load_dspx: unknown core (%02x)!\n", coretype);
  481. }
  482. file_open((uint8_t*)filename, FA_READ);
  483. filesize = file_handle.fsize;
  484. if(file_res) {
  485. printf("Could not read %s: error %d\n", filename, file_res);
  486. return;
  487. }
  488. fpga_reset_dspx_addr();
  489. for(word_cnt = 0; word_cnt < pgmsize;) {
  490. if(!sector_remaining) {
  491. bytes_read = file_read();
  492. sector_remaining = bytes_read;
  493. sector_cnt = 0;
  494. }
  495. pgmdata = (pgmdata << 8) | file_buf[sector_cnt];
  496. sector_cnt++;
  497. wordsize_cnt++;
  498. sector_remaining--;
  499. if(wordsize_cnt == 3){
  500. wordsize_cnt = 0;
  501. word_cnt++;
  502. fpga_write_dspx_pgm(pgmdata);
  503. }
  504. }
  505. wordsize_cnt = 0;
  506. if(coretype & FEAT_ST0010) {
  507. file_seek(0xc000);
  508. sector_remaining = 0;
  509. }
  510. for(word_cnt = 0; word_cnt < datsize;) {
  511. if(!sector_remaining) {
  512. bytes_read = file_read();
  513. sector_remaining = bytes_read;
  514. sector_cnt = 0;
  515. }
  516. datdata = (datdata << 8) | file_buf[sector_cnt];
  517. sector_cnt++;
  518. wordsize_cnt++;
  519. sector_remaining--;
  520. if(wordsize_cnt == 2){
  521. wordsize_cnt = 0;
  522. word_cnt++;
  523. fpga_write_dspx_dat(datdata);
  524. }
  525. }
  526. fpga_reset_dspx_addr();
  527. file_close();
  528. }