.cue support, Pico stubs

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@433 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2008-05-01 11:27:50 +00:00
parent b923ecbe75
commit 9037e45d9f
16 changed files with 530 additions and 161 deletions

View file

@ -528,9 +528,14 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
// setup correct memory map for loaded ROM // setup correct memory map for loaded ROM
// call PicoMemReset again due to possible memmap change // call PicoMemReset again due to possible memmap change
if (PicoAHW & PAHW_MCD) switch (PicoAHW) {
PicoMemSetupCD(); default:
else PicoMemSetup(); elprintf(EL_STATUS|EL_ANOMALY, "starting in unknown hw configuration: %x", PicoAHW);
case 0:
case PAHW_SVP: PicoMemSetup(); break;
case PAHW_MCD: PicoMemSetupCD(); break;
case PAHW_PICO: PicoMemSetupPico(); break;
}
PicoMemReset(); PicoMemReset();
PicoPower(); PicoPower();
@ -674,6 +679,13 @@ static void PicoCartDetect(void)
PicoSVPStartup(); PicoSVPStartup();
} }
// Pico
else if (rom_strcmp(0x100, "SEGA PICO") == 0 ||
rom_strcmp(0x100, "IMA IKUNOUJYUKU") == 0) // what is that supposed to mean?
{
PicoInitPico();
}
// Detect 12-in-1 mapper // Detect 12-in-1 mapper
else if ((name_cmp("ROBOCOP 3") == 0 && Pico.romsize == 0x200000) || else if ((name_cmp("ROBOCOP 3") == 0 && Pico.romsize == 0x200000) ||
(rom_strcmp(0x160, "FLICKY") == 0 && Pico.romsize >= 0x200000) || (rom_strcmp(0x160, "FLICKY") == 0 && Pico.romsize >= 0x200000) ||

View file

@ -210,6 +210,14 @@ static u32 OtherRead16End(u32 a, int realsize)
{ {
u32 d=0; u32 d=0;
// 32x test
/*
if (a == 0xa130ec) { d = 0x4d41; goto end; } // MA
else if (a == 0xa130ee) { d = 0x5253; goto end; } // RS
else if (a == 0xa15100) { d = 0x0080; goto end; }
else
*/
// for games with simple protection devices, discovered by Haze // for games with simple protection devices, discovered by Haze
// some dumb detection is used, but that should be enough to make things work // some dumb detection is used, but that should be enough to make things work
if ((a>>22) == 1 && Pico.romsize >= 512*1024) { if ((a>>22) == 1 && Pico.romsize >= 512*1024) {
@ -488,7 +496,6 @@ static void PicoWrite32(u32 a,u32 d)
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// TODO: asm code
static void OtherWrite16End(u32 a,u32 d,int realsize) static void OtherWrite16End(u32 a,u32 d,int realsize)
{ {
PicoWrite8Hook(a, d>>8, realsize); PicoWrite8Hook(a, d>>8, realsize);
@ -507,6 +514,10 @@ PICO_INTERNAL void PicoMemResetHooks(void)
PicoWrite16Hook = OtherWrite16End; PicoWrite16Hook = OtherWrite16End;
} }
#ifdef EMU_M68K
static void m68k_mem_setup(void);
#endif
PICO_INTERNAL void PicoMemSetup(void) PICO_INTERNAL void PicoMemSetup(void)
{ {
// Setup memory callbacks: // Setup memory callbacks:
@ -530,7 +541,7 @@ PICO_INTERNAL void PicoMemSetup(void)
// setup FAME fetchmap // setup FAME fetchmap
{ {
int i; int i;
// by default, point everything to fitst 64k of ROM // by default, point everything to first 64k of ROM
for (i = 0; i < M68K_FETCHBANK1; i++) for (i = 0; i < M68K_FETCHBANK1; i++)
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS)); PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
// now real ROM // now real ROM
@ -541,15 +552,24 @@ PICO_INTERNAL void PicoMemSetup(void)
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS)); PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
} }
#endif #endif
#ifdef EMU_M68K
m68k_mem_setup();
#endif
} }
/* some nasty things below :( */
#ifdef EMU_M68K #ifdef EMU_M68K
unsigned int m68k_read_pcrelative_CD8 (unsigned int a); unsigned int (*pm68k_read_memory_8) (unsigned int address) = NULL;
unsigned int m68k_read_pcrelative_CD16(unsigned int a); unsigned int (*pm68k_read_memory_16)(unsigned int address) = NULL;
unsigned int m68k_read_pcrelative_CD32(unsigned int a); unsigned int (*pm68k_read_memory_32)(unsigned int address) = NULL;
void (*pm68k_write_memory_8) (unsigned int address, unsigned char value) = NULL;
void (*pm68k_write_memory_16)(unsigned int address, unsigned short value) = NULL;
void (*pm68k_write_memory_32)(unsigned int address, unsigned int value) = NULL;
unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address) = NULL;
unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address) = NULL;
unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address) = NULL;
// these are allowed to access RAM // these are here for core debugging mode
static unsigned int m68k_read_8 (unsigned int a, int do_fake) static unsigned int m68k_read_8 (unsigned int a, int do_fake)
{ {
a&=0xffffff; a&=0xffffff;
@ -557,9 +577,7 @@ static unsigned int m68k_read_8 (unsigned int a, int do_fake)
#ifdef EMU_CORE_DEBUG #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if(PicoAHW&1) return m68k_read_pcrelative_CD8(a); return pm68k_read_memory_pcr_8(a);
if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
return 0;
} }
static unsigned int m68k_read_16(unsigned int a, int do_fake) static unsigned int m68k_read_16(unsigned int a, int do_fake)
{ {
@ -568,9 +586,7 @@ static unsigned int m68k_read_16(unsigned int a, int do_fake)
#ifdef EMU_CORE_DEBUG #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if(PicoAHW&1) return m68k_read_pcrelative_CD16(a); return pm68k_read_memory_pcr_16(a);
if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
return 0;
} }
static unsigned int m68k_read_32(unsigned int a, int do_fake) static unsigned int m68k_read_32(unsigned int a, int do_fake)
{ {
@ -579,9 +595,7 @@ static unsigned int m68k_read_32(unsigned int a, int do_fake)
#ifdef EMU_CORE_DEBUG #ifdef EMU_CORE_DEBUG
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15]; if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
#endif #endif
if(PicoAHW&1) return m68k_read_pcrelative_CD32(a); return pm68k_read_memory_pcr_32(a);
if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
return 0;
} }
unsigned int m68k_read_pcrelative_8 (unsigned int a) { return m68k_read_8 (a, 1); } unsigned int m68k_read_pcrelative_8 (unsigned int a) { return m68k_read_8 (a, 1); }
@ -593,6 +607,24 @@ unsigned int m68k_read_disassembler_8 (unsigned int a) { return m68k_read_8 (a,
unsigned int m68k_read_disassembler_16(unsigned int a) { return m68k_read_16(a, 0); } unsigned int m68k_read_disassembler_16(unsigned int a) { return m68k_read_16(a, 0); }
unsigned int m68k_read_disassembler_32(unsigned int a) { return m68k_read_32(a, 0); } unsigned int m68k_read_disassembler_32(unsigned int a) { return m68k_read_32(a, 0); }
static unsigned int m68k_read_memory_pcr_8(unsigned int a)
{
if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
return 0;
}
static unsigned int m68k_read_memory_pcr_16(unsigned int a)
{
if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
return 0;
}
static unsigned int m68k_read_memory_pcr_32(unsigned int a)
{
if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
return 0;
}
#ifdef EMU_CORE_DEBUG #ifdef EMU_CORE_DEBUG
// ROM only // ROM only
unsigned int m68k_read_memory_8(unsigned int a) unsigned int m68k_read_memory_8(unsigned int a)
@ -628,47 +660,30 @@ unsigned int m68k_read_memory_32(unsigned int a)
void m68k_write_memory_8(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; } void m68k_write_memory_8(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
void m68k_write_memory_16(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; } void m68k_write_memory_16(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
void m68k_write_memory_32(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; } void m68k_write_memory_32(unsigned int address, unsigned int value) { lastwrite_mus_d[lwp_mus++&15] = value; }
#else
unsigned char PicoReadCD8w (unsigned int a); #else // if !EMU_CORE_DEBUG
unsigned short PicoReadCD16w(unsigned int a);
unsigned int PicoReadCD32w(unsigned int a);
void PicoWriteCD8w (unsigned int a, unsigned char d);
void PicoWriteCD16w(unsigned int a, unsigned short d);
void PicoWriteCD32w(unsigned int a, unsigned int d);
/* it appears that Musashi doesn't always mask the unused bits */ /* it appears that Musashi doesn't always mask the unused bits */
unsigned int m68k_read_memory_8(unsigned int address) unsigned int m68k_read_memory_8 (unsigned int address) { return pm68k_read_memory_8 (address) & 0xff; }
{ unsigned int m68k_read_memory_16(unsigned int address) { return pm68k_read_memory_16(address) & 0xffff; }
unsigned int d = (PicoAHW&1) ? PicoReadCD8w(address) : PicoRead8(address); unsigned int m68k_read_memory_32(unsigned int address) { return pm68k_read_memory_32(address); }
return d&0xff; void m68k_write_memory_8 (unsigned int address, unsigned int value) { pm68k_write_memory_8 (address, (u8)value); }
} void m68k_write_memory_16(unsigned int address, unsigned int value) { pm68k_write_memory_16(address,(u16)value); }
void m68k_write_memory_32(unsigned int address, unsigned int value) { pm68k_write_memory_32(address, value); }
#endif // !EMU_CORE_DEBUG
unsigned int m68k_read_memory_16(unsigned int address) static void m68k_mem_setup(void)
{ {
unsigned int d = (PicoAHW&1) ? PicoReadCD16w(address) : PicoRead16(address); pm68k_read_memory_8 = PicoRead8;
return d&0xffff; pm68k_read_memory_16 = PicoRead16;
pm68k_read_memory_32 = PicoRead32;
pm68k_write_memory_8 = PicoWrite8;
pm68k_write_memory_16 = PicoWrite16;
pm68k_write_memory_32 = PicoWrite32;
pm68k_read_memory_pcr_8 = m68k_read_memory_pcr_8;
pm68k_read_memory_pcr_16 = m68k_read_memory_pcr_16;
pm68k_read_memory_pcr_32 = m68k_read_memory_pcr_32;
} }
unsigned int m68k_read_memory_32(unsigned int address)
{
return (PicoAHW&1) ? PicoReadCD32w(address) : PicoRead32(address);
}
void m68k_write_memory_8(unsigned int address, unsigned int value)
{
if (PicoAHW&1) PicoWriteCD8w(address, (u8)value); else PicoWrite8(address, (u8)value);
}
void m68k_write_memory_16(unsigned int address, unsigned int value)
{
if (PicoAHW&1) PicoWriteCD16w(address,(u16)value); else PicoWrite16(address,(u16)value);
}
void m68k_write_memory_32(unsigned int address, unsigned int value)
{
if (PicoAHW&1) PicoWriteCD32w(address, value); else PicoWrite32(address, value);
}
#endif
#endif // EMU_M68K #endif // EMU_M68K

View file

@ -16,7 +16,7 @@ int PicoOpt = 0;
int PicoSkipFrame = 0; // skip rendering frame? int PicoSkipFrame = 0; // skip rendering frame?
int emustatus = 0; // rapid_ym2612, multi_ym_updates int emustatus = 0; // rapid_ym2612, multi_ym_updates
int PicoPad[2]; // Joypads, format is SACB RLDU int PicoPad[2]; // Joypads, format is SACB RLDU
int PicoAHW = 0; // active addon hardware: scd_active, 32x_active, svp_active int PicoAHW = 0; // active addon hardware: scd_active, 32x_active, svp_active, pico_active
int PicoRegionOverride = 0; // override the region detection 0: Auto, 1: Japan NTSC, 2: Japan PAL, 4: US, 8: Europe int PicoRegionOverride = 0; // override the region detection 0: Auto, 1: Japan NTSC, 2: Japan PAL, 4: US, 8: Europe
int PicoAutoRgnOrder = 0; int PicoAutoRgnOrder = 0;
int z80startCycle, z80stopCycle; // in 68k cycles int z80startCycle, z80stopCycle; // in 68k cycles

179
Pico/Pico/Memory.c Normal file
View file

@ -0,0 +1,179 @@
#include "../PicoInt.h"
#ifndef UTYPES_DEFINED
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#define UTYPES_DEFINED
#endif
// -----------------------------------------------------------------
// Read Rom and read Ram
static u32 PicoReadPico8(u32 a)
{
u32 d=0;
if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram
if (a<Pico.romsize) { d = *(u8 *)(Pico.rom+(a^1)); goto end; } // Rom
a&=0xffffff;
if ((a&0xffffe0)==0xc00000) { // VDP
d=PicoVideoRead(a);
if ((a&1)==0) d>>=8;
goto end;
}
elprintf(EL_UIO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
end:
elprintf(EL_IO, "r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
return d;
}
static u32 PicoReadPico16(u32 a)
{
u32 d=0;
if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram
a&=0xfffffe;
if (a<Pico.romsize) { d = *(u16 *)(Pico.rom+a); goto end; } // Rom
if ((a&0xffffe0)==0xc00000) {
d = PicoVideoRead(a);
goto end;
}
elprintf(EL_UIO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
end:
elprintf(EL_IO, "r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
return d;
}
static u32 PicoReadPico32(u32 a)
{
u32 d=0;
if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram
a&=0xfffffe;
if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); d = (pm[0]<<16)|pm[1]; goto end; } // Rom
if ((a&0xffffe0)==0xc00000) {
d = (PicoVideoRead(a)<<16)|PicoVideoRead(a+2);
goto end;
}
elprintf(EL_UIO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
end:
elprintf(EL_IO, "r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
return d;
}
// -----------------------------------------------------------------
// Write Ram
static void PicoWritePico8(u32 a,u8 d)
{
elprintf(EL_IO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram
a&=0xffffff;
if ((a&0xffffe0)==0xc00000) { // VDP
d&=0xff;
PicoVideoWrite(a,(u16)(d|(d<<8))); // Byte access gets mirrored
return;
}
elprintf(EL_UIO, "w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
}
static void PicoWritePico16(u32 a,u16 d)
{
elprintf(EL_IO, "w16: %06x, %04x", a&0xffffff, d);
if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
a&=0xfffffe;
if ((a&0xffffe0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; } // VDP
elprintf(EL_UIO, "w16: %06x, %04x", a&0xffffff, d);
}
static void PicoWritePico32(u32 a,u32 d)
{
elprintf(EL_IO, "w32: %06x, %08x", a&0xffffff, d);
if ((a&0xe00000)==0xe00000)
{
// Ram:
u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));
pm[0]=(u16)(d>>16); pm[1]=(u16)d;
return;
}
a&=0xfffffe;
if ((a&0xffffe0)==0xc00000)
{
// VDP:
PicoVideoWrite(a, (u16)(d>>16));
PicoVideoWrite(a+2,(u16)d);
return;
}
elprintf(EL_UIO, "w32: %06x, %08x", a&0xffffff, d);
}
#ifdef EMU_M68K
extern unsigned int (*pm68k_read_memory_8) (unsigned int address);
extern unsigned int (*pm68k_read_memory_16)(unsigned int address);
extern unsigned int (*pm68k_read_memory_32)(unsigned int address);
extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value);
extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value);
extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value);
extern unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address);
extern unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address);
extern unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address);
static unsigned int m68k_read_memory_pcrp_8(unsigned int a)
{
if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
return 0;
}
static unsigned int m68k_read_memory_pcrp_16(unsigned int a)
{
if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
return 0;
}
static unsigned int m68k_read_memory_pcrp_32(unsigned int a)
{
if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
return 0;
}
#endif // EMU_M68K
PICO_INTERNAL void PicoMemSetupPico(void)
{
#ifdef EMU_M68K
pm68k_read_memory_8 = PicoReadPico8;
pm68k_read_memory_16 = PicoReadPico16;
pm68k_read_memory_32 = PicoReadPico32;
pm68k_write_memory_8 = PicoWritePico8;
pm68k_write_memory_16 = PicoWritePico16;
pm68k_write_memory_32 = PicoWritePico32;
pm68k_read_memory_pcr_8 = m68k_read_memory_pcrp_8;
pm68k_read_memory_pcr_16 = m68k_read_memory_pcrp_16;
pm68k_read_memory_pcr_32 = m68k_read_memory_pcrp_32;
#endif
}

10
Pico/Pico/Pico.c Normal file
View file

@ -0,0 +1,10 @@
#include "../PicoInt.h"
PICO_INTERNAL int PicoInitPico(void)
{
elprintf(EL_STATUS, "Pico detected");
PicoAHW = PAHW_PICO;
return 0;
}

View file

@ -212,9 +212,10 @@ extern struct DrZ80 drZ80;
// --------------------------------------------------------- // ---------------------------------------------------------
// Pico active hw // Pico active hw
#define PAHW_MCD (1<<0) #define PAHW_MCD (1<<0)
#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)
extern int PicoAHW; extern int PicoAHW;
// main oscillator clock which controls timing // main oscillator clock which controls timing
@ -420,6 +421,9 @@ PICO_INTERNAL void PicoMemSetupCD(void);
PICO_INTERNAL_ASM void PicoMemResetCD(int r3); PICO_INTERNAL_ASM void PicoMemResetCD(int r3);
PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3); PICO_INTERNAL_ASM void PicoMemResetCDdecode(int r3);
// Pico/Memory.c
PICO_INTERNAL void PicoMemSetupPico(void);
// Pico.c // Pico.c
extern struct Pico Pico; extern struct Pico Pico;
extern struct PicoSRAM SRam; extern struct PicoSRAM SRam;
@ -436,6 +440,9 @@ PICO_INTERNAL void PicoPowerMCD(void);
PICO_INTERNAL int PicoResetMCD(void); PICO_INTERNAL int PicoResetMCD(void);
PICO_INTERNAL int PicoFrameMCD(void); PICO_INTERNAL int PicoFrameMCD(void);
// Pico/Pico.c
PICO_INTERNAL int PicoInitPico(void);
// Sek.c // Sek.c
PICO_INTERNAL int SekInit(void); PICO_INTERNAL int SekInit(void);
PICO_INTERNAL int SekReset(void); PICO_INTERNAL int SekReset(void);

View file

@ -114,7 +114,7 @@ PICO_INTERNAL int SekInit()
m68k_init(); m68k_init();
m68k_set_int_ack_callback(SekIntAckM68K); m68k_set_int_ack_callback(SekIntAckM68K);
m68k_set_tas_instr_callback(SekTasCallback); m68k_set_tas_instr_callback(SekTasCallback);
m68k_pulse_reset(); // Init cpu emulator //m68k_pulse_reset();
m68k_set_context(oldcontext); m68k_set_context(oldcontext);
} }
#endif #endif

