optimized 68k core using prebuild const tables

This commit is contained in:
ekeeke31 2012-01-15 19:56:30 +00:00
parent b051d03f86
commit 873870b4a1
5 changed files with 12358 additions and 54 deletions

View File

@ -316,6 +316,7 @@ void m68k_run(unsigned int cycles)
void m68k_init(void) void m68k_init(void)
{ {
#ifdef BUILD_TABLES
static uint emulation_initialized = 0; static uint emulation_initialized = 0;
/* The first call to this function initializes the opcode handler jump table */ /* The first call to this function initializes the opcode handler jump table */
@ -324,6 +325,7 @@ void m68k_init(void)
m68ki_build_opcode_table(); m68ki_build_opcode_table();
emulation_initialized = 1; emulation_initialized = 1;
} }
#endif
#if M68K_EMULATE_INT_ACK == OPT_ON #if M68K_EMULATE_INT_ACK == OPT_ON
m68k_set_int_ack_callback(NULL); m68k_set_int_ack_callback(NULL);

View File

@ -738,7 +738,11 @@ int emulate_address_error;
static unsigned int end_cycles; static unsigned int end_cycles;
/* Cycles used by CPU instructions */ /* Cycles used by CPU instructions */
#ifdef BUILD_TABLES
static unsigned char m68ki_cycles[0x10000]; static unsigned char m68ki_cycles[0x10000];
#else
#include "m68ki_cycles.h"
#endif
/* Used by shift & rotate instructions */ /* Used by shift & rotate instructions */
static const uint8 m68ki_shift_8_table[65] = 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) INLINE uint m68ki_read_8_fc(uint address, uint fc)
{ {
_m68k_memory_map *temp;
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ 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)); if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
else return READ_BYTE(temp->base, (address) & 0xffff); else return READ_BYTE(temp->base, (address) & 0xffff);
} }
INLINE uint m68ki_read_16_fc(uint address, uint fc) INLINE uint m68ki_read_16_fc(uint address, uint fc)
{ {
_m68k_memory_map *temp;
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_READ, 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)); if (temp->read16) return (*temp->read16)(ADDRESS_68K(address));
else return *(uint16 *)(temp->base + ((address) & 0xffff)); else return *(uint16 *)(temp->base + ((address) & 0xffff));
} }
INLINE uint m68ki_read_32_fc(uint address, uint fc) INLINE uint m68ki_read_32_fc(uint address, uint fc)
{ {
_m68k_memory_map *temp;
m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */ m68ki_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_READ, 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))); if (temp->read16) return ((*temp->read16)(ADDRESS_68K(address)) << 16) | ((*temp->read16)(ADDRESS_68K(address + 2)));
else return m68k_read_immediate_32(address); else return m68k_read_immediate_32(address);
} }
INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) 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) */ 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); if (temp->write8) (*temp->write8)(ADDRESS_68K(address),value);
else WRITE_BYTE(temp->base, (address) & 0xffff, value); else WRITE_BYTE(temp->base, (address) & 0xffff, value);
} }
INLINE void m68ki_write_16_fc(uint address, uint fc, uint 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_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_WRITE, 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); if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value);
else *(uint16 *)(temp->base + ((address) & 0xffff)) = value; else *(uint16 *)(temp->base + ((address) & 0xffff)) = value;
} }
INLINE void m68ki_write_32_fc(uint address, uint fc, uint 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_set_fc(fc) /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error(address, MODE_WRITE, 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); if (temp->write16) (*temp->write16)(ADDRESS_68K(address),value>>16);
else *(uint16 *)(temp->base + ((address) & 0xffff)) = 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 */ /* Service an interrupt request and start exception processing */
INLINE void m68ki_exception_interrupt(uint int_level) INLINE void m68ki_exception_interrupt(uint int_level)
{ {
uint vector, sr, new_pc;
#if M68K_EMULATE_ADDRESS_ERROR == OPT_ON #if M68K_EMULATE_ADDRESS_ERROR == OPT_ON
CPU_INSTR_MODE = INSTRUCTION_NO; CPU_INSTR_MODE = INSTRUCTION_NO;
#endif /* M68K_EMULATE_ADDRESS_ERROR */ #endif /* M68K_EMULATE_ADDRESS_ERROR */
@ -1533,10 +1551,10 @@ INLINE void m68ki_exception_interrupt(uint int_level)
return; return;
/* Always use the autovectors. */ /* Always use the autovectors. */
uint vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level; vector = EXCEPTION_INTERRUPT_AUTOVECTOR+int_level;
/* Start exception processing */ /* Start exception processing */
uint sr = m68ki_init_exception(); sr = m68ki_init_exception();
/* Set the interrupt mask to the level of the one being serviced */ /* Set the interrupt mask to the level of the one being serviced */
FLAG_INT_MASK = int_level<<8; FLAG_INT_MASK = int_level<<8;
@ -1545,7 +1563,7 @@ INLINE void m68ki_exception_interrupt(uint int_level)
m68ki_int_ack(int_level) m68ki_int_ack(int_level)
/* Get the new PC */ /* 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 vector is uninitialized, call the uninitialized interrupt vector */
if(new_pc == 0) if(new_pc == 0)

4099
source/m68k/m68ki_cycles.h Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,8 @@ INLINE void UseDivsCycles(sint32 dst, sint16 src)
if ((abs(dst) >> 16) < abs(src)) if ((abs(dst) >> 16) < abs(src))
{ {
int i;
/* absolute quotient */ /* absolute quotient */
uint32 quotient = abs(dst) / abs(src); uint32 quotient = abs(dst) / abs(src);
@ -68,7 +70,6 @@ INLINE void UseDivsCycles(sint32 dst, sint16 src)
} }
/* check higher 15-bits of quotient */ /* check higher 15-bits of quotient */
int i;
for (i=0; i<15; i++) for (i=0; i<15; i++)
{ {
quotient >>= 1; quotient >>= 1;
@ -19693,7 +19694,7 @@ static void m68k_op_sbcd_8_rr(void)
uint dst = *r_dst; uint dst = *r_dst;
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); 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. */ FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to assume cleared. */
if(res > 9) if(res > 9)
@ -19710,8 +19711,8 @@ static void m68k_op_sbcd_8_rr(void)
res = MASK_OUT_ABOVE_8(res); res = MASK_OUT_ABOVE_8(res);
// FLAG_V &= res; /* Undefined V behavior part II */ /* FLAG_V &= res; */ /* Undefined V behavior part II */
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */ /* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
FLAG_Z |= res; FLAG_Z |= res;
*r_dst = MASK_OUT_BELOW_8(*r_dst) | 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 dst = m68ki_read_8(ea);
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); 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. */ FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
if(res > 9) if(res > 9)
@ -19742,8 +19743,8 @@ static void m68k_op_sbcd_8_mm_ax7(void)
res = MASK_OUT_ABOVE_8(res); res = MASK_OUT_ABOVE_8(res);
// FLAG_V &= res; /* Undefined V behavior part II */ /* FLAG_V &= res; */ /* Undefined V behavior part II */
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */ /* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
FLAG_Z |= res; FLAG_Z |= res;
m68ki_write_8(ea, 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 dst = m68ki_read_8(ea);
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); 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. */ FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
if(res > 9) if(res > 9)
@ -19774,8 +19775,8 @@ static void m68k_op_sbcd_8_mm_ay7(void)
res = MASK_OUT_ABOVE_8(res); res = MASK_OUT_ABOVE_8(res);
// FLAG_V &= res; /* Undefined V behavior part II */ /* FLAG_V &= res; */ /* Undefined V behavior part II */
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */ /* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
FLAG_Z |= res; FLAG_Z |= res;
m68ki_write_8(ea, 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 dst = m68ki_read_8(ea);
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); 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. */ FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
if(res > 9) if(res > 9)
@ -19806,8 +19807,8 @@ static void m68k_op_sbcd_8_mm_axy7(void)
res = MASK_OUT_ABOVE_8(res); res = MASK_OUT_ABOVE_8(res);
// FLAG_V &= res; /* Undefined V behavior part II */ /* FLAG_V &= res; */ /* Undefined V behavior part II */
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */ /* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
FLAG_Z |= res; FLAG_Z |= res;
m68ki_write_8(ea, 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 dst = m68ki_read_8(ea);
uint res = LOW_NIBBLE(dst) - LOW_NIBBLE(src) - XFLAG_AS_1(); 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. */ FLAG_V = VFLAG_CLEAR; /* Undefined in Motorola's M68000PM/AD rev.1 and safer to return zero. */
if(res > 9) if(res > 9)
@ -19838,8 +19839,8 @@ static void m68k_op_sbcd_8_mm(void)
res = MASK_OUT_ABOVE_8(res); res = MASK_OUT_ABOVE_8(res);
// FLAG_V &= res; /* Undefined V behavior part II */ /* FLAG_V &= res; */ /* Undefined V behavior part II */
// FLAG_N = NFLAG_8(res); /* Undefined N behavior */ /* FLAG_N = NFLAG_8(res); */ /* Undefined N behavior */
FLAG_Z |= res; FLAG_Z |= res;
m68ki_write_8(ea, 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) 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 disabled in order to function properly. Some Amiga software may also rely
on this, but only when accessing specific addresses so additional functionality on this, but only when accessing specific addresses so additional functionality
will be needed. */ will be needed. */
uint allow_writeback = m68ki_tas_callback(); if (m68ki_tas_callback()) m68ki_write_8(ea, dst | 0x80);
if (allow_writeback==1) m68ki_write_8(ea, dst | 0x80);
} }
@ -23614,6 +23597,12 @@ static void m68k_op_unlk_32(void)
/* ========================= OPCODE TABLE BUILDER ========================= */ /* ========================= OPCODE TABLE BUILDER ========================= */
/* ======================================================================== */ /* ======================================================================== */
#ifndef BUILD_TABLES
#include "m68ki_instruction_jump_table.h"
#else
/* This is used to generate the opcode handler jump table */ /* This is used to generate the opcode handler jump table */
typedef struct typedef struct
{ {
@ -25347,7 +25336,7 @@ static void m68ki_build_opcode_table(void)
{ {
/* default to illegal */ /* default to illegal */
m68ki_instruction_jump_table[i] = m68k_op_illegal; m68ki_instruction_jump_table[i] = m68k_op_illegal;
m68ki_cycles[i] = 0; m68ki_cycles[i] = 4;
} }
ostruct = &m68k_opcode_handler_table[0]; ostruct = &m68k_opcode_handler_table[0];
@ -25420,6 +25409,7 @@ static void m68ki_build_opcode_table(void)
} }
} }
#endif
/* ======================================================================== */ /* ======================================================================== */
/* ============================== END OF FILE ============================= */ /* ============================== END OF FILE ============================= */