X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=Pico%2Fcd%2FMemory.c;h=71ec377be0ce7ce70b670fe31ed007ed535e1a3e;hb=eff55556cff77fd64cff4be32e449e0a58aed6fe;hp=fc25081eb58296ac577a0757fb00453233001b0b;hpb=89fa852dce08d9aab0f19458a4afa246e9839e9e;p=picodrive.git diff --git a/Pico/cd/Memory.c b/Pico/cd/Memory.c index fc25081..71ec377 100644 --- a/Pico/cd/Memory.c +++ b/Pico/cd/Memory.c @@ -1,10 +1,6 @@ -// This is part of Pico Library - -// (c) Copyright 2004 Dave, All rights reserved. -// (c) Copyright 2007 notaz, All rights reserved. -// Free for non-commercial use. - -// For commercial use, separate licencing terms must be obtained. +// Memory I/O handlers for Sega/Mega CD. +// Loosely based on Gens code. +// (c) Copyright 2007, Grazvydas "notaz" Ignotas // A68K no longer supported here @@ -12,28 +8,33 @@ #include "../PicoInt.h" -#include "../sound/sound.h" #include "../sound/ym2612.h" #include "../sound/sn76496.h" #include "gfx_cd.h" #include "pcm.h" +#ifndef UTYPES_DEFINED typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; +#define UTYPES_DEFINED +#endif //#define __debug_io //#define __debug_io2 -//#define rdprintf dprintf -#define rdprintf(...) +#define rdprintf dprintf +//#define rdprintf(...) //#define wrdprintf dprintf #define wrdprintf(...) +#define plprintf dprintf +//#define plprintf(...) // ----------------------------------------------------------------- // poller detection +//#undef USE_POLL_DETECT #define POLL_LIMIT 16 #define POLL_CYCLES 124 // int m68k_poll_addr, m68k_poll_cnt; @@ -52,7 +53,9 @@ static u32 m68k_reg_read16(u32 a) goto end; case 2: d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7); - dprintf("m68k_regs r3: %02x @%06x", (u8)d, SekPc); + // the DMNA delay must only be visible on s68k side (Lunar2, Silpheed) + if (Pico_mcd->m.state_flags&2) { d &= ~1; d |= 2; } + //printf("m68k_regs r3: %02x @%06x\n", (u8)d, SekPc); goto end; case 4: d = Pico_mcd->s68k_regs[4]<<8; @@ -113,11 +116,12 @@ void m68k_reg_write8(u32 a, u32 d) Pico_mcd->m.busreq = d; return; case 2: + dprintf("m68k: prg wp=%02x", d); Pico_mcd->s68k_regs[2] = d; // really use s68k side register return; case 3: { u32 dold = Pico_mcd->s68k_regs[3]&0x1f; - dprintf("m68k_regs w3: %02x @%06x", (u8)d, SekPc); + //printf("m68k_regs w3: %02x @%06x\n", (u8)d, SekPc); d &= 0xc2; if ((dold>>6) != ((d>>6)&3)) dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); @@ -141,7 +145,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -161,7 +165,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -172,7 +176,7 @@ void m68k_reg_write8(u32 a, u32 d) #ifdef USE_POLL_DETECT if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(0); s68k_poll_adclk = 0; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -181,6 +185,31 @@ void m68k_reg_write8(u32 a, u32 d) dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d); } +#ifndef _ASM_CD_MEMORY_C +static +#endif +u32 s68k_poll_detect(u32 a, u32 d) +{ +#ifdef USE_POLL_DETECT + // polling detection + if (a == (s68k_poll_adclk&0xff)) { + unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8); + if (clkdiff <= POLL_CYCLES) { + s68k_poll_cnt++; + //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt); + if (s68k_poll_cnt > POLL_LIMIT) { + SekSetStopS68k(1); + plprintf("s68k poll detected @ %06x, a=%02x\n", SekPcS68k, a); + } + s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; + return d; + } + } + s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; + s68k_poll_cnt = 0; +#endif + return d; +} #define READ_FONT_DATA(basemask) \ { \ @@ -206,9 +235,9 @@ u32 s68k_reg_read16(u32 a) case 0: return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state case 2: - d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f); - dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k); - goto poll_detect; + d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f); + //printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k); + return s68k_poll_detect(a, d); case 6: return CDC_Read_Reg(); case 8: @@ -238,31 +267,10 @@ u32 s68k_reg_read16(u32 a) d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1]; - if (a >= 0x0e && a < 0x30) goto poll_detect; + if (a >= 0x0e && a < 0x30) + return s68k_poll_detect(a, d); return d; - -poll_detect: -#ifdef USE_POLL_DETECT - // polling detection - if (a == (s68k_poll_adclk&0xfe)) { - unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8); - if (clkdiff <= POLL_CYCLES) { - s68k_poll_cnt++; - //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt); - if (s68k_poll_cnt > POLL_LIMIT) { - SekSetStopS68k(1); - //printf("%05i:%03i: s68k poll detected @ %06x, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, SekPcS68k, a); - } - s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; - return d; - } - } - s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a; - s68k_poll_cnt = 0; - -#endif - return d; } #ifndef _ASM_CD_MEMORY_C @@ -279,7 +287,7 @@ void s68k_reg_write8(u32 a, u32 d) return; // only m68k can change WP case 3: { int dold = Pico_mcd->s68k_regs[3]; - dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k); + //printf("s68k_regs w3: %02x @%06x\n", (u8)d, SekPcS68k); d &= 0x1d; d |= dold&0xc2; if (d&4) { @@ -396,7 +404,7 @@ static void OtherWrite8End(u32 a, u32 d, int realsize) { if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; } - dprintf("m68k FIXME: strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc); + dprintf("m68k FIXME: strange w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc); } @@ -405,14 +413,15 @@ static void OtherWrite8End(u32 a, u32 d, int realsize) #include "cell_map.c" #endif // !def _ASM_CD_MEMORY_C + // ----------------------------------------------------------------- // Read Rom and read Ram //u8 PicoReadM68k8_(u32 a); #ifdef _ASM_CD_MEMORY_C -u8 PicoReadM68k8(u32 a); +u32 PicoReadM68k8(u32 a); #else -static u8 PicoReadM68k8(u32 a) +static u32 PicoReadM68k8(u32 a) { u32 d=0; @@ -423,7 +432,7 @@ static u8 PicoReadM68k8(u32 a) if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; d = *(prg_bank+((a^1)&0x1ffff)); goto end; @@ -461,17 +470,17 @@ static u8 PicoReadM68k8(u32 a) #ifdef __debug_io dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc); #endif - return (u8)d; + return d; } #endif #ifdef _ASM_CD_MEMORY_C -u16 PicoReadM68k16(u32 a); +u32 PicoReadM68k16(u32 a); #else -static u16 PicoReadM68k16(u32 a) +static u32 PicoReadM68k16(u32 a) { - u16 d=0; + u32 d=0; if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram @@ -480,9 +489,11 @@ static u16 PicoReadM68k16(u32 a) if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; + wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc); d = *(u16 *)(prg_bank+(a&0x1fffe)); + wrdprintf("ret = %04x", d); goto end; } @@ -506,7 +517,7 @@ static u16 PicoReadM68k16(u32 a) if ((a&0xffffc0)==0xa12000) rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc); - d = (u16)OtherRead16(a, 16); + d = OtherRead16(a, 16); if ((a&0xffffc0)==0xa12000) rdprintf("ret = %04x", d); @@ -535,7 +546,7 @@ static u32 PicoReadM68k32(u32 a) if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; u16 *pm=(u16 *)(prg_bank+(a&0x1fffe)); d = (pm[0]<<16)|pm[1]; @@ -583,7 +594,6 @@ static u32 PicoReadM68k32(u32 a) // ----------------------------------------------------------------- -// Write Ram #ifdef _ASM_CD_MEMORY_C void PicoWriteM68k8(u32 a,u8 d); @@ -605,7 +615,7 @@ static void PicoWriteM68k8(u32 a,u8 d) a&=0xffffff; // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; *(u8 *)(prg_bank+((a^1)&0x1ffff))=d; return; @@ -627,8 +637,11 @@ static void PicoWriteM68k8(u32 a,u8 d) return; } - if ((a&0xffffc0)==0xa12000) + if ((a&0xffffc0)==0xa12000) { rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc); + m68k_reg_write8(a, d); + return; + } OtherWrite8(a,d,8); } @@ -653,8 +666,9 @@ static void PicoWriteM68k16(u32 a,u16 d) a&=0xfffffe; // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; + wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc); *(u16 *)(prg_bank+(a&0x1fffe))=d; return; } @@ -682,8 +696,8 @@ static void PicoWriteM68k16(u32 a,u16 d) Pico_mcd->s68k_regs[0xe] = d >> 8; #ifdef USE_POLL_DETECT if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) { - SekSetStopS68k(0); s68k_poll_adclk = -1; - //printf("%05i:%03i: s68k poll release, a=%02x\n", Pico.m.frame_count, Pico.m.scanline, a); + SekSetStopS68k(0); s68k_poll_adclk = 0; + plprintf("s68k poll release, a=%02x\n", a); } #endif return; @@ -718,7 +732,7 @@ static void PicoWriteM68k32(u32 a,u32 d) a&=0xfffffe; // prg RAM - if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) { + if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) { u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6]; u16 *pm=(u16 *)(prg_bank+(a&0x1fffe)); pm[0]=(u16)(d>>16); pm[1]=(u16)d; @@ -750,8 +764,10 @@ static void PicoWriteM68k32(u32 a,u32 d) return; } - if ((a&0xffffc0)==0xa12000) + if ((a&0xffffc0)==0xa12000) { rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc); + if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f); + } OtherWrite16(a, (u16)(d>>16)); OtherWrite16(a+2,(u16)d); @@ -759,12 +775,14 @@ static void PicoWriteM68k32(u32 a,u32 d) #endif +// ----------------------------------------------------------------- +// S68k // ----------------------------------------------------------------- #ifdef _ASM_CD_MEMORY_C -u8 PicoReadS68k8(u32 a); +u32 PicoReadS68k8(u32 a); #else -static u8 PicoReadS68k8(u32 a) +static u32 PicoReadS68k8(u32 a) { u32 d=0; @@ -780,7 +798,13 @@ static u8 PicoReadS68k8(u32 a) if ((a&0xfffe00) == 0xff8000) { a &= 0x1ff; rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); - if (a >= 0x58 && a < 0x68) + if (a >= 0x0e && a < 0x30) { + d = Pico_mcd->s68k_regs[a]; + s68k_poll_detect(a, d); + rdprintf("ret = %02x", (u8)d); + goto end; + } + else if (a >= 0x58 && a < 0x68) d = gfx_cd_read(a&~1); else d = s68k_reg_read16(a&~1); if ((a&1)==0) d>>=8; @@ -846,16 +870,15 @@ static u8 PicoReadS68k8(u32 a) #ifdef __debug_io2 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k); #endif - return (u8)d; + return d; } #endif -//u16 PicoReadS68k16_(u32 a); #ifdef _ASM_CD_MEMORY_C -u16 PicoReadS68k16(u32 a); +u32 PicoReadS68k16(u32 a); #else -static u16 PicoReadS68k16(u32 a) +static u32 PicoReadS68k16(u32 a) { u32 d=0; @@ -863,7 +886,9 @@ static u16 PicoReadS68k16(u32 a) // prg RAM if (a < 0x80000) { + wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k); d = *(u16 *)(Pico_mcd->prg_ram+a); + wrdprintf("ret = %04x", d); goto end; } @@ -979,7 +1004,6 @@ static u32 PicoReadS68k32(u32 a) d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16; d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff]; d |= d << 4; d &= 0x0f0f0f0f; - dprintf("FIXME: decode"); } else { // allow access in any mode, like Gens does u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1]; @@ -1002,7 +1026,7 @@ static u32 PicoReadS68k32(u32 a) // PCM if ((a&0xff8000)==0xff0000) { - dprintf("FIXME: s68k_pcm r32: [%06x] @%06x", a, SekPcS68k); + dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k); a &= 0x7fff; if (a >= 0x2000) { a >>= 1; @@ -1058,8 +1082,6 @@ static void decode_write8(u32 a, u8 d, int r3) d &= 0x0f; if (!(a&1)) d <<= 4; - //dprintf("FIXME: decode, r3 = %02x", r3); - if (r3 == 8) { if ((!(*pd & (~oldmask))) && d) goto do_it; } else if (r3 > 8) { @@ -1097,15 +1119,11 @@ static void decode_write16(u32 a, u16 d, int r3) } else { *pd = d; } - - //dprintf("FIXME: decode"); } #endif // ----------------------------------------------------------------- -//void PicoWriteS68k8_(u32 a,u8 d); -//void PicoWriteS68k8__(u32 a,u8 d); #ifdef _ASM_CD_MEMORY_C void PicoWriteS68k8(u32 a,u8 d); #else @@ -1116,21 +1134,11 @@ static void PicoWriteS68k8(u32 a,u8 d) #endif a&=0xffffff; -#if 0 - PicoWriteS68k8_(a, d); -/* if ((a&0xfc0000)!=0x080000) { - PicoWriteS68k8_(a, d); - return; - } - printf("r3: %02x\n", Pico_mcd->s68k_regs[3]); - PicoWriteS68k8__(a,d);*/ - return; -#endif // prg RAM if (a < 0x80000) { u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1)); - *pm=d; + if (a >= (Pico_mcd->s68k_regs[2]<<8)) *pm=d; return; } @@ -1205,7 +1213,9 @@ static void PicoWriteS68k16(u32 a,u16 d) // prg RAM if (a < 0x80000) { - *(u16 *)(Pico_mcd->prg_ram+a)=d; + wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k); + if (a >= (Pico_mcd->s68k_regs[2]<<8)) // needed for Dungeon Explorer + *(u16 *)(Pico_mcd->prg_ram+a)=d; return; } @@ -1289,8 +1299,10 @@ static void PicoWriteS68k32(u32 a,u32 d) // prg RAM if (a < 0x80000) { - u16 *pm=(u16 *)(Pico_mcd->prg_ram+a); - pm[0]=(u16)(d>>16); pm[1]=(u16)d; + if (a >= (Pico_mcd->s68k_regs[2]<<8)) { + u16 *pm=(u16 *)(Pico_mcd->prg_ram+a); + pm[0]=(u16)(d>>16); pm[1]=(u16)d; + } return; } @@ -1302,6 +1314,7 @@ static void PicoWriteS68k32(u32 a,u32 d) gfx_cd_write16(a, d>>16); gfx_cd_write16(a+2, d&0xffff); } else { + if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f); s68k_reg_write8(a, d>>24); s68k_reg_write8(a+1,(d>>16)&0xff); s68k_reg_write8(a+2,(d>>8) &0xff); @@ -1443,7 +1456,7 @@ static u32 PicoCheckPcS68k(u32 pc) #endif -void PicoMemSetupCD() +PICO_INTERNAL void PicoMemSetupCD(void) { dprintf("PicoMemSetupCD()"); #ifdef EMU_C68K