mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-11-13 06:15:07 +01:00
[Core/CD] added emulation of Word-RAM access limitations in 2M mode (fixes graphical issues in Marko's Magic Football)
This commit is contained in:
parent
9b0b8d3afc
commit
6cc8bbc277
@ -19,6 +19,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke)
|
||||
* added CDC & GFX register polling detection / synchronization
|
||||
* added configurable CD-DA and PCM outputs mixing volume
|
||||
* added setting to enable/disable CD access time simulation
|
||||
* added emulation of Word-RAM access limitations in 2M mode (fixes graphical issues in Marko's Magic Football)
|
||||
* improved Timer interrupt timings and CDD interrupt accuracy (fixes audio stutters during Popful Mail FMV)
|
||||
* improved CDC emulation (fixes random freezes during Jeopardy & ESPN Sunday Night NFL intro)
|
||||
* improved emulation of mirrored memory areas
|
||||
|
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 3.8 MiB After Width: | Height: | Size: 3.8 MiB |
Binary file not shown.
Before Width: | Height: | Size: 4.0 MiB After Width: | Height: | Size: 4.0 MiB |
@ -463,7 +463,7 @@ void cdc_reg_w(unsigned char data)
|
||||
default: /* invalid */
|
||||
{
|
||||
#ifdef LOG_CDC
|
||||
error("invalid CDC tranfer destination (%d)\n", scd.regs[0x04>>1].byte.h & 0x07);
|
||||
error("invalid CDC transfer destination (%d)\n", scd.regs[0x04>>1].byte.h & 0x07);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
260
core/cd_hw/scd.c
260
core/cd_hw/scd.c
@ -73,6 +73,44 @@ static void s68k_unused_16_w(unsigned int address, unsigned int data)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Locked area (cause SUB-CPU to wait for /DTACK assertion) */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
static void s68k_lockup_w_8 (unsigned int address, unsigned int data)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error ("[SUB 68k] Lockup write8 %08X = %02X (%08X)\n", address, data, s68k.pc);
|
||||
#endif
|
||||
s68k_pulse_wait();
|
||||
}
|
||||
|
||||
static void s68k_lockup_w_16 (unsigned int address, unsigned int data)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error ("[SUB 68k] Lockup write16 %08X = %04X (%08X)\n", address, data, s68k.pc);
|
||||
#endif
|
||||
s68k_pulse_wait();
|
||||
}
|
||||
|
||||
static unsigned int s68k_lockup_r_8 (unsigned int address)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error ("[SUB 68k] Lockup read8 %08X.b (%08X)\n", address, s68k.pc);
|
||||
#endif
|
||||
s68k_pulse_wait();
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static unsigned int s68k_lockup_r_16 (unsigned int address)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error ("[SUB 68k] Lockup read16 %08X.w (%08X)\n", address, s68k.pc);
|
||||
#endif
|
||||
s68k_pulse_wait();
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* PRG-RAM DMA access */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -718,6 +756,17 @@ INLINE void word_ram_switch(uint8 mode)
|
||||
*ptr3++=*ptr1++;
|
||||
}
|
||||
|
||||
/* MAIN-CPU: $200000-$21FFFF is mapped to Word-RAM 0 or 1 */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x22; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is mapped to Word-RAM 0 or 1 */
|
||||
for (i=0x0c; i<0x0e; i++)
|
||||
{
|
||||
@ -742,26 +791,6 @@ INLINE void word_ram_switch(uint8 mode)
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
}
|
||||
|
||||
/* MAIN-CPU: $220000-$23FFFF is mapped to 256K Word-RAM (upper 128K) */
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||
for (i=0x0c; i<0x0e; i++)
|
||||
{
|
||||
@ -929,6 +958,26 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
/* check if RET bit is cleared */
|
||||
if (!(data & 0x01))
|
||||
{
|
||||
/* MAIN-CPU: $200000-$23FFFF is unmapped */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = zbank_unused_w;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM in $08FFFF-$0BFFFF is unlocked (/DTACK asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* set DMNA bit */
|
||||
data |= 0x02;
|
||||
|
||||
@ -951,6 +1000,26 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
||||
/* Word-RAM is returned to MAIN-CPU */
|
||||
scd.dmna = 0;
|
||||
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to Word-RAM */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM in $08FFFF-$0BFFFF is locked (/DTACK not asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||
}
|
||||
|
||||
/* clear DMNA bit */
|
||||
scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1d);
|
||||
return;
|
||||
@ -1192,6 +1261,26 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
/* check if RET bit is cleared */
|
||||
if (!(data & 0x01))
|
||||
{
|
||||
/* MAIN-CPU: $200000-$23FFFF is unmapped */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = zbank_unused_w;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM in $08FFFF-$0BFFFF is unlocked (/DTACK asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* set DMNA bit */
|
||||
data |= 0x02;
|
||||
|
||||
@ -1214,6 +1303,26 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
||||
/* Word-RAM is returned to MAIN-CPU */
|
||||
scd.dmna = 0;
|
||||
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to Word-RAM */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM in $08FFFF-$0BFFFF is locked (/DTACK not asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||
}
|
||||
|
||||
/* clear DMNA bit */
|
||||
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1d);
|
||||
return;
|
||||
@ -1516,10 +1625,11 @@ void scd_init(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
/* access to Word-RAM in $08FFFF-$0BFFFF is locked by default (/DTACK not asserted) */
|
||||
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1590,6 +1700,8 @@ void scd_reset(int hard)
|
||||
{
|
||||
if (hard)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Clear all ASIC registers by default */
|
||||
memset(scd.regs, 0, sizeof(scd.regs));
|
||||
|
||||
@ -1606,6 +1718,26 @@ void scd_reset(int hard)
|
||||
/* 2M mode */
|
||||
word_ram_switch(0);
|
||||
|
||||
/* MAIN-CPU access to Word-RAM at $200000-$23FFFF is enabled on reset */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* SUB-CPU access to Word-RAM at $08FFFF-$0BFFFF is locked on reset (/DTACK not asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||
}
|
||||
|
||||
/* reset PRG-RAM bank on MAIN-CPU side */
|
||||
m68k.memory_map[scd.cartridge.boot + 0x02].base = scd.prg_ram;
|
||||
m68k.memory_map[scd.cartridge.boot + 0x03].base = scd.prg_ram + 0x10000;
|
||||
@ -1685,7 +1817,11 @@ void scd_update(unsigned int cycles)
|
||||
/* update CDC DMA transfer */
|
||||
if (cdc.dma_w)
|
||||
{
|
||||
cdc_dma_update();
|
||||
/* check if Word-RAM is returned to SUB-CPU in 2M mode */
|
||||
if ((cdc.dma_w != word_ram_2M_dma_w) || scd.dmna)
|
||||
{
|
||||
cdc_dma_update();
|
||||
}
|
||||
}
|
||||
|
||||
/* run both CPU in sync until end of line */
|
||||
@ -1941,6 +2077,12 @@ int scd_context_load(uint8 *state, char *version)
|
||||
{
|
||||
/* Word-RAM 1 data mapped at $200000-$21FFFF */
|
||||
m68k.memory_map[i].base = scd.word_ram[1] + ((i & 0x01) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
@ -1981,6 +2123,12 @@ int scd_context_load(uint8 *state, char *version)
|
||||
{
|
||||
/* Word-RAM 0 data mapped at $200000-$21FFFF */
|
||||
m68k.memory_map[i].base = scd.word_ram[0] + ((i & 0x01) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
@ -2020,30 +2168,52 @@ int scd_context_load(uint8 *state, char *version)
|
||||
/* 2M mode */
|
||||
load_param(scd.word_ram_2M, sizeof(scd.word_ram_2M));
|
||||
|
||||
/* MAIN-CPU: $200000-$21FFFF is mapped to 256K Word-RAM (upper 128K) */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x22; i++)
|
||||
/* check RET bit */
|
||||
if (scd.regs[0x03>>1].byte.l & 0x01)
|
||||
{
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
}
|
||||
/* MAIN-CPU: $200000-$23FFFF is mapped to 256K Word-RAM */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
}
|
||||
|
||||
/* MAIN-CPU: $220000-$23FFFF is mapped to 256K Word-RAM (lower 128K) */
|
||||
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = NULL;
|
||||
m68k.memory_map[i].read16 = NULL;
|
||||
m68k.memory_map[i].write8 = NULL;
|
||||
m68k.memory_map[i].write16 = NULL;
|
||||
zbank_memory_map[i].read = NULL;
|
||||
zbank_memory_map[i].write = NULL;
|
||||
/* SUB-CPU: access to Word-RAM at $080000-$0BFFFF is locked (/DTACK not asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||
}
|
||||
}
|
||||
|
||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
else
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
/* MAIN-CPU: $200000-$23FFFF is unmapped */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = zbank_unused_w;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM at $080000-$0BFFFF is unlocked (/DTACK asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||
|
@ -243,6 +243,7 @@ typedef struct
|
||||
|
||||
uint dar[16]; /* Data and Address Registers */
|
||||
uint pc; /* Program Counter */
|
||||
uint prev_pc; /* Previous Program Counter */
|
||||
uint sp[5]; /* User and Interrupt Stack Pointers */
|
||||
uint ir; /* Instruction Register */
|
||||
uint t1_flag; /* Trace 1 */
|
||||
@ -382,6 +383,11 @@ extern void m68k_clear_halt(void);
|
||||
extern void s68k_pulse_halt(void);
|
||||
extern void s68k_clear_halt(void);
|
||||
|
||||
/* Put the CPU in waiting state as if DTACK pin is not asserted during bus access */
|
||||
extern void m68k_pulse_wait(void);
|
||||
extern void m68k_clear_wait(void);
|
||||
extern void s68k_pulse_wait(void);
|
||||
extern void s68k_clear_wait(void);
|
||||
|
||||
/* Peek at the internals of a CPU context. This can either be a context
|
||||
* retrieved using m68k_get_context() or the currently running context.
|
||||
|
@ -296,6 +296,9 @@ void m68k_run(unsigned int cycles)
|
||||
cpu_hook(HOOK_M68K_E, 0, REG_PC, 0);
|
||||
#endif
|
||||
|
||||
/* Save current instruction PC */
|
||||
m68k.prev_pc = REG_PC;
|
||||
|
||||
/* Decode next instruction */
|
||||
REG_IR = m68ki_read_imm_16();
|
||||
|
||||
@ -396,6 +399,24 @@ void m68k_clear_halt(void)
|
||||
CPU_STOPPED &= ~STOP_LEVEL_HALT;
|
||||
}
|
||||
|
||||
void m68k_pulse_wait(void)
|
||||
{
|
||||
/* Hold the DTACK line on the CPU */
|
||||
CPU_STOPPED |= STOP_LEVEL_WAIT;
|
||||
|
||||
/* End CPU execution */
|
||||
m68k.cycles = m68k.cycle_end - m68k_cycles();
|
||||
|
||||
/* Rollback current instruction (memory access will be executed once /DTACK is asserted) */
|
||||
m68k.pc = m68k.prev_pc;
|
||||
}
|
||||
|
||||
void m68k_clear_wait(void)
|
||||
{
|
||||
/* Assert the DTACK line on the CPU */
|
||||
CPU_STOPPED &= ~STOP_LEVEL_WAIT;
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
@ -48,6 +48,7 @@
|
||||
/* Different ways to stop the CPU */
|
||||
#define STOP_LEVEL_STOP 1
|
||||
#define STOP_LEVEL_HALT 2
|
||||
#define STOP_LEVEL_WAIT 4
|
||||
|
||||
/* Used for 68000 address error processing */
|
||||
#if M68K_EMULATE_ADDRESS_ERROR
|
||||
|
@ -253,6 +253,9 @@ void s68k_run(unsigned int cycles)
|
||||
/* Set the address space for reads */
|
||||
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
/* Save current instruction PC */
|
||||
s68k.prev_pc = REG_PC;
|
||||
|
||||
/* Decode next instruction */
|
||||
REG_IR = m68ki_read_imm_16();
|
||||
|
||||
@ -354,6 +357,24 @@ void s68k_clear_halt(void)
|
||||
CPU_STOPPED &= ~STOP_LEVEL_HALT;
|
||||
}
|
||||
|
||||
void s68k_pulse_wait(void)
|
||||
{
|
||||
/* Hold the DTACK line on the CPU */
|
||||
CPU_STOPPED |= STOP_LEVEL_WAIT;
|
||||
|
||||
/* End CPU execution */
|
||||
s68k.cycles = s68k.cycle_end - s68k_cycles();
|
||||
|
||||
/* Rollback current instruction (memory access will be executed once /DTACK is asserted) */
|
||||
s68k.pc = s68k.prev_pc;
|
||||
}
|
||||
|
||||
void s68k_clear_wait(void)
|
||||
{
|
||||
/* Assert the DTACK line on the CPU */
|
||||
CPU_STOPPED &= ~STOP_LEVEL_WAIT;
|
||||
}
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
/* ======================================================================== */
|
||||
|
@ -88,8 +88,7 @@ void m68k_lockup_w_8 (unsigned int address, unsigned int data)
|
||||
#endif
|
||||
if (!config.force_dtack)
|
||||
{
|
||||
m68k_pulse_halt();
|
||||
m68k.cycles = m68k.cycle_end;
|
||||
m68k_pulse_wait();
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,8 +99,7 @@ void m68k_lockup_w_16 (unsigned int address, unsigned int data)
|
||||
#endif
|
||||
if (!config.force_dtack)
|
||||
{
|
||||
m68k_pulse_halt();
|
||||
m68k.cycles = m68k.cycle_end;
|
||||
m68k_pulse_wait();
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,12 +108,11 @@ unsigned int m68k_lockup_r_8 (unsigned int address)
|
||||
#ifdef LOGERROR
|
||||
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
address = m68k.pc | (address & 1);
|
||||
if (!config.force_dtack)
|
||||
{
|
||||
m68k_pulse_halt();
|
||||
m68k.cycles = m68k.cycle_end;
|
||||
m68k_pulse_wait();
|
||||
}
|
||||
address = m68k.pc | (address & 1);
|
||||
return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff);
|
||||
}
|
||||
|
||||
@ -124,12 +121,11 @@ unsigned int m68k_lockup_r_16 (unsigned int address)
|
||||
#ifdef LOGERROR
|
||||
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
||||
#endif
|
||||
address = m68k.pc;
|
||||
if (!config.force_dtack)
|
||||
{
|
||||
m68k_pulse_halt();
|
||||
m68k.cycles = m68k.cycle_end;
|
||||
m68k_pulse_wait();
|
||||
}
|
||||
address = m68k.pc;
|
||||
return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff));
|
||||
}
|
||||
|
||||
@ -780,12 +776,47 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
|
||||
/* writing 0 to DMNA in 2M mode does nothing */
|
||||
if (data & 0x02)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Word-RAM is assigned to SUB-CPU */
|
||||
scd.dmna = 1;
|
||||
|
||||
/* MAIN-CPU: $200000-$23FFFF is unmapped */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = zbank_unused_w;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM at 0x080000-0x0BFFFF is unlocked (/DTACK asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* clear RET bit and update BK0-1 & DMNA bits */
|
||||
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2);
|
||||
|
||||
/* check if SUB-CPU is waiting for Word-RAM access */
|
||||
if (s68k.stopped & 0x04)
|
||||
{
|
||||
/* sync SUB-CPU with MAIN-CPU */
|
||||
s68k.cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE;
|
||||
|
||||
/* restart SUB-CPU */
|
||||
s68k_clear_wait();
|
||||
#ifdef LOG_SCD
|
||||
error("s68k started from %d cycles\n", s68k.cycles);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check if graphics operation is running */
|
||||
if (scd.regs[0x58>>1].byte.h & 0x80)
|
||||
{
|
||||
@ -1038,12 +1069,47 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
|
||||
/* writing 0 to DMNA in 2M mode does nothing */
|
||||
if (data & 0x02)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Word-RAM is assigned to SUB-CPU */
|
||||
scd.dmna = 1;
|
||||
|
||||
/* MAIN-CPU: $200000-$23FFFF is unmapped */
|
||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x24; i++)
|
||||
{
|
||||
m68k.memory_map[i].read8 = m68k_read_bus_8;
|
||||
m68k.memory_map[i].read16 = m68k_read_bus_16;
|
||||
m68k.memory_map[i].write8 = m68k_unused_8_w;
|
||||
m68k.memory_map[i].write16 = m68k_unused_16_w;
|
||||
zbank_memory_map[i].read = zbank_unused_r;
|
||||
zbank_memory_map[i].write = zbank_unused_w;
|
||||
}
|
||||
|
||||
/* SUB-CPU: access to Word-RAM at 0x080000-0x0BFFFF is unlocked (/DTACK asserted) */
|
||||
for (i=0x08; i<0x0c; i++)
|
||||
{
|
||||
s68k.memory_map[i].read8 = NULL;
|
||||
s68k.memory_map[i].read16 = NULL;
|
||||
s68k.memory_map[i].write8 = NULL;
|
||||
s68k.memory_map[i].write16 = NULL;
|
||||
}
|
||||
|
||||
/* clear RET bit and update WP0-7 & BK0-1 bits */
|
||||
scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2);
|
||||
|
||||
/* check if SUB-CPU is waiting for Word-RAM access */
|
||||
if (s68k.stopped & 0x04)
|
||||
{
|
||||
/* sync SUB-CPU with MAIN-CPU */
|
||||
s68k.cycles = (m68k.cycles * SCYCLES_PER_LINE) / MCYCLES_PER_LINE;
|
||||
|
||||
/* restart SUB-CPU */
|
||||
s68k_clear_wait();
|
||||
#ifdef LOG_SCD
|
||||
error("s68k started from %d cycles\n", s68k.cycles);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* check if graphics operation is running */
|
||||
if (scd.regs[0x58>>1].byte.h & 0x80)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user