main.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. #include <arm/NXP/LPC17xx/LPC17xx.h>
  2. #include <string.h>
  3. #include "config.h"
  4. #include "obj/autoconf.h"
  5. #include "clock.h"
  6. #include "uart.h"
  7. #include "bits.h"
  8. #include "power.h"
  9. #include "timer.h"
  10. #include "ff.h"
  11. #include "diskio.h"
  12. #include "spi.h"
  13. #include "fileops.h"
  14. #include "fpga.h"
  15. #include "fpga_spi.h"
  16. #include "filetypes.h"
  17. #include "memory.h"
  18. #include "snes.h"
  19. #include "led.h"
  20. #include "sort.h"
  21. #include "cic.h"
  22. #include "tests.h"
  23. #include "cli.h"
  24. #include "sdnative.h"
  25. #include "crc.h"
  26. #include "smc.h"
  27. #include "msu1.h"
  28. #include "rtc.h"
  29. #include "sysinfo.h"
  30. #include "cfg.h"
  31. #define EMC0TOGGLE (3<<4)
  32. #define MR0R (1<<1)
  33. int i;
  34. int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
  35. int sd_offload_partial = 0;
  36. int sd_offload_start_mid = 0;
  37. int sd_offload_end_mid = 0;
  38. uint16_t sd_offload_partial_start = 0;
  39. uint16_t sd_offload_partial_end = 0;
  40. volatile enum diskstates disk_state;
  41. extern volatile tick_t ticks;
  42. extern snes_romprops_t romprops;
  43. extern volatile int reset_changed;
  44. extern volatile cfg_t CFG;
  45. enum system_states
  46. {
  47. SYS_RTC_STATUS = 0,
  48. SYS_LAST_STATUS = 1
  49. };
  50. int main( void )
  51. {
  52. uint8_t card_go = 0;
  53. uint32_t saved_dir_id;
  54. uint32_t mem_dir_id;
  55. uint32_t mem_magic;
  56. uint8_t cmd = 0;
  57. uint64_t btime = 0;
  58. uint32_t filesize = 0;
  59. uint8_t snes_reset_prev = 0, snes_reset_now = 0, snes_reset_state = 0;
  60. uint16_t reset_count = 0;
  61. LPC_GPIO2->FIODIR = BV( 4 ) | BV( 5 );
  62. LPC_GPIO1->FIODIR = BV( 23 ) | BV( SNES_CIC_PAIR_BIT );
  63. BITBAND( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1;
  64. LPC_GPIO0->FIODIR = BV( 16 );
  65. /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
  66. LPC_PINCON->PINSEL1 = BV( 18 ) | BV( 19 ) | BV( 20 ) | BV( 21 ) /* UART3 */
  67. | BV( 3 ) | BV( 5 ); /* SSP0 (FPGA) except SS */
  68. LPC_PINCON->PINSEL0 = BV( 31 ); /* SSP0 */
  69. /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
  70. /* pull-down CIC data lines */
  71. LPC_PINCON->PINMODE0 = BV( 0 ) | BV( 1 ) | BV( 2 ) | BV( 3 );
  72. clock_disconnect(); /* Disable clock */
  73. snes_init(); /* Set SNES Reset */
  74. power_init(); /* Enable power block of LPC */
  75. timer_init(); /* Enable internal timer */
  76. uart_init(); /* Configure UART */
  77. fpga_spi_init(); /* Configure FPGA_SPI IOs */
  78. spi_preinit(); /* Initialise SPI IO */
  79. led_init(); /* Initialise LEDs IO */
  80. /* do this last because the peripheral init()s change PCLK dividers */
  81. clock_init();
  82. /* Output FPGA clock */
  83. LPC_PINCON->PINSEL0 |= BV( 20 ) | BV( 21 ); /* MAT3.0 (FPGA clock) */
  84. led_pwm(); /* Enabke PWM on LED (even if not used...) */
  85. sdn_init(); /* SD init */
  86. /* Print banner */
  87. printf( "\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY );
  88. /* Init file manager */
  89. file_init();
  90. /* */
  91. cic_init( 0 );
  92. /* setup timer (fpga clk) */
  93. LPC_TIM3->TCR = 2;
  94. LPC_TIM3->CTCR = 0;
  95. LPC_TIM3->PR = 0;
  96. LPC_TIM3->EMR = EMC0TOGGLE;
  97. LPC_TIM3->MCR = MR0R;
  98. LPC_TIM3->MR0 = 1;
  99. LPC_TIM3->TCR = 1;
  100. fpga_init();
  101. fpga_rompgm();
  102. sram_writebyte( 0, SRAM_CMD_ADDR );
  103. while ( 1 ) /* Main loop */
  104. {
  105. if ( disk_state == DISK_CHANGED )
  106. {
  107. sdn_init(); /* Reinit SD card */
  108. newcard = 1;
  109. }
  110. load_bootrle( SRAM_MENU_ADDR );
  111. set_saveram_mask( 0xffff );
  112. set_rom_mask( 0x3fffff );
  113. set_mapper( 0x7 );
  114. snes_reset( 0 );
  115. while ( get_cic_state() == CIC_FAIL )
  116. {
  117. rdyled( 0 );
  118. readled( 0 );
  119. writeled( 0 );
  120. delay_ms( 500 );
  121. rdyled( 1 );
  122. readled( 1 );
  123. writeled( 1 );
  124. delay_ms( 500 );
  125. }
  126. /* Wait for valid card inserted */
  127. card_go = 0;
  128. while ( !card_go )
  129. {
  130. if ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) )
  131. {
  132. snes_bootprint( " No SD Card found! \0" );
  133. while ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) );
  134. delay_ms( 200 );
  135. }
  136. file_open( ( uint8_t * )"/sd2snes/menu.bin", FA_READ );
  137. if ( file_status != FILE_OK )
  138. {
  139. snes_bootprint( " /sd2snes/menu.bin not found! \0" );
  140. while ( disk_status( 0 ) == RES_OK );
  141. }
  142. else
  143. {
  144. /* Card found ! */
  145. card_go = 1;
  146. }
  147. file_close();
  148. }
  149. snes_bootprint( " Loading ... \0" );
  150. if ( get_cic_state() == CIC_PAIR )
  151. {
  152. printf( "PAIR MODE ENGAGED!\n" );
  153. cic_pair( CIC_NTSC, CIC_NTSC );
  154. }
  155. rdyled( 1 );
  156. readled( 0 );
  157. writeled( 0 );
  158. /* Load user config */
  159. cfg_load();
  160. cfg_save();
  161. sram_writebyte( cfg_is_last_game_valid(), SRAM_STATUS_ADDR + SYS_LAST_STATUS );
  162. cfg_get_last_game( file_lfn );
  163. sram_writeblock( strrchr( ( const char * )file_lfn, '/' ) + 1, SRAM_LASTGAME_ADDR, 256 );
  164. *fs_path = 0;
  165. get_db_id( &saved_dir_id );
  166. mem_dir_id = sram_readlong( SRAM_DIRID );
  167. mem_magic = sram_readlong( SRAM_SCRATCHPAD );
  168. printf( "mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id );
  169. if ( ( mem_magic != 0x12345678 ) || ( mem_dir_id != saved_dir_id ) || ( newcard ) )
  170. {
  171. newcard = 0;
  172. /* generate fs footprint (interesting files only) */
  173. uint32_t curr_dir_id = scan_dir( fs_path, NULL, 0, 0 );
  174. printf( "curr dir id = %lx\n", curr_dir_id );
  175. /* files changed or no database found? */
  176. if ( ( get_db_id( &saved_dir_id ) != FR_OK ) || saved_dir_id != curr_dir_id )
  177. {
  178. uint32_t endaddr, direndaddr;
  179. /* rebuild database */
  180. printf( "saved dir id = %lx\n", saved_dir_id );
  181. printf( "rebuilding database..." );
  182. snes_bootprint( " rebuilding database ... \0" );
  183. curr_dir_id = scan_dir( fs_path, NULL, 1, 0 );
  184. sram_writeblock( &curr_dir_id, SRAM_DB_ADDR, 4 );
  185. sram_readblock( &endaddr, SRAM_DB_ADDR + 4, 4 );
  186. sram_readblock( &direndaddr, SRAM_DB_ADDR + 8, 4 );
  187. printf( "%lx %lx\n", endaddr, direndaddr );
  188. printf( "sorting database..." );
  189. snes_bootprint( " sorting database ... \0" );
  190. sort_all_dir( direndaddr );
  191. printf( "done\n" );
  192. snes_bootprint( " saving database ... \0" );
  193. save_sram( ( uint8_t * )"/sd2snes/sd2snes.db", endaddr - SRAM_DB_ADDR, SRAM_DB_ADDR );
  194. save_sram( ( uint8_t * )"/sd2snes/sd2snes.dir", direndaddr - ( SRAM_DIR_ADDR ), SRAM_DIR_ADDR );
  195. fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
  196. printf( "done\n" );
  197. }
  198. else
  199. {
  200. printf( "saved dir id = %lx\n", saved_dir_id );
  201. printf( "different card, consistent db, loading db...\n" );
  202. fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
  203. load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
  204. load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
  205. }
  206. sram_writelong( curr_dir_id, SRAM_DIRID );
  207. sram_writelong( 0x12345678, SRAM_SCRATCHPAD );
  208. }
  209. else
  210. {
  211. snes_bootprint( " same card, loading db... \n" );
  212. fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
  213. load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
  214. load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
  215. }
  216. /* cli_loop(); */
  217. /* load menu */
  218. fpga_dspx_reset( 1 );
  219. uart_putc( '(' );
  220. uart_putcrlf();
  221. load_rom( ( uint8_t * )"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0 );
  222. /* force memory size + mapper */
  223. set_rom_mask( 0x3fffff );
  224. set_mapper( 0x7 );
  225. uart_putc( ')' );
  226. uart_putcrlf();
  227. sram_writebyte( 0, SRAM_CMD_ADDR );
  228. snes_bootprint( " same card, loading db... \n" );
  229. if ( ( rtc_state = rtc_isvalid() ) != RTC_OK )
  230. {
  231. printf( "RTC invalid!\n" );
  232. sram_writebyte( 0xff, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
  233. set_bcdtime( 0x20120701000000LL );
  234. set_fpga_time( 0x20120701000000LL );
  235. invalidate_rtc();
  236. }
  237. else
  238. {
  239. printf( "RTC valid!\n" );
  240. sram_writebyte( 0x00, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
  241. set_fpga_time( get_bcdtime() );
  242. }
  243. sram_memset( SRAM_SYSINFO_ADDR, 13 * 40, 0x20 );
  244. printf( "SNES GO!\n" );
  245. snes_reset( 1 );
  246. fpga_reset_srtc_state();
  247. delay_ms( SNES_RESET_PULSELEN_MS );
  248. sram_writebyte( 32, SRAM_CMD_ADDR );
  249. snes_reset( 0 );
  250. cmd = 0;
  251. btime = 0;
  252. filesize = 0;
  253. printf( "test sram... " );
  254. while ( !sram_reliable() )
  255. {
  256. cli_entrycheck();
  257. }
  258. printf( "ok\nWaiting command from menu...\n" );
  259. //while(1) {
  260. // delay_ms(1000);
  261. // printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
  262. //}
  263. //sram_hexdump(SRAM_DB_ADDR, 0x200);
  264. //sram_hexdump(SRAM_MENU_ADDR, 0x400);
  265. while ( !cmd )
  266. {
  267. cmd = menu_main_loop();
  268. printf( "cmd: %d\n", cmd );
  269. switch ( cmd )
  270. {
  271. case SNES_CMD_LOADROM:
  272. get_selected_name( file_lfn );
  273. printf( "Selected name: %s\n", file_lfn );
  274. cfg_save_last_game( file_lfn );
  275. cfg_set_last_game_valid( 1 );
  276. cfg_save();
  277. filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
  278. printf( "Filesize = %lu\n", filesize );
  279. break;
  280. case SNES_CMD_SETRTC:
  281. /* get time from RAM */
  282. btime = sram_gettime( SRAM_PARAM_ADDR );
  283. /* set RTC */
  284. set_bcdtime( btime );
  285. set_fpga_time( btime );
  286. cmd = 0; /* stay in menu loop */
  287. break;
  288. case SNES_CMD_SYSINFO:
  289. /* go to sysinfo loop */
  290. sysinfo_loop();
  291. cmd = 0; /* stay in menu loop */
  292. break;
  293. case SNES_CMD_LOADSPC:
  294. /* load SPC file */
  295. get_selected_name( file_lfn );
  296. printf( "Selected name: %s\n", file_lfn );
  297. filesize = load_spc( file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR );
  298. cmd = 0; /* stay in menu loop */
  299. break;
  300. case SNES_CMD_RESET:
  301. /* process RESET request from SNES */
  302. printf( "RESET requested by SNES\n" );
  303. snes_reset_pulse();
  304. cmd = 0; /* stay in menu loop */
  305. break;
  306. case SNES_CMD_LOADLAST:
  307. cfg_get_last_game( file_lfn );
  308. printf( "Selected name: %s\n", file_lfn );
  309. filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
  310. break;
  311. default:
  312. printf( "unknown cmd: %d\n", cmd );
  313. cmd = 0; /* unknown cmd: stay in loop */
  314. break;
  315. }
  316. }
  317. printf( "loaded %lu bytes\n", filesize );
  318. printf( "cmd was %x, going to snes main loop\n", cmd );
  319. if ( romprops.has_msu1 )
  320. {
  321. while ( !msu1_loop() );
  322. prepare_reset();
  323. continue;
  324. }
  325. cmd = 0;
  326. snes_reset_prev = 0;
  327. snes_reset_now = 0;
  328. snes_reset_state = 0;
  329. reset_count = 0;
  330. while ( fpga_test() == FPGA_TEST_TOKEN )
  331. {
  332. cli_entrycheck();
  333. sleep_ms( 250 );
  334. sram_reliable();
  335. printf( "%s ", get_cic_statename( get_cic_state() ) );
  336. if ( reset_changed )
  337. {
  338. printf( "reset\n" );
  339. reset_changed = 0;
  340. fpga_reset_srtc_state();
  341. }
  342. snes_reset_now = get_snes_reset();
  343. if ( snes_reset_now )
  344. {
  345. if ( !snes_reset_prev )
  346. {
  347. printf( "RESET BUTTON DOWN\n" );
  348. snes_reset_state = 1;
  349. reset_count = 0;
  350. }
  351. }
  352. else
  353. {
  354. if ( snes_reset_prev )
  355. {
  356. printf( "RESET BUTTON UP\n" );
  357. snes_reset_state = 0;
  358. }
  359. }
  360. if ( snes_reset_state )
  361. {
  362. reset_count++;
  363. }
  364. else
  365. {
  366. sram_reliable();
  367. snes_main_loop();
  368. }
  369. if ( reset_count > 4 )
  370. {
  371. reset_count = 0;
  372. prepare_reset();
  373. break;
  374. }
  375. snes_reset_prev = snes_reset_now;
  376. }
  377. /* fpga test fail: panic */
  378. if ( fpga_test() != FPGA_TEST_TOKEN )
  379. {
  380. led_panic();
  381. }
  382. /* else reset */
  383. }
  384. }