starting SMS work
authornotaz <notasas@gmail.com>
Sun, 16 Aug 2009 13:00:07 +0000 (13:00 +0000)
committernotaz <notasas@gmail.com>
Sun, 16 Aug 2009 13:00:07 +0000 (13:00 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive/platform@756 be3aeb3a-fb24-0410-a615-afba39da0efa

common/emu.c
common/emu.h
common/menu.c
linux/Makefile

index 3443c98..1cecc39 100644 (file)
@@ -174,8 +174,7 @@ static int emu_isBios(const char *name)
 \r
 static unsigned char id_header[0x100];\r
 \r
-/* checks if fname points to valid MegaCD image\r
- * if so, checks for suitable BIOS */\r
+/* checks if fname points to valid MegaCD image */\r
 static int emu_cd_check(int *pregion, const char *fname_in)\r
 {\r
        const char *fname = fname_in;\r
@@ -243,6 +242,58 @@ static int emu_cd_check(int *pregion, const char *fname_in)
        return type;\r
 }\r
 \r
+static int detect_media(const char *fname)\r
+{\r
+       static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 };\r
+       pm_file *pmf;\r
+       char buff[32];\r
+       char ext[5];\r
+       int i;\r
+\r
+       get_ext(fname, ext);\r
+\r
+       // detect wrong extensions\r
+       if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) // s.gz ~ .mds.gz\r
+               return PM_BAD;\r
+\r
+       /* don't believe in extensions, except .cue */\r
+       if (strcasecmp(ext, ".cue") == 0)\r
+               return PM_CD;\r
+\r
+       pmf = pm_open(fname);\r
+       if (pmf == NULL)\r
+               return PM_BAD;\r
+\r
+       if (pm_read(buff, 32, pmf) != 32) {\r
+               pm_close(pmf);\r
+               return PM_BAD;\r
+       }\r
+\r
+       if (strncasecmp("SEGADISCSYSTEM", buff + 0x00, 14) == 0 ||\r
+           strncasecmp("SEGADISCSYSTEM", buff + 0x10, 14) == 0) {\r
+               pm_close(pmf);\r
+               return PM_CD;\r
+       }\r
+\r
+       for (i = 0; i < array_size(sms_offsets); i++) {\r
+               if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i])\r
+                       goto not_mark3;         /* actually it could be but can't be detected */\r
+\r
+               if (pm_read(buff, 16, pmf) != 16)\r
+                       goto not_mark3;\r
+\r
+               if (strncasecmp("TMR SEGA", buff, 8) == 0) {\r
+                       pm_close(pmf);\r
+                       return PM_MARK3;\r
+               }\r
+       }\r
+\r
+not_mark3:\r
+       pm_close(pmf);\r
+       /* the main emu function is to emulate MD, so assume MD */\r
+       return PM_MD_CART;\r
+}\r
+\r
 static int extract_text(char *dest, const unsigned char *src, int len, int swab)\r
 {\r
        char *p = dest;\r
@@ -321,6 +372,7 @@ static void shutdown_MCD(void)
 }\r
 \r
 // note: this function might mangle rom_fname\r
+// XXX: portions of this code should move to pico/\r
 int emu_reload_rom(char *rom_fname)\r
 {\r
        unsigned int rom_size = 0;\r
@@ -328,20 +380,14 @@ int emu_reload_rom(char *rom_fname)
        unsigned char *rom_data = NULL;\r
        char ext[5];\r
        pm_file *rom = NULL;\r
-       int ret, cd_state, cd_region, cfg_loaded = 0;\r
+       int cd_state = CIT_NOT_CD;\r
+       int ret, media_type, cd_region;\r
+       int cfg_loaded = 0, bad_rom = 0;\r
 \r
        lprintf("emu_ReloadRom(%s)\n", rom_fname);\r
 \r
        get_ext(rom_fname, ext);\r
 \r
-       // detect wrong extensions\r
-       if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz\r
-               me_update_msg("Not a ROM/CD selected.");\r
-               return 0;\r
-       }\r
-\r
-       PicoPatchUnload();\r
-\r
        // check for movie file\r
        if (movie_data) {\r
                free(movie_data);\r
@@ -396,46 +442,53 @@ int emu_reload_rom(char *rom_fname)
                get_ext(rom_fname, ext);\r
        }\r
 \r
+       media_type = detect_media(rom_fname);\r
+       if (media_type == PM_BAD) {\r
+               me_update_msg("Not a ROM/CD img selected.");\r
+               return 0;\r
+       }\r
+\r
        shutdown_MCD();\r
