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@756 be3aeb3a-fb24-0410-a615-afba39da0efa

pico/cart.c
pico/pico.c
pico/pico.h
pico/pico_int.h
pico/sms.c [new file with mode: 0644]
pico/z80if.c
platform/common/emu.c
platform/common/emu.h
platform/common/menu.c
platform/linux/Makefile

index 44a1a25..11484ff 100644 (file)
@@ -13,7 +13,7 @@
 #include "../unzip/unzip_stream.h"\r
 \r
 \r
-static char *rom_exts[] = { "bin", "gen", "smd", "iso" };\r
+static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };\r
 \r
 void (*PicoCartUnloadHook)(void) = NULL;\r
 \r
@@ -99,7 +99,10 @@ pm_file *pm_open(const char *path)
         if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip;\r
         if (strlen(zipentry->name) < 5) continue;\r
 \r
-        ext = zipentry->name+strlen(zipentry->name)-3;\r
+        ext = zipentry->name + strlen(zipentry->name) - 2;\r
+        if (ext[-1] != '.') ext--;\r
+        if (ext[-1] != '.') ext--;\r
+\r
         for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)\r
           if (strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip;\r
       }\r
@@ -437,7 +440,7 @@ static unsigned char *PicoCartAlloc(int filesize)
   return rom;\r
 }\r
 \r
-int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize)\r
+int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)\r
 {\r
   unsigned char *rom=NULL; int size, bytes_read;\r
   if (f==NULL) return 1;\r
@@ -478,19 +481,22 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize)
     return 3;\r
   }\r
 \r
-  // maybe we are loading MegaCD BIOS?\r
-  if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
-       !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
-    PicoAHW |= PAHW_MCD;\r
-    rom = cd_realloc(rom, size);\r
-  }\r
+  if (!is_sms)\r
+  {\r
+    // maybe we are loading MegaCD BIOS?\r
+    if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||\r
+         !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
+      PicoAHW |= PAHW_MCD;\r
+      rom = cd_realloc(rom, size);\r
+    }\r
 \r
-  // Check for SMD:\r
-  if (size >= 0x4200 && (size&0x3fff)==0x200 &&\r
-      ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {\r
-    DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD\r
+    // Check for SMD:\r
+    if (size >= 0x4200 && (size&0x3fff)==0x200 &&\r
+        ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {\r
+      DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD\r
+    }\r
+    else Byteswap(rom,size); // Just byteswap\r
   }\r
-  else Byteswap(rom,size); // Just byteswap\r
 \r
   if (prom)  *prom=rom;\r
   if (psize) *psize=size;\r
@@ -520,7 +526,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
     PicoCartUnloadHook = NULL;\r
   }\r
 \r
-  PicoAHW &= PAHW_MCD;\r
+  PicoAHW &= PAHW_MCD|PAHW_SMS;\r
 \r
   PicoMemResetHooks();\r
   PicoDmaHook = NULL;\r
@@ -531,7 +537,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
 \r
   PicoMemReset();\r
 \r
-  if (!(PicoAHW & PAHW_MCD))\r
+  if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))\r
     PicoCartDetect();\r
 \r
   // setup correct memory map for loaded ROM\r
@@ -543,15 +549,25 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
     case PAHW_SVP:  PicoMemSetup(); break;\r
     case PAHW_MCD:  PicoMemSetupCD(); break;\r
     case PAHW_PICO: PicoMemSetupPico(); break;\r
+    case PAHW_SMS:  PicoMemSetupMS(); break;\r
   }\r
   PicoMemReset();\r
 \r
-  PicoPower();\r
+  if (PicoAHW & PAHW_SMS)\r
+    PicoPowerMS();\r
+  else\r
+    PicoPower();\r
+\r
   return 0;\r
 }\r
 \r
 void PicoCartUnload(void)\r
 {\r
+  if (PicoCartUnloadHook != NULL) {\r
+    PicoCartUnloadHook();\r
+    PicoCartUnloadHook = NULL;\r
+  }\r
+\r
   if (Pico.rom != NULL) {\r
     SekFinishIdleDet();\r
     free(Pico.rom);\r
index e079f8a..f900dfe 100644 (file)
@@ -289,6 +289,10 @@ void PicoFrame(void)
     PicoFrameMCD();\r
     return;\r
   }\r
+  else if (PicoAHW & PAHW_SMS) {\r
+    PicoFrameMS();\r
+    return;\r
+  }\r
 \r
   //if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode\r
 \r
index 828a63d..c6b118c 100644 (file)
@@ -57,6 +57,7 @@ extern int PicoOpt; // bitfield
 #define PAHW_32X  (1<<1)\r
 #define PAHW_SVP  (1<<2)\r
 #define PAHW_PICO (1<<3)\r
+#define PAHW_SMS  (1<<4)\r
 extern int PicoAHW;            // Pico active hw\r
 extern int PicoVer;\r
 extern int PicoSkipFrame;      // skip rendering frame, but still do sound (if enabled) and emulation stuff\r
@@ -133,7 +134,7 @@ pm_file *pm_open(const char *path);
 size_t   pm_read(void *ptr, size_t bytes, pm_file *stream);\r
 int      pm_seek(pm_file *stream, long offset, int whence);\r
 int      pm_close(pm_file *fp);\r
-int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize);\r
+int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);\r
 int PicoCartInsert(unsigned char *rom,unsigned int romsize);\r
 void Byteswap(unsigned char *data,int len);\r
 void PicoCartUnload(void);\r
