fixed cart mapper, code cleanup

This commit is contained in:
ekeeke31 2008-12-05 16:26:57 +00:00
parent 0165ac387f
commit c4c78f58be
12 changed files with 460 additions and 564 deletions

View File

@ -33,7 +33,7 @@ CURRENT:
- fixed "Reset" button behavior, now acts more like Genesis Reset button ;-)
- minor bugfixes and menu tweaks
[NGC only]
- added 480p support in menu

View File

@ -3,7 +3,7 @@
* Genesis Plus 1.2a
* Cartridge Hardware support
*
* code by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* Most cartridge protections documented by Haze
* (http://haze.mameworld.info/)
@ -112,7 +112,7 @@ T_CART_ENTRY rom_database[CART_CNT] =
/* previous inputs */
static int old_system[2] = {-1,-1};
int old_system[2] = {-1,-1};
/* temporary memory chunk */
uint8 mem_chunk[0x10000];
@ -341,15 +341,12 @@ void cart_hw_init()
***********************************************/
memset(&cart_hw, 0, sizeof(cart_hw));
/* default write handler for !TIME signal */
cart_hw.time_w = default_time_w;
/* search for game into database */
/* search for game into database */
for (i=0; i < CART_CNT + 1; i++)
{
/* known cart found ! */
if ((rominfo.checksum == rom_database[i].chk_1) &&
(realchecksum == rom_database[i].chk_2))
(realchecksum == rom_database[i].chk_2))
{
/* retrieve hardware information */
memcpy(&cart_hw, &(rom_database[i].cart_hw), sizeof(cart_hw));
@ -405,11 +402,15 @@ void cart_hw_init()
/* assume SSF2 mapper */
cart_hw.bankshift = 1;
}
/* default write handler for !TIME signal */
if (!cart_hw.time_w) cart_hw.time_w = default_time_w;
}
/************************************************************
MAPPER handlers
*************************************************************/
/*
"official" ROM/RAM switch
*/
@ -492,8 +493,8 @@ void special_mapper_w(uint32 address, uint32 data)
Realtec ROM Bankswitch (Earth Defend, Balloon Boy & Funny World, Whac-A-Critter)
*/
void realtec_mapper_w(uint32 address, uint32 data)
{
int i;
{
int i;
uint32 base;
/* 32 x 128k banks */
@ -537,27 +538,27 @@ void seganet_mapper_w(uint32 address, uint32 data)
{
if ((address & 0xff) == 0xf1)
{
int i;
if (data & 1)
{
int i;
if (data & 1)
{
/* ROM Write protected */
for (i=0; i<0x40; i++)
{
m68k_memory_map[i].write8 = m68k_unused_8_w;
m68k_memory_map[i].write16 = m68k_unused_16_w;
zbank_memory_map[i].write = zbank_unused_w;
}
}
else
{
/* ROM Write enabled */
for (i=0; i<0x40; i++);
}
}
else
{
/* ROM Write enabled */
for (i=0; i<0x40; i++)
{
m68k_memory_map[i].write8 = NULL;
m68k_memory_map[i].write16 = NULL;
zbank_memory_map[i].write = NULL;
}
}
}
}
}
@ -571,7 +572,7 @@ uint32 radica_mapper_r(uint32 address)
/* 64 x 64k banks */
for (i = 0; i < 64; i++)
{
{
m68k_memory_map[i].base = &cart_rom[((address++)& 0x3f)<< 16];
}
return 0xff;

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a
* Cartridge Hardware support
*
* code by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* Lots of protection mechanism have been discovered by Haze
* (http://haze.mameworld.info/)

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a
* Serial EEPROM support
*
* code by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a
* Serial EEPROM support
*
* code by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -27,23 +27,7 @@
uint32 m68k_read_bus_8(uint32 address)
{
#ifdef LOGERROR
error("Unused read8 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
error("D0 = %x \n", m68k_get_reg (NULL, M68K_REG_D0));
error("D1 = %x \n", m68k_get_reg (NULL, M68K_REG_D1));
error("D2 = %x \n", m68k_get_reg (NULL, M68K_REG_D2));
error("D3 = %x \n", m68k_get_reg (NULL, M68K_REG_D3));
error("D4 = %x \n", m68k_get_reg (NULL, M68K_REG_D4));
error("D5 = %x \n", m68k_get_reg (NULL, M68K_REG_D5));
error("D6 = %x \n", m68k_get_reg (NULL, M68K_REG_D6));
error("D7 = %x \n", m68k_get_reg (NULL, M68K_REG_D7));
error("A0 = %x \n", m68k_get_reg (NULL, M68K_REG_A0));
error("A1 = %x \n", m68k_get_reg (NULL, M68K_REG_A1));
error("A2 = %x \n", m68k_get_reg (NULL, M68K_REG_A2));
error("A3 = %x \n", m68k_get_reg (NULL, M68K_REG_A3));
error("A4 = %x \n", m68k_get_reg (NULL, M68K_REG_A4));
error("A5 = %x \n", m68k_get_reg (NULL, M68K_REG_A5));
error("A6 = %x \n", m68k_get_reg (NULL, M68K_REG_A6));
error("A7 = %x \n", m68k_get_reg (NULL, M68K_REG_A7));
error("Unused read8 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
return m68k_read_pcrelative_8(REG_PC | (address&1));
@ -52,23 +36,7 @@ uint32 m68k_read_bus_8(uint32 address)
uint32 m68k_read_bus_16(uint32 address)
{
#ifdef LOGERROR
error("Unused read16 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
error("D0 = %x \n", m68k_get_reg (NULL, M68K_REG_D0));
error("D1 = %x \n", m68k_get_reg (NULL, M68K_REG_D1));
error("D2 = %x \n", m68k_get_reg (NULL, M68K_REG_D2));
error("D3 = %x \n", m68k_get_reg (NULL, M68K_REG_D3));
error("D4 = %x \n", m68k_get_reg (NULL, M68K_REG_D4));
error("D5 = %x \n", m68k_get_reg (NULL, M68K_REG_D5));
error("D6 = %x \n", m68k_get_reg (NULL, M68K_REG_D6));
error("D7 = %x \n", m68k_get_reg (NULL, M68K_REG_D7));
error("A0 = %x \n", m68k_get_reg (NULL, M68K_REG_A0));
error("A1 = %x \n", m68k_get_reg (NULL, M68K_REG_A1));
error("A2 = %x \n", m68k_get_reg (NULL, M68K_REG_A2));
error("A3 = %x \n", m68k_get_reg (NULL, M68K_REG_A3));
error("A4 = %x \n", m68k_get_reg (NULL, M68K_REG_A4));
error("A5 = %x \n", m68k_get_reg (NULL, M68K_REG_A5));
error("A6 = %x \n", m68k_get_reg (NULL, M68K_REG_A6));
error("A7 = %x \n", m68k_get_reg (NULL, M68K_REG_A7));
error("Unused read16 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
return m68k_read_pcrelative_16(REG_PC);
}
@ -77,14 +45,14 @@ uint32 m68k_read_bus_16(uint32 address)
void m68k_unused_8_w (uint32 address, uint32 data)
{
#ifdef LOGERROR
error("Unused write8 %08X = %02X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
error("Unused write8 %08X = %02X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
}
void m68k_unused_16_w (uint32 address, uint32 data)
{
#ifdef LOGERROR
error("Unused write16 %08X = %04X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
error("Unused write16 %08X = %04X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
}
@ -97,39 +65,39 @@ void m68k_unused_16_w (uint32 address, uint32 data)
void m68k_lockup_w_8 (uint32 address, uint32 data)
{
#ifdef LOGERROR
error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
error ("Lockup %08X = %02X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
}
void m68k_lockup_w_16 (uint32 address, uint32 data)
{
#ifdef LOGERROR
error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
error ("Lockup %08X = %04X (%08X)\n", address, data, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
}
uint32 m68k_lockup_r_8 (uint32 address)
{
#ifdef LOGERROR
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
error ("Lockup %08X.b (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
return -1;
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
return -1;
}
uint32 m68k_lockup_r_16 (uint32 address)
{
#ifdef LOGERROR
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
error ("Lockup %08X.w (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC));
#endif
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
return -1;
gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice ();
return -1;
}
/* PICO data */
@ -143,135 +111,123 @@ static int pico_page[7] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F};
uint32 eeprom_read_byte(uint32 address)
{
if (address == eeprom.type.sda_out_adr)
return eeprom_read(address, 0);
else
return READ_BYTE(cart_rom, address);
if (address == eeprom.type.sda_out_adr) return eeprom_read(address, 0);
else return READ_BYTE(cart_rom, address);
}
uint32 eeprom_read_word(uint32 address)
{
if (address == (eeprom.type.sda_out_adr & 0xfffffe))
return eeprom_read(address, 1);
else
return *(uint16 *)(cart_rom + address);
if (address == (eeprom.type.sda_out_adr & 0xfffffe)) return eeprom_read(address, 1);
else return *(uint16 *)(cart_rom + address);
}
void eeprom_write_byte(uint32 address, uint32 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))
eeprom_write(address, data, 0);
else
m68k_unused_8_w(address, data);
else m68k_unused_8_w(address, data);
}
void eeprom_write_word(uint32 address, uint32 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)))
eeprom_write(address, data, 1);
else
m68k_unused_16_w (address, data);
else m68k_unused_16_w (address, data);
}
/******* Z80 *************************************************/
uint32 z80_read_byte(uint32 address)
{
if (zbusack) return m68k_read_bus_8(address);
switch ((address >> 13) & 3)
{
case 2: /* YM2612 */
return fm_read(0, address & 3);
{
if (zbusack) return m68k_read_bus_8(address);
switch ((address >> 13) & 3)
{
case 2: /* YM2612 */
return fm_read(0, address & 3);
case 3: /* MISC */
if ((address & 0xff00) == 0x7f00)
return m68k_lockup_r_8(address); /* VDP */
else
return (m68k_read_bus_8(address) | 0xff);
case 3: /* MISC */
if ((address & 0xff00) == 0x7f00) return m68k_lockup_r_8(address); /* VDP */
else return (m68k_read_bus_8(address) | 0xff);
default: /* ZRAM */
return zram[address & 0x1fff];
}
}
default: /* ZRAM */
return zram[address & 0x1fff];
}
}
uint32 z80_read_word(uint32 address)
{
if (zbusack) return m68k_read_bus_16(address);
switch ((address >> 13) & 3)
{
{
case 2: /* YM2612 */
{
{
int temp = fm_read(0, address & 3);
return (temp << 8 | temp);
}
case 3: /* MISC */
if ((address & 0xff00) == 0x7f00)
return m68k_lockup_r_16(address); /* VDP */
else
return (m68k_read_bus_16(address) | 0xffff);
if ((address & 0xff00) == 0x7f00) return m68k_lockup_r_16(address); /* VDP */
else return (m68k_read_bus_16(address) | 0xffff);
default: /* ZRAM */
{
int temp = zram[address & 0x1fff];
return (temp << 8 | temp);
}
}
}
}
}
void z80_write_byte(uint32 address, uint32 data)
{
if (zbusack)
{
{
m68k_unused_8_w(address, data);
return;
}
switch ((address >> 13) & 3)
{
case 2: /* YM2612 */
fm_write(0, address & 3, data);
return;
case 3:
switch ((address >> 8) & 0x7f)
{
case 0x60: /* Bank register */
case 0x60: /* Bank register */
gen_bank_w(data & 1);
return;
case 0x7f: /* VDP */
case 0x7f: /* VDP */
m68k_lockup_w_8(address, data);
return;
default:
m68k_unused_8_w(address, data);
return;
}
default: /* ZRAM */
zram[address & 0x1fff] = data;
count_m68k++; /* Z80 bus latency (Pacman 2: New Adventures) */
return;
}
}
}
void z80_write_word(uint32 address, uint32 data)
{
{
/* Z80 still hold the bus ? */
if (zbusack)
{
{
m68k_unused_16_w(address, data);
return;
}
switch ((address >> 13) & 3)
{
{
case 2: /* YM2612 */
fm_write (0, address & 3, data >> 8);
return;
@ -279,255 +235,217 @@ void z80_write_word(uint32 address, uint32 data)
case 3:
switch ((address >> 8) & 0x7f)
{
case 0x60: /* Bank register */
case 0x60: /* Bank register */
gen_bank_w ((data >> 8) & 1);
return;
case 0x7f: /* VDP */
case 0x7f: /* VDP */
m68k_lockup_w_16(address, data);
return;
default:
default:
m68k_unused_16_w(address, data);
return;
}
}
default: /* ZRAM */
zram[address & 0x1fff] = data >> 8;
return;
default: /* ZRAM */
zram[address & 0x1fff] = data >> 8;
return;
}
}
/******* I/O & CTRL ******************************************/
uint32 ctrl_io_read_byte(uint32 address)
{
/* I/O & CONTROL REGISTERS */
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if (address & 0xe0)
return m68k_read_bus_8(address);
else
return (io_read((address >> 1) & 0x0f));
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if (address & 0xe0) return m68k_read_bus_8(address);
else return (io_read((address >> 1) & 0x0f));
case 0x11: /* BUSACK */
if (address & 1)
return m68k_read_bus_8(address);
else
return ((m68k_read_pcrelative_8(REG_PC) & 0xfe) | zbusack);
case 0x11: /* BUSACK */
if (address & 1) return m68k_read_bus_8(address);
else return ((m68k_read_pcrelative_8(REG_PC) & 0xfe) | zbusack);
case 0x30: /* TIME */
if (cart_hw.time_r)
return cart_hw.time_r(address);
else
return m68k_read_bus_8(address);
case 0x30: /* TIME */
if (cart_hw.time_r) return cart_hw.time_r(address);
else return m68k_read_bus_8(address);
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
return m68k_read_bus_8(address);
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
return m68k_read_bus_8(address);
default: /* Invalid address */
return m68k_lockup_r_8(address);
}
}
default: /* Invalid address */
return m68k_lockup_r_8(address);
}
}
uint32 ctrl_io_read_word(uint32 address)
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
{
if (address & 0xe0)
return m68k_read_bus_16(address);
int temp = io_read((address >> 1) & 0x0f);
return (temp << 8 | temp);
}
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
{
if (address & 0xe0) return m68k_read_bus_16(address);
int temp = io_read((address >> 1) & 0x0f);
return (temp << 8 | temp);
}
case 0x11: /* BUSACK */
return ((m68k_read_pcrelative_16(REG_PC) & 0xfeff) | (zbusack << 8));
case 0x11: /* BUSACK */
return ((m68k_read_pcrelative_16(REG_PC) & 0xfeff) | (zbusack << 8));
case 0x50: /* SVP */
if (svp)
{
switch (address & 0xff)
{
case 0:
case 2:
return svp->ssp1601.gr[SSP_XST].h;
case 0x30: /* TIME */
if (cart_hw.time_r) return cart_hw.time_r(address);
else return m68k_read_bus_16(address);
case 4:
{
uint32 temp = svp->ssp1601.gr[SSP_PM0].h;
svp->ssp1601.gr[SSP_PM0].h &= ~1;
return temp;
}
case 0x50: /* SVP */
if (svp)
{
if ((address & 0xfd) == 0) return svp->ssp1601.gr[SSP_XST].h;
else if ((address & 0xff) == 4)
{
uint32 temp = svp->ssp1601.gr[SSP_PM0].h;
svp->ssp1601.gr[SSP_PM0].h &= ~1;
return temp;
}
}
return m68k_read_bus_16(address);
default:
return m68k_read_bus_16(address);
}
}
else
return m68k_read_bus_16(address);
case 0x30: /* TIME */
if (cart_hw.time_r)
return cart_hw.time_r(address);
else
return m68k_read_bus_16(address);
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
return m68k_read_bus_16(address);
default: /* Invalid address */
case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x41: /* BOOTROM */
case 0x44: /* RADICA */
return m68k_read_bus_16(address);
default: /* Invalid address */
return m68k_lockup_r_16(address);
}
}
}
}
void ctrl_io_write_byte(uint32 address, uint32 data)
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01)
io_write((address >> 1) & 0x0f, data); /* get /LWR only */
else
m68k_unused_8_w(address, data);
return;
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
else m68k_unused_8_w(address, data);
return;
case 0x11: /* BUSREQ */
case 0x11: /* BUSREQ */
if (address & 1) m68k_unused_8_w(address, data);
else gen_busreq_w(data & 1);
return;
case 0x12: /* RESET */
if (address & 1) m68k_unused_8_w(address, data);
else gen_reset_w(data & 1);
return;
case 0x30: /* TIME */
cart_hw.time_w(address, data);
return;
case 0x41: /* BOOTROM */
if (address & 1)
m68k_unused_8_w(address, data);
else
gen_busreq_w(data & 1);
return;
case 0x12: /* RESET */
if (address & 1)
m68k_unused_8_w(address, data);
else
gen_reset_w(data & 1);
return;
case 0x30: /* TIME */
if (cart_hw.time_w)
cart_hw.time_w(address, data);
else
m68k_unused_8_w(address, data);
return;
case 0x41: /* BOOTROM */
if (address & 1)
{
{
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
}
else m68k_unused_8_w (address, data);
return;
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
}
else m68k_unused_8_w (address, data);
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
m68k_unused_8_w(address, data);
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
m68k_unused_8_w(address, data);
return;
default: /* Invalid address */
m68k_lockup_w_8(address, data);
return;
}
}
default: /* Invalid address */
m68k_lockup_w_8(address, data);
return;
}
}
void ctrl_io_write_word(uint32 address, uint32 data)
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if (address & 0xe0)
m68k_unused_16_w (address, data);
else
io_write ((address >> 1) & 0x0f, data & 0xff);
return;
case 0x11: /* BUSREQ */
gen_busreq_w ((data >> 8) & 1);
return;
case 0x12: /* RESET */
gen_reset_w ((data >> 8) & 1);
return;
case 0x50: /* SVP REGISTERS */
if (svp)
{
if (address & 0xfd)
m68k_unused_16_w(address, data);
else
{
/* just guessing here (Notaz) */
svp->ssp1601.gr[SSP_XST].h = data;
svp->ssp1601.gr[SSP_PM0].h |= 2;
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
}
}
else
m68k_unused_16_w (address, data);
return;
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if (address & 0xe0) m68k_unused_16_w (address, data);
else io_write ((address >> 1) & 0x0f, data & 0xff);
return;
case 0x11: /* BUSREQ */
gen_busreq_w ((data >> 8) & 1);
return;
case 0x12: /* RESET */
gen_reset_w ((data >> 8) & 1);
return;
case 0x50: /* SVP REGISTERS */
if (svp)
{
if (address & 0xfd) m68k_unused_16_w(address, data);
else
{
/* just guessing here (Notaz) */
svp->ssp1601.gr[SSP_XST].h = data;
svp->ssp1601.gr[SSP_PM0].h |= 2;
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
}
}
else m68k_unused_16_w (address, data);
return;
case 0x30: /* TIME */
if (cart_hw.time_w)
{
cart_hw.time_w(address & 0xfe, data >> 8);
cart_hw.time_w(address, data & 0xff);
}
else
m68k_unused_16_w (address, data);
return;
case 0x41: /* BOOTROM */
case 0x30: /* TIME */
cart_hw.time_w(address & 0xfe, data >> 8);
cart_hw.time_w(address, data & 0xff);
return;
case 0x41: /* BOOTROM */
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
m68k_unused_16_w (address, data);
return;
default: /* Unused */
m68k_lockup_w_16 (address, data);
return;
}
}
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
m68k_unused_16_w (address, data);
return;
default: /* Unused */
m68k_lockup_w_16 (address, data);
return;
}
}
/******* VDP *************************************************/
@ -574,14 +492,14 @@ uint32 vdp_read_word(uint32 address)
case 0x00: /* DATA */
return vdp_data_r();
case 0x04: /* CTRL */
case 0x04: /* CTRL */
return ((vdp_ctrl_r() & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
case 0x08: /* HVC */
case 0x08: /* HVC */
case 0x0c:
return vdp_hvc_r();
case 0x18: /* Unused */
case 0x18: /* Unused */
case 0x1c:
return m68k_read_bus_16(address);
@ -594,15 +512,15 @@ void vdp_write_byte(uint32 address, uint32 data)
{
switch (address & 0xfc)
{
case 0x00: /* Data port */
case 0x00: /* Data port */
vdp_data_w(data << 8 | data);
return;
case 0x04: /* Control port */
case 0x04: /* Control port */
vdp_ctrl_w(data << 8 | data);
return;
case 0x10: /* PSG */
case 0x10: /* PSG */
case 0x14:
if (address & 1) psg_write(0, data);
else m68k_unused_8_w(address, data);
@ -616,42 +534,42 @@ void vdp_write_byte(uint32 address, uint32 data)
vdp_test_w(data << 8 | data);
return;
default: /* Invalid address */
default: /* Invalid address */
m68k_lockup_w_8(address, data);
return;
}
}
void vdp_write_word(uint32 address, uint32 data)
{
switch (address & 0xfc)
{
case 0x00: /* DATA */
vdp_data_w(data);
return;
case 0x04: /* CTRL */
vdp_ctrl_w(data);
return;
case 0x10: /* PSG */
case 0x14:
psg_write(0, data & 0xff);
return;
case 0x18: /* Unused */
m68k_unused_16_w(address, data);
return;
case 0x1c: /* Test register */
vdp_test_w(data);
return;
default: /* Invalid address */
m68k_lockup_w_16 (address, data);
{
switch (address & 0xfc)
{
case 0x00: /* DATA */
vdp_data_w(data);
return;
}
}
case 0x04: /* CTRL */
vdp_ctrl_w(data);
return;
case 0x10: /* PSG */
case 0x14:
psg_write(0, data & 0xff);
return;
case 0x18: /* Unused */
m68k_unused_16_w(address, data);
return;
case 0x1c: /* Test register */
vdp_test_w(data);
return;
default: /* Invalid address */
m68k_lockup_w_16 (address, data);
return;
}
}
/******* PICO ************************************************/
@ -701,7 +619,7 @@ uint32 pico_read_byte(uint32 address)
default:
return m68k_read_bus_8(address);
}
}
}
uint32 pico_read_word(uint32 address)

