mirror of
https://github.com/holub/mame
synced 2025-04-26 02:07:14 +03:00
(SNES) Rewritten cycle steal code from scratch and nailed it directly in the G65816 CPU core [Angelo Salese, byuu]
This commit is contained in:
parent
6f13297dcf
commit
170b6ae5c2
@ -143,6 +143,9 @@ extern void g65816i_set_reg_E(g65816i_cpu_struct *cpustate, int regnum, uint val
|
||||
extern void g65816i_set_line_E(g65816i_cpu_struct *cpustate, int line, int state);
|
||||
extern int g65816i_execute_E(g65816i_cpu_struct *cpustate, int cycles);
|
||||
|
||||
extern int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
|
||||
|
||||
|
||||
void (*const *const g65816i_opcodes[5])(g65816i_cpu_struct *cpustate) =
|
||||
{
|
||||
g65816i_opcodes_M0X0,
|
||||
@ -525,6 +528,22 @@ CPU_GET_INFO( g65816 )
|
||||
SNES specific, used to handle master cycles
|
||||
*/
|
||||
|
||||
int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr)
|
||||
{
|
||||
if(cpustate->cpu_type == CPU_TYPE_G65816)
|
||||
return 0;
|
||||
|
||||
if(addr & 0x408000) {
|
||||
if(addr & 0x800000) return (1) ? 6 : 8; // TODO: fastROM setting
|
||||
return 8;
|
||||
}
|
||||
if((addr + 0x6000) & 0x4000) return 8;
|
||||
if((addr - 0x4000) & 0x7e00) return 6;
|
||||
|
||||
return 12;
|
||||
}
|
||||
|
||||
|
||||
static CPU_INIT( 5a22 )
|
||||
{
|
||||
g65816i_cpu_struct *cpustate = get_safe_token(device);
|
||||
|
@ -103,6 +103,7 @@ struct _g65816i_cpu_struct
|
||||
void (*set_reg)(g65816i_cpu_struct *cpustate, int regnum, uint val);
|
||||
void (*set_line)(g65816i_cpu_struct *cpustate, int line, int state);
|
||||
int (*execute)(g65816i_cpu_struct *cpustate, int cycles);
|
||||
int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
|
||||
uint source;
|
||||
uint destination;
|
||||
int ICount;
|
||||
@ -114,6 +115,7 @@ extern uint (*const g65816i_get_reg[])(g65816i_cpu_struct *cpustate, int regnum)
|
||||
extern void (*const g65816i_set_reg[])(g65816i_cpu_struct *cpustate, int regnum, uint val);
|
||||
extern void (*const g65816i_set_line[])(g65816i_cpu_struct *cpustate, int line, int state);
|
||||
extern int (*const g65816i_execute[])(g65816i_cpu_struct *cpustate, int cycles);
|
||||
extern int bus_5A22_cycle_burst(g65816i_cpu_struct *cpustate, uint addr);
|
||||
|
||||
#define REGISTER_A cpustate->a /* Accumulator */
|
||||
#define REGISTER_B cpustate->b /* Accumulator hi byte */
|
||||
@ -244,6 +246,7 @@ INLINE void g65816i_set_execution_mode(g65816i_cpu_struct *cpustate, uint mode)
|
||||
#define CLK_W_SIY 5
|
||||
|
||||
#define CLK(A) CLOCKS -= (cpustate->cpu_type == CPU_TYPE_G65816 ? A : A*6)
|
||||
#define CLK_BUS(A) CLOCKS -= A
|
||||
#define USE_ALL_CLKS() CLOCKS = 0
|
||||
|
||||
|
||||
|
@ -59,12 +59,14 @@
|
||||
INLINE uint g65816i_read_8_normal(g65816i_cpu_struct *cpustate, uint address)
|
||||
{
|
||||
address = ADDRESS_65816(address);
|
||||
CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
|
||||
return g65816_read_8(address);
|
||||
}
|
||||
|
||||
INLINE uint g65816i_read_8_immediate(g65816i_cpu_struct *cpustate, uint address)
|
||||
{
|
||||
address = ADDRESS_65816(address);
|
||||
CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
|
||||
return g65816_read_8_immediate(address);
|
||||
}
|
||||
|
||||
@ -76,6 +78,7 @@ INLINE uint g65816i_read_8_direct(g65816i_cpu_struct *cpustate, uint address)
|
||||
#else
|
||||
address = ADDRESS_65816(address);
|
||||
#endif
|
||||
CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
|
||||
return g65816_read_8(address);
|
||||
}
|
||||
|
||||
@ -90,6 +93,7 @@ INLINE uint g65816i_read_8_vector(g65816i_cpu_struct *cpustate, uint address)
|
||||
INLINE void g65816i_write_8_normal(g65816i_cpu_struct *cpustate, uint address, uint value)
|
||||
{
|
||||
address = ADDRESS_65816(address);
|
||||
CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
|
||||
g65816_write_8(address, MAKE_UINT_8(value));
|
||||
}
|
||||
|
||||
@ -101,6 +105,7 @@ INLINE void g65816i_write_8_direct(g65816i_cpu_struct *cpustate, uint address, u
|
||||
#else
|
||||
address = ADDRESS_65816(address);
|
||||
#endif
|
||||
CLOCKS -= (bus_5A22_cycle_burst(cpustate,address));
|
||||
g65816_write_8(address, MAKE_UINT_8(value));
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,10 @@
|
||||
Thanks to Anomie for invaluable technical information.
|
||||
Thanks to byuu for invaluable technical information.
|
||||
|
||||
TODO:
|
||||
- DMA takes some Master CPU clock cycles that aren't taken into account
|
||||
for now.
|
||||
|
||||
***************************************************************************/
|
||||
#define __MACHINE_SNES_C
|
||||
|
||||
@ -55,8 +59,6 @@ struct snes_cart_info snes_cart;
|
||||
#include "machine/snes7110.c"
|
||||
#include "machine/snesbsx.c"
|
||||
|
||||
#define USE_CYCLE_STEAL 1
|
||||
|
||||
// ST-010 and ST-011 RAM interface
|
||||
UINT8 st010_read_ram(snes_state *state, UINT16 addr)
|
||||
{
|
||||
@ -892,70 +894,6 @@ address | | | | | | |
|
||||
|
||||
*/
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
/*FIXME: missing work RAM access steal / we need to do this less "aggressive" otherwise we lose too much CPU horsepower, why? */
|
||||
static int snes_bank_0x00_0x3f_cycles(running_machine &machine,UINT32 offset)
|
||||
{
|
||||
/*
|
||||
$00-$3F | $0000-$1FFF | Slow | Address Bus A + /WRAM (mirror $7E:0000-$1FFF)
|
||||
| $2000-$20FF | Fast | Address Bus A
|
||||
| $2100-$21FF | Fast | Address Bus B
|
||||
| $2200-$3FFF | Fast | Address Bus A
|
||||
| $4000-$41FF | XSlow | Internal CPU registers (see Note 1 below)
|
||||
| $4200-$43FF | Fast | Internal CPU registers (see Note 1 below)
|
||||
| $4400-$5FFF | Fast | Address Bus A
|
||||
| $6000-$7FFF | Slow | Address Bus A
|
||||
| $8000-$FFFF | Slow | Address Bus A + /CART
|
||||
*/
|
||||
|
||||
if(((offset & 0xff00) == 0x4000) || ((offset & 0xff00) == 0x4100))
|
||||
return 0; //TODO: 12
|
||||
if(((offset & 0xff00) == 0x4200) || ((offset & 0xff00) == 0x4300))
|
||||
return 0; //TODO: 6
|
||||
|
||||
if((offset & 0xff00) <= 0x1f00)
|
||||
return 0; //TODO: 8
|
||||
|
||||
if((offset & 0xff00) >= 0x6000)
|
||||
return 8;
|
||||
|
||||
return 0; //TODO: 6
|
||||
}
|
||||
|
||||
static int snes_bank_0x80_0xbf_cycles(running_machine &machine,UINT32 offset)
|
||||
{
|
||||
/*
|
||||
$80-$BF | $0000-$1FFF | Slow | Address Bus A + /WRAM (mirror $7E:0000-$1FFF)
|
||||
| $2000-$20FF | Fast | Address Bus A
|
||||
| $2100-$21FF | Fast | Address Bus B
|
||||
| $2200-$3FFF | Fast | Address Bus A
|
||||
| $4000-$41FF | XSlow | Internal CPU registers (see Note 1 below)
|
||||
| $4200-$43FF | Fast | Internal CPU registers (see Note 1 below)
|
||||
| $4400-$5FFF | Fast | Address Bus A
|
||||
| $6000-$7FFF | Slow | Address Bus A
|
||||
| $8000-$FFFF | Note2 | Address Bus A + /CART
|
||||
*/
|
||||
|
||||
|
||||
if(((offset & 0xff00) == 0x4000) || ((offset & 0xff00) == 0x4100))
|
||||
return 0; //TODO: 12
|
||||
|
||||
if(((offset & 0xff00) == 0x4200) || ((offset & 0xff00) == 0x4300))
|
||||
return 0; //TODO: 6
|
||||
|
||||
if((offset & 0xff00) <= 0x1f00)
|
||||
return 0; //TODO: 8
|
||||
|
||||
if(((offset & 0xff00) >= 0x6000) && ((offset & 0xff00) <= 0x7f00))
|
||||
return 0; //TODO: 8
|
||||
|
||||
if(((offset & 0xff00) >= 0x8000) && ((offset & 0xff00) <= 0xff00))
|
||||
return (snes_ram[MEMSEL] & 1) ? 6 : 8;
|
||||
|
||||
return 0; //TODO: 6
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 0x000000 - 0x2fffff */
|
||||
READ8_HANDLER( snes_r_bank1 )
|
||||
{
|
||||
@ -1007,11 +945,6 @@ READ8_HANDLER( snes_r_bank1 )
|
||||
else
|
||||
value = snes_ram[offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1074,11 +1007,6 @@ READ8_HANDLER( snes_r_bank2 )
|
||||
else
|
||||
value = snes_ram[0x300000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1117,11 +1045,6 @@ READ8_HANDLER( snes_r_bank3 )
|
||||
else /* Mode 21 & 25 + SuperFX games */
|
||||
value = snes_ram[0x400000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -8);
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1166,11 +1089,6 @@ READ8_HANDLER( snes_r_bank4 )
|
||||
else if (state->m_cart[0].mode & 0x0a) /* Mode 21 & 25 */
|
||||
value = snes_ram[0x600000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -8);
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1204,11 +1122,6 @@ READ8_HANDLER( snes_r_bank5 )
|
||||
else
|
||||
value = snes_ram[0x700000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -8);
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1254,11 +1167,6 @@ READ8_HANDLER( snes_r_bank6 )
|
||||
else
|
||||
value = snes_ram[0x800000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x80_0xbf_cycles(space->machine(), offset));
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1318,11 +1226,6 @@ READ8_HANDLER( snes_r_bank7 )
|
||||
else /* Mode 21 & 25 + SuperFX Games */
|
||||
value = snes_ram[0xc00000 + offset];
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -((snes_ram[MEMSEL] & 1) ? 6 : 8));
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1376,11 +1279,6 @@ WRITE8_HANDLER( snes_w_bank1 )
|
||||
dsp_set_sr(data);
|
||||
else
|
||||
logerror( "(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset );
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 0x300000 - 0x3fffff */
|
||||
@ -1438,11 +1336,6 @@ WRITE8_HANDLER( snes_w_bank2 )
|
||||
dsp_set_sr(data);
|
||||
else
|
||||
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x300000);
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x00_0x3f_cycles(space->machine(), offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 0x600000 - 0x6fffff */
|
||||
@ -1479,11 +1372,6 @@ WRITE8_HANDLER( snes_w_bank4 )
|
||||
}
|
||||
else if (state->m_cart[0].mode & 0x0a)
|
||||
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x600000);
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -8);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 0x700000 - 0x7dffff */
|
||||
@ -1506,11 +1394,6 @@ WRITE8_HANDLER( snes_w_bank5 )
|
||||
}
|
||||
else if (state->m_cart[0].mode & 0x0a)
|
||||
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x700000);
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -8);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1562,11 +1445,6 @@ WRITE8_HANDLER( snes_w_bank6 )
|
||||
dsp_set_sr(data);
|
||||
else
|
||||
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0x800000);
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -snes_bank_0x80_0xbf_cycles(space->machine(), offset));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -1617,11 +1495,6 @@ WRITE8_HANDLER( snes_w_bank7 )
|
||||
}
|
||||
else if (state->m_cart[0].mode & 0x0a)
|
||||
logerror("(PC=%06x) Attempt to write to ROM address: %X\n",cpu_get_pc(&space->device()),offset + 0xc00000);
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
if(!space->debugger_access())
|
||||
device_adjust_icount(&space->device(), -((snes_ram[MEMSEL] & 1) ? 6 : 8));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2143,12 +2016,6 @@ INLINE void snes_dma_transfer( address_space *space, UINT8 dma, UINT32 abus, UIN
|
||||
{
|
||||
snes_state *state = space->machine().driver_data<snes_state>();
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
/* every byte transfer takes 8 master cycles */
|
||||
// FIXME: this cycle steal makes Final Fantasy VI (III in US) very glitchy!
|
||||
// device_adjust_icount(&space->device(),-8);
|
||||
#endif
|
||||
|
||||
if (state->m_dma_channel[dma].dmap & 0x80) /* PPU->CPU */
|
||||
{
|
||||
if (bbus == 0x2180 && ((abus & 0xfe0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000))
|
||||
@ -2355,11 +2222,6 @@ static void snes_dma( address_space *space, UINT8 channels )
|
||||
|
||||
/* FIXME: we also need to round to the nearest 8 master cycles */
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
/* overhead steals 8 master cycles, correct? */
|
||||
device_adjust_icount(&space->device(),-8);
|
||||
#endif
|
||||
|
||||
/* Assume priority of the 8 DMA channels is 0-7 */
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
@ -2468,18 +2330,9 @@ static void snes_dma( address_space *space, UINT8 channels )
|
||||
/* We're done, so write the new abus back to the registers */
|
||||
state->m_dma_channel[i].src_addr = abus;
|
||||
state->m_dma_channel[i].trans_size = 0;
|
||||
|
||||
#if USE_CYCLE_STEAL
|
||||
/* active channel takes 8 master cycles */
|
||||
device_adjust_icount(&space->device(),-8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* finally, take yet another 8 master cycles for the aforementioned overhead */
|
||||
#if USE_CYCLE_STEAL
|
||||
device_adjust_icount(&space->device(),-8);
|
||||
#endif
|
||||
}
|
||||
|
||||
READ8_HANDLER( superfx_r_bank1 )
|
||||
|
Loading…
Reference in New Issue
Block a user