CPU emulation code cleanup & optimization

This commit is contained in:
ekeeke31 2010-07-16 08:29:05 +00:00
parent 64c2278395
commit 7a28d34f4d
6 changed files with 100 additions and 89 deletions

View File

@ -32,21 +32,31 @@ static const char copyright_notice[] =
/* ================================ INCLUDES ============================== */ /* ================================ INCLUDES ============================== */
/* ======================================================================== */ /* ======================================================================== */
extern void m68040_fpu_op0(void);
extern void m68040_fpu_op1(void);
#include "m68kops.h" #include "m68kops.h"
#include "m68kcpu.h" #include "m68kcpu.h"
//#include "m68kfpu.c"
#if M68K_EMULATE_040
#include "m68kfpu.c"
extern void m68040_fpu_op0(void);
extern void m68040_fpu_op1(void);
#endif /* M68K_EMULATE_040 */
/* ======================================================================== */ /* ======================================================================== */
/* ================================= DATA ================================= */ /* ================================= DATA ================================= */
/* ======================================================================== */ /* ======================================================================== */
//int m68ki_initial_cycles; #if 0
//int m68ki_remaining_cycles = 0; /* Number of clocks remaining */ int m68ki_initial_cycles;
int m68ki_remaining_cycles = 0; /* Number of clocks remaining */
#endif
#if M68K_EMULATE_TRACE
uint m68ki_tracing = 0; uint m68ki_tracing = 0;
#endif /* M68K_EMULATE_TRACE */
#if M68K_EMULATE_FC
uint m68ki_address_space; uint m68ki_address_space;
#endif /* M68K_EMULATE_FC */
#ifdef M68K_LOG_ENABLE #ifdef M68K_LOG_ENABLE
const char *const m68ki_cpu_names[] = const char *const m68ki_cpu_names[] =
@ -783,12 +793,12 @@ void m68k_set_cpu_type(unsigned int cpu_type)
} }
} }
#if 0
/* Execute a single instruction */ /* Execute a single instruction */
//INLINE int m68k_execute(void) INLINE int m68k_execute(void)
INLINE void m68k_execute(void)
{ {
/* Set our pool of clock cycles available */ /* Set our pool of clock cycles available */
//SET_CYCLES(0); SET_CYCLES(0);
/* Set tracing accodring to T1. (T0 is done inside instruction) */ /* Set tracing accodring to T1. (T0 is done inside instruction) */
m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */ m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */
@ -811,8 +821,9 @@ INLINE void m68k_execute(void)
m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */ m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
/* return how many clocks we used */ /* return how many clocks we used */
//return - GET_CYCLES(); return GET_CYCLES();
} }
#endif
/* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */ /* ASG: rewrote so that the int_level is a mask of the IPL0/IPL1/IPL2 bits */
/* KS: Modified so that IPL* bits match with mask positions in the SR /* KS: Modified so that IPL* bits match with mask positions in the SR
@ -839,32 +850,32 @@ extern uint8 irq_status;
void m68k_run (unsigned int cycles) void m68k_run (unsigned int cycles)
{ {
unsigned int int_level;
/* Return point if we had an address error */ /* Return point if we had an address error */
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */ m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
while (mcycles_68k < cycles) while (mcycles_68k < cycles)
{ {
/* check interrupt updates */ /* check IRQ triggering */
if (irq_status & 0x10) if (irq_status & 0x10)
{ {
irq_status &= ~0x10; irq_status &= ~0x10;
int_level = irq_status & 6; CPU_INT_LEVEL = (irq_status & 6) << 8;
/* hardware latency */ /* IRQ was triggered during previous instruction */
if (irq_status & 0x40) if (irq_status & 0x40)
m68k_execute(); {
/* one instruction latency */
REG_IR = m68ki_read_imm_16();
m68ki_instruction_jump_table[REG_IR]();
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
}
#ifdef LOGVDP #ifdef LOGVDP
error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, mcycles_68k/3420, mcycles_68k, mcycles_68k%3420,int_level,FLAG_INT_MASK,m68k_get_reg (NULL, M68K_REG_PC)); error("[%d(%d)][%d(%d)] IRQ Level = %d(0x%02x) (%x)\n", v_counter, mcycles_68k/3420, mcycles_68k, mcycles_68k%3420,int_level,FLAG_INT_MASK,m68k_get_reg (NULL, M68K_REG_PC));
#endif #endif
/* update IRQ level */ /* update internal interrupt level */
CPU_INT_LEVEL = int_level << 8;
m68ki_check_interrupts(); m68ki_check_interrupts();
if (mcycles_68k >= cycles) if (mcycles_68k >= cycles) return;
return;
} }
/* Make sure we're not stopped */ /* Make sure we're not stopped */
@ -875,11 +886,13 @@ void m68k_run (unsigned int cycles)
} }
/* execute a single instruction */ /* execute a single instruction */
m68k_execute(); REG_IR = m68ki_read_imm_16();
m68ki_instruction_jump_table[REG_IR]();
USE_CYCLES(CYC_INSTRUCTION[REG_IR]);
} }
} }
/* #if 0
int m68k_cycles_run(void) int m68k_cycles_run(void)
{ {
return m68ki_initial_cycles - GET_CYCLES(); return m68ki_initial_cycles - GET_CYCLES();
@ -889,10 +902,8 @@ int m68k_cycles_remaining(void)
{ {
return GET_CYCLES(); return GET_CYCLES();
} }
*/
/* Change the timeslice */ /* Change the timeslice */
/*
void m68k_modify_timeslice(int cycles) void m68k_modify_timeslice(int cycles)
{ {
m68ki_initial_cycles += cycles; m68ki_initial_cycles += cycles;
@ -904,7 +915,7 @@ void m68k_end_timeslice(void)
m68ki_initial_cycles = GET_CYCLES(); m68ki_initial_cycles = GET_CYCLES();
SET_CYCLES(0); SET_CYCLES(0);
} }
*/ #endif
void m68k_init(void) void m68k_init(void)
{ {
@ -933,8 +944,9 @@ void m68k_pulse_reset(void)
{ {
/* Clear all stop levels and eat up all remaining cycles */ /* Clear all stop levels and eat up all remaining cycles */
CPU_STOPPED = 0; CPU_STOPPED = 0;
//SET_CYCLES(0); #if 0
SET_CYCLES(0);
#endif
CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET; CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
/* Turn off tracing */ /* Turn off tracing */

View File

@ -917,13 +917,19 @@ typedef struct
extern unsigned int mcycles_68k; extern unsigned int mcycles_68k;
extern m68ki_cpu_core m68ki_cpu; extern m68ki_cpu_core m68ki_cpu;
//extern sint m68ki_remaining_cycles; #if 0
extern sint m68ki_remaining_cycles;
#endif
#if M68K_EMULATE_TRACE
extern uint m68ki_tracing; extern uint m68ki_tracing;
#endif
extern const uint8 m68ki_shift_8_table[]; extern const uint8 m68ki_shift_8_table[];
extern const uint16 m68ki_shift_16_table[]; extern const uint16 m68ki_shift_16_table[];
extern const uint m68ki_shift_32_table[]; extern const uint m68ki_shift_32_table[];
extern uint16 m68ki_exception_cycle_table[][256]; extern uint16 m68ki_exception_cycle_table[][256];
#if M68K_EMULATE_FC
extern uint m68ki_address_space; extern uint m68ki_address_space;
#endif
extern const uint8 m68ki_ea_idx_cycle_table[]; extern const uint8 m68ki_ea_idx_cycle_table[];
extern uint m68ki_aerr_address; extern uint m68ki_aerr_address;
@ -1124,7 +1130,6 @@ INLINE uint m68ki_read_8_fc(uint address, uint fc)
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]; _m68k_memory_map *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);
} }
@ -1152,6 +1157,7 @@ INLINE uint m68ki_read_32_fc(uint address, uint fc)
INLINE void m68ki_write_8_fc(uint address, uint fc, uint value) INLINE void m68ki_write_8_fc(uint address, uint fc, uint value)
{ {
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]; _m68k_memory_map *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);
@ -1161,6 +1167,7 @@ INLINE void m68ki_write_16_fc(uint address, uint fc, uint value)
{ {
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff]; _m68k_memory_map *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;
@ -1170,9 +1177,11 @@ INLINE void m68ki_write_32_fc(uint address, uint fc, uint value)
{ {
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */ m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */ m68ki_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff]; _m68k_memory_map *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;
temp = &m68k_memory_map[((address + 2)>>16)&0xff]; temp = &m68k_memory_map[((address + 2)>>16)&0xff];
if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff); if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff);
else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value; else *(uint16 *)(temp->base + ((address + 2) & 0xffff)) = value;
@ -1612,7 +1621,7 @@ INLINE void m68ki_stack_frame_0001(uint pc, uint sr, uint vector)
*/ */
INLINE void m68ki_stack_frame_0010(uint sr, uint vector) INLINE void m68ki_stack_frame_0010(uint sr, uint vector)
{ {
m68ki_push_32(REG_PPC); m68ki_push_32(REG_PC-2);
m68ki_push_16(0x2000 | (vector<<2)); m68ki_push_16(0x2000 | (vector<<2));
m68ki_push_32(REG_PC); m68ki_push_32(REG_PC);
m68ki_push_16(sr); m68ki_push_16(sr);
@ -1875,7 +1884,7 @@ INLINE void m68ki_exception_privilege_violation(void)
} }
#endif /* M68K_EMULATE_ADDRESS_ERROR */ #endif /* M68K_EMULATE_ADDRESS_ERROR */
m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_PRIVILEGE_VIOLATION); m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_PRIVILEGE_VIOLATION);
m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION); m68ki_jump_vector(EXCEPTION_PRIVILEGE_VIOLATION);
/* Use up some clock cycles and undo the instruction's cycles */ /* Use up some clock cycles and undo the instruction's cycles */
@ -1888,12 +1897,12 @@ INLINE void m68ki_exception_1010(void)
uint sr; uint sr;
#if M68K_LOG_1010_1111 == OPT_ON #if M68K_LOG_1010_1111 == OPT_ON
M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n", M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1010 instruction %04x (%s)\n",
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
#endif #endif
sr = m68ki_init_exception(); sr = m68ki_init_exception();
m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1010); m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1010);
m68ki_jump_vector(EXCEPTION_1010); m68ki_jump_vector(EXCEPTION_1010);
/* Use up some clock cycles and undo the instruction's cycles */ /* Use up some clock cycles and undo the instruction's cycles */
@ -1907,12 +1916,12 @@ INLINE void m68ki_exception_1111(void)
#if M68K_LOG_1010_1111 == OPT_ON #if M68K_LOG_1010_1111 == OPT_ON
M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n", M68K_DO_LOG_EMU((M68K_LOG_FILEHANDLE "%s at %08x: called 1111 instruction %04x (%s)\n",
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
#endif #endif
sr = m68ki_init_exception(); sr = m68ki_init_exception();
m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_1111); m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_1111);
m68ki_jump_vector(EXCEPTION_1111); m68ki_jump_vector(EXCEPTION_1111);
/* Use up some clock cycles and undo the instruction's cycles */ /* Use up some clock cycles and undo the instruction's cycles */
@ -1925,8 +1934,8 @@ INLINE void m68ki_exception_illegal(void)
uint sr; uint sr;
M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n", M68K_DO_LOG((M68K_LOG_FILEHANDLE "%s at %08x: illegal instruction %04x (%s)\n",
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PPC), REG_IR, m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
m68ki_disassemble_quick(ADDRESS_68K(REG_PPC)))); m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
sr = m68ki_init_exception(); sr = m68ki_init_exception();
@ -1937,7 +1946,7 @@ INLINE void m68ki_exception_illegal(void)
} }
#endif /* M68K_EMULATE_ADDRESS_ERROR */ #endif /* M68K_EMULATE_ADDRESS_ERROR */
m68ki_stack_frame_0000(REG_PPC, sr, EXCEPTION_ILLEGAL_INSTRUCTION); m68ki_stack_frame_0000(REG_PC-2, sr, EXCEPTION_ILLEGAL_INSTRUCTION);
m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION); m68ki_jump_vector(EXCEPTION_ILLEGAL_INSTRUCTION);
/* Use up some clock cycles and undo the instruction's cycles */ /* Use up some clock cycles and undo the instruction's cycles */