View File

@ -60,11 +60,10 @@ void zbank_lockup_w(uint32 address, uint32 data)
}
/* I/O & Control registers */
uint32 zbank_read_ctrl_io(uint32 address)
{
switch ((address >> 8) & 0xff)
{
{
case 0x00: /* I/O chip */
if (address & 0xe0) return zbank_unused_r(address);
else return (io_read((address >> 1) & 0x0f));
@ -89,99 +88,98 @@ uint32 zbank_read_ctrl_io(uint32 address)
default: /* Invalid address */
return zbank_lockup_r(address);
}
}
}
void zbank_write_ctrl_io(uint32 address, uint32 data)
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
{
switch ((address >> 8) & 0xff)
{
case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
else zbank_unused_w(address, data);
return;
return;
case 0x11: /* BUSREQ */
case 0x11: /* BUSREQ */
if (address & 1) zbank_unused_w(address, data);
else gen_busreq_w(data & 1);
return;
else gen_busreq_w(data & 1);
return;
case 0x12: /* RESET */
case 0x12: /* RESET */
if (address & 1) zbank_unused_w(address, data);
else gen_reset_w(data & 1);
return;
else gen_reset_w(data & 1);
return;
case 0x30: /* TIME */
case 0x30: /* TIME */
if (cart_hw.time_w) cart_hw.time_w(address, data);
else zbank_unused_w(address, data);
return;
return;
case 0x41: /* BOOTROM */
if (address & 1)
{
case 0x41: /* BOOTROM */
if (address & 1)
{
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
}
/* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2))
{
config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize);
}
}
else zbank_unused_w (address, data);
return;
return;
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */
case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */
zbank_unused_w(address, data);
return;
return;
default: /* Invalid address */
default: /* Invalid address */
zbank_lockup_w(address, data);
return;
}
}
return;
}
}
/* VDP */
/* VDP */
uint32 zbank_read_vdp(uint32 address)
{
switch (address & 0xfd)
{
case 0x00: /* DATA */
return (vdp_data_r() >> 8);
{
switch (address & 0xfd)
{
case 0x00: /* DATA */
return (vdp_data_r() >> 8);
case 0x01: /* DATA */
return (vdp_data_r() & 0xff);
case 0x01: /* DATA */
return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */
return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
case 0x04: /* CTRL */
return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff);
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
case 0x08: /* HVC */
case 0x0c:
return (vdp_hvc_r() >> 8);
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
case 0x18: /* Unused */
case 0x19:
case 0x1c:
case 0x1d:
case 0x09: /* HVC */
case 0x0d:
return (vdp_hvc_r() & 0xff);
case 0x18: /* Unused */
case 0x19:
case 0x1c:
case 0x1d:
return zbank_unused_r(address);
default: /* Invalid address */
default: /* Invalid address */
return zbank_lockup_r(address);
}
}
}
void zbank_write_vdp(uint32 address, uint32 data)
{

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a
* FreezeState support
*
* coded by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a
* FreezeState support
*
* coded by Eke-Eke, GC/Wii port
* Copyright (C) Eke-Eke, GC/Wii port
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -23,8 +23,6 @@
#include "shared.h"
#define CLOCK_NTSC 53693175
#define CLOCK_PAL 53203424
#define SND_SIZE (snd.buffer_size * sizeof(int16))
/* Global variables */
@ -32,7 +30,6 @@ t_bitmap bitmap;
t_snd snd;
uint8 vdp_rate;
uint16 lines_per_frame;
double Master_Clock;
uint32 aim_m68k;
uint32 count_m68k;
uint32 line_m68k;
@ -55,7 +52,6 @@ void system_init (void)
/* PAL/NTSC timings */
vdp_rate = vdp_pal ? 50 : 60;
lines_per_frame = vdp_pal ? 313 : 262;
Master_Clock = vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC;
gen_init ();
vdp_init ();
@ -139,27 +135,29 @@ int system_frame (int do_skip)
}
odd_frame ^= 1;
/* update VDP status */
status &= 0xFFF5; // clear VBLANK and DMA flags
if (odd_frame && interlaced) status |= 0x0010; // even/odd field flag (interlaced modes only)
/* clear VBLANK and DMA flags */
status &= 0xFFF5;
/* even/odd field flag (interlaced modes only) */
if (odd_frame && interlaced) status |= 0x0010;
else status &= 0xFFEF;
/* Reload H Counter */
/* reload HCounter */
int h_counter = reg[10];
/* parse sprites for line 0 (done on last line) */
parse_satb (0x80);
/* Line processing */
/* process frame */
for (line = 0; line < lines_per_frame; line ++)
{
/* Update VCounter */
/* update VCounter */
v_counter = line;
/* 6-Buttons or Menacer update */
/* update 6-Buttons or Menacer */
input_update();
/* Update CPU cycle counters */
/* update CPU cycle counters */
hint_m68k = count_m68k;
line_m68k = aim_m68k;
line_z80 = aim_z80;
@ -176,10 +174,11 @@ int system_frame (int do_skip)
gen_reset(0);
}
/* Horizontal Interrupt */
/* active display */
if (line <= vdp_height)
{
if(--h_counter < 0)
/* H Interrupt */
if(--h_counter < 0)
{
h_counter = reg[10];
hint_pending = 1;
@ -196,44 +195,46 @@ int system_frame (int do_skip)
if ((line < vdp_height) && (h_counter == 0)) aim_m68k -= 36;
/* update DMA timings */
if (dma_length) dma_update();
if (dma_length) dma_update();
/* Vertical Retrace */
/* vertical retrace */
if (line == vdp_height)
{
{
/* render overscan */
if ((line < end_line) && (!do_skip)) render_line(line, 1);
/* update inputs */
update_input();
/* update inputs (doing this here fix Warriors of Eternal Sun) */
update_input();
/* set VBLANK flag */
status |= 0x08;
/* set VBLANK flag */
status |= 0x08;
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
zirq = 1;
z80_set_irq_line(0, ASSERT_LINE);
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
zirq = 1;
z80_set_irq_line(0, ASSERT_LINE);
/* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */
m68k_run(line_m68k + 84);
/* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */
m68k_run(line_m68k + 84);
if (zreset && !zbusreq)
{
current_z80 = line_z80 + 39 - count_z80;
if (current_z80 > 0) count_z80 += z80_execute(current_z80);
}
else count_z80 = line_z80 + 39;
else count_z80 = line_z80 + 39;
/* Vertical Interrupt */
status |= 0x80;
vint_pending = 1;
if (reg[1] & 0x20) irq_status = (irq_status & 0xff) | 0x2416; // 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant)
/* V Interrupt */
status |= 0x80;
vint_pending = 1;
/* 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant) */
if (reg[1] & 0x20) irq_status = (irq_status & 0xff) | 0x2416;
}
else if (!do_skip)
{
/* render scanline and parse sprites for line n+1 */
render_line(line, 0);
if (line < (vdp_height-1)) parse_satb(0x81 + line);
}
}
}
else
{
@ -241,20 +242,17 @@ int system_frame (int do_skip)
if (dma_length) dma_update();
/* render overscan */
if ((line < end_line) || (line >= start_line))
{
if (!do_skip) render_line(line, 1);
}
if ((!do_skip) && ((line < end_line) || (line >= start_line))) render_line(line, 1);
/* clear any pending Z80 interrupt */
if (zirq)
{
zirq = 0;
z80_set_irq_line(0, CLEAR_LINE);
}
zirq = 0;
z80_set_irq_line(0, CLEAR_LINE);
}
}
/* Process line */
/* process line */
m68k_run(aim_m68k);
if (zreset == 1 && zbusreq == 0)
{

View File

@ -76,7 +76,6 @@ uint32 fifo_lastwrite; /* last VDP write cycle */
uint8 fifo_latency; /* VDP write cycles latency */
uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */
double vdp_timings[4][4];
/* Tables that define the playfield layout */
static const uint8 shift_table[] = { 6, 7, 0, 8 };
@ -84,10 +83,11 @@ static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F };
static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF };
static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 };
static uint16 sat_base_mask; /* Base bits of SAT */
static uint16 sat_addr_mask; /* Index bits of SAT */
static uint32 dma_endCycles; /* 68k cycles to DMA end */
static uint8 dma_type; /* Type of DMA */
static uint16 sat_base_mask; /* Base bits of SAT */
static uint16 sat_addr_mask; /* Index bits of SAT */
static uint32 dma_endCycles; /* 68k cycles to DMA end */
static uint8 dma_type; /* Type of DMA */
static double vdp_timings[4][4]; /* DMA timings */
static inline void vdp_reg_w(unsigned int r, unsigned int d);
@ -119,10 +119,10 @@ static inline void vdp_reg_w(unsigned int r, unsigned int d);
*/
static const uint8 dma_rates[16] = {
8, 9, 83 , 102, /* 68K to VRAM */
8, 9, 83 , 102, /* 68K to VRAM */
16, 18, 167, 205, /* 68K to CRAM or VSRAM */
15, 17, 166, 204, /* DMA fill */
8, 9, 83 , 102, /* DMA Copy */
8, 9, 83 , 102, /* DMA Copy */
};
/* Function prototypes */
@ -159,6 +159,7 @@ void vdp_reset(void)
pending = 0;
status = 0x200; /* fifo empty */
status |= vdp_pal;
ntab = 0;
ntbb = 0;
@ -324,7 +325,7 @@ void dma_update()
*/
static inline void dma_copy(void)
{
int name;
int name;
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
int source = (reg[22] << 8 | reg[21]) & 0xFFFF;
if (!length) length = 0x10000;
@ -365,48 +366,45 @@ static inline void dma_vbus (void)
dma_length = length;
dma_update();
switch (source >> 21)
/* DMA source */
if ((source >> 17) == 0x50)
{
case 5:
do
{
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
(e.g. Z80 isn't reset and 68000 has the bus) */
if (source <= 0xa0ffff) temp = (zbusack ? *(uint16 *)(work_ram + (source & 0xffff)) : 0xffff);
/* Z80 & I/O area */
do
{
/* Return $FFFF only when the Z80 isn't hogging the Z-bus.
(e.g. Z80 isn't reset and 68000 has the bus) */
if (source <= 0xa0ffff) temp = (zbusack ? *(uint16 *)(work_ram + (source & 0xffff)) : 0xffff);
/* The I/O chip and work RAM try to drive the data bus which results
/* The I/O chip and work RAM try to drive the data bus which results
in both values being combined in random ways when read.
We return the I/O chip values which seem to have precedence, */
else if (source <= 0xa1001f)
{
temp = io_read((source >> 1) & 0x0f);
else if (source <= 0xa1001f)
{
temp = io_read((source >> 1) & 0x0f);
temp = (temp << 8 | temp);
}
/* All remaining locations access work RAM */
else temp = *(uint16 *)(work_ram + (source & 0xffff));
source += 2;
source = ((base & 0xFE0000) | (source & 0x1FFFF));
data_write (temp);
}
while (--length);
break;
case 0:
case 1:
if (svp) source = source - 2;
/* All remaining locations access work RAM */
else temp = *(uint16 *)(work_ram + (source & 0xffff));
default:
do
{
temp = *(uint16 *)(m68k_memory_map[source>>16].base + (source & 0xffff));
source += 2;
source = ((base & 0xFE0000) | (source & 0x1FFFF));
data_write (temp);
}
while (--length);
break;
source += 2;
source = ((base & 0xFE0000) | (source & 0x1FFFF));
data_write (temp);
}
while (--length);
}
else
{
/* ROM & RAM */
do
{
temp = *(uint16 *)(m68k_memory_map[source>>16].base + (source & 0xffff));
source += 2;
source = ((base & 0xFE0000) | (source & 0x1FFFF));
data_write (temp);
}
while (--length);
}
/* update length & source address registers */
@ -420,7 +418,7 @@ static inline void dma_vbus (void)
/* VRAM FILL */
static inline void dma_fill(unsigned int data)
{
int name;
int name;
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
if (!length) length = 0x10000;
@ -442,7 +440,6 @@ static inline void dma_fill(unsigned int data)
{
/* update internal SAT (fix Battletech) */
WRITE_BYTE(sat, (addr & sat_addr_mask)^1, data);
WRITE_BYTE(vram, addr^1, data);
MARK_BG_DIRTY (addr);
addr += reg[15];
@ -618,39 +615,26 @@ static inline void vdp_reg_w(unsigned int r, unsigned int d)
switch(r)
{
case 0x00: /* CTRL #1 */
/* Check if HINT has been enabled or disabled */
if (hint_pending && ((d&0x10) != (reg[0]&0x10)))
{
/* update IRQ status */
irq_status &= 0x20;
irq_status |= 0x10;
if (vint_pending && (reg[1] & 0x20))
{
irq_status |= 6;
}
else if (d & 0x10)
{
irq_status |= 4;
}
if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
else if (d & 0x10) irq_status |= 4;
}
break;
case 0x01: /* CTRL #2 */
/* Check if VINT has been enabled or disabled */
if (vint_pending && ((d&0x20) != (reg[1]&0x20)))
{
/* update IRQ status */
irq_status &= 0x20;
irq_status |= 0x110;
if (d & 0x20)
{
irq_status |= 6;
}
else if (hint_pending && (reg[0] & 0x10))
{
irq_status |= 4;
}
if (d & 0x20) irq_status |= 6;
else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
}
/* Check if the viewport height has actually been changed */
if((reg[1] & 8) != (d & 8))
{
@ -792,22 +776,24 @@ unsigned int vdp_ctrl_r(void)
* 8 Write FIFO full
* 9 Write FIFO empty
* 10 - 15 Next word on bus
*/
*/
/* update FIFO flags */
fifo_update();
if (fifo_write_cnt < 4)
{
status &= 0xFEFF;
if (fifo_write_cnt == 0) status |= 0x200;
}
/* update FIFO flags */
fifo_update();
if (fifo_write_cnt < 4)
{
status &= 0xFEFF;
if (fifo_write_cnt == 0) status |= 0x200;
}
else status ^= 0x200;
/* update DMA Busy flag */
if ((status & 2) && !dma_length && (count_m68k >= dma_endCycles))
{
status &= 0xFFFD;
}
unsigned int temp = status | vdp_pal;
unsigned int temp = status;
/* display OFF: VBLANK flag is set */
if (!(reg[1] & 0x40)) temp |= 0x8;
@ -917,25 +903,21 @@ void vdp_test_w(unsigned int value)
int vdp_int_ack_callback(int int_level)
{
/* VINT triggered ? */
if (irq_status&0x20)
{
vint_pending = 0;
status &= ~0x80; /* clear VINT flag */
status &= ~0x80; /* clear VINT flag */
}
else
{
hint_pending = 0;
hint_pending = 0;
}
/* update IRQ status */
irq_status = 0x10;
if (vint_pending && (reg[1] & 0x20))
{
irq_status |= 6;
}
else if (hint_pending && (reg[0] & 0x10))
{
irq_status |= 4;
}
if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
return M68K_INT_ACK_AUTOVECTOR;
}

View File

@ -63,7 +63,6 @@ extern int32 fifo_write_cnt;
extern uint32 fifo_lastwrite;
extern uint8 fifo_latency;
extern uint8 vdp_pal;
extern double vdp_timings[4][4];
extern uint8 *vctab;
extern uint8 *hctab;