memory.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  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, addr);
  47. }
  48. }
  49. void sram_writebyte(uint8_t val, uint32_t addr) {
  50. printf("WriteB %8Xh @%08lXh\n", val, addr);
  51. set_mcu_addr(addr);
  52. FPGA_SELECT();
  53. FPGA_TX_BYTE(0x98); /* WRITE */
  54. FPGA_TX_BYTE(val);
  55. FPGA_WAIT_RDY();
  56. FPGA_DESELECT();
  57. }
  58. uint8_t sram_readbyte(uint32_t addr) {
  59. set_mcu_addr(addr);
  60. FPGA_SELECT();
  61. FPGA_TX_BYTE(0x88); /* READ */
  62. FPGA_WAIT_RDY();
  63. uint8_t val = FPGA_RX_BYTE();
  64. FPGA_DESELECT();
  65. //printf(" ReadB %8Xh @%08lXh\n", val, addr);
  66. return val;
  67. }
  68. void sram_writeshort(uint16_t val, uint32_t addr) {
  69. printf("WriteS %8Xh @%08lXh\n", val, addr);
  70. set_mcu_addr(addr);
  71. FPGA_SELECT();
  72. FPGA_TX_BYTE(0x98); /* WRITE */
  73. FPGA_TX_BYTE(val&0xff);
  74. FPGA_WAIT_RDY();
  75. FPGA_TX_BYTE((val>>8)&0xff);
  76. FPGA_WAIT_RDY();
  77. FPGA_DESELECT();
  78. }
  79. void sram_writelong(uint32_t val, uint32_t addr) {
  80. printf("WriteL %8lXh @%08lXh\n", val, addr);
  81. set_mcu_addr(addr);
  82. FPGA_SELECT();
  83. FPGA_TX_BYTE(0x98); /* WRITE */
  84. FPGA_TX_BYTE(val&0xff);
  85. FPGA_WAIT_RDY();
  86. FPGA_TX_BYTE((val>>8)&0xff);
  87. FPGA_WAIT_RDY();
  88. FPGA_TX_BYTE((val>>16)&0xff);
  89. FPGA_WAIT_RDY();
  90. FPGA_TX_BYTE((val>>24)&0xff);
  91. FPGA_WAIT_RDY();
  92. FPGA_DESELECT();
  93. }
  94. uint16_t sram_readshort(uint32_t addr) {
  95. set_mcu_addr(addr);
  96. FPGA_SELECT();
  97. FPGA_TX_BYTE(0x88);
  98. FPGA_WAIT_RDY();
  99. uint32_t val = FPGA_RX_BYTE();
  100. FPGA_WAIT_RDY();
  101. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  102. FPGA_DESELECT();
  103. //printf(" ReadS %8lXh @%08lXh\n", val, addr);
  104. return val;
  105. }
  106. uint32_t sram_readlong(uint32_t addr) {
  107. set_mcu_addr(addr);
  108. FPGA_SELECT();
  109. FPGA_TX_BYTE(0x88);
  110. FPGA_WAIT_RDY();
  111. uint32_t val = FPGA_RX_BYTE();
  112. FPGA_WAIT_RDY();
  113. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  114. FPGA_WAIT_RDY();
  115. val |= ((uint32_t)FPGA_RX_BYTE()<<16);
  116. FPGA_WAIT_RDY();
  117. val |= ((uint32_t)FPGA_RX_BYTE()<<24);
  118. FPGA_DESELECT();
  119. //printf(" ReadL %8lXh @%08lXh\n", val, addr);
  120. return val;
  121. }
  122. void sram_readlongblock(uint32_t* buf, uint32_t addr, uint16_t count) {
  123. set_mcu_addr(addr);
  124. FPGA_SELECT();
  125. FPGA_TX_BYTE(0x88);
  126. uint16_t i=0;
  127. while(i<count) {
  128. FPGA_WAIT_RDY();
  129. uint32_t val = (uint32_t)FPGA_RX_BYTE()<<24;
  130. FPGA_WAIT_RDY();
  131. val |= ((uint32_t)FPGA_RX_BYTE()<<16);
  132. FPGA_WAIT_RDY();
  133. val |= ((uint32_t)FPGA_RX_BYTE()<<8);
  134. FPGA_WAIT_RDY();
  135. val |= FPGA_RX_BYTE();
  136. buf[i++] = val;
  137. }
  138. FPGA_DESELECT();
  139. }
  140. void sram_readblock(void* buf, uint32_t addr, uint16_t size) {
  141. uint16_t count=size;
  142. uint8_t* tgt = buf;
  143. set_mcu_addr(addr);
  144. FPGA_SELECT();
  145. FPGA_TX_BYTE(0x88); /* READ */
  146. while(count--) {
  147. FPGA_WAIT_RDY();
  148. *(tgt++) = FPGA_RX_BYTE();
  149. }
  150. FPGA_DESELECT();
  151. }
  152. void sram_readstrn(void* buf, uint32_t addr, uint16_t size) {
  153. uint16_t count=size;
  154. uint8_t* tgt = buf;
  155. set_mcu_addr(addr);
  156. FPGA_SELECT();
  157. FPGA_TX_BYTE(0x88); /* READ */
  158. while(count--) {
  159. FPGA_WAIT_RDY();
  160. if(!(*(tgt++) = FPGA_RX_BYTE())) break;
  161. }
  162. FPGA_DESELECT();
  163. }
  164. void sram_writeblock(void* buf, uint32_t addr, uint16_t size) {
  165. printf("WriteZ %08lX -> %08lX [%d]\n", addr, addr+size, size);
  166. uint16_t count=size;
  167. uint8_t* src = buf;
  168. set_mcu_addr(addr);
  169. FPGA_SELECT();
  170. FPGA_TX_BYTE(0x98); /* WRITE */
  171. while(count--) {
  172. FPGA_TX_BYTE(*src++);
  173. FPGA_WAIT_RDY();
  174. }
  175. FPGA_DESELECT();
  176. }
  177. uint32_t load_rom(uint8_t* filename, uint32_t base_addr, uint8_t flags) {
  178. UINT bytes_read;
  179. DWORD filesize, read_size = 0;
  180. UINT count=0;
  181. tick_t ticksstart, ticks_total=0;
  182. ticksstart=getticks();
  183. printf("%s\n", filename);
  184. file_open(filename, FA_READ);
  185. if(file_res) {
  186. uart_putc('?');
  187. uart_putc(0x30+file_res);
  188. return 0;
  189. }
  190. filesize = file_handle.fsize;
  191. smc_id(&romprops);
  192. file_close();
  193. /* reconfigure FPGA if necessary */
  194. if(romprops.fpga_conf) {
  195. printf("reconfigure FPGA with %s...\n", romprops.fpga_conf);
  196. fpga_pgm((uint8_t*)romprops.fpga_conf);
  197. }
  198. set_mcu_addr(base_addr);
  199. file_open(filename, FA_READ);
  200. ff_sd_offload=1;
  201. sd_offload_tgt=0;
  202. f_lseek(&file_handle, romprops.offset);
  203. for(;;) {
  204. ff_sd_offload=1;
  205. sd_offload_tgt=0;
  206. bytes_read = file_read();
  207. read_size += bytes_read;
  208. if (file_res || !bytes_read) break;
  209. if(!(count++ % 512)) {
  210. uart_putc('.');
  211. }
  212. }
  213. file_close();
  214. printf("Read %ld [%08lX] bytes...\n", read_size, read_size);
  215. set_mapper(romprops.mapper_id);
  216. printf("rom header map: %02x; mapper id: %d\n", romprops.header.map, romprops.mapper_id);
  217. ticks_total=getticks()-ticksstart;
  218. printf("%u ticks total\n", ticks_total);
  219. if(romprops.mapper_id==3) {
  220. printf("BSX Flash cart image\n");
  221. printf("attempting to load BSX BIOS /sd2snes/bsxbios.bin...\n");
  222. load_sram_offload((uint8_t*)"/sd2snes/bsxbios.bin", 0x800000);
  223. printf("attempting to load BS data file /sd2snes/bsxpage.bin...\n");
  224. load_sram_offload((uint8_t*)"/sd2snes/bsxpage.bin", 0x900000);
  225. printf("Type: %02x\n", romprops.header.destcode);
  226. set_bsx_regs(0xc0, 0x3f);
  227. uint16_t rombase;
  228. if(romprops.header.ramsize & 1) {
  229. rombase = 0xff00;
  230. // set_bsx_regs(0x36, 0xc9);
  231. } else {
  232. rombase = 0x7f00;
  233. // set_bsx_regs(0x34, 0xcb);
  234. }
  235. sram_writebyte(0x33, rombase+0xda);
  236. sram_writebyte(0x00, rombase+0xd4);
  237. sram_writebyte(0xfc, rombase+0xd5);
  238. set_fpga_time(0x0220110301180530LL);
  239. }
  240. if(romprops.has_dspx || romprops.has_cx4) {
  241. printf("DSPx game. Loading firmware image %s...\n", romprops.dsp_fw);
  242. load_dspx(romprops.dsp_fw, romprops.fpga_features);
  243. /* fallback to DSP1B firmware if DSP1.bin is not present */
  244. if(file_res && romprops.dsp_fw == DSPFW_1) {
  245. load_dspx(DSPFW_1B, romprops.fpga_features);
  246. }
  247. if(file_res) {
  248. snes_menu_errmsg(MENU_ERR_NODSP, (void*)romprops.dsp_fw);
  249. }
  250. }
  251. uint32_t rammask;
  252. uint32_t rommask;
  253. while(filesize > (romprops.romsize_bytes + romprops.offset)) {
  254. romprops.romsize_bytes <<= 1;
  255. }
  256. if(romprops.header.ramsize == 0) {
  257. rammask = 0;
  258. } else {
  259. rammask = romprops.ramsize_bytes - 1;
  260. }
  261. rommask = romprops.romsize_bytes - 1;
  262. if (rommask >= SRAM_SAVE_ADDR)
  263. rommask = SRAM_SAVE_ADDR - 1;
  264. printf("ramsize=%x rammask=%lx\nromsize=%x rommask=%lx\n", romprops.header.ramsize, rammask, romprops.header.romsize, rommask);
  265. set_saveram_mask(rammask);
  266. set_rom_mask(rommask);
  267. readled(0);
  268. if(flags & LOADROM_WITH_SRAM) {
  269. if(romprops.ramsize_bytes) {
  270. strcpy(strrchr((char*)filename, (int)'.'), ".srm");
  271. printf("SRM file: %s\n", filename);
  272. load_sram(filename, SRAM_SAVE_ADDR);
  273. } else {
  274. printf("No SRAM\n");
  275. }
  276. }
  277. printf("check MSU...");
  278. if(msu1_check(filename)) {
  279. romprops.fpga_features |= FEAT_MSU1;
  280. romprops.has_msu1 = 1;
  281. } else {
  282. romprops.has_msu1 = 0;
  283. }
  284. printf("done\n");
  285. romprops.fpga_features |= FEAT_SRTC;
  286. romprops.fpga_features |= FEAT_213F;
  287. fpga_set_213f(romprops.region);
  288. fpga_set_features(romprops.fpga_features);
  289. if(flags & LOADROM_WITH_RESET) {
  290. fpga_dspx_reset(1);
  291. snes_reset_pulse();
  292. fpga_dspx_reset(0);
  293. }
  294. return (uint32_t)filesize;
  295. }
  296. uint32_t load_spc(uint8_t* filename, uint32_t spc_data_addr, uint32_t spc_header_addr) {
  297. DWORD filesize;
  298. UINT bytes_read;
  299. uint8_t data;
  300. UINT j;
  301. printf("%s\n", filename);
  302. file_open(filename, FA_READ); /* Open SPC file */
  303. if(file_res) return 0;
  304. filesize = file_handle.fsize;
  305. if (filesize < 65920) { /* At this point, we care about filesize only */
  306. file_close(); /* since SNES decides if it is an SPC file */
  307. sram_writebyte(0, spc_header_addr); /* If file is too small, destroy previous SPC header */
  308. return 0;
  309. }
  310. set_mcu_addr(spc_data_addr);
  311. f_lseek(&file_handle, 0x100L); /* Load 64K data segment */
  312. for(;;) {
  313. bytes_read = file_read();
  314. if (file_res || !bytes_read) break;
  315. FPGA_SELECT();
  316. FPGA_TX_BYTE(0x98);
  317. for(j=0; j<bytes_read; j++) {
  318. FPGA_TX_BYTE(file_buf[j]);
  319. FPGA_WAIT_RDY();
  320. }
  321. FPGA_DESELECT();
  322. }
  323. file_close();
  324. file_open(filename, FA_READ); /* Reopen SPC file to reset file_getc state*/
  325. set_mcu_addr(spc_header_addr);
  326. f_lseek(&file_handle, 0x0L); /* Load 256 bytes header */
  327. FPGA_SELECT();
  328. FPGA_TX_BYTE(0x98);
  329. for (j = 0; j < 256; j++) {
  330. data = file_getc();
  331. FPGA_TX_BYTE(data);
  332. FPGA_WAIT_RDY();
  333. }
  334. FPGA_DESELECT();
  335. file_close();
  336. file_open(filename, FA_READ); /* Reopen SPC file to reset file_getc state*/
  337. set_mcu_addr(spc_header_addr+0x100);
  338. f_lseek(&file_handle, 0x10100L); /* Load 128 DSP registers */
  339. FPGA_SELECT();
  340. FPGA_TX_BYTE(0x98);
  341. for (j = 0; j < 128; j++) {
  342. data = file_getc();
  343. FPGA_TX_BYTE(data);
  344. FPGA_WAIT_RDY();
  345. }
  346. FPGA_DESELECT();
  347. file_close(); /* Done ! */
  348. /* clear echo buffer to avoid artifacts */
  349. uint8_t esa = sram_readbyte(spc_header_addr+0x100+0x6d);
  350. uint8_t edl = sram_readbyte(spc_header_addr+0x100+0x7d);
  351. uint8_t flg = sram_readbyte(spc_header_addr+0x100+0x6c);
  352. if(!(flg & 0x20) && (edl & 0x0f)) {
  353. int echo_start = esa << 8;
  354. int echo_length = (edl & 0x0f) << 11;
  355. printf("clearing echo buffer %04x-%04x...\n", echo_start, echo_start+echo_length-1);
  356. sram_memset(spc_data_addr+echo_start, echo_length, 0);
  357. }
  358. return (uint32_t)filesize;
  359. }
  360. uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
  361. set_mcu_addr(base_addr);
  362. UINT bytes_read;
  363. DWORD filesize;
  364. file_open(filename, FA_READ);
  365. filesize = file_handle.fsize;
  366. if(file_res) return 0;
  367. for(;;) {
  368. ff_sd_offload=1;
  369. sd_offload_tgt=0;
  370. bytes_read = file_read();
  371. if (file_res || !bytes_read) break;
  372. }
  373. file_close();
  374. return (uint32_t)filesize;
  375. }
  376. uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
  377. set_mcu_addr(base_addr);
  378. UINT bytes_read;
  379. DWORD filesize;
  380. file_open(filename, FA_READ);
  381. filesize = file_handle.fsize;
  382. if(file_res) {
  383. printf("load_sram: could not open %s, res=%d\n", filename, file_res);
  384. return 0;
  385. }
  386. for(;;) {
  387. bytes_read = file_read();
  388. if (file_res || !bytes_read) break;
  389. FPGA_SELECT();
  390. FPGA_TX_BYTE(0x98);
  391. for(int j=0; j<bytes_read; j++) {
  392. FPGA_TX_BYTE(file_buf[j]);
  393. FPGA_WAIT_RDY();
  394. }
  395. FPGA_DESELECT();
  396. }
  397. file_close();
  398. return (uint32_t)filesize;
  399. }
  400. uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr) {
  401. uint8_t data;
  402. set_mcu_addr(base_addr);
  403. DWORD filesize;
  404. file_open(filename, FA_READ);
  405. filesize = file_handle.fsize;
  406. if(file_res) return 0;
  407. FPGA_SELECT();
  408. FPGA_TX_BYTE(0x98);
  409. for(;;) {
  410. data = rle_file_getc();
  411. if (file_res || file_status) break;
  412. FPGA_TX_BYTE(data);
  413. FPGA_WAIT_RDY();
  414. }
  415. FPGA_DESELECT();
  416. file_close();
  417. return (uint32_t)filesize;
  418. }
  419. uint32_t load_bootrle(uint32_t base_addr) {
  420. uint8_t data;
  421. set_mcu_addr(base_addr);
  422. DWORD filesize = 0;
  423. rle_mem_init(bootrle, sizeof(bootrle));
  424. FPGA_SELECT();
  425. FPGA_TX_BYTE(0x98);
  426. for(;;) {
  427. data = rle_mem_getc();
  428. if(rle_state) break;
  429. FPGA_TX_BYTE(data);
  430. FPGA_WAIT_RDY();
  431. filesize++;
  432. }
  433. FPGA_DESELECT();
  434. return (uint32_t)filesize;
  435. }
  436. void save_sram(uint8_t* filename, uint32_t sram_size, uint32_t base_addr) {
  437. uint32_t count = 0;
  438. //uint32_t num = 0;
  439. FPGA_DESELECT();
  440. file_open(filename, FA_CREATE_ALWAYS | FA_WRITE);
  441. if(file_res) {
  442. uart_putc(0x30+file_res);
  443. }
  444. while(count<sram_size) {
  445. set_mcu_addr(base_addr+count);
  446. FPGA_SELECT();
  447. FPGA_TX_BYTE(0x88); /* read */
  448. for(int j=0; j<sizeof(file_buf); j++) {
  449. FPGA_WAIT_RDY();
  450. file_buf[j] = FPGA_RX_BYTE();
  451. count++;
  452. }
  453. FPGA_DESELECT();
  454. /*num = */file_write();
  455. if(file_res) {
  456. uart_putc(0x30+file_res);
  457. }
  458. }
  459. file_close();
  460. }
  461. uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) {
  462. uint8_t data;
  463. uint32_t count;
  464. uint32_t crc;
  465. crc=0;
  466. crc_valid=1;
  467. set_mcu_addr(base_addr);
  468. FPGA_SELECT();
  469. FPGA_TX_BYTE(0x88);
  470. for(count=0; count<size; count++) {
  471. FPGA_WAIT_RDY();
  472. data = FPGA_RX_BYTE();
  473. if(get_snes_reset()) {
  474. crc_valid = 0;
  475. break;
  476. }
  477. crc += crc32_update(crc, data);
  478. }
  479. FPGA_DESELECT();
  480. return crc;
  481. }
  482. uint8_t sram_reliable() {
  483. uint16_t score=0;
  484. uint32_t val;
  485. uint8_t result = 0;
  486. /*while(score<SRAM_RELIABILITY_SCORE) {
  487. if(sram_readlong(SRAM_SCRATCHPAD)==val) {
  488. score++;
  489. } else {
  490. set_pwr_led(0);
  491. score=0;
  492. }
  493. } */
  494. for(uint16_t i = 0; i < SRAM_RELIABILITY_SCORE; i++) {
  495. val=sram_readlong(SRAM_SCRATCHPAD);
  496. if(val==0x12345678) {
  497. score++;
  498. } //else {
  499. //printf("i=%d val=%08lX\n", i, val);
  500. //}
  501. }
  502. if(score<SRAM_RELIABILITY_SCORE) {
  503. result = 0;
  504. /* dprintf("score=%d\n", score); */
  505. } else {
  506. result = 1;
  507. }
  508. rdyled(result);
  509. return result;
  510. }
  511. void sram_memset(uint32_t base_addr, uint32_t len, uint8_t val) {
  512. set_mcu_addr(base_addr);
  513. FPGA_SELECT();
  514. FPGA_TX_BYTE(0x98);
  515. for(uint32_t i=0; i<len; i++) {
  516. FPGA_TX_BYTE(val);
  517. FPGA_WAIT_RDY();
  518. }
  519. FPGA_DESELECT();
  520. }
  521. uint64_t sram_gettime(uint32_t base_addr) {
  522. set_mcu_addr(base_addr);
  523. FPGA_SELECT();
  524. FPGA_TX_BYTE(0x88);
  525. uint8_t data;
  526. uint64_t result = 0LL;
  527. /* 1st nibble is the century - 10 (binary)
  528. 4th nibble is the month (binary)
  529. all other fields are BCD */
  530. for(int i=0; i<12; i++) {
  531. FPGA_WAIT_RDY();
  532. data = FPGA_RX_BYTE();
  533. data &= 0xf;
  534. switch(i) {
  535. case 0:
  536. result = (result << 4) | ((data / 10) + 1);
  537. result = (result << 4) | (data % 10);
  538. break;
  539. case 3:
  540. result = (result << 4) | ((data / 10));
  541. result = (result << 4) | (data % 10);
  542. break;
  543. default:
  544. result = (result << 4) | data;
  545. }
  546. }
  547. FPGA_DESELECT();
  548. return result & 0x00ffffffffffffffLL;
  549. }
  550. void load_dspx(const uint8_t *filename, uint8_t coretype) {
  551. UINT bytes_read;
  552. //DWORD filesize;
  553. uint16_t word_cnt;
  554. uint8_t wordsize_cnt = 0;
  555. uint16_t sector_remaining = 0;
  556. uint16_t sector_cnt = 0;
  557. uint16_t pgmsize = 0;
  558. uint16_t datsize = 0;
  559. uint32_t pgmdata = 0;
  560. uint16_t datdata = 0;
  561. if(coretype & FEAT_ST0010) {
  562. datsize = 1536;
  563. pgmsize = 2048;
  564. } else if (coretype & FEAT_DSPX) {
  565. datsize = 1024;
  566. pgmsize = 2048;
  567. } else if (coretype & FEAT_CX4) {
  568. datsize = 0;
  569. pgmsize = 1024; /* Cx4 data ROM */
  570. } else {
  571. printf("load_dspx: unknown core (%02x)!\n", coretype);
  572. }
  573. file_open((uint8_t*)filename, FA_READ);
  574. /*filesize = file_handle.fsize;*/
  575. if(file_res) {
  576. printf("Could not read %s: error %d\n", filename, file_res);
  577. return;
  578. }
  579. fpga_reset_dspx_addr();
  580. for(word_cnt = 0; word_cnt < pgmsize;) {
  581. if(!sector_remaining) {
  582. bytes_read = file_read();
  583. sector_remaining = bytes_read;
  584. sector_cnt = 0;
  585. }
  586. pgmdata = (pgmdata << 8) | file_buf[sector_cnt];
  587. sector_cnt++;
  588. wordsize_cnt++;
  589. sector_remaining--;
  590. if(wordsize_cnt == 3){
  591. wordsize_cnt = 0;
  592. word_cnt++;
  593. fpga_write_dspx_pgm(pgmdata);
  594. }
  595. }
  596. wordsize_cnt = 0;
  597. if(coretype & FEAT_ST0010) {
  598. file_seek(0xc000);
  599. sector_remaining = 0;
  600. }
  601. for(word_cnt = 0; word_cnt < datsize;) {
  602. if(!sector_remaining) {
  603. bytes_read = file_read();
  604. sector_remaining = bytes_read;
  605. sector_cnt = 0;
  606. }
  607. datdata = (datdata << 8) | file_buf[sector_cnt];
  608. sector_cnt++;
  609. wordsize_cnt++;
  610. sector_remaining--;
  611. if(wordsize_cnt == 2){
  612. wordsize_cnt = 0;
  613. word_cnt++;
  614. fpga_write_dspx_dat(datdata);
  615. }
  616. }
  617. fpga_reset_dspx_addr();
  618. file_close();
  619. }