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

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

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a * Genesis Plus 1.2a
* Cartridge Hardware support * 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 * Lots of protection mechanism have been discovered by Haze
* (http://haze.mameworld.info/) * (http://haze.mameworld.info/)

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a * Genesis Plus 1.2a
* Serial EEPROM support * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a * Genesis Plus 1.2a
* Serial EEPROM support * 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 * 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 * 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) uint32 m68k_read_bus_8(uint32 address)
{ {
#ifdef LOGERROR #ifdef LOGERROR
error("Unused read8 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC)); 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));
#endif #endif
return m68k_read_pcrelative_8(REG_PC | (address&1)); 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) uint32 m68k_read_bus_16(uint32 address)
{ {
#ifdef LOGERROR #ifdef LOGERROR
error("Unused read16 %08X (%08X)\n", address, m68k_get_reg (NULL, M68K_REG_PC)); 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));
#endif #endif
return m68k_read_pcrelative_16(REG_PC); 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) void m68k_unused_8_w (uint32 address, uint32 data)
{ {
#ifdef LOGERROR #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 #endif
} }
void m68k_unused_16_w (uint32 address, uint32 data) void m68k_unused_16_w (uint32 address, uint32 data)
{ {
#ifdef LOGERROR #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 #endif
} }
@ -97,39 +65,39 @@ void m68k_unused_16_w (uint32 address, uint32 data)
void m68k_lockup_w_8 (uint32 address, uint32 data) void m68k_lockup_w_8 (uint32 address, uint32 data)
{ {
#ifdef LOGERROR #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 #endif
gen_running = config.force_dtack; gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice (); if (!gen_running) m68k_end_timeslice ();
} }
void m68k_lockup_w_16 (uint32 address, uint32 data) void m68k_lockup_w_16 (uint32 address, uint32 data)
{ {
#ifdef LOGERROR #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 #endif
gen_running = config.force_dtack; gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice (); if (!gen_running) m68k_end_timeslice ();
} }
uint32 m68k_lockup_r_8 (uint32 address) uint32 m68k_lockup_r_8 (uint32 address)
{ {
#ifdef LOGERROR #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 #endif
gen_running = config.force_dtack; gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice (); if (!gen_running) m68k_end_timeslice ();
return -1; return -1;
} }
uint32 m68k_lockup_r_16 (uint32 address) uint32 m68k_lockup_r_16 (uint32 address)
{ {
#ifdef LOGERROR #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 #endif
gen_running = config.force_dtack; gen_running = config.force_dtack;
if (!gen_running) m68k_end_timeslice (); if (!gen_running) m68k_end_timeslice ();
return -1; return -1;
} }
/* PICO data */ /* PICO data */
@ -143,91 +111,79 @@ static int pico_page[7] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F};
uint32 eeprom_read_byte(uint32 address) uint32 eeprom_read_byte(uint32 address)
{ {
if (address == eeprom.type.sda_out_adr) if (address == eeprom.type.sda_out_adr) return eeprom_read(address, 0);
return eeprom_read(address, 0); else return READ_BYTE(cart_rom, address);
else
return READ_BYTE(cart_rom, address);
} }
uint32 eeprom_read_word(uint32 address) uint32 eeprom_read_word(uint32 address)
{ {
if (address == (eeprom.type.sda_out_adr & 0xfffffe)) if (address == (eeprom.type.sda_out_adr & 0xfffffe)) return eeprom_read(address, 1);
return eeprom_read(address, 1); else return *(uint16 *)(cart_rom + address);
else
return *(uint16 *)(cart_rom + address);
} }
void eeprom_write_byte(uint32 address, uint32 data) void eeprom_write_byte(uint32 address, uint32 data)
{ {
if ((address == eeprom.type.sda_in_adr) || if ((address == eeprom.type.sda_in_adr) || (address == eeprom.type.scl_adr))
(address == eeprom.type.scl_adr))
eeprom_write(address, data, 0); eeprom_write(address, data, 0);
else else m68k_unused_8_w(address, data);
m68k_unused_8_w(address, data);
} }
void eeprom_write_word(uint32 address, uint32 data) void eeprom_write_word(uint32 address, uint32 data)
{ {
if ((address == (eeprom.type.sda_in_adr&0xfffffe)) || if ((address == (eeprom.type.sda_in_adr&0xfffffe)) || (address == (eeprom.type.scl_adr&0xfffffe)))
(address == (eeprom.type.scl_adr&0xfffffe)))
eeprom_write(address, data, 1); eeprom_write(address, data, 1);
else else m68k_unused_16_w (address, data);
m68k_unused_16_w (address, data);
} }
/******* Z80 *************************************************/ /******* Z80 *************************************************/
uint32 z80_read_byte(uint32 address) 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) switch ((address >> 13) & 3)
{ {
case 2: /* YM2612 */ case 2: /* YM2612 */
return fm_read(0, address & 3); return fm_read(0, address & 3);
case 3: /* MISC */ case 3: /* MISC */
if ((address & 0xff00) == 0x7f00) if ((address & 0xff00) == 0x7f00) return m68k_lockup_r_8(address); /* VDP */
return m68k_lockup_r_8(address); /* VDP */ else return (m68k_read_bus_8(address) | 0xff);
else
return (m68k_read_bus_8(address) | 0xff);
default: /* ZRAM */ default: /* ZRAM */
return zram[address & 0x1fff]; return zram[address & 0x1fff];
} }
} }
uint32 z80_read_word(uint32 address) uint32 z80_read_word(uint32 address)
{ {
if (zbusack) return m68k_read_bus_16(address); if (zbusack) return m68k_read_bus_16(address);
switch ((address >> 13) & 3) switch ((address >> 13) & 3)
{ {
case 2: /* YM2612 */ case 2: /* YM2612 */
{ {
int temp = fm_read(0, address & 3); int temp = fm_read(0, address & 3);
return (temp << 8 | temp); return (temp << 8 | temp);
} }
case 3: /* MISC */ case 3: /* MISC */
if ((address & 0xff00) == 0x7f00) if ((address & 0xff00) == 0x7f00) return m68k_lockup_r_16(address); /* VDP */
return m68k_lockup_r_16(address); /* VDP */ else return (m68k_read_bus_16(address) | 0xffff);
else
return (m68k_read_bus_16(address) | 0xffff);
default: /* ZRAM */ default: /* ZRAM */
{ {
int temp = zram[address & 0x1fff]; int temp = zram[address & 0x1fff];
return (temp << 8 | temp); return (temp << 8 | temp);
} }
} }
} }
void z80_write_byte(uint32 address, uint32 data) void z80_write_byte(uint32 address, uint32 data)
{ {
if (zbusack) if (zbusack)
{ {
m68k_unused_8_w(address, data); m68k_unused_8_w(address, data);
return; return;
} }
@ -241,11 +197,11 @@ void z80_write_byte(uint32 address, uint32 data)
case 3: case 3:
switch ((address >> 8) & 0x7f) switch ((address >> 8) & 0x7f)
{ {
case 0x60: /* Bank register */ case 0x60: /* Bank register */
gen_bank_w(data & 1); gen_bank_w(data & 1);
return; return;
case 0x7f: /* VDP */ case 0x7f: /* VDP */
m68k_lockup_w_8(address, data); m68k_lockup_w_8(address, data);
return; return;
@ -259,19 +215,19 @@ void z80_write_byte(uint32 address, uint32 data)
count_m68k++; /* Z80 bus latency (Pacman 2: New Adventures) */ count_m68k++; /* Z80 bus latency (Pacman 2: New Adventures) */
return; return;
} }
} }
void z80_write_word(uint32 address, uint32 data) void z80_write_word(uint32 address, uint32 data)
{ {
/* Z80 still hold the bus ? */ /* Z80 still hold the bus ? */
if (zbusack) if (zbusack)
{ {
m68k_unused_16_w(address, data); m68k_unused_16_w(address, data);
return; return;
} }
switch ((address >> 13) & 3) switch ((address >> 13) & 3)
{ {
case 2: /* YM2612 */ case 2: /* YM2612 */
fm_write (0, address & 3, data >> 8); fm_write (0, address & 3, data >> 8);
return; return;
@ -279,22 +235,22 @@ void z80_write_word(uint32 address, uint32 data)
case 3: case 3:
switch ((address >> 8) & 0x7f) switch ((address >> 8) & 0x7f)
{ {
case 0x60: /* Bank register */ case 0x60: /* Bank register */
gen_bank_w ((data >> 8) & 1); gen_bank_w ((data >> 8) & 1);
return; return;
case 0x7f: /* VDP */ case 0x7f: /* VDP */
m68k_lockup_w_16(address, data); m68k_lockup_w_16(address, data);
return; return;
default: default:
m68k_unused_16_w(address, data); m68k_unused_16_w(address, data);
return; return;
} }
default: /* ZRAM */ default: /* ZRAM */
zram[address & 0x1fff] = data >> 8; zram[address & 0x1fff] = data >> 8;
return; return;
} }
} }
@ -302,232 +258,194 @@ void z80_write_word(uint32 address, uint32 data)
/******* I/O & CTRL ******************************************/ /******* I/O & CTRL ******************************************/
uint32 ctrl_io_read_byte(uint32 address) uint32 ctrl_io_read_byte(uint32 address)
{ {
/* I/O & CONTROL REGISTERS */ switch ((address >> 8) & 0xff)
switch ((address >> 8) & 0xff) {
{ case 0x00: /* I/O chip */
case 0x00: /* I/O chip */ if (address & 0xe0) return m68k_read_bus_8(address);
if (address & 0xe0) else return (io_read((address >> 1) & 0x0f));
return m68k_read_bus_8(address);
else
return (io_read((address >> 1) & 0x0f));
case 0x11: /* BUSACK */ case 0x11: /* BUSACK */
if (address & 1) if (address & 1) return m68k_read_bus_8(address);
return m68k_read_bus_8(address); else return ((m68k_read_pcrelative_8(REG_PC) & 0xfe) | zbusack);
else
return ((m68k_read_pcrelative_8(REG_PC) & 0xfe) | zbusack);
case 0x30: /* TIME */ case 0x30: /* TIME */
if (cart_hw.time_r) if (cart_hw.time_r) return cart_hw.time_r(address);
return cart_hw.time_r(address); else return m68k_read_bus_8(address);
else
return m68k_read_bus_8(address);
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
case 0x12: /* RESET */ case 0x12: /* RESET */
case 0x20: /* MEGA-CD */ case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */ case 0x40: /* TMSS */
case 0x41: /* BOOTROM */ case 0x41: /* BOOTROM */
case 0x44: /* RADICA */ case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */ case 0x50: /* SVP REGISTERS */
return m68k_read_bus_8(address); return m68k_read_bus_8(address);
default: /* Invalid address */ default: /* Invalid address */
return m68k_lockup_r_8(address); return m68k_lockup_r_8(address);
} }
} }
uint32 ctrl_io_read_word(uint32 address) uint32 ctrl_io_read_word(uint32 address)
{ {
switch ((address >> 8) & 0xff) switch ((address >> 8) & 0xff)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
{ {
if (address & 0xe0) if (address & 0xe0) return m68k_read_bus_16(address);
return m68k_read_bus_16(address); int temp = io_read((address >> 1) & 0x0f);
int temp = io_read((address >> 1) & 0x0f); return (temp << 8 | temp);
return (temp << 8 | temp); }
}
case 0x11: /* BUSACK */ case 0x11: /* BUSACK */
return ((m68k_read_pcrelative_16(REG_PC) & 0xfeff) | (zbusack << 8)); return ((m68k_read_pcrelative_16(REG_PC) & 0xfeff) | (zbusack << 8));
case 0x50: /* SVP */ case 0x30: /* TIME */
if (svp) if (cart_hw.time_r) return cart_hw.time_r(address);
{ else return m68k_read_bus_16(address);
switch (address & 0xff)
{
case 0:
case 2:
return svp->ssp1601.gr[SSP_XST].h;
case 4: case 0x50: /* SVP */
{ if (svp)
uint32 temp = svp->ssp1601.gr[SSP_PM0].h; {
svp->ssp1601.gr[SSP_PM0].h &= ~1; if ((address & 0xfd) == 0) return svp->ssp1601.gr[SSP_XST].h;
return temp; 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: case 0x10: /* MEMORY MODE */
return m68k_read_bus_16(address); case 0x12: /* RESET */
} case 0x20: /* MEGA-CD */
} case 0x40: /* TMSS */
else case 0x41: /* BOOTROM */
return m68k_read_bus_16(address); case 0x44: /* RADICA */
return m68k_read_bus_16(address);
case 0x30: /* TIME */ default: /* Invalid address */
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 */
return m68k_lockup_r_16(address); return m68k_lockup_r_16(address);
} }
} }
void ctrl_io_write_byte(uint32 address, uint32 data) void ctrl_io_write_byte(uint32 address, uint32 data)
{ {
switch ((address >> 8) & 0xff) switch ((address >> 8) & 0xff)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
io_write((address >> 1) & 0x0f, data); /* get /LWR only */ else m68k_unused_8_w(address, data);
else return;
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) 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; m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */ /* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2)) if (!(config.bios_enabled & 2))
{ {
config.bios_enabled |= 2; config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800); memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize); memset(cart_rom, 0, genromsize);
} }
} }
else m68k_unused_8_w (address, data); else m68k_unused_8_w (address, data);
return; return;
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */ case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */ case 0x40: /* TMSS */
case 0x44: /* RADICA */ case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */ case 0x50: /* SVP REGISTERS */
m68k_unused_8_w(address, data); m68k_unused_8_w(address, data);
return; return;
default: /* Invalid address */ default: /* Invalid address */
m68k_lockup_w_8(address, data); m68k_lockup_w_8(address, data);
return; return;
} }
} }
void ctrl_io_write_word(uint32 address, uint32 data) void ctrl_io_write_word(uint32 address, uint32 data)
{ {
switch ((address >> 8) & 0xff) switch ((address >> 8) & 0xff)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
if (address & 0xe0) if (address & 0xe0) m68k_unused_16_w (address, data);
m68k_unused_16_w (address, data); else io_write ((address >> 1) & 0x0f, data & 0xff);
else return;
io_write ((address >> 1) & 0x0f, data & 0xff);
return;
case 0x11: /* BUSREQ */ case 0x11: /* BUSREQ */
gen_busreq_w ((data >> 8) & 1); gen_busreq_w ((data >> 8) & 1);
return; return;
case 0x12: /* RESET */ case 0x12: /* RESET */
gen_reset_w ((data >> 8) & 1); gen_reset_w ((data >> 8) & 1);
return; return;
case 0x50: /* SVP REGISTERS */ case 0x50: /* SVP REGISTERS */
if (svp) if (svp)
{ {
if (address & 0xfd) if (address & 0xfd) m68k_unused_16_w(address, data);
m68k_unused_16_w(address, data); else
else {
{ /* just guessing here (Notaz) */
/* just guessing here (Notaz) */ svp->ssp1601.gr[SSP_XST].h = data;
svp->ssp1601.gr[SSP_XST].h = data; svp->ssp1601.gr[SSP_PM0].h |= 2;
svp->ssp1601.gr[SSP_PM0].h |= 2; svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0; }
} }
} else m68k_unused_16_w (address, data);
else return;
m68k_unused_16_w (address, data);
return;
case 0x30: /* TIME */ case 0x30: /* TIME */
if (cart_hw.time_w) cart_hw.time_w(address & 0xfe, data >> 8);
{ cart_hw.time_w(address, data & 0xff);
cart_hw.time_w(address & 0xfe, data >> 8); return;
cart_hw.time_w(address, data & 0xff);
}
else
m68k_unused_16_w (address, data);
return;
case 0x41: /* BOOTROM */ case 0x41: /* BOOTROM */
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom; m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */ /* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2)) if (!(config.bios_enabled & 2))
{ {
config.bios_enabled |= 2; config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800); memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize); memset(cart_rom, 0, genromsize);
} }
return; return;
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */ case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */ case 0x40: /* TMSS */
case 0x44: /* RADICA */ case 0x44: /* RADICA */
m68k_unused_16_w (address, data); m68k_unused_16_w (address, data);
return; return;
default: /* Unused */ default: /* Unused */
m68k_lockup_w_16 (address, data); m68k_lockup_w_16 (address, data);
return; return;
} }
} }
/******* VDP *************************************************/ /******* VDP *************************************************/
@ -574,14 +492,14 @@ uint32 vdp_read_word(uint32 address)
case 0x00: /* DATA */ case 0x00: /* DATA */
return vdp_data_r(); return vdp_data_r();
case 0x04: /* CTRL */ case 0x04: /* CTRL */
return ((vdp_ctrl_r() & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00)); return ((vdp_ctrl_r() & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
case 0x08: /* HVC */ case 0x08: /* HVC */
case 0x0c: case 0x0c:
return vdp_hvc_r(); return vdp_hvc_r();
case 0x18: /* Unused */ case 0x18: /* Unused */
case 0x1c: case 0x1c:
return m68k_read_bus_16(address); return m68k_read_bus_16(address);
@ -594,15 +512,15 @@ void vdp_write_byte(uint32 address, uint32 data)
{ {
switch (address & 0xfc) switch (address & 0xfc)
{ {
case 0x00: /* Data port */ case 0x00: /* Data port */
vdp_data_w(data << 8 | data); vdp_data_w(data << 8 | data);
return; return;
case 0x04: /* Control port */ case 0x04: /* Control port */
vdp_ctrl_w(data << 8 | data); vdp_ctrl_w(data << 8 | data);
return; return;
case 0x10: /* PSG */ case 0x10: /* PSG */
case 0x14: case 0x14:
if (address & 1) psg_write(0, data); if (address & 1) psg_write(0, data);
else m68k_unused_8_w(address, 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); vdp_test_w(data << 8 | data);
return; return;
default: /* Invalid address */ default: /* Invalid address */
m68k_lockup_w_8(address, data); m68k_lockup_w_8(address, data);
return; return;
} }
} }
void vdp_write_word(uint32 address, uint32 data) void vdp_write_word(uint32 address, uint32 data)
{ {
switch (address & 0xfc) switch (address & 0xfc)
{ {
case 0x00: /* DATA */ case 0x00: /* DATA */
vdp_data_w(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; 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 ************************************************/ /******* PICO ************************************************/
@ -701,7 +619,7 @@ uint32 pico_read_byte(uint32 address)
default: default:
return m68k_read_bus_8(address); return m68k_read_bus_8(address);
} }
} }
uint32 pico_read_word(uint32 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 */ /* I/O & Control registers */
uint32 zbank_read_ctrl_io(uint32 address) uint32 zbank_read_ctrl_io(uint32 address)
{ {
switch ((address >> 8) & 0xff) switch ((address >> 8) & 0xff)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
if (address & 0xe0) return zbank_unused_r(address); if (address & 0xe0) return zbank_unused_r(address);
else return (io_read((address >> 1) & 0x0f)); else return (io_read((address >> 1) & 0x0f));
@ -89,99 +88,98 @@ uint32 zbank_read_ctrl_io(uint32 address)
default: /* Invalid address */ default: /* Invalid address */
return zbank_lockup_r(address); return zbank_lockup_r(address);
} }
} }
void zbank_write_ctrl_io(uint32 address, uint32 data) void zbank_write_ctrl_io(uint32 address, uint32 data)
{ {
switch ((address >> 8) & 0xff) switch ((address >> 8) & 0xff)
{ {
case 0x00: /* I/O chip */ case 0x00: /* I/O chip */
if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */ if ((address & 0xe1) == 0x01) io_write((address >> 1) & 0x0f, data); /* get /LWR only */
else zbank_unused_w(address, data); else zbank_unused_w(address, data);
return; return;
case 0x11: /* BUSREQ */ case 0x11: /* BUSREQ */
if (address & 1) zbank_unused_w(address, data); if (address & 1) zbank_unused_w(address, data);
else gen_busreq_w(data & 1); else gen_busreq_w(data & 1);
return; return;
case 0x12: /* RESET */ case 0x12: /* RESET */
if (address & 1) zbank_unused_w(address, data); if (address & 1) zbank_unused_w(address, data);
else gen_reset_w(data & 1); else gen_reset_w(data & 1);
return; return;
case 0x30: /* TIME */ case 0x30: /* TIME */
if (cart_hw.time_w) cart_hw.time_w(address, data); if (cart_hw.time_w) cart_hw.time_w(address, data);
else zbank_unused_w(address, data); else zbank_unused_w(address, data);
return; return;
case 0x41: /* BOOTROM */ case 0x41: /* BOOTROM */
if (address & 1) if (address & 1)
{ {
m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom; m68k_memory_map[0].base = (data & 1) ? default_rom : bios_rom;
/* autodetect BIOS ROM file */ /* autodetect BIOS ROM file */
if (!(config.bios_enabled & 2)) if (!(config.bios_enabled & 2))
{ {
config.bios_enabled |= 2; config.bios_enabled |= 2;
memcpy(bios_rom, cart_rom, 0x800); memcpy(bios_rom, cart_rom, 0x800);
memset(cart_rom, 0, genromsize); memset(cart_rom, 0, genromsize);
} }
} }
else zbank_unused_w (address, data); else zbank_unused_w (address, data);
return; return;
case 0x10: /* MEMORY MODE */ case 0x10: /* MEMORY MODE */
case 0x20: /* MEGA-CD */ case 0x20: /* MEGA-CD */
case 0x40: /* TMSS */ case 0x40: /* TMSS */
case 0x44: /* RADICA */ case 0x44: /* RADICA */
case 0x50: /* SVP REGISTERS */ case 0x50: /* SVP REGISTERS */
zbank_unused_w(address, data); zbank_unused_w(address, data);
return; return;
default: /* Invalid address */ default: /* Invalid address */
zbank_lockup_w(address, data); zbank_lockup_w(address, data);
return; return;
} }
} }
/* VDP */ /* VDP */
uint32 zbank_read_vdp(uint32 address) uint32 zbank_read_vdp(uint32 address)
{ {
switch (address & 0xfd) switch (address & 0xfd)
{ {
case 0x00: /* DATA */ case 0x00: /* DATA */
return (vdp_data_r() >> 8); return (vdp_data_r() >> 8);
case 0x01: /* DATA */ case 0x01: /* DATA */
return (vdp_data_r() & 0xff); return (vdp_data_r() & 0xff);
case 0x04: /* CTRL */ case 0x04: /* CTRL */
return (0xfc | ((vdp_ctrl_r() >> 8) & 3)); return (0xfc | ((vdp_ctrl_r() >> 8) & 3));
case 0x05: /* CTRL */ case 0x05: /* CTRL */
return (vdp_ctrl_r() & 0xff); return (vdp_ctrl_r() & 0xff);
case 0x08: /* HVC */ case 0x08: /* HVC */
case 0x0c: case 0x0c:
return (vdp_hvc_r() >> 8); return (vdp_hvc_r() >> 8);
case 0x09: /* HVC */ case 0x09: /* HVC */
case 0x0d: case 0x0d:
return (vdp_hvc_r() & 0xff); return (vdp_hvc_r() & 0xff);
case 0x18: /* Unused */ case 0x18: /* Unused */
case 0x19: case 0x19:
case 0x1c: case 0x1c:
case 0x1d: case 0x1d:
return zbank_unused_r(address); return zbank_unused_r(address);
default: /* Invalid address */ default: /* Invalid address */
return zbank_lockup_r(address); return zbank_lockup_r(address);
} }
} }
void zbank_write_vdp(uint32 address, uint32 data) void zbank_write_vdp(uint32 address, uint32 data)
{ {

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a * Genesis Plus 1.2a
* FreezeState support * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@ -2,7 +2,7 @@
* Genesis Plus 1.2a * Genesis Plus 1.2a
* FreezeState support * 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 * 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 * it under the terms of the GNU General Public License as published by

View File

@ -23,8 +23,6 @@
#include "shared.h" #include "shared.h"
#define CLOCK_NTSC 53693175
#define CLOCK_PAL 53203424
#define SND_SIZE (snd.buffer_size * sizeof(int16)) #define SND_SIZE (snd.buffer_size * sizeof(int16))
/* Global variables */ /* Global variables */
@ -32,7 +30,6 @@ t_bitmap bitmap;
t_snd snd; t_snd snd;
uint8 vdp_rate; uint8 vdp_rate;
uint16 lines_per_frame; uint16 lines_per_frame;
double Master_Clock;
uint32 aim_m68k; uint32 aim_m68k;
uint32 count_m68k; uint32 count_m68k;
uint32 line_m68k; uint32 line_m68k;
@ -55,7 +52,6 @@ void system_init (void)
/* PAL/NTSC timings */ /* PAL/NTSC timings */
vdp_rate = vdp_pal ? 50 : 60; vdp_rate = vdp_pal ? 50 : 60;
lines_per_frame = vdp_pal ? 313 : 262; lines_per_frame = vdp_pal ? 313 : 262;
Master_Clock = vdp_pal ? (double)CLOCK_PAL : (double)CLOCK_NTSC;
gen_init (); gen_init ();
vdp_init (); vdp_init ();
@ -139,27 +135,29 @@ int system_frame (int do_skip)
} }
odd_frame ^= 1; odd_frame ^= 1;
/* update VDP status */ /* clear VBLANK and DMA flags */
status &= 0xFFF5; // clear VBLANK and DMA flags status &= 0xFFF5;
if (odd_frame && interlaced) status |= 0x0010; // even/odd field flag (interlaced modes only)
/* even/odd field flag (interlaced modes only) */
if (odd_frame && interlaced) status |= 0x0010;
else status &= 0xFFEF; else status &= 0xFFEF;
/* Reload H Counter */ /* reload HCounter */
int h_counter = reg[10]; int h_counter = reg[10];
/* parse sprites for line 0 (done on last line) */ /* parse sprites for line 0 (done on last line) */
parse_satb (0x80); parse_satb (0x80);
/* Line processing */ /* process frame */
for (line = 0; line < lines_per_frame; line ++) for (line = 0; line < lines_per_frame; line ++)
{ {
/* Update VCounter */ /* update VCounter */
v_counter = line; v_counter = line;
/* 6-Buttons or Menacer update */ /* update 6-Buttons or Menacer */
input_update(); input_update();
/* Update CPU cycle counters */ /* update CPU cycle counters */
hint_m68k = count_m68k; hint_m68k = count_m68k;
line_m68k = aim_m68k; line_m68k = aim_m68k;
line_z80 = aim_z80; line_z80 = aim_z80;
@ -176,10 +174,11 @@ int system_frame (int do_skip)
gen_reset(0); gen_reset(0);
} }
/* Horizontal Interrupt */ /* active display */
if (line <= vdp_height) if (line <= vdp_height)
{ {
if(--h_counter < 0) /* H Interrupt */
if(--h_counter < 0)
{ {
h_counter = reg[10]; h_counter = reg[10];
hint_pending = 1; hint_pending = 1;
@ -196,44 +195,46 @@ int system_frame (int do_skip)
if ((line < vdp_height) && (h_counter == 0)) aim_m68k -= 36; if ((line < vdp_height) && (h_counter == 0)) aim_m68k -= 36;
/* update DMA timings */ /* update DMA timings */
if (dma_length) dma_update(); if (dma_length) dma_update();
/* Vertical Retrace */ /* vertical retrace */
if (line == vdp_height) if (line == vdp_height)
{ {
/* render overscan */ /* render overscan */
if ((line < end_line) && (!do_skip)) render_line(line, 1); if ((line < end_line) && (!do_skip)) render_line(line, 1);
/* update inputs */ /* update inputs (doing this here fix Warriors of Eternal Sun) */
update_input(); update_input();
/* set VBLANK flag */ /* set VBLANK flag */
status |= 0x08; status |= 0x08;
/* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */ /* Z80 interrupt is 16ms period (one frame) and 64us length (one scanline) */
zirq = 1; zirq = 1;
z80_set_irq_line(0, ASSERT_LINE); z80_set_irq_line(0, ASSERT_LINE);
/* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */ /* delay between HINT, VBLANK and VINT (Dracula, OutRunners, VR Troopers) */
m68k_run(line_m68k + 84); m68k_run(line_m68k + 84);
if (zreset && !zbusreq) if (zreset && !zbusreq)
{ {
current_z80 = line_z80 + 39 - count_z80; current_z80 = line_z80 + 39 - count_z80;
if (current_z80 > 0) count_z80 += z80_execute(current_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 */ /* V Interrupt */
status |= 0x80; status |= 0x80;
vint_pending = 1; vint_pending = 1;
if (reg[1] & 0x20) irq_status = (irq_status & 0xff) | 0x2416; // 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant)
/* 36 cycles latency after VINT occurence flag (Ex-Mutants, Tyrant) */
if (reg[1] & 0x20) irq_status = (irq_status & 0xff) | 0x2416;
} }
else if (!do_skip) else if (!do_skip)
{ {
/* render scanline and parse sprites for line n+1 */ /* render scanline and parse sprites for line n+1 */
render_line(line, 0); render_line(line, 0);
if (line < (vdp_height-1)) parse_satb(0x81 + line); if (line < (vdp_height-1)) parse_satb(0x81 + line);
} }
} }
else else
{ {
@ -241,20 +242,17 @@ int system_frame (int do_skip)
if (dma_length) dma_update(); if (dma_length) dma_update();
/* render overscan */ /* render overscan */
if ((line < end_line) || (line >= start_line)) if ((!do_skip) && ((line < end_line) || (line >= start_line))) render_line(line, 1);
{
if (!do_skip) render_line(line, 1);
}
/* clear any pending Z80 interrupt */ /* clear any pending Z80 interrupt */
if (zirq) if (zirq)
{ {
zirq = 0; zirq = 0;
z80_set_irq_line(0, CLEAR_LINE); z80_set_irq_line(0, CLEAR_LINE);
} }
} }
/* Process line */ /* process line */
m68k_run(aim_m68k); m68k_run(aim_m68k);
if (zreset == 1 && zbusreq == 0) 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 fifo_latency; /* VDP write cycles latency */
uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */ uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */
double vdp_timings[4][4];
/* Tables that define the playfield layout */ /* Tables that define the playfield layout */
static const uint8 shift_table[] = { 6, 7, 0, 8 }; 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 uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF };
static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 }; static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 };
static uint16 sat_base_mask; /* Base bits of SAT */ static uint16 sat_base_mask; /* Base bits of SAT */
static uint16 sat_addr_mask; /* Index bits of SAT */ static uint16 sat_addr_mask; /* Index bits of SAT */
static uint32 dma_endCycles; /* 68k cycles to DMA end */ static uint32 dma_endCycles; /* 68k cycles to DMA end */
static uint8 dma_type; /* Type of DMA */ 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); 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] = { 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 */ 16, 18, 167, 205, /* 68K to CRAM or VSRAM */
15, 17, 166, 204, /* DMA fill */ 15, 17, 166, 204, /* DMA fill */
8, 9, 83 , 102, /* DMA Copy */ 8, 9, 83 , 102, /* DMA Copy */
}; };
/* Function prototypes */ /* Function prototypes */
@ -159,6 +159,7 @@ void vdp_reset(void)
pending = 0; pending = 0;
status = 0x200; /* fifo empty */ status = 0x200; /* fifo empty */
status |= vdp_pal;
ntab = 0; ntab = 0;
ntbb = 0; ntbb = 0;
@ -324,7 +325,7 @@ void dma_update()
*/ */
static inline void dma_copy(void) static inline void dma_copy(void)
{ {
int name; int name;
int length = (reg[20] << 8 | reg[19]) & 0xFFFF; int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
int source = (reg[22] << 8 | reg[21]) & 0xFFFF; int source = (reg[22] << 8 | reg[21]) & 0xFFFF;
if (!length) length = 0x10000; if (!length) length = 0x10000;
@ -365,48 +366,45 @@ static inline void dma_vbus (void)
dma_length = length; dma_length = length;
dma_update(); dma_update();
switch (source >> 21) /* DMA source */
if ((source >> 17) == 0x50)
{ {
case 5: /* Z80 & I/O area */
do do
{ {
/* Return $FFFF only when the Z80 isn't hogging the Z-bus. /* Return $FFFF only when the Z80 isn't hogging the Z-bus.
(e.g. Z80 isn't reset and 68000 has the bus) */ (e.g. Z80 isn't reset and 68000 has the bus) */
if (source <= 0xa0ffff) temp = (zbusack ? *(uint16 *)(work_ram + (source & 0xffff)) : 0xffff); 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. in both values being combined in random ways when read.
We return the I/O chip values which seem to have precedence, */ We return the I/O chip values which seem to have precedence, */
else if (source <= 0xa1001f) else if (source <= 0xa1001f)
{ {
temp = io_read((source >> 1) & 0x0f); temp = io_read((source >> 1) & 0x0f);
temp = (temp << 8 | temp); 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: /* All remaining locations access work RAM */
case 1: else temp = *(uint16 *)(work_ram + (source & 0xffff));
if (svp) source = source - 2;
default: source += 2;
do source = ((base & 0xFE0000) | (source & 0x1FFFF));
{ data_write (temp);
temp = *(uint16 *)(m68k_memory_map[source>>16].base + (source & 0xffff)); }
source += 2; while (--length);
source = ((base & 0xFE0000) | (source & 0x1FFFF)); }
data_write (temp); else
} {
while (--length); /* ROM & RAM */
break; 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 */ /* update length & source address registers */
@ -420,7 +418,7 @@ static inline void dma_vbus (void)
/* VRAM FILL */ /* VRAM FILL */
static inline void dma_fill(unsigned int data) static inline void dma_fill(unsigned int data)
{ {
int name; int name;
int length = (reg[20] << 8 | reg[19]) & 0xFFFF; int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
if (!length) length = 0x10000; if (!length) length = 0x10000;
@ -442,7 +440,6 @@ static inline void dma_fill(unsigned int data)
{ {
/* update internal SAT (fix Battletech) */ /* update internal SAT (fix Battletech) */
WRITE_BYTE(sat, (addr & sat_addr_mask)^1, data); WRITE_BYTE(sat, (addr & sat_addr_mask)^1, data);
WRITE_BYTE(vram, addr^1, data); WRITE_BYTE(vram, addr^1, data);
MARK_BG_DIRTY (addr); MARK_BG_DIRTY (addr);
addr += reg[15]; addr += reg[15];
@ -618,39 +615,26 @@ static inline void vdp_reg_w(unsigned int r, unsigned int d)
switch(r) switch(r)
{ {
case 0x00: /* CTRL #1 */ case 0x00: /* CTRL #1 */
/* Check if HINT has been enabled or disabled */
if (hint_pending && ((d&0x10) != (reg[0]&0x10))) if (hint_pending && ((d&0x10) != (reg[0]&0x10)))
{ {
/* update IRQ status */
irq_status &= 0x20; irq_status &= 0x20;
irq_status |= 0x10; irq_status |= 0x10;
if (vint_pending && (reg[1] & 0x20)) if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
{ else if (d & 0x10) irq_status |= 4;
irq_status |= 6;
}
else if (d & 0x10)
{
irq_status |= 4;
}
} }
break; break;
case 0x01: /* CTRL #2 */ case 0x01: /* CTRL #2 */
/* Check if VINT has been enabled or disabled */
if (vint_pending && ((d&0x20) != (reg[1]&0x20))) if (vint_pending && ((d&0x20) != (reg[1]&0x20)))
{ {
/* update IRQ status */
irq_status &= 0x20; irq_status &= 0x20;
irq_status |= 0x110; irq_status |= 0x110;
if (d & 0x20) if (d & 0x20) irq_status |= 6;
{ else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
irq_status |= 6;
}
else if (hint_pending && (reg[0] & 0x10))
{
irq_status |= 4;
}
} }
/* Check if the viewport height has actually been changed */ /* Check if the viewport height has actually been changed */
if((reg[1] & 8) != (d & 8)) if((reg[1] & 8) != (d & 8))
{ {
@ -792,22 +776,24 @@ unsigned int vdp_ctrl_r(void)
* 8 Write FIFO full * 8 Write FIFO full
* 9 Write FIFO empty * 9 Write FIFO empty
* 10 - 15 Next word on bus * 10 - 15 Next word on bus
*/ */
/* update FIFO flags */ /* update FIFO flags */
fifo_update(); fifo_update();
if (fifo_write_cnt < 4) if (fifo_write_cnt < 4)
{ {
status &= 0xFEFF; status &= 0xFEFF;
if (fifo_write_cnt == 0) status |= 0x200; if (fifo_write_cnt == 0) status |= 0x200;
} }
else status ^= 0x200; else status ^= 0x200;
/* update DMA Busy flag */ /* update DMA Busy flag */
if ((status & 2) && !dma_length && (count_m68k >= dma_endCycles)) if ((status & 2) && !dma_length && (count_m68k >= dma_endCycles))
{
status &= 0xFFFD; status &= 0xFFFD;
}
unsigned int temp = status | vdp_pal; unsigned int temp = status;
/* display OFF: VBLANK flag is set */ /* display OFF: VBLANK flag is set */
if (!(reg[1] & 0x40)) temp |= 0x8; 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) int vdp_int_ack_callback(int int_level)
{ {
/* VINT triggered ? */
if (irq_status&0x20) if (irq_status&0x20)
{ {
vint_pending = 0; vint_pending = 0;
status &= ~0x80; /* clear VINT flag */ status &= ~0x80; /* clear VINT flag */
} }
else else
{ {
hint_pending = 0; hint_pending = 0;
} }
/* update IRQ status */
irq_status = 0x10; irq_status = 0x10;
if (vint_pending && (reg[1] & 0x20)) if (vint_pending && (reg[1] & 0x20)) irq_status |= 6;
{ else if (hint_pending && (reg[0] & 0x10)) irq_status |= 4;
irq_status |= 6;
}
else if (hint_pending && (reg[0] & 0x10))
{
irq_status |= 4;
}
return M68K_INT_ACK_AUTOVECTOR; return M68K_INT_ACK_AUTOVECTOR;
} }

View File

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