mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
.cue support, Pico stubs
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@433 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
parent
b923ecbe75
commit
9037e45d9f
16 changed files with 530 additions and 161 deletions
18
Pico/Cart.c
18
Pico/Cart.c
|
@ -528,9 +528,14 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
|
|||
|
||||
// setup correct memory map for loaded ROM
|
||||
// call PicoMemReset again due to possible memmap change
|
||||
if (PicoAHW & PAHW_MCD)
|
||||
PicoMemSetupCD();
|
||||
else PicoMemSetup();
|
||||
switch (PicoAHW) {
|
||||
default:
|
||||
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();
|
||||
|
||||
PicoPower();
|
||||
|
@ -674,6 +679,13 @@ static void PicoCartDetect(void)
|
|||
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
|
||||
else if ((name_cmp("ROBOCOP 3") == 0 && Pico.romsize == 0x200000) ||
|
||||
(rom_strcmp(0x160, "FLICKY") == 0 && Pico.romsize >= 0x200000) ||
|
||||
|
|
119
Pico/Memory.c
119
Pico/Memory.c
|
@ -210,6 +210,14 @@ static u32 OtherRead16End(u32 a, int realsize)
|
|||
{
|
||||
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
|
||||
// some dumb detection is used, but that should be enough to make things work
|
||||
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)
|
||||
{
|
||||
PicoWrite8Hook(a, d>>8, realsize);
|
||||
|
@ -507,6 +514,10 @@ PICO_INTERNAL void PicoMemResetHooks(void)
|
|||
PicoWrite16Hook = OtherWrite16End;
|
||||
}
|
||||
|
||||
#ifdef EMU_M68K
|
||||
static void m68k_mem_setup(void);
|
||||
#endif
|
||||
|
||||
PICO_INTERNAL void PicoMemSetup(void)
|
||||
{
|
||||
// Setup memory callbacks:
|
||||
|
@ -530,7 +541,7 @@ PICO_INTERNAL void PicoMemSetup(void)
|
|||
// setup FAME fetchmap
|
||||
{
|
||||
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++)
|
||||
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));
|
||||
// now real ROM
|
||||
|
@ -541,15 +552,24 @@ PICO_INTERNAL void PicoMemSetup(void)
|
|||
PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));
|
||||
}
|
||||
#endif
|
||||
#ifdef EMU_M68K
|
||||
m68k_mem_setup();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* some nasty things below :( */
|
||||
#ifdef EMU_M68K
|
||||
unsigned int m68k_read_pcrelative_CD8 (unsigned int a);
|
||||
unsigned int m68k_read_pcrelative_CD16(unsigned int a);
|
||||
unsigned int m68k_read_pcrelative_CD32(unsigned int a);
|
||||
unsigned int (*pm68k_read_memory_8) (unsigned int address) = NULL;
|
||||
unsigned int (*pm68k_read_memory_16)(unsigned int address) = NULL;
|
||||
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)
|
||||
{
|
||||
a&=0xffffff;
|
||||
|
@ -557,9 +577,7 @@ static unsigned int m68k_read_8 (unsigned int a, int do_fake)
|
|||
#ifdef EMU_CORE_DEBUG
|
||||
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
|
||||
#endif
|
||||
if(PicoAHW&1) return m68k_read_pcrelative_CD8(a);
|
||||
if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram
|
||||
return 0;
|
||||
return pm68k_read_memory_pcr_8(a);
|
||||
}
|
||||
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
|
||||
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
|
||||
#endif
|
||||
if(PicoAHW&1) return m68k_read_pcrelative_CD16(a);
|
||||
if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram
|
||||
return 0;
|
||||
return pm68k_read_memory_pcr_16(a);
|
||||
}
|
||||
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
|
||||
if(do_fake&&((ppop&0x3f)==0x3a||(ppop&0x3f)==0x3b)) return lastread_d[lrp_mus++&15];
|
||||
#endif
|
||||
if(PicoAHW&1) return m68k_read_pcrelative_CD32(a);
|
||||
if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram
|
||||
return 0;
|
||||
return pm68k_read_memory_pcr_32(a);
|
||||
}
|
||||
|
||||
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_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
|
||||
// ROM only
|
||||
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_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; }
|
||||
#else
|
||||
unsigned char PicoReadCD8w (unsigned int a);
|
||||
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);
|
||||
|
||||
#else // if !EMU_CORE_DEBUG
|
||||
|
||||
/* it appears that Musashi doesn't always mask the unused bits */
|
||||
unsigned int m68k_read_memory_8(unsigned int address)
|
||||
{
|
||||
unsigned int d = (PicoAHW&1) ? PicoReadCD8w(address) : PicoRead8(address);
|
||||
return d&0xff;
|
||||
}
|
||||
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 m68k_read_memory_32(unsigned int address) { return pm68k_read_memory_32(address); }
|
||||
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);
|
||||
return d&0xffff;
|
||||
pm68k_read_memory_8 = PicoRead8;
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ int PicoOpt = 0;
|
|||
int PicoSkipFrame = 0; // skip rendering frame?
|
||||
int emustatus = 0; // rapid_ym2612, multi_ym_updates
|
||||
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 PicoAutoRgnOrder = 0;
|
||||
int z80startCycle, z80stopCycle; // in 68k cycles
|
||||
|
|
179
Pico/Pico/Memory.c
Normal file
179
Pico/Pico/Memory.c
Normal 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
10
Pico/Pico/Pico.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "../PicoInt.h"
|
||||
|
||||
PICO_INTERNAL int PicoInitPico(void)
|
||||
{
|
||||
elprintf(EL_STATUS, "Pico detected");
|
||||
PicoAHW = PAHW_PICO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -215,6 +215,7 @@ extern struct DrZ80 drZ80;
|
|||
#define PAHW_MCD (1<<0)
|
||||
#define PAHW_32X (1<<1)
|
||||
#define PAHW_SVP (1<<2)
|
||||
#define PAHW_PICO (1<<3)
|
||||
extern int PicoAHW;
|
||||
|
||||
// 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 PicoMemResetCDdecode(int r3);
|
||||
|
||||
// Pico/Memory.c
|
||||
PICO_INTERNAL void PicoMemSetupPico(void);
|
||||
|
||||
// Pico.c
|
||||
extern struct Pico Pico;
|
||||
extern struct PicoSRAM SRam;
|
||||
|
@ -436,6 +440,9 @@ PICO_INTERNAL void PicoPowerMCD(void);
|
|||
PICO_INTERNAL int PicoResetMCD(void);
|
||||
PICO_INTERNAL int PicoFrameMCD(void);
|
||||
|
||||
// Pico/Pico.c
|
||||
PICO_INTERNAL int PicoInitPico(void);
|
||||
|
||||
// Sek.c
|
||||
PICO_INTERNAL int SekInit(void);
|
||||
PICO_INTERNAL int SekReset(void);
|
||||
|
|
|
@ -114,7 +114,7 @@ PICO_INTERNAL int SekInit()
|
|||
m68k_init();
|
||||
m68k_set_int_ack_callback(SekIntAckM68K);
|
||||
m68k_set_tas_instr_callback(SekTasCallback);
|
||||
m68k_pulse_reset(); // Init cpu emulator
|
||||
//m68k_pulse_reset();
|
||||
m68k_set_context(oldcontext);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1636,6 +1636,10 @@ void PicoMemResetCD(int r3)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef EMU_M68K
|
||||
static void m68k_mem_setup_cd(void);
|
||||
#endif
|
||||
|
||||
PICO_INTERNAL void PicoMemSetupCD(void)
|
||||
{
|
||||
// additional handlers for common code
|
||||
|
@ -1702,6 +1706,9 @@ PICO_INTERNAL void PicoMemSetupCD(void)
|
|||
// PicoMemResetCD() will setup word ram for both
|
||||
}
|
||||
#endif
|
||||
#ifdef EMU_M68K
|
||||
m68k_mem_setup_cd();
|
||||
#endif
|
||||
|
||||
// m68k_poll_addr = m68k_poll_cnt = 0;
|
||||
s68k_poll_adclk = s68k_poll_cnt = 0;
|
||||
|
@ -1709,27 +1716,27 @@ PICO_INTERNAL void PicoMemSetupCD(void)
|
|||
|
||||
|
||||
#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);
|
||||
}
|
||||
unsigned short PicoReadCD16w(unsigned int a) {
|
||||
static unsigned int PicoReadCD16w(unsigned int 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
if(m68ki_cpu_p == &PicoCpuMS68k) {
|
||||
|
@ -1756,7 +1763,7 @@ unsigned int m68k_read_pcrelative_CD8 (unsigned int a)
|
|||
}
|
||||
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;
|
||||
if(m68ki_cpu_p == &PicoCpuMS68k) {
|
||||
|
@ -1783,7 +1790,7 @@ unsigned int m68k_read_pcrelative_CD16(unsigned int a)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
unsigned int m68k_read_pcrelative_CD32(unsigned int a)
|
||||
static unsigned int m68k_read_pcrelative_CD32(unsigned int a)
|
||||
{
|
||||
u16 *pm;
|
||||
a&=0xffffff;
|
||||
|
@ -1813,5 +1820,28 @@ unsigned int m68k_read_pcrelative_CD32(unsigned int a)
|
|||
}
|
||||
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
|
||||
|
||||
|
|
|
@ -9,15 +9,61 @@
|
|||
|
||||
#include "../PicoInt.h"
|
||||
#include "cd_file.h"
|
||||
#include "cue.h"
|
||||
|
||||
//#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;
|
||||
char tmp_name[1024], tmp_ext[10];
|
||||
cue_data_t *cue_data = NULL;
|
||||
pm_file *pmf;
|
||||
static char *exts[] = {
|
||||
"%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();
|
||||
|
||||
/* 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].F = pmf = pm_open(iso_name);
|
||||
Tracks[0].F = pmf = pm_open(cd_img_name);
|
||||
if (Tracks[0].F == NULL)
|
||||
{
|
||||
Tracks[0].ftype = 0;
|
||||
Tracks[0].Length = 0;
|
||||
if (cue_data != NULL)
|
||||
cue_destroy(cue_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (Tracks[0].ftype == TYPE_ISO)
|
||||
Tracks[0].Length = pmf->size >>= 11; // size in sectors
|
||||
else Tracks[0].Length = pmf->size /= 2352;
|
||||
cd_img_sectors = pmf->size >>= 11; // size in sectors
|
||||
else cd_img_sectors = pmf->size /= 2352;
|
||||
Tracks[0].Offset = 0;
|
||||
|
||||
Tracks[0].MSF.M = 0; // minutes
|
||||
Tracks[0].MSF.S = 2; // seconds
|
||||
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))
|
||||
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++)
|
||||
{
|
||||
int ext_len;
|
||||
FILE *tmp_file;
|
||||
sprintf(tmp_ext, exts[j], i);
|
||||
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;
|
||||
strcat(tmp_name, tmp_ext);
|
||||
|
||||
tmp_file = fopen(tmp_name, "rb");
|
||||
if (!tmp_file && i > 1 && iso_name_len > ext_len) {
|
||||
index = num_track - 1;
|
||||
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;
|
||||
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);
|
||||
|
||||
// MP3 File
|
||||
Tracks[index].ftype = TYPE_MP3;
|
||||
fs *= 75;
|
||||
fs /= Tracks[index].KBtps * 1000;
|
||||
Tracks[index].Length = fs;
|
||||
Cur_LBA += Tracks[index].Length;
|
||||
|
||||
cdprintf("Track %i: %s - %02d:%02d:%02d len=%i AUDIO", index, tmp_name, Tracks[index].MSF.M,
|
||||
Tracks[index].MSF.S, Tracks[index].MSF.F, fs);
|
||||
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, tmp_name);
|
||||
|
||||
num_track++;
|
||||
missed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret != 0) missed++;
|
||||
}
|
||||
|
||||
finish:
|
||||
Pico_mcd->TOC.Last_Track = num_track - 1;
|
||||
|
||||
index = num_track - 1;
|
||||
|
||||
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);
|
||||
|
||||
if (PicoCDLoadProgressCB != NULL) PicoCDLoadProgressCB(100);
|
||||
|
@ -153,11 +224,14 @@ PICO_INTERNAL void Unload_ISO(void)
|
|||
for(i = 1; i < 100; i++)
|
||||
{
|
||||
if (Pico_mcd->TOC.Tracks[i].F != NULL)
|
||||
#if !DONT_OPEN_MANY_FILES
|
||||
fclose(Pico_mcd->TOC.Tracks[i].F);
|
||||
#else
|
||||
{
|
||||
#if DONT_OPEN_MANY_FILES
|
||||
if (Pico_mcd->TOC.Tracks[i].type == TYPE_MP3)
|
||||
free(Pico_mcd->TOC.Tracks[i].F);
|
||||
else
|
||||
#endif
|
||||
fclose(Pico_mcd->TOC.Tracks[i].F);
|
||||
}
|
||||
}
|
||||
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);
|
||||
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("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);
|
||||
|
@ -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 + 4) & 0x3FFF],
|
||||
Pico_mcd->cdc.Buffer[(Pico_mcd->cdc.PT.N + 5) & 0x3FFF]);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct
|
|||
char ftype; // TYPE_ISO, TYPE_BIN, TYPE_MP3
|
||||
void *F;
|
||||
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 pad;
|
||||
} _scd_track;
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include <string.h>
|
||||
#include "cue.h"
|
||||
|
||||
//#include "../PicoInt.h"
|
||||
#define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
|
||||
#include "../PicoInt.h"
|
||||
// #define elprintf(w,f,...) printf(f "\n",##__VA_ARGS__);
|
||||
|
||||
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] = 0;
|
||||
|
||||
if (*p != sep)
|
||||
if (sep == '\"' && *p != sep)
|
||||
elprintf(EL_STATUS, "cue: bad token: \"%s\"", buff);
|
||||
|
||||
return d + skip;
|
||||
|
@ -51,19 +51,19 @@ static int get_token(const char *buff, char *dest, int len)
|
|||
static char *get_ext(char *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)
|
||||
|
||||
/* 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];
|
||||
FILE *f, *tmpf;
|
||||
int ret, count = 0, count_alloc = 2;
|
||||
cue_data *data;
|
||||
cue_data_t *data;
|
||||
void *tmp;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
|
@ -92,6 +92,7 @@ cue_data *cue_parse(const char *fname)
|
|||
count_alloc *= 2;
|
||||
tmp = realloc(data, sizeof(*data) + count_alloc * sizeof(cue_track));
|
||||
if (tmp == NULL) { count--; break; }
|
||||
data = tmp;
|
||||
}
|
||||
memset(&data->tracks[count], 0, sizeof(data->tracks[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));
|
||||
// check type
|
||||
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;
|
||||
else if (strcmp(buff2, "MODE1/2048"))
|
||||
else if (strcmp(buff2, "MODE1/2048") == 0)
|
||||
data->tracks[count].type = CT_ISO;
|
||||
else if (strcmp(buff2, "AUDIO"))
|
||||
else if (strcmp(buff2, "AUDIO") == 0)
|
||||
{
|
||||
if (data->tracks[count].fname != NULL)
|
||||
{
|
||||
|
@ -132,6 +133,11 @@ cue_data *cue_parse(const char *fname)
|
|||
data->tracks[count].fname);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// propagate previous
|
||||
data->tracks[count].type = data->tracks[count-1].type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
elprintf(EL_STATUS, "unhandled track type: \"%s\"", buff2);
|
||||
|
@ -149,18 +155,28 @@ cue_data *cue_parse(const char *fname)
|
|||
}
|
||||
// offset in file
|
||||
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) {
|
||||
elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff);
|
||||
count--; break;
|
||||
}
|
||||
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 "))
|
||||
{
|
||||
int m, s, f;
|
||||
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) {
|
||||
elprintf(EL_STATUS, "cue: failed to parse: \"%s\"", buff);
|
||||
continue;
|
||||
|
@ -169,7 +185,7 @@ cue_data *cue_parse(const char *fname)
|
|||
}
|
||||
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;
|
||||
|
||||
|
@ -200,19 +216,22 @@ void cue_destroy(cue_data *data)
|
|||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
cue_data *data = cue_parse(argv[1]);
|
||||
cue_data_t *data = cue_parse(argv[1]);
|
||||
int c;
|
||||
|
||||
if (data == NULL) return 1;
|
||||
|
||||
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,
|
||||
data->tracks[c].pregap, data->tracks[c].fname);
|
||||
printf("%2i: %i %9i %02i:%02i:%02i %9i %s\n", c, data->tracks[c].type, data->tracks[c].sector_offset,
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ typedef struct
|
|||
{
|
||||
int track_count;
|
||||
cue_track tracks[0];
|
||||
} cue_data;
|
||||
} cue_data_t;
|
||||
|
||||
|
||||
cue_data *cue_parse(const char *fname);
|
||||
void cue_destroy(cue_data *data);
|
||||
cue_data_t *cue_parse(const char *fname);
|
||||
void cue_destroy(cue_data_t *data);
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <Pico/PicoInt.h>
|
||||
#include <Pico/Patch.h>
|
||||
#include <Pico/cd/cue.h>
|
||||
#include <zlib/zlib.h>
|
||||
|
||||
#if defined(__GP2X__)
|
||||
|
@ -163,12 +164,24 @@ int emu_cdCheck(int *pregion)
|
|||
{
|
||||
unsigned char buf[32];
|
||||
pm_file *cd_f;
|
||||
int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe
|
||||
char ext[5];
|
||||
int region = 4; // 1: Japan, 4: US, 8: Europe
|
||||
char ext[5], *fname = romFileName;
|
||||
cue_track_type type = CT_UNKNOWN;
|
||||
cue_data_t *cue_data = NULL;
|
||||
|
||||
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 (pm_read(buf, 32, cd_f) != 32) {
|
||||
|
@ -176,18 +189,27 @@ int emu_cdCheck(int *pregion)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) type = 1; // Sega CD (ISO)
|
||||
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) type = 2; // Sega CD (BIN)
|
||||
if (type == 0) {
|
||||
if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) {
|
||||
if (type && type != CT_ISO)
|
||||
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);
|
||||
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);
|
||||
|
||||
/* 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_close(cd_f);
|
||||
|
||||
|
@ -195,7 +217,7 @@ int emu_cdCheck(int *pregion)
|
|||
if (buf[0] == 0xa1) region = 1; // JAP
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ OBJS += ../../Pico/Area.o ../../Pico/Cart.o ../../Pico/Memory.o ../../Pico/Misc.
|
|||
../../Pico/Patch.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/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
|
||||
endif
|
||||
# Pico - carthw
|
||||
|
|
|
@ -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 - 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/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 - Pico
|
||||
OBJS += Pico/Pico/Pico.o Pico/Pico/Memory.o
|
||||
# Pico - sound
|
||||
OBJS += Pico/sound/sound.o Pico/sound/sn76496.o Pico/sound/ym2612.o Pico/sound/mix.o
|
||||
# Pico - carthw
|
||||
|
@ -77,7 +79,7 @@ endif
|
|||
endif
|
||||
|
||||
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
|
||||
|
||||
all: mkdirs PicoDrive
|
||||
|
|
|
@ -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 - 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/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 - carthw
|
||||
OBJS += ../../Pico/carthw/carthw.o ../../Pico/carthw/svp/svp.o ../../Pico/carthw/svp/Memory.o \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue