mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-27 19:51:48 +01:00
.added proper TMSS emulation
.memory bus handlers code cleanup & optimization
This commit is contained in:
parent
f8c7045b72
commit
79d5f55611
@ -50,11 +50,11 @@ typedef struct
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8 *rom; /* ROM data */
|
uint8 *rom; /* ROM data */
|
||||||
uint8 *base; /* ROM base area (slot 0) */
|
uint8 *base; /* ROM base (slot 0) */
|
||||||
uint32 romsize; /* ROM size */
|
uint32 romsize; /* ROM size */
|
||||||
uint32 mask; /* mask ROM */
|
uint32 mask; /* ROM mask */
|
||||||
uint16 lock_on; /* 1: Lock-On enabled */
|
uint8 lock_on; /* 1: Lock-On port */
|
||||||
uint16 jcart; /* 1: J-CART port enabled */
|
uint8 jcart; /* 1: J-CART port */
|
||||||
T_CART_HW hw; /* Extra hardware */
|
T_CART_HW hw; /* Extra hardware */
|
||||||
} T_CART;
|
} T_CART;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ void io_init(void)
|
|||||||
void io_reset(void)
|
void io_reset(void)
|
||||||
{
|
{
|
||||||
/* Reset I/O registers */
|
/* Reset I/O registers */
|
||||||
io_reg[0x00] = region_code | 0x20 | (config.bios_enabled == 3);
|
io_reg[0x00] = region_code | 0x20 | (config.tmss & 1);
|
||||||
io_reg[0x01] = 0x7F;
|
io_reg[0x01] = 0x7F;
|
||||||
io_reg[0x02] = 0x7F;
|
io_reg[0x02] = 0x7F;
|
||||||
io_reg[0x03] = 0x7F;
|
io_reg[0x03] = 0x7F;
|
||||||
|
175
source/genesis.c
175
source/genesis.c
@ -23,11 +23,16 @@
|
|||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
uint8 bios_rom[0x10000]; /* OS ROM */
|
uint8 tmss[4]; /* TMSS security register */
|
||||||
|
uint8 bios_rom[0x800]; /* OS ROM */
|
||||||
uint8 work_ram[0x10000]; /* 68K RAM */
|
uint8 work_ram[0x10000]; /* 68K RAM */
|
||||||
uint8 zram[0x2000]; /* Z80 RAM */
|
uint8 zram[0x2000]; /* Z80 RAM */
|
||||||
uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
|
|
||||||
uint32 zbank; /* Z80 bank window address */
|
uint32 zbank; /* Z80 bank window address */
|
||||||
|
uint8 zstate; /* Z80 bus state (d0 = BUSACK, d1 = /RESET) */
|
||||||
|
|
||||||
|
/* PICO data */
|
||||||
|
uint8 pico_current;
|
||||||
|
uint8 pico_page[7];
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/* Init, reset, shutdown functions */
|
/* Init, reset, shutdown functions */
|
||||||
@ -68,11 +73,7 @@ void gen_init(void)
|
|||||||
zbank_memory_map[i].write = zbank_lockup_w;
|
zbank_memory_map[i].write = zbank_lockup_w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Z80 bus */
|
/* Z80 bus (bank access) */
|
||||||
m68k_memory_map[0xa0].read8 = z80_read_byte;
|
|
||||||
m68k_memory_map[0xa0].read16 = z80_read_word;
|
|
||||||
m68k_memory_map[0xa0].write8 = z80_write_byte;
|
|
||||||
m68k_memory_map[0xa0].write16 = z80_write_word;
|
|
||||||
zbank_memory_map[0xa0].read = zbank_lockup_r;
|
zbank_memory_map[0xa0].read = zbank_lockup_r;
|
||||||
zbank_memory_map[0xa0].write = zbank_lockup_w;
|
zbank_memory_map[0xa0].write = zbank_lockup_w;
|
||||||
|
|
||||||
@ -84,34 +85,43 @@ void gen_init(void)
|
|||||||
zbank_memory_map[0xa1].read = zbank_read_ctrl_io;
|
zbank_memory_map[0xa1].read = zbank_read_ctrl_io;
|
||||||
zbank_memory_map[0xa1].write = zbank_write_ctrl_io;
|
zbank_memory_map[0xa1].write = zbank_write_ctrl_io;
|
||||||
|
|
||||||
|
/* VDP (initially locked on models with TMSS) */
|
||||||
|
if (!(config.tmss & 1))
|
||||||
|
{
|
||||||
|
for (i=0xc0; i<0xe0; i+=8)
|
||||||
|
{
|
||||||
|
m68k_memory_map[i].read8 = vdp_read_byte;
|
||||||
|
m68k_memory_map[i].read16 = vdp_read_word;
|
||||||
|
m68k_memory_map[i].write8 = vdp_write_byte;
|
||||||
|
m68k_memory_map[i].write16 = vdp_write_word;
|
||||||
|
zbank_memory_map[i].read = zbank_read_vdp;
|
||||||
|
zbank_memory_map[i].write = zbank_write_vdp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* SEGA PICO */
|
/* SEGA PICO */
|
||||||
if (system_hw == SYSTEM_PICO)
|
if (system_hw == SYSTEM_PICO)
|
||||||
{
|
{
|
||||||
m68k_memory_map[0x80].read8 = pico_read_byte;
|
m68k_memory_map[0x80].read8 = pico_read_byte;
|
||||||
m68k_memory_map[0x80].read16 = pico_read_word;
|
m68k_memory_map[0x80].read16 = pico_read_word;
|
||||||
m68k_memory_map[0x80].write8 = m68k_unused_8_w;
|
m68k_memory_map[0x80].write8 = m68k_unused_8_w;
|
||||||
m68k_memory_map[0x80].write16 = m68k_unused_16_w;
|
m68k_memory_map[0x80].write16 = m68k_unused_16_w;
|
||||||
|
|
||||||
/* there is no I/O area (Notaz) */
|
/* there is no I/O area (Notaz) */
|
||||||
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
|
|
||||||
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
|
|
||||||
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
|
|
||||||
m68k_memory_map[0xa0].write16 = m68k_unused_16_w;
|
|
||||||
m68k_memory_map[0xa1].read8 = m68k_read_bus_8;
|
m68k_memory_map[0xa1].read8 = m68k_read_bus_8;
|
||||||
m68k_memory_map[0xa1].read16 = m68k_read_bus_16;
|
m68k_memory_map[0xa1].read16 = m68k_read_bus_16;
|
||||||
m68k_memory_map[0xa1].write8 = m68k_unused_8_w;
|
m68k_memory_map[0xa1].write8 = m68k_unused_8_w;
|
||||||
m68k_memory_map[0xa1].write16 = m68k_unused_16_w;
|
m68k_memory_map[0xa1].write16 = m68k_unused_16_w;
|
||||||
}
|
|
||||||
|
|
||||||
/* VDP */
|
/* page registers */
|
||||||
for (i=0xc0; i<0xe0; i+=8)
|
pico_current = 0x00;
|
||||||
{
|
pico_page[0] = 0x00;
|
||||||
m68k_memory_map[i].read8 = vdp_read_byte;
|
pico_page[1] = 0x01;
|
||||||
m68k_memory_map[i].read16 = vdp_read_word;
|
pico_page[2] = 0x03;
|
||||||
m68k_memory_map[i].write8 = vdp_write_byte;
|
pico_page[3] = 0x07;
|
||||||
m68k_memory_map[i].write16 = vdp_write_word;
|
pico_page[4] = 0x0F;
|
||||||
zbank_memory_map[i].read = zbank_read_vdp;
|
pico_page[5] = 0x1F;
|
||||||
zbank_memory_map[i].write = zbank_write_vdp;
|
pico_page[6] = 0x3F;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,8 +131,9 @@ void gen_hardreset(void)
|
|||||||
memset (work_ram, 0x00, sizeof (work_ram));
|
memset (work_ram, 0x00, sizeof (work_ram));
|
||||||
memset (zram, 0x00, sizeof (zram));
|
memset (zram, 0x00, sizeof (zram));
|
||||||
|
|
||||||
/* TMSS BIOS support */
|
/* TMSS + OS ROM support */
|
||||||
if (config.bios_enabled == 3)
|
memset(tmss, 0x00, sizeof(tmss));
|
||||||
|
if (config.tmss == 3)
|
||||||
m68k_memory_map[0].base = bios_rom;
|
m68k_memory_map[0].base = bios_rom;
|
||||||
|
|
||||||
/* Reset CPU cycles (check EA logo corruption, no glitches for Skitchin/Budokan on PAL 60hz MD2 with TMSS) */
|
/* Reset CPU cycles (check EA logo corruption, no glitches for Skitchin/Budokan on PAL 60hz MD2 with TMSS) */
|
||||||
@ -130,6 +141,10 @@ void gen_hardreset(void)
|
|||||||
|
|
||||||
/* Z80 bus is released & Z80 reset is asserted */
|
/* Z80 bus is released & Z80 reset is asserted */
|
||||||
zstate = 0;
|
zstate = 0;
|
||||||
|
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
|
||||||
|
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
|
||||||
|
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
|
||||||
|
m68k_memory_map[0xa0].write16 = m68k_unused_16_w;
|
||||||
|
|
||||||
/* Assume default bank is $000000-$007FFF */
|
/* Assume default bank is $000000-$007FFF */
|
||||||
zbank = 0;
|
zbank = 0;
|
||||||
@ -170,10 +185,76 @@ void gen_shutdown(void)
|
|||||||
z80_exit();
|
z80_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------
|
/*-----------------------------------------------------------------------
|
||||||
Bus controller chip functions
|
OS ROM / TMSS register control functions
|
||||||
-----------------------------------------------------------------------*/
|
-----------------------------------------------------------------------*/
|
||||||
void gen_busreq_w(uint32 state, uint32 cycles)
|
|
||||||
|
void gen_tmss_w(unsigned int offset, unsigned int data)
|
||||||
|
{
|
||||||
|
/* write TMSS regisiter */
|
||||||
|
WRITE_WORD(tmss, offset, data);
|
||||||
|
|
||||||
|
/* VDP requires "SEGA" value to be written in TMSSS register */
|
||||||
|
int i;
|
||||||
|
if (strncmp((char *)tmss, "SEGA", 4) == 0)
|
||||||
|
{
|
||||||
|
for (i=0xc0; i<0xe0; i+=8)
|
||||||
|
{
|
||||||
|
m68k_memory_map[i].read8 = vdp_read_byte;
|
||||||
|
m68k_memory_map[i].read16 = vdp_read_word;
|
||||||
|
m68k_memory_map[i].write8 = vdp_write_byte;
|
||||||
|
m68k_memory_map[i].write16 = vdp_write_word;
|
||||||
|
zbank_memory_map[i].read = zbank_read_vdp;
|
||||||
|
zbank_memory_map[i].write = zbank_write_vdp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i=0xc0; i<0xe0; i+=8)
|
||||||
|
{
|
||||||
|
m68k_memory_map[i].read8 = m68k_lockup_r_8;
|
||||||
|
m68k_memory_map[i].read16 = m68k_lockup_r_16;
|
||||||
|
m68k_memory_map[i].write8 = m68k_lockup_w_8;
|
||||||
|
m68k_memory_map[i].write16 = m68k_lockup_w_16;
|
||||||
|
zbank_memory_map[i].read = zbank_lockup_r;
|
||||||
|
zbank_memory_map[i].write = zbank_lockup_w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gen_bankswitch_w(unsigned int data)
|
||||||
|
{
|
||||||
|
/* BIOS has not been loaded yet */
|
||||||
|
if (!(config.tmss & 2))
|
||||||
|
{
|
||||||
|
config.tmss |= 2;
|
||||||
|
memcpy(bios_rom, cart.rom, 0x800);
|
||||||
|
memset(cart.rom, 0xff, cart.romsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data & 1)
|
||||||
|
{
|
||||||
|
/* enable CART */
|
||||||
|
m68k_memory_map[0].base = cart.base;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* enable internal BIOS ROM */
|
||||||
|
m68k_memory_map[0].base = bios_rom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int gen_bankswitch_r(void)
|
||||||
|
{
|
||||||
|
return (m68k_memory_map[0].base == cart.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
Z80 Bus controller chip functions
|
||||||
|
-----------------------------------------------------------------------*/
|
||||||
|
void gen_zbusreq_w(unsigned int state, unsigned int cycles)
|
||||||
{
|
{
|
||||||
if (state) /* Z80 Bus Requested */
|
if (state) /* Z80 Bus Requested */
|
||||||
{
|
{
|
||||||
@ -183,7 +264,16 @@ void gen_busreq_w(uint32 state, uint32 cycles)
|
|||||||
|
|
||||||
/* request Z80 bus */
|
/* request Z80 bus */
|
||||||
zstate |= 2;
|
zstate |= 2;
|
||||||
}
|
|
||||||
|
/* enable 68k access */
|
||||||
|
if (zstate & 1)
|
||||||
|
{
|
||||||
|
m68k_memory_map[0xa0].read8 = z80_read_byte;
|
||||||
|
m68k_memory_map[0xa0].read16 = z80_read_word;
|
||||||
|
m68k_memory_map[0xa0].write8 = z80_write_byte;
|
||||||
|
m68k_memory_map[0xa0].write16 = z80_write_word;
|
||||||
|
}
|
||||||
|
}
|
||||||
else /* Z80 Bus Released */
|
else /* Z80 Bus Released */
|
||||||
{
|
{
|
||||||
/* if z80 is restarted, resynchronize with 68k */
|
/* if z80 is restarted, resynchronize with 68k */
|
||||||
@ -192,10 +282,16 @@ void gen_busreq_w(uint32 state, uint32 cycles)
|
|||||||
|
|
||||||
/* release Z80 bus */
|
/* release Z80 bus */
|
||||||
zstate &= 1;
|
zstate &= 1;
|
||||||
|
|
||||||
|
/* disable 68k access */
|
||||||
|
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
|
||||||
|
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
|
||||||
|
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
|
||||||
|
m68k_memory_map[0xa0].write16 = m68k_unused_16_w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_reset_w(uint32 state, uint32 cycles)
|
void gen_zreset_w(unsigned int state, unsigned int cycles)
|
||||||
{
|
{
|
||||||
/* detect !ZRESET transitions */
|
/* detect !ZRESET transitions */
|
||||||
if (state == (zstate & 1))
|
if (state == (zstate & 1))
|
||||||
@ -212,6 +308,15 @@ void gen_reset_w(uint32 state, uint32 cycles)
|
|||||||
|
|
||||||
/* negate Z80 reset */
|
/* negate Z80 reset */
|
||||||
zstate |= 1;
|
zstate |= 1;
|
||||||
|
|
||||||
|
/* enable 68k access */
|
||||||
|
if (zstate & 1)
|
||||||
|
{
|
||||||
|
m68k_memory_map[0xa0].read8 = z80_read_byte;
|
||||||
|
m68k_memory_map[0xa0].read16 = z80_read_word;
|
||||||
|
m68k_memory_map[0xa0].write8 = z80_write_byte;
|
||||||
|
m68k_memory_map[0xa0].write16 = z80_write_word;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* !ZRESET active */
|
else /* !ZRESET active */
|
||||||
{
|
{
|
||||||
@ -221,13 +326,19 @@ void gen_reset_w(uint32 state, uint32 cycles)
|
|||||||
|
|
||||||
/* assert Z80 reset */
|
/* assert Z80 reset */
|
||||||
zstate &= 2;
|
zstate &= 2;
|
||||||
|
|
||||||
|
/* disable 68k access */
|
||||||
|
m68k_memory_map[0xa0].read8 = m68k_read_bus_8;
|
||||||
|
m68k_memory_map[0xa0].read16 = m68k_read_bus_16;
|
||||||
|
m68k_memory_map[0xa0].write8 = m68k_unused_8_w;
|
||||||
|
m68k_memory_map[0xa0].write16 = m68k_unused_16_w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset YM2612 */
|
/* reset YM2612 */
|
||||||
fm_reset(cycles);
|
fm_reset(cycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_bank_w (uint32 state)
|
void gen_zbank_w (unsigned int state)
|
||||||
{
|
{
|
||||||
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
|
zbank = ((zbank >> 1) | ((state & 1) << 23)) & 0xFF8000;
|
||||||
}
|
}
|
||||||
|
@ -25,20 +25,26 @@
|
|||||||
#define _GENESIS_H_
|
#define _GENESIS_H_
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern uint8 bios_rom[0x10000];
|
extern uint8 tmss[4];
|
||||||
|
extern uint8 bios_rom[0x800];
|
||||||
extern uint8 work_ram[0x10000];
|
extern uint8 work_ram[0x10000];
|
||||||
extern uint8 zram[0x2000];
|
extern uint8 zram[0x2000];
|
||||||
extern uint8 zstate;
|
|
||||||
extern uint32 zbank;
|
extern uint32 zbank;
|
||||||
|
extern uint8 zstate;
|
||||||
|
extern uint8 pico_current;
|
||||||
|
extern uint8 pico_page[7];
|
||||||
|
|
||||||
/* Function prototypes */
|
/* Function prototypes */
|
||||||
extern void gen_init(void);
|
extern void gen_init(void);
|
||||||
extern void gen_hardreset(void);
|
extern void gen_hardreset(void);
|
||||||
extern void gen_softreset(int state);
|
extern void gen_softreset(int state);
|
||||||
extern void gen_shutdown(void);
|
extern void gen_shutdown(void);
|
||||||
extern void gen_busreq_w(uint32 state, uint32 cycles);
|
extern void gen_tmss_w(unsigned int offset, unsigned int data);
|
||||||
extern void gen_reset_w(uint32 state, uint32 cycles);
|
extern void gen_bankswitch_w(unsigned int data);
|
||||||
extern void gen_bank_w(uint32 state);
|
extern unsigned int gen_bankswitch_r(void);
|
||||||
|
extern void gen_zbusreq_w(unsigned int state, unsigned int cycles);
|
||||||
|
extern void gen_zreset_w(unsigned int state, unsigned int cycles);
|
||||||
|
extern void gen_zbank_w(unsigned int state);
|
||||||
extern int z80_irq_callback(int param);
|
extern int z80_irq_callback(int param);
|
||||||
|
|
||||||
#endif /* _GEN_H_ */
|
#endif /* _GEN_H_ */
|
||||||
|
@ -85,7 +85,7 @@ void config_default(void)
|
|||||||
config.region_detect = 0;
|
config.region_detect = 0;
|
||||||
config.force_dtack = 0;
|
config.force_dtack = 0;
|
||||||
config.addr_error = 1;
|
config.addr_error = 1;
|
||||||
config.bios_enabled = 0;
|
config.tmss = 0;
|
||||||
config.lock_on = 0;
|
config.lock_on = 0;
|
||||||
config.romtype = 0;
|
config.romtype = 0;
|
||||||
config.hot_swap = 0;
|
config.hot_swap = 0;
|
||||||
|
@ -47,7 +47,7 @@ typedef struct
|
|||||||
uint8 region_detect;
|
uint8 region_detect;
|
||||||
uint8 force_dtack;
|
uint8 force_dtack;
|
||||||
uint8 addr_error;
|
uint8 addr_error;
|
||||||
uint8 bios_enabled;
|
uint8 tmss;
|
||||||
uint8 lock_on;
|
uint8 lock_on;
|
||||||
uint8 hot_swap;
|
uint8 hot_swap;
|
||||||
uint8 romtype;
|
uint8 romtype;
|
||||||
|
@ -1009,7 +1009,7 @@ static void systemmenu ()
|
|||||||
|
|
||||||
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
sprintf (items[1].text, "System Lockups: %s", config.force_dtack ? "OFF" : "ON");
|
||||||
sprintf (items[2].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
sprintf (items[2].text, "68k Address Error: %s", config.addr_error ? "ON" : "OFF");
|
||||||
sprintf (items[3].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
|
sprintf (items[3].text, "System TMSS: %s", (config.tmss & 1) ? "ON":"OFF");
|
||||||
|
|
||||||
if (config.lock_on == TYPE_GG)
|
if (config.lock_on == TYPE_GG)
|
||||||
sprintf (items[4].text, "Lock-On: GAME GENIE");
|
sprintf (items[4].text, "Lock-On: GAME GENIE");
|
||||||
@ -1106,8 +1106,8 @@ static void systemmenu ()
|
|||||||
|
|
||||||
|
|
||||||
case 3: /*** BIOS support ***/
|
case 3: /*** BIOS support ***/
|
||||||
config.bios_enabled ^= 1;
|
config.tmss ^= 1;
|
||||||
sprintf (items[3].text, "System BIOS: %s", (config.bios_enabled & 1) ? "ON":"OFF");
|
sprintf (items[3].text, "System TMSS: %s", (config.tmss & 1) ? "ON":"OFF");
|
||||||
if (cart.romsize)
|
if (cart.romsize)
|
||||||
{
|
{
|
||||||
system_init();
|
system_init();
|
||||||
|
@ -104,8 +104,8 @@ static bool FindIOS(u32 ios)
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void load_bios(void)
|
static void load_bios(void)
|
||||||
{
|
{
|
||||||
/* reset BIOS found flag */
|
/* reset BIOS flag */
|
||||||
config.bios_enabled &= ~2;
|
config.tmss &= ~2;
|
||||||
|
|
||||||
/* open BIOS file */
|
/* open BIOS file */
|
||||||
FILE *fp = fopen(OS_ROM, "rb");
|
FILE *fp = fopen(OS_ROM, "rb");
|
||||||
@ -116,7 +116,7 @@ static void load_bios(void)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
/* update BIOS flags */
|
/* update BIOS flags */
|
||||||
config.bios_enabled |= 2;
|
config.tmss |= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_machine(void)
|
static void init_machine(void)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[(ADDR)+1]<<24) | \
|
#define READ_WORD_LONG(BASE, ADDR) (((BASE)[(ADDR)+1]<<24) | \
|
||||||
((BASE)[(ADDR)]<<16) | \
|
((BASE)[(ADDR)]<<16) | \
|
||||||
((BASE)[(ADDR)+3]<<8) | \
|
((BASE)[(ADDR)+3]<<8) | \
|
||||||
(BASE)[(ADDR)+1])
|
(BASE)[(ADDR)+2])
|
||||||
|
|
||||||
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
|
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[(ADDR)^1] = (VAL)&0xff
|
||||||
|
|
||||||
@ -25,8 +25,8 @@
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
|
#define READ_BYTE(BASE, ADDR) (BASE)[ADDR]
|
||||||
#define READ_WORD(BASE, ADDR) *(uint16 *)((BASE) + (ADDR));
|
#define READ_WORD(BASE, ADDR) *(uint16 *)((BASE) + (ADDR))
|
||||||
#define READ_WORD_LONG(BASE, ADDR) *(uint32 *)((BASE) + (ADDR));
|
#define READ_WORD_LONG(BASE, ADDR) *(uint32 *)((BASE) + (ADDR))
|
||||||
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[ADDR] = VAL & 0xff
|
#define WRITE_BYTE(BASE, ADDR, VAL) (BASE)[ADDR] = VAL & 0xff
|
||||||
#define WRITE_WORD(BASE, ADDR, VAL) *(uint16 *)((BASE) + (ADDR)) = VAL & 0xffff
|
#define WRITE_WORD(BASE, ADDR, VAL) *(uint16 *)((BASE) + (ADDR)) = VAL & 0xffff
|
||||||
#define WRITE_WORD_LONG(BASE, ADDR, VAL) *(uint32 *)((BASE) + (ADDR)) = VAL & 0xffffffff
|
#define WRITE_WORD_LONG(BASE, ADDR, VAL) *(uint32 *)((BASE) + (ADDR)) = VAL & 0xffffffff
|
||||||
|
496
source/mem68k.c
496
source/mem68k.c
@ -1,6 +1,6 @@
|
|||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* 68k bus arbitration
|
* 68k bus address decoding
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||||
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
||||||
@ -24,13 +24,16 @@
|
|||||||
#include "m68kcpu.h"
|
#include "m68kcpu.h"
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* Unused area (return open bus data, i.e prefetched instruction word) */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
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));
|
||||||
#endif
|
#endif
|
||||||
return m68k_read_pcrelative_8(REG_PC | (address&1));
|
return m68k_read_pcrelative_8(REG_PC | (address & 1));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 m68k_read_bus_16(uint32 address)
|
uint32 m68k_read_bus_16(uint32 address)
|
||||||
@ -56,19 +59,19 @@ void m68k_unused_16_w (uint32 address, uint32 data)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Functions to handle memory accesses which cause the Genesis to halt
|
|
||||||
either temporarily (press RESET button to restart) or unrecoverably
|
|
||||||
(cycle power to restart).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* Illegal area (cause system to lock-up since !DTACK is not returned) */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
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
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
m68k_pulse_halt ();
|
{
|
||||||
|
m68k_pulse_halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void m68k_lockup_w_16 (uint32 address, uint32 data)
|
void m68k_lockup_w_16 (uint32 address, uint32 data)
|
||||||
@ -77,7 +80,9 @@ void m68k_lockup_w_16 (uint32 address, uint32 data)
|
|||||||
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
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
m68k_pulse_halt ();
|
{
|
||||||
|
m68k_pulse_halt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 m68k_lockup_r_8 (uint32 address)
|
uint32 m68k_lockup_r_8 (uint32 address)
|
||||||
@ -86,8 +91,10 @@ uint32 m68k_lockup_r_8 (uint32 address)
|
|||||||
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
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
m68k_pulse_halt ();
|
{
|
||||||
return -1;
|
m68k_pulse_halt();
|
||||||
|
}
|
||||||
|
return m68k_read_pcrelative_8(REG_PC | (address & 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 m68k_lockup_r_16 (uint32 address)
|
uint32 m68k_lockup_r_16 (uint32 address)
|
||||||
@ -96,120 +103,128 @@ uint32 m68k_lockup_r_16 (uint32 address)
|
|||||||
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
|
||||||
if (!config.force_dtack)
|
if (!config.force_dtack)
|
||||||
m68k_pulse_halt ();
|
{
|
||||||
return -1;
|
m68k_pulse_halt();
|
||||||
|
}
|
||||||
|
return m68k_read_pcrelative_16(REG_PC);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PICO data */
|
|
||||||
static int pico_page[7] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F};
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/* 68000 memory handlers */
|
/* cartridge EEPROM */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/******* EEPROM **********************************************/
|
|
||||||
|
|
||||||
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 READ_BYTE(cart.rom, address);
|
return READ_BYTE(cart.rom, address);
|
||||||
|
}
|
||||||
|
return eeprom_read(address, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 *(uint16 *)(cart.rom + address);
|
return *(uint16 *)(cart.rom + address);
|
||||||
|
}
|
||||||
|
return eeprom_read(address, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eeprom_write_byte(uint32 address, uint32 data)
|
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);
|
m68k_unused_8_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eeprom_write(address, data, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eeprom_write_word(uint32 address, uint32 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);
|
m68k_unused_16_w (address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eeprom_write(address, data, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******* Z80 *************************************************/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* Z80 bus (accessed through I/O chip) */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
uint32 z80_read_byte(uint32 address)
|
uint32 z80_read_byte(uint32 address)
|
||||||
{
|
{
|
||||||
/* Z80 bus is available ? */
|
|
||||||
if (zstate ^ 3)
|
|
||||||
return m68k_read_bus_8(address);
|
|
||||||
|
|
||||||
switch ((address >> 13) & 3)
|
switch ((address >> 13) & 3)
|
||||||
{
|
{
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
|
{
|
||||||
return fm_read(mcycles_68k, address & 3);
|
return fm_read(mcycles_68k, address & 3);
|
||||||
|
}
|
||||||
|
|
||||||
case 3: /* MISC */
|
case 3: /* Misc */
|
||||||
|
{
|
||||||
if ((address & 0xff00) == 0x7f00)
|
if ((address & 0xff00) == 0x7f00)
|
||||||
return m68k_lockup_r_8(address); /* VDP */
|
{
|
||||||
|
/* VDP (through 68k bus) */
|
||||||
|
return m68k_lockup_r_8(address);
|
||||||
|
}
|
||||||
return (m68k_read_bus_8(address) | 0xff);
|
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)
|
||||||
{
|
{
|
||||||
/* Z80 bus is available ? */
|
|
||||||
if (zstate ^ 3)
|
|
||||||
return m68k_read_bus_16(address);
|
|
||||||
|
|
||||||
switch ((address >> 13) & 3)
|
switch ((address >> 13) & 3)
|
||||||
{
|
{
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
{
|
{
|
||||||
int temp = fm_read(mcycles_68k, address & 3);
|
unsigned int data = fm_read(mcycles_68k, address & 3);
|
||||||
return (temp << 8 | temp);
|
return (data << 8 | data);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 3: /* MISC */
|
case 3: /* Misc */
|
||||||
|
{
|
||||||
if ((address & 0xff00) == 0x7f00)
|
if ((address & 0xff00) == 0x7f00)
|
||||||
return m68k_lockup_r_16(address); /* VDP */
|
{
|
||||||
|
/* VDP (through 68k bus) */
|
||||||
|
return m68k_lockup_r_16(address);
|
||||||
|
}
|
||||||
return (m68k_read_bus_16(address) | 0xffff);
|
return (m68k_read_bus_16(address) | 0xffff);
|
||||||
|
}
|
||||||
|
|
||||||
default: /* ZRAM */
|
default: /* ZRAM */
|
||||||
{
|
{
|
||||||
int temp = zram[address & 0x1fff];
|
unsigned int data = zram[address & 0x1fff];
|
||||||
return (temp << 8 | temp);
|
return (data << 8 | data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void z80_write_byte(uint32 address, uint32 data)
|
void z80_write_byte(uint32 address, uint32 data)
|
||||||
{
|
{
|
||||||
/* Z80 bus is available ? */
|
|
||||||
if (zstate ^ 3)
|
|
||||||
{
|
|
||||||
m68k_unused_8_w(address, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ((address >> 13) & 3)
|
switch ((address >> 13) & 3)
|
||||||
{
|
{
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
|
{
|
||||||
fm_write(mcycles_68k, address & 3, data);
|
fm_write(mcycles_68k, address & 3, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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_zbank_w(data & 1);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x7f: /* VDP */
|
case 0x7f: /* VDP */
|
||||||
@ -220,86 +235,128 @@ void z80_write_byte(uint32 address, uint32 data)
|
|||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default: /* ZRAM */
|
default: /* ZRAM */
|
||||||
|
{
|
||||||
zram[address & 0x1fff] = data;
|
zram[address & 0x1fff] = data;
|
||||||
mcycles_68k+=8; /* Z80 bus latency (Pacman 2: New Adventures) */
|
mcycles_68k += 8; /* Z80 bus latency (fixes Pacman 2: New Adventures) */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void z80_write_word(uint32 address, uint32 data)
|
void z80_write_word(uint32 address, uint32 data)
|
||||||
{
|
{
|
||||||
/* Z80 bus is available ? */
|
|
||||||
if (zstate ^ 3)
|
|
||||||
{
|
|
||||||
m68k_unused_16_w(address, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ((address >> 13) & 3)
|
switch ((address >> 13) & 3)
|
||||||
{
|
{
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
fm_write (mcycles_68k, address & 3, data >> 8);
|
{
|
||||||
|
fm_write(mcycles_68k, address & 3, data >> 8);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
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_zbank_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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******* I/O & CTRL ******************************************/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* I/O Control */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
uint32 ctrl_io_read_byte(uint32 address)
|
uint32 ctrl_io_read_byte(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_8(address);
|
return m68k_read_bus_8(address);
|
||||||
return (io_read((address >> 1) & 0x0f));
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe;
|
||||||
if (zstate ^ 3)
|
if (zstate ^ 3)
|
||||||
return (m68k_read_pcrelative_8(REG_PC) | 0x01);
|
{
|
||||||
return (m68k_read_pcrelative_8(REG_PC) & 0xfe);
|
return (data | 0x01);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
if (cart.hw.time_r)
|
{
|
||||||
return ((address & 1) ? (cart.hw.time_r(address) & 0xff) : (cart.hw.time_r(address) >> 8));
|
if (!cart.hw.time_r)
|
||||||
return m68k_read_bus_8(address);
|
{
|
||||||
|
return m68k_read_bus_8(address);
|
||||||
|
}
|
||||||
|
unsigned int data = cart.hw.time_r(address);
|
||||||
|
if (address & 1)
|
||||||
|
{
|
||||||
|
return (data & 0xff);
|
||||||
|
}
|
||||||
|
return (data >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x41: /* OS ROM */
|
||||||
|
{
|
||||||
|
if (!(address & 1))
|
||||||
|
{
|
||||||
|
return m68k_read_bus_8(address);
|
||||||
|
}
|
||||||
|
unsigned int data = m68k_read_pcrelative_8(REG_PC) & 0xfe;
|
||||||
|
return (gen_bankswitch_r() | data);
|
||||||
|
}
|
||||||
|
|
||||||
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 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,45 +367,70 @@ uint32 ctrl_io_read_word(uint32 address)
|
|||||||
case 0x00: /* I/O chip */
|
case 0x00: /* I/O chip */
|
||||||
{
|
{
|
||||||
if (address & 0xe0)
|
if (address & 0xe0)
|
||||||
return m68k_read_bus_16(address);
|
{
|
||||||
int temp = io_read((address >> 1) & 0x0f);
|
return m68k_read_bus_16(address);
|
||||||
return (temp << 8 | temp);
|
}
|
||||||
|
unsigned int data = io_read((address >> 1) & 0x0f);
|
||||||
|
return (data << 8 | data);
|
||||||
}
|
}
|
||||||
|
|
||||||
case 0x11: /* BUSACK */
|
case 0x11: /* BUSACK */
|
||||||
|
{
|
||||||
|
unsigned int data = m68k_read_pcrelative_16(REG_PC) & 0xfeff;
|
||||||
if (zstate ^ 3)
|
if (zstate ^ 3)
|
||||||
return (m68k_read_pcrelative_16(REG_PC) | 0x100);
|
{
|
||||||
return (m68k_read_pcrelative_16(REG_PC) & 0xfeff);
|
return data | 0x0100;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
if (cart.hw.time_r)
|
{
|
||||||
return cart.hw.time_r(address);
|
if (!cart.hw.time_r)
|
||||||
return m68k_read_bus_16(address);
|
|
||||||
|
|
||||||
case 0x50: /* SVP */
|
|
||||||
if (svp)
|
|
||||||
{
|
{
|
||||||
if ((address & 0xfd) == 0)
|
return m68k_read_bus_16(address);
|
||||||
|
}
|
||||||
|
return cart.hw.time_r(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x50: /* SVP */
|
||||||
|
{
|
||||||
|
switch (address & 0xfe)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
return svp->ssp1601.gr[SSP_XST].h;
|
return svp->ssp1601.gr[SSP_XST].h;
|
||||||
if ((address & 0xff) == 4)
|
}
|
||||||
|
|
||||||
|
case 4:
|
||||||
{
|
{
|
||||||
uint32 temp = svp->ssp1601.gr[SSP_PM0].h;
|
uint32 temp = svp->ssp1601.gr[SSP_PM0].h;
|
||||||
svp->ssp1601.gr[SSP_PM0].h &= ~1;
|
svp->ssp1601.gr[SSP_PM0].h &= ~1;
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return m68k_read_bus_16(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return m68k_read_bus_16(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: /* OS ROM */
|
||||||
case 0x44: /* RADICA */
|
case 0x44: /* RADICA */
|
||||||
|
{
|
||||||
return m68k_read_bus_16(address);
|
return m68k_read_bus_16(address);
|
||||||
|
}
|
||||||
|
|
||||||
default: /* Invalid address */
|
default: /* Invalid address */
|
||||||
|
{
|
||||||
return m68k_lockup_r_16(address);
|
return m68k_lockup_r_16(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,60 +439,71 @@ 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)
|
{
|
||||||
io_write((address >> 1) & 0x0f, data); /* get /LWR only */
|
if ((address & 0xe1) != 0x01)
|
||||||
else
|
{
|
||||||
|
/* get /LWR only */
|
||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io_write((address >> 1) & 0x0f, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x11: /* BUSREQ */
|
case 0x11: /* BUSREQ */
|
||||||
|
{
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
|
{
|
||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
else
|
return;
|
||||||
gen_busreq_w(data & 1, mcycles_68k);
|
}
|
||||||
|
gen_zbusreq_w(data & 1, mcycles_68k);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x12: /* RESET */
|
case 0x12: /* RESET */
|
||||||
|
{
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
|
{
|
||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
else
|
return;
|
||||||
gen_reset_w(data & 1, mcycles_68k);
|
}
|
||||||
|
gen_zreset_w(data & 1, mcycles_68k);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
|
{
|
||||||
cart.hw.time_w(address, data);
|
cart.hw.time_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x41: /* BOOTROM */
|
case 0x41: /* OS ROM */
|
||||||
if (address & 1)
|
{
|
||||||
|
if (!(address & 1))
|
||||||
{
|
{
|
||||||
m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom;
|
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, 0xff, cart.romsize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m68k_unused_8_w (address, data);
|
|
||||||
}
|
}
|
||||||
|
gen_bankswitch_w(data & 1);
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,107 +512,123 @@ 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);
|
{
|
||||||
else
|
m68k_unused_16_w(address, data);
|
||||||
io_write ((address >> 1) & 0x0f, data & 0xff);
|
return;
|
||||||
|
}
|
||||||
|
io_write((address >> 1) & 0x0f, data & 0xff);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x11: /* BUSREQ */
|
case 0x11: /* BUSREQ */
|
||||||
gen_busreq_w ((data >> 8) & 1, mcycles_68k);
|
{
|
||||||
|
gen_zbusreq_w((data >> 8) & 1, mcycles_68k);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x12: /* RESET */
|
case 0x12: /* RESET */
|
||||||
gen_reset_w ((data >> 8) & 1, mcycles_68k);
|
{
|
||||||
return;
|
gen_zreset_w((data >> 8) & 1, mcycles_68k);
|
||||||
|
|
||||||
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
|
{
|
||||||
cart.hw.time_w(address & 0xfe, data >> 8);
|
cart.hw.time_w(address & 0xfe, data >> 8);
|
||||||
cart.hw.time_w(address, data & 0xff);
|
cart.hw.time_w(address, data & 0xff);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
case 0x41: /* BOOTROM */
|
|
||||||
|
|
||||||
m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom;
|
|
||||||
|
|
||||||
/* autodetect BIOS ROM file */
|
case 0x40: /* TMSS */
|
||||||
if (!(config.bios_enabled & 2))
|
{
|
||||||
|
gen_tmss_w(address & 3, data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x50: /* SVP REGISTERS */
|
||||||
|
{
|
||||||
|
if (address & 0xfd)
|
||||||
{
|
{
|
||||||
config.bios_enabled |= 2;
|
m68k_unused_16_w(address, data);
|
||||||
memcpy(bios_rom, cart.rom, 0x800);
|
return;
|
||||||
memset(cart.rom, 0xff, cart.romsize);
|
|
||||||
}
|
}
|
||||||
|
svp->ssp1601.gr[SSP_XST].h = data;
|
||||||
|
svp->ssp1601.gr[SSP_PM0].h |= 2;
|
||||||
|
svp->ssp1601.emu_status &= ~SSP_WAIT_PM0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x10: /* MEMORY MODE */
|
case 0x10: /* MEMORY MODE */
|
||||||
case 0x20: /* MEGA-CD */
|
case 0x20: /* MEGA-CD */
|
||||||
case 0x40: /* TMSS */
|
case 0x41: /* OS ROM */
|
||||||
case 0x44: /* RADICA */
|
case 0x44: /* RADICA */
|
||||||
|
{
|
||||||
m68k_unused_16_w (address, data);
|
m68k_unused_16_w (address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default: /* Unused */
|
default: /* Invalid address */
|
||||||
|
{
|
||||||
m68k_lockup_w_16 (address, data);
|
m68k_lockup_w_16 (address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******* VDP *************************************************/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* VDP */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
uint32 vdp_read_byte(uint32 address)
|
uint32 vdp_read_byte(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 ((m68k_read_pcrelative_8(REG_PC) & 0xfc) | ((vdp_ctrl_r(mcycles_68k) >> 8) & 3));
|
{
|
||||||
|
return (((vdp_ctrl_r(mcycles_68k) >> 8) & 3) | (m68k_read_pcrelative_8(REG_PC) & 0xfc));
|
||||||
|
}
|
||||||
|
|
||||||
case 0x05: /* CTRL */
|
case 0x05: /* CTRL */
|
||||||
|
{
|
||||||
return (vdp_ctrl_r(mcycles_68k) & 0xff);
|
return (vdp_ctrl_r(mcycles_68k) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x08: /* HVC */
|
case 0x08: /* HVC */
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
|
{
|
||||||
return (vdp_hvc_r(mcycles_68k) >> 8);
|
return (vdp_hvc_r(mcycles_68k) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x09: /* HVC */
|
case 0x09: /* HVC */
|
||||||
case 0x0d:
|
case 0x0d:
|
||||||
|
{
|
||||||
return (vdp_hvc_r(mcycles_68k) & 0xff);
|
return (vdp_hvc_r(mcycles_68k) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
case 0x18: /* Unused */
|
||||||
case 0x19:
|
case 0x19:
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
case 0x1d:
|
case 0x1d:
|
||||||
|
{
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,21 +637,31 @@ uint32 vdp_read_word(uint32 address)
|
|||||||
switch (address & 0xfc)
|
switch (address & 0xfc)
|
||||||
{
|
{
|
||||||
case 0x00: /* DATA */
|
case 0x00: /* DATA */
|
||||||
|
{
|
||||||
return vdp_data_r();
|
return vdp_data_r();
|
||||||
|
}
|
||||||
|
|
||||||
case 0x04: /* CTRL */
|
case 0x04: /* CTRL */
|
||||||
return ((vdp_ctrl_r(mcycles_68k) & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
|
{
|
||||||
|
return ((vdp_ctrl_r(mcycles_68k) & 0x3FF) | (m68k_read_pcrelative_16(REG_PC) & 0xFC00));
|
||||||
|
}
|
||||||
|
|
||||||
case 0x08: /* HVC */
|
case 0x08: /* HVC */
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
|
{
|
||||||
return vdp_hvc_r(mcycles_68k);
|
return vdp_hvc_r(mcycles_68k);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
case 0x18: /* Unused */
|
||||||
case 0x1c:
|
case 0x1c:
|
||||||
|
{
|
||||||
return m68k_read_bus_16(address);
|
return m68k_read_bus_16(address);
|
||||||
|
}
|
||||||
|
|
||||||
default: /* Invalid address */
|
default: /* Invalid address */
|
||||||
|
{
|
||||||
return m68k_lockup_r_16(address);
|
return m68k_lockup_r_16(address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,32 +670,46 @@ 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(mcycles_68k, data);
|
if (!(address & 1))
|
||||||
else
|
{
|
||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
psg_write(mcycles_68k, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
case 0x18: /* Unused */
|
||||||
|
{
|
||||||
m68k_unused_8_w(address, data);
|
m68k_unused_8_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x1c: /* TEST register */
|
case 0x1c: /* TEST register */
|
||||||
|
{
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,29 +718,41 @@ 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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x04: /* CTRL */
|
case 0x04: /* CTRL */
|
||||||
|
{
|
||||||
vdp_ctrl_w(data);
|
vdp_ctrl_w(data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x10: /* PSG */
|
case 0x10: /* PSG */
|
||||||
case 0x14:
|
case 0x14:
|
||||||
|
{
|
||||||
psg_write(mcycles_68k, data & 0xff);
|
psg_write(mcycles_68k, data & 0xff);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
case 0x18: /* Unused */
|
||||||
|
{
|
||||||
m68k_unused_16_w(address, data);
|
m68k_unused_16_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x1c: /* Test register */
|
case 0x1c: /* Test register */
|
||||||
|
{
|
||||||
vdp_test_w(data);
|
vdp_test_w(data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default: /* Invalid address */
|
default: /* Invalid address */
|
||||||
|
{
|
||||||
m68k_lockup_w_16 (address, data);
|
m68k_lockup_w_16 (address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +765,9 @@ uint32 pico_read_byte(uint32 address)
|
|||||||
switch (address & 0xff)
|
switch (address & 0xff)
|
||||||
{
|
{
|
||||||
case 0x01: /* VERSION register */
|
case 0x01: /* VERSION register */
|
||||||
return (0x40);
|
{
|
||||||
|
return 0x40;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x03: /* IO register */
|
case 0x03: /* IO register */
|
||||||
{
|
{
|
||||||
@ -637,32 +784,43 @@ uint32 pico_read_byte(uint32 address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 0x05: /* MSB PEN X coordinate */
|
case 0x05: /* MSB PEN X coordinate */
|
||||||
|
{
|
||||||
return (input.analog[0][0] >> 8);
|
return (input.analog[0][0] >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x07: /* LSB PEN X coordinate */
|
case 0x07: /* LSB PEN X coordinate */
|
||||||
|
{
|
||||||
return (input.analog[0][0] & 0xff);
|
return (input.analog[0][0] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x09: /* MSB PEN Y coordinate */
|
case 0x09: /* MSB PEN Y coordinate */
|
||||||
|
{
|
||||||
return (input.analog[0][1] >> 8);
|
return (input.analog[0][1] >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x0b: /* LSB PEN Y coordinate */
|
case 0x0b: /* LSB PEN Y coordinate */
|
||||||
|
{
|
||||||
return (input.analog[0][1] & 0xff);
|
return (input.analog[0][1] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x0d: /* PAGE register */
|
case 0x0d: /* PAGE register (TODO) */
|
||||||
return pico_page[pico_current]; /* TODO */
|
{
|
||||||
|
return pico_page[pico_current];
|
||||||
|
}
|
||||||
|
|
||||||
case 0x10: /* PCM registers */
|
case 0x10: /* PCM registers (TODO) */
|
||||||
case 0x11:
|
{
|
||||||
case 0x12:
|
return 0x80;
|
||||||
case 0x13:
|
}
|
||||||
return 0x80; /* TODO */
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
return ((m68k_read_bus_8(address) << 8) | pico_read_byte(address | 1));
|
return (pico_read_byte(address | 1) | (m68k_read_bus_8(address) << 8));
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,4 @@ extern void vdp_write_word(uint32 address, uint32 data);
|
|||||||
extern uint32 pico_read_byte(uint32 address);
|
extern uint32 pico_read_byte(uint32 address);
|
||||||
extern uint32 pico_read_word(uint32 address);
|
extern uint32 pico_read_word(uint32 address);
|
||||||
|
|
||||||
uint32 pico_current;
|
|
||||||
|
|
||||||
#endif /* _MEM68K_H_ */
|
#endif /* _MEM68K_H_ */
|
||||||
|
142
source/membnk.c
142
source/membnk.c
@ -1,6 +1,6 @@
|
|||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* 68k bus banked access from Z80
|
* Z80 bank access to 68k bus
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||||
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
||||||
@ -32,7 +32,7 @@ uint32 zbank_unused_r(uint32 address)
|
|||||||
#ifdef LOGERROR
|
#ifdef LOGERROR
|
||||||
error("Z80 bank unused read %06X\n", address);
|
error("Z80 bank unused read %06X\n", address);
|
||||||
#endif
|
#endif
|
||||||
return (address & 1) ? 0x00 : 0xFF;
|
return (address & 1) ? 0x00 : 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zbank_unused_w(uint32 address, uint32 data)
|
void zbank_unused_w(uint32 address, uint32 data)
|
||||||
@ -52,7 +52,7 @@ uint32 zbank_lockup_r(uint32 address)
|
|||||||
mcycles_z80 = 0xffffffff;
|
mcycles_z80 = 0xffffffff;
|
||||||
zstate = 0;
|
zstate = 0;
|
||||||
}
|
}
|
||||||
return 0xFF;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zbank_lockup_w(uint32 address, uint32 data)
|
void zbank_lockup_w(uint32 address, uint32 data)
|
||||||
@ -73,31 +73,60 @@ 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)
|
if (address & 0xe0)
|
||||||
|
{
|
||||||
return zbank_unused_r(address);
|
return zbank_unused_r(address);
|
||||||
|
}
|
||||||
return (io_read((address >> 1) & 0x0f));
|
return (io_read((address >> 1) & 0x0f));
|
||||||
|
}
|
||||||
|
|
||||||
case 0x11: /* BUSACK */
|
case 0x11: /* BUSACK */
|
||||||
|
{
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
|
{
|
||||||
return zbank_unused_r(address);
|
return zbank_unused_r(address);
|
||||||
|
}
|
||||||
return 0xff;
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
if (cart.hw.time_r)
|
{
|
||||||
return ((address & 1) ? (cart.hw.time_r(address) & 0xff) : (cart.hw.time_r(address) >> 8));
|
if (!cart.hw.time_r)
|
||||||
return zbank_unused_r(address);
|
{
|
||||||
|
return zbank_unused_r(address);
|
||||||
|
}
|
||||||
|
unsigned int data = cart.hw.time_r(address);
|
||||||
|
if (address & 1)
|
||||||
|
{
|
||||||
|
return (data & 0xff);
|
||||||
|
}
|
||||||
|
return (data >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x41: /* OS ROM */
|
||||||
|
{
|
||||||
|
if (!(address & 1))
|
||||||
|
{
|
||||||
|
return zbank_unused_r(address);
|
||||||
|
}
|
||||||
|
return (gen_bankswitch_r() | 0xfe);
|
||||||
|
}
|
||||||
|
|
||||||
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 0x44: /* RADICA */
|
case 0x44: /* RADICA */
|
||||||
case 0x50: /* SVP REGISTERS */
|
case 0x50: /* SVP REGISTERS */
|
||||||
|
{
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,60 +135,71 @@ 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 */
|
/* get /LWR only */
|
||||||
else
|
if ((address & 0xe1) != 0x01)
|
||||||
|
{
|
||||||
zbank_unused_w(address, data);
|
zbank_unused_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
io_write((address >> 1) & 0x0f, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x11: /* BUSREQ */
|
case 0x11: /* BUSREQ */
|
||||||
|
{
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
|
{
|
||||||
zbank_unused_w(address, data);
|
zbank_unused_w(address, data);
|
||||||
else
|
return;
|
||||||
gen_busreq_w(data & 1, mcycles_z80);
|
}
|
||||||
|
gen_zbusreq_w(data & 1, mcycles_z80);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x12: /* RESET */
|
case 0x12: /* RESET */
|
||||||
|
{
|
||||||
if (address & 1)
|
if (address & 1)
|
||||||
|
{
|
||||||
zbank_unused_w(address, data);
|
zbank_unused_w(address, data);
|
||||||
else
|
return;
|
||||||
gen_reset_w(data & 1, mcycles_z80);
|
}
|
||||||
|
gen_zreset_w(data & 1, mcycles_z80);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x30: /* TIME */
|
case 0x30: /* TIME */
|
||||||
|
{
|
||||||
cart.hw.time_w(address, data);
|
cart.hw.time_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x41: /* BOOTROM */
|
case 0x41: /* OS ROM */
|
||||||
if (address & 1)
|
{
|
||||||
|
if (!(address & 1))
|
||||||
{
|
{
|
||||||
m68k_memory_map[0].base = (data & 1) ? cart.base : bios_rom;
|
zbank_unused_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, 0xff, cart.romsize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
zbank_unused_w (address, data);
|
|
||||||
}
|
}
|
||||||
|
gen_bankswitch_w(data & 1);
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,33 +210,49 @@ 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(mcycles_z80) >> 8) & 3));
|
{
|
||||||
|
return (((vdp_ctrl_r(mcycles_z80) >> 8) & 3) | 0xfc);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x05: /* CTRL */
|
case 0x05: /* CTRL */
|
||||||
|
{
|
||||||
return (vdp_ctrl_r(mcycles_z80) & 0xff);
|
return (vdp_ctrl_r(mcycles_z80) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x08: /* HVC */
|
case 0x08: /* HVC */
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
|
{
|
||||||
return (vdp_hvc_r(mcycles_z80) >> 8);
|
return (vdp_hvc_r(mcycles_z80) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
case 0x09: /* HVC */
|
case 0x09: /* HVC */
|
||||||
case 0x0d:
|
case 0x0d:
|
||||||
|
{
|
||||||
return (vdp_hvc_r(mcycles_z80) & 0xff);
|
return (vdp_hvc_r(mcycles_z80) & 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,31 +261,45 @@ void zbank_write_vdp(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(mcycles_z80, data);
|
if (!(address & 1))
|
||||||
else
|
{
|
||||||
zbank_unused_w(address, data);
|
zbank_unused_w(address, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
psg_write(mcycles_z80, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
case 0x18: /* Unused */
|
||||||
|
{
|
||||||
zbank_unused_w(address, data);
|
zbank_unused_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x1c: /* TEST register */
|
case 0x1c: /* TEST register */
|
||||||
|
{
|
||||||
vdp_test_w(data << 8 | data);
|
vdp_test_w(data << 8 | data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default: /* Invalid address */
|
default: /* Invalid address */
|
||||||
|
{
|
||||||
zbank_lockup_w(address, data);
|
zbank_lockup_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
123
source/memz80.c
123
source/memz80.c
@ -1,6 +1,6 @@
|
|||||||
/***************************************************************************************
|
/***************************************************************************************
|
||||||
* Genesis Plus
|
* Genesis Plus
|
||||||
* Z80 bus arbitration (Genesis mode)
|
* Z80 bus address decoding (Genesis mode)
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||||
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
* Eke-Eke (2007,2008,2009), additional code & fixes for the GCN/Wii port
|
||||||
@ -65,78 +65,6 @@ static inline unsigned int z80_lockup_r(unsigned int address)
|
|||||||
}
|
}
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
VDP access
|
|
||||||
*/
|
|
||||||
static inline unsigned int z80_vdp_r(unsigned int address)
|
|
||||||
{
|
|
||||||
switch (address & 0xfd)
|
|
||||||
{
|
|
||||||
case 0x00: /* DATA */
|
|
||||||
return (vdp_data_r() >> 8);
|
|
||||||
|
|
||||||
case 0x01: /* DATA */
|
|
||||||
return (vdp_data_r() & 0xff);
|
|
||||||
|
|
||||||
case 0x04: /* CTRL */
|
|
||||||
return (0xfc | (vdp_ctrl_r(mcycles_z80) >> 8));
|
|
||||||
|
|
||||||
case 0x05: /* CTRL */
|
|
||||||
return (vdp_ctrl_r(mcycles_z80) & 0xff);
|
|
||||||
|
|
||||||
case 0x08: /* HVC */
|
|
||||||
case 0x0c:
|
|
||||||
return (vdp_hvc_r(mcycles_z80) >> 8);
|
|
||||||
|
|
||||||
case 0x09: /* HVC */
|
|
||||||
case 0x0d:
|
|
||||||
return (vdp_hvc_r(mcycles_z80) & 0xff);
|
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
|
||||||
case 0x19:
|
|
||||||
case 0x1c:
|
|
||||||
case 0x1d:
|
|
||||||
return z80_unused_r(address);
|
|
||||||
|
|
||||||
default: /* Invalid address */
|
|
||||||
return z80_lockup_r(address);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void z80_vdp_w(unsigned int address, unsigned int data)
|
|
||||||
{
|
|
||||||
switch (address & 0xfc)
|
|
||||||
{
|
|
||||||
case 0x00: /* Data port */
|
|
||||||
vdp_data_w(data << 8 | data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x04: /* Control port */
|
|
||||||
vdp_ctrl_w(data << 8 | data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x10: /* PSG */
|
|
||||||
case 0x14:
|
|
||||||
if (address & 1)
|
|
||||||
psg_write(mcycles_z80, data);
|
|
||||||
else
|
|
||||||
z80_unused_w(address, data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x18: /* Unused */
|
|
||||||
z80_unused_w(address, data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x1c: /* Test register */
|
|
||||||
vdp_test_w(data << 8 | data);
|
|
||||||
return;
|
|
||||||
|
|
||||||
default: /* Invalid address */
|
|
||||||
z80_lockup_w(address, data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Z80 memory handlers
|
Z80 memory handlers
|
||||||
*/
|
*/
|
||||||
@ -146,23 +74,33 @@ unsigned int cpu_readmem16(unsigned int address)
|
|||||||
{
|
{
|
||||||
case 0: /* Work RAM */
|
case 0: /* Work RAM */
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
return zram[address & 0x1fff];
|
return zram[address & 0x1fff];
|
||||||
|
}
|
||||||
|
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
|
{
|
||||||
return fm_read(mcycles_68k, address & 3);
|
return fm_read(mcycles_68k, address & 3);
|
||||||
|
}
|
||||||
|
|
||||||
case 3: /* VDP */
|
case 3: /* VDP */
|
||||||
if ((address >> 8) == 0x7f)
|
{
|
||||||
return z80_vdp_r (address);
|
if ((address >> 8) != 0x7f)
|
||||||
return z80_unused_r(address);
|
{
|
||||||
|
return z80_unused_r(address);
|
||||||
|
}
|
||||||
|
return (*zbank_memory_map[0xc0].read)(address);
|
||||||
|
}
|
||||||
|
|
||||||
default: /* V-bus bank */
|
default: /* V-bus bank */
|
||||||
{
|
{
|
||||||
address = zbank | (address & 0x7fff);
|
address = zbank | (address & 0x7fff);
|
||||||
int slot = address >> 16;
|
unsigned int slot = address >> 16;
|
||||||
if (zbank_memory_map[slot].read)
|
if (zbank_memory_map[slot].read)
|
||||||
|
{
|
||||||
return (*zbank_memory_map[slot].read)(address);
|
return (*zbank_memory_map[slot].read)(address);
|
||||||
return READ_BYTE(m68k_memory_map[slot].base, address&0xffff);
|
}
|
||||||
|
return READ_BYTE(m68k_memory_map[slot].base, address & 0xffff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,38 +112,51 @@ void cpu_writemem16(unsigned int address, unsigned int data)
|
|||||||
{
|
{
|
||||||
case 0: /* Work RAM */
|
case 0: /* Work RAM */
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
zram[address & 0x1fff] = data;
|
zram[address & 0x1fff] = data;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 2: /* YM2612 */
|
case 2: /* YM2612 */
|
||||||
|
{
|
||||||
fm_write(mcycles_z80, address & 3, data);
|
fm_write(mcycles_z80, address & 3, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 3: /* Bank register and VDP */
|
case 3: /* Bank register and VDP */
|
||||||
|
{
|
||||||
switch(address >> 8)
|
switch(address >> 8)
|
||||||
{
|
{
|
||||||
case 0x60:
|
case 0x60:
|
||||||
gen_bank_w(data & 1);
|
{
|
||||||
|
gen_zbank_w(data & 1);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x7f:
|
case 0x7f:
|
||||||
z80_vdp_w(address, data);
|
{
|
||||||
|
(*zbank_memory_map[0xc0].write)(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
z80_unused_w(address, data);
|
z80_unused_w(address, data);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
}
|
||||||
|
|
||||||
default: /* V-bus bank */
|
default: /* V-bus bank */
|
||||||
{
|
{
|
||||||
address = zbank | (address & 0x7fff);
|
address = zbank | (address & 0x7fff);
|
||||||
int slot = address >> 16;
|
unsigned int slot = address >> 16;
|
||||||
if (zbank_memory_map[slot].write)
|
if (zbank_memory_map[slot].write)
|
||||||
|
{
|
||||||
(*zbank_memory_map[slot].write)(address, data);
|
(*zbank_memory_map[slot].write)(address, data);
|
||||||
else
|
return;
|
||||||
WRITE_BYTE(m68k_memory_map[slot].base, address&0xffff, data);
|
}
|
||||||
|
WRITE_BYTE(m68k_memory_map[slot].base, address & 0xffff, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -223,7 +174,7 @@ unsigned int cpu_readport16(unsigned int port)
|
|||||||
#if LOGERROR
|
#if LOGERROR
|
||||||
error("Z80 read port %04X\n", port);
|
error("Z80 read port %04X\n", port);
|
||||||
#endif
|
#endif
|
||||||
return 0xFF;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cpu_writeport16(unsigned int port, unsigned int data)
|
void cpu_writeport16(unsigned int port, unsigned int data)
|
||||||
|
@ -926,7 +926,6 @@ static inline uint32 get_hscroll(int line)
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/* Layers render functions */
|
/* Layers render functions */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void render_bg(int line, int width)
|
static void render_bg(int line, int width)
|
||||||
{
|
{
|
||||||
uint32 column, atex, atbuf, *src, *dst;
|
uint32 column, atex, atbuf, *src, *dst;
|
||||||
@ -1723,9 +1722,8 @@ void render_shutdown(void)
|
|||||||
|
|
||||||
void render_line(int line)
|
void render_line(int line)
|
||||||
{
|
{
|
||||||
/* display OFF */
|
/* display disabled */
|
||||||
if (reg[0] & 0x01)
|
if (reg[0] & 0x01) return;
|
||||||
return;
|
|
||||||
|
|
||||||
uint8 *lb = tmp_buf;
|
uint8 *lb = tmp_buf;
|
||||||
int width = bitmap.viewport.w;
|
int width = bitmap.viewport.w;
|
||||||
|
@ -27,7 +27,7 @@ void set_config_defaults(void)
|
|||||||
config.region_detect = 0;
|
config.region_detect = 0;
|
||||||
config.force_dtack = 0;
|
config.force_dtack = 0;
|
||||||
config.addr_error = 1;
|
config.addr_error = 1;
|
||||||
config.bios_enabled = 0;
|
config.tmss = 0;
|
||||||
config.lock_on = 0;
|
config.lock_on = 0;
|
||||||
config.romtype = 0;
|
config.romtype = 0;
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ void set_config_defaults(void)
|
|||||||
config.gun_cursor[1] = 1;
|
config.gun_cursor[1] = 1;
|
||||||
config.invert_mouse = 0;
|
config.invert_mouse = 0;
|
||||||
for (i=0;i<MAX_INPUTS;i++)
|
for (i=0;i<MAX_INPUTS;i++)
|
||||||
|
{
|
||||||
config.input[i].padtype = DEVICE_3BUTTON;
|
config.input[i].padtype = DEVICE_3BUTTON;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,35 +9,36 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8 padtype;
|
uint8 padtype;
|
||||||
} t_input_c;
|
} t_input_config;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint8 hq_fm;
|
uint8 hq_fm;
|
||||||
uint8 psgBoostNoise;
|
|
||||||
int32 psg_preamp;
|
|
||||||
int32 fm_preamp;
|
|
||||||
uint8 filter;
|
uint8 filter;
|
||||||
uint16 low_freq;
|
uint8 psgBoostNoise;
|
||||||
uint16 high_freq;
|
|
||||||
uint8 lp_range;
|
|
||||||
float lg;
|
|
||||||
float mg;
|
|
||||||
float hg;
|
|
||||||
float rolloff;
|
|
||||||
uint8 dac_bits;
|
uint8 dac_bits;
|
||||||
|
int16 psg_preamp;
|
||||||
|
int16 fm_preamp;
|
||||||
|
int16 lp_range;
|
||||||
|
int16 low_freq;
|
||||||
|
int16 high_freq;
|
||||||
|
int16 lg;
|
||||||
|
int16 mg;
|
||||||
|
int16 hg;
|
||||||
|
float rolloff;
|
||||||
uint8 region_detect;
|
uint8 region_detect;
|
||||||
uint8 force_dtack;
|
uint8 force_dtack;
|
||||||
uint8 addr_error;
|
uint8 addr_error;
|
||||||
uint8 bios_enabled;
|
uint8 tmss;
|
||||||
uint8 lock_on;
|
uint8 lock_on;
|
||||||
|
uint8 hot_swap;
|
||||||
uint8 romtype;
|
uint8 romtype;
|
||||||
uint8 overscan;
|
|
||||||
uint8 render;
|
|
||||||
uint8 ntsc;
|
|
||||||
t_input_c input[MAX_INPUTS];
|
|
||||||
uint8 gun_cursor[2];
|
|
||||||
uint8 invert_mouse;
|
uint8 invert_mouse;
|
||||||
|
uint8 gun_cursor[2];
|
||||||
|
uint8 overscan;
|
||||||
|
uint8 ntsc;
|
||||||
|
uint8 render;
|
||||||
|
t_input_config input[MAX_INPUTS];
|
||||||
} t_config;
|
} t_config;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
|
@ -215,8 +215,8 @@ void vdp_reset(void)
|
|||||||
if (config.overscan & 2)
|
if (config.overscan & 2)
|
||||||
bitmap.viewport.x = 12;
|
bitmap.viewport.x = 12;
|
||||||
|
|
||||||
/* reset some registers normally set by BIOS */
|
/* initialize registers if OS ROM is not used */
|
||||||
if (config.bios_enabled == 1)
|
if (config.tmss == 1)
|
||||||
{
|
{
|
||||||
reg_w(0 , 0x04); /* Palette bit set */
|
reg_w(0 , 0x04); /* Palette bit set */
|
||||||
reg_w(1 , 0x04); /* Mode 5 enabled */
|
reg_w(1 , 0x04); /* Mode 5 enabled */
|
||||||
@ -489,7 +489,7 @@ void vdp_data_w(unsigned int data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* restricted VDP writes during active display */
|
/* restricted VDP writes during active display */
|
||||||
if (!(status&8) && (reg[1]&0x40))
|
if (!(status & 8) && (reg[1] & 0x40))
|
||||||
{
|
{
|
||||||
/* update VDP FIFO */
|
/* update VDP FIFO */
|
||||||
fifo_update(mcycles_68k);
|
fifo_update(mcycles_68k);
|
||||||
|
Loading…
Reference in New Issue
Block a user