.fixed optimization of memory handlers (better branch prediction ?)

.fixed savestate snaphot when 16:9 correction is used
.fixed overscan support (separated H & V border emulation)
This commit is contained in:
ekeeke31 2010-06-15 06:14:35 +00:00
parent 682dd53a38
commit 3434f89e3b
6 changed files with 158 additions and 154 deletions

View File

@ -134,7 +134,9 @@ void gen_hardreset(void)
/* TMSS + OS ROM support */ /* TMSS + OS ROM support */
memset(tmss, 0x00, sizeof(tmss)); memset(tmss, 0x00, sizeof(tmss));
if (config.tmss == 3) if (config.tmss == 3)
{
m68k_memory_map[0].base = bios_rom; m68k_memory_map[0].base = bios_rom;
}
/* Reset CPU cycles (check EA logo corruption, no glitches for Skitchin/Budokan on PAL 60hz MD2 with TMSS) */ /* Reset CPU cycles (check EA logo corruption, no glitches for Skitchin/Budokan on PAL 60hz MD2 with TMSS) */
mcycles_68k = mcycles_z80 = (rand() % lines_per_frame) * MCYCLES_PER_LINE; mcycles_68k = mcycles_z80 = (rand() % lines_per_frame) * MCYCLES_PER_LINE;
@ -268,10 +270,11 @@ void gen_zbusreq_w(unsigned int state, unsigned int cycles)
/* enable 68k access */ /* enable 68k access */
if (zstate & 1) if (zstate & 1)
{ {
m68k_memory_map[0xa0].read8 = z80_read_byte; _m68k_memory_map *base = &m68k_memory_map[0xa0];
m68k_memory_map[0xa0].read16 = z80_read_word; base->read8 = z80_read_byte;
m68k_memory_map[0xa0].write8 = z80_write_byte; base->read16 = z80_read_word;
m68k_memory_map[0xa0].write16 = z80_write_word; base->write8 = z80_write_byte;
base->write16 = z80_write_word;
} }
} }
else /* Z80 Bus Released */ else /* Z80 Bus Released */
@ -284,10 +287,11 @@ void gen_zbusreq_w(unsigned int state, unsigned int cycles)
zstate &= 1; zstate &= 1;
/* disable 68k access */ /* disable 68k access */
m68k_memory_map[0xa0].read8 = m68k_read_bus_8; _m68k_memory_map *base = &m68k_memory_map[0xa0];
m68k_memory_map[0xa0].read16 = m68k_read_bus_16; base->read8 = m68k_read_bus_8;
m68k_memory_map[0xa0].write8 = m68k_unused_8_w; base->read16 = m68k_read_bus_16;
m68k_memory_map[0xa0].write16 = m68k_unused_16_w; base->write8 = m68k_unused_8_w;
base->write16 = m68k_unused_16_w;
} }
} }
@ -312,10 +316,11 @@ void gen_zreset_w(unsigned int state, unsigned int cycles)
/* enable 68k access */ /* enable 68k access */
if (zstate & 1) if (zstate & 1)
{ {
m68k_memory_map[0xa0].read8 = z80_read_byte; _m68k_memory_map *base = &m68k_memory_map[0xa0];
m68k_memory_map[0xa0].read16 = z80_read_word; base->read8 = z80_read_byte;
m68k_memory_map[0xa0].write8 = z80_write_byte; base->read16 = z80_read_word;
m68k_memory_map[0xa0].write16 = z80_write_word; base->write8 = z80_write_byte;
base->write16 = z80_write_word;
} }
} }
else /* !ZRESET active */ else /* !ZRESET active */
@ -328,10 +333,11 @@ void gen_zreset_w(unsigned int state, unsigned int cycles)
zstate &= 2; zstate &= 2;
/* disable 68k access */ /* disable 68k access */
m68k_memory_map[0xa0].read8 = m68k_read_bus_8; _m68k_memory_map *base = &m68k_memory_map[0xa0];
m68k_memory_map[0xa0].read16 = m68k_read_bus_16; base->read8 = m68k_read_bus_8;
m68k_memory_map[0xa0].write8 = m68k_unused_8_w; base->read16 = m68k_read_bus_16;
m68k_memory_map[0xa0].write16 = m68k_unused_16_w; base->write8 = m68k_unused_8_w;
base->write16 = m68k_unused_16_w;
} }
/* reset YM2612 */ /* reset YM2612 */