View file

@ -1636,6 +1636,10 @@ void PicoMemResetCD(int r3)
} }
#endif #endif
#ifdef EMU_M68K
static void m68k_mem_setup_cd(void);
#endif
PICO_INTERNAL void PicoMemSetupCD(void) PICO_INTERNAL void PicoMemSetupCD(void)
{ {
// additional handlers for common code // additional handlers for common code
@ -1702,6 +1706,9 @@ PICO_INTERNAL void PicoMemSetupCD(void)
// PicoMemResetCD() will setup word ram for both // PicoMemResetCD() will setup word ram for both
} }
#endif #endif
#ifdef EMU_M68K
m68k_mem_setup_cd();
#endif
// m68k_poll_addr = m68k_poll_cnt = 0; // m68k_poll_addr = m68k_poll_cnt = 0;
s68k_poll_adclk = s68k_poll_cnt = 0; s68k_poll_adclk = s68k_poll_cnt = 0;
@ -1709,27 +1716,27 @@ PICO_INTERNAL void PicoMemSetupCD(void)
#ifdef EMU_M68K #ifdef EMU_M68K
unsigned char PicoReadCD8w (unsigned int a) { static unsigned int PicoReadCD8w (unsigned int a) {
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a); return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a);
} }
unsigned short PicoReadCD16w(unsigned int a) { static unsigned int PicoReadCD16w(unsigned int a) {
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a); return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a);
} }
unsigned int PicoReadCD32w(unsigned int a) { static unsigned int PicoReadCD32w(unsigned int a) {
return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a); return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a);
} }
void PicoWriteCD8w (unsigned int a, unsigned char d) { static void PicoWriteCD8w (unsigned int a, unsigned char d) {
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d); if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);
} }
void PicoWriteCD16w(unsigned int a, unsigned short d) { static void PicoWriteCD16w(unsigned int a, unsigned short d) {
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d); if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);
} }
void PicoWriteCD32w(unsigned int a, unsigned int d) { static void PicoWriteCD32w(unsigned int a, unsigned int d) {
if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d); if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);
} }
// these are allowed to access RAM // these are allowed to access RAM
unsigned int m68k_read_pcrelative_CD8 (unsigned int a) static unsigned int m68k_read_pcrelative_CD8 (unsigned int a)
{ {
a&=0xffffff; a&=0xffffff;
if(m68ki_cpu_p == &PicoCpuMS68k) { if(m68ki_cpu_p == &PicoCpuMS68k) {
@ -1756,7 +1763,7 @@ unsigned int m68k_read_pcrelative_CD8 (unsigned int a)
} }
return 0;//(u8) lastread_d; return 0;//(u8) lastread_d;
} }
unsigned int m68k_read_pcrelative_CD16(unsigned int a) static unsigned int m68k_read_pcrelative_CD16(unsigned int a)
{ {
a&=0xffffff; a&=0xffffff;
if(m68ki_cpu_p == &PicoCpuMS68k) { if(m68ki_cpu_p == &PicoCpuMS68k) {
@ -1783,7 +1790,7 @@ unsigned int m68k_read_pcrelative_CD16(unsigned int a)
} }
return 0; return 0;
} }
unsigned int m68k_read_pcrelative_CD32(unsigned int a) static unsigned int m68k_read_pcrelative_CD32(unsigned int a)
{ {
u16 *pm; u16 *pm;
a&=0xffffff; a&=0xffffff;
@ -1813,5 +1820,28 @@ unsigned int m68k_read_pcrelative_CD32(unsigned int a)
} }
return 0; return 0;
} }
extern unsigned int (*pm68k_read_memory_8) (unsigned int address);
extern unsigned int (*pm68k_read_memory_16)(unsigned int address);
extern unsigned int (*pm68k_read_memory_32)(unsigned int address);
extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value);
extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value);
extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value);
extern unsigned int (*pm68k_read_memory_pcr_8) (unsigned int address);
extern unsigned int (*pm68k_read_memory_pcr_16)(unsigned int address);
extern unsigned int (*pm68k_read_memory_pcr_32)(unsigned int address);
static void m68k_mem_setup_cd(void)
{
pm68k_read_memory_8 = PicoReadCD8w;
pm68k_read_memory_16 = PicoReadCD16w;
pm68k_read_memory_32 = PicoReadCD32w;
pm68k_write_memory_8 = PicoWriteCD8w;
pm68k_write_memory_16 = PicoWriteCD16w;
pm68k_write_memory_32 = PicoWriteCD32w;
pm68k_read_memory_pcr_8 = m68k_read_pcrelative_CD8;
pm68k_read_memory_pcr_16 = m68k_read_pcrelative_CD16;
pm68k_read_memory_pcr_32 = m68k_read_pcrelative_CD32;
}
#endif // EMU_M68K #endif // EMU_M68K