View File

@ -80,14 +80,14 @@ extern uint32 mcycles_68k;
extern uint8 system_hw; extern uint8 system_hw;
/* Function prototypes */ /* Function prototypes */
extern int audio_init (int samplerate,float framerate); extern int audio_init(int samplerate,float framerate);
extern void audio_reset (void); extern void audio_reset(void);
extern void audio_shutdown (void); extern void audio_shutdown(void);
extern int audio_update (void); extern int audio_update(void);
extern void audio_set_equalizer(void); extern void audio_set_equalizer(void);
extern void system_init (void); extern void system_init(void);
extern void system_reset (void); extern void system_reset(void);
extern void system_shutdown (void); extern void system_shutdown(void);
extern void system_frame(int do_skip); extern void system_frame(int do_skip);
#endif /* _SYSTEM_H_ */ #endif /* _SYSTEM_H_ */

View File

@ -131,15 +131,11 @@
#define LOG(x) #define LOG(x)
#endif #endif
#define cpu_readop(a) cpu_readmem16(a)
#define cpu_readop_arg(a) cpu_readmem16(a)
/* execute main opcodes inside a big switch statement */ /* execute main opcodes inside a big switch statement */
#ifndef BIG_SWITCH
#define BIG_SWITCH 1 #define BIG_SWITCH 1
#endif
#define cpu_readop(a) zram[(a) & 0x1fff]
#define cpu_readop_arg(a) zram[(a) & 0x1fff]
#define CF 0x01 #define CF 0x01
#define NF 0x02 #define NF 0x02
@ -3409,35 +3405,19 @@ void z80_exit(void)
****************************************************************************/ ****************************************************************************/
void z80_run(unsigned int cycles) void z80_run(unsigned int cycles)
{ {
/* check for NMIs on the way in; they can only be set externally */
/* via timers, and can't be dynamically enabled, so it is safe */
/* to just check here */
if (Z80.nmi_pending)
{
LOG(("Z80 #%d take NMI\n", cpu_getactivecpu()));
LEAVE_HALT; /* Check if processor was halted */
IFF1 = 0;
PUSH( pc );
PCD = 0x0066;
WZ=PCD;
mcycles_z80 += 11*15;
Z80.nmi_pending = FALSE;
}
while( mcycles_z80 < cycles ) while( mcycles_z80 < cycles )
{ {
/* check for IRQs before each instruction */ /* check for IRQs before each instruction */
if (Z80.irq_state != CLEAR_LINE && IFF1 && !Z80.after_ei) if (Z80.irq_state != CLEAR_LINE && IFF1 && !Z80.after_ei)
take_interrupt();
Z80.after_ei = FALSE;
if (mcycles_z80 < cycles)
{ {
take_interrupt();
if (mcycles_z80 >= cycles) return;
}
Z80.after_ei = FALSE;
R++; R++;
EXEC_INLINE(op,ROP()); EXEC_INLINE(op,ROP());
} }
}
} }
/**************************************************************************** /****************************************************************************
@ -3477,19 +3457,29 @@ void z80_set_context (void *src)
****************************************************************************/ ****************************************************************************/
void z80_set_irq_line(int irqline, int state) void z80_set_irq_line(int irqline, int state)
{ {
if (irqline == INPUT_LINE_NMI) if (irqline != INPUT_LINE_NMI)
{
/* mark an NMI pending on the rising edge */
if (Z80.nmi_state == CLEAR_LINE && state != CLEAR_LINE)
Z80.nmi_pending = TRUE;
Z80.nmi_state = state;
}
else
{ {
/* update the IRQ state via the daisy chain */ /* update the IRQ state via the daisy chain */
Z80.irq_state = state; Z80.irq_state = state;
/* the main execute loop will take the interrupt */ /* the main execute loop will take the interrupt */
} }
else
{
/* mark an NMI pending on the rising edge */
if (Z80.nmi_state == CLEAR_LINE && state != CLEAR_LINE)
{
LOG(("Z80 #%d take NMI\n", cpu_getactivecpu()));
LEAVE_HALT; /* Check if processor was halted */
IFF1 = 0;
PUSH( pc );
PCD = 0x0066;
WZ=PCD;
mcycles_z80 += 11*15;
}
Z80.nmi_state = state;
}
} }