View File

@ -1088,8 +1088,8 @@ static void systemmenu ()
hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32; hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32;
/* reinitialize overscan area */ /* reinitialize overscan area */
bitmap.viewport.x = config.overscan ? 14 : 0; bitmap.viewport.x = (config.overscan & 2) ? ((reg[12] & 1) ? 16 : 12) : 0;
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0; bitmap.viewport.y = (config.overscan & 1) ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
} }
break; break;
@ -2367,6 +2367,7 @@ static int savemenu(void)
{ {
/* set menu background */ /* set menu background */
bg_saves[0].w = bg_saves[0].texture->width * 2; bg_saves[0].w = bg_saves[0].texture->width * 2;
if (config.aspect & 2) bg_saves[0].w = (bg_saves[0].w * 3) / 4;
bg_saves[0].h = bg_saves[0].texture->height * 2; bg_saves[0].h = bg_saves[0].texture->height * 2;
bg_saves[0].x = (vmode->fbWidth - bg_saves[0].w) / 2; bg_saves[0].x = (vmode->fbWidth - bg_saves[0].w) / 2;
bg_saves[0].y = (vmode->efbHeight - bg_saves[0].h) / 2; bg_saves[0].y = (vmode->efbHeight - bg_saves[0].h) / 2;

View File

@ -454,21 +454,24 @@ static void gxSetAspectRatio(int *xscale, int *yscale)
/* the following values have been deducted from comparison with a real 50/60hz Mega Drive */ /* the following values have been deducted from comparison with a real 50/60hz Mega Drive */
if (config.aspect) if (config.aspect)
{ {
if (config.overscan) /* vertical borders */
{ if (config.overscan & 1)
/* borders are emulated */
*xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
*yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120); *yscale = vdp_pal + ((gc_pal && !config.render) ? 143 : 120);
}
else else
{ {
/* borders are simulated (black) */
*xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
*yscale = bitmap.viewport.h / 2; *yscale = bitmap.viewport.h / 2;
if (vdp_pal && (!gc_pal || config.render)) *yscale = *yscale * 240 / 288; if (vdp_pal && (!gc_pal || config.render))
else if (!vdp_pal && gc_pal && !config.render) *yscale = *yscale * 288 / 240; *yscale = *yscale * 240 / 288;
else if (!vdp_pal && gc_pal && !config.render)
*yscale = *yscale * 288 / 240;
} }
/* horizontal borders */
if (config.overscan & 2)
*xscale = 358 + ((reg[12] & 1)*2) - gc_pal;
else
*xscale = 325 + ((reg[12] & 1)*2) - gc_pal;
/* 16/9 correction */ /* 16/9 correction */
if (config.aspect & 2) if (config.aspect & 2)
*xscale = (*xscale * 3) / 4; *xscale = (*xscale * 3) / 4;
@ -477,18 +480,17 @@ static void gxSetAspectRatio(int *xscale, int *yscale)
/* manual aspect ratio (default is fullscreen) */ /* manual aspect ratio (default is fullscreen) */
else else
{ {
if (config.overscan) /* vertical borders */
{ if (config.overscan & 1)
/* borders are emulated */
*xscale = 352;
*yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120); *yscale = (gc_pal && !config.render) ? (vdp_pal ? (268*144 / bitmap.viewport.h):143) : (vdp_pal ? (224*144 / bitmap.viewport.h):120);
}
else else
{
/* borders are simulated (black) */
*xscale = 320;
*yscale = (gc_pal && !config.render) ? 134 : 112; *yscale = (gc_pal && !config.render) ? 134 : 112;
}
/* horizontal borders */
if (config.overscan & 2)
*xscale = 352;
else
*xscale = 320;
/* add user scaling */ /* add user scaling */
*xscale += config.xscale; *xscale += config.xscale;

View File

@ -115,40 +115,40 @@ unsigned int m68k_lockup_r_16 (unsigned int address)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
unsigned int eeprom_read_byte(unsigned int address) unsigned int eeprom_read_byte(unsigned int address)
{ {
if (address != eeprom.type.sda_out_adr) if (address == eeprom.type.sda_out_adr)
{ {
return READ_BYTE(cart.rom, address); return eeprom_read(address, 0);
} }
return eeprom_read(address, 0); return READ_BYTE(cart.rom, address);
} }
unsigned int eeprom_read_word(unsigned int address) unsigned int eeprom_read_word(unsigned int address)
{ {
if (address != (eeprom.type.sda_out_adr & 0xfffffe)) if (address == (eeprom.type.sda_out_adr & 0xfffffe))
{ {
return *(uint16 *)(cart.rom + address); return eeprom_read(address, 1);
} }
return eeprom_read(address, 1); return *(uint16 *)(cart.rom + address);
} }
void eeprom_write_byte(unsigned int address, unsigned int data) void eeprom_write_byte(unsigned int address, unsigned int data)
{ {
if ((address != eeprom.type.sda_in_adr) && (address != eeprom.type.scl_adr)) if ((address == eeprom.type.sda_in_adr) || (address == eeprom.type.scl_adr))
{ {
m68k_unused_8_w(address, data); eeprom_write(address, data, 0);
return; return;
} }
eeprom_write(address, data, 0); m68k_unused_8_w(address, data);
} }
void eeprom_write_word(unsigned int address, unsigned int data) void eeprom_write_word(unsigned int address, unsigned int data)
{ {
if ((address != (eeprom.type.sda_in_adr & 0xfffffe)) && (address != (eeprom.type.scl_adr & 0xfffffe))) if ((address == (eeprom.type.sda_in_adr & 0xfffffe)) || (address == (eeprom.type.scl_adr & 0xfffffe)))
{ {
m68k_unused_16_w (address, data); eeprom_write(address, data, 1);
return; return;
} }
eeprom_write(address, data, 1); m68k_unused_16_w (address, data);
} }
@ -245,49 +245,49 @@ unsigned int ctrl_io_read_byte(unsigned int address)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if (address & 0xe0) if (!(address & 0xe0))
{ {
return m68k_read_bus_8(address); return io_read((address >> 1) & 0x0f);
} }
return io_read((address >> 1) & 0x0f); return m68k_read_bus_8(address);
} }
case 0x11: /* BUSACK */ case 0x11: /* BUSACK */
{ {
if (address & 1) if (!(address & 1))
{
return m68k_read_bus_8(address);
}
unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe;
if (zstate ^ 3)
{ {
unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe;
if (zstate == 3)
{
return data;
}
return (data | 0x01); return (data | 0x01);
} }
return data; return m68k_read_bus_8(address);
} }
case 0x30: /* TIME */ case 0x30: /* TIME */
{ {
if (!cart.hw.time_r) if (cart.hw.time_r)
{ {
return m68k_read_bus_8(address); unsigned int data = cart.hw.time_r(address);
if (address & 1)
{
return (data & 0xff);
}
return (data >> 8);
} }
unsigned int data = cart.hw.time_r(address); return m68k_read_bus_8(address);
if (address & 1)
{
return (data & 0xff);
}
return (data >> 8);
} }
case 0x41: /* OS ROM */ case 0x41: /* OS ROM */
{ {
if (!(address & 1)) if (address & 1)
{ {
return m68k_read_bus_8(address); unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe;
return (gen_bankswitch_r() | data);
} }
unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe; return m68k_read_bus_8(address);
return (gen_bankswitch_r() | data);
} }
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
@ -313,55 +313,48 @@ unsigned int ctrl_io_read_word(unsigned int address)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if (address & 0xe0) if (!(address & 0xe0))
{ {
return m68k_read_bus_16(address); unsigned int data = io_read((address >> 1) & 0x0f);
return (data << 8 | data);
} }
unsigned int data = io_read((address >> 1) & 0x0f); return m68k_read_bus_16(address);
return (data << 8 | data); }
}
case 0x11: /* BUSACK */ case 0x11: /* BUSACK */
{ {
unsigned int data = m68k_read_pcrelative_16(REG_PC) & 0xfeff; unsigned int data = m68k_read_pcrelative_16(REG_PC) & 0xfeff;
if (zstate ^ 3) if (zstate == 3)
{ {
return data | 0x0100; return data;
} }
return data; return (data | 0x0100);
} }
case 0x30: /* TIME */ case 0x30: /* TIME */
{ {
if (!cart.hw.time_r) if (cart.hw.time_r)
{ {
return m68k_read_bus_16(address); return cart.hw.time_r(address);
} }
return cart.hw.time_r(address); return m68k_read_bus_16(address);
} }
case 0x50: /* SVP */ case 0x50: /* SVP */
{ {
switch (address & 0xfe) if ((address & 0xfd) == 0)
{ {
case 0: return svp->ssp1601.gr[SSP_XST].h;
case 2:
{
return svp->ssp1601.gr[SSP_XST].h;
}
case 4:
{
unsigned int temp = svp->ssp1601.gr[SSP_PM0].h;
svp->ssp1601.gr[SSP_PM0].h &= ~1;
return temp;
}
default:
{
return m68k_read_bus_16(address);
}
} }
if ((address & 0xff) == 4)
{
unsigned int data = svp->ssp1601.gr[SSP_PM0].h;
svp->ssp1601.gr[SSP_PM0].h &= ~1;
return data;
}
return m68k_read_bus_16(address);
} }
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
@ -387,35 +380,35 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if ((address & 0xe1) != 0x01) if ((address & 0xe1) == 0x01)
{ {
/* get /LWR only */ /* get /LWR only */
m68k_unused_8_w(address, data); io_write((address >> 1) & 0x0f, data);
return; return;
} }
io_write((address >> 1) & 0x0f, data); m68k_unused_8_w(address, data);
return; return;
} }
case 0x11: /* BUSREQ */ case 0x11: /* BUSREQ */
{ {
if (address & 1) if (!(address & 1))
{ {
m68k_unused_8_w(address, data); gen_zbusreq_w(data & 1, mcycles_68k);
return; return;
} }
gen_zbusreq_w(data & 1, mcycles_68k); m68k_unused_8_w(address, data);
return; return;
} }
case 0x12: /* RESET */ case 0x12: /* RESET */
{ {
if (address & 1) if (!(address & 1))
{ {
m68k_unused_8_w(address, data); gen_zreset_w(data & 1, mcycles_68k);
return; return;
} }
gen_zreset_w(data & 1, mcycles_68k); m68k_unused_8_w(address, data);
return; return;
} }
@ -427,12 +420,12 @@ void ctrl_io_write_byte(unsigned int address, unsigned int data)
case 0x41: /* OS ROM */ case 0x41: /* OS ROM */
{ {
if (!(address & 1)) if (address & 1)
{ {
m68k_unused_8_w(address, data); gen_bankswitch_w(data & 1);
return; return;
} }
gen_bankswitch_w(data & 1); m68k_unused_8_w(address, data);
return; return;
} }
@ -460,12 +453,12 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if (address & 0xe0) if (!(address & 0xe0))
{ {
m68k_unused_16_w(address, data); io_write((address >> 1) & 0x0f, data & 0xff);
return; return;
} }
io_write((address >> 1) & 0x0f, data & 0xff); m68k_unused_16_w(address, data);
return; return;
} }
@ -496,14 +489,14 @@ void ctrl_io_write_word(unsigned int address, unsigned int data)
case 0x50: /* SVP REGISTERS */ case 0x50: /* SVP REGISTERS */
{ {
if (address & 0xfd) if (!(address & 0xfd))
{ {
m68k_unused_16_w(address, data); svp->ssp1601.gr[SSP_XST].h = data;
svp->ssp1601.gr[SSP_PM0].h |= 2;
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
return; return;
} }
svp->ssp1601.gr[SSP_XST].h = data; m68k_unused_16_w(address, data);
svp->ssp1601.gr[SSP_PM0].h |= 2;
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
return; return;
} }
@ -631,12 +624,12 @@ void vdp_write_byte(unsigned int address, unsigned int data)
case 0x10: /* PSG */ case 0x10: /* PSG */
case 0x14: case 0x14:
{ {
if (!(address & 1)) if (address & 1)
{ {
m68k_unused_8_w(address, data); psg_write(mcycles_68k, data);
return; return;
} }
psg_write(mcycles_68k, data); m68k_unused_8_w(address, data);
return; return;
} }

