updated EEPROM code, gmv fixed

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@249 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-09-16 15:44:18 +00:00
parent 32826a1a22
commit 1dceadaee4
14 changed files with 306 additions and 170 deletions

View file

@ -310,10 +310,18 @@ int PicoCartInsert(unsigned char *rom,unsigned int romsize)
if(rom != NULL) if(rom != NULL)
*(unsigned long *)(rom+romsize) = 0xFFFE4EFA; // 4EFA FFFE byteswapped *(unsigned long *)(rom+romsize) = 0xFFFE4EFA; // 4EFA FFFE byteswapped
SRam.resize=1;
Pico.rom=rom; Pico.rom=rom;
Pico.romsize=romsize; Pico.romsize=romsize;
// setup correct memory map for loaded ROM
if (PicoMCD & 1)
PicoMemSetupCD();
else PicoMemSetup();
PicoMemReset();
if (!(PicoMCD & 1))
PicoCartDetect();
return PicoReset(1); return PicoReset(1);
} }
@ -323,3 +331,115 @@ int PicoUnloadCart(unsigned char* romdata)
return 0; return 0;
} }
static int name_cmp(const char *name)
{
int i, len = strlen(name);
const char *name_rom = (const char *)Pico.rom+0x150;
for (i = 0; i < len; i++)
if (name[i] != name_rom[i^1])
return 1;
return 0;
}
/* various cart-specific things, which can't be handled by generic code */
void PicoCartDetect(void)
{
int sram_size = 0, csum;
if(SRam.data) free(SRam.data); SRam.data=0;
Pico.m.sram_reg = 0;
csum = PicoRead32(0x18c) & 0xffff;
if (Pico.rom[0x1B1] == 'R' && Pico.rom[0x1B0] == 'A')
{
if (Pico.rom[0x1B2] & 0x40)
{
// EEPROM
SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games
SRam.end = PicoRead32(0x1B8);
sram_size = 0x2000;
Pico.m.sram_reg |= 4;
} else {
// normal SRAM
SRam.start = PicoRead32(0x1B4) & 0xFFFF00;
SRam.end = PicoRead32(0x1B8) | 1;
sram_size = SRam.end - SRam.start + 1;
}
Pico.m.sram_reg |= 0x10; // SRAM was detected
}
if (sram_size <= 0)
{
// some games may have bad headers, like S&K and Sonic3
// note: majority games use 0x200000 as starting address, but there are some which
// use something else (0x300000 by HardBall '95). Luckily they have good headers.
SRam.start = 0x200000;
SRam.end = 0x203FFF;
sram_size = 0x004000;
}
if (sram_size)
{
SRam.data = (unsigned char *) calloc(sram_size, 1);
if(!SRam.data) return;
}
SRam.changed = 0;
// set EEPROM defaults, in case it gets detected
SRam.eeprom_type = 0; // 7bit (24C01)
SRam.eeprom_abits = 3; // eeprom access must be odd addr for: bit0 ~ cl, bit1 ~ in
SRam.eeprom_bit_cl = 1;
SRam.eeprom_bit_in = 0;
SRam.eeprom_bit_out= 0;
// some known EEPROM data (thanks to EkeEke)
if (name_cmp("COLLEGE SLAM") == 0 ||
name_cmp("FRANK THOMAS BIGHURT BASEBAL") == 0)
{
SRam.eeprom_type = 3;
SRam.eeprom_abits = 2;
SRam.eeprom_bit_cl = 0;
}
else if (name_cmp("NBA JAM TOURNAMENT EDITION") == 0 ||
name_cmp("NFL QUARTERBACK CLUB") == 0)
{
SRam.eeprom_type = 2;
SRam.eeprom_abits = 2;
SRam.eeprom_bit_cl = 0;
}
else if (name_cmp("NBA JAM") == 0)
{
SRam.eeprom_type = 2;
SRam.eeprom_bit_out = 1;
SRam.eeprom_abits = 0;
}
else if (name_cmp("NHLPA HOCKEY '93") == 0 ||
name_cmp("NHLPA Hockey '93") == 0 ||
name_cmp("RINGS OF POWER") == 0)
{
SRam.start = SRam.end = 0x200000;
Pico.m.sram_reg = 0x14;
SRam.eeprom_abits = 0;
SRam.eeprom_bit_cl = 6;
SRam.eeprom_bit_in = 7;
SRam.eeprom_bit_out= 7;
}
else if ( name_cmp("MICRO MACHINES II") == 0 ||
(name_cmp(" ") == 0 && // Micro Machines {Turbo Tournament '96, Military - It's a Blast!}
(csum == 0x165e || csum == 0x168b || csum == 0xCEE0 || csum == 0x2C41)))
{
SRam.start = 0x300000;
SRam.end = 0x380001;
Pico.m.sram_reg = 0x14;
SRam.eeprom_type = 2;
SRam.eeprom_abits = 0;
SRam.eeprom_bit_cl = 1;
SRam.eeprom_bit_in = 0;
SRam.eeprom_bit_out= 7;
}
// Some games malfunction if SRAM is not filled with 0xff
if (name_cmp("DINO DINI'S SOCCER") == 0 ||
name_cmp("MICRO MACHINES II") == 0)
memset(SRam.data, 0xff, sram_size);
}

View file