+       PicoPatchUnload();\r
 \r
-       // check for MegaCD image\r
-       cd_state = emu_cd_check(&cd_region, rom_fname);\r
-       if (cd_state >= 0 && cd_state != CIT_NOT_CD)\r
+       if (media_type == PM_CD)\r
        {\r
-               PicoAHW |= PAHW_MCD;\r
-               // valid CD image, check for BIOS..\r
+               // check for MegaCD image\r
+               cd_state = emu_cd_check(&cd_region, rom_fname);\r
+               if (cd_state >= 0 && cd_state != CIT_NOT_CD)\r
+               {\r
+                       // valid CD image, check for BIOS..\r
 \r
-               // we need to have config loaded at this point\r
-               ret = emu_read_config(1, 0);\r
-               if (!ret) emu_read_config(0, 0);\r
-               cfg_loaded = 1;\r
+                       // we need to have config loaded at this point\r
+                       ret = emu_read_config(1, 0);\r
+                       if (!ret) emu_read_config(0, 0);\r
+                       cfg_loaded = 1;\r
+\r
+                       if (PicoRegionOverride) {\r
+                               cd_region = PicoRegionOverride;\r
+                               lprintf("override region to %s\n", cd_region != 4 ?\r
+                                       (cd_region == 8 ? "EU" : "JAP") : "USA");\r
+                       }\r
+                       if (!find_bios(cd_region, &used_rom_name))\r
+                               return 0;\r
 \r
-               if (PicoRegionOverride) {\r
-                       cd_region = PicoRegionOverride;\r
-                       lprintf("overrided region to %s\n", cd_region != 4 ? (cd_region == 8 ? "EU" : "JAP") : "USA");\r
+                       get_ext(used_rom_name, ext);\r
+                       PicoAHW |= PAHW_MCD;\r
                }\r
-               if (!find_bios(cd_region, &used_rom_name)) {\r
-                       PicoAHW &= ~PAHW_MCD;\r
+               else {\r
+                       me_update_msg("Invalid CD image");\r
                        return 0;\r
                }\r
-\r
-               get_ext(used_rom_name, ext);\r
        }\r
-       else\r
-       {\r
-               if (PicoAHW & PAHW_MCD) Stop_CD();\r
-               PicoAHW &= ~PAHW_MCD;\r
+       else if (media_type == PM_MARK3) {\r
+               lprintf("detected SMS ROM\n");\r
+               PicoAHW = PAHW_SMS;\r
        }\r
 \r
        rom = pm_open(used_rom_name);\r
-       if (!rom) {\r
-               me_update_msg("Failed to open ROM/CD image");\r
-               goto fail;\r
-       }\r
-\r
-       if (cd_state < 0) {\r
-               me_update_msg("Invalid CD image");\r
-               goto fail;\r
+       if (rom == NULL) {\r
+               me_update_msg("Failed to open ROM");\r
+               return 0;\r
        }\r
 \r
        menu_romload_prepare(used_rom_name); // also CD load\r
@@ -443,21 +496,29 @@ int emu_reload_rom(char *rom_fname)
        PicoCartUnload();\r
        rom_loaded = 0;\r
 \r
-       if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
+       ret = PicoCartLoad(rom, &rom_data, &rom_size, (PicoAHW & PAHW_SMS) ? 1 : 0);\r
+       pm_close(rom);\r
+       if (ret != 0) {\r
                if      (ret == 2) me_update_msg("Out of memory");\r
                else if (ret == 3) me_update_msg("Read failed");\r
                else               me_update_msg("PicoCartLoad() failed.");\r
-               goto fail2;\r
+               goto fail;\r
        }\r
-       pm_close(rom);\r
-       rom = NULL;\r
-\r
-       // detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
-       if (rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
-         ((*(unsigned char *)(rom_data+4)<<16)|(*(unsigned short *)(rom_data+6))) >= (int)rom_size) {\r
-               if (rom_data) free(rom_data);\r
-               me_update_msg("Not a ROM selected.");\r
-               goto fail2;\r
+\r
+       // detect wrong files\r
+       if (strncmp((char *)rom_data, "Pico", 4) == 0)\r
+               bad_rom = 1;\r
+       else if (!(PicoAHW & PAHW_SMS)) {\r
+               unsigned short *d = (unsigned short *)(rom_data + 4);\r
+               if ((((d[0] << 16) | d[1]) & 0xffffff) >= (int)rom_size) {\r
+                       lprintf("bad reset vector\n");\r
+                       bad_rom = 1;\r
+               }\r
+       }\r
+\r
+       if (bad_rom) {\r
+               me_update_msg("Bad ROM detected.");\r
+               goto fail;\r
        }\r
 \r
        // load config for this ROM (do this before insert to get correct region)\r
@@ -468,18 +529,19 @@ int emu_reload_rom(char *rom_fname)
                if (!ret) emu_read_config(0, 0);\r
        }\r
 \r
-       lprintf("PicoCartInsert(%p, %d);\n", rom_data, rom_size);\r
        if (PicoCartInsert(rom_data, rom_size)) {\r
                me_update_msg("Failed to load ROM.");\r
-               goto fail2;\r
+               goto fail;\r
        }\r
 \r
        // insert CD if it was detected\r
        if (cd_state != CIT_NOT_CD) {\r
                ret = Insert_CD(rom_fname, cd_state);\r
                if (ret != 0) {\r
+                       PicoCartUnload();\r
+                       rom_data = NULL; // freed by unload\r
                        me_update_msg("Insert_CD() failed, invalid CD image?");\r
-                       goto fail2;\r
+                       goto fail;\r
                }\r
        }\r
 \r
@@ -511,8 +573,22 @@ int emu_reload_rom(char *rom_fname)
        }\r
        else\r
        {\r
+               const char *sys_name, *tv_standard;\r
+               int fps;\r
+\r
+               if (PicoAHW & PAHW_SMS) {\r
+                       sys_name = "Master System";\r
+               } else {\r
+                       sys_name = "MegaDrive";\r
+                       if ((Pico.m.hardware&0xc0) == 0x80)\r
+                               sys_name = "Genesis";\r
+               }\r
+               tv_standard = Pico.m.pal ? "PAL" : "NTSC";\r
+               fps = Pico.m.pal ? 50 : 60;\r
+\r
+               emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps);\r
+\r
                PicoOpt &= ~POPT_DIS_VDP_FIFO;\r
-               emu_status_msg(Pico.m.pal ? "PAL SYSTEM / 50 FPS" : "NTSC SYSTEM / 60 FPS");\r
        }\r
 \r
        strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);\r
@@ -525,10 +601,10 @@ int emu_reload_rom(char *rom_fname)
 \r
        return 1;\r
 \r
-fail2:\r
-       menu_romload_end();\r
 fail:\r
-       if (rom != NULL) pm_close(rom);\r
+       if (rom_data)\r
+               free(rom_data);\r
+       menu_romload_end();\r
        return 0;\r
 }\r
 \r