View File

@ -74,11 +74,11 @@ unsigned int zbank_read_ctrl_io(unsigned int address)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if (address & 0xe0) if (!(address & 0xe0))
{ {
return zbank_unused_r(address); return (io_read((address >> 1) & 0x0f));
} }
return (io_read((address >> 1) & 0x0f)); return zbank_unused_r(address);
} }
case 0x11: /* BUSACK */ case 0x11: /* BUSACK */
@ -92,25 +92,25 @@ unsigned int zbank_read_ctrl_io(unsigned int address)
case 0x30: /* TIME */ case 0x30: /* TIME */
{ {
if (!cart.hw.time_r) if (cart.hw.time_r)
{ {
return zbank_unused_r(address); unsigned int data = cart.hw.time_r(address);
if (address & 1)
{
return (data & 0xff);
}
return (data >> 8);
} }
unsigned int data = cart.hw.time_r(address); return zbank_unused_r(address);
if (address & 1)
{
return (data & 0xff);
}
return (data >> 8);
} }
case 0x41: /* OS ROM */ case 0x41: /* OS ROM */
{ {
if (!(address & 1)) if (address & 1)
{ {
return zbank_unused_r(address); return (gen_bankswitch_r() | 0xfe);
} }
return (gen_bankswitch_r() | 0xfe); return zbank_unused_r(address);
} }
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
@ -137,34 +137,34 @@ void zbank_write_ctrl_io(unsigned int address, unsigned int data)
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
/* get /LWR only */ /* get /LWR only */
if ((address & 0xe1) != 0x01) if ((address & 0xe1) == 0x01)
{ {
zbank_unused_w(address, data); io_write((address >> 1) & 0x0f, data);
return; return;
} }
io_write((address >> 1) & 0x0f, data); zbank_unused_w(address, data);
return; return;
} }
case 0x11: /* BUSREQ */ case 0x11: /* BUSREQ */
{ {
if (address & 1) if (!(address & 1))
{ {
zbank_unused_w(address, data); gen_zbusreq_w(data & 1, mcycles_z80);
return; return;
} }
gen_zbusreq_w(data & 1, mcycles_z80); zbank_unused_w(address, data);
return; return;
} }
case 0x12: /* RESET */ case 0x12: /* RESET */
{ {
if (address & 1) if (!(address & 1))
{ {
zbank_unused_w(address, data); gen_zreset_w(data & 1, mcycles_z80);
return; return;
} }
gen_zreset_w(data & 1, mcycles_z80); zbank_unused_w(address, data);
return; return;
} }
@ -176,12 +176,12 @@ void zbank_write_ctrl_io(unsigned int address, unsigned int data)
case 0x41: /* OS ROM */ case 0x41: /* OS ROM */
{ {
if (!(address & 1)) if (address & 1)
{ {
zbank_unused_w(address, data); gen_bankswitch_w(data & 1);
return; return;
} }
gen_bankswitch_w(data & 1); zbank_unused_w(address, data);
return; return;
} }
@ -275,12 +275,12 @@ void zbank_write_vdp(unsigned int address, unsigned int data)
case 0x10: /* PSG */ case 0x10: /* PSG */
case 0x14: case 0x14:
{ {
if (!(address & 1)) if (address & 1)
{ {
zbank_unused_w(address, data); psg_write(mcycles_z80, data);
return; return;
} }
psg_write(mcycles_z80, data); zbank_unused_w(address, data);
return; return;
} }

View File

@ -65,6 +65,8 @@ static inline unsigned int z80_lockup_r(unsigned int address)
} }
return 0xff; return 0xff;
} }
/* /*
Z80 memory handlers Z80 memory handlers
*/ */
@ -85,11 +87,11 @@ unsigned int cpu_readmem16(unsigned int address)
case 3: /* VDP */ case 3: /* VDP */
{ {
if ((address >> 8) != 0x7f) if ((address >> 8) == 0x7f)
{ {
return z80_unused_r(address); return (*zbank_memory_map[0xc0].read)(address);
} }
return (*zbank_memory_map[0xc0].read)(address); return z80_unused_r(address);
} }
default: /* V-bus bank */ default: /* V-bus bank */