index d3b64a8..45955ad 100644 (file)
@@ -551,6 +551,11 @@ PICO_INTERNAL void PsndClear(void);
 PICO_INTERNAL void PsndGetSamples(int y);\r
 extern int PsndDacLine;\r
 \r
+// sms.c\r
+void PicoPowerMS(void);\r
+void PicoMemSetupMS(void);\r
+void PicoFrameMS(void);\r
+\r
 // emulation event logging\r
 #ifndef EL_LOGMASK\r
 #define EL_LOGMASK 0\r
@@ -596,7 +601,7 @@ extern void lprintf(const char *fmt, ...);
 #define cdprintf(x...)\r
 #endif\r
 \r
-#if defined(__GNUC__) && !defined(ARM)\r
+#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3\r
 #define MEMH_FUNC __attribute__((aligned(4)))\r
 #else\r
 #define MEMH_FUNC\r
diff --git a/pico/sms.c b/pico/sms.c
new file mode 100644 (file)
index 0000000..a7a0f8f
--- /dev/null
@@ -0,0 +1,55 @@
+#include "pico_int.h"
+
+static unsigned char z80_sms_in(unsigned short p)
+{
+  elprintf(EL_ANOMALY, "Z80 port %04x read", p);
+  return 0xff;
+}
+
+static void z80_sms_out(unsigned short p, unsigned char d)
+{
+  elprintf(EL_ANOMALY, "Z80 port %04x write %02x", p, d);
+}
+
+static unsigned char MEMH_FUNC xread(unsigned short a)
+{
+  elprintf(EL_ANOMALY, "Z80 read  [%04x]", a);
+  return 0;
+}
+
+static void MEMH_FUNC xwrite(unsigned int a, unsigned char data)
+{
+  elprintf(EL_ANOMALY, "Z80 write [%04x] %02x", a, data);
+}
+
+void PicoPowerMS(void)
+{
+}
+
+void PicoMemSetupMS(void)
+{
+  z80_map_set(z80_read_map, 0x0000, 0xbfff, Pico.rom, 0);
+  z80_map_set(z80_read_map, 0xc000, 0xdfff, Pico.zram, 0);
+  z80_map_set(z80_read_map, 0xe000, 0xffff, xread, 1);
+
+  z80_map_set(z80_write_map, 0x0000, 0xbfff, Pico.rom, 0);
+  z80_map_set(z80_write_map, 0xc000, 0xdfff, Pico.zram, 0);
+  z80_map_set(z80_write_map, 0xe000, 0xffff, xwrite, 1);
+#ifdef _USE_DRZ80
+  drZ80.z80_in = z80_sms_in;
+  drZ80.z80_out = z80_sms_out;
+#endif
+#ifdef _USE_CZ80
+  Cz80_Set_Fetch(&CZ80, 0x0000, 0xbfff, (UINT32)Pico.rom);
+  Cz80_Set_Fetch(&CZ80, 0xc000, 0xdfff, (UINT32)Pico.zram);
+  Cz80_Set_INPort(&CZ80, z80_sms_in);
+  Cz80_Set_OUTPort(&CZ80, z80_sms_out);
+#endif
+}
+
+void PicoFrameMS(void)
+{
+  z80_run(OSC_NTSC / 13 / 60);
+}
+
index 815e003..7ed85c7 100644 (file)
@@ -119,7 +119,8 @@ PICO_INTERNAL void z80_reset(void)
   drZ80.z80irqvector = 0xff0000; // RST 38h
   drZ80.Z80PC_BASE = drZ80.Z80PC = z80_read_map[0] << 1;
   // drZ80 is locked in single bank
-  drZ80.Z80SP_BASE = z80_read_map[0] << 1;
+  drZ80.Z80SP_BASE = ((PicoAHW & PAHW_SMS) ?
+    z80_read_map[0xc000 >> Z80_MEM_SHIFT] : z80_read_map[0]) << 1;
 //  drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ?
 #endif
 #ifdef _USE_CZ80
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 \