View file

@ -9,15 +9,61 @@
#include "../PicoInt.h" #include "../PicoInt.h"
#include "cd_file.h" #include "cd_file.h"
#include "cue.h"
//#define cdprintf(f,...) printf(f "\n",##__VA_ARGS__) // tmp //#define cdprintf(f,...) printf(f "\n",##__VA_ARGS__) // tmp
#define DEBUG_CD
PICO_INTERNAL int Load_CD_Image(const char *iso_name, cd_img_type type) static int audio_track_mp3(const char *fname, int index)
{ {
int i, j, num_track, Cur_LBA, index, ret, iso_name_len; _scd_track *Tracks = Pico_mcd->TOC.Tracks;
FILE *tmp_file;
int fs, ret;
tmp_file = fopen(fname, "rb");
if (tmp_file == NULL)
return -1;
ret = fseek(tmp_file, 0, SEEK_END);
fs = ftell(tmp_file); // used to calculate length
fseek(tmp_file, 0, SEEK_SET);
#if DONT_OPEN_MANY_FILES
// some systems (like PSP) can't have many open files at a time,
// so we work with their names instead.
fclose(tmp_file);
tmp_file = (void *) strdup(fname);
#endif
Tracks[index].KBtps = (short) mp3_get_bitrate(tmp_file, fs);
Tracks[index].KBtps >>= 3;
if (ret != 0 || Tracks[index].KBtps <= 0)
{
elprintf(EL_STATUS, "track %2i: mp3 bitrate %i", index+1, Tracks[index].KBtps);
#if !DONT_OPEN_MANY_FILES
fclose(tmp_file);
#else
free(tmp_file);
#endif
return -1;
}
Tracks[index].F = tmp_file;
// MP3 File
Tracks[index].ftype = TYPE_MP3;
fs *= 75;
fs /= Tracks[index].KBtps * 1000;
Tracks[index].Length = fs;
Tracks[index].Offset = 0;
return 0;
}
PICO_INTERNAL int Load_CD_Image(const char *cd_img_name, cd_img_type type)
{
int i, j, num_track, Cur_LBA, index, ret, iso_name_len, missed, cd_img_sectors;
_scd_track *Tracks = Pico_mcd->TOC.Tracks; _scd_track *Tracks = Pico_mcd->TOC.Tracks;
char tmp_name[1024], tmp_ext[10]; char tmp_name[1024], tmp_ext[10];
cue_data_t *cue_data = NULL;
pm_file *pmf; pm_file *pmf;
static char *exts[] = { static char *exts[] = {
"%02d.mp3", " %02d.mp3", "-%02d.mp3", "_%02d.mp3", " - %02d.mp3", "%02d.mp3", " %02d.mp3", "-%02d.mp3", "_%02d.mp3", " - %02d.mp3",
@ -31,109 +77,134 @@ PICO_INTERNAL int Load_CD_Image(const char *iso_name, cd_img_type type)
Unload_ISO(); Unload_ISO();
/* is this .cue? */
ret = strlen(cd_img_name);
if (ret >= 3 && strcasecmp(cd_img_name + ret - 3, "cue") == 0)
cue_data = cue_parse(cd_img_name);
if (cue_data != NULL)
cd_img_name = cue_data->tracks[1].fname;
Tracks[0].ftype = type == CIT_BIN ? TYPE_BIN : TYPE_ISO; Tracks[0].ftype = type == CIT_BIN ? TYPE_BIN : TYPE_ISO;
Tracks[0].F = pmf = pm_open(iso_name); Tracks[0].F = pmf = pm_open(cd_img_name);
if (Tracks[0].F == NULL) if (Tracks[0].F == NULL)
{ {
Tracks[0].ftype = 0; Tracks[0].ftype = 0;
Tracks[0].Length = 0; Tracks[0].Length = 0;
if (cue_data != NULL)
cue_destroy(cue_data);
return -1; return -1;
} }
if (Tracks[0].ftype == TYPE_ISO) if (Tracks[0].ftype == TYPE_ISO)
Tracks[0].Length = pmf->size >>= 11; // size in sectors cd_img_sectors = pmf->size >>= 11; // size in sectors
else Tracks[0].Length = pmf->size /= 2352; else cd_img_sectors = pmf->size /= 2352;
Tracks[0].Offset = 0;
Tracks[0].MSF.M = 0; // minutes Tracks[0].MSF.M = 0; // minutes
Tracks[0].MSF.S = 2; // seconds Tracks[0].MSF.S = 2; // seconds
Tracks[0].MSF.F = 0; // frames Tracks[0].MSF.F = 0; // frames
cdprintf("Track 0 - %02d:%02d:%02d DATA", Tracks[0].MSF.M, Tracks[0].MSF.S, Tracks[0].MSF.F); elprintf(EL_STATUS, "Track 0: %02d:%02d:%02d %9i DATA",
Tracks[0].MSF.M, Tracks[0].MSF.S, Tracks[0].MSF.F, Tracks[0].Length);
Cur_LBA = Tracks[0].Length; // Size in sectors Cur_LBA = Tracks[0].Length = cd_img_sectors;
iso_name_len = strlen(iso_name); if (cue_data != NULL)
{
if (cue_data->tracks[2].fname == NULL) { // NULL means track2 is in same file as track1
Cur_LBA = Tracks[0].Length = cue_data->tracks[2].sector_offset;
}
for (num_track = 2; num_track <= cue_data->track_count; num_track++)
{
index = num_track - 1;
Cur_LBA += cue_data->tracks[num_track].pregap;
if (cue_data->tracks[num_track].type == CT_MP3) {
ret = audio_track_mp3(cue_data->tracks[num_track].fname, index);
if (ret != 0) break;
}
else
{
Tracks[index].ftype = cue_data->tracks[num_track].type;
if (cue_data->tracks[num_track].fname != NULL)
{
Tracks[index].F = fopen(cue_data->tracks[num_track].fname, "rb");
elprintf(EL_STATUS, "track %2i (%s): can't determine length",
cue_data->tracks[num_track].fname);
Tracks[index].Length = 2*75;
Tracks[index].Offset = 0;
} else {
if (num_track < cue_data->track_count)
Tracks[index].Length = cue_data->tracks[num_track+1].sector_offset -
cue_data->tracks[num_track].sector_offset;
else
Tracks[index].Length = cd_img_sectors - cue_data->tracks[num_track].sector_offset;
Tracks[index].Offset = cue_data->tracks[num_track].sector_offset;
}
}
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
Cur_LBA += Tracks[index].Length;
elprintf(EL_STATUS, "Track %2i: %02d:%02d:%02d %9i AUDIO - %s", index, Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F, Tracks[index].Length,
cue_data->tracks[num_track].fname);
}
cue_destroy(cue_data);
goto finish;
}
/* track autosearch, Gens-like */
iso_name_len = strlen(cd_img_name);
if (iso_name_len >= sizeof(tmp_name)) if (iso_name_len >= sizeof(tmp_name))
iso_name_len = sizeof(tmp_name) - 1; iso_name_len = sizeof(tmp_name) - 1;
for (num_track = 2, i = 0; i < 100; i++) for (num_track = 2, i = 0, missed = 0; i < 100 && missed < 4; i++)
{ {
if (PicoCDLoadProgressCB != NULL && i > 1) PicoCDLoadProgressCB(i); if (PicoCDLoadProgressCB != NULL && i > 1) PicoCDLoadProgressCB(i + (100-i)*missed/4);
for (j = 0; j < sizeof(exts)/sizeof(char *); j++) for (j = 0; j < sizeof(exts)/sizeof(char *); j++)
{ {
int ext_len; int ext_len;
FILE *tmp_file;
sprintf(tmp_ext, exts[j], i); sprintf(tmp_ext, exts[j], i);
ext_len = strlen(tmp_ext); ext_len = strlen(tmp_ext);
memcpy(tmp_name, iso_name, iso_name_len + 1); memcpy(tmp_name, cd_img_name, iso_name_len + 1);
tmp_name[iso_name_len - 4] = 0; tmp_name[iso_name_len - 4] = 0;
strcat(tmp_name, tmp_ext); strcat(tmp_name, tmp_ext);
tmp_file = fopen(tmp_name, "rb"); index = num_track - 1;
if (!tmp_file && i > 1 && iso_name_len > ext_len) { ret = audio_track_mp3(tmp_name, index);
if (ret != 0 && i > 1 && iso_name_len > ext_len) {
tmp_name[iso_name_len - ext_len] = 0; tmp_name[iso_name_len - ext_len] = 0;
strcat(tmp_name, tmp_ext); strcat(tmp_name, tmp_ext);
tmp_file = fopen(tmp_name, "rb"); ret = audio_track_mp3(tmp_name, index);
} }
if (tmp_file) if (ret == 0)
{ {
int fs;
index = num_track - 1;
ret = fseek(tmp_file, 0, SEEK_END);
fs = ftell(tmp_file); // used to calculate lenght
fseek(tmp_file, 0, SEEK_SET);
#if DONT_OPEN_MANY_FILES
// some systems (like PSP) can't have many open files at a time,
// so we work with their names instead.
fclose(tmp_file);
tmp_file = (void *) strdup(tmp_name);
#endif
Tracks[index].KBtps = (short) mp3_get_bitrate(tmp_file, fs);
Tracks[index].KBtps >>= 3;
if (ret != 0 || Tracks[index].KBtps <= 0)
{
cdprintf("Error track %i: rate %i", index, Tracks[index].KBtps);
#if !DONT_OPEN_MANY_FILES
fclose(tmp_file);
#else
free(tmp_file);
#endif
continue;
}
Tracks[index].F = tmp_file;
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF); LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
// MP3 File
Tracks[index].ftype = TYPE_MP3;
fs *= 75;
fs /= Tracks[index].KBtps * 1000;
Tracks[index].Length = fs;
Cur_LBA += Tracks[index].Length; Cur_LBA += Tracks[index].Length;
cdprintf("Track %i: %s - %02d:%02d:%02d len=%i AUDIO", index, tmp_name, Tracks[index].MSF.M, elprintf(EL_STATUS, "Track %2i: %02d:%02d:%02d %9i AUDIO - %s", index, Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F, fs); Tracks[index].MSF.S, Tracks[index].MSF.F, Tracks[index].Length, tmp_name);
num_track++; num_track++;
missed = 0;
break; break;
} }
} }
if (ret != 0) missed++;
} }
finish:
Pico_mcd->TOC.Last_Track = num_track - 1; Pico_mcd->TOC.Last_Track = num_track - 1;
index = num_track - 1; index = num_track - 1;
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF); LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
cdprintf("End CD - %02d:%02d:%02d\n\n", Tracks[index].MSF.M, elprintf(EL_STATUS, "End CD - %02d:%02d:%02d\n", Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F); Tracks[index].MSF.S, Tracks[index].MSF.F);
if (PicoCDLoadProgressCB != NULL) PicoCDLoadProgressCB(100); if (PicoCDLoadProgressCB != NULL) PicoCDLoadProgressCB(100);
@ -153,11 +224,14 @@ PICO_INTERNAL void Unload_ISO(void)
for(i = 1; i < 100; i++) for(i = 1; i < 100; i++)
{ {
if (Pico_mcd->TOC.Tracks[i].F != NULL) if (Pico_mcd->TOC.Tracks[i].F != NULL)
#if !DONT_OPEN_MANY_FILES {
fclose(Pico_mcd->TOC.Tracks[i].F); #if DONT_OPEN_MANY_FILES
#else if (Pico_mcd->TOC.Tracks[i].type == TYPE_MP3)
free(Pico_mcd->TOC.Tracks[i].F); free(Pico_mcd->TOC.Tracks[i].F);
else
#endif #endif
fclose(Pico_mcd->TOC.Tracks[i].F);
}
} }
memset(Pico_mcd->TOC.Tracks, 0, sizeof(Pico_mcd->TOC.Tracks)); memset(Pico_mcd->TOC.Tracks, 0, sizeof(Pico_mcd->TOC.Tracks));
} }
@ -223,7 +297,6 @@ PICO_INTERNAL int FILE_Read_One_LBA_CDC(void)
//pm_read(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, 2048, Pico_mcd->TOC.Tracks[0].F); //pm_read(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, 2048, Pico_mcd->TOC.Tracks[0].F);
PicoCDBufferRead(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, where_read); PicoCDBufferRead(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, where_read);
#ifdef DEBUG_CD
cdprintf("Read -> WA = %d Buffer[%d] =", Pico_mcd->cdc.WA.N, Pico_mcd->cdc.PT.N & 0x3FFF); cdprintf("Read -> WA = %d Buffer[%d] =", Pico_mcd->cdc.WA.N, Pico_mcd->cdc.PT.N & 0x3FFF);
cdprintf("Header 1 = %.2X %.2X %.2X %.2X", Pico_mcd->cdc.HEAD.B.B0, cdprintf("Header 1 = %.2X %.2X %.2X %.2X", Pico_mcd->cdc.HEAD.B.B0,
Pico_mcd->cdc.HEAD.B.B1, Pico_mcd->cdc.HEAD.B.B2, Pico_mcd->cdc.HEAD.B.B3); Pico_mcd->cdc.HEAD.B.B1, Pico_mcd->cdc.HEAD.B.B2, Pico_mcd->cdc.HEAD.B.B3);
@ -234,7 +307,6 @@ PICO_INTERNAL int FILE_Read_One_LBA_CDC(void)
Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 3) & 0x3FFF], Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 3) & 0x3FFF],
Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 4) & 0x3FFF], Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 4) & 0x3FFF],
Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 5) & 0x3FFF]); Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 5) & 0x3FFF]);
#endif
} }
} }

