starting SMS work

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@756 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2009-08-16 13:00:07 +00:00
parent d8f51995c4
commit 3e49ffd0bf
10 changed files with 246 additions and 80 deletions

View file

@ -13,7 +13,7 @@
#include "../unzip/unzip_stream.h" #include "../unzip/unzip_stream.h"
static char *rom_exts[] = { "bin", "gen", "smd", "iso" }; static const char *rom_exts[] = { "bin", "gen", "smd", "iso", "sms", "gg", "sg" };
void (*PicoCartUnloadHook)(void) = NULL; void (*PicoCartUnloadHook)(void) = NULL;
@ -99,7 +99,10 @@ pm_file *pm_open(const char *path)
if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip; if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip;
if (strlen(zipentry->name) < 5) continue; if (strlen(zipentry->name) < 5) continue;
ext = zipentry->name+strlen(zipentry->name)-3; ext = zipentry->name + strlen(zipentry->name) - 2;
if (ext[-1] != '.') ext--;
if (ext[-1] != '.') ext--;
for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++) for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)
if (strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip; if (strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip;
} }
@ -437,7 +440,7 @@ static unsigned char *PicoCartAlloc(int filesize)
return rom; return rom;
} }
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize) int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms)
{ {
unsigned char *rom=NULL; int size, bytes_read; unsigned char *rom=NULL; int size, bytes_read;
if (f==NULL) return 1; if (f==NULL) return 1;
@ -478,19 +481,22 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize)
return 3; return 3;
} }
// maybe we are loading MegaCD BIOS? if (!is_sms)
if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) || {
!strncmp((char *)rom+0x128, "BOOT", 4))) { // maybe we are loading MegaCD BIOS?
PicoAHW |= PAHW_MCD; if (!(PicoAHW & PAHW_MCD) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) ||
rom = cd_realloc(rom, size); !strncmp((char *)rom+0x128, "BOOT", 4))) {
} PicoAHW |= PAHW_MCD;
rom = cd_realloc(rom, size);
}
// Check for SMD: // Check for SMD:
if (size >= 0x4200 && (size&0x3fff)==0x200 && if (size >= 0x4200 && (size&0x3fff)==0x200 &&
((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) { ((rom[0x2280] == 'S' && rom[0x280] == 'E') || (rom[0x280] == 'S' && rom[0x2281] == 'E'))) {
DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD
}
else Byteswap(rom,size); // Just byteswap
} }
else Byteswap(rom,size); // Just byteswap
if (prom) *prom=rom; if (prom) *prom=rom;
if (psize) *psize=size; if (psize) *psize=size;
@ -520,7 +526,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
PicoCartUnloadHook = NULL; PicoCartUnloadHook = NULL;
} }
PicoAHW &= PAHW_MCD; PicoAHW &= PAHW_MCD|PAHW_SMS;
PicoMemResetHooks(); PicoMemResetHooks();
PicoDmaHook = NULL; PicoDmaHook = NULL;
@ -531,7 +537,7 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
PicoMemReset(); PicoMemReset();
if (!(PicoAHW & PAHW_MCD)) if (!(PicoAHW & (PAHW_MCD|PAHW_SMS)))
PicoCartDetect(); PicoCartDetect();
// setup correct memory map for loaded ROM // setup correct memory map for loaded ROM
@ -543,15 +549,25 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
case PAHW_SVP: PicoMemSetup(); break; case PAHW_SVP: PicoMemSetup(); break;
case PAHW_MCD: PicoMemSetupCD(); break; case PAHW_MCD: PicoMemSetupCD(); break;
case PAHW_PICO: PicoMemSetupPico(); break; case PAHW_PICO: PicoMemSetupPico(); break;
case PAHW_SMS: PicoMemSetupMS(); break;
} }
PicoMemReset(); PicoMemReset();
PicoPower(); if (PicoAHW & PAHW_SMS)
PicoPowerMS();
else
PicoPower();
return 0; return 0;
} }
void PicoCartUnload(void) void PicoCartUnload(void)
{ {
if (PicoCartUnloadHook != NULL) {
PicoCartUnloadHook();
PicoCartUnloadHook = NULL;
}
if (Pico.rom != NULL) { if (Pico.rom != NULL) {
SekFinishIdleDet(); SekFinishIdleDet();
free(Pico.rom); free(Pico.rom);

View file

@ -289,6 +289,10 @@ void PicoFrame(void)
PicoFrameMCD(); PicoFrameMCD();
return; return;
} }
else if (PicoAHW & PAHW_SMS) {
PicoFrameMS();
return;
}
//if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode //if(Pico.video.reg[12]&0x2) Pico.video.status ^= 0x10; // change odd bit in interlace mode

View file

@ -57,6 +57,7 @@ extern int PicoOpt; // bitfield
#define PAHW_32X (1<<1) #define PAHW_32X (1<<1)
#define PAHW_SVP (1<<2) #define PAHW_SVP (1<<2)
#define PAHW_PICO (1<<3) #define PAHW_PICO (1<<3)
#define PAHW_SMS (1<<4)
extern int PicoAHW; // Pico active hw extern int PicoAHW; // Pico active hw
extern int PicoVer; extern int PicoVer;
extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff extern int PicoSkipFrame; // skip rendering frame, but still do sound (if enabled) and emulation stuff
@ -133,7 +134,7 @@ pm_file *pm_open(const char *path);
size_t pm_read(void *ptr, size_t bytes, pm_file *stream); size_t pm_read(void *ptr, size_t bytes, pm_file *stream);
int pm_seek(pm_file *stream, long offset, int whence); int pm_seek(pm_file *stream, long offset, int whence);
int pm_close(pm_file *fp); int pm_close(pm_file *fp);
int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize); int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms);
int PicoCartInsert(unsigned char *rom,unsigned int romsize); int PicoCartInsert(unsigned char *rom,unsigned int romsize);
void Byteswap(unsigned char *data,int len); void Byteswap(unsigned char *data,int len);
void PicoCartUnload(void); void PicoCartUnload(void);

