Browse Source

firmware: FPGA "RTC" interface + offload SRAM loading

ikari 13 years ago
parent
commit
00c6ed254e
7 changed files with 74 additions and 11 deletions
  1. 16 2
      src/fpga_spi.c
  2. 2 0
      src/fpga_spi.h
  3. 8 6
      src/main.c
  4. 22 3
      src/memory.c
  5. 1 0
      src/memory.h
  6. 22 0
      src/rtc.c
  7. 3 0
      src/rtc.h

+ 16 - 2
src/fpga_spi.c

@@ -69,7 +69,9 @@
 	E3	-		reset DAC playback pointer (0)
 	E4	hhll		set MSU read pointer
 
-	E5	tt{12}		set RTC (SRTC/SPC7110 format)
+	E5	tt{7}		set RTC (SPC7110 format + 1000s of year,
+				         nibbles packed)
+                                eg 0x20111210094816 is 2011-12-10, 9:48:16
 	E6	ssrr		set/reset BS-X status register [7:0]
 	F0	-		receive test token (to see if FPGA is alive)
 	F1	-		receive status (16bit, MSB first), see below
@@ -321,4 +323,16 @@ void set_bsx_regs(uint8_t set, uint8_t reset) {
   FPGA_DESELECT();
 }
 
-
+void set_fpga_time(uint64_t time) {
+  FPGA_SELECT();
+  FPGA_TX_BYTE(0xe5);
+  FPGA_TX_BYTE((time >> 48) & 0xff);
+  FPGA_TX_BYTE((time >> 40) & 0xff);
+  FPGA_TX_BYTE((time >> 32) & 0xff);
+  FPGA_TX_BYTE((time >> 24) & 0xff);
+  FPGA_TX_BYTE((time >> 16) & 0xff);
+  FPGA_TX_BYTE((time >> 8) & 0xff);
+  FPGA_TX_BYTE(time & 0xff);
+  FPGA_TX_BYTE(0x00);
+  FPGA_DESELECT();
+}

+ 2 - 0
src/fpga_spi.h

@@ -73,4 +73,6 @@ uint16_t get_msu_track(void);
 uint32_t get_msu_offset(void);
 uint32_t get_snes_sysclk(void);
 void set_bsx_regs(uint8_t set, uint8_t reset);
+void set_fpga_time(uint64_t time);
+
 #endif

+ 8 - 6
src/main.c

@@ -94,6 +94,7 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
     set_rom_mask(0x3fffff);
     set_mapper(0x7);
     set_mcu_ovr(0);
