main.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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 "usb_hid.h"
  29. #define EMC0TOGGLE (3<<4)
  30. #define MR0R (1<<1)
  31. int i;
  32. int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
  33. int sd_offload_partial = 0;
  34. uint16_t sd_offload_partial_start = 0;
  35. uint16_t sd_offload_partial_end = 0;
  36. /* FIXME HACK */
  37. volatile enum diskstates disk_state;
  38. extern volatile tick_t ticks;
  39. extern snes_romprops_t romprops;
  40. int main(void) {
  41. LPC_GPIO2->FIODIR = BV(0) | BV(1) | BV(2);
  42. LPC_GPIO1->FIODIR = 0;
  43. LPC_GPIO0->FIODIR = BV(16);
  44. /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
  45. LPC_PINCON->PINSEL1 = BV(18) | BV(19) | BV(20) | BV(21) /* UART3 */
  46. | BV(3) | BV(5); /* SSP0 (FPGA) except SS */
  47. LPC_PINCON->PINSEL0 = BV(31); /* SSP0 */
  48. /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
  49. /* pull-down CIC data lines */
  50. LPC_PINCON->PINMODE3 = BV(18) | BV(19) | BV(20) | BV(21);
  51. clock_disconnect();
  52. snes_init();
  53. snes_reset(1);
  54. power_init();
  55. timer_init();
  56. uart_init();
  57. fpga_spi_init();
  58. spi_preinit();
  59. led_init();
  60. /* do this last because the peripheral init()s change PCLK dividers */
  61. clock_init();
  62. LPC_PINCON->PINSEL0 |= BV(20) | BV(21); /* MAT3.0 (FPGA clock) */
  63. led_pwm();
  64. sdn_init();
  65. printf("\n\nsd2snes mk.2\n============\nfw ver.: " VER "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY);
  66. printf("PCONP=%lx\n", LPC_SC->PCONP);
  67. file_init();
  68. cic_init(0);
  69. /* setup timer (fpga clk) */
  70. LPC_TIM3->CTCR=0;
  71. LPC_TIM3->EMR=EMC0TOGGLE;
  72. LPC_TIM3->MCR=MR0R;
  73. LPC_TIM3->MR0=1;
  74. LPC_TIM3->TCR=1;
  75. fpga_init();
  76. fpga_rompgm();
  77. sram_writebyte(0, SRAM_CMD_ADDR);
  78. while(1) {
  79. set_mcu_ovr(1);
  80. if(disk_state == DISK_CHANGED) {
  81. sdn_init();
  82. newcard = 1;
  83. }
  84. load_bootrle(SRAM_MENU_ADDR);
  85. set_saveram_mask(0x1fff);
  86. set_rom_mask(0x3fffff);
  87. set_mapper(0x7);
  88. set_mcu_ovr(0);
  89. snes_reset(0);
  90. while(get_cic_state() == CIC_FAIL) {
  91. rdyled(0);
  92. readled(0);
  93. writeled(0);
  94. delay_ms(500);
  95. rdyled(1);
  96. readled(1);
  97. writeled(1);
  98. delay_ms(500);
  99. }
  100. /* some sanity checks */
  101. uint8_t card_go = 0;
  102. while(!card_go) {
  103. if(disk_status(0) & (STA_NOINIT|STA_NODISK)) {
  104. snes_bootprint(" No Card! \0");
  105. while(disk_status(0) & (STA_NOINIT|STA_NODISK));
  106. delay_ms(200);
  107. }
  108. file_open((uint8_t*)"/sd2snes/menu.bin", FA_READ);
  109. if(file_status != FILE_OK) {
  110. snes_bootprint(" /sd2snes/menu.bin not found! \0");
  111. while(disk_status(0) == RES_OK);
  112. } else {
  113. card_go = 1;
  114. }
  115. file_close();
  116. }
  117. snes_bootprint(" Loading ... \0");
  118. if(get_cic_state() == CIC_PAIR) {
  119. printf("PAIR MODE ENGAGED!\n");
  120. cic_pair(CIC_PAL, CIC_NTSC);
  121. }
  122. rdyled(1);
  123. readled(0);
  124. writeled(0);
  125. /* exclusive mode */
  126. set_mcu_ovr(1);
  127. *fs_path=0;
  128. uint32_t saved_dir_id;
  129. get_db_id(&saved_dir_id);
  130. uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
  131. uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
  132. printf("mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id);
  133. if((mem_magic != 0x12345678) || (mem_dir_id != saved_dir_id) || (newcard)) {
  134. newcard = 0;
  135. /* generate fs footprint (interesting files only) */
  136. uint32_t curr_dir_id = scan_dir(fs_path, 0, 0);
  137. printf("curr dir id = %lx\n", curr_dir_id);
  138. /* files changed or no database found? */
  139. if((get_db_id(&saved_dir_id) != FR_OK)
  140. || saved_dir_id != curr_dir_id) {
  141. /* rebuild database */
  142. printf("saved dir id = %lx\n", saved_dir_id);
  143. printf("rebuilding database...");
  144. snes_bootprint(" rebuilding database ... \0");
  145. curr_dir_id = scan_dir(fs_path, 1, 0);
  146. sram_writeblock(&curr_dir_id, SRAM_DB_ADDR, 4);
  147. uint32_t endaddr, direndaddr;
  148. sram_readblock(&endaddr, SRAM_DB_ADDR+4, 4);
  149. sram_readblock(&direndaddr, SRAM_DB_ADDR+8, 4);
  150. printf("%lx %lx\n", endaddr, direndaddr);
  151. printf("sorting database...");
  152. snes_bootprint(" sorting database ... \0");
  153. sort_all_dir(direndaddr);
  154. printf("done\n");
  155. snes_bootprint(" saving database ... \0");
  156. save_sram((uint8_t*)"/sd2snes/sd2snes.db", endaddr-SRAM_DB_ADDR, SRAM_DB_ADDR);
  157. save_sram((uint8_t*)"/sd2snes/sd2snes.dir", direndaddr-(SRAM_DIR_ADDR), SRAM_DIR_ADDR);
  158. printf("done\n");
  159. } else {
  160. printf("saved dir id = %lx\n", saved_dir_id);
  161. printf("different card, consistent db, loading db...\n");
  162. load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
  163. load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
  164. }
  165. sram_writelong(curr_dir_id, SRAM_DIRID);
  166. sram_writelong(0x12345678, SRAM_SCRATCHPAD);
  167. } else {
  168. printf("same card, loading db...\n");
  169. load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
  170. load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
  171. }
  172. /* load menu */
  173. fpga_pgm((uint8_t*)"/main.bit.rle");
  174. uart_putc('(');
  175. load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
  176. /* force memory size + mapper */
  177. set_rom_mask(0x3fffff);
  178. set_mapper(0x7);
  179. uart_putc(')');
  180. uart_putcrlf();
  181. sram_writebyte(0, SRAM_CMD_ADDR);
  182. /* shared mode */
  183. set_mcu_ovr(0);
  184. printf("SNES GO!\n");
  185. snes_reset(1);
  186. delay_ms(1);
  187. snes_reset(0);
  188. uint8_t cmd = 0;
  189. uint32_t filesize=0;
  190. sram_writebyte(32, SRAM_CMD_ADDR);
  191. printf("test sram\n");
  192. while(!sram_reliable());
  193. printf("ok\n");
  194. //while(1) {
  195. // delay_ms(1000);
  196. // printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
  197. //}
  198. //sram_hexdump(SRAM_DB_ADDR, 0x200);
  199. //sram_hexdump(SRAM_MENU_ADDR, 0x400);
  200. while(!cmd) {
  201. cmd=menu_main_loop();
  202. // cmd = 1;
  203. printf("cmd: %d\n", cmd);
  204. sleep_ms(50);
  205. uart_putc('-');
  206. switch(cmd) {
  207. case SNES_CMD_LOADROM:
  208. get_selected_name(file_lfn);
  209. set_mcu_ovr(1);
  210. // strcpy((char*)file_lfn, "/roms/b/BS Zelda no Densetsu Kodai no Sekiban Dai 1 Hanashi (J).smc");
  211. printf("Selected name: %s\n", file_lfn);
  212. filesize = load_rom(file_lfn, SRAM_ROM_ADDR);
  213. if(romprops.ramsize_bytes) {
  214. strcpy(strrchr((char*)file_lfn, (int)'.'), ".srm");
  215. printf("SRM file: %s\n", file_lfn);
  216. load_sram(file_lfn, SRAM_SAVE_ADDR);
  217. } else {
  218. printf("No SRAM\n");
  219. }
  220. set_mcu_ovr(0);
  221. snes_reset(1);
  222. delay_ms(10);
  223. snes_reset(0);
  224. break;
  225. case SNES_CMD_SETRTC:
  226. cmd=0; /* stay in loop */
  227. break;
  228. default:
  229. printf("unknown cmd: %d\n", cmd);
  230. cmd=0; /* unknown cmd: stay in loop */
  231. break;
  232. }
  233. }
  234. printf("cmd was %x, going to snes main loop\n", cmd);
  235. /* always try MSU1 for now */
  236. if(msu1_entrycheck_and_loop()) {
  237. prepare_reset();
  238. continue;
  239. }
  240. cmd=0;
  241. uint8_t snes_reset_prev=0, snes_reset_now=0, snes_reset_state=0;
  242. uint16_t reset_count=0;
  243. while(fpga_test() == FPGA_TEST_TOKEN) {
  244. cli_entrycheck();
  245. sleep_ms(250);
  246. sram_reliable();
  247. printf("%s ", get_cic_statename(get_cic_state()));
  248. snes_reset_now=get_snes_reset();
  249. if(snes_reset_now) {
  250. if(!snes_reset_prev) {
  251. printf("RESET BUTTON DOWN\n");
  252. snes_reset_state=1;
  253. reset_count=0;
  254. }
  255. } else {
  256. if(snes_reset_prev) {
  257. printf("RESET BUTTON UP\n");
  258. snes_reset_state=0;
  259. }
  260. }
  261. if(snes_reset_state) {
  262. reset_count++;
  263. } else {
  264. sram_reliable();
  265. snes_main_loop();
  266. }
  267. if(reset_count>4) {
  268. reset_count=0;
  269. prepare_reset();
  270. break;
  271. }
  272. snes_reset_prev = snes_reset_now;
  273. }
  274. /* fpga test fail: panic */
  275. if(fpga_test() != FPGA_TEST_TOKEN){
  276. led_panic();
  277. }
  278. /* else reset */
  279. }
  280. }