View file

@ -46,6 +46,7 @@ typedef struct
char ftype; // TYPE_ISO, TYPE_BIN, TYPE_MP3 char ftype; // TYPE_ISO, TYPE_BIN, TYPE_MP3
void *F; void *F;
int Length; int Length;
int Offset; // sector offset, when single file is used for multiple virtual tracks
short KBtps; // kbytes per sec for mp3s (bitrate / 1000 / 8) short KBtps; // kbytes per sec for mp3s (bitrate / 1000 / 8)
short pad; short pad;
} _scd_track; } _scd_track;

View file

@ -3,8 +3,8 @@
#include <string.h> #include <string.h>
#include "cue.h" #include "cue.h"
//#include "../PicoInt.h" #include "../PicoInt.h"
#define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__); // #define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
static char *mystrip(char *str) static char *mystrip(char *str)
{ {
@ -42,7 +42,7 @@ static int get_token(const char *buff, char *dest, int len)
dest[d++] = *p++; dest[d++] = *p++;
dest[d] = 0; dest[d] = 0;
if (*p != sep) if (sep == '\"' && *p != sep)
elprintf(EL_STATUS, "cue: bad token: \"%s\"", buff); elprintf(EL_STATUS, "cue: bad token: \"%s\"", buff);
return d + skip; return d + skip;
@ -51,19 +51,19 @@ static int get_token(const char *buff, char *dest, int len)
static char *get_ext(char *fname) static char *get_ext(char *fname)
{ {
int len = strlen(fname); int len = strlen(fname);
return (len >= 3) ? (fname - 3) : (fname - len); return (len >= 3) ? (fname + len - 3) : fname;
} }
#define BEGINS(buff,str) (strncmp(buff,str,sizeof(str)-1) == 0) #define BEGINS(buff,str) (strncmp(buff,str,sizeof(str)-1) == 0)
/* note: tracks[0] is not used */ /* note: tracks[0] is not used */
cue_data *cue_parse(const char *fname) cue_data_t *cue_parse(const char *fname)
{ {
char buff[256], current_file[256], buff2[32]; char buff[256], current_file[256], buff2[32];
FILE *f, *tmpf; FILE *f, *tmpf;
int ret, count = 0, count_alloc = 2; int ret, count = 0, count_alloc = 2;
cue_data *data; cue_data_t *data;
void *tmp; void *tmp;
f = fopen(fname, "r"); f = fopen(fname, "r");
@ -92,6 +92,7 @@ cue_data *cue_parse(const char *fname)
count_alloc *= 2; count_alloc *= 2;
tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cue_track)); tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cue_track));
if (tmp == NULL) { count--; break; } if (tmp == NULL) { count--; break; }
data = tmp;
} }
memset(&data->tracks[count], 0, sizeof(data->tracks[0])); memset(&data->tracks[count], 0, sizeof(data->tracks[0]));
if (count == 1 || strcmp(data->tracks[1].fname, current_file) != 0) if (count == 1 || strcmp(data->tracks[1].fname, current_file) != 0)
@ -113,11 +114,11 @@ cue_data *cue_parse(const char *fname)
count, atoi(buff2)); count, atoi(buff2));
// check type // check type
get_token(buff+6+ret, buff2, sizeof(buff2)); get_token(buff+6+ret, buff2, sizeof(buff2));
if (strcmp(buff2, "MODE1/2352")) if (strcmp(buff2, "MODE1/2352") == 0)
data->tracks[count].type = CT_BIN; data->tracks[count].type = CT_BIN;
else if (strcmp(buff2, "MODE1/2048")) else if (strcmp(buff2, "MODE1/2048") == 0)
data->tracks[count].type = CT_ISO; data->tracks[count].type = CT_ISO;
else if (strcmp(buff2, "AUDIO")) else if (strcmp(buff2, "AUDIO") == 0)
{ {
if (data->tracks[count].fname != NULL) if (data->tracks[count].fname != NULL)
{ {
@ -132,6 +133,11 @@ cue_data *cue_parse(const char *fname)
data->tracks[count].fname); data->tracks[count].fname);
} }
} }
else
{
// propagate previous
data->tracks[count].type = data->tracks[count-1].type;
}
} }
else { else {
elprintf(EL_STATUS, "unhandled track type: \"%s\"", buff2); elprintf(EL_STATUS, "unhandled track type: \"%s\"", buff2);
@ -149,18 +155,28 @@ cue_data *cue_parse(const char *fname)
} }
// offset in file // offset in file
get_token(buff+6+ret, buff2, sizeof(buff2)); get_token(buff+6+ret, buff2, sizeof(buff2));
ret = sscanf(buff2, "%i:%i:%i", &m, &s, &f); ret = sscanf(buff2, "%d:%d:%d", &m, &s, &f);
if (ret != 3) { if (ret != 3) {
elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff); elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff);
count--; break; count--; break;
} }
data->tracks[count].sector_offset = m*60*75 + s*75 + f; data->tracks[count].sector_offset = m*60*75 + s*75 + f;
// some strange .cues may need this
if (data->tracks[count].fname != NULL && strcmp(data->tracks[count].fname, current_file) != 0)
{
free(data->tracks[count].fname);
data->tracks[count].fname = strdup(current_file);
}
if (data->tracks[count].fname == NULL && strcmp(data->tracks[1].fname, current_file) != 0)
{
data->tracks[count].fname = strdup(current_file);
}
} }
else if (BEGINS(buff, "PREGAP ")) else if (BEGINS(buff, "PREGAP "))
{ {
int m, s, f; int m, s, f;
get_token(buff+7, buff2, sizeof(buff2)); get_token(buff+7, buff2, sizeof(buff2));
ret = sscanf(buff2, "%i:%i:%i", &m, &s, &f); ret = sscanf(buff2, "%d:%d:%d", &m, &s, &f);
if (ret != 3) { if (ret != 3) {
elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff); elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff);
continue; continue;
@ -169,7 +185,7 @@ cue_data *cue_parse(const char *fname)
} }
else else
{ {
elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff); elprintf(EL_STATUS, "cue: unhandled line: \"%s\"", buff);
} }
} }
@ -187,7 +203,7 @@ cue_data *cue_parse(const char *fname)
} }
void cue_destroy(cue_data *data) void cue_destroy(cue_data_t *data)
{ {
int c; int c;
@ -200,19 +216,22 @@ void cue_destroy(cue_data *data)
} }
#if 0
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
cue_data *data = cue_parse(argv[1]); cue_data_t *data = cue_parse(argv[1]);
int c; int c;
if (data == NULL) return 1; if (data == NULL) return 1;
for (c = 1; c <= data->track_count; c++) for (c = 1; c <= data->track_count; c++)
printf("%2i: %i %9i %9i %s\n", c, data->tracks[c].type, data->tracks[c].sector_offset, printf("%2i: %i %9i %02i:%02i:%02i %9i %s\n", c, data->tracks[c].type, data->tracks[c].sector_offset,
data->tracks[c].pregap, data->tracks[c].fname); data->tracks[c].sector_offset / (75*60), data->tracks[c].sector_offset / 75 % 60,
data->tracks[c].sector_offset % 75, data->tracks[c].pregap, data->tracks[c].fname);
cue_destroy(data); cue_destroy(data);
return 0; return 0;
} }
#endif

