123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- #include <arm/NXP/LPC17xx/LPC17xx.h>
- #include <string.h>
- #include "config.h"
- #include "obj/autoconf.h"
- #include "clock.h"
- #include "uart.h"
- #include "bits.h"
- #include "power.h"
- #include "timer.h"
- #include "ff.h"
- #include "diskio.h"
- #include "spi.h"
- #include "fileops.h"
- #include "fpga.h"
- #include "fpga_spi.h"
- #include "filetypes.h"
- #include "memory.h"
- #include "snes.h"
- #include "led.h"
- #include "sort.h"
- #include "cic.h"
- #include "tests.h"
- #include "cli.h"
- #include "sdnative.h"
- #include "crc.h"
- #include "smc.h"
- #include "msu1.h"
- #include "rtc.h"
- #include "sysinfo.h"
- #include "cfg.h"
- #define EMC0TOGGLE (3<<4)
- #define MR0R (1<<1)
- int i;
- int sd_offload = 0, ff_sd_offload = 0, sd_offload_tgt = 0;
- int sd_offload_partial = 0;
- int sd_offload_start_mid = 0;
- int sd_offload_end_mid = 0;
- uint16_t sd_offload_partial_start = 0;
- uint16_t sd_offload_partial_end = 0;
- volatile enum diskstates disk_state;
- extern volatile tick_t ticks;
- extern snes_romprops_t romprops;
- extern volatile int reset_changed;
- extern volatile cfg_t CFG;
- enum system_states
- {
- SYS_RTC_STATUS = 0,
- SYS_LAST_STATUS = 1
- };
- int main( void )
- {
- uint8_t card_go = 0;
- uint32_t saved_dir_id;
- uint32_t mem_dir_id;
- uint32_t mem_magic;
- uint8_t cmd = 0;
- uint64_t btime = 0;
- uint32_t filesize = 0;
- uint8_t snes_reset_prev = 0, snes_reset_now = 0, snes_reset_state = 0;
- uint16_t reset_count = 0;
- LPC_GPIO2->FIODIR = BV( 4 ) | BV( 5 );
- LPC_GPIO1->FIODIR = BV( 23 ) | BV( SNES_CIC_PAIR_BIT );
- BITBAND( SNES_CIC_PAIR_REG->FIOSET, SNES_CIC_PAIR_BIT ) = 1;
- LPC_GPIO0->FIODIR = BV( 16 );
- /* connect UART3 on P0[25:26] + SSP0 on P0[15:18] + MAT3.0 on P0[10] */
- LPC_PINCON->PINSEL1 = BV( 18 ) | BV( 19 ) | BV( 20 ) | BV( 21 ) /* UART3 */
- | BV( 3 ) | BV( 5 ); /* SSP0 (FPGA) except SS */
- LPC_PINCON->PINSEL0 = BV( 31 ); /* SSP0 */
- /* | BV(13) | BV(15) | BV(17) | BV(19) SSP1 (SD) */
- /* pull-down CIC data lines */
- LPC_PINCON->PINMODE0 = BV( 0 ) | BV( 1 ) | BV( 2 ) | BV( 3 );
- clock_disconnect(); /* Disable clock */
- snes_init(); /* Set SNES Reset */
- power_init(); /* Enable power block of LPC */
- timer_init(); /* Enable internal timer */
- uart_init(); /* Configure UART */
- fpga_spi_init(); /* Configure FPGA_SPI IOs */
- spi_preinit(); /* Initialise SPI IO */
- led_init(); /* Initialise LEDs IO */
- /* do this last because the peripheral init()s change PCLK dividers */
- clock_init();
- /* Output FPGA clock */
- LPC_PINCON->PINSEL0 |= BV( 20 ) | BV( 21 ); /* MAT3.0 (FPGA clock) */
- led_pwm(); /* Enabke PWM on LED (even if not used...) */
- sdn_init(); /* SD init */
- /* Print banner */
- printf( "\n\nsd2snes mk.2\n============\nfw ver.: " CONFIG_VERSION "\ncpu clock: %d Hz\n", CONFIG_CPU_FREQUENCY );
- /* Init file manager */
- file_init();
- /* */
- cic_init( 0 );
- /* setup timer (fpga clk) */
- LPC_TIM3->TCR = 2;
- LPC_TIM3->CTCR = 0;
- LPC_TIM3->PR = 0;
- LPC_TIM3->EMR = EMC0TOGGLE;
- LPC_TIM3->MCR = MR0R;
- LPC_TIM3->MR0 = 1;
- LPC_TIM3->TCR = 1;
- fpga_init();
- fpga_rompgm();
- sram_writebyte( 0, SRAM_CMD_ADDR );
- while ( 1 ) /* Main loop */
- {
- if ( disk_state == DISK_CHANGED )
- {
- sdn_init(); /* Reinit SD card */
- newcard = 1;
- }
- load_bootrle( SRAM_MENU_ADDR );
- set_saveram_mask( 0xffff );
- set_rom_mask( 0x3fffff );
- set_mapper( 0x7 );
- snes_reset( 0 );
- while ( get_cic_state() == CIC_FAIL )
- {
- rdyled( 0 );
- readled( 0 );
- writeled( 0 );
- delay_ms( 500 );
- rdyled( 1 );
- readled( 1 );
- writeled( 1 );
- delay_ms( 500 );
- }
- /* Wait for valid card inserted */
- card_go = 0;
- while ( !card_go )
- {
- if ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) )
- {
- snes_bootprint( " No SD Card found! \0" );
- while ( disk_status( 0 ) & ( STA_NOINIT | STA_NODISK ) );
- delay_ms( 200 );
- }
- file_open( ( uint8_t * )"/sd2snes/menu.bin", FA_READ );
- if ( file_status != FILE_OK )
- {
- snes_bootprint( " /sd2snes/menu.bin not found! \0" );
- while ( disk_status( 0 ) == RES_OK );
- }
- else
- {
- /* Card found ! */
- card_go = 1;
- }
- file_close();
- }
- snes_bootprint( " Loading ... \0" );
- if ( get_cic_state() == CIC_PAIR )
- {
- printf( "PAIR MODE ENGAGED!\n" );
- cic_pair( CIC_NTSC, CIC_NTSC );
- }
- rdyled( 1 );
- readled( 0 );
- writeled( 0 );
- /* Load user config */
- cfg_load();
- cfg_save();
- sram_writebyte( cfg_is_last_game_valid(), SRAM_STATUS_ADDR + SYS_LAST_STATUS );
- cfg_get_last_game( file_lfn );
- sram_writeblock( strrchr( ( const char * )file_lfn, '/' ) + 1, SRAM_LASTGAME_ADDR, 256 );
- *fs_path = 0;
- get_db_id( &saved_dir_id );
- mem_dir_id = sram_readlong( SRAM_DIRID );
- mem_magic = sram_readlong( SRAM_SCRATCHPAD );
- printf( "mem_magic=%lx mem_dir_id=%lx saved_dir_id=%lx\n", mem_magic, mem_dir_id, saved_dir_id );
- if ( ( mem_magic != 0x12345678 ) || ( mem_dir_id != saved_dir_id ) || ( newcard ) )
- {
- newcard = 0;
- /* generate fs footprint (interesting files only) */
- uint32_t curr_dir_id = scan_dir( fs_path, NULL, 0, 0 );
- printf( "curr dir id = %lx\n", curr_dir_id );
- /* files changed or no database found? */
- if ( ( get_db_id( &saved_dir_id ) != FR_OK ) || saved_dir_id != curr_dir_id )
- {
- uint32_t endaddr, direndaddr;
- /* rebuild database */
- printf( "saved dir id = %lx\n", saved_dir_id );
- printf( "rebuilding database..." );
- snes_bootprint( " rebuilding database ... \0" );
- curr_dir_id = scan_dir( fs_path, NULL, 1, 0 );
- sram_writeblock( &curr_dir_id, SRAM_DB_ADDR, 4 );
- sram_readblock( &endaddr, SRAM_DB_ADDR + 4, 4 );
- sram_readblock( &direndaddr, SRAM_DB_ADDR + 8, 4 );
- printf( "%lx %lx\n", endaddr, direndaddr );
- printf( "sorting database..." );
- snes_bootprint( " sorting database ... \0" );
- sort_all_dir( direndaddr );
- printf( "done\n" );
- snes_bootprint( " saving database ... \0" );
- save_sram( ( uint8_t * )"/sd2snes/sd2snes.db", endaddr - SRAM_DB_ADDR, SRAM_DB_ADDR );
- save_sram( ( uint8_t * )"/sd2snes/sd2snes.dir", direndaddr - ( SRAM_DIR_ADDR ), SRAM_DIR_ADDR );
- fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
- printf( "done\n" );
- }
- else
- {
- printf( "saved dir id = %lx\n", saved_dir_id );
- printf( "different card, consistent db, loading db...\n" );
- fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
- load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
- load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
- }
- sram_writelong( curr_dir_id, SRAM_DIRID );
- sram_writelong( 0x12345678, SRAM_SCRATCHPAD );
- }
- else
- {
- snes_bootprint( " same card, loading db... \n" );
- fpga_pgm( ( uint8_t * )"/sd2snes/fpga_base.bit" );
- load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.db", SRAM_DB_ADDR );
- load_sram_offload( ( uint8_t * )"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR );
- }
- /* cli_loop(); */
- /* load menu */
- fpga_dspx_reset( 1 );
- uart_putc( '(' );
- uart_putcrlf();
- load_rom( ( uint8_t * )"/sd2snes/menu.bin", SRAM_MENU_ADDR, 0 );
- /* force memory size + mapper */
- set_rom_mask( 0x3fffff );
- set_mapper( 0x7 );
- uart_putc( ')' );
- uart_putcrlf();
- sram_writebyte( 0, SRAM_CMD_ADDR );
- snes_bootprint( " same card, loading db... \n" );
- if ( ( rtc_state = rtc_isvalid() ) != RTC_OK )
- {
- printf( "RTC invalid!\n" );
- sram_writebyte( 0xff, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
- set_bcdtime( 0x20120701000000LL );
- set_fpga_time( 0x20120701000000LL );
- invalidate_rtc();
- }
- else
- {
- printf( "RTC valid!\n" );
- sram_writebyte( 0x00, SRAM_STATUS_ADDR + SYS_RTC_STATUS );
- set_fpga_time( get_bcdtime() );
- }
- sram_memset( SRAM_SYSINFO_ADDR, 13 * 40, 0x20 );
- printf( "SNES GO!\n" );
- snes_reset( 1 );
- fpga_reset_srtc_state();
- delay_ms( SNES_RESET_PULSELEN_MS );
- sram_writebyte( 32, SRAM_CMD_ADDR );
- snes_reset( 0 );
- cmd = 0;
- btime = 0;
- filesize = 0;
- printf( "test sram... " );
- while ( !sram_reliable() )
- {
- cli_entrycheck();
- }
- printf( "ok\nWaiting command from menu...\n" );
- //while(1) {
- // delay_ms(1000);
- // printf("Estimated SNES master clock: %ld Hz\n", get_snes_sysclk());
- //}
- //sram_hexdump(SRAM_DB_ADDR, 0x200);
- //sram_hexdump(SRAM_MENU_ADDR, 0x400);
- while ( !cmd )
- {
- cmd = menu_main_loop();
- printf( "cmd: %d\n", cmd );
- switch ( cmd )
- {
- case SNES_CMD_LOADROM:
- get_selected_name( file_lfn );
- printf( "Selected name: %s\n", file_lfn );
- cfg_save_last_game( file_lfn );
- cfg_set_last_game_valid( 1 );
- cfg_save();
- filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
- printf( "Filesize = %lu\n", filesize );
- break;
- case SNES_CMD_SETRTC:
- /* get time from RAM */
- btime = sram_gettime( SRAM_PARAM_ADDR );
- /* set RTC */
- set_bcdtime( btime );
- set_fpga_time( btime );
- cmd = 0; /* stay in menu loop */
- break;
- case SNES_CMD_SYSINFO:
- /* go to sysinfo loop */
- sysinfo_loop();
- cmd = 0; /* stay in menu loop */
- break;
- case SNES_CMD_LOADSPC:
- /* load SPC file */
- get_selected_name( file_lfn );
- printf( "Selected name: %s\n", file_lfn );
- filesize = load_spc( file_lfn, SRAM_SPC_DATA_ADDR, SRAM_SPC_HEADER_ADDR );
- cmd = 0; /* stay in menu loop */
- break;
- case SNES_CMD_RESET:
- /* process RESET request from SNES */
- printf( "RESET requested by SNES\n" );
- snes_reset_pulse();
- cmd = 0; /* stay in menu loop */
- break;
- case SNES_CMD_LOADLAST:
- cfg_get_last_game( file_lfn );
- printf( "Selected name: %s\n", file_lfn );
- filesize = load_rom( file_lfn, SRAM_ROM_ADDR, LOADROM_WITH_SRAM | LOADROM_WITH_RESET );
- break;
- default:
- printf( "unknown cmd: %d\n", cmd );
- cmd = 0; /* unknown cmd: stay in loop */
- break;
- }
- }
- printf( "loaded %lu bytes\n", filesize );
- printf( "cmd was %x, going to snes main loop\n", cmd );
- if ( romprops.has_msu1 )
- {
- while ( !msu1_loop() );
- prepare_reset();
- continue;
- }
- cmd = 0;
- snes_reset_prev = 0;
- snes_reset_now = 0;
- snes_reset_state = 0;
- reset_count = 0;
- while ( fpga_test() == FPGA_TEST_TOKEN )
- {
- cli_entrycheck();
- sleep_ms( 250 );
- sram_reliable();
- printf( "%s ", get_cic_statename( get_cic_state() ) );
- if ( reset_changed )
- {
- printf( "reset\n" );
- reset_changed = 0;
- fpga_reset_srtc_state();
- }
- snes_reset_now = get_snes_reset();
- if ( snes_reset_now )
- {
- if ( !snes_reset_prev )
- {
- printf( "RESET BUTTON DOWN\n" );
- snes_reset_state = 1;
- reset_count = 0;
- }
- }
- else
- {
- if ( snes_reset_prev )
- {
- printf( "RESET BUTTON UP\n" );
- snes_reset_state = 0;
- }
- }
- if ( snes_reset_state )
- {
- reset_count++;
- }
- else
- {
- sram_reliable();
- snes_main_loop();
- }
- if ( reset_count > 4 )
- {
- reset_count = 0;
- prepare_reset();
- break;
- }
- snes_reset_prev = snes_reset_now;
- }
- /* fpga test fail: panic */
- if ( fpga_test() != FPGA_TEST_TOKEN )
- {
- led_panic();
- }
- /* else reset */
- }
- }
|