memory.c 20 KB

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