X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=pico%2Fcd%2Fmemory.c;h=b15e9c8a04e323539849e04679380ce28b09311e;hb=e71fae1f13fa9cb16b435c18edb5e1505b18e592;hp=82e6d6ddc8bc74977ffd8b70417d644467deed57;hpb=08769494e89920b5987f10c9d15e33e4e0110930;p=picodrive.git diff --git a/pico/cd/memory.c b/pico/cd/memory.c index 82e6d6d..b15e9c8 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -65,39 +65,41 @@ void PicoWriteS68k16_dec_m1b1(u32 a, u32 d); void PicoWriteS68k16_dec_m2b1(u32 a, u32 d); #endif -static void remap_prg_window(int r3); -static void remap_word_ram(int r3); +static void remap_prg_window(u32 r1, u32 r3); +static void remap_word_ram(u32 r3); // poller detection #define POLL_LIMIT 16 -#define POLL_CYCLES 124 +#define POLL_CYCLES 64 -u32 m68k_comm_check(u32 a, u32 d) +void m68k_comm_check(u32 a) { pcd_sync_s68k(SekCyclesDone(), 0); if (a != Pico_mcd->m.m68k_poll_a) { Pico_mcd->m.m68k_poll_a = a; Pico_mcd->m.m68k_poll_cnt = 0; - return d; + return; } Pico_mcd->m.m68k_poll_cnt++; - return d; } #ifndef _ASM_CD_MEMORY_C static u32 m68k_reg_read16(u32 a) { - u32 d=0; + u32 d = 0; a &= 0x3e; switch (a) { case 0: - d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens + // here IFL2 is always 0, just like in Gens + d = ((Pico_mcd->s68k_regs[0x33] << 13) & 0x8000) + | Pico_mcd->m.busreq; goto end; case 2: + m68k_comm_check(a); d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7); elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc); - goto end_comm; + goto end; case 4: d = Pico_mcd->s68k_regs[4]<<8; goto end; @@ -121,17 +123,15 @@ static u32 m68k_reg_read16(u32 a) if (a < 0x30) { // comm flag/cmd/status (0xE-0x2F) + m68k_comm_check(a); d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1]; - goto end_comm; + goto end; } elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a); end: return d; - -end_comm: - return m68k_comm_check(a, d); } #endif @@ -143,9 +143,6 @@ void m68k_reg_write8(u32 a, u32 d) u32 dold; a &= 0x3f; - Pico_mcd->m.m68k_poll_a = - Pico_mcd->m.m68k_poll_cnt = 0; - switch (a) { case 0: d &= 1; @@ -157,23 +154,26 @@ void m68k_reg_write8(u32 a, u32 d) return; case 1: d &= 3; - elprintf(EL_CDREGS, "d m.busreq %u %u", d, Pico_mcd->m.busreq); - if (d == Pico_mcd->m.busreq) + dold = Pico_mcd->m.busreq; + if (!(d & 1)) + d |= 2; // verified: can't release bus on reset + if (dold == d) return; + pcd_sync_s68k(SekCyclesDone(), 0); - if ((Pico_mcd->m.busreq ^ d) & 1) { + if ((dold ^ d) & 1) elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1)); - if (!(d & 1)) - d |= 2; // verified: reset also gives bus - else { - elprintf(EL_CDREGS, "m68k: resetting s68k"); - SekResetS68k(); - } + if (!(d & 1)) + Pico_mcd->m.state_flags |= PCD_ST_S68K_RST; + else if (d == 1 && (Pico_mcd->m.state_flags & PCD_ST_S68K_RST)) { + Pico_mcd->m.state_flags &= ~PCD_ST_S68K_RST; + elprintf(EL_CDREGS, "m68k: resetting s68k"); + SekResetS68k(); } - if ((Pico_mcd->m.busreq ^ d) & 2) { + if ((dold ^ d) & 2) { elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1); - remap_prg_window(Pico_mcd->s68k_regs[3]); + remap_prg_window(d, Pico_mcd->s68k_regs[3]); } Pico_mcd->m.busreq = d; return; @@ -184,24 +184,24 @@ void m68k_reg_write8(u32 a, u32 d) case 3: dold = Pico_mcd->s68k_regs[3]; elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc); - //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2); - //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") : - // ((d&2) ? "word ram to s68k" : "word ram to m68k")); - if (dold & 4) { // 1M mode - d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing - } else { - if ((d ^ dold) & d & 2) { // DMNA is being set - dold &= ~1; // return word RAM to s68k - /* Silpheed hack: bset(w3), r3, btst, bne, r3 */ - SekEndRun(20+16+10+12+16); - } - } - d = (d & 0xc2) | (dold & 0x1f); if ((d ^ dold) & 0xc0) { elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); - remap_prg_window(d); + remap_prg_window(Pico_mcd->m.busreq, d); + } + + // 2M mode state is tracked regardless of current mode + if (d & 2) { + Pico_mcd->m.dmna_ret_2m |= 2; + Pico_mcd->m.dmna_ret_2m &= ~1; } + if (dold & 4) { // 1M mode + d ^= 2; // 0 sets DMNA, 1 does nothing + d = (d & 0xc2) | (dold & 0x1f); + } + else + d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m; + goto write_comm; case 6: Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer @@ -212,7 +212,6 @@ void m68k_reg_write8(u32 a, u32 d) ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]); return; case 0x0f: - d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case) a = 0x0e; case 0x0e: goto write_comm; @@ -228,18 +227,17 @@ write_comm: if (d == Pico_mcd->s68k_regs[a]) return; - Pico_mcd->s68k_regs[a] = d; pcd_sync_s68k(SekCyclesDone(), 0); - if (Pico_mcd->m.s68k_poll_a == a && Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) { + Pico_mcd->s68k_regs[a] = d; + if (Pico_mcd->m.s68k_poll_a == (a & ~1) + && Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) + { SekSetStopS68k(0); Pico_mcd->m.s68k_poll_a = 0; elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a); } } -#ifndef _ASM_CD_MEMORY_C -static -#endif u32 s68k_poll_detect(u32 a, u32 d) { #ifdef USE_POLL_DETECT @@ -255,7 +253,7 @@ u32 s68k_poll_detect(u32 a, u32 d) //printf("-- diff: %u, cnt = %i\n", clkdiff, cnt); if (Pico_mcd->m.s68k_poll_cnt > POLL_LIMIT) { SekSetStopS68k(1); - elprintf(EL_CDPOLL, "s68k poll detected @ %06x, a=%02x", + elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x", SekPcS68k, a); } } @@ -343,35 +341,34 @@ void s68k_reg_write8(u32 a, u32 d) elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k); d &= 0x1d; d |= dold & 0xc2; + + // 2M mode state + if (d & 1) { + Pico_mcd->m.dmna_ret_2m |= 1; + Pico_mcd->m.dmna_ret_2m &= ~2; // DMNA clears + } + if (d & 4) { - if ((d ^ dold) & 0x1d) { - d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit - remap_word_ram(d); - } if (!(dold & 4)) { elprintf(EL_CDREG3, "wram mode 2M->1M"); wram_2M_to_1M(Pico_mcd->word_ram2M); } + + if ((d ^ dold) & 0x1d) + remap_word_ram(d); + + if ((d ^ dold) & 0x05) + d &= ~2; // clear DMNA - swap complete } else { if (dold & 4) { elprintf(EL_CDREG3, "wram mode 1M->2M"); - if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k - d &= ~3; - d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode - } wram_1M_to_2M(Pico_mcd->word_ram2M); remap_word_ram(d); } - // s68k can only set RET, writing 0 has no effect - else if ((dold ^ d) & d & 1) { // RET being set - SekEndRunS68k(20+16+10+12+16); // see DMNA case - } else - d |= dold & 1; - if (d & 1) - d &= ~2; // DMNA clears + d = (d & ~3) | Pico_mcd->m.dmna_ret_2m; } goto write_comm; } @@ -395,8 +392,6 @@ void s68k_reg_write8(u32 a, u32 d) Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k(); return; case 0x0e: - d &= 0xff; - d = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair a = 0x0f; case 0x0f: goto write_comm; @@ -556,12 +551,14 @@ static void PicoWriteM68k8_ramc(u32 a, u32 d) return; } - elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); + elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", + a, d & 0xff, SekPc); } static void PicoWriteM68k16_ramc(u32 a, u32 d) { - elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x", a, d, SekPcS68k); + elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x", + a, d, SekPcS68k); PicoWriteM68k8_ramc(a + 1, d); } @@ -575,7 +572,8 @@ static u32 PicoReadM68k8_io(u32 a) if (!(a & 1)) d >>= 8; d &= 0xff; - elprintf(EL_CDREGS, "m68k_regs r8: [%02x] %02x @%06x", a & 0x3f, d, SekPc); + elprintf(EL_CDREGS, "m68k_regs r8: [%02x] %02x @%06x", + a & 0x3f, d, SekPc); return d; } @@ -588,7 +586,8 @@ static u32 PicoReadM68k16_io(u32 a) u32 d; if ((a & 0xff00) == 0x2000) { d = m68k_reg_read16(a); - elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x", a & 0x3f, d, SekPc); + elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x", + a & 0x3f, d, SekPc); return d; } @@ -598,7 +597,8 @@ static u32 PicoReadM68k16_io(u32 a) static void PicoWriteM68k8_io(u32 a, u32 d) { if ((a & 0xff00) == 0x2000) { // a12000 - a120ff - elprintf(EL_CDREGS, "m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc); + elprintf(EL_CDREGS, "m68k_regs w8: [%02x] %02x @%06x", + a & 0x3f, d, SekPc); m68k_reg_write8(a, d); return; } @@ -609,7 +609,8 @@ static void PicoWriteM68k8_io(u32 a, u32 d) static void PicoWriteM68k16_io(u32 a, u32 d) { if ((a & 0xff00) == 0x2000) { // a12000 - a120ff - elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc); + elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x", + a & 0x3f, d, SekPc); m68k_reg_write8(a, d >> 8); if ((a & 0x3e) != 0x0e) // special case @@ -639,25 +640,27 @@ static u32 s68k_unmapped_read16(u32 a) static void s68k_unmapped_write8(u32 a, u32 d) { - elprintf(EL_UIO, "s68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); + elprintf(EL_UIO, "s68k unmapped w8 [%06x] %02x @%06x", + a, d & 0xff, SekPc); } static void s68k_unmapped_write16(u32 a, u32 d) { - elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); + elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x", + a, d & 0xffff, SekPc); } -// PRG RAM protected range (000000 - 00ff00)? +// PRG RAM protected range (000000 - 01fdff)? // XXX verify: ff00 or 1fe00 max? static void PicoWriteS68k8_prgwp(u32 a, u32 d) { - if (a >= (Pico_mcd->s68k_regs[2] << 8)) + if (a >= (Pico_mcd->s68k_regs[2] << 9)) Pico_mcd->prg_ram[a ^ 1] = d; } static void PicoWriteS68k16_prgwp(u32 a, u32 d) { - if (a >= (Pico_mcd->s68k_regs[2] << 8)) + if (a >= (Pico_mcd->s68k_regs[2] << 9)) *(u16 *)(Pico_mcd->prg_ram + a) = d; } @@ -806,20 +809,22 @@ static u32 PicoReadS68k8_pr(u32 a) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1ff; - elprintf(EL_CDREGS, "s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); if (a >= 0x0e && a < 0x30) { d = Pico_mcd->s68k_regs[a]; - s68k_poll_detect(a, d); - elprintf(EL_CDREGS, "ret = %02x", (u8)d); - return d; + s68k_poll_detect(a & ~1, d); + goto regs_done; } else if (a >= 0x58 && a < 0x68) d = gfx_cd_read(a & ~1); else d = s68k_reg_read16(a & ~1); if (!(a & 1)) d >>= 8; - elprintf(EL_CDREGS, "ret = %02x", (u8)d); - return d & 0xff; + +regs_done: + d &= 0xff; + elprintf(EL_CDREGS, "s68k_regs r8: [%02x] %02x @%06x", + a, d, SekPcS68k); + return d; } // PCM @@ -847,11 +852,12 @@ static u32 PicoReadS68k16_pr(u32 a) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1fe; - elprintf(EL_CDREGS, "s68k_regs r16: [%02x] @ %06x", a, SekPcS68k); if (0x58 <= a && a < 0x68) d = gfx_cd_read(a); else d = s68k_reg_read16(a); - elprintf(EL_CDREGS, "ret = %04x", d); + + elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @%06x", + a, d, SekPcS68k); return d; } @@ -878,7 +884,7 @@ static void PicoWriteS68k8_pr(u32 a, u32 d) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1ff; - elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k); + elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @%06x", a, d, SekPcS68k); if (0x58 <= a && a < 0x68) gfx_cd_write16(a&~1, (d<<8)|d); else s68k_reg_write8(a,d); @@ -903,7 +909,7 @@ static void PicoWriteS68k16_pr(u32 a, u32 d) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1fe; - elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k); + elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @%06x", a, d, SekPcS68k); if (a >= 0x58 && a < 0x68) gfx_cd_write16(a, d); else { @@ -954,11 +960,11 @@ static const void *s68k_dec_write16[2][4] = { // ----------------------------------------------------------------- -static void remap_prg_window(int r3) +static void remap_prg_window(u32 r1, u32 r3) { // PRG RAM - if (Pico_mcd->m.busreq & 2) { - void *bank = Pico_mcd->prg_ram_b[r3 >> 6]; + if (r1 & 2) { + void *bank = Pico_mcd->prg_ram_b[(r3 >> 6) & 3]; cpu68k_map_all_ram(0x020000, 0x03ffff, bank, 0); } else { @@ -966,7 +972,7 @@ static void remap_prg_window(int r3) } } -static void remap_word_ram(int r3) +static void remap_word_ram(u32 r3) { void *bank; @@ -1017,13 +1023,14 @@ static void remap_word_ram(int r3) void pcd_state_loaded_mem(void) { - int r3 = Pico_mcd->s68k_regs[3]; + u32 r3 = Pico_mcd->s68k_regs[3]; /* after load events */ if (r3 & 4) // 1M mode? wram_2M_to_1M(Pico_mcd->word_ram2M); remap_word_ram(r3); - remap_prg_window(r3); + remap_prg_window(Pico_mcd->m.busreq, r3); + Pico_mcd->m.dmna_ret_2m &= 3; // restore hint vector *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector; @@ -1064,8 +1071,8 @@ PICO_INTERNAL void PicoMemSetupCD(void) cpu68k_map_set(s68k_read16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); cpu68k_map_set(s68k_write8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 0); - cpu68k_map_set(s68k_write8_map, 0x000000, 0x00ffff, PicoWriteS68k8_prgwp, 1); - cpu68k_map_set(s68k_write16_map, 0x000000, 0x00ffff, PicoWriteS68k16_prgwp, 1); + cpu68k_map_set(s68k_write8_map, 0x000000, 0x01ffff, PicoWriteS68k8_prgwp, 1); + cpu68k_map_set(s68k_write16_map, 0x000000, 0x01ffff, PicoWriteS68k16_prgwp, 1); // BRAM cpu68k_map_set(s68k_read8_map, 0xfe0000, 0xfeffff, PicoReadS68k8_bram, 1);