View file

@ -551,6 +551,11 @@ PICO_INTERNAL void PsndClear(void);
PICO_INTERNAL void PsndGetSamples(int y); PICO_INTERNAL void PsndGetSamples(int y);
extern int PsndDacLine; extern int PsndDacLine;
// sms.c
void PicoPowerMS(void);
void PicoMemSetupMS(void);
void PicoFrameMS(void);
// emulation event logging // emulation event logging
#ifndef EL_LOGMASK #ifndef EL_LOGMASK
#define EL_LOGMASK 0 #define EL_LOGMASK 0
@ -596,7 +601,7 @@ extern void lprintf(const char *fmt, ...);
#define cdprintf(x...) #define cdprintf(x...)
#endif #endif
#if defined(__GNUC__) && !defined(ARM) #if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 3
#define MEMH_FUNC __attribute__((aligned(4))) #define MEMH_FUNC __attribute__((aligned(4)))
#else #else
#define MEMH_FUNC #define MEMH_FUNC

55
pico/sms.c Normal file
View file

@ -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);
}

View file

@ -119,7 +119,8 @@ PICO_INTERNAL void z80_reset(void)
drZ80.z80irqvector = 0xff0000; // RST 38h drZ80.z80irqvector = 0xff0000; // RST 38h
drZ80.Z80PC_BASE = drZ80.Z80PC = z80_read_map[0] << 1; drZ80.Z80PC_BASE = drZ80.Z80PC = z80_read_map[0] << 1;
// drZ80 is locked in single bank // 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 ? // drZ80.Z80SP = drZ80.z80_rebaseSP(0x2000); // 0xf000 ?
#endif #endif
#ifdef _USE_CZ80 #ifdef _USE_CZ80

View file

