mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
mcd, some cleanup, fix Word-RAM in 2M mode
This commit is contained in:
parent
02db230830
commit
8eeb342641
7 changed files with 227 additions and 75 deletions
|
@ -91,31 +91,6 @@ PICO_INTERNAL int PicoResetMCD(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SekRunM68kOnce(void)
|
|
||||||
{
|
|
||||||
int cyc_do;
|
|
||||||
pevt_log_m68k_o(EVT_RUN_START);
|
|
||||||
|
|
||||||
if ((cyc_do = Pico.t.m68c_aim - Pico.t.m68c_cnt) > 0) {
|
|
||||||
Pico.t.m68c_cnt += cyc_do;
|
|
||||||
|
|
||||||
#if defined(EMU_C68K)
|
|
||||||
PicoCpuCM68k.cycles = cyc_do;
|
|
||||||
CycloneRun(&PicoCpuCM68k);
|
|
||||||
Pico.t.m68c_cnt -= PicoCpuCM68k.cycles;
|
|
||||||
#elif defined(EMU_M68K)
|
|
||||||
Pico.t.m68c_cnt += m68k_execute(cyc_do) - cyc_do;
|
|
||||||
#elif defined(EMU_F68K)
|
|
||||||
Pico.t.m68c_cnt += fm68k_emulate(&PicoCpuFM68k, cyc_do, 0) - cyc_do;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
SekCyclesLeft = 0;
|
|
||||||
|
|
||||||
SekTrace(0);
|
|
||||||
pevt_log_m68k_o(EVT_RUN_END);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SekRunS68k(unsigned int to)
|
static void SekRunS68k(unsigned int to)
|
||||||
{
|
{
|
||||||
int cyc_do;
|
int cyc_do;
|
||||||
|
@ -281,8 +256,7 @@ void pcd_irq_s68k(int irq, int state)
|
||||||
{
|
{
|
||||||
if (state) {
|
if (state) {
|
||||||
SekInterruptS68k(irq);
|
SekInterruptS68k(irq);
|
||||||
if (SekIsStoppedS68k())
|
Pico_mcd->m.state_flags &= ~(PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP);
|
||||||
SekSetStopS68k(0);
|
|
||||||
Pico_mcd->m.s68k_poll_cnt = 0;
|
Pico_mcd->m.s68k_poll_cnt = 0;
|
||||||
} else
|
} else
|
||||||
SekInterruptClearS68k(irq);
|
SekInterruptClearS68k(irq);
|
||||||
|
@ -315,7 +289,7 @@ int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync)
|
||||||
if (event_time_next && CYCLES_GT(target, event_time_next))
|
if (event_time_next && CYCLES_GT(target, event_time_next))
|
||||||
target = event_time_next;
|
target = event_time_next;
|
||||||
|
|
||||||
if (SekIsStoppedS68k())
|
if (Pico_mcd->m.state_flags & (PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP))
|
||||||
SekCycleCntS68k = SekCycleAimS68k = target;
|
SekCycleCntS68k = SekCycleAimS68k = target;
|
||||||
else
|
else
|
||||||
SekRunS68k(target);
|
SekRunS68k(target);
|
||||||
|
@ -331,40 +305,42 @@ int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync)
|
||||||
#define pcd_run_cpus_normal pcd_run_cpus
|
#define pcd_run_cpus_normal pcd_run_cpus
|
||||||
//#define pcd_run_cpus_lockstep pcd_run_cpus
|
//#define pcd_run_cpus_lockstep pcd_run_cpus
|
||||||
|
|
||||||
static void SekSyncM68k(void);
|
static int SekSyncM68k(int once);
|
||||||
|
|
||||||
void pcd_run_cpus_normal(int m68k_cycles)
|
void pcd_run_cpus_normal(int m68k_cycles)
|
||||||
{
|
{
|
||||||
Pico.t.m68c_aim += m68k_cycles;
|
Pico.t.m68c_aim += m68k_cycles;
|
||||||
|
|
||||||
while (CYCLES_GT(Pico.t.m68c_aim, Pico.t.m68c_cnt)) {
|
while (CYCLES_GT(Pico.t.m68c_aim, Pico.t.m68c_cnt)) {
|
||||||
if (SekShouldInterrupt())
|
if (SekShouldInterrupt()) {
|
||||||
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;
|
||||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_POLL_DETECT
|
#ifdef USE_POLL_DETECT
|
||||||
if (Pico_mcd->m.m68k_poll_cnt >= 16) {
|
if (Pico_mcd->m.state_flags & (PCD_ST_M68K_POLL|PCD_ST_M68K_SLEEP)) {
|
||||||
int s68k_left;
|
int s68k_left;
|
||||||
// main CPU is polling, (wake and) run sub only
|
// main CPU is polling, (wake and) run sub only
|
||||||
if (SekIsStoppedS68k()) {
|
Pico_mcd->m.state_flags &= ~(PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP);
|
||||||
SekSetStopS68k(0);
|
Pico_mcd->m.s68k_poll_cnt = 0;
|
||||||
Pico_mcd->m.s68k_poll_cnt = 0;
|
|
||||||
}
|
|
||||||
s68k_left = pcd_sync_s68k(Pico.t.m68c_aim, 1);
|
s68k_left = pcd_sync_s68k(Pico.t.m68c_aim, 1);
|
||||||
|
|
||||||
Pico.t.m68c_cnt = Pico.t.m68c_aim;
|
Pico.t.m68c_cnt = Pico.t.m68c_aim;
|
||||||
if (s68k_left > 0)
|
if (s68k_left > 0)
|
||||||
Pico.t.m68c_cnt -= ((long long)s68k_left * mcd_s68k_cycle_mult >> 16);
|
Pico.t.m68c_cnt -= ((long long)s68k_left * mcd_s68k_cycle_mult >> 16);
|
||||||
if (SekIsStoppedS68k()) {
|
if (Pico_mcd->m.state_flags & (PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP)) {
|
||||||
// slave has stopped, wake master to avoid lockups
|
// slave has stopped, wake master to avoid lockups
|
||||||
|
Pico_mcd->m.state_flags &= ~(PCD_ST_M68K_POLL|PCD_ST_M68K_SLEEP);
|
||||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
elprintf(EL_CDPOLL, "m68k poll [%02x] x%d @%06x",
|
elprintf(EL_CDPOLL, "m68k poll [%02x] x%d @%06x",
|
||||||
Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc);
|
Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
SekRunM68kOnce();
|
SekSyncM68k(1);
|
||||||
if (Pico_mcd->m.need_sync) {
|
if (Pico_mcd->m.state_flags & PCD_ST_S68K_SYNC) {
|
||||||
Pico_mcd->m.need_sync = 0;
|
Pico_mcd->m.state_flags &= ~PCD_ST_S68K_SYNC;
|
||||||
pcd_sync_s68k(Pico.t.m68c_cnt, 0);
|
pcd_sync_s68k(Pico.t.m68c_cnt, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,7 +351,7 @@ void pcd_run_cpus_lockstep(int m68k_cycles)
|
||||||
unsigned int target = Pico.t.m68c_aim + m68k_cycles;
|
unsigned int target = Pico.t.m68c_aim + m68k_cycles;
|
||||||
do {
|
do {
|
||||||
Pico.t.m68c_aim += 8;
|
Pico.t.m68c_aim += 8;
|
||||||
SekSyncM68k();
|
SekSyncM68k(0);
|
||||||
pcd_sync_s68k(Pico.t.m68c_aim, 0);
|
pcd_sync_s68k(Pico.t.m68c_aim, 0);
|
||||||
} while (CYCLES_GT(target, Pico.t.m68c_aim));
|
} while (CYCLES_GT(target, Pico.t.m68c_aim));
|
||||||
|
|
||||||
|
@ -438,6 +414,11 @@ void pcd_state_loaded(void)
|
||||||
if ((unsigned int)diff > 12500000/50)
|
if ((unsigned int)diff > 12500000/50)
|
||||||
Pico_mcd->pcm.update_cycles = cycles;
|
Pico_mcd->pcm.update_cycles = cycles;
|
||||||
|
|
||||||
|
if (Pico_mcd->m.need_sync) {
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SYNC;
|
||||||
|
Pico_mcd->m.need_sync = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// reschedule
|
// reschedule
|
||||||
event_time_next = 0;
|
event_time_next = 0;
|
||||||
pcd_run_events(SekCycleCntS68k);
|
pcd_run_events(SekCycleCntS68k);
|
||||||
|
|
135
pico/cd/memory.c
135
pico/cd/memory.c
|
@ -71,11 +71,11 @@ void m68k_comm_check(u32 a)
|
||||||
u32 cycles = SekCyclesDone();
|
u32 cycles = SekCyclesDone();
|
||||||
u32 clkdiff = cycles - Pico_mcd->m.m68k_poll_clk;
|
u32 clkdiff = cycles - Pico_mcd->m.m68k_poll_clk;
|
||||||
pcd_sync_s68k(cycles, 0);
|
pcd_sync_s68k(cycles, 0);
|
||||||
if (a == 0x0e && !Pico_mcd->m.need_sync && (Pico_mcd->s68k_regs[3]&0x4)) {
|
if (a == 0x0e && !(Pico_mcd->m.state_flags & PCD_ST_S68K_SYNC) && (Pico_mcd->s68k_regs[3]&0x4)) {
|
||||||
// there are cases when slave updates comm and only switches RAM
|
// there are cases when slave updates comm and only switches RAM
|
||||||
// over after that (mcd1 bios), so there must be a resync..
|
// over after that (mcd1 bios), so there must be a resync..
|
||||||
SekEndRun(64);
|
SekEndRun(64);
|
||||||
Pico_mcd->m.need_sync = 1;
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SYNC;
|
||||||
}
|
}
|
||||||
Pico_mcd->m.m68k_poll_clk = cycles;
|
Pico_mcd->m.m68k_poll_clk = cycles;
|
||||||
if (SekNotPolling || a != Pico_mcd->m.m68k_poll_a || clkdiff > POLL_CYCLES || clkdiff <= 16) {
|
if (SekNotPolling || a != Pico_mcd->m.m68k_poll_a || clkdiff > POLL_CYCLES || clkdiff <= 16) {
|
||||||
|
@ -85,8 +85,11 @@ void m68k_comm_check(u32 a)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Pico_mcd->m.m68k_poll_cnt++;
|
Pico_mcd->m.m68k_poll_cnt++;
|
||||||
if(Pico_mcd->m.m68k_poll_cnt >= POLL_LIMIT)
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;
|
||||||
|
if (Pico_mcd->m.m68k_poll_cnt >= POLL_LIMIT) {
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_M68K_POLL;
|
||||||
SekEndRun(8);
|
SekEndRun(8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _ASM_CD_MEMORY_C
|
#ifndef _ASM_CD_MEMORY_C
|
||||||
|
@ -149,6 +152,7 @@ void m68k_reg_write8(u32 a, u32 d)
|
||||||
u32 dold;
|
u32 dold;
|
||||||
a &= 0x3f;
|
a &= 0x3f;
|
||||||
|
|
||||||
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;
|
||||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||||
|
|
||||||
switch (a) {
|
switch (a) {
|
||||||
|
@ -208,6 +212,8 @@ void m68k_reg_write8(u32 a, u32 d)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;
|
d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;
|
||||||
|
if ((dold ^ d) & 0x1f)
|
||||||
|
remap_word_ram(d);
|
||||||
|
|
||||||
goto write_comm;
|
goto write_comm;
|
||||||
case 6:
|
case 6:
|
||||||
|
@ -243,12 +249,10 @@ write_comm:
|
||||||
// Delay slave a bit to make sure master can check before slave changes.
|
// Delay slave a bit to make sure master can check before slave changes.
|
||||||
SekCycleCntS68k += 24; // Silpheed
|
SekCycleCntS68k += 24; // Silpheed
|
||||||
}
|
}
|
||||||
if (Pico_mcd->m.s68k_poll_a == (a & ~1))
|
if ((Pico_mcd->m.s68k_poll_a ^ a) & ~1) {
|
||||||
{
|
if (Pico_mcd->m.state_flags & PCD_ST_S68K_POLL)
|
||||||
if (SekIsStoppedS68k()) {
|
|
||||||
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
|
elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);
|
||||||
SekSetStopS68k(0);
|
Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;
|
||||||
}
|
|
||||||
Pico_mcd->m.s68k_poll_cnt = 0;
|
Pico_mcd->m.s68k_poll_cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,7 +261,7 @@ u32 s68k_poll_detect(u32 a, u32 d)
|
||||||
{
|
{
|
||||||
#ifdef USE_POLL_DETECT
|
#ifdef USE_POLL_DETECT
|
||||||
u32 cycles, cnt = 0;
|
u32 cycles, cnt = 0;
|
||||||
if (SekIsStoppedS68k())
|
if (Pico_mcd->m.state_flags & (PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP))
|
||||||
return d;
|
return d;
|
||||||
SekEndRunS68k(8);
|
SekEndRunS68k(8);
|
||||||
|
|
||||||
|
@ -267,8 +271,9 @@ u32 s68k_poll_detect(u32 a, u32 d)
|
||||||
if (clkdiff <= POLL_CYCLES) {
|
if (clkdiff <= POLL_CYCLES) {
|
||||||
cnt = Pico_mcd->m.s68k_poll_cnt + 1;
|
cnt = Pico_mcd->m.s68k_poll_cnt + 1;
|
||||||
//printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);
|
//printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);
|
||||||
|
Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;
|
||||||
if (cnt > POLL_LIMIT) {
|
if (cnt > POLL_LIMIT) {
|
||||||
SekSetStopS68k(1);
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_POLL;
|
||||||
elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x",
|
elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x",
|
||||||
SekPcS68k, a);
|
SekPcS68k, a);
|
||||||
}
|
}
|
||||||
|
@ -376,9 +381,6 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
wram_2M_to_1M(Pico_mcd->word_ram2M);
|
wram_2M_to_1M(Pico_mcd->word_ram2M);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((d ^ dold) & 0x1d)
|
|
||||||
remap_word_ram(d);
|
|
||||||
|
|
||||||
if ((d ^ dold) & 0x05)
|
if ((d ^ dold) & 0x05)
|
||||||
d &= ~2; // clear DMNA - swap complete
|
d &= ~2; // clear DMNA - swap complete
|
||||||
}
|
}
|
||||||
|
@ -387,10 +389,11 @@ void s68k_reg_write8(u32 a, u32 d)
|
||||||
if (dold & 4) {
|
if (dold & 4) {
|
||||||
elprintf(EL_CDREG3, "wram mode 1M->2M");
|
elprintf(EL_CDREG3, "wram mode 1M->2M");
|
||||||
wram_1M_to_2M(Pico_mcd->word_ram2M);
|
wram_1M_to_2M(Pico_mcd->word_ram2M);
|
||||||
remap_word_ram(d);
|
|
||||||
}
|
}
|
||||||
d = (d & ~3) | Pico_mcd->m.dmna_ret_2m;
|
d = (d & ~3) | Pico_mcd->m.dmna_ret_2m;
|
||||||
}
|
}
|
||||||
|
if ((dold ^ d) & 0x1f)
|
||||||
|
remap_word_ram(d);
|
||||||
goto write_comm;
|
goto write_comm;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
|
@ -495,15 +498,18 @@ write_comm:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Pico_mcd->s68k_regs[a] = (u8) d;
|
Pico_mcd->s68k_regs[a] = (u8) d;
|
||||||
if (Pico_mcd->m.m68k_poll_cnt)
|
if ((Pico_mcd->m.m68k_poll_a ^ a) & ~1) {
|
||||||
SekEndRunS68k(8);
|
SekEndRunS68k(8);
|
||||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;
|
||||||
|
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void s68k_reg_write16(u32 a, u32 d)
|
void s68k_reg_write16(u32 a, u32 d)
|
||||||
{
|
{
|
||||||
u8 *r = Pico_mcd->s68k_regs;
|
u8 *r = Pico_mcd->s68k_regs;
|
||||||
|
|
||||||
|
Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;
|
||||||
Pico_mcd->m.s68k_poll_cnt = 0;
|
Pico_mcd->m.s68k_poll_cnt = 0;
|
||||||
|
|
||||||
if ((a & 0x1f0) == 0x20)
|
if ((a & 0x1f0) == 0x20)
|
||||||
|
@ -559,9 +565,11 @@ write_comm:
|
||||||
|
|
||||||
r[a] = d >> 8;
|
r[a] = d >> 8;
|
||||||
r[a + 1] = d;
|
r[a + 1] = d;
|
||||||
if (Pico_mcd->m.m68k_poll_cnt)
|
if ((Pico_mcd->m.m68k_poll_a ^ a) & ~1) {
|
||||||
SekEndRunS68k(8);
|
SekEndRunS68k(8);
|
||||||
Pico_mcd->m.m68k_poll_cnt = 0;
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;
|
||||||
|
Pico_mcd->m.m68k_poll_cnt = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
@ -1065,35 +1073,104 @@ static void remap_prg_window(u32 r1, u32 r3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if main or sub CPU accesses Word-RAM while it is assigned to the other CPU
|
||||||
|
// GA doesn't assert DTACK, which means the CPU is blocked until the Word_RAM
|
||||||
|
// is reassigned to it (e.g. Mega Race).
|
||||||
|
static u32 m68k_wordram_read8(u32 a)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_M68K_SLEEP;
|
||||||
|
SekEndRun(0);
|
||||||
|
return Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 m68k_wordram_read16(u32 a)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_M68K_SLEEP;
|
||||||
|
SekEndRun(0);
|
||||||
|
return ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void m68k_wordram_write8(u32 a, u32 d)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_M68K_SLEEP;
|
||||||
|
SekEndRun(0);
|
||||||
|
Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void m68k_wordram_write16(u32 a, u32 d)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_M68K_SLEEP;
|
||||||
|
SekEndRun(0);
|
||||||
|
((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 s68k_wordram_read8(u32 a)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;
|
||||||
|
SekEndRunS68k(0);
|
||||||
|
return Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 s68k_wordram_read16(u32 a)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;
|
||||||
|
SekEndRunS68k(0);
|
||||||
|
return ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s68k_wordram_write8(u32 a, u32 d)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;
|
||||||
|
SekEndRunS68k(0);
|
||||||
|
Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s68k_wordram_write16(u32 a, u32 d)
|
||||||
|
{
|
||||||
|
Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;
|
||||||
|
SekEndRunS68k(0);
|
||||||
|
((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff] = d;
|
||||||
|
}
|
||||||
|
|
||||||
static void remap_word_ram(u32 r3)
|
static void remap_word_ram(u32 r3)
|
||||||
{
|
{
|
||||||
void *bank;
|
void *bank;
|
||||||
|
|
||||||
// WORD RAM
|
// WORD RAM
|
||||||
if (!(r3 & 4)) {
|
if (!(r3 & 4)) {
|
||||||
// 2M mode. XXX: allowing access in all cases for simplicity
|
// 2M mode.
|
||||||
bank = Pico_mcd->word_ram2M;
|
bank = Pico_mcd->word_ram2M;
|
||||||
cpu68k_map_all_ram(0x200000, 0x23ffff, bank, 0);
|
if (r3 & 1) {
|
||||||
cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);
|
Pico_mcd->m.state_flags &= ~PCD_ST_M68K_SLEEP;
|
||||||
|
cpu68k_map_all_ram(0x200000, 0x23ffff, bank, 0);
|
||||||
|
cpu68k_map_all_funcs(0x80000, 0xbffff,
|
||||||
|
s68k_wordram_read8, s68k_wordram_read16,
|
||||||
|
s68k_wordram_write8, s68k_wordram_write16, 1);
|
||||||
|
} else {
|
||||||
|
Pico_mcd->m.state_flags &= ~PCD_ST_S68K_SLEEP;
|
||||||
|
cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);
|
||||||
|
cpu68k_map_all_funcs(0x200000, 0x23ffff,
|
||||||
|
m68k_wordram_read8, m68k_wordram_read16,
|
||||||
|
m68k_wordram_write8, m68k_wordram_write16, 0);
|
||||||
|
}
|
||||||
// TODO: handle 0x0c0000
|
// TODO: handle 0x0c0000
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int b0 = r3 & 1;
|
int b0 = r3 & 1;
|
||||||
int m = (r3 & 0x18) >> 3;
|
int m = (r3 & 0x18) >> 3;
|
||||||
|
Pico_mcd->m.state_flags &= ~(PCD_ST_M68K_SLEEP|PCD_ST_S68K_SLEEP);
|
||||||
bank = Pico_mcd->word_ram1M[b0];
|
bank = Pico_mcd->word_ram1M[b0];
|
||||||
cpu68k_map_all_ram(0x200000, 0x21ffff, bank, 0);
|
cpu68k_map_all_ram(0x200000, 0x21ffff, bank, 0);
|
||||||
bank = Pico_mcd->word_ram1M[b0 ^ 1];
|
bank = Pico_mcd->word_ram1M[b0 ^ 1];
|
||||||
cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1);
|
cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1);
|
||||||
// "cell arrange" on m68k
|
// "cell arrange" on m68k
|
||||||
cpu68k_map_set(m68k_read8_map, 0x220000, 0x23ffff, m68k_cell_read8[b0], 1);
|
cpu68k_map_all_funcs(0x220000, 0x23ffff,
|
||||||
cpu68k_map_set(m68k_read16_map, 0x220000, 0x23ffff, m68k_cell_read16[b0], 1);
|
m68k_cell_read8[b0], m68k_cell_read16[b0],
|
||||||
cpu68k_map_set(m68k_write8_map, 0x220000, 0x23ffff, m68k_cell_write8[b0], 1);
|
m68k_cell_write8[b0], m68k_cell_write16[b0], 0);
|
||||||
cpu68k_map_set(m68k_write16_map, 0x220000, 0x23ffff, m68k_cell_write16[b0], 1);
|
|
||||||
// "decode format" on s68k
|
// "decode format" on s68k
|
||||||
cpu68k_map_set(s68k_read8_map, 0x080000, 0x0bffff, s68k_dec_read8[b0 ^ 1], 1);
|
cpu68k_map_all_funcs(0x80000, 0xbffff,
|
||||||
cpu68k_map_set(s68k_read16_map, 0x080000, 0x0bffff, s68k_dec_read16[b0 ^ 1], 1);
|
s68k_dec_read8[b0^1], s68k_dec_read16[b0^1],
|
||||||
cpu68k_map_set(s68k_write8_map, 0x080000, 0x0bffff, s68k_dec_write8[b0 ^ 1][m], 1);
|
s68k_dec_write8[b0^1][m], s68k_dec_write16[b0^1][m], 1);
|
||||||
cpu68k_map_set(s68k_write16_map, 0x080000, 0x0bffff, s68k_dec_write16[b0 ^ 1][m], 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,7 @@ m_m68k_read8_r02:
|
||||||
m_m68k_read8_r03:
|
m_m68k_read8_r03:
|
||||||
add r1, r1, #0x110000
|
add r1, r1, #0x110000
|
||||||
stmfd sp!, {r1, lr}
|
stmfd sp!, {r1, lr}
|
||||||
|
bic r0, r0, #1
|
||||||
bl m68k_comm_check
|
bl m68k_comm_check
|
||||||
ldmfd sp!, {r1, lr}
|
ldmfd sp!, {r1, lr}
|
||||||
ldrb r0, [r1, #3]
|
ldrb r0, [r1, #3]
|
||||||
|
@ -223,6 +224,7 @@ m_m68k_read8_hi:
|
||||||
bxge lr
|
bxge lr
|
||||||
add r1, r1, r0
|
add r1, r1, r0
|
||||||
stmfd sp!, {r1, lr}
|
stmfd sp!, {r1, lr}
|
||||||
|
bic r0, r0, #1
|
||||||
bl m68k_comm_check
|
bl m68k_comm_check
|
||||||
ldmfd sp!, {r1, lr}
|
ldmfd sp!, {r1, lr}
|
||||||
ldrb r0, [r1]
|
ldrb r0, [r1]
|
||||||
|
@ -378,10 +380,10 @@ m_m68k_write16_regs:
|
||||||
beq m_m68k_write16_regs_spec
|
beq m_m68k_write16_regs_spec
|
||||||
and r3, r1, #0xff
|
and r3, r1, #0xff
|
||||||
add r2, r0, #1
|
add r2, r0, #1
|
||||||
stmfd sp!,{r2,r3,lr}
|
stmfd sp!,{r2,r3,r12,lr}
|
||||||
mov r1, r1, lsr #8
|
mov r1, r1, lsr #8
|
||||||
bl m68k_reg_write8
|
bl m68k_reg_write8
|
||||||
ldmfd sp!,{r0,r1,lr}
|
ldmfd sp!,{r0,r1,r12,lr}
|
||||||
b m68k_reg_write8
|
b m68k_reg_write8
|
||||||
|
|
||||||
m_m68k_write16_regs_spec: @ special case
|
m_m68k_write16_regs_spec: @ special case
|
||||||
|
|
|
@ -81,6 +81,38 @@ void cpu68k_map_set(uptr *map, u32 start_addr, u32 end_addr,
|
||||||
}
|
}
|
||||||
|
|
||||||
// more specialized/optimized function (does same as above)
|
// more specialized/optimized function (does same as above)
|
||||||
|
void cpu68k_map_read_mem(u32 start_addr, u32 end_addr, void *ptr, int is_sub)
|
||||||
|
{
|
||||||
|
uptr *r8map, *r16map;
|
||||||
|
uptr addr = (uptr)ptr;
|
||||||
|
int shift = M68K_MEM_SHIFT;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!is_sub) {
|
||||||
|
r8map = m68k_read8_map;
|
||||||
|
r16map = m68k_read16_map;
|
||||||
|
} else {
|
||||||
|
r8map = s68k_read8_map;
|
||||||
|
r16map = s68k_read16_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr -= start_addr;
|
||||||
|
addr >>= 1;
|
||||||
|
for (i = start_addr >> shift; i <= end_addr >> shift; i++)
|
||||||
|
r8map[i] = r16map[i] = addr;
|
||||||
|
#ifdef EMU_F68K
|
||||||
|
// setup FAME fetchmap
|
||||||
|
{
|
||||||
|
M68K_CONTEXT *ctx = is_sub ? &PicoCpuFS68k : &PicoCpuFM68k;
|
||||||
|
int shiftout = 24 - FAMEC_FETCHBITS;
|
||||||
|
i = start_addr >> shiftout;
|
||||||
|
addr = (uptr)ptr - (i << shiftout);
|
||||||
|
for (; i <= (end_addr >> shiftout); i++)
|
||||||
|
ctx->Fetch[i] = addr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void cpu68k_map_all_ram(u32 start_addr, u32 end_addr, void *ptr, int is_sub)
|
void cpu68k_map_all_ram(u32 start_addr, u32 end_addr, void *ptr, int is_sub)
|
||||||
{
|
{
|
||||||
uptr *r8map, *r16map, *w8map, *w16map;
|
uptr *r8map, *r16map, *w8map, *w16map;
|
||||||
|
@ -117,6 +149,55 @@ void cpu68k_map_all_ram(u32 start_addr, u32 end_addr, void *ptr, int is_sub)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cpu68k_map_read_funcs(u32 start_addr, u32 end_addr, u32 (*r8)(u32), u32 (*r16)(u32), int is_sub)
|
||||||
|
{
|
||||||
|
uptr *r8map, *r16map;
|
||||||
|
uptr ar8 = (uptr)r8, ar16 = (uptr)r16;
|
||||||
|
int shift = M68K_MEM_SHIFT;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!is_sub) {
|
||||||
|
r8map = m68k_read8_map;
|
||||||
|
r16map = m68k_read16_map;
|
||||||
|
} else {
|
||||||
|
r8map = s68k_read8_map;
|
||||||
|
r16map = s68k_read16_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar8 = (ar8 >> 1 ) | MAP_FLAG;
|
||||||
|
ar16 = (ar16 >> 1 ) | MAP_FLAG;
|
||||||
|
for (i = start_addr >> shift; i <= end_addr >> shift; i++)
|
||||||
|
r8map[i] = ar8, r16map[i] = ar16;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpu68k_map_all_funcs(u32 start_addr, u32 end_addr, u32 (*r8)(u32), u32 (*r16)(u32), void (*w8)(u32, u32), void (*w16)(u32, u32), int is_sub)
|
||||||
|
{
|
||||||
|
uptr *r8map, *r16map, *w8map, *w16map;
|
||||||
|
uptr ar8 = (uptr)r8, ar16 = (uptr)r16;
|
||||||
|
uptr aw8 = (uptr)w8, aw16 = (uptr)w16;
|
||||||
|
int shift = M68K_MEM_SHIFT;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!is_sub) {
|
||||||
|
r8map = m68k_read8_map;
|
||||||
|
r16map = m68k_read16_map;
|
||||||
|
w8map = m68k_write8_map;
|
||||||
|
w16map = m68k_write16_map;
|
||||||
|
} else {
|
||||||
|
r8map = s68k_read8_map;
|
||||||
|
r16map = s68k_read16_map;
|
||||||
|
w8map = s68k_write8_map;
|
||||||
|
w16map = s68k_write16_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
ar8 = (ar8 >> 1 ) | MAP_FLAG;
|
||||||
|
ar16 = (ar16 >> 1 ) | MAP_FLAG;
|
||||||
|
aw8 = (aw8 >> 1 ) | MAP_FLAG;
|
||||||
|
aw16 = (aw16 >> 1 ) | MAP_FLAG;
|
||||||
|
for (i = start_addr >> shift; i <= end_addr >> shift; i++)
|
||||||
|
r8map[i] = ar8, r16map[i] = ar16, w8map[i] = aw8, w16map[i] = aw16;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 m68k_unmapped_read8(u32 a)
|
static u32 m68k_unmapped_read8(u32 a)
|
||||||
{
|
{
|
||||||
elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
|
elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);
|
||||||
|
|
|
@ -48,7 +48,10 @@ void z80_map_set(uptr *map, u16 start_addr, u16 end_addr,
|
||||||
const void *func_or_mh, int is_func);
|
const void *func_or_mh, int is_func);
|
||||||
void cpu68k_map_set(uptr *map, u32 start_addr, u32 end_addr,
|
void cpu68k_map_set(uptr *map, u32 start_addr, u32 end_addr,
|
||||||
const void *func_or_mh, int is_func);
|
const void *func_or_mh, int is_func);
|
||||||
|
void cpu68k_map_read_mem(u32 start_addr, u32 end_addr, void *ptr, int is_sub);
|
||||||
void cpu68k_map_all_ram(u32 start_addr, u32 end_addr, void *ptr, int is_sub);
|
void cpu68k_map_all_ram(u32 start_addr, u32 end_addr, void *ptr, int is_sub);
|
||||||
|
void cpu68k_map_read_funcs(u32 start_addr, u32 end_addr, u32 (*r8)(u32), u32 (*r16)(u32), int is_sub);
|
||||||
|
void cpu68k_map_all_funcs(u32 start_addr, u32 end_addr, u32 (*r8)(u32), u32 (*r16)(u32), void (*w8)(u32, u32), void (*w16)(u32, u32), int is_sub);
|
||||||
void m68k_map_unmap(u32 start_addr, u32 end_addr);
|
void m68k_map_unmap(u32 start_addr, u32 end_addr);
|
||||||
|
|
||||||
#define MAP_FLAG ((uptr)1 << (sizeof(uptr) * 8 - 1))
|
#define MAP_FLAG ((uptr)1 << (sizeof(uptr) * 8 - 1))
|
||||||
|
|
|
@ -38,7 +38,7 @@ static void SekExecM68k(int cyc_do)
|
||||||
SekCyclesLeft = 0;
|
SekCyclesLeft = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SekSyncM68k(void)
|
static int SekSyncM68k(int once)
|
||||||
{
|
{
|
||||||
int cyc_do;
|
int cyc_do;
|
||||||
|
|
||||||
|
@ -56,11 +56,14 @@ static void SekSyncM68k(void)
|
||||||
z80_buscyc = cyc_do;
|
z80_buscyc = cyc_do;
|
||||||
Pico.t.m68c_cnt += z80_buscyc;
|
Pico.t.m68c_cnt += z80_buscyc;
|
||||||
Pico.t.z80_buscycles -= z80_buscyc;
|
Pico.t.z80_buscycles -= z80_buscyc;
|
||||||
|
if (once) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SekTrace(0);
|
SekTrace(0);
|
||||||
pevt_log_m68k_o(EVT_RUN_END);
|
pevt_log_m68k_o(EVT_RUN_END);
|
||||||
pprof_end(m68k);
|
pprof_end(m68k);
|
||||||
|
|
||||||
|
return Pico.t.m68c_aim > Pico.t.m68c_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void SekRunM68k(int cyc)
|
static __inline void SekRunM68k(int cyc)
|
||||||
|
@ -72,7 +75,7 @@ static __inline void SekRunM68k(int cyc)
|
||||||
refresh = (cyc + refresh) & 0x3f;
|
refresh = (cyc + refresh) & 0x3f;
|
||||||
Pico.t.m68c_aim += cyc;
|
Pico.t.m68c_aim += cyc;
|
||||||
|
|
||||||
SekSyncM68k();
|
SekSyncM68k(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SyncCPUs(unsigned int cycles)
|
static void SyncCPUs(unsigned int cycles)
|
||||||
|
@ -300,7 +303,7 @@ static int PicoFrameHints(void)
|
||||||
while (l-- > 0) {
|
while (l-- > 0) {
|
||||||
Pico.t.m68c_cnt -= CYCLES_M68K_LINE;
|
Pico.t.m68c_cnt -= CYCLES_M68K_LINE;
|
||||||
do_timing_hacks_start(pv);
|
do_timing_hacks_start(pv);
|
||||||
SekSyncM68k();
|
SekSyncM68k(0);
|
||||||
do_timing_hacks_end(pv);
|
do_timing_hacks_end(pv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -506,7 +506,12 @@ struct mcd_pcm
|
||||||
} ch[8];
|
} ch[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PCD_ST_S68K_RST 1
|
#define PCD_ST_S68K_RST 1
|
||||||
|
#define PCD_ST_S68K_SYNC 2
|
||||||
|
#define PCD_ST_S68K_SLEEP 4
|
||||||
|
#define PCD_ST_M68K_SLEEP 8
|
||||||
|
#define PCD_ST_S68K_POLL 16
|
||||||
|
#define PCD_ST_M68K_POLL 32
|
||||||
|
|
||||||
struct mcd_misc
|
struct mcd_misc
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue