main.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  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. LPC_GPIO2->FIODIR = BV(4) | BV(5);
  53. LPC_GPIO1->FIODIR = BV(23) | BV(SNES_CIC_PAIR_BIT);
  54. BITBAND(SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT) = 1;
  55. LPC_GPIO0->FIODIR = BV(16);
  56. /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
  57. LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
  58. | BV(3) | BV(5); /* SSP0 (FPGA) except SS */
  59. LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
  60. /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
  61. /* pull-down CIC data lines */
  62. LPC_PINCON->PINMODE0 = BV(0) | BV(1) | BV(2) | BV(3);
  63. clock_disconnect();
  64. snes_init();
  65. snes_reset(1);
  66. power_init();
  67. timer_init();
  68. uart_init();
  69. fpga_spi_init();
  70. spi_preinit();
  71. led_init();
  72. /* do this last because the peripheral init()s change PCLK dividers */
  73. clock_init();
  74. LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
  75. led_pwm();
  76. sdn_init();
  77. printf("\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
  78. printf("PCONP=%lx\n", LPC_SC->PCONP);
  79. file_init();
  80. cic_init(0);
  81. /* setup timer (fpga clk) */
  82. LPC_TIM3->TCR=2;
  83. LPC_TIM3->CTCR=0;
  84. LPC_TIM3->PR=0;
  85. LPC_TIM3->EMR=EMC0TOGGLE;
  86. LPC_TIM3->MCR=MR0R;
  87. LPC_TIM3->MR0=1;
  88. LPC_TIM3->TCR=1;
  89. fpga_init();
  90. fpga_rompgm();
  91. sram_writebyte(0, SRAM_CMD_ADDR);
  92. while(1) {
  93. if(disk_state == DISK_CHANGED) {
  94. sdn_init();
  95. newcard = 1;
  96. }
  97. load_bootrle(SRAM_MENU_ADDR);
  98. set_saveram_mask(0x1fff);
  99. set_rom_mask(0x3fffff);
  100. set_mapper(0x7);
  101. snes_reset(0);
  102. while(get_cic_state() == CIC_FAIL) {
  103. rdyled(0);
  104. readled(0);
  105. writeled(0);
  106. delay_ms(500);
  107. rdyled(1);
  108. readled(1);
  109. writeled(1);
  110. delay_ms(500);
  111. }
  112. /* some sanity checks */
  113. uint8_t card_go = 0;
  114. while(!card_go) {
  115. if(disk_status(0) & (STA_NOINIT|STA_NODISK))
  116. {
  117. snes_bootprint(" No SD Card found! \0");
  118. while(disk_status(0) & (STA_NOINIT|STA_NODISK));
  119. delay_ms(200);
  120. }
  121. file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
  122. if(file_status != FILE_OK)
  123. {
  124. snes_bootprint(" /sd2snes/menu.bin not found! \0");
  125. while(disk_status(0) == RES_OK);
  126. }
  127. else
  128. {
  129. card_go = 1;
  130. }
  131. file_close();
  132. }
  133. snes_bootprint(" Loading ... \0");
  134. if(get_cic_state() == CIC_PAIR) {
  135. printf("PAIR MODE ENGAGED!\n");
  136. cic_pair(CIC_NTSC, CIC_NTSC);
  137. }
  138. rdyled(1);
  139. readled(0);
  140. writeled(0);
  141. cfg_load();
  142. cfg_save();
  143. sram_writebyte(cfg_is_last_game_valid(), SRAM_STATUS_ADDR+SYS_LAST_STATUS);
  144. cfg_get_last_game(file_lfn);
  145. sram_writeblock(strrchr((const char*)file_lfn, '/')+1, SRAM_LASTGAME_ADDR, 256);
  146. *fs_path=0;
  147. uint32_t saved_dir_id;
  148. get_db_id(&saved_dir_id);
  149. uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
  150. uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
  151. printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
  152. if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
  153. newcard = 0;
  154. /* generate fs footprint (interesting files only) */
  155. uint32_t curr_dir_id = scan_dir(fs_path, NULL, 0, 0);
  156. printf("curr dir id = %lx\n", curr_dir_id);
  157. /* files changed or no database found? */
  158. if((get_db_id(&saved_dir_id) != FR_OK)
  159. || saved_dir_id != curr_dir_id) {
  160. /* rebuild database */
  161. printf("saved dir id = %lx\n", saved_dir_id);
  162. printf("rebuilding database...");
  163. snes_bootprint(" rebuilding database ... \0");
  164. curr_dir_id = scan_dir(fs_path, NULL, 1, 0);
  165. sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
  166. uint32_t endaddr, direndaddr;
  167. sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
  168. sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
  169. printf("%lx %lx\n", endaddr, direndaddr);
  170. printf("sorting database...");
  171. snes_bootprint(" sorting database ... \0");
  172. sort_all_dir(direndaddr);
  173. printf("done\n");
  174. snes_bootprint(" saving database ... \0");
  175. save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
  176. save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
  177. fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
  178. printf("done\n");
  179. } else {
  180. printf("saved dir id = %lx\n", saved_dir_id);
  181. printf("different card, consistent db, loading db...\n");
  182. fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
  183. load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
  184. load_sram_offload((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
  185. }
  186. sram_writelong(curr_dir_id, SRAM_DIRID);
  187. sram_writelong(0x12345678, SRAM_SCRATCHPAD);
  188. } else {
  189. snes_bootprint(" same card, loading db... \0");
  190. printf("same card, loading db...\n");
  191. fpga_pgm((uint8_t*)"/sd2snes/fpga_base.bit");
  192. load_sram_offload((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
  193. load_sram_offload((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
  194. }
  195. /* cli_loop(); */
  196. /* load menu */
  197. fpga_dspx_reset(1);
  198. uart_putc('(');
  199. load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0);
  200. /* force memory size + mapper */
  201. set_rom_mask(0x3fffff);
  202. set_mapper(0x7);
  203. uart_putc(')');
  204. uart_putcrlf();
  205. sram_writebyte(0, SRAM_CMD_ADDR);
  206. if((rtc_state = rtc_isvalid()) != RTC_OK) {
  207. printf("RTC invalid!\n");
  208. sram_writebyte(0xff, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
  209. set_bcdtime(0x20120701000000LL);
  210. set_fpga_time(0x20120701000000LL);
  211. invalidate_rtc();
  212. } else {
  213. printf("RTC valid!\n");
  214. sram_writebyte(0x00, SRAM_STATUS_ADDR+SYS_RTC_STATUS);
  215. set_fpga_time(get_bcdtime());
  216. }
  217. sram_memset(SRAM_SYSINFO_ADDR, 13*40, 0x20);
  218. printf("SNES GO!\n");
  219. snes_reset(1);
  220. fpga_reset_srtc_state();
  221. delay_ms(SNES_RESET_PULSELEN_MS);
  222. sram_writebyte(32, SRAM_CMD_ADDR);
  223. snes_reset(0);
  224. uint8_t cmd = 0;
  225. uint64_t btime = 0;
  226. uint32_t filesize=0;
  227. printf("test sram\n");
  228. while(!sram_reliable()) cli_entrycheck();
  229. printf("ok\n");
  230. //while(1) {
  231. // delay_ms(1000);
  232. // printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
  233. //}
  234. //sram_hexdump(SRAM_DB_ADDR, 0x200);
  235. //sram_hexdump(SRAM_MENU_ADDR, 0x400);
  236. while(!cmd) {
  237. cmd=menu_main_loop();
  238. printf("cmd: %d\n", cmd);
  239. uart_putc('-');
  240. switch(cmd) {
  241. case SNES_CMD_LOADROM:
  242. get_selected_name(file_lfn);
  243. printf("Selected name: %s\n", file_lfn);
  244. cfg_save_last_game(file_lfn);
  245. cfg_set_last_game_valid(1);
  246. cfg_save();
  247. filesize = load_rom(file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET);
  248. printf("Filesize = %lu\n", filesize);
  249. break;
  250. case SNES_CMD_SETRTC:
  251. /* get time from RAM */
  252. btime = sram_gettime(SRAM_PARAM_ADDR);
  253. /* set RTC */
  254. set_bcdtime(btime);
  255. set_fpga_time(btime);
  256. cmd=0; /* stay in menu loop */
  257. break;
  258. case SNES_CMD_SYSINFO:
  259. /* go to sysinfo loop */
  260. sysinfo_loop();
  261. cmd=0; /* stay in menu loop */
  262. break;
  263. case SNES_CMD_LOADSPC:
  264. /* load SPC file */
  265. get_selected_name(file_lfn);
  266. printf("Selected name: %s\n", file_lfn);
  267. filesize = load_spc(file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR);
  268. cmd=0; /* stay in menu loop */
  269. break;
  270. case SNES_CMD_RESET:
  271. /* process RESET request from SNES */
  272. printf("RESET requested by SNES\n");
  273. snes_reset_pulse();
  274. cmd=0; /* stay in menu loop */
  275. break;
  276. case SNES_CMD_LOADLAST:
  277. cfg_get_last_game(file_lfn);
  278. printf("Selected name: %s\n", file_lfn);
  279. filesize = load_rom(file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET);
  280. break;
  281. default:
  282. printf("unknown cmd: %d\n", cmd);
  283. cmd=0; /* unknown cmd: stay in loop */
  284. break;
  285. }
  286. }
  287. printf("loaded %lu bytes\n", filesize);
  288. printf("cmd was %x, going to snes main loop\n", cmd);
  289. if(romprops.has_msu1) {
  290. while(!msu1_loop());
  291. prepare_reset();
  292. continue;
  293. }
  294. cmd=0;
  295. uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
  296. uint16_t reset_count=0;
  297. while(fpga_test() == FPGA_TEST_TOKEN)
  298. {
  299. cli_entrycheck();
  300. sleep_ms(250);
  301. sram_reliable();
  302. printf("%s ", get_cic_statename(get_cic_state()));
  303. if(reset_changed)
  304. {
  305. printf("reset\n");
  306. reset_changed = 0;
  307. fpga_reset_srtc_state();
  308. }
  309. snes_reset_now = get_snes_reset();
  310. if (snes_reset_now)
  311. {
  312. if (!snes_reset_prev)
  313. {
  314. printf("RESET BUTTON DOWN\n");
  315. snes_reset_state = 1;
  316. reset_count = 0;
  317. }
  318. }
  319. else
  320. {
  321. if (snes_reset_prev)
  322. {
  323. printf("RESET BUTTON UP\n");
  324. snes_reset_state = 0;
  325. }
  326. }
  327. if (snes_reset_state)
  328. {
  329. reset_count++;
  330. } else {
  331. sram_reliable();
  332. snes_main_loop();
  333. }
  334. if(reset_count>4) {
  335. reset_count=0;
  336. prepare_reset();
  337. break;
  338. }
  339. snes_reset_prev = snes_reset_now;
  340. }
  341. /* fpga test fail: panic */
  342. if(fpga_test() != FPGA_TEST_TOKEN){
  343. led_panic();
  344. }
  345. /* else reset */
  346. }
  347. }