@ -174,8 +174,7 @@ static int emu_isBios(const char *name)
static unsigned char id_header[0x100]; static unsigned char id_header[0x100];
/* checks if fname points to valid MegaCD image /* checks if fname points to valid MegaCD image */
* if so, checks for suitable BIOS */
static int emu_cd_check(int *pregion, const char *fname_in) static int emu_cd_check(int *pregion, const char *fname_in)
{ {
const char *fname = fname_in; const char *fname = fname_in;
@ -243,6 +242,58 @@ static int emu_cd_check(int *pregion, const char *fname_in)
return type; return type;
} }
static int detect_media(const char *fname)
{
static const short sms_offsets[] = { 0x7ff0, 0x3ff0, 0x1ff0 };
pm_file *pmf;
char buff[32];
char ext[5];
int i;
get_ext(fname, ext);
// detect wrong extensions
if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) // s.gz ~ .mds.gz
return PM_BAD;
/* don't believe in extensions, except .cue */
if (strcasecmp(ext, ".cue") == 0)
return PM_CD;
pmf = pm_open(fname);
if (pmf == NULL)
return PM_BAD;
if (pm_read(buff, 32, pmf) != 32) {
pm_close(pmf);
return PM_BAD;
}
if (strncasecmp("SEGADISCSYSTEM", buff + 0x00, 14) == 0 ||
strncasecmp("SEGADISCSYSTEM", buff + 0x10, 14) == 0) {
pm_close(pmf);
return PM_CD;
}
for (i = 0; i < array_size(sms_offsets); i++) {
if (pm_seek(pmf, sms_offsets[i], SEEK_SET) != sms_offsets[i])
goto not_mark3; /* actually it could be but can't be detected */
if (pm_read(buff, 16, pmf) != 16)
goto not_mark3;
if (strncasecmp("TMR SEGA", buff, 8) == 0) {
pm_close(pmf);
return PM_MARK3;
}
}
not_mark3:
pm_close(pmf);
/* the main emu function is to emulate MD, so assume MD */
return PM_MD_CART;
}
static int extract_text(char *dest, const unsigned char *src, int len, int swab) static int extract_text(char *dest, const unsigned char *src, int len, int swab)
{ {
char *p = dest; char *p = dest;
@ -321,6 +372,7 @@ static void shutdown_MCD(void)
} }
// note: this function might mangle rom_fname // note: this function might mangle rom_fname
// XXX: portions of this code should move to pico/
int emu_reload_rom(char *rom_fname) int emu_reload_rom(char *rom_fname)
{ {
unsigned int rom_size = 0; unsigned int rom_size = 0;
@ -328,20 +380,14 @@ int emu_reload_rom(char *rom_fname)
unsigned char *rom_data = NULL; unsigned char *rom_data = NULL;
char ext[5]; char ext[5];
pm_file *rom = NULL; pm_file *rom = NULL;
int ret, cd_state, cd_region, cfg_loaded = 0; int cd_state = CIT_NOT_CD;
int ret, media_type, cd_region;
int cfg_loaded = 0, bad_rom = 0;
lprintf("emu_ReloadRom(%s)\n", rom_fname); lprintf("emu_ReloadRom(%s)\n", rom_fname);
get_ext(rom_fname, ext); get_ext(rom_fname, ext);
// detect wrong extensions
if (!strcmp(ext, ".srm") || !strcmp(ext, "s.gz") || !strcmp(ext, ".mds")) { // s.gz ~ .mds.gz
me_update_msg("Not a ROM/CD selected.");
return 0;
}
PicoPatchUnload();
// check for movie file // check for movie file
if (movie_data) { if (movie_data) {
free(movie_data); free(movie_data);
@ -396,46 +442,53 @@ int emu_reload_rom(char *rom_fname)
get_ext(rom_fname, ext); get_ext(rom_fname, ext);
} }
media_type = detect_media(rom_fname);
if (media_type == PM_BAD) {
me_update_msg("Not a ROM/CD img selected.");
return 0;
}
shutdown_MCD(); shutdown_MCD();
PicoPatchUnload();
// check for MegaCD image if (media_type == PM_CD)
cd_state = emu_cd_check(&cd_region, rom_fname);
if (cd_state >= 0 && cd_state != CIT_NOT_CD)
{ {
PicoAHW |= PAHW_MCD; // check for MegaCD image
// valid CD image, check for BIOS.. cd_state = emu_cd_check(&cd_region, rom_fname);
if (cd_state >= 0 && cd_state != CIT_NOT_CD)
{
// valid CD image, check for BIOS..
// we need to have config loaded at this point // we need to have config loaded at this point
ret = emu_read_config(1, 0); ret = emu_read_config(1, 0);
if (!ret) emu_read_config(0, 0); if (!ret) emu_read_config(0, 0);
cfg_loaded = 1; cfg_loaded = 1;
if (PicoRegionOverride) { if (PicoRegionOverride) {
cd_region = PicoRegionOverride; cd_region = PicoRegionOverride;
lprintf("overrided region to %s\n", cd_region != 4 ? (cd_region == 8 ? "EU" : "JAP") : "USA"); lprintf("override region to %s\n", cd_region != 4 ?
(cd_region == 8 ? "EU" : "JAP") : "USA");
}
if (!find_bios(cd_region, &used_rom_name))
return 0;
get_ext(used_rom_name, ext);
PicoAHW |= PAHW_MCD;
} }
if (!find_bios(cd_region, &used_rom_name)) { else {
PicoAHW &= ~PAHW_MCD; me_update_msg("Invalid CD image");
return 0; return 0;
} }
get_ext(used_rom_name, ext);
} }
else else if (media_type == PM_MARK3) {
{ lprintf("detected SMS ROM\n");
if (PicoAHW & PAHW_MCD) Stop_CD(); PicoAHW = PAHW_SMS;
PicoAHW &= ~PAHW_MCD;
} }
rom = pm_open(used_rom_name); rom = pm_open(used_rom_name);
if (!rom) { if (rom == NULL) {
me_update_msg("Failed to open ROM/CD image"); me_update_msg("Failed to open ROM");
goto fail; return 0;
}
if (cd_state < 0) {
me_update_msg("Invalid CD image");
goto fail;
} }
menu_romload_prepare(used_rom_name); // also CD load menu_romload_prepare(used_rom_name); // also CD load
@ -443,21 +496,29 @@ int emu_reload_rom(char *rom_fname)
PicoCartUnload(); PicoCartUnload();
rom_loaded = 0; rom_loaded = 0;
if ( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) { ret = PicoCartLoad(rom, &rom_data, &rom_size, (PicoAHW & PAHW_SMS) ? 1 : 0);
pm_close(rom);
if (ret != 0) {
if (ret == 2) me_update_msg("Out of memory"); if (ret == 2) me_update_msg("Out of memory");
else if (ret == 3) me_update_msg("Read failed"); else if (ret == 3) me_update_msg("Read failed");
else me_update_msg("PicoCartLoad() failed."); else me_update_msg("PicoCartLoad() failed.");
goto fail2; goto fail;
} }
pm_close(rom);
rom = NULL;
// detect wrong files (Pico crashes on very small files), also see if ROM EP is good // detect wrong files
if (rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 || if (strncmp((char *)rom_data, "Pico", 4) == 0)
((*(unsigned char *)(rom_data+4)<<16)|(*(unsigned short *)(rom_data+6))) >= (int)rom_size) { bad_rom = 1;
if (rom_data) free(rom_data); else if (!(PicoAHW & PAHW_SMS)) {
me_update_msg("Not a ROM selected."); unsigned short *d = (unsigned short *)(rom_data + 4);
goto fail2; if ((((d[0] << 16) | d[1]) & 0xffffff) >= (int)rom_size) {
lprintf("bad reset vector\n");
bad_rom = 1;
}
}
if (bad_rom) {
me_update_msg("Bad ROM detected.");
goto fail;
} }
// load config for this ROM (do this before insert to get correct region) // load config for this ROM (do this before insert to get correct region)
@ -468,18 +529,19 @@ int emu_reload_rom(char *rom_fname)
if (!ret) emu_read_config(0, 0); if (!ret) emu_read_config(0, 0);
} }
lprintf("PicoCartInsert(%p, %d);\n", rom_data, rom_size);
if (PicoCartInsert(rom_data, rom_size)) { if (PicoCartInsert(rom_data, rom_size)) {
me_update_msg("Failed to load ROM."); me_update_msg("Failed to load ROM.");
goto fail2; goto fail;
} }
// insert CD if it was detected // insert CD if it was detected
if (cd_state != CIT_NOT_CD) { if (cd_state != CIT_NOT_CD) {
ret = Insert_CD(rom_fname, cd_state); ret = Insert_CD(rom_fname, cd_state);
if (ret != 0) { if (ret != 0) {
PicoCartUnload();
rom_data = NULL; // freed by unload
me_update_msg("Insert_CD() failed, invalid CD image?"); me_update_msg("Insert_CD() failed, invalid CD image?");
goto fail2; goto fail;
} }
} }
@ -511,8 +573,22 @@ int emu_reload_rom(char *rom_fname)
} }
else else
{ {
const char *sys_name, *tv_standard;
int fps;
if (PicoAHW & PAHW_SMS) {
sys_name = "Master System";
} else {
sys_name = "MegaDrive";
if ((Pico.m.hardware&0xc0) == 0x80)
sys_name = "Genesis";
}
tv_standard = Pico.m.pal ? "PAL" : "NTSC";
fps = Pico.m.pal ? 50 : 60;
emu_status_msg("%s %s / %dFPS", tv_standard, sys_name, fps);
PicoOpt &= ~POPT_DIS_VDP_FIFO; PicoOpt &= ~POPT_DIS_VDP_FIFO;
emu_status_msg(Pico.m.pal ? "PAL SYSTEM / 50 FPS" : "NTSC SYSTEM / 60 FPS");
} }
strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1); strncpy(rom_fname_loaded, rom_fname, sizeof(rom_fname_loaded)-1);
@ -525,10 +601,10 @@ int emu_reload_rom(char *rom_fname)
return 1; return 1;
fail2:
menu_romload_end();
fail: fail:
if (rom != NULL) pm_close(rom); if (rom_data)
free(rom_data);
menu_romload_end();
return 0; return 0;
} }