index 59fa7a1..5b695ef 100644 (file)
@@ -9,6 +9,8 @@
 extern "C" {
 #endif
 
+#define array_size(x) (sizeof(x) / sizeof(x[0]))
+
 extern void *g_screen_ptr;
 
 #if SCREEN_SIZE_FIXED
@@ -97,6 +99,13 @@ enum TPicoGameState {
        PGS_SuspendWake,        /* PSP */
 };
 
+// media types
+enum {
+       PM_BAD = 0,
+       PM_MD_CART,     /* also 32x */
+       PM_MARK3,
+       PM_CD,
+};
 
 void  emu_init(void);
 void  emu_finish(void);
index 688d538..dff1b39 100644 (file)
@@ -22,8 +22,6 @@
 #include <pico/pico_int.h>\r
 #include <pico/patch.h>\r
 \r
-#define array_size(x) (sizeof(x) / sizeof(x[0]))\r
-\r
 static char static_buff[64];\r
 static char menu_error_msg[64] = { 0, };\r
 static int  menu_error_time = 0;\r
index 4aa44d8..c68595c 100644 (file)
@@ -12,7 +12,7 @@ CFLAGS += -O3 -Wall
 CFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math
 CFLAGS += -fprofile-generate
 else
-CFLAGS = -ggdb -Wall
+CFLAGS = -ggdb -Wall -falign-functions=2
 endif
 DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV
 CFLAGS += -I../.. -I.
@@ -38,7 +38,8 @@ endif
 
 # Pico
 OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \
-       pico/videoport.o pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o pico/debug.o
+       pico/videoport.o pico/draw2.o pico/draw.o pico/z80if.o pico/patch.o \
+       pico/sms.o pico/debug.o
 # Pico - CD
 OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \
        pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \