From 7969166ef66a8623cb4d8c609eb6e67314aefd79 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 2 Sep 2007 21:03:49 +0000 Subject: [PATCH] sram handling refactored git-svn-id: file:///home/notaz/opt/svn/PicoDrive@239 be3aeb3a-fb24-0410-a615-afba39da0efa --- Pico/Memory.c | 100 +++++++++++++++++++++++++---------------------- Pico/Memory.s | 97 ++++++++++++++++++--------------------------- Pico/MemoryCmn.c | 15 ++++++- Pico/Misc.c | 76 +++++++++++++++++------------------ Pico/Pico.c | 1 + 5 files changed, 143 insertions(+), 146 deletions(-) diff --git a/Pico/Memory.c b/Pico/Memory.c index dc9c7386..72c43960 100644 --- a/Pico/Memory.c +++ b/Pico/Memory.c @@ -144,14 +144,49 @@ int PadRead(int i) #ifndef _ASM_MEMORY_C -// address must already be checked -static int SRAMRead(u32 a) +static +#endif +u32 SRAMRead(u32 a) { - u8 *d = SRam.data-SRam.start+a; - return (d[0]<<8)|d[1]; + unsigned int sreg = Pico.m.sram_reg; + if(!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM + Pico.m.sram_reg|=0x10; // should be normal SRAM + } + if(sreg & 4) // EEPROM read + return SRAMReadEEPROM(); + else // if(sreg & 1) // (sreg&5) is one of prerequisites + return *(u8 *)(SRam.data-SRam.start+a); } -#endif +static void SRAMWrite(u32 a, u32 d) +{ + dprintf("sram_w: %06x, %08x @%06x", a&0xffffff, d, SekPc); + unsigned int sreg = Pico.m.sram_reg; + if(!(sreg & 0x10)) { + // not detected SRAM + if((a&~1)==0x200000) { + Pico.m.sram_reg|=4; // this should be a game with EEPROM (like NBA Jam) + SRam.start=0x200000; SRam.end=SRam.start+1; + } + Pico.m.sram_reg|=0x10; + } + if(sreg & 4) { // EEPROM write + if(SekCyclesDoneT()-lastSSRamWrite < 46) { + // just update pending state + SRAMUpdPending(a, d); + } else { + SRAMWriteEEPROM(sreg>>6); // execute pending + SRAMUpdPending(a, d); + lastSSRamWrite = SekCyclesDoneT(); + } + } else if(!(sreg & 2)) { + u8 *pm=(u8 *)(SRam.data-SRam.start+a); + if(*pm != (u8)d) { + SRam.changed = 1; + *pm=(u8)d; + } + } +} // for nonstandard reads #ifndef _ASM_MEMORY_C @@ -237,32 +272,7 @@ static void OtherWrite8End(u32 a,u32 d,int realsize) //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) { - dprintf("sram w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc); - unsigned int sreg = Pico.m.sram_reg; - if(!(sreg & 0x10)) { - // not detected SRAM - if((a&~1)==0x200000) { - Pico.m.sram_reg|=4; // this should be a game with EEPROM (like NBA Jam) - SRam.start=0x200000; SRam.end=SRam.start+1; - } - Pico.m.sram_reg|=0x10; - } - if(sreg & 4) { // EEPROM write - if(SekCyclesDoneT()-lastSSRamWrite < 46) { - // just update pending state - SRAMUpdPending(a, d); - } else { - SRAMWriteEEPROM(sreg>>6); // execute pending - SRAMUpdPending(a, d); - lastSSRamWrite = SekCyclesDoneT(); - } - } else if(!(sreg & 2)) { - u8 *pm=(u8 *)(SRam.data-SRam.start+a); - if(*pm != (u8)d) { - SRam.changed = 1; - *pm=(u8)d; - } - } + SRAMWrite(a, d); return; } @@ -317,18 +327,9 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a) #if !(defined(EMU_C68K) && defined(EMU_M68K)) // sram - if(a >= SRam.start && a <= SRam.end) { - unsigned int sreg = Pico.m.sram_reg; - if(!(sreg & 0x10) && (sreg & 1) && a > 0x200001) { // not yet detected SRAM - Pico.m.sram_reg|=0x10; // should be normal SRAM - } - if(sreg & 4) { // EEPROM read - d = SRAMReadEEPROM(); - goto end; - } else if(sreg & 1) { - d = *(u8 *)(SRam.data-SRam.start+a); - goto end; - } + if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { + d = SRAMRead(a); + goto end; } #endif @@ -345,7 +346,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead8(u32 a) //if ((a&0xe0ffff)==0xe0a9ba+0x69c) // dprintf("r8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); - //if(a==0x200001) dprintf("r8 : %02x @ %06x [%i]", d, SekPc, SekCyclesDoneT()); + //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 dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); @@ -369,8 +370,9 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a) #if !(defined(EMU_C68K) && defined(EMU_M68K)) // sram - if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg & 1)) { + if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { d = SRAMRead(a); + d |= d<<8; goto end; } #endif @@ -383,6 +385,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead16(u32 a) 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 dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc); @@ -405,8 +408,9 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a) a&=0xfffffe; // sram - if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg & 1)) { + if(a >= SRam.start && a <= SRam.end && (Pico.m.sram_reg&5)) { d = (SRAMRead(a)<<16)|SRAMRead(a+2); + d |= d<<8; goto end; } @@ -416,6 +420,7 @@ PICO_INTERNAL_ASM u32 CPU_CALL PicoRead32(u32 a) d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32); end: + //if(a==0x200000) printf("r32: %08x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT()); #ifdef __debug_io dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc); #endif @@ -442,6 +447,7 @@ PICO_INTERNAL_ASM void CPU_CALL PicoWrite8(u32 a,u8 d) lastwrite_cyc_d[lwp_cyc++&15] = d; #endif //if ((a&0xe0ffff)==0xe0a9ba+0x69c) + //if(a==0x200000||a==0x200001) printf("w8 : %02x [%06x] @ %06x [%i]\n", d, a, SekPc, SekCyclesDoneT()); // dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc); if ((a&0xe00000)==0xe00000) { *(u8 *)(Pico.ram+((a^1)&0xffff))=d; return; } // Ram @@ -462,6 +468,7 @@ void CPU_CALL PicoWrite16(u32 a,u16 d) #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 log_io(a, 16, 1); @@ -478,6 +485,7 @@ static void CPU_CALL PicoWrite32(u32 a,u32 d) #if defined(EMU_C68K) && defined(EMU_M68K) lastwrite_cyc_d[lwp_cyc++&15] = d; #endif + //if(a==0x200000) printf("w32: %08x @ %06x [%i]\n", d, SekPc, SekCyclesDoneT()); if ((a&0xe00000)==0xe00000) { diff --git a/Pico/Memory.s b/Pico/Memory.s index 4208fec6..88b8c43e 100644 --- a/Pico/Memory.s +++ b/Pico/Memory.s @@ -40,8 +40,8 @@ m_read8_def_table: .long m_read_null @ 0xB80000 - 0xBFFFFF .long m_read8_vdp @ 0xC00000 - 0xC7FFFF .long m_read8_vdp @ 0xC80000 - 0xCFFFFF - .long m_read_null @ 0xD00000 - 0xD7FFFF - .long m_read_null @ 0xD80000 - 0xDFFFFF + .long m_read8_vdp @ 0xD00000 - 0xD7FFFF + .long m_read8_vdp @ 0xD80000 - 0xDFFFFF .long m_read8_ram @ 0xE00000 - 0xE7FFFF .long m_read8_ram @ 0xE80000 - 0xEFFFFF .long m_read8_ram @ 0xF00000 - 0xF7FFFF @@ -73,9 +73,9 @@ m_read16_def_table: .long m_read_null @ 0xB00000 - 0xB7FFFF .long m_read_null @ 0xB80000 - 0xBFFFFF .long m_read16_vdp @ 0xC00000 - 0xC7FFFF - .long m_read_null @ 0xC80000 - 0xCFFFFF - .long m_read_null @ 0xD00000 - 0xD7FFFF - .long m_read_null @ 0xD80000 - 0xDFFFFF + .long m_read16_vdp @ 0xC80000 - 0xCFFFFF + .long m_read16_vdp @ 0xD00000 - 0xD7FFFF + .long m_read16_vdp @ 0xD80000 - 0xDFFFFF .long m_read16_ram @ 0xE00000 - 0xE7FFFF .long m_read16_ram @ 0xE80000 - 0xEFFFFF .long m_read16_ram @ 0xF00000 - 0xF7FFFF @@ -107,9 +107,9 @@ m_read32_def_table: .long m_read_null @ 0xB00000 - 0xB7FFFF .long m_read_null @ 0xB80000 - 0xBFFFFF .long m_read32_vdp @ 0xC00000 - 0xC7FFFF - .long m_read_null @ 0xC80000 - 0xCFFFFF - .long m_read_null @ 0xD00000 - 0xD7FFFF - .long m_read_null @ 0xD80000 - 0xDFFFFF + .long m_read32_vdp @ 0xC80000 - 0xCFFFFF + .long m_read32_vdp @ 0xD00000 - 0xD7FFFF + .long m_read32_vdp @ 0xD80000 - 0xDFFFFF .long m_read32_ram @ 0xE00000 - 0xE7FFFF .long m_read32_ram @ 0xE80000 - 0xEFFFFF .long m_read32_ram @ 0xF00000 - 0xF7FFFF @@ -284,31 +284,14 @@ m_read8_rom4: @ 0x200000 - 0x27ffff, SRAM area orr r0, r0, #0x200000 cmp r0, r1 bgt m_read8_nosram - ldr r1, [r2, #4] @ SRam.start (1ci) + ldr r1, [r2, #4] @ SRam.start cmp r0, r1 blt m_read8_nosram - ldrb r1, [r3, #0x11] @ Pico.m.sram_reg (1ci) - sub r12,r0, #0x200000 - tst r1, #0x10 - bne m_read8_detected - cmp r12,#1 - ble m_read8_detected - tst r1, #1 - orrne r1, r1, #0x10 - strneb r1, [r3, #0x11] -m_read8_detected: - tst r1, #4 @ EEPROM read? - bne SRAMReadEEPROM -m_read8_noteeprom: - tst r1, #1 - beq m_read8_nosram - ldr r3, [r2] @ SRam.data - ldr r2, [r2, #4] @ SRam.start (1ci) - sub r3, r3, r2 - ldrb r0, [r3, r0] - bx lr + ldrb r1, [r3, #0x11] @ Pico.m.sram_reg + tst r1, #5 + bne SRAMRead m_read8_nosram: - ldr r1, [r3, #4] @ 1ci + ldr r1, [r3, #4] @ romsize cmp r0, r1 movgt r0, #0 bxgt lr @ bad location @@ -499,22 +482,18 @@ m_read16_rom4: @ 0x200000 - 0x27ffff, SRAM area (NBA Live 95) orr r0, r0, #0x200000 cmp r0, r1 bgt m_read16_nosram - ldrb r1, [r3, #0x11] @ Pico.m.sram_reg (2ci) - tst r1, #1 - beq m_read16_nosram - ldr r1, [r2, #4] @ SRam.start (1ci) + ldr r1, [r2, #4] @ SRam.start cmp r0, r1 blt m_read16_nosram - ldr r2, [r2] @ SRam.data (1ci) - sub r2, r2, r1 - ldrh r0, [r2, r0] @ 2ci - and r1, r0, #0xff - mov r0, r0, lsr #8 - orr r0, r0, r1, lsl #8 - bx lr - + ldrb r1, [r3, #0x11] @ Pico.m.sram_reg + tst r1, #5 + beq m_read16_nosram + stmfd sp!,{lr} + bl SRAMRead + orr r0, r0, r0, lsl #8 + ldmfd sp!,{pc} m_read16_nosram: - ldr r1, [r3, #4] @ 1ci + ldr r1, [r3, #4] @ romsize cmp r0, r1 movgt r0, #0 bxgt lr @ bad location @@ -573,7 +552,7 @@ m_read16_misc: b OtherRead16 m_read16_vdp: - tst r0, #0x70000 + tst r0, #0x70000 @ if ((a&0xe700e0)==0xc00000) tsteq r0, #0x000e0 bxne lr @ invalid read bic r0, r0, #1 @@ -631,26 +610,24 @@ m_read32_rom4: @ 0x200000 - 0x27ffff, SRAM area (does any game do long reads?) orr r0, r0, #0x200000 cmp r0, r1 bgt m_read32_nosram - ldrb r1, [r3, #0x11] @ Pico.m.sram_reg (2ci) - tst r1, #1 - beq m_read32_nosram - ldr r1, [r2, #4] @ SRam.start (1ci) + ldr r1, [r2, #4] @ SRam.start cmp r0, r1 blt m_read32_nosram - ldr r2, [r2] @ SRam.data (1ci) - sub r2, r2, r1 - ldrh r0, [r2, r0]! @ (1ci) - ldrh r1, [r2, #2] - orr r0, r0, r0, lsl #16 - mov r0, r0, ror #8 - mov r0, r0, lsl #16 - orr r0, r0, r1, lsr #8 - and r1, r1, #0xff - orr r0, r0, r1, lsl #8 + ldrb r1, [r3, #0x11] @ Pico.m.sram_reg + tst r1, #5 + beq m_read32_nosram + stmfd sp!,{r0,lr} + bl SRAMRead + ldmfd sp!,{r1,lr} + stmfd sp!,{r0,lr} + add r0, r1, #2 + bl SRAMRead + ldmfd sp!,{r1,lr} + orr r0, r1, r0, lsl #16 + orr r0, r0, r0, lsl #8 bx lr - m_read32_nosram: - ldr r1, [r3, #4] @ (1ci) + ldr r1, [r3, #4] @ romsize cmp r0, r1 movgt r0, #0 bxgt lr @ bad location diff --git a/Pico/MemoryCmn.c b/Pico/MemoryCmn.c index 2bce627d..0a86223e 100644 --- a/Pico/MemoryCmn.c +++ b/Pico/MemoryCmn.c @@ -214,8 +214,19 @@ void OtherWrite16(u32 a,u32 d) return; } - OtherWrite8End(a, d>>8, 16); - OtherWrite8End(a+1,d&0xff, 16); + if (a >= SRam.start && a <= SRam.end) { + if ((a&0x16)==0x10) { // detected, not EEPROM, write not disabled + u8 *pm=(u8 *)(SRam.data-SRam.start+a); + *pm++=d>>8; + *pm++=d; + SRam.changed = 1; + } + else + SRAMWrite(a, d); // ?? + return; + } + //OtherWrite8End(a, d>>8, 16); + //OtherWrite8End(a+1,d&0xff, 16); } diff --git a/Pico/Misc.c b/Pico/Misc.c index 2a0e5699..8e89a4f2 100644 --- a/Pico/Misc.c +++ b/Pico/Misc.c @@ -145,7 +145,7 @@ 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; - //dprintf("[%02x]", d); + //printf("EEPROM write %i\n", d&3); 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)) saddr&=0x1fff; @@ -154,11 +154,11 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) if((sreg & 1) && !(d&1)) { // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter //dprintf("-start-"); - if(!(sreg&0x8000) && scyc >= 9) { - if(scyc != 28) sreg |= 0x4000; // 1 word + if(!(sreg&0x8000) && scyc >= 9) { + if(scyc != 28) sreg |= 0x4000; // 1 word //dprintf("detected word count: %i", scyc==28 ? 2 : 1); - sreg |= 0x8000; - } + sreg |= 0x8000; + } //saddr = 0; scyc = 0; sreg |= 8; @@ -171,30 +171,30 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) else if((sreg & 8) && !(sreg & 2) && (d&2)) { // we are started and SCL went high - next cycle scyc++; // pre-increment - if(sreg & 0x20) { + if(sreg & 0x20) { // X24C02+ - if((ssa&1) && scyc == 18) { - scyc = 9; - saddr++; // next address in read mode - if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask - } - else if((sreg&0x4000) && scyc == 27) scyc = 18; - else if(scyc == 36) scyc = 27; - } else { - // X24C01 + if((ssa&1) && scyc == 18) { + scyc = 9; + saddr++; // next address in read mode + if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask + } + else if((sreg&0x4000) && scyc == 27) scyc = 18; + else if(scyc == 36) scyc = 27; + } else { + // X24C01 if(scyc == 18) { scyc = 9; // wrap if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode - } - } - //dprintf("scyc: %i", scyc); + } + } + //dprintf("scyc: %i", scyc); } else if((sreg & 8) && (sreg & 2) && !(d&2)) { // we are started and SCL went low (falling edge) if(sreg & 0x20) { - // X24C02+ - if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles - else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) { + // X24C02+ + if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles + else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) { if(!(ssa&1)) { // data write unsigned char *pm=SRam.data+saddr; @@ -208,18 +208,18 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) } else if(scyc > 9) { if(!(ssa&1)) { // we latch another addr bit - saddr<<=1; - if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask - saddr|=d&1; + saddr<<=1; + if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask + saddr|=d&1; //if(scyc==17||scyc==26) dprintf("addr reg done: %x", saddr); - } + } } else { - // slave address - ssa<<=1; ssa|=d&1; + // slave address + ssa<<=1; ssa|=d&1; //if(scyc==8) dprintf("slave done: %x", ssa); } - } else { - // X24C01 + } else { + // X24C01 if(scyc == 9); // ACK cycle, do nothing else if(scyc > 9) { if(!(saddr&1)) { @@ -237,7 +237,7 @@ PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA) saddr<<=1; saddr|=d&1; saddr&=0xff; //if(scyc==8) dprintf("addr done: %x", saddr>>1); } - } + } } sreg &= ~3; sreg |= d&3; // remember SCL and SDA @@ -265,17 +265,17 @@ PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void) // started and first command word received shift = 17-scyc; if(sreg & 0x20) { - // X24C02+ + // X24C02+ if(ssa&1) { //dprintf("read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg); - d = (SRam.data[saddr]>>shift)&1; - } - } else { - // X24C01 + d = (SRam.data[saddr]>>shift)&1; + } + } else { + // X24C01 if(saddr&1) { - d = (SRam.data[saddr>>1]>>shift)&1; - } - } + d = (SRam.data[saddr>>1]>>shift)&1; + } + } } //else dprintf("r ack"); diff --git a/Pico/Pico.c b/Pico/Pico.c index 259dc18a..6f9ed4ba 100644 --- a/Pico/Pico.c +++ b/Pico/Pico.c @@ -678,6 +678,7 @@ char *debugString(void) dstrp+=strlen(dstrp); sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i\n", reg[0x10]&3, (reg[0x10]&0x30)>>4, bit(Pico.m.sram_reg, 4), bit(Pico.m.sram_reg, 2)); 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); dstrp+=strlen(dstrp); #ifdef EMU_C68K -- 2.39.5