mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2025-01-27 18:35:29 +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 CDC & GFX register polling detection / synchronization
|
||||||
* added configurable CD-DA and PCM outputs mixing volume
|
* added configurable CD-DA and PCM outputs mixing volume
|
||||||
* added setting to enable/disable CD access time simulation
|
* 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 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 CDC emulation (fixes random freezes during Jeopardy & ESPN Sunday Night NFL intro)
|
||||||
* improved emulation of mirrored memory areas
|
* 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 */
|
default: /* invalid */
|
||||||
{
|
{
|
||||||
#ifdef LOG_CDC
|
#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
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
234
core/cd_hw/scd.c
234
core/cd_hw/scd.c
@ -73,6 +73,44 @@ static void s68k_unused_16_w(unsigned int address, unsigned int data)
|
|||||||
#endif
|
#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 */
|
/* PRG-RAM DMA access */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@ -718,6 +756,17 @@ INLINE void word_ram_switch(uint8 mode)
|
|||||||
*ptr3++=*ptr1++;
|
*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 */
|
/* SUB-CPU: $0C0000-$0DFFFF is mapped to Word-RAM 0 or 1 */
|
||||||
for (i=0x0c; i<0x0e; i++)
|
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);
|
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 */
|
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||||
for (i=0x0c; i<0x0e; i++)
|
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 */
|
/* check if RET bit is cleared */
|
||||||
if (!(data & 0x01))
|
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 */
|
/* set DMNA bit */
|
||||||
data |= 0x02;
|
data |= 0x02;
|
||||||
|
|
||||||
@ -951,6 +1000,26 @@ static void scd_write_byte(unsigned int address, unsigned int data)
|
|||||||
/* Word-RAM is returned to MAIN-CPU */
|
/* Word-RAM is returned to MAIN-CPU */
|
||||||
scd.dmna = 0;
|
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 */
|
/* clear DMNA bit */
|
||||||
scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1d);
|
scd.regs[0x02 >> 1].byte.l = (scd.regs[0x02 >> 1].byte.l & ~0x1f) | (data & 0x1d);
|
||||||
return;
|
return;
|
||||||
@ -1192,6 +1261,26 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
|||||||
/* check if RET bit is cleared */
|
/* check if RET bit is cleared */
|
||||||
if (!(data & 0x01))
|
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 */
|
/* set DMNA bit */
|
||||||
data |= 0x02;
|
data |= 0x02;
|
||||||
|
|
||||||
@ -1214,6 +1303,26 @@ static void scd_write_word(unsigned int address, unsigned int data)
|
|||||||
/* Word-RAM is returned to MAIN-CPU */
|
/* Word-RAM is returned to MAIN-CPU */
|
||||||
scd.dmna = 0;
|
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 */
|
/* clear DMNA bit */
|
||||||
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1d);
|
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0x1f) | (data & 0x1d);
|
||||||
return;
|
return;
|
||||||
@ -1516,10 +1625,11 @@ void scd_init(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s68k.memory_map[i].read8 = NULL;
|
/* access to Word-RAM in $08FFFF-$0BFFFF is locked by default (/DTACK not asserted) */
|
||||||
s68k.memory_map[i].read16 = NULL;
|
s68k.memory_map[i].read8 = s68k_lockup_r_8;
|
||||||
s68k.memory_map[i].write8 = NULL;
|
s68k.memory_map[i].read16 = s68k_lockup_r_16;
|
||||||
s68k.memory_map[i].write16 = NULL;
|
s68k.memory_map[i].write8 = s68k_lockup_w_8;
|
||||||
|
s68k.memory_map[i].write16 = s68k_lockup_w_16;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1590,6 +1700,8 @@ void scd_reset(int hard)
|
|||||||
{
|
{
|
||||||
if (hard)
|
if (hard)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Clear all ASIC registers by default */
|
/* Clear all ASIC registers by default */
|
||||||
memset(scd.regs, 0, sizeof(scd.regs));
|
memset(scd.regs, 0, sizeof(scd.regs));
|
||||||
|
|
||||||
@ -1606,6 +1718,26 @@ void scd_reset(int hard)
|
|||||||
/* 2M mode */
|
/* 2M mode */
|
||||||
word_ram_switch(0);
|
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 */
|
/* 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 + 0x02].base = scd.prg_ram;
|
||||||
m68k.memory_map[scd.cartridge.boot + 0x03].base = scd.prg_ram + 0x10000;
|
m68k.memory_map[scd.cartridge.boot + 0x03].base = scd.prg_ram + 0x10000;
|
||||||
@ -1684,9 +1816,13 @@ void scd_update(unsigned int cycles)
|
|||||||
|
|
||||||
/* update CDC DMA transfer */
|
/* update CDC DMA transfer */
|
||||||
if (cdc.dma_w)
|
if (cdc.dma_w)
|
||||||
|
{
|
||||||
|
/* 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();
|
cdc_dma_update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* run both CPU in sync until end of line */
|
/* run both CPU in sync until end of line */
|
||||||
do
|
do
|
||||||
@ -1941,6 +2077,12 @@ int scd_context_load(uint8 *state, char *version)
|
|||||||
{
|
{
|
||||||
/* Word-RAM 1 data mapped at $200000-$21FFFF */
|
/* Word-RAM 1 data mapped at $200000-$21FFFF */
|
||||||
m68k.memory_map[i].base = scd.word_ram[1] + ((i & 0x01) << 16);
|
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++)
|
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 */
|
/* Word-RAM 0 data mapped at $200000-$21FFFF */
|
||||||
m68k.memory_map[i].base = scd.word_ram[0] + ((i & 0x01) << 16);
|
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++)
|
for (i=scd.cartridge.boot+0x22; i<scd.cartridge.boot+0x24; i++)
|
||||||
@ -2020,15 +2168,13 @@ int scd_context_load(uint8 *state, char *version)
|
|||||||
/* 2M mode */
|
/* 2M mode */
|
||||||
load_param(scd.word_ram_2M, sizeof(scd.word_ram_2M));
|
load_param(scd.word_ram_2M, sizeof(scd.word_ram_2M));
|
||||||
|
|
||||||
/* MAIN-CPU: $200000-$21FFFF is mapped to 256K Word-RAM (upper 128K) */
|
/* check RET bit */
|
||||||
for (i=scd.cartridge.boot+0x20; i<scd.cartridge.boot+0x22; i++)
|
if (scd.regs[0x03>>1].byte.l & 0x01)
|
||||||
|
{
|
||||||
|
/* 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].base = scd.word_ram_2M + ((i & 0x03) << 16);
|
||||||
}
|
|
||||||
|
|
||||||
/* 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].read8 = NULL;
|
||||||
m68k.memory_map[i].read16 = NULL;
|
m68k.memory_map[i].read16 = NULL;
|
||||||
m68k.memory_map[i].write8 = NULL;
|
m68k.memory_map[i].write8 = NULL;
|
||||||
@ -2037,7 +2183,30 @@ int scd_context_load(uint8 *state, char *version)
|
|||||||
zbank_memory_map[i].write = NULL;
|
zbank_memory_map[i].write = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SUB-CPU: $080000-$0BFFFF is mapped to 256K Word-RAM */
|
/* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* 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++)
|
for (i=0x08; i<0x0c; i++)
|
||||||
{
|
{
|
||||||
s68k.memory_map[i].read8 = NULL;
|
s68k.memory_map[i].read8 = NULL;
|
||||||
@ -2045,6 +2214,7 @@ int scd_context_load(uint8 *state, char *version)
|
|||||||
s68k.memory_map[i].write8 = NULL;
|
s68k.memory_map[i].write8 = NULL;
|
||||||
s68k.memory_map[i].write16 = NULL;
|
s68k.memory_map[i].write16 = NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
/* SUB-CPU: $0C0000-$0DFFFF is unmapped */
|
||||||
for (i=0x0c; i<0x0e; i++)
|
for (i=0x0c; i<0x0e; i++)
|
||||||
|
@ -243,6 +243,7 @@ typedef struct
|
|||||||
|
|
||||||
uint dar[16]; /* Data and Address Registers */
|
uint dar[16]; /* Data and Address Registers */
|
||||||
uint pc; /* Program Counter */
|
uint pc; /* Program Counter */
|
||||||
|
uint prev_pc; /* Previous Program Counter */
|
||||||
uint sp[5]; /* User and Interrupt Stack Pointers */
|
uint sp[5]; /* User and Interrupt Stack Pointers */
|
||||||
uint ir; /* Instruction Register */
|
uint ir; /* Instruction Register */
|
||||||
uint t1_flag; /* Trace 1 */
|
uint t1_flag; /* Trace 1 */
|
||||||
@ -382,6 +383,11 @@ extern void m68k_clear_halt(void);
|
|||||||
extern void s68k_pulse_halt(void);
|
extern void s68k_pulse_halt(void);
|
||||||
extern void s68k_clear_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
|
/* Peek at the internals of a CPU context. This can either be a context
|
||||||
* retrieved using m68k_get_context() or the currently running 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);
|
cpu_hook(HOOK_M68K_E, 0, REG_PC, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Save current instruction PC */
|
||||||
|
m68k.prev_pc = REG_PC;
|
||||||
|
|
||||||
/* Decode next instruction */
|
/* Decode next instruction */
|
||||||
REG_IR = m68ki_read_imm_16();
|
REG_IR = m68ki_read_imm_16();
|
||||||
|
|
||||||
@ -396,6 +399,24 @@ void m68k_clear_halt(void)
|
|||||||
CPU_STOPPED &= ~STOP_LEVEL_HALT;
|
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 ============================= */
|
/* ============================== END OF FILE ============================= */
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
/* Different ways to stop the CPU */
|
/* Different ways to stop the CPU */
|
||||||
#define STOP_LEVEL_STOP 1
|
#define STOP_LEVEL_STOP 1
|
||||||
#define STOP_LEVEL_HALT 2
|
#define STOP_LEVEL_HALT 2
|
||||||
|
#define STOP_LEVEL_WAIT 4
|
||||||
|
|
||||||
/* Used for 68000 address error processing */
|
/* Used for 68000 address error processing */
|
||||||
#if M68K_EMULATE_ADDRESS_ERROR
|
#if M68K_EMULATE_ADDRESS_ERROR
|
||||||
|
@ -253,6 +253,9 @@ void s68k_run(unsigned int cycles)
|
|||||||
/* Set the address space for reads */
|
/* Set the address space for reads */
|
||||||
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
|
m68ki_use_data_space() /* auto-disable (see m68kcpu.h) */
|
||||||
|
|
||||||
|
/* Save current instruction PC */
|
||||||
|
s68k.prev_pc = REG_PC;
|
||||||
|
|
||||||
/* Decode next instruction */
|
/* Decode next instruction */
|
||||||
REG_IR = m68ki_read_imm_16();
|
REG_IR = m68ki_read_imm_16();
|
||||||
|
|
||||||
@ -354,6 +357,24 @@ void s68k_clear_halt(void)
|
|||||||
CPU_STOPPED &= ~STOP_LEVEL_HALT;
|
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 ============================= */
|
/* ============================== END OF FILE ============================= */
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
|
@ -88,8 +88,7 @@ void m68k_lockup_w_8 (unsigned int address, unsigned int data)
|
|||||||
#endif
|
#endif
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
{
|
{
|
||||||
m68k_pulse_halt();
|
m68k_pulse_wait();
|
||||||
m68k.cycles = m68k.cycle_end;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,8 +99,7 @@ void m68k_lockup_w_16 (unsigned int address, unsigned int data)
|
|||||||
#endif
|
#endif
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
{
|
{
|
||||||
m68k_pulse_halt();
|
m68k_pulse_wait();
|
||||||
m68k.cycles = m68k.cycle_end;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,12 +108,11 @@ unsigned int m68k_lockup_r_8 (unsigned int address)
|
|||||||
#ifdef LOGERROR
|
#ifdef LOGERROR
|
||||||
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
||||||
#endif
|
#endif
|
||||||
|
address = m68k.pc | (address & 1);
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
{
|
{
|
||||||
m68k_pulse_halt();
|
m68k_pulse_wait();
|
||||||
m68k.cycles = m68k.cycle_end;
|
|
||||||
}
|
}
|
||||||
address = m68k.pc | (address & 1);
|
|
||||||
return READ_BYTE(m68k.memory_map[((address)>>16)&0xff].base, (address) & 0xffff);
|
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
|
#ifdef LOGERROR
|
||||||
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg(M68K_REG_PC));
|
||||||
#endif
|
#endif
|
||||||
|
address = m68k.pc;
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
{
|
{
|
||||||
m68k_pulse_halt();
|
m68k_pulse_wait();
|
||||||
m68k.cycles = m68k.cycle_end;
|
|
||||||
}
|
}
|
||||||
address = m68k.pc;
|
|
||||||
return *(uint16 *)(m68k.memory_map[((address)>>16)&0xff].base + ((address) & 0xffff));
|
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 */
|
/* writing 0 to DMNA in 2M mode does nothing */
|
||||||
if (data & 0x02)
|
if (data & 0x02)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Word-RAM is assigned to SUB-CPU */
|
/* Word-RAM is assigned to SUB-CPU */
|
||||||
scd.dmna = 1;
|
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 */
|
/* clear RET bit and update BK0-1 & DMNA bits */
|
||||||
scd.regs[0x03>>1].byte.l = (scd.regs[0x03>>1].byte.l & ~0xc3) | (data & 0xc2);
|
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 */
|
/* check if graphics operation is running */
|
||||||
if (scd.regs[0x58>>1].byte.h & 0x80)
|
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 */
|
/* writing 0 to DMNA in 2M mode does nothing */
|
||||||
if (data & 0x02)
|
if (data & 0x02)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Word-RAM is assigned to SUB-CPU */
|
/* Word-RAM is assigned to SUB-CPU */
|
||||||
scd.dmna = 1;
|
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 */
|
/* clear RET bit and update WP0-7 & BK0-1 bits */
|
||||||
scd.regs[0x02>>1].w = (scd.regs[0x02>>1].w & ~0xffc3) | (data & 0xffc2);
|
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 */
|
/* check if graphics operation is running */
|
||||||
if (scd.regs[0x58>>1].byte.h & 0x80)
|
if (scd.regs[0x58>>1].byte.h & 0x80)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user