+    delay_ms(100);
     snes_reset(0);
     while(get_cic_state() == CIC_FAIL) {
       rdyled(0);
@@ -139,6 +140,7 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
 
     uint32_t mem_dir_id = sram_readlong(SRAM_DIRID);
     uint32_t mem_magic = sram_readlong(SRAM_SCRATCHPAD);
+    fpga_pgm((uint8_t*)"/main.bit.rle");
     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;
@@ -169,18 +171,18 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
       } else {
 	printf("saved dir id = %lx\n", saved_dir_id);
 	printf("different card, consistent db, loading db...\n");
-	load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
-	load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
+	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 {
       printf("same card, loading db...\n");
-      load_sram((uint8_t*)"/sd2snes/sd2snes.db", SRAM_DB_ADDR);
-      load_sram((uint8_t*)"/sd2snes/sd2snes.dir", SRAM_DIR_ADDR);
+      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_pgm((uint8_t*)"/main.bit.rle");
 
     uart_putc('(');
     load_rom((uint8_t*)"/sd2snes/menu.bin", SRAM_MENU_ADDR);
@@ -223,7 +225,7 @@ printf("PCONP=%lx\n", LPC_SC->PCONP);
 	case SNES_CMD_LOADROM:
 	  get_selected_name(file_lfn);
 	  set_mcu_ovr(1);
-// strcpy((char*)file_lfn, "/roms/b/BS Zelda no Densetsu Kodai no Sekiban Dai 1 Hanashi (J).smc");
+// strcpy((char*)file_lfn, "/bs3-1.smc");
 	  printf("Selected name: %s\n", file_lfn);
 	  filesize = load_rom(file_lfn, SRAM_ROM_ADDR);
 	  if(romprops.ramsize_bytes) {

+ 22 - 3
src/memory.c

@@ -211,21 +211,23 @@ ticks_read+=getticks()-tickstmp;
 ticks_total=getticks()-ticksstart;
   printf("%u ticks in read, %u ticks in tx, %u ticks total\n", ticks_read, ticks_tx, ticks_total);
   if(romprops.mapper_id==3) {
+    printf("BSX Flash cart image\n");
     printf("attempting to load BSX BIOS /sd2snes/bsxbios.sfc...\n");
-    load_sram((uint8_t*)"/sd2snes/bsxbios.sfc", 0x800000);
+    load_sram_offload((uint8_t*)"/sd2snes/bsxbios.sfc", 0x800000);
     printf("Type: %02x\n", romprops.header.destcode);
     set_bsx_regs(0xc0, 0x3f);
     uint16_t rombase;
     if(romprops.header.ramsize & 1) {
       rombase = 0xff00;
-//      set_bsx_regs(0xf6, 0x09);
+//      set_bsx_regs(0x36, 0xc9);
     } else {
       rombase = 0x7f00;
-//      set_bsx_regs(0xf4, 0x0b);
+//      set_bsx_regs(0x34, 0xcb);
     }
     sram_writebyte(0x33, rombase+0xda);
     sram_writebyte(0x00, rombase+0xd4);
     sram_writebyte(0xfc, rombase+0xd5);
+    set_fpga_time(0x0020110212180500LL);
   }
   uint32_t rammask;
   uint32_t rommask;
@@ -247,6 +249,23 @@ ticks_total=getticks()-ticksstart;
   return (uint32_t)filesize;
 }
 
+uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr) {
+  set_mcu_addr(base_addr);
+  UINT bytes_read;
+  DWORD filesize;
+  file_open(filename, FA_READ);
+  filesize = file_handle.fsize;
+  if(file_res) return 0;
+  for(;;) {
+    ff_sd_offload=1;
+    sd_offload_tgt=0;
+    bytes_read = file_read();
+    if (file_res || !bytes_read) break;
+  }
+  file_close();
+  return (uint32_t)filesize;
+}
+
 uint32_t load_sram(uint8_t* filename, uint32_t base_addr) {
   set_mcu_addr(base_addr);
   UINT bytes_read;

+ 1 - 0
src/memory.h

@@ -45,6 +45,7 @@
 
 uint32_t load_rom(uint8_t* filename, uint32_t base_addr);
 uint32_t load_sram(uint8_t* filename, uint32_t base_addr);
+uint32_t load_sram_offload(uint8_t* filename, uint32_t base_addr);
 uint32_t load_sram_rle(uint8_t* filename, uint32_t base_addr);
 uint32_t load_bootrle(uint32_t base_addr);
 void sram_hexdump(uint32_t addr, uint32_t len);

+ 22 - 0
src/rtc.c

@@ -52,3 +52,25 @@ uint32_t get_fattime(void) {
     ((uint32_t)time.tm_min)   << 5  |
     ((uint32_t)time.tm_sec)   >> 1;
 }
+
+uint64_t get_bcdtime(void) {
+  struct tm time;
+  read_rtc(&time);
+  uint16_t year = time.tm_year + 1900;
+
+  return ((uint64_t)(time.tm_wday % 7) << 56)
+         |((uint64_t)((year / 1000) % 10) << 52)
+         |((uint64_t)((year / 100) % 10) << 48)
+         |((uint64_t)((year / 10) % 10) << 44)
+         |((uint64_t)(year % 10) << 40)
+         |((uint64_t)(time.tm_mon / 10) << 36)
+         |((uint64_t)(time.tm_mon % 10) << 32)
+         |((time.tm_mday / 10) << 28)
+         |((time.tm_mday % 10) << 24)
+         |((time.tm_hour / 10) << 20)
+         |((time.tm_hour % 10) << 16)
+         |((time.tm_min / 10) << 12)
+         |((time.tm_min % 10) << 8)
+         |((time.tm_sec / 10) << 4)
+         |(time.tm_sec % 10);
+}

+ 3 - 0
src/rtc.h

@@ -59,4 +59,7 @@ void read_rtc(struct tm *time);
 /* Set time from struct tm */
 void set_rtc(struct tm *time);
 
+/* get current time in 60-bit BCD format (WYYYYMMDDHHMMSS) (W=DOW) */
+uint64_t get_bcdtime(void);
+
 #endif