snes.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. snes.c: SNES hardware control and monitoring
  19. */
  20. #include <arm/NXP/LPC17xx/LPC17xx.h>
  21. #include <string.h>
  22. #include "bits.h"
  23. #include "config.h"
  24. #include "uart.h"
  25. #include "snes.h"
  26. #include "memory.h"
  27. #include "fileops.h"
  28. #include "ff.h"
  29. #include "led.h"
  30. #include "smc.h"
  31. #include "timer.h"
  32. #include "cli.h"
  33. #include "fpga.h"
  34. #include "fpga_spi.h"
  35. uint8_t initloop = 1;
  36. uint32_t saveram_crc, saveram_crc_old;
  37. extern snes_romprops_t romprops;
  38. volatile int reset_changed;
  39. volatile int reset_pressed;
  40. void prepare_reset()
  41. {
  42. snes_reset( 1 );
  43. delay_ms( SNES_RESET_PULSELEN_MS );
  44. if ( romprops.ramsize_bytes && fpga_test() == FPGA_TEST_TOKEN )
  45. {
  46. writeled( 1 );
  47. save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
  48. writeled( 0 );
  49. }
  50. rdyled( 1 );
  51. readled( 1 );
  52. writeled( 1 );
  53. snes_reset( 0 );
  54. while ( get_snes_reset() );
  55. snes_reset( 1 );
  56. fpga_dspx_reset( 1 );
  57. delay_ms( 200 );
  58. }
  59. void snes_init()
  60. {
  61. /* put reset level on reset pin */
  62. BITBAND( SNES_RESET_REG->FIOCLR, SNES_RESET_BIT ) = 1;
  63. /* reset the SNES */
  64. snes_reset( 1 );
  65. }
  66. void snes_reset_pulse()
  67. {
  68. snes_reset( 1 );
  69. delay_ms( SNES_RESET_PULSELEN_MS );
  70. snes_reset( 0 );
  71. }
  72. /*
  73. * sets the SNES reset state.
  74. *
  75. * state: put SNES in reset state when 1, release when 0
  76. */
  77. void snes_reset( int state )
  78. {
  79. BITBAND( SNES_RESET_REG->FIODIR, SNES_RESET_BIT ) = state;
  80. }
  81. /*
  82. * gets the SNES reset state.
  83. *
  84. * returns: 1 when reset, 0 when not reset
  85. */
  86. uint8_t get_snes_reset()
  87. {
  88. return !BITBAND( SNES_RESET_REG->FIOPIN, SNES_RESET_BIT );
  89. }
  90. /*
  91. * SD2SNES main loop.
  92. * monitors SRAM changes and other things
  93. */
  94. uint32_t diffcount = 0, samecount = 0, didnotsave = 0;
  95. uint8_t sram_valid = 0;
  96. void snes_main_loop()
  97. {
  98. if ( !romprops.ramsize_bytes )
  99. {
  100. return;
  101. }
  102. if ( initloop )
  103. {
  104. saveram_crc_old = calc_sram_crc( SRAM_SAVE_ADDR, romprops.ramsize_bytes );
  105. initloop = 0;
  106. }
  107. saveram_crc = calc_sram_crc( SRAM_SAVE_ADDR, romprops.ramsize_bytes );
  108. sram_valid = sram_reliable();
  109. if ( crc_valid && sram_valid )
  110. {
  111. if ( saveram_crc != saveram_crc_old )
  112. {
  113. if ( samecount )
  114. {
  115. diffcount = 1;
  116. }
  117. else
  118. {
  119. diffcount++;
  120. didnotsave++;
  121. }
  122. samecount = 0;
  123. }
  124. if ( saveram_crc == saveram_crc_old )
  125. {
  126. samecount++;
  127. }
  128. if ( diffcount >= 1 && samecount == 5 )
  129. {
  130. printf( "SaveRAM CRC: 0x%04lx; saving %s\n", saveram_crc, file_lfn );
  131. writeled( 1 );
  132. save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
  133. writeled( 0 );
  134. didnotsave = 0;
  135. }
  136. if ( didnotsave > 50 )
  137. {
  138. printf( "periodic save (sram contents keep changing...)\n" );
  139. diffcount = 0;
  140. writeled( 1 );
  141. save_sram( file_lfn, romprops.ramsize_bytes, SRAM_SAVE_ADDR );
  142. didnotsave = 0;
  143. writeled( 1 );
  144. }
  145. saveram_crc_old = saveram_crc;
  146. }
  147. printf( "crc=%lx crc_valid=%d sram_valid=%d diffcount=%ld samecount=%ld, didnotsave=%ld\n", saveram_crc, crc_valid,
  148. sram_valid, diffcount, samecount, didnotsave );
  149. }
  150. /*
  151. * SD2SNES menu loop.
  152. * monitors menu selection. return when selection was made.
  153. */
  154. uint8_t menu_main_loop()
  155. {
  156. uint8_t cmd = 0;
  157. sram_writebyte( 0, SRAM_CMD_ADDR );
  158. while ( !cmd )
  159. {
  160. if ( !get_snes_reset() )
  161. {
  162. while ( !sram_reliable() )
  163. {
  164. printf( "hurr\n" );
  165. }
  166. cmd = sram_readbyte( SRAM_CMD_ADDR );
  167. //cmd = SNES_CMD_LOADSPC;
  168. }
  169. if ( get_snes_reset() )
  170. {
  171. cmd = 0;
  172. }
  173. sleep_ms( 20 );
  174. cli_entrycheck();
  175. }
  176. return cmd;
  177. }
  178. void get_selected_name( uint8_t *fn )
  179. {
  180. uint32_t addr;
  181. addr = sram_readlong( SRAM_PARAM_ADDR );
  182. printf( "fd addr=%lx\n", addr );
  183. sram_readblock( fn, addr + 7 + SRAM_MENU_ADDR, 256 );
  184. //memcpy(fn, "dossier sans titre/ff6.sfc", 28);
  185. }
  186. void snes_bootprint( void *msg )
  187. {
  188. printf( "SNES SAY: %s\n", ( char * )msg );
  189. sram_writeblock( msg, SRAM_CMD_ADDR, 33 );
  190. }
  191. void snes_menu_errmsg( int err, void *msg )
  192. {
  193. printf( "%d: %s\n", err, ( char * )msg );
  194. sram_writeblock( msg, SRAM_CMD_ADDR + 1, 64 );
  195. sram_writebyte( err, SRAM_CMD_ADDR );
  196. }