View file

@ -20,9 +20,9 @@ typedef struct
{ {
int track_count; int track_count;
cue_track tracks[0]; cue_track tracks[0];
} cue_data; } cue_data_t;
cue_data *cue_parse(const char *fname); cue_data_t *cue_parse(const char *fname);
void cue_destroy(cue_data *data); void cue_destroy(cue_data_t *data);

View file

@ -18,6 +18,7 @@
#include <Pico/PicoInt.h> #include <Pico/PicoInt.h>
#include <Pico/Patch.h> #include <Pico/Patch.h>
#include <Pico/cd/cue.h>
#include <zlib/zlib.h> #include <zlib/zlib.h>
#if defined(__GP2X__) #if defined(__GP2X__)
@ -163,12 +164,24 @@ int emu_cdCheck(int *pregion)
{ {
unsigned char buf[32]; unsigned char buf[32];
pm_file *cd_f; pm_file *cd_f;
int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe int region = 4; // 1: Japan, 4: US, 8: Europe
char ext[5]; char ext[5], *fname = romFileName;
cue_track_type type = CT_UNKNOWN;
cue_data_t *cue_data = NULL;
get_ext(romFileName, ext); get_ext(romFileName, ext);
if (strcasecmp(ext, ".cue") == 0) {
cue_data = cue_parse(romFileName);
if (cue_data != NULL) {
fname = cue_data->tracks[1].fname;
type = cue_data->tracks[1].type;
}
}
cd_f = pm_open(fname);
if (cue_data != NULL)
cue_destroy(cue_data);
cd_f = pm_open(romFileName);
if (!cd_f) return 0; // let the upper level handle this if (!cd_f) return 0; // let the upper level handle this
if (pm_read(buf, 32, cd_f) != 32) { if (pm_read(buf, 32, cd_f) != 32) {
@ -176,18 +189,27 @@ int emu_cdCheck(int *pregion)
return 0; return 0;
} }
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) type = 1; // Sega CD (ISO) if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) {
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) type = 2; // Sega CD (BIN) if (type && type != CT_ISO)
if (type == 0) { elprintf(EL_STATUS, ".cue has wrong type: %i", type);
type = CT_ISO; // Sega CD (ISO)
}
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) {
if (type && type != CT_BIN)
elprintf(EL_STATUS, ".cue has wrong type: %i", type);
type = CT_BIN; // Sega CD (BIN)
}
if (type == CT_UNKNOWN) {
pm_close(cd_f); pm_close(cd_f);
return 0; return 0;
} }
pm_seek(cd_f, (type == 1) ? 0x100 : 0x110, SEEK_SET); pm_seek(cd_f, (type == CT_ISO) ? 0x100 : 0x110, SEEK_SET);
pm_read(id_header, sizeof(id_header), cd_f); pm_read(id_header, sizeof(id_header), cd_f);
/* it seems we have a CD image here. Try to detect region now.. */ /* it seems we have a CD image here. Try to detect region now.. */
pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET); pm_seek(cd_f, (type == CT_ISO) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);
pm_read(buf, 1, cd_f); pm_read(buf, 1, cd_f);
pm_close(cd_f); pm_close(cd_f);
@ -195,7 +217,7 @@ int emu_cdCheck(int *pregion)
if (buf[0] == 0xa1) region = 1; // JAP if (buf[0] == 0xa1) region = 1; // JAP
lprintf("detected %s Sega/Mega CD image with %s region\n", lprintf("detected %s Sega/Mega CD image with %s region\n",
type == 2 ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA"); type == CT_BIN ? "BIN" : "ISO", region != 4 ? (region == 8 ? "EU" : "JAP") : "USA");
if (pregion != NULL) *pregion = region; if (pregion != NULL) *pregion = region;

View file

@ -70,7 +70,7 @@ OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.
../../Pico/Patch.o ../../Pico/Patch.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/gfx_cd.o \ ../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/cue.o ../../Pico/cd/gfx_cd.o \
../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o ../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o
endif endif
# Pico - carthw # Pico - carthw

View file

@ -39,8 +39,10 @@ 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/Patch.o Pico/VideoPort.o Pico/Draw2.o Pico/Draw.o Pico/Patch.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/gfx_cd.o \ Pico/cd/cd_sys.o Pico/cd/cd_file.o Pico/cd/cue.o Pico/cd/gfx_cd.o \
Pico/cd/Area.o Pico/cd/Misc.o Pico/cd/pcm.o Pico/cd/buffering.o Pico/cd/Area.o Pico/cd/Misc.o Pico/cd/pcm.o Pico/cd/buffering.o
# Pico - Pico
OBJS += Pico/Pico/Pico.o Pico/Pico/Memory.o
# Pico - sound # Pico - sound
OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o
# Pico - carthw # Pico - carthw
@ -77,7 +79,7 @@ endif
endif endif
vpath %.c = ../.. vpath %.c = ../..
DIRS = platform platform/gp2x platform/common Pico Pico/cd Pico/sound Pico/carthw/svp \ DIRS = platform platform/gp2x platform/common Pico Pico/cd Pico/Pico Pico/sound Pico/carthw/svp \
zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80 zlib unzip cpu cpu/musashi cpu/fame cpu/mz80 cpu/cz80
all: mkdirs PicoDrive all: mkdirs PicoDrive

View file

@ -38,7 +38,7 @@ OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.
../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o ../../Pico/Misc_amips.o ../../Pico/Patch.o ../../Pico/Draw_amips.o ../../Pico/Memory_amips.o ../../Pico/Misc_amips.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/gfx_cd.o \ ../../Pico/cd/cd_sys.o ../../Pico/cd/cd_file.o ../../Pico/cd/cue.o ../../Pico/cd/gfx_cd.o \
../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o ../../Pico/cd/Area.o ../../Pico/cd/Misc.o ../../Pico/cd/pcm.o ../../Pico/cd/buffering.o
# Pico - carthw # Pico - carthw
OBJS += ../../Pico/carthw/carthw.o ../../Pico/carthw/svp/svp.o ../../Pico/carthw/svp/Memory.o \ OBJS += ../../Pico/carthw/carthw.o ../../Pico/carthw/svp/svp.o ../../Pico/carthw/svp/Memory.o \