mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-28 12:11:50 +01:00
optimized 68k core using prebuild const tables
This commit is contained in:
parent
b051d03f86
commit
873870b4a1
@ -316,6 +316,7 @@ void m68k_run(unsigned int cycles)
|
||||
|
||||
void m68k_init(void)
|
||||
{
|
||||
#ifdef BUILD_TABLES
|
||||
static uint emulation_initialized = 0;
|
||||
|
||||
/* The first call to this function initializes the opcode handler jump table */
|
||||
@ -324,6 +325,7 @@ void m68k_init(void)
|
||||
m68ki_build_opcode_table();
|
||||
emulation_initialized = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_INT_ACK == OPT_ON
|
||||
m68k_set_int_ack_callback(NULL);
|
||||
|
@ -738,7 +738,11 @@ int emulate_address_error;
|
||||
static unsigned int end_cycles;
|
||||
|
||||
/* Cycles used by CPU instructions */
|
||||
#ifdef BUILD_TABLES
|
||||
static unsigned char m68ki_cycles[0x10000];
|
||||
#else
|
||||
#include "m68ki_cycles.h"
|
||||
#endif
|
||||
|
||||
/* Used by shift & rotate instructions */
|
||||
static const uint8 m68ki_shift_8_table[65] =
|
||||
@ -1047,58 +1051,70 @@ INLINE uint m68ki_read_imm_32(void)
|
||||
*/
|
||||
INLINE uint m68ki_read_8_fc(uint address, uint fc)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
|
||||
else return READ_BYTE(temp->base, (address) & 0xffff);
|
||||
}
|
||||
|
||||
INLINE uint m68ki_read_16_fc(uint address, uint fc)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
|
||||
else return *(uint16 *)(temp->base + ((address) & 0xffff));
|
||||
}
|
||||
|
||||
INLINE uint m68ki_read_32_fc(uint address, uint fc)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_READ, fc) /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
|
||||
else return m68k_read_immediate_32(address);
|
||||
}
|
||||
|
||||
INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
|
||||
else WRITE_BYTE(temp->base, (address) & 0xffff, value);
|
||||
}
|
||||
|
||||
INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
|
||||
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
|
||||
}
|
||||
|
||||
INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
|
||||
{
|
||||
_m68k_memory_map *temp;
|
||||
|
||||
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
|
||||
m68ki_check_address_error(address, MODE_WRITE, fc) /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16);
|
||||
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value >> 16;
|
||||
|
||||
@ -1521,6 +1537,8 @@ INLINE void m68ki_exception_address_error(void)
|
||||
/* Service an interrupt request and start exception processing */
|
||||
INLINE void m68ki_exception_interrupt(uint int_level)
|
||||
{
|
||||
uint vector, sr, new_pc;
|
||||
|
||||
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
|
||||
CPU_INSTR_MODE = INSTRUCTION_NO;
|
||||
#endif /* M68K_EMULATE_ADDRESS_ERROR */
|
||||
@ -1533,10 +1551,10 @@ INLINE void m68ki_exception_interrupt(uint int_level)
|
||||
return;
|
||||
|
||||
/* Always use the autovectors. */
|
||||
uint vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
|
||||
vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
|
||||
|
||||
/* Start exception processing */
|
||||
uint sr = m68ki_init_exception();
|
||||
sr = m68ki_init_exception();
|
||||
|
||||
/* Set the interrupt mask to the level of the one being serviced */
|
||||
FLAG_INT_MASK = int_level<<8;
|
||||
@ -1545,7 +1563,7 @@ INLINE void m68ki_exception_interrupt(uint int_level)
|
||||
m68ki_int_ack(int_level)
|
||||
|
||||
/* Get the new PC */
|
||||
uint new_pc = m68ki_read_data_32(vector<<2);
|
||||
new_pc = m68ki_read_data_32(vector<<2);
|
||||
|
||||
/* If vector is uninitialized, call the uninitialized interrupt vector */
|
||||
if(new_pc == 0)
|
||||
|
4099
source/m68k/m68ki_cycles.h
Normal file
4099
source/m68k/m68ki_cycles.h
Normal file
File diff suppressed because it is too large
Load Diff
8195
source/m68k/m68ki_instruction_jump_table.h
Normal file
8195
source/m68k/m68ki_instruction_jump_table.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -53,6 +53,8 @@ INLINE void UseDivsCycles(sint32 dst, sint16 src)
|
||||
|
||||
if ((abs(dst) >> 16) < abs(src))
|
||||
{
|
||||
int i;
|
||||
|
||||
/* absolute quotient */
|
||||
uint32 quotient = abs(dst) / abs(src);
|
||||
|
||||
@ -68,7 +70,6 @@ INLINE void UseDivsCycles(sint32 dst, sint16 src)
|
||||
}
|
||||
|
||||
/* check higher 15-bits of quotient */
|
||||
int i;
|
||||
for (i=0; i<15; i++)
|
||||
{
|
||||
quotient >>= 1;
|
||||
@ -19693,7 +19694,7 @@ static void m68k_op_sbcd_8_rr(void)
|
||||
uint dst = *r_dst;
|
||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||
|
||||
// FLAG_V = ~res; /* Undefined V behavior */
|
||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to assume cleared. */
|
||||
|
||||
if(res > 9)
|
||||
@ -19710,8 +19711,8 @@ static void m68k_op_sbcd_8_rr(void)
|
||||
|
||||
res = MASK_OUT_ABOVE_8(res);
|
||||
|
||||
// FLAG_V &= res; /* Undefined V behavior part II */
|
||||
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||
/* FLAG_V &= res; */ /* Undefined V behavior part II */
|
||||
/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
|
||||
FLAG_Z |= res;
|
||||
|
||||
*r_dst = MASK_OUT_BELOW_8(*r_dst) | res;
|
||||
@ -19725,7 +19726,7 @@ static void m68k_op_sbcd_8_mm_ax7(void)
|
||||
uint dst = m68ki_read_8(ea);
|
||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||
|
||||
// FLAG_V = ~res; /* Undefined V behavior */
|
||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
||||
|
||||
if(res > 9)
|
||||
@ -19742,8 +19743,8 @@ static void m68k_op_sbcd_8_mm_ax7(void)
|
||||
|
||||
res = MASK_OUT_ABOVE_8(res);
|
||||
|
||||
// FLAG_V &= res; /* Undefined V behavior part II */
|
||||
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||
/* FLAG_V &= res; */ /* Undefined V behavior part II */
|
||||
/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
|
||||
FLAG_Z |= res;
|
||||
|
||||
m68ki_write_8(ea, res);
|
||||
@ -19757,7 +19758,7 @@ static void m68k_op_sbcd_8_mm_ay7(void)
|
||||
uint dst = m68ki_read_8(ea);
|
||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||
|
||||
// FLAG_V = ~res; /* Undefined V behavior */
|
||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
||||
|
||||
if(res > 9)
|
||||
@ -19774,8 +19775,8 @@ static void m68k_op_sbcd_8_mm_ay7(void)
|
||||
|
||||
res = MASK_OUT_ABOVE_8(res);
|
||||
|
||||
// FLAG_V &= res; /* Undefined V behavior part II */
|
||||
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||
/* FLAG_V &= res; */ /* Undefined V behavior part II */
|
||||
/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
|
||||
FLAG_Z |= res;
|
||||
|
||||
m68ki_write_8(ea, res);
|
||||
@ -19789,7 +19790,7 @@ static void m68k_op_sbcd_8_mm_axy7(void)
|
||||
uint dst = m68ki_read_8(ea);
|
||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||
|
||||
// FLAG_V = ~res; /* Undefined V behavior */
|
||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
||||
|
||||
if(res > 9)
|
||||
@ -19806,8 +19807,8 @@ static void m68k_op_sbcd_8_mm_axy7(void)
|
||||
|
||||
res = MASK_OUT_ABOVE_8(res);
|
||||
|
||||
// FLAG_V &= res; /* Undefined V behavior part II */
|
||||
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||
/* FLAG_V &= res; */ /* Undefined V behavior part II */
|
||||
/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
|
||||
FLAG_Z |= res;
|
||||
|
||||
m68ki_write_8(ea, res);
|
||||
@ -19821,7 +19822,7 @@ static void m68k_op_sbcd_8_mm(void)
|
||||
uint dst = m68ki_read_8(ea);
|
||||
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1();
|
||||
|
||||
// FLAG_V = ~res; /* Undefined V behavior */
|
||||
/* FLAG_V = ~res; */ /* Undefined V behavior */
|
||||
FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
|
||||
|
||||
if(res > 9)
|
||||
@ -19838,8 +19839,8 @@ static void m68k_op_sbcd_8_mm(void)
|
||||
|
||||
res = MASK_OUT_ABOVE_8(res);
|
||||
|
||||
// FLAG_V &= res; /* Undefined V behavior part II */
|
||||
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */
|
||||
/* FLAG_V &= res; */ /* Undefined V behavior part II */
|
||||
/* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
|
||||
FLAG_Z |= res;
|
||||
|
||||
m68ki_write_8(ea, res);
|
||||
@ -23126,9 +23127,7 @@ static void m68k_op_tas_8_ai(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23146,9 +23145,7 @@ static void m68k_op_tas_8_pi(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23166,9 +23163,7 @@ static void m68k_op_tas_8_pi7(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23186,9 +23181,7 @@ static void m68k_op_tas_8_pd(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23206,9 +23199,7 @@ static void m68k_op_tas_8_pd7(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23226,9 +23217,7 @@ static void m68k_op_tas_8_di(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23246,9 +23235,7 @@ static void m68k_op_tas_8_ix(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23266,9 +23253,7 @@ static void m68k_op_tas_8_aw(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23286,9 +23271,7 @@ static void m68k_op_tas_8_al(void)
|
||||
disabled in order to function properly. Some Amiga software may also rely
|
||||
on this, but only when accessing specific addresses so additional functionality
|
||||
will be needed. */
|
||||
uint allow_writeback = m68ki_tas_callback();
|
||||
|
||||
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
|
||||
if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
|
||||
}
|
||||
|
||||
|
||||
@ -23614,6 +23597,12 @@ static void m68k_op_unlk_32(void)
|
||||
/* ========================= OPCODE TABLE BUILDER ========================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
#ifndef BUILD_TABLES
|
||||
|
||||
#include "m68ki_instruction_jump_table.h"
|
||||
|
||||
#else
|
||||
|
||||
/* This is used to generate the opcode handler jump table */
|
||||
typedef struct
|
||||
{
|
||||
@ -25347,7 +25336,7 @@ static void m68ki_build_opcode_table(void)
|
||||
{
|
||||
/* default to illegal */
|
||||
m68ki_instruction_jump_table[i] = m68k_op_illegal;
|
||||
m68ki_cycles[i] = 0;
|
||||
m68ki_cycles[i] = 4;
|
||||
}
|
||||
|
||||
ostruct = &m68k_opcode_handler_table[0];
|
||||
@ -25420,6 +25409,7 @@ static void m68ki_build_opcode_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ======================================================================== */
|
||||
/* ============================== END OF FILE ============================= */
|
||||
|
Loading…
Reference in New Issue
Block a user