mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-28 04:01:48 +01:00
CPU emulation code cleanup & optimization
This commit is contained in:
parent
64c2278395
commit
7a28d34f4d
@ -180,7 +180,7 @@ _m68k_memory_map m68k_memory_map[256];
|
||||
|
||||
/* Read data immediately following the PC */
|
||||
#define m68k_read_immediate_16(address) *(uint16 *)(m68k_memory_map[((address)>>16)&0xff].base + ((address) & 0xffff))
|
||||
#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2))
|
||||
#define m68k_read_immediate_32(address) (m68k_read_immediate_16(address) << 16) | (m68k_read_immediate_16(address+2))
|
||||
|
||||
/* Read data relative to the PC */
|
||||
#define m68k_read_pcrelative_8(address) READ_BYTE(m68k_memory_map[((address)>>16)&0xff].base, (address) & 0xffff)
|
||||
|
@ -32,21 +32,31 @@ static const char copyright_notice[] =
|
||||
/* ================================ INCLUDES ============================== */
|
||||
/* ======================================================================== */
|
||||
|
||||
extern void m68040_fpu_op0(void);
|
||||
extern void m68040_fpu_op1(void);
|
||||
|
||||
#include "m68kops.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 ================================= */
|
||||
/* ======================================================================== */
|
||||
|
||||
//int m68ki_initial_cycles;
|
||||
//int m68ki_remaining_cycles = 0; /* Number of clocks remaining */
|
||||
#if 0
|
||||
int m68ki_initial_cycles;
|
||||
int m68ki_remaining_cycles = 0; /* Number of clocks remaining */
|
||||
#endif
|
||||
|
||||
#if M68K_EMULATE_TRACE
|
||||
uint m68ki_tracing = 0;
|
||||
#endif /* M68K_EMULATE_TRACE */
|
||||
|
||||
#if M68K_EMULATE_FC
|
||||
uint m68ki_address_space;
|
||||
#endif /* M68K_EMULATE_FC */
|
||||
|
||||
#ifdef M68K_LOG_ENABLE
|
||||
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 */
|
||||
//INLINE int m68k_execute(void)
|
||||
INLINE void m68k_execute(void)
|
||||
INLINE int m68k_execute(void)
|
||||
{
|
||||
/* Set our pool of clock cycles available */
|
||||
//SET_CYCLES(0);
|
||||
SET_CYCLES(0);
|
||||
|
||||
/* Set tracing accodring to T1. (T0 is done inside instruction) */
|
||||
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) */
|
||||
|
||||
/* 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 */
|
||||
/* 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)
|
||||
{
|
||||
unsigned int int_level;
|
||||
|
||||
/* Return point if we had an address error */
|
||||
m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
while (mcycles_68k < cycles)
|
||||
{
|
||||
/* check interrupt updates */
|
||||
/* check IRQ triggering */
|
||||
if (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)
|
||||
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
|
||||
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
|
||||
/* update IRQ level */
|
||||
CPU_INT_LEVEL = int_level << 8;
|
||||
/* update internal interrupt level */
|
||||
m68ki_check_interrupts();
|
||||
|
||||
if (mcycles_68k >= cycles)
|
||||
return;
|
||||
if (mcycles_68k >= cycles) return;
|
||||
}
|
||||
|
||||
/* Make sure we're not stopped */
|
||||
@ -875,11 +886,13 @@ void m68k_run (unsigned int cycles)
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
return m68ki_initial_cycles - GET_CYCLES();
|
||||
@ -889,10 +902,8 @@ int m68k_cycles_remaining(void)
|
||||
{
|
||||
return GET_CYCLES();
|
||||
}
|
||||
*/
|
||||
|
||||
/* Change the timeslice */
|
||||
/*
|
||||
void m68k_modify_timeslice(int cycles)
|
||||
{
|
||||
m68ki_initial_cycles += cycles;
|
||||
@ -904,7 +915,7 @@ void m68k_end_timeslice(void)
|
||||
m68ki_initial_cycles = GET_CYCLES();
|
||||
SET_CYCLES(0);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
void m68k_init(void)
|
||||
{
|
||||
@ -933,8 +944,9 @@ void m68k_pulse_reset(void)
|
||||
{
|
||||
/* Clear all stop levels and eat up all remaining cycles */
|
||||
CPU_STOPPED = 0;
|
||||
//SET_CYCLES(0);
|
||||
|
||||
#if 0
|
||||
SET_CYCLES(0);
|
||||
#endif
|
||||
CPU_RUN_MODE = RUN_MODE_BERR_AERR_RESET;
|
||||
|
||||
/* Turn off tracing */
|
||||
|
@ -917,13 +917,19 @@ typedef struct
|
||||
extern unsigned int mcycles_68k;
|
||||
|
||||
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;
|
||||
#endif
|
||||
extern const uint8 m68ki_shift_8_table[];
|
||||
extern const uint16 m68ki_shift_16_table[];
|
||||
extern const uint m68ki_shift_32_table[];
|
||||
extern uint16 m68ki_exception_cycle_table[][256];
|
||||
#if M68K_EMULATE_FC
|
||||
extern uint m68ki_address_space;
|
||||
#endif
|
||||
extern const uint8 m68ki_ea_idx_cycle_table[];
|
||||
|
||||
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) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
|
||||
if (temp->read8) return (*temp->read8)(ADDRESS_68K(address));
|
||||
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)
|
||||
{
|
||||
m68ki_set_fc(fc); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->write8) (*temp->write8)(ADDRESS_68K(address),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_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *temp = &m68k_memory_map[((address)>>16)&0xff];
|
||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address),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_check_address_error_010_less(address, MODE_WRITE, fc); /* auto-disable (see m68kcpu.h) */
|
||||
|
||||
_m68k_memory_map *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;
|
||||
|
||||
temp = &m68k_memory_map[((address + 2)>>16)&0xff];
|
||||
if (temp->write16) (*temp->write16)(ADDRESS_68K(address+2),value&0xffff);
|
||||
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)
|
||||
{
|
||||
m68ki_push_32(REG_PPC);
|
||||
m68ki_push_32(REG_PC-2);
|
||||
m68ki_push_16(0x2000 | (vector<<2));
|
||||
m68ki_push_32(REG_PC);
|
||||
m68ki_push_16(sr);
|
||||
@ -1875,7 +1884,7 @@ INLINE void m68ki_exception_privilege_violation(void)
|
||||
}
|
||||
#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);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
@ -1888,12 +1897,12 @@ INLINE void m68ki_exception_1010(void)
|
||||
uint sr;
|
||||
#if M68K_LOG_1010_1111 == OPT_ON
|
||||
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_disassemble_quick(ADDRESS_68K(REG_PPC))));
|
||||
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
|
||||
m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
/* 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
|
||||
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_disassemble_quick(ADDRESS_68K(REG_PPC))));
|
||||
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
|
||||
m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
@ -1925,8 +1934,8 @@ INLINE void m68ki_exception_illegal(void)
|
||||
uint sr;
|
||||
|
||||
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_disassemble_quick(ADDRESS_68K(REG_PPC))));
|
||||
m68ki_cpu_names[CPU_TYPE], ADDRESS_68K(REG_PC-2), REG_IR,
|
||||
m68ki_disassemble_quick(ADDRESS_68K(REG_PC-2))));
|
||||
|
||||
sr = m68ki_init_exception();
|
||||
|
||||
@ -1937,7 +1946,7 @@ INLINE void m68ki_exception_illegal(void)
|
||||
}
|
||||
#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);
|
||||
|
||||
/* Use up some clock cycles and undo the instruction's cycles */
|
||||
|
@ -1923,7 +1923,7 @@ void parse_satb(int line)
|
||||
size = q[link + 1] >> 8;
|
||||
height = sizetab[size & 3];
|
||||
|
||||
if ((ypos >= 0) && (ypos < height))
|
||||
if ((ypos >= 0) && (ypos < height))
|
||||
{
|
||||
/* Sprite limit (max. 16 or 20 sprites displayed per line) */
|
||||
if(count == limit)
|
||||
|
@ -80,14 +80,14 @@ extern uint32 mcycles_68k;
|
||||
extern uint8 system_hw;
|
||||
|
||||
/* Function prototypes */
|
||||
extern int audio_init (int samplerate,float framerate);
|
||||
extern void audio_reset (void);
|
||||
extern void audio_shutdown (void);
|
||||
extern int audio_update (void);
|
||||
extern int audio_init(int samplerate,float framerate);
|
||||
extern void audio_reset(void);
|
||||
extern void audio_shutdown(void);
|
||||
extern int audio_update(void);
|
||||
extern void audio_set_equalizer(void);
|
||||
extern void system_init (void);
|
||||
extern void system_reset (void);
|
||||
extern void system_shutdown (void);
|
||||
extern void system_init(void);
|
||||
extern void system_reset(void);
|
||||
extern void system_shutdown(void);
|
||||
extern void system_frame(int do_skip);
|
||||
|
||||
#endif /* _SYSTEM_H_ */
|
||||
|
@ -131,15 +131,11 @@
|
||||
#define LOG(x)
|
||||
#endif
|
||||
|
||||
#define cpu_readop(a) cpu_readmem16(a)
|
||||
#define cpu_readop_arg(a) cpu_readmem16(a)
|
||||
|
||||
/* execute main opcodes inside a big switch statement */
|
||||
#ifndef BIG_SWITCH
|
||||
#define BIG_SWITCH 1
|
||||
#endif
|
||||
|
||||
#define BIG_SWITCH 1
|
||||
|
||||
#define cpu_readop(a) zram[(a) & 0x1fff]
|
||||
#define cpu_readop_arg(a) zram[(a) & 0x1fff]
|
||||
|
||||
#define CF 0x01
|
||||
#define NF 0x02
|
||||
@ -3409,36 +3405,20 @@ void z80_exit(void)
|
||||
****************************************************************************/
|
||||
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 )
|
||||
{
|
||||
/* check for IRQs before each instruction */
|
||||
if (Z80.irq_state != CLEAR_LINE && IFF1 && !Z80.after_ei)
|
||||
take_interrupt();
|
||||
Z80.after_ei = FALSE;
|
||||
|
||||
if (mcycles_z80 < cycles)
|
||||
{
|
||||
R++;
|
||||
EXEC_INLINE(op,ROP());
|
||||
take_interrupt();
|
||||
if (mcycles_z80 >= cycles) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Z80.after_ei = FALSE;
|
||||
R++;
|
||||
EXEC_INLINE(op,ROP());
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Burn 'cycles' T-states. Adjust R register for the lost time
|
||||
@ -3477,19 +3457,29 @@ void z80_set_context (void *src)
|
||||
****************************************************************************/
|
||||
void z80_set_irq_line(int irqline, int state)
|
||||
{
|
||||
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
|
||||
if (irqline != INPUT_LINE_NMI)
|
||||
{
|
||||
/* update the IRQ state via the daisy chain */
|
||||
Z80.irq_state = state;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user