@ -153,6 +153,7 @@ u32 SRAMRead(u32 a)
{ {
unsigned int sreg = Pico.m.sram_reg; unsigned int sreg = Pico.m.sram_reg;
if(!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM if(!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM
elprintf(EL_SRAMIO, "normal sram detected.");
Pico.m.sram_reg|=0x10; // should be normal SRAM Pico.m.sram_reg|=0x10; // should be normal SRAM
} }
if(sreg & 4) // EEPROM read if(sreg & 4) // EEPROM read
@ -163,23 +164,29 @@ u32 SRAMRead(u32 a)
static void SRAMWrite(u32 a, u32 d) static void SRAMWrite(u32 a, u32 d)
{ {
dprintf("sram_w: %06x, %08x @%06x", a&0xffffff, d, SekPc);
unsigned int sreg = Pico.m.sram_reg; unsigned int sreg = Pico.m.sram_reg;
if(!(sreg & 0x10)) { if(!(sreg & 0x10)) {
// not detected SRAM // not detected SRAM
if((a&~1)==0x200000) { if((a&~1)==0x200000) {
Pico.m.sram_reg|=4; // this should be a game with EEPROM (like NBA Jam) elprintf(EL_SRAMIO, "eeprom detected.");
sreg|=4; // this should be a game with EEPROM (like NBA Jam)
SRam.start=0x200000; SRam.end=SRam.start+1; SRam.start=0x200000; SRam.end=SRam.start+1;
} } else
Pico.m.sram_reg|=0x10; elprintf(EL_SRAMIO, "normal sram detected.");
sreg|=0x10;
Pico.m.sram_reg=sreg;
} }
if(sreg & 4) { // EEPROM write if(sreg & 4) { // EEPROM write
if(SekCyclesDoneT()-lastSSRamWrite < 46) { // this diff must be at most 16 for NBA Jam to work
if(SekCyclesDoneT()-lastSSRamWrite < 16) {
// just update pending state // just update pending state
elprintf(EL_EEPROM, "eeprom: skip because cycles=%i", SekCyclesDoneT()-lastSSRamWrite);
SRAMUpdPending(a, d); SRAMUpdPending(a, d);
} else { } else {
int old=sreg;
SRAMWriteEEPROM(sreg>>6); // execute pending SRAMWriteEEPROM(sreg>>6); // execute pending
SRAMUpdPending(a, d); SRAMUpdPending(a, d);
if ((old^Pico.m.sram_reg)&0xc0) // update time only if SDA/SCL changed
lastSSRamWrite = SekCyclesDoneT(); lastSSRamWrite = SekCyclesDoneT();
} }
} else if(!(sreg & 2)) { } else if(!(sreg & 2)) {
@ -199,8 +206,6 @@ u32 OtherRead16End(u32 a, int realsize)
{ {
u32 d=0; u32 d=0;
dprintf("strange r%i: %06x @%06x", realsize, a&0xffffff, SekPc);
// 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) {
@ -262,7 +267,7 @@ u32 OtherRead16End(u32 a, int realsize)
} }
end: end:
dprintf("ret = %04x", d); elprintf(EL_UIO, "strange r%i: [%06x] %04x @%06x", realsize, a&0xffffff, d, SekPc);
return d; return d;
} }
@ -272,9 +277,8 @@ end:
static void OtherWrite8End(u32 a,u32 d,int realsize) static void OtherWrite8End(u32 a,u32 d,int realsize)
{ {
// sram // sram
//if(a==0x200000) dprintf("cc : %02x @ %06x [%i|%i]", d, SekPc, SekCyclesDoneT(), SekCyclesDone());
//if(a==0x200001) dprintf("w8 : %02x @ %06x [%i]", d, SekPc, SekCyclesDoneT());
if(a >= SRam.start && a <= SRam.end) { if(a >= SRam.start && a <= SRam.end) {
elprintf(EL_SRAMIO, "sram w8 [%06x] %02x @ %06x", a, d, SekPc);
SRAMWrite(a, d); SRAMWrite(a, d);
return; return;
} }
@ -288,13 +292,13 @@ static void OtherWrite8End(u32 a,u32 d,int realsize)
#else #else
// sram access register // sram access register
if(a == 0xA130F1) { if(a == 0xA130F1) {
dprintf("sram reg=%02x", d); elprintf(EL_SRAMIO, "sram reg=%02x", d);
Pico.m.sram_reg &= ~3; Pico.m.sram_reg &= ~3;
Pico.m.sram_reg |= (u8)(d&3); Pico.m.sram_reg |= (u8)(d&3);
return; return;
} }
#endif #endif
dprintf("strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc); elprintf(EL_UIO, "strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);
if(a >= 0xA13004 && a < 0xA13040) { if(a >= 0xA13004 && a < 0xA13040) {
// dumb 12-in-1 or 4-in-1 banking support // dumb 12-in-1 or 4-in-1 banking support
@ -332,6 +336,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a)
// sram // sram
if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
d = SRAMRead(a); d = SRAMRead(a);
elprintf(EL_SRAMIO, "sram r8 [%06x] %02x @ %06x", a, d, SekPc);
goto end; goto end;
} }
#endif #endif
@ -343,14 +348,6 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a)
d=OtherRead16(a&~1, 8); if ((a&1)==0) d>>=8; d=OtherRead16(a&~1, 8); if ((a&1)==0) d>>=8;
end: end:
//if ((a&0xe0ffff)==0xe0AE57+0x69c)
// dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
//if ((a&0xe0ffff)==0xe0a9ba+0x69c)
// dprintf("r8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);
//if(a==0x200001||a==0x200000) printf("r8 : %02x [%06x] @ %06x [%i]\n", d, a, SekPc, SekCyclesDoneT());
//dprintf("r8 : %06x, %02x @%06x [%03i]", a&0xffffff, (u8)d, SekPc, Pico.m.scanline);
#ifdef __debug_io #ifdef __debug_io
dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);
#endif #endif
@ -376,6 +373,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a)
if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
d = SRAMRead(a); d = SRAMRead(a);
d |= d<<8; d |= d<<8;
elprintf(EL_SRAMIO, "sram r16 [%06x] %04x @ %06x", a, d, SekPc);
goto end; goto end;
} }
#endif #endif
@ -386,10 +384,6 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a)
d = OtherRead16(a, 16); d = OtherRead16(a, 16);
end: end:
//if ((a&0xe0ffff)==0xe0AF0E+0x69c||(a&0xe0ffff)==0xe0A9A8+0x69c||(a&0xe0ffff)==0xe0A9AA+0x69c||(a&0xe0ffff)==0xe0A9AC+0x69c)
// dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
//if(a==0x200000) printf("r16: %04x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT());
#ifdef __debug_io #ifdef __debug_io
dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
#endif #endif
@ -414,6 +408,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a)
if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) {
d = (SRAMRead(a)<<16)|SRAMRead(a+2); d = (SRAMRead(a)<<16)|SRAMRead(a+2);
d |= d<<8; d |= d<<8;
elprintf(EL_SRAMIO, "sram r32 [%06x] %08x @ %06x", a, d, SekPc);
goto end; goto end;
} }
@ -423,7 +418,6 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a)
d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32); d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);
end: end:
//if(a==0x200000) printf("r32: %08x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT());
#ifdef __debug_io #ifdef __debug_io
dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc); dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);
#endif #endif
@ -469,9 +463,6 @@ void CPU_CALL PicoWrite16(u32 a,u16 d)
#if defined(EMU_C68K) && defined(EMU_M68K) #if defined(EMU_C68K) && defined(EMU_M68K)
lastwrite_cyc_d[lwp_cyc++&15] = d; lastwrite_cyc_d[lwp_cyc++&15] = d;
#endif #endif
//if ((a&0xe0ffff)==0xe0AF0E+0x69c||(a&0xe0ffff)==0xe0A9A8+0x69c||(a&0xe0ffff)==0xe0A9AA+0x69c||(a&0xe0ffff)==0xe0A9AC+0x69c)
// dprintf("w16: %06x, %04x @%06x", a&0xffffff, d, SekPc);
//if(a==0x200000) printf("w16: %04x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT());
if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram
log_io(a, 16, 1); log_io(a, 16, 1);
@ -488,7 +479,6 @@ static void CPU_CALL PicoWrite32(u32 a,u32 d)
#if defined(EMU_C68K) && defined(EMU_M68K) #if defined(EMU_C68K) && defined(EMU_M68K)
lastwrite_cyc_d[lwp_cyc++&15] = d; lastwrite_cyc_d[lwp_cyc++&15] = d;
#endif #endif
//if(a==0x200000) printf("w32: %08x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT());
if ((a&0xe00000)==0xe00000) if ((a&0xe00000)==0xe00000)
{ {
@ -647,14 +637,17 @@ void PicoWriteCD8w (unsigned int a, unsigned char d);
void PicoWriteCD16w(unsigned int a, unsigned short d); void PicoWriteCD16w(unsigned int a, unsigned short d);
void PicoWriteCD32w(unsigned int a, unsigned int d); void PicoWriteCD32w(unsigned int a, unsigned int d);
/* 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 (PicoMCD&1) ? PicoReadCD8w(address) : PicoRead8(address); unsigned int d = (PicoMCD&1) ? PicoReadCD8w(address) : PicoRead8(address);
return d&0xff;
} }
unsigned int m68k_read_memory_16(unsigned int address) unsigned int m68k_read_memory_16(unsigned int address)
{ {
return (PicoMCD&1) ? PicoReadCD16w(address) : PicoRead16(address); unsigned int d = (PicoMCD&1) ? PicoReadCD16w(address) : PicoRead16(address);
return d&0xffff;
} }
unsigned int m68k_read_memory_32(unsigned int address) unsigned int m68k_read_memory_32(unsigned int address)

View file

@ -435,6 +435,19 @@ m_read8_ram:
bx lr bx lr
m_read8_above_rom: m_read8_above_rom:
@ might still be SRam (Micro Machines, HardBall '95)
ldr r2, =(SRam)
ldr r3, =(Pico+0x22200)
ldr r1, [r2, #8] @ SRam.end
cmp r0, r1
bgt m_read8_ar_nosram
ldr r1, [r2, #4] @ SRam.start
cmp r0, r1
blt m_read8_ar_nosram
ldrb r1, [r3, #0x11] @ Pico.m.sram_reg
tst r1, #5
bne SRAMRead
m_read8_ar_nosram:
stmfd sp!,{r0,lr} stmfd sp!,{r0,lr}
bic r0, r0, #1 bic r0, r0, #1
mov r1, #8 mov r1, #8
@ -566,7 +579,24 @@ m_read16_ram:
bx lr bx lr
m_read16_above_rom: m_read16_above_rom:
@ might still be SRam
ldr r2, =(SRam)
ldr r3, =(Pico+0x22200)
ldr r1, [r2, #8] @ SRam.end
bic r0, r0, #1 bic r0, r0, #1
cmp r0, r1
bgt m_read16_ar_nosram
ldr r1, [r2, #4] @ SRam.start
cmp r0, r1
blt m_read16_ar_nosram
ldrb r1, [r3, #0x11] @ Pico.m.sram_reg
tst r1, #5
beq m_read16_ar_nosram
stmfd sp!,{lr}
bl SRAMRead
orr r0, r0, r0, lsl #8
ldmfd sp!,{pc}
m_read16_ar_nosram:
mov r1, #16 mov r1, #16
b OtherRead16End b OtherRead16End

View file

@ -221,6 +221,7 @@ void OtherWrite16(u32 a,u32 d)
#ifndef _CD_MEMORY_C #ifndef _CD_MEMORY_C
if (a >= SRam.start && a <= SRam.end) { if (a >= SRam.start && a <= SRam.end) {
elprintf(EL_SRAMIO, "sram w16 [%06x] %04x @ %06x", a, d, SekPc);
if ((a&0x16)==0x10) { // detected, not EEPROM, write not disabled if ((a&0x16)==0x10) { // detected, not EEPROM, write not disabled
u8 *pm=(u8 *)(SRam.data-SRam.start+a); u8 *pm=(u8 *)(SRam.data-SRam.start+a);
*pm++=d>>8; *pm++=d>>8;
@ -228,7 +229,7 @@ void OtherWrite16(u32 a,u32 d)
SRam.changed = 1; SRam.changed = 1;
} }
else else
SRAMWrite(a, d); // ?? SRAMWrite(a, d);
return; return;
} }
#else #else

View file

@ -131,54 +131,48 @@ const unsigned short vcounts[] = {
// rarely used EEPROM SRAM code // rarely used EEPROM SRAM code
// known games which use this: // known games which use this:
// Wonder Boy in Monster World, Megaman - The Wily Wars (X24C01, 128 bytes) // Wonder Boy in Monster World, Megaman - The Wily Wars (X24C01, 128 bytes)
// NFL Quarterback Club*, Frank Thomas Big Hurt Baseball (X24C04?)
// College Slam, Blockbuster World Video Game Championship II, NBA Jam (X24C04?)
// HardBall '95
// the above sports games use addr 0x200000 for SCL line (handled in Memory.c) // (see Genesis Plus for Wii/GC code and docs for info,
// full game list and better code).
unsigned int lastSSRamWrite = 0xffff0000; unsigned int lastSSRamWrite = 0xffff0000;
// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=type(1==uses 0x200000 for SCL and 2K bytes), // sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),
// d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA) // d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)
PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
{ {
unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.sram_addr, scyc = Pico.m.sram_cycle, ssa = Pico.m.sram_slave; unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;
//printf("EEPROM write %i\n", d&3); elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1,
sreg |= saddr&0xc000; // we store word count in add reg: dw?a aaaa ... (d=word count detected, w=words(0==use 2 words, else 1)) (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite);
saddr&=0x1fff; saddr&=0x1fff;
if(sreg & d & 2) { if(sreg & d & 2) {
// SCL was and is still high.. // SCL was and is still high..
if((sreg & 1) && !(d&1)) { if((sreg & 1) && !(d&1)) {
// ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter
//dprintf("-start-"); elprintf(EL_EEPROM, "eeprom: -start-");
if(!(sreg&0x8000) && scyc >= 9) {
if(scyc != 28) sreg |= 0x4000; // 1 word
//dprintf("detected word count: %i", scyc==28 ? 2 : 1);
sreg |= 0x8000;
}
//saddr = 0; //saddr = 0;
scyc = 0; scyc = 0;
sreg |= 8; sreg |= 8;
} else if(!(sreg & 1) && (d&1)) { } else if(!(sreg & 1) && (d&1)) {
// SDA went high == stop command // SDA went high == stop command
//dprintf("-stop-"); elprintf(EL_EEPROM, "eeprom: -stop-");
sreg &= ~8; sreg &= ~8;
} }
} }
else if((sreg & 8) && !(sreg & 2) && (d&2)) { else if((sreg & 8) && !(sreg & 2) && (d&2))
{
// we are started and SCL went high - next cycle // we are started and SCL went high - next cycle
scyc++; // pre-increment scyc++; // pre-increment
if(sreg & 0x20) { if(SRam.eeprom_type) {
// X24C02+ // X24C02+
if((ssa&1) && scyc == 18) { if((ssa&1) && scyc == 18) {
scyc = 9; scyc = 9;
saddr++; // next address in read mode saddr++; // next address in read mode
if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask
} }
else if((sreg&0x4000) && scyc == 27) scyc = 18; else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18;
else if(scyc == 36) scyc = 27; else if(scyc == 36) scyc = 27;
} else { } else {
// X24C01 // X24C01
@ -187,21 +181,22 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode
} }
} }
//dprintf("scyc: %i", scyc); elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc);
} }
else if((sreg & 8) && (sreg & 2) && !(d&2)) { else if((sreg & 8) && (sreg & 2) && !(d&2))
{
// we are started and SCL went low (falling edge) // we are started and SCL went low (falling edge)
if(sreg & 0x20) { if(SRam.eeprom_type) {
// X24C02+ // X24C02+
if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles
else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) { else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) {
if(!(ssa&1)) { if(!(ssa&1)) {
// data write // data write
unsigned char *pm=SRam.data+saddr; unsigned char *pm=SRam.data+saddr;
*pm <<= 1; *pm |= d&1; *pm <<= 1; *pm |= d&1;
if(scyc == 26 || scyc == 35) { if(scyc == 26 || scyc == 35) {
saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented
//dprintf("w done: %02x; addr inc: %x", *pm, saddr); elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm);
} }
SRam.changed = 1; SRam.changed = 1;
} }
@ -209,14 +204,17 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
if(!(ssa&1)) { if(!(ssa&1)) {
// we latch another addr bit // we latch another addr bit
saddr<<=1; saddr<<=1;
if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask
saddr|=d&1; saddr|=d&1;
//if(scyc==17||scyc==26) dprintf("addr reg done: %x", saddr); if(scyc==17||scyc==26) {
elprintf(EL_EEPROM, "eeprom: addr reg done: %x", saddr);
if(scyc==17&&SRam.eeprom_type==2) { saddr&=0xff; saddr|=(ssa<<7)&0x700; } // add device bits too
}
} }
} else { } else {
// slave address // slave address
ssa<<=1; ssa|=d&1; ssa<<=1; ssa|=d&1;
//if(scyc==8) dprintf("slave done: %x", ssa); if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa);
} }
} else { } else {
// X24C01 // X24C01
@ -228,77 +226,89 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
*pm <<= 1; *pm |= d&1; *pm <<= 1; *pm |= d&1;
if(scyc == 17) { if(scyc == 17) {
saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented
//dprintf("addr inc: %x", saddr>>1); elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm);
} }
SRam.changed = 1; SRam.changed = 1;
} }
} else { } else {
// we latch another addr bit // we latch another addr bit
saddr<<=1; saddr|=d&1; saddr&=0xff; saddr<<=1; saddr|=d&1; saddr&=0xff;
//if(scyc==8) dprintf("addr done: %x", saddr>>1); if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1);
} }
} }
} }
sreg &= ~3; sreg |= d&3; // remember SCL and SDA sreg &= ~3; sreg |= d&3; // remember SCL and SDA
Pico.m.sram_reg = (unsigned char) sreg; Pico.m.sram_reg = (unsigned char) sreg;
Pico.m.sram_addr = (unsigned short)(saddr|(sreg&0xc000)); Pico.m.eeprom_cycle= (unsigned char) scyc;
Pico.m.sram_cycle= (unsigned char) scyc; Pico.m.eeprom_slave= (unsigned char) ssa;
Pico.m.sram_slave= (unsigned char) ssa; Pico.m.eeprom_addr = (unsigned short)saddr;
} }
PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void) PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)
{ {
unsigned int shift, d=0; unsigned int shift, d;
unsigned int sreg, saddr, scyc, ssa; unsigned int sreg, saddr, scyc, ssa, interval;
// flush last pending write // flush last pending write
SRAMWriteEEPROM(Pico.m.sram_reg>>6); SRAMWriteEEPROM(Pico.m.sram_reg>>6);
sreg = Pico.m.sram_reg; saddr = Pico.m.sram_addr&0x1fff; scyc = Pico.m.sram_cycle; ssa = Pico.m.sram_slave; sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;
// if(!(sreg & 2) && (sreg&0x80)) scyc++; // take care of raising edge now to compensate lag interval = SekCyclesDoneT()-lastSSRamWrite;
d = (sreg>>6)&1; // use SDA as "open bus"
if(SekCyclesDoneT()-lastSSRamWrite < 46) { // NBA Jam is nasty enough to read <before> raising the SCL and starting the new cycle.
// data was just written, there was no time to respond (used by sports games) // this is probably valid because data changes occur while SCL is low and data can be read
d = (sreg>>6)&1; // before it's actual cycle begins.
} else if((sreg & 8) && scyc > 9 && scyc != 18 && scyc != 27) { if (!(sreg&0x80) && interval >= 24) {
elprintf(EL_EEPROM, "eeprom: early read, cycles=%i", interval);
scyc++;
}
if (!(sreg & 8)); // not started, use open bus
else if (scyc == 9 || scyc == 18 || scyc == 27) {
elprintf(EL_EEPROM, "eeprom: r ack");
d = 0;
} else if (scyc > 9 && scyc < 18) {
// started and first command word received // started and first command word received
shift = 17-scyc; shift = 17-scyc;
if(sreg & 0x20) { if (SRam.eeprom_type) {
// X24C02+ // X24C02+
if (ssa&1) { if (ssa&1) {
//dprintf("read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg); elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);
if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr]);
d = (SRam.data[saddr]>>shift)&1; d = (SRam.data[saddr]>>shift)&1;
} }
} else { } else {
// X24C01 // X24C01
if (saddr&1) { if (saddr&1) {
elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr>>1, scyc, sreg);
if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr>>1]);
d = (SRam.data[saddr>>1]>>shift)&1; d = (SRam.data[saddr>>1]>>shift)&1;
} }
} }
} }
//else dprintf("r ack");
return d; return (d << SRam.eeprom_bit_out);
} }
PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d) PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)
{ {
unsigned int sreg = Pico.m.sram_reg; unsigned int d1, sreg = Pico.m.sram_reg;
if(!(a&1)) sreg|=0x20; if (!((SRam.eeprom_abits^a)&1))
{
if(sreg&0x20) { // address through 0x200000 // SCL
if(!(a&1)) {
sreg &= ~0x80; sreg &= ~0x80;
sreg|=d<<7; d1 = (d >> SRam.eeprom_bit_cl) & 1;
} else { sreg |= d1<<7;
sreg&=~0x40;
sreg|=(d<<6)&0x40;
} }
} else { if (!(((SRam.eeprom_abits>>1)^a)&1))
sreg&=~0xc0; {
sreg|=d<<6; // SDA in
sreg &= ~0x40;
d1 = (d >> SRam.eeprom_bit_in) & 1;
sreg |= d1<<6;
} }
Pico.m.sram_reg = (unsigned char) sreg; Pico.m.sram_reg = (unsigned char) sreg;

View file

@ -19,7 +19,7 @@ int PicoAutoRgnOrder = 0;
int emustatus = 0; int emustatus = 0;
void (*PicoWriteSound)(int len) = 0; // called once per frame at the best time to send sound buffer (PsndOut) to hardware void (*PicoWriteSound)(int len) = 0; // called once per frame at the best time to send sound buffer (PsndOut) to hardware
struct PicoSRAM SRam; struct PicoSRAM SRam = {0,};
int z80startCycle, z80stopCycle; // in 68k cycles int z80startCycle, z80stopCycle; // in 68k cycles
//int z80ExtraCycles = 0; //int z80ExtraCycles = 0;
int PicoPad[2]; // Joypads, format is SACB RLDU int PicoPad[2]; // Joypads, format is SACB RLDU
@ -39,7 +39,6 @@ int PicoInit(void)
PicoInitMCD(); PicoInitMCD();
SRam.data=0; SRam.data=0;
SRam.resize=1;
return 0; return 0;
} }
@ -59,13 +58,10 @@ int PicoReset(int hard)
unsigned int region=0; unsigned int region=0;
int support=0,hw=0,i=0; int support=0,hw=0,i=0;
unsigned char pal=0; unsigned char pal=0;
unsigned char sram_reg=Pico.m.sram_reg; // must be preserved
if (Pico.romsize<=0) return 1; if (Pico.romsize<=0) return 1;
// setup correct memory map
if (PicoMCD & 1)
PicoMemSetupCD();
else PicoMemSetup();
PicoMemReset(); PicoMemReset();
SekReset(); SekReset();
// s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games). // s68k doesn't have the TAS quirk, so we just globally set normal TAS handler in MCD mode (used by Batman games).
@ -149,56 +145,17 @@ int PicoReset(int hard)
return 0; return 0;
} }
if(SRam.resize) { // reset sram state; enable sram access by default if it doesn't overlap with ROM
int sram_size = 0; Pico.m.sram_reg=sram_reg&0x14;
if(SRam.data) free(SRam.data); SRam.data=0; if (!(Pico.m.sram_reg&4) && Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1;
Pico.m.sram_reg = 0;
if(*(Pico.rom+0x1B1) == 'R' && *(Pico.rom+0x1B0) == 'A') {
if(*(Pico.rom+0x1B2) & 0x40) {
// EEPROM
// what kind of EEPROMs are actually used? X24C02? X24C04? (X24C01 has only 128), but we will support up to 8K
SRam.start = PicoRead32(0x1B4) & ~1; // zero address is used for clock by some games
SRam.end = PicoRead32(0x1B8);
sram_size = 0x2000;
Pico.m.sram_reg = 4;
} else {
// normal SRAM
SRam.start = PicoRead32(0x1B4) & 0xFFFF00;
SRam.end = PicoRead32(0x1B8) | 1;
sram_size = SRam.end - SRam.start + 1;
}
Pico.m.sram_reg |= 0x10; // SRAM was detected
}
if(sram_size <= 0) {
// some games may have bad headers, like S&K and Sonic3
SRam.start = 0x200000;
SRam.end = 0x203FFF;
sram_size = 0x004000;
}
// enable sram access by default if it doesn't overlap with ROM
if(Pico.romsize <= SRam.start) Pico.m.sram_reg |= 1;
SRam.reg_back = Pico.m.sram_reg;
if(sram_size) {
SRam.data = (unsigned char *) calloc(sram_size, 1);
if(!SRam.data) return 1;
}
SRam.resize=0;
// Dino Dini's Soccer malfunctions if SRAM is not filled with 0xff
if (strncmp((char *)Pico.rom+0x150, "IDOND NI'I", 10) == 0)
memset(SRam.data, 0xff, sram_size);
elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x", elprintf(EL_STATUS, "sram: det: %i; eeprom: %i; start: %06x; end: %06x",
(Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end); (Pico.m.sram_reg>>4)&1, (Pico.m.sram_reg>>2)&1, SRam.start, SRam.end);
}
Pico.m.sram_reg = SRam.reg_back; // restore sram_reg
SRam.changed = 0;
return 0; return 0;
} }
// dma2vram settings are just hacks to unglitch Legend of Galahad (needs <= 104 to work) // dma2vram settings are just hacks to unglitch Legend of Galahad (needs <= 104 to work)
// same for Outrunners (92-121, when active is set to 24) // same for Outrunners (92-121, when active is set to 24)
static const int dma_timings[] = { static const int dma_timings[] = {
@ -692,8 +649,8 @@ char *debugString(void)
sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); dstrp+=strlen(dstrp); sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); dstrp+=strlen(dstrp);
sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3));
dstrp+=strlen(dstrp); dstrp+=strlen(dstrp);
sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i\n", reg[0x10]&3, (reg[0x10]&0x30)>>4, sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,
bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2)); dstrp+=strlen(dstrp); bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2), SRam.eeprom_type); dstrp+=strlen(dstrp);
sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); dstrp+=strlen(dstrp); sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); dstrp+=strlen(dstrp);
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status);
dstrp+=strlen(dstrp); dstrp+=strlen(dstrp);

View file

@ -34,6 +34,7 @@ void mp3_update(int *buffer, int length, int stereo);
// alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites, // alt_renderer, 6button_gamepad, accurate_timing, accurate_sprites,
// draw_no_32col_border, external_ym2612, enable_cd_pcm, enable_cd_cdda // draw_no_32col_border, external_ym2612, enable_cd_pcm, enable_cd_cdda
// enable_cd_gfx, cd_perfect_sync, soft_32col_scaling, enable_cd_ramcart // enable_cd_gfx, cd_perfect_sync, soft_32col_scaling, enable_cd_ramcart
// disable_vdp_fifo
extern int PicoOpt; extern int PicoOpt;
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

View file

@ -171,9 +171,9 @@ struct PicoMisc
unsigned char z80_fakeval; unsigned char z80_fakeval;
unsigned char pad0; unsigned char pad0;
unsigned char padDelay[2]; // 10 gamepad phase time outs, so we count a delay unsigned char padDelay[2]; // 10 gamepad phase time outs, so we count a delay
unsigned short sram_addr; // EEPROM address register unsigned short eeprom_addr; // EEPROM address register
unsigned char sram_cycle; // EEPROM SRAM cycle number unsigned char eeprom_cycle; // EEPROM SRAM cycle number
unsigned char sram_slave; // EEPROM slave word for X24C02 and better SRAMs unsigned char eeprom_slave; // EEPROM slave word for X24C02 and better SRAMs
unsigned char prot_bytes[2]; // simple protection faking unsigned char prot_bytes[2]; // simple protection faking
unsigned short dma_xfers; unsigned short dma_xfers;
unsigned char pad[2]; unsigned char pad[2];
@ -204,10 +204,14 @@ struct PicoSRAM
unsigned char *data; // actual data unsigned char *data; // actual data
unsigned int start; // start address in 68k address space unsigned int start; // start address in 68k address space
unsigned int end; unsigned int end;
unsigned char resize; // 0c: 1=SRAM size changed and needs to be reallocated on PicoReset unsigned char unused1; // 0c: unused
unsigned char reg_back; // copy of Pico.m.sram_reg to set after reset unsigned char unused2;
unsigned char changed; unsigned char changed;
unsigned char pad; unsigned char eeprom_type; // eeprom type: 0: 7bit (24C01), 2: device with 2 addr words (X24C02+), 3: dev with 3 addr words
unsigned char eeprom_abits; // eeprom access must be odd addr for: bit0 ~ cl, bit1 ~ out
unsigned char eeprom_bit_cl; // bit number for cl
unsigned char eeprom_bit_in; // bit number for in
unsigned char eeprom_bit_out; // bit number for out
}; };
// MCD // MCD
@ -291,6 +295,9 @@ PICO_INTERNAL int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub);
PICO_INTERNAL int PicoCdSaveState(void *file); PICO_INTERNAL int PicoCdSaveState(void *file);
PICO_INTERNAL int PicoCdLoadState(void *file); PICO_INTERNAL int PicoCdLoadState(void *file);
// Cart.c
PICO_INTERNAL void PicoCartDetect(void);
// Draw.c // Draw.c
PICO_INTERNAL int PicoLine(int scan); PICO_INTERNAL int PicoLine(int scan);
PICO_INTERNAL void PicoFrameStart(void); PICO_INTERNAL void PicoFrameStart(void);
@ -397,6 +404,10 @@ PICO_INTERNAL void z80_exit(void);
#define EL_VDPDMA 0x0040 /* VDP DMA transfers and their timing */ #define EL_VDPDMA 0x0040 /* VDP DMA transfers and their timing */
#define EL_BUSREQ 0x0080 /* z80 busreq r/w */ #define EL_BUSREQ 0x0080 /* z80 busreq r/w */
#define EL_Z80BNK 0x0100 /* z80 i/o through bank area */ #define EL_Z80BNK 0x0100 /* z80 i/o through bank area */
#define EL_SRAMIO 0x0200 /* sram i/o */
#define EL_EEPROM 0x0400 /* eeprom debug */
#define EL_UIO 0x0800 /* unmapped i/o */
#define EL_IO 0x1000 /* all i/o */
#define EL_STATUS 0x4000 /* status messages */ #define EL_STATUS 0x4000 /* status messages */
#define EL_ANOMALY 0x8000 /* some unexpected conditions */ #define EL_ANOMALY 0x8000 /* some unexpected conditions */

View file

@ -337,7 +337,7 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d)
else else
{ {
// preliminary FIFO emulation for Chaos Engine, The (E) // preliminary FIFO emulation for Chaos Engine, The (E)
if(!(pvid->status&8) && (pvid->reg[1]&0x40) && Pico.m.scanline!=-1) // active display, accurate mode? if(!(pvid->status&8) && (pvid->reg[1]&0x40) && Pico.m.scanline!=-1 && !(PicoOpt&0x10000)) // active display, accurate mode?
{ {
pvid->status&=~0x200; // FIFO no longer empty pvid->status&=~0x200; // FIFO no longer empty
pvid->lwrite_cnt++; pvid->lwrite_cnt++;

View file

@ -32,7 +32,12 @@ use_cyclone = 1
endif endif
DEFINC = -I../.. -I. -DARM -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK DEFINC = -I../.. -I. -DARM -D__GP2X__ -D_UNZIP_SUPPORT # -DBENCHMARK
COPT_COMMON = -static -Wall -O2 -ftracer -fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math -Winline COPT_COMMON = -static -Wall -Winline
ifeq ($(DEBUG),)
COPT_COMMON += -O2 -ftracer -fstrength-reduce -fomit-frame-pointer -fstrict-aliasing -ffast-math
else
COPT_COMMON += -ggdb
endif
ifeq "$(profile)" "1" ifeq "$(profile)" "1"
COPT_COMMON += -fprofile-generate COPT_COMMON += -fprofile-generate
endif endif

View file

@ -26,6 +26,7 @@
#include <Pico/Patch.h> #include <Pico/Patch.h>
#include <zlib/zlib.h> #include <zlib/zlib.h>
//#define PFRAMES
#ifdef BENCHMARK #ifdef BENCHMARK
#define OSD_FPS_X 220 #define OSD_FPS_X 220
@ -352,7 +353,7 @@ int emu_ReloadRom(void)
if(movie_data[0x14] == '6') if(movie_data[0x14] == '6')
PicoOpt |= 0x20; // 6 button pad PicoOpt |= 0x20; // 6 button pad
else PicoOpt &= ~0x20; else PicoOpt &= ~0x20;
PicoOpt |= 0x40; // accurate timing PicoOpt |= 0x10040; // accurate timing, no VDP fifo timing
if(movie_data[0xF] >= 'A') { if(movie_data[0xF] >= 'A') {
if(movie_data[0x16] & 0x80) { if(movie_data[0x16] & 0x80) {
PicoRegionOverride = 8; PicoRegionOverride = 8;
@ -367,6 +368,7 @@ int emu_ReloadRom(void)
} }
else else
{ {
PicoOpt &= ~0x10000;
if(Pico.m.pal) { if(Pico.m.pal) {
strcpy(noticeMsg, "PAL SYSTEM / 50 FPS"); strcpy(noticeMsg, "PAL SYSTEM / 50 FPS");
} else { } else {
@ -1185,17 +1187,18 @@ void emu_Loop(void)
// prepare sound stuff // prepare sound stuff
if(currentConfig.EmuOpt & 4) { if(currentConfig.EmuOpt & 4) {
int snd_excess_add; int snd_excess_add;
if(PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old || crashed_940) { if (PsndRate != PsndRate_old || (PicoOpt&0x20b) != (PicoOpt_old&0x20b) || Pico.m.pal != pal_old ||
((PicoOpt&0x200) && crashed_940)) {
/* if 940 is turned off, we need it to be put back to sleep */ /* if 940 is turned off, we need it to be put back to sleep */
if (!(PicoOpt&0x200) && ((PicoOpt^PicoOpt_old)&0x200)) { if (!(PicoOpt&0x200) && ((PicoOpt^PicoOpt_old)&0x200)) {
Reset940(1, 2); Reset940(1, 2);
Pause940(1); Pause940(1);
} }
sound_rerate(1); sound_rerate(Pico.m.frame_count ? 1 : 0);
} }
//excess_samples = PsndRate - PsndLen*target_fps;
snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps; snd_excess_add = ((PsndRate - PsndLen*target_fps)<<16) / target_fps;
printf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n", PsndRate, PsndLen, snd_excess_add, (PicoOpt&8)>>3, Pico.m.pal); printf("starting audio: %i len: %i (ex: %04x) stereo: %i, pal: %i\n",
PsndRate, PsndLen, snd_excess_add, (PicoOpt&8)>>3, Pico.m.pal);
gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3); gp2x_start_sound(PsndRate, 16, (PicoOpt&8)>>3);
gp2x_sound_volume(currentConfig.volume, currentConfig.volume); gp2x_sound_volume(currentConfig.volume, currentConfig.volume);
PicoWriteSound = updateSound; PicoWriteSound = updateSound;
@ -1307,6 +1310,9 @@ void emu_Loop(void)
if (frames_shown > frames_done) frames_shown = frames_done; if (frames_shown > frames_done) frames_shown = frames_done;
} }
} }
#ifdef PFRAMES
sprintf(fpsbuff, "%i", Pico.m.frame_count);
#endif
lim_time = (frames_done+1) * target_frametime + vsync_offset; lim_time = (frames_done+1) * target_frametime + vsync_offset;
if(currentConfig.Frameskip >= 0) { // frameskip enabled if(currentConfig.Frameskip >= 0) { // frameskip enabled
@ -1571,7 +1577,7 @@ int emu_SaveLoadGame(int load, int sram)
} }
} else { } else {
sram_size = SRam.end-SRam.start+1; sram_size = SRam.end-SRam.start+1;
if(SRam.reg_back & 4) sram_size=0x2000; if(Pico.m.sram_reg & 4) sram_size=0x2000;
sram_data = SRam.data; sram_data = SRam.data;
} }
if (!sram_data) return 0; // SRam forcefully disabled for this game if (!sram_data) return 0; // SRam forcefully disabled for this game

View file

@ -13,7 +13,7 @@
#define CAN_HANDLE_240_LINES 1 #define CAN_HANDLE_240_LINES 1
// logging emu events // logging emu events
#define EL_LOGMASK 0 // (EL_STATUS|EL_ANOMALY) // xffff #define EL_LOGMASK 0 // (EL_STATUS|EL_ANOMALY|EL_UIO) // xffff
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
#define dprintf(x...) #define dprintf(x...)

View file

@ -13,7 +13,7 @@
// pico.c // pico.c
#define CAN_HANDLE_240_LINES 1 #define CAN_HANDLE_240_LINES 1
#define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK) #define EL_LOGMASK (EL_ANOMALY|EL_STATUS|EL_SRAMIO|EL_EEPROM) // EL_VDPDMA|EL_ASVDP|EL_SR) // |EL_BUSREQ|EL_Z80BNK)
//#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__) //#define dprintf(f,...) printf("%05i:%03i: " f "\n",Pico.m.frame_count,Pico.m.scanline,##__VA_ARGS__)
#define dprintf(x...) #define dprintf(x...)

View file

@ -227,13 +227,15 @@ Symbian:
Changelog Changelog
--------- ---------
1.332 1.34
+ Some new optimizations in memory handlers, and for shadow/hilight mode. + Some new optimizations in memory handlers, and for shadow/hilight mode.
+ Added some hacks to make more games work without enabling "accurate timing". + Added some hacks to make more games work without enabling "accurate timing".
* Fixed hang of NBA Jam (ingame saves do not work though).
* Adjusted timing for "accurate timing" mode and added preliminary VDP FIFO * Adjusted timing for "accurate timing" mode and added preliminary VDP FIFO
emulation. Fixes Double Dragon 2, tearing in Chaos Engine and some other games. emulation. Fixes Double Dragon 2, tearing in Chaos Engine and some other games.
* Fixed a few games not having sound at startup. * Fixed a few games not having sound at startup.
* Updated serial EEPROM code to support more games. Thanks to EkeEke for
providing info about additional EEPROM types and game mappers.
* The above change fixed hang of NBA Jam.
1.33 1.33
* Updated Cyclone core to 0.0088. * Updated Cyclone core to 0.0088.