From 30997a1c4337f5963fa6e921359bd9c96b8b0dcb Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Thu, 16 Aug 2007 10:03:18 +0000 Subject: [PATCH] - changelog updated - added VFAT support and old files saved - corrected some docs - added SRAM crc calculation after SRAM saving on SDCARD - modified reload_rom actions order - fixed some vdp status bits --- Makefile | 6 +- changelog.txt | 16 +- source/docs/Genesis_ROM_Format.txt | 1 + source/docs/eeprom.txt | 9 +- source/docs/ssf2tnc.txt | 1 - source/ngc/gui/filesel.c | 114 +++--- source/ngc/gui/filesel.c.old | 540 +++++++++++++++++++++++++++++ source/ngc/gui/iso9660.h | 7 +- source/ngc/gui/iso9660.h.old | 44 +++ source/ngc/gui/mcard.c | 1 + source/ngc/gui/rominfo.c | 20 +- source/ngc/gui/rominfo.h | 4 +- source/ngc/loadrom.c | 4 +- source/ngc/unzip.c | 13 +- source/ngc/unzip.c.old | 190 ++++++++++ source/vdp.c | 2 +- 16 files changed, 874 insertions(+), 98 deletions(-) create mode 100644 source/ngc/gui/filesel.c.old create mode 100644 source/ngc/gui/iso9660.h.old create mode 100644 source/ngc/unzip.c.old diff --git a/Makefile b/Makefile index d553855..24ea67a 100644 --- a/Makefile +++ b/Makefile @@ -17,15 +17,15 @@ TARGET := genplus BUILD := build SOURCES := source source/m68k source/cpu source/sound \ - source/ngc source/ngc/gui + source/ngc source/ngc/gui source/ngc/vfat INCLUDES := source source/m68k source/cpu source/sound \ - source/ngc source/ngc/gui + source/ngc source/ngc/gui source/ngc/vfat #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- MACHDEP = -DGEKKO -mcpu=750 -meabi -mhard-float -CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) \ +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -DWORDS_BIGENDIAN \ -DNGC="1" -DGENESIS_HACKS="1" \ LDFLAGS = $(MACHDEP) -mogc -Wl,-Map,$(notdir $@).map -Wl,--cref diff --git a/changelog.txt b/changelog.txt index 1694179..883c32f 100644 --- a/changelog.txt +++ b/changelog.txt @@ -3,23 +3,25 @@ The Genesis Plus Project CHANGELOG: -- completely rewrote EEPROM emulation: added support for all known EEPROM types (24C01-24C65) and mappers (Sega, Acclaim, EA, Codemasters) +- completely rewrote EEPROM emulation: now support all known EEPROM types (24C01-24C65) and mappers (Sega, Acclaim, EA, Codemasters) used in a few games (now use game database) as backup RAM. This should fix SRAM load/save support in the following games: . NBA Jam (alternate Acclaim mapper) - . College Slam, Frank Thomas Big Hurt Baseball (24C016 type) + . College Slam, Frank Thomas Big Hurt Baseball (24C65 type) . NHLPA Hockey 93, Rings of Power (EA mapper) . Micromachines games (Codemasters mapper) - SRAM data is now initialized with 0xFF: fix Micromachines 2, Dino Dini Soccer and maybe more - corrected 16-bits SRAM read/write: fix some Sega Sports and EA Sports games (NFL95, NBA Action 95, NL97, NHL98,...) -- modified WRITE_xxx & READ_xxx macros for better multiple endianness support +- modified WRITE_xxx & READ_xxx macros for portability - rewrote BIG ENDIAN support in render.c and vdp.c: should be a little faster (no more useless word swapping) - fixed leftmost Window/PlaneA column render and implemented window bug (see gen-vdp.txt) - sprite limit emulation and sprite collision detection should be now a little more accurate -- added 9bits (RGB333) pixel color extrapolation to support fullcolor range (0-65535) when using 16bits rendering (RGB 565) +- corrected test before CRAM writes +- removed redundant "color_update()" calls +- added 9bits (RGB333) pixel color extrapolation to cover each color full range (0-31;0-63) in 16bits mode (RGB 565) - completely rewrote interrupt (VINT/HINT) handling: Sesame's Street Counting Cafe now works without any hacks, -other timing sensitive games seem to be ok +other timing sensitive games are ok - modified Hcounter tables: Road Rash games (I,II,III) don't need any timing hacks anymore - corrected VDP latency so it does not interfere with DMA timings anymore @@ -130,10 +132,10 @@ For your information, games that are actually detected and need special timings - modified cpu execution timings, with more correct hblank and interrupts timing (fix ISS Deluxe, Double Dragon 2 and certainly more) (Based on Gens code) - modified busreq mechanism: better synchro between z80 & 68k (no need to dejitter anymore) (Based on Gens code) - added sprite collision detection (fix Strider 2) -- modified dma fill operation according to correct endianness (fix Contra Hardcorps gfx garbage) +- modified dma fill operation for big endian platform (fix Contra Hardcorps gfx garbage) -??? +Based on Softdev's initial releases WIP1.2 unzip.c diff --git a/source/docs/Genesis_ROM_Format.txt b/source/docs/Genesis_ROM_Format.txt index d8cc77f..bf81dc6 100644 --- a/source/docs/Genesis_ROM_Format.txt +++ b/source/docs/Genesis_ROM_Format.txt @@ -1,3 +1,4 @@ + THE COMPLETE DOCUMENTATION ABOUT GENESIS ROM FORMAT diff --git a/source/docs/eeprom.txt b/source/docs/eeprom.txt index 629c754..1b617b1 100644 --- a/source/docs/eeprom.txt +++ b/source/docs/eeprom.txt @@ -1,3 +1,10 @@ +This is the result of testing EEPROM support under Genesis Plus. +Following games use custom external RAM (serial EEPROM) for backup. +It seems that different EEPROM Mapper have been used, depending upon companies. + +Eke~Eke - July 2007 + + ------------------------------------------------------- ACCLAIM (81) ------------------------------------------------------- @@ -16,7 +23,7 @@ SDA_IN : 0x200000 (0) SDA_OUT: 0x200000 (1) SCL : 0x200000 (1) -Note: this game uses a different EEPROM mapper than other Accolade games. +Note: this game uses a different EEPROM mapper than other Acclaim games. Blockbuster World Video Game Championship II (U) diff --git a/source/docs/ssf2tnc.txt b/source/docs/ssf2tnc.txt index cf58e1b..cc1860f 100644 --- a/source/docs/ssf2tnc.txt +++ b/source/docs/ssf2tnc.txt @@ -1,4 +1,3 @@ - --------------------------------------- SSFII GENESIS TECHNICAL INFORMATION Second Edition (July 26, 2000) diff --git a/source/ngc/gui/filesel.c b/source/ngc/gui/filesel.c index 3d5549d..75e98c8 100644 --- a/source/ngc/gui/filesel.c +++ b/source/ngc/gui/filesel.c @@ -24,6 +24,9 @@ #include "iso9660.h" #include "font.h" #include "unzip.h" +#include "diskio.h" +#include "vfat.h" + #define PAGESIZE 12 #define PADCAL 70 @@ -32,13 +35,15 @@ static int maxfiles; u8 havedir = 0; u8 haveSDdir = 0; u8 UseSDCARD = 0; -sd_file *filehandle; char rootSDdir[SDCARD_MAX_PATH_LEN]; int LoadFile (unsigned char *buffer); int offset = 0; int selection = 0; int old_selection = 0; int old_offset = 0; +VFATFS fs; +FSDIRENTRY f; + extern void reloadrom (); @@ -48,16 +53,16 @@ extern void reloadrom (); static void ShowFiles (int offset, int selection) { int i, j; - char text[MAXJOLIET+2]; + char text[MAX_LONG_NAME+2]; ClearScreen (); j = 0; for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) { - memset(text,0,MAXJOLIET+2); - if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].filename + filelist[i].filename_offset); - else sprintf (text, "%s", filelist[i].filename + filelist[i].filename_offset); + memset(text,0,MAX_LONG_NAME+2); + if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].displayname + filelist[i].filename_offset); + else sprintf (text, "%s", filelist[i].displayname + filelist[i].filename_offset); if (j == (selection - offset)) WriteCentre_HL ((j * fheight) + 120, text); else WriteCentre ((j * fheight) + 120, text); @@ -75,48 +80,31 @@ int updateSDdirname() char *test; char temp[1024]; - /* current directory doesn't change */ - if (strcmp(filelist[selection].filename,".") == 0) return 0; /* go up to parent directory */ - else if (strcmp(filelist[selection].filename,"..") == 0) + if (strcmp(filelist[selection].filename,"..") == 0) { /* determine last subdirectory namelength */ sprintf(temp,"%s",rootSDdir); - test= strtok(temp,"\\"); + test= strtok(temp,"/"); while (test != NULL) { size = strlen(test); - test = strtok(NULL,"\\"); + test = strtok(NULL,"/"); } /* remove last subdirectory name */ size = strlen(rootSDdir) - size - 1; rootSDdir[size] = 0; - /* handles root name */ - if (strcmp(rootSDdir,"dev0:") == 0) sprintf(rootSDdir,"dev0:\\genplus\\.."); - return 1; } else { - /* test new directory namelength */ - if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) - { - /* handles root name */ - if (strcmp(rootSDdir,"dev0:\\genplus\\..") == 0) sprintf(rootSDdir,"dev0:"); - /* update current directory name */ - sprintf(rootSDdir, "%s\\%s",rootSDdir, filelist[selection].filename); + sprintf(rootSDdir, "%s/%s",rootSDdir, filelist[selection].filename); return 1; } - else - { - WaitPrompt ("Dirname is too long !"); - return -1; - } - } } /*************************************************************************** @@ -124,30 +112,26 @@ int updateSDdirname() ***************************************************************************/ int parseSDdirectory() { - int entries = 0; int nbfiles = 0; - DIR *sddir = NULL; + FSDIRENTRY fsdir; /* Get a list of files from the actual root directory */ - entries = SDCARD_ReadDir (rootSDdir, &sddir); + int res = VFAT_opendir(0, &fsdir, rootSDdir); - if (entries < 0) entries = 0; - if (entries > MAXFILES) entries = MAXFILES; - - /* Move to DVD structure - this is required for the file selector */ - while (entries) + if (res == FS_SUCCESS) + { + while ( VFAT_readdir(&fsdir) == FS_SUCCESS ) { memset (&filelist[nbfiles], 0, sizeof (FILEENTRIES)); - strncpy(filelist[nbfiles].filename,sddir[nbfiles].fname,MAXJOLIET); - filelist[nbfiles].filename[MAXJOLIET-1] = 0; - filelist[nbfiles].length = sddir[nbfiles].fsize; - filelist[nbfiles].flags = (char)(sddir[nbfiles].fattr & SDCARD_ATTR_DIR); + strcpy(filelist[nbfiles].displayname, fsdir.longname); + strcpy(filelist[nbfiles].filename, fsdir.shortname); + filelist[nbfiles].length = fsdir.fsize; + filelist[nbfiles].flags = fsdir.dirent.attribute & ATTR_DIRECTORY; nbfiles++; - entries--; } - /*** Release memory ***/ - free(sddir); + VFAT_closedir(&fsdir); + } return nbfiles; } @@ -259,7 +243,7 @@ void FileSelector () { filelist[selection].filename_offset = 0; if (((!UseSDCARD) && (basedir == rootdir)) || - (UseSDCARD && strcmp(rootSDdir,"dev0:\\genplus\\..") == 0)) return; + (UseSDCARD && strcmp(rootSDdir,"/") == 0)) return; go_up = 1; } @@ -277,13 +261,14 @@ void FileSelector () if (go_up) { go_up = 0; - selection = 1; + selection = UseSDCARD ? 0 : 1; } /*** This is directory ***/ if (filelist[selection].flags) { - if (UseSDCARD) /* SDCARD directory handler */ + /* SDCARD directory handler */ + if (UseSDCARD) { /* update current directory */ int status = updateSDdirname(); @@ -308,7 +293,6 @@ void FileSelector () offset = 0; } - /* set new entry list */ maxfiles = parseSDdirectory(); if (!maxfiles) @@ -326,7 +310,8 @@ void FileSelector () haveSDdir = 0; } } - else /* DVD directory handler */ + /* DVD directory handler */ + else { /* move to a new directory */ if (selection != 0) @@ -417,6 +402,7 @@ void OpenDVD () int OpenSD () { UseSDCARD = 1; + char msg[20]; if (haveSDdir == 0) { @@ -427,10 +413,18 @@ int OpenSD () old_selection = selection = offset = old_offset = 0; /* Reset SDCARD root directory */ - sprintf(rootSDdir,"dev0:\\genplus\\roms"); + sprintf(rootSDdir,"/genplus/roms"); /* Parse initial root directory and get entries list */ ShowAction("Reading Directory ..."); + int res = VFAT_mount(FS_SLOTA, &fs); + if ( res != FS_TYPE_FAT16 ) + { + sprintf(msg,"Error mounting SDCARD: %d", res); + WaitPrompt (msg); + return 0; + } + if ((maxfiles = parseSDdirectory ())) { /* Select an entry */ @@ -442,7 +436,7 @@ int OpenSD () else { /* no entries found */ - WaitPrompt ("Error reading dev0:\\genplus\\roms"); + WaitPrompt ("Error reading /genplus/roms"); return 0; } } @@ -461,22 +455,14 @@ void GetSDInfo () rootdirlength = 0; /* Check filename length */ - if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) - sprintf(fname, "%s\\%s",rootSDdir,filelist[selection].filename); - - else - { - WaitPrompt ("Maximum Filename Length reached !"); - haveSDdir = 0; // reset everything before next access - } + sprintf(fname, "%s/%s",rootSDdir,filelist[selection].filename); - filehandle = SDCARD_OpenFile (fname, "rb"); - if (filehandle == NULL) + int res = VFAT_fopen(0, &f, fname, FS_READ); + if (res != FS_SUCCESS ) { WaitPrompt ("Unable to open file!"); return; } - rootdirlength = SDCARD_GetFileSize (filehandle); } /**************************************************************************** @@ -507,16 +493,16 @@ int LoadFile (unsigned char *buffer) discoffset = rootdir; ShowAction ("Loading ... Wait"); - if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); + if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); else dvd_read (&readbuffer, 2048, discoffset); if (!IsZipFile ((char *) readbuffer)) { - if (UseSDCARD) SDCARD_SeekFile (filehandle, 0, SDCARD_SEEK_SET); + if (UseSDCARD) VFAT_fseek(&f, 0, SEEK_SET); for (i = 0; i < blocks; i++) { - if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); + if (UseSDCARD) VFAT_fread (&f, readbuffer, 2048); else dvd_read(readbuffer, 2048, discoffset); memcpy (buffer + offset, readbuffer, 2048); offset += 2048; @@ -527,14 +513,14 @@ int LoadFile (unsigned char *buffer) if (rootdirlength % 2048) { i = rootdirlength % 2048; - if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, i); + if (UseSDCARD) VFAT_fread (&f, readbuffer, i); else dvd_read (readbuffer, 2048, discoffset); memcpy (buffer + offset, readbuffer, i); } } else return UnZipBuffer (buffer, discoffset, rootdirlength); - if (UseSDCARD) SDCARD_CloseFile (filehandle); + if (UseSDCARD) VFAT_fclose(&f); return rootdirlength; } diff --git a/source/ngc/gui/filesel.c.old b/source/ngc/gui/filesel.c.old new file mode 100644 index 0000000..3d5549d --- /dev/null +++ b/source/ngc/gui/filesel.c.old @@ -0,0 +1,540 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * File Selection + ***************************************************************************/ +#include "shared.h" +#include "dvd.h" +#include "iso9660.h" +#include "font.h" +#include "unzip.h" + +#define PAGESIZE 12 +#define PADCAL 70 + +static int maxfiles; +u8 havedir = 0; +u8 haveSDdir = 0; +u8 UseSDCARD = 0; +sd_file *filehandle; +char rootSDdir[SDCARD_MAX_PATH_LEN]; +int LoadFile (unsigned char *buffer); +int offset = 0; +int selection = 0; +int old_selection = 0; +int old_offset = 0; + +extern void reloadrom (); + +/*************************************************************************** + * Showfile screen + ***************************************************************************/ +static void ShowFiles (int offset, int selection) +{ + int i, j; + char text[MAXJOLIET+2]; + + ClearScreen (); + j = 0; + + for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) + { + memset(text,0,MAXJOLIET+2); + if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].filename + filelist[i].filename_offset); + else sprintf (text, "%s", filelist[i].filename + filelist[i].filename_offset); + + if (j == (selection - offset)) WriteCentre_HL ((j * fheight) + 120, text); + else WriteCentre ((j * fheight) + 120, text); + j++; + } + SetScreen (); +} + +/*************************************************************************** + * Update SDCARD curent directory name + ***************************************************************************/ +int updateSDdirname() +{ + int size=0; + char *test; + char temp[1024]; + + /* current directory doesn't change */ + if (strcmp(filelist[selection].filename,".") == 0) return 0; + + /* go up to parent directory */ + else if (strcmp(filelist[selection].filename,"..") == 0) + { + /* determine last subdirectory namelength */ + sprintf(temp,"%s",rootSDdir); + test= strtok(temp,"\\"); + while (test != NULL) + { + size = strlen(test); + test = strtok(NULL,"\\"); + } + + /* remove last subdirectory name */ + size = strlen(rootSDdir) - size - 1; + rootSDdir[size] = 0; + + /* handles root name */ + if (strcmp(rootSDdir,"dev0:") == 0) sprintf(rootSDdir,"dev0:\\genplus\\.."); + + return 1; + } + else + { + /* test new directory namelength */ + if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) + { + /* handles root name */ + if (strcmp(rootSDdir,"dev0:\\genplus\\..") == 0) sprintf(rootSDdir,"dev0:"); + + /* update current directory name */ + sprintf(rootSDdir, "%s\\%s",rootSDdir, filelist[selection].filename); + return 1; + } + else + { + WaitPrompt ("Dirname is too long !"); + return -1; + } + } +} + +/*************************************************************************** + * Browse SDCARD subdirectories + ***************************************************************************/ +int parseSDdirectory() +{ + int entries = 0; + int nbfiles = 0; + DIR *sddir = NULL; + + /* Get a list of files from the actual root directory */ + entries = SDCARD_ReadDir (rootSDdir, &sddir); + + if (entries < 0) entries = 0; + if (entries > MAXFILES) entries = MAXFILES; + + /* Move to DVD structure - this is required for the file selector */ + while (entries) + { + memset (&filelist[nbfiles], 0, sizeof (FILEENTRIES)); + strncpy(filelist[nbfiles].filename,sddir[nbfiles].fname,MAXJOLIET); + filelist[nbfiles].filename[MAXJOLIET-1] = 0; + filelist[nbfiles].length = sddir[nbfiles].fsize; + filelist[nbfiles].flags = (char)(sddir[nbfiles].fattr & SDCARD_ATTR_DIR); + nbfiles++; + entries--; + } + + /*** Release memory ***/ + free(sddir); + + return nbfiles; +} + +/**************************************************************************** + * FileSelector + * + * Let user select a file from the File listing + ****************************************************************************/ +void FileSelector () +{ + short p; + signed char a,b; + int haverom = 0; + int redraw = 1; + int go_up = 0; + int i,size; + + while (haverom == 0) + { + if (redraw) ShowFiles (offset, selection); + redraw = 0; + p = PAD_ButtonsDown (0); + a = PAD_StickY (0); + b = PAD_StickX (0); + + /* + * check selection screen changes + */ + + /* scroll displayed filename */ + if ((p & PAD_BUTTON_LEFT) || (b < -PADCAL)) + { + if (filelist[selection].filename_offset > 0) + { + filelist[selection].filename_offset --; + redraw = 1; + } + } + else if ((p & PAD_BUTTON_RIGHT) || (b > PADCAL)) + { + size = 0; + for (i=filelist[selection].filename_offset; i back_framewidth) + { + filelist[selection].filename_offset ++; + redraw = 1; + } + } + + /* highlight next item */ + else if ((p & PAD_BUTTON_DOWN) || (a < -PADCAL)) + { + filelist[selection].filename_offset = 0; + selection++; + if (selection == maxfiles) selection = offset = 0; + if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; + redraw = 1; + } + + /* highlight previous item */ + else if ((p & PAD_BUTTON_UP) || (a > PADCAL)) + { + filelist[selection].filename_offset = 0; + selection--; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - PAGESIZE + 1; + } + if (selection < offset) offset -= PAGESIZE; + if (offset < 0) offset = 0; + redraw = 1; + } + + /* go back one page */ + else if (p & PAD_TRIGGER_L) + { + filelist[selection].filename_offset = 0; + selection -= PAGESIZE; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - PAGESIZE + 1; + } + if (selection < offset) offset -= PAGESIZE; + if (offset < 0) offset = 0; + redraw = 1; + } + + /* go forward one page */ + else if (p & PAD_TRIGGER_R) + { + filelist[selection].filename_offset = 0; + selection += PAGESIZE; + if (selection > maxfiles - 1) selection = offset = 0; + if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; + redraw = 1; + } + + /* + * Check pressed key + */ + + /* go up one directory or quit */ + if (p & PAD_BUTTON_B) + { + filelist[selection].filename_offset = 0; + if (((!UseSDCARD) && (basedir == rootdir)) || + (UseSDCARD && strcmp(rootSDdir,"dev0:\\genplus\\..") == 0)) return; + go_up = 1; + } + + /* quit */ + if (p & PAD_TRIGGER_Z) + { + filelist[selection].filename_offset = 0; + return; + } + + /* open selected file or directory */ + if ((p & PAD_BUTTON_A) || go_up) + { + filelist[selection].filename_offset = 0; + if (go_up) + { + go_up = 0; + selection = 1; + } + + /*** This is directory ***/ + if (filelist[selection].flags) + { + if (UseSDCARD) /* SDCARD directory handler */ + { + /* update current directory */ + int status = updateSDdirname(); + + /* move to new directory */ + if (status == 1) + { + /* reinit selector (previous value is saved for one level) */ + if (selection == 1) + { + selection = old_selection; + offset = old_offset; + old_selection = 0; + old_offset = 0; + } + else + { + /* save current selector value */ + old_selection = selection; + old_offset = offset; + selection = 0; + offset = 0; + } + + + /* set new entry list */ + maxfiles = parseSDdirectory(); + if (!maxfiles) + { + /* quit */ + WaitPrompt ("Error reading directory !"); + haverom = 1; + haveSDdir = 0; + } + } + else if (status == -1) + { + /* quit */ + haverom = 1; + haveSDdir = 0; + } + } + else /* DVD directory handler */ + { + /* move to a new directory */ + if (selection != 0) + { + /* update current directory */ + rootdir = filelist[selection].offset; + rootdirlength = filelist[selection].length; + + /* reinit selector (previous value is saved for one level) */ + if (selection == 1) + { + selection = old_selection; + offset = old_offset; + old_selection = 0; + old_offset = 0; + } + else + { + /* save current selector value */ + old_selection = selection; + old_offset = offset; + selection = 0; + offset = 0; + } + + /* get new entry list */ + maxfiles = parsedirectory (); + } + } + } + else /*** This is a file ***/ + { + rootdir = filelist[selection].offset; + rootdirlength = filelist[selection].length; + genromsize = LoadFile (cart_rom); + reloadrom (); + haverom = 1; + } + redraw = 1; + } + } +} + +/**************************************************************************** + * OpenDVD + * + * Function to load a DVD directory and display to user. + ****************************************************************************/ +void OpenDVD () +{ + UseSDCARD = 0; + if (!getpvd()) + { + ShowAction("Mounting DVD ... Wait"); + DVD_Mount(); + havedir = 0; + if (!getpvd()) + { + WaitPrompt ("Failed to mount DVD"); + return; + } + } + + if (havedir == 0) + { + /* don't mess with SD entries */ + haveSDdir = 0; + + /* reinit selector */ + rootdir = basedir; + old_selection = selection = offset = old_offset = 0; + + if ((maxfiles = parsedirectory ())) + { + FileSelector (); + havedir = 1; + } + } + else FileSelector (); +} + +/**************************************************************************** + * OpenSD updated to use the new libogc. Written by softdev and pasted + * into this code by Drack. + * Modified for subdirectory browing & quick filelist recovery + * Enjoy! +*****************************************************************************/ +int OpenSD () +{ + UseSDCARD = 1; + + if (haveSDdir == 0) + { + /* don't mess with DVD entries */ + havedir = 0; + + /* reinit selector */ + old_selection = selection = offset = old_offset = 0; + + /* Reset SDCARD root directory */ + sprintf(rootSDdir,"dev0:\\genplus\\roms"); + + /* Parse initial root directory and get entries list */ + ShowAction("Reading Directory ..."); + if ((maxfiles = parseSDdirectory ())) + { + /* Select an entry */ + FileSelector (); + + /* memorize last entries list, actual root directory and selection for next access */ + haveSDdir = 1; + } + else + { + /* no entries found */ + WaitPrompt ("Error reading dev0:\\genplus\\roms"); + return 0; + } + } + /* Retrieve previous entries list and made a new selection */ + else FileSelector (); + + return 1; +} + +/**************************************************************************** + * SDCard Get Info + ****************************************************************************/ +void GetSDInfo () +{ + char fname[SDCARD_MAX_PATH_LEN]; + rootdirlength = 0; + + /* Check filename length */ + if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) + sprintf(fname, "%s\\%s",rootSDdir,filelist[selection].filename); + + else + { + WaitPrompt ("Maximum Filename Length reached !"); + haveSDdir = 0; // reset everything before next access + } + + filehandle = SDCARD_OpenFile (fname, "rb"); + if (filehandle == NULL) + { + WaitPrompt ("Unable to open file!"); + return; + } + rootdirlength = SDCARD_GetFileSize (filehandle); +} + +/**************************************************************************** + * LoadFile + * + * This function will load a file from DVD or SDCARD, in BIN, SMD or ZIP format. + * The values for offset and length are inherited from rootdir and + * rootdirlength. + * + * The buffer parameter should re-use the initial ROM buffer. + ****************************************************************************/ +int LoadFile (unsigned char *buffer) +{ + int offset; + int blocks; + int i; + u64 discoffset; + char readbuffer[2048]; + + /* SDCard Addition */ + if (UseSDCARD) GetSDInfo (); + + /* How many 2k blocks to read */ + if (rootdirlength == 0) return 0; + blocks = rootdirlength / 2048; + + offset = 0; + discoffset = rootdir; + ShowAction ("Loading ... Wait"); + + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); + else dvd_read (&readbuffer, 2048, discoffset); + + if (!IsZipFile ((char *) readbuffer)) + { + if (UseSDCARD) SDCARD_SeekFile (filehandle, 0, SDCARD_SEEK_SET); + + for (i = 0; i < blocks; i++) + { + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); + else dvd_read(readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, 2048); + offset += 2048; + discoffset += 2048; + } + + /* And final cleanup */ + if (rootdirlength % 2048) + { + i = rootdirlength % 2048; + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, i); + else dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, i); + } + } + else return UnZipBuffer (buffer, discoffset, rootdirlength); + + if (UseSDCARD) SDCARD_CloseFile (filehandle); + + return rootdirlength; +} diff --git a/source/ngc/gui/iso9660.h b/source/ngc/gui/iso9660.h index ae132d6..026adda 100644 --- a/source/ngc/gui/iso9660.h +++ b/source/ngc/gui/iso9660.h @@ -22,16 +22,17 @@ * This is not intended as a complete guide to ISO9660. * Here I use the bare minimum! ***************************************************************************/ - -#define MAXJOLIET 256 +#include "vfat.h" #define MAXFILES 1000 /** Restrict to 1000 files per dir **/ +#define MAXJOLIET 256 typedef struct { u64 offset; unsigned int length; char flags; - char filename[MAXJOLIET]; + char filename[13]; + char displayname[MAX_LONG_NAME]; u16 filename_offset; } FILEENTRIES; diff --git a/source/ngc/gui/iso9660.h.old b/source/ngc/gui/iso9660.h.old new file mode 100644 index 0000000..ae132d6 --- /dev/null +++ b/source/ngc/gui/iso9660.h.old @@ -0,0 +1,44 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * DVD ISO9660/Joliet Parsing + * + * This is not intended as a complete guide to ISO9660. + * Here I use the bare minimum! + ***************************************************************************/ + +#define MAXJOLIET 256 +#define MAXFILES 1000 /** Restrict to 1000 files per dir **/ + +typedef struct +{ + u64 offset; + unsigned int length; + char flags; + char filename[MAXJOLIET]; + u16 filename_offset; +} FILEENTRIES; + +extern u64 basedir; +extern u64 rootdir; +extern int rootdirlength; + +extern int getpvd (); +extern int parsedirectory (); +extern FILEENTRIES filelist[MAXFILES]; diff --git a/source/ngc/gui/mcard.c b/source/ngc/gui/mcard.c index 5433c6c..0119f3e 100644 --- a/source/ngc/gui/mcard.c +++ b/source/ngc/gui/mcard.c @@ -131,6 +131,7 @@ int SD_ManageFile(char *filename, int direction, int filetype) return 0; } + if (filetype) sram.crc = crc32 (0, &sram.sram[0], 0x10000); sprintf (filename, "Saved %d bytes successfully", filesize); WaitPrompt (filename); return 1; diff --git a/source/ngc/gui/rominfo.c b/source/ngc/gui/rominfo.c index ff7da62..436c988 100644 --- a/source/ngc/gui/rominfo.c +++ b/source/ngc/gui/rominfo.c @@ -32,8 +32,7 @@ #define ROMCOPYRIGHT 272 #define ROMDOMESTIC 288 #define ROMWORLD 336 -#define ROMTYPE0 384 -#define ROMTYPE1 385 +#define ROMTYPE 384 #define ROMPRODUCT 386 #define ROMCHECKSUM 398 #define ROMIOSUPPORT 400 @@ -232,7 +231,7 @@ void getrominfo (char *romheader) memcpy (&rominfo.copyright, romheader + ROMCOPYRIGHT, 16); memcpy (&rominfo.domestic, romheader + ROMDOMESTIC, 48); memcpy (&rominfo.international, romheader + ROMWORLD, 48); - memcpy (&rominfo.ROMType, romheader + ROMTYPE0, 2); + memcpy (&rominfo.ROMType, romheader + ROMTYPE, 2); memcpy (&rominfo.product, romheader + ROMPRODUCT, 12); memcpy (&rominfo.checksum, romheader + ROMCHECKSUM, 2); memcpy (&rominfo.io_support, romheader + ROMIOSUPPORT, 16); @@ -302,7 +301,6 @@ void showrominfo () } } - while (quit == 0) { if (redraw) @@ -348,15 +346,19 @@ void showrominfo () sprintf (msg, "Checksum - %04x (%04x) (%s)", rominfo.checksum, realchecksum, rominfo.checksum == realchecksum ? "Good" : "Bad"); break; case 10: - sprintf (msg, "ROM end: 0x%06X", rominfo.romend); + sprintf (msg, "ROM end: $%06X", rominfo.romend); break; case 11: - if (sram.detected) sprintf (msg, "External RAM start: 0x%06X", rominfo.ramstart); - else sprintf (msg, "External RAM start: UNDETECTED"); + if (sram.custom) sprintf (msg, "EEPROM(%dK) - $%06X", ((eeprom.type.size_mask+1)* 8) /1024, (unsigned int)sram.start); + else if (sram.detected) sprintf (msg, "SRAM Start - $%06X", rominfo.ramstart); + else sprintf (msg, "External RAM undetected"); + break; case 12: - if (sram.detected) sprintf (msg, "External RAM end : 0x%06X", rominfo.ramend); - else sprintf (msg, "External RAM end : UNDETECTED"); + if (sram.custom) sprintf (msg, "EEPROM(%dK) - $%06X", ((eeprom.type.size_mask+1)* 8) /1024, (unsigned int)sram.end); + else if (sram.detected) sprintf (msg, "SRAM End - $%06X", rominfo.ramend); + else if (sram.on) sprintf (msg, "Default SRAM activated "); + else sprintf (msg, "SRAM is disactivated "); break; case 13: if (region_code == REGION_USA) sprintf (msg, "Region - %s (USA)", rominfo.country); diff --git a/source/ngc/gui/rominfo.h b/source/ngc/gui/rominfo.h index 2d92275..9078dbf 100644 --- a/source/ngc/gui/rominfo.h +++ b/source/ngc/gui/rominfo.h @@ -29,8 +29,8 @@ typedef struct char copyright[18]; /* Copyright message */ char domestic[50]; /* Domestic name of ROM */ char international[50]; /* International name of ROM */ - char ROMType[4]; - char product[14]; /* Product type and serial number */ + char ROMType[4]; /* Educational or Game */ + char product[14]; /* Product serial number */ unsigned short checksum; /* Checksum */ char io_support[18]; /* Actually 16 chars :) */ unsigned int romstart; diff --git a/source/ngc/loadrom.c b/source/ngc/loadrom.c index 50163bf..cba2461 100644 --- a/source/ngc/loadrom.c +++ b/source/ngc/loadrom.c @@ -180,11 +180,11 @@ extern uint8 autoload; void reloadrom () { load_memrom (genromsize); - SRAM_Init (); /* SRAM Infos from ROM header */ getrominfo (cart_rom); /* Other Infos from ROM Header */ genesis_set_region (); /* Region Detection */ detect_game(); /* game special patches */ - + SRAM_Init (); /* SRAM Infos from ROM header */ + system_init (); audio_init(48000); ClearGGCodes (); /* Game Genie */ diff --git a/source/ngc/unzip.c b/source/ngc/unzip.c index e7941a1..a629279 100644 --- a/source/ngc/unzip.c +++ b/source/ngc/unzip.c @@ -26,8 +26,11 @@ #include "shared.h" #include "dvd.h" #include "font.h" +#include "diskio.h" +#include "vfat.h" -extern sd_file *filehandle; +extern VFATFS fs; +extern FSDIRENTRY f; extern u8 UseSDCARD; /* @@ -111,8 +114,8 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) /*** Read Zip Header ***/ if ( UseSDCARD ) { - SDCARD_SeekFile(filehandle, 0, SDCARD_SEEK_SET); - SDCARD_ReadFile(filehandle, &readbuffer, 2048); + VFAT_fseek(&f, 0, SEEK_SET); + VFAT_fread(&f, readbuffer, 2048); } else dvd_read (&readbuffer, 2048, discoffset); @@ -171,14 +174,14 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) zipchunk = ZIPCHUNK; discoffset += 2048; - if (UseSDCARD) SDCARD_ReadFile(filehandle, &readbuffer, 2048); + if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); else dvd_read (&readbuffer, 2048, discoffset); } while (res != Z_STREAM_END); inflateEnd (&zs); - if ( UseSDCARD ) SDCARD_CloseFile(filehandle); + if ( UseSDCARD ) VFAT_fclose(&f); if (res == Z_STREAM_END) { diff --git a/source/ngc/unzip.c.old b/source/ngc/unzip.c.old new file mode 100644 index 0000000..e7941a1 --- /dev/null +++ b/source/ngc/unzip.c.old @@ -0,0 +1,190 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Nintendo Gamecube Zip Support + * + * Only partial support is included, in that only the first file within the archive + * is considered to be a Genesis ROM image. + ***************************************************************************/ +#include +#include +#include "shared.h" +#include "dvd.h" +#include "font.h" + +extern sd_file *filehandle; +extern u8 UseSDCARD; + +/* + * PKWare Zip Header - adopted into zip standard + */ +#define PKZIPID 0x504b0304 +#define MAXROM 0x500000 +#define ZIPCHUNK 2048 + +/* + * Zip file header definition + */ +typedef struct +{ + unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50 + unsigned short zipversion __attribute__ ((__packed__)); + unsigned short zipflags __attribute__ ((__packed__)); + unsigned short compressionMethod __attribute__ ((__packed__)); + unsigned short lastmodtime __attribute__ ((__packed__)); + unsigned short lastmoddate __attribute__ ((__packed__)); + unsigned int crc32 __attribute__ ((__packed__)); + unsigned int compressedSize __attribute__ ((__packed__)); + unsigned int uncompressedSize __attribute__ ((__packed__)); + unsigned short filenameLength __attribute__ ((__packed__)); + unsigned short extraDataLength __attribute__ ((__packed__)); +} PKZIPHEADER; + +/* + * Zip files are stored little endian + * Support functions for short and int types + */ +static inline u32 FLIP32 (u32 b) +{ + unsigned int c; + c = (b & 0xff000000) >> 24; + c |= (b & 0xff0000) >> 8; + c |= (b & 0xff00) << 8; + c |= (b & 0xff) << 24; + return c; +} + +static inline u16 FLIP16 (u16 b) +{ + u16 c; + c = (b & 0xff00) >> 8; + c |= (b & 0xff) << 8; + return c; +} + +/**************************************************************************** + * IsZipFile + * + * Returns TRUE when PKZIPID is first four characters of buffer + ****************************************************************************/ +int IsZipFile (char *buffer) +{ + unsigned int *check; + check = (unsigned int *) buffer; + if (check[0] == PKZIPID) return 1; + return 0; +} + + /***************************************************************************** + * UnZipBuffer + * + * It should be noted that there is a limit of 5MB total size for any ROM + ******************************************************************************/ +int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) +{ + PKZIPHEADER pkzip; + int zipoffset = 0; + int zipchunk = 0; + char out[ZIPCHUNK]; + z_stream zs; + int res; + int bufferoffset = 0; + int have = 0; + char readbuffer[2048]; + char msg[128]; + + /*** Read Zip Header ***/ + if ( UseSDCARD ) + { + SDCARD_SeekFile(filehandle, 0, SDCARD_SEEK_SET); + SDCARD_ReadFile(filehandle, &readbuffer, 2048); + } + else dvd_read (&readbuffer, 2048, discoffset); + + /*** Copy PKZip header to local, used as info ***/ + memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER)); + + sprintf (msg, "Unzipping %d bytes ... Wait", FLIP32 (pkzip.uncompressedSize)); + ShowAction (msg); + + /*** Prepare the zip stream ***/ + memset (&zs, 0, sizeof (z_stream)); + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = 0; + zs.next_in = Z_NULL; + res = inflateInit2 (&zs, -MAX_WBITS); + + if (res != Z_OK) return 0; + + /*** Set ZipChunk for first pass ***/ + zipoffset = (sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) + FLIP16 (pkzip.extraDataLength)); + zipchunk = ZIPCHUNK - zipoffset; + + /*** Now do it! ***/ + do + { + zs.avail_in = zipchunk; + zs.next_in = (Bytef *) & readbuffer[zipoffset]; + + /*** Now inflate until input buffer is exhausted ***/ + do + { + zs.avail_out = ZIPCHUNK; + zs.next_out = (Bytef *) & out; + res = inflate (&zs, Z_NO_FLUSH); + + if (res == Z_MEM_ERROR) + { + inflateEnd (&zs); + return 0; + } + + have = ZIPCHUNK - zs.avail_out; + if (have) + { + /*** Copy to normal block buffer ***/ + memcpy (&outbuffer[bufferoffset], &out, have); + bufferoffset += have; + } + } + while (zs.avail_out == 0); + + /*** Readup the next 2k block ***/ + zipoffset = 0; + zipchunk = ZIPCHUNK; + discoffset += 2048; + + if (UseSDCARD) SDCARD_ReadFile(filehandle, &readbuffer, 2048); + else dvd_read (&readbuffer, 2048, discoffset); + } + while (res != Z_STREAM_END); + + inflateEnd (&zs); + + if ( UseSDCARD ) SDCARD_CloseFile(filehandle); + + if (res == Z_STREAM_END) + { + if (FLIP32 (pkzip.uncompressedSize) == (u32) bufferoffset) return bufferoffset; + else return FLIP32 (pkzip.uncompressedSize); + } + + return 0; +} diff --git a/source/vdp.c b/source/vdp.c index ff65e0e..0fb098f 100644 --- a/source/vdp.c +++ b/source/vdp.c @@ -351,7 +351,7 @@ uint16 vdp_ctrl_r (void) pending = 0; /* reset status */ - status ^= 0xFF00; /* toggle FIFO status & new word on bus */ + status ^= 0x0300; /* toggle FIFO status */ status &= 0xFF9F; /* clear sprite overflow & sprite collision */ if (!(status & 8)) status &= ~0x0080; /* not in VBLANK: clear vint flag */