mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-25 02:31:49 +01:00
fixed cart mapper, code cleanup
This commit is contained in:
parent
0165ac387f
commit
c4c78f58be
@ -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;
|
||||
|
@ -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/)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
584
source/mem68k.c
584
source/mem68k.c
@ -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,91 +111,79 @@ 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);
|
||||
{
|
||||
if (zbusack) return m68k_read_bus_8(address);
|
||||
|
||||
switch ((address >> 13) & 3)
|
||||
{
|
||||
case 2: /* YM2612 */
|
||||
return fm_read(0, address & 3);
|
||||
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;
|
||||
}
|
||||
@ -241,11 +197,11 @@ void z80_write_byte(uint32 address, uint32 data)
|
||||
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;
|
||||
|
||||
@ -259,19 +215,19 @@ void z80_write_byte(uint32 address, uint32 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,22 +235,22 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,232 +258,194 @@ void z80_write_word(uint32 address, uint32 data)
|
||||
/******* 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 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);
|
||||
|
||||
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 */
|
||||
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;
|
||||
{
|
||||
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 0x11: /* BUSREQ */
|
||||
gen_busreq_w ((data >> 8) & 1);
|
||||
return;
|
||||
|
||||
case 0x12: /* RESET */
|
||||
gen_reset_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 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 0x30: /* TIME */
|
||||
cart_hw.time_w(address & 0xfe, data >> 8);
|
||||
cart_hw.time_w(address, data & 0xff);
|
||||
return;
|
||||
|
||||
case 0x41: /* BOOTROM */
|
||||
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;
|
||||
/* 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
126
source/membnk.c
126
source/membnk.c
@ -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 0x09: /* HVC */
|
||||
case 0x0d:
|
||||
return (vdp_hvc_r() & 0xff);
|
||||
|
||||
case 0x18: /* Unused */
|
||||
case 0x19:
|
||||
case 0x1c:
|
||||
case 0x1d:
|
||||
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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
146
source/vdp.c
146
source/vdp.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user