View file

@ -9,6 +9,8 @@
extern "C" { extern "C" {
#endif #endif
#define array_size(x) (sizeof(x) / sizeof(x[0]))
extern void *g_screen_ptr; extern void *g_screen_ptr;
#if SCREEN_SIZE_FIXED #if SCREEN_SIZE_FIXED
@ -97,6 +99,13 @@ enum TPicoGameState {
PGS_SuspendWake, /* PSP */ PGS_SuspendWake, /* PSP */
}; };
// media types
enum {
PM_BAD = 0,
PM_MD_CART, /* also 32x */
PM_MARK3,
PM_CD,
};
void emu_init(void); void emu_init(void);
void emu_finish(void); void emu_finish(void);

View file

@ -22,8 +22,6 @@
#include <pico/pico_int.h> #include <pico/pico_int.h>
#include <pico/patch.h> #include <pico/patch.h>
#define array_size(x) (sizeof(x) / sizeof(x[0]))
static char static_buff[64]; static char static_buff[64];
static char menu_error_msg[64] = { 0, }; static char menu_error_msg[64] = { 0, };
static int menu_error_time = 0; static int menu_error_time = 0;

View file

@ -12,7 +12,7 @@ CFLAGS += -O3 -Wall
CFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math CFLAGS += -ftracer -fstrength-reduce -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math
CFLAGS += -fprofile-generate CFLAGS += -fprofile-generate
else else
CFLAGS = -ggdb -Wall CFLAGS = -ggdb -Wall -falign-functions=2
endif endif
DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV DEFINES = _UNZIP_SUPPORT IO_STATS IN_EVDEV
CFLAGS += -I../.. -I. CFLAGS += -I../.. -I.
@ -38,7 +38,8 @@ endif
# Pico # Pico
OBJS += pico/area.o pico/cart.o pico/memory.o pico/misc.o pico/pico.o pico/sek.o \ 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 # Pico - CD
OBJS += pico/cd/pico.o pico/cd/memory.o pico/cd/sek.o pico/cd/LC89510.o \ 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 \ pico/cd/cd_sys.o pico/cd/cd_file.o pico/cd/cue.o pico/cd/gfx_cd.o \