notaz.gp2x.de
/
picodrive.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
bugfixes, famec tuning
[picodrive.git]
/
cpu
/
fame
/
famec.c
diff --git
a/cpu/fame/famec.c
b/cpu/fame/famec.c
index
3dcb8b1
..
11d2cb2
100644
(file)
--- a/
cpu/fame/famec.c
+++ b/
cpu/fame/famec.c
@@
-17,15
+17,14
@@
// Options //
\r
#define FAMEC_ROLL_INLINE
\r
#define FAMEC_EMULATE_TRACE
\r
// Options //
\r
#define FAMEC_ROLL_INLINE
\r
#define FAMEC_EMULATE_TRACE
\r
-#define FAMEC_IRQ_CYCLES
\r
#define FAMEC_CHECK_BRANCHES
\r
#define FAMEC_CHECK_BRANCHES
\r
-// #define FAMEC_USE_DATA_BANKS
\r
-// #define FAMEC_EXTRA_INLINE
\r
+#define FAMEC_EXTRA_INLINE
\r
// #define FAMEC_DEBUG
\r
// #define FAMEC_DEBUG
\r
-#define FAMEC_NO_GOTOS
\r
+
//
#define FAMEC_NO_GOTOS
\r
#define FAMEC_ADR_BITS 24
\r
// #define FAMEC_FETCHBITS 8
\r
#define FAMEC_DATABITS 8
\r
#define FAMEC_ADR_BITS 24
\r
// #define FAMEC_FETCHBITS 8
\r
#define FAMEC_DATABITS 8
\r
+#define FAMEC_32BIT_PC
\r
\r
#define USE_CYCLONE_TIMING
\r
#define USE_CYCLONE_TIMING_DIV
\r
\r
#define USE_CYCLONE_TIMING
\r
#define USE_CYCLONE_TIMING_DIV
\r
@@
-40,6
+39,7
@@
#ifndef FAMEC_EXTRA_INLINE
\r
#define FAMEC_EXTRA_INLINE
\r
#else
\r
#ifndef FAMEC_EXTRA_INLINE
\r
#define FAMEC_EXTRA_INLINE
\r
#else
\r
+#undef FAMEC_EXTRA_INLINE
\r
#define FAMEC_EXTRA_INLINE INLINE
\r
#endif
\r
\r
#define FAMEC_EXTRA_INLINE INLINE
\r
#endif
\r
\r
@@
-83,17
+83,6
@@
typedef unsigned int u32;
typedef signed int s32;
\r
*/
\r
\r
typedef signed int s32;
\r
*/
\r
\r
-#ifdef FAMEC_EMULATE_TRACE
\r
-static u32 flag_T;
\r
-#endif
\r
-static u32 flag_C;
\r
-static u32 flag_V;
\r
-static u32 flag_NotZ;
\r
-static u32 flag_N;
\r
-static u32 flag_X; // 16 bytes aligned
\r
-static u32 flag_S;
\r
-static u32 flag_I;
\r
-
\r
#ifndef M68K_OK
\r
#define M68K_OK 0
\r
#endif
\r
#ifndef M68K_OK
\r
#define M68K_OK 0
\r
#endif
\r
@@
-287,17
+276,29
@@
static u32 flag_I;
#define M68K_PPL (m68kcontext.sr >> 8) & 7
\r
\r
#define GET_PC \
\r
#define M68K_PPL (m68kcontext.sr >> 8) & 7
\r
\r
#define GET_PC \
\r
- (u32)PC - BasePC;
\r
+ ((u32)PC - BasePC)
\r
+
\r
+
\r
+#ifndef FAMEC_32BIT_PC
\r
+
\r
+#define SET_PC(A) \
\r
+{ \
\r
+ u32 pc = A; \
\r
+ BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
\r
+ PC = (u16*)((pc & M68K_ADR_MASK) + BasePC); \
\r
+}
\r
+
\r
+#else
\r
\r
#define SET_PC(A) \
\r
\r
#define SET_PC(A) \
\r
- BasePC = g_m68kcontext->Fetch[((A) >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
\r
- /* BasePC -= (A) & 0xFF000000; */ \
\r
- PC = (u16*)(((A) & M68K_ADR_MASK) + BasePC);
\r
+{ \
\r
+ u32 pc = A; \
\r
+ BasePC = m68kcontext.Fetch[(pc >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
\r
+ BasePC -= pc & 0xFF000000; \
\r
+ PC = (u16*)(pc + BasePC); \
\r
+}
\r
\r
\r
-#define SET_PC_BASE(P,B,A) \
\r
- (B) = g_m68kcontext->Fetch[((A) >> M68K_FETCHSFT) & M68K_FETCHMASK]; \
\r
- /* (B) -= (A) & 0xFF000000; */ \
\r
- (P) = (u16*)(((A) & M68K_ADR_MASK) + (B));
\r
+#endif
\r
\r
\r
#define PRE_IO \
\r
\r
\r
#define PRE_IO \
\r
@@
-465,7
+466,7
@@
static u32 flag_I;
if (interrupt_chk__()) \
\r
{ \
\r
cycles_needed=m68kcontext.io_cycle_counter-(CLK); \
\r
if (interrupt_chk__()) \
\r
{ \
\r
cycles_needed=m68kcontext.io_cycle_counter-(CLK); \
\r
- m68kcontext.io_cycle_counter=
(CLK); \
\r
+ m68kcontext.io_cycle_counter=(CLK); \
\r
}
\r
\r
\r
}
\r
\r
\r
@@
-480,9
+481,10
@@
static u32 flag_I;
#define CHECK_BRANCH_EXCEPTION(_PC_) \
\r
if ((_PC_)&1) \
\r
{ \
\r
#define CHECK_BRANCH_EXCEPTION(_PC_) \
\r
if ((_PC_)&1) \
\r
{ \
\r
- u32 pr_PC=GET_PC; \
\r
+ u32
new_PC,
pr_PC=GET_PC; \
\r
m68kcontext.execinfo |= FM68K_EMULATE_GROUP_0; \
\r
m68kcontext.execinfo |= FM68K_EMULATE_GROUP_0; \
\r
- execute_exception_group_0(M68K_ADDRESS_ERROR_EX, 0, pr_PC, 0x12 ); \
\r
+ new_PC = execute_exception_group_0(M68K_ADDRESS_ERROR_EX, 0, pr_PC, 0x12 ); \
\r
+ SET_PC(new_PC); \
\r
CHECK_BRANCH_EXCEPTION_GOTO_END \
\r
}
\r
#else
\r
CHECK_BRANCH_EXCEPTION_GOTO_END \
\r
}
\r
#else
\r
@@
-492,9
+494,6
@@
static u32 flag_I;
\r
static int init_jump_table(void);
\r
\r
\r
static int init_jump_table(void);
\r
\r
-/* Custom function handler */
\r
-typedef void (*icust_handler_func)(u32 vector);
\r
-
\r
// global variable
\r
///////////////////
\r
\r
// global variable
\r
///////////////////
\r
\r
@@
-502,20
+501,30
@@
typedef void (*icust_handler_func)(u32 vector);
M68K_CONTEXT *g_m68kcontext;
\r
#define m68kcontext (*g_m68kcontext)
\r
\r
M68K_CONTEXT *g_m68kcontext;
\r
#define m68kcontext (*g_m68kcontext)
\r
\r
-/* static s32 io_cycle_counter; */
\r
-static s32 cycles_needed=0;
\r
+#ifdef FAMEC_NO_GOTOS
\r
+static u32 Opcode;
\r
+static s32 cycles_needed;
\r
static u16 *PC;
\r
static u32 BasePC;
\r
static u16 *PC;
\r
static u32 BasePC;
\r
-// static u32 Fetch[M68K_FETCHBANK];
\r
+static u32 flag_V;
\r
+static u32 flag_NotZ;
\r
+static u32 flag_N;
\r
+static u32 flag_X;
\r
+#endif
\r
+
\r
+#ifdef FAMEC_EMULATE_TRACE
\r
+static u32 flag_T;
\r
+#endif
\r
+static u32 flag_S;
\r
+static u32 flag_I;
\r
+
\r
+static u32 initialised = 0;
\r
\r
/* Custom function handler */
\r
typedef void (*opcode_func)(void);
\r
\r
static opcode_func JumpTable[0x10000];
\r
\r
\r
/* Custom function handler */
\r
typedef void (*opcode_func)(void);
\r
\r
static opcode_func JumpTable[0x10000];
\r
\r
-
\r
-static u32 initialised = 0;
\r
-
\r
// exception cycle table (taken from musashi core)
\r
static const s32 exception_cycle_table[256] =
\r
{
\r
// exception cycle table (taken from musashi core)
\r
static const s32 exception_cycle_table[256] =
\r
{
\r
@@
-665,7
+674,11
@@
int fm68k_reset(void)
/****************************************************************************/
\r
u32 fm68k_get_pc(M68K_CONTEXT *context)
\r
{
\r
/****************************************************************************/
\r
u32 fm68k_get_pc(M68K_CONTEXT *context)
\r
{
\r
+#ifdef FAMEC_NO_GOTOS
\r
return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc;
\r
return (context->execinfo & M68K_RUNNING)?(u32)PC-BasePC:context->pc;
\r
+#else
\r
+ return context->pc; // approximate PC in this mode
\r
+#endif
\r
}
\r
\r
\r
}
\r
\r
\r
@@
-684,61
+697,62
@@
int fm68k_would_interrupt(void)
return interrupt_chk__();
\r
}
\r
\r
return interrupt_chk__();
\r
}
\r
\r
-static FAMEC_EXTRA_INLINE
void execute_exception(s32 vect
)
\r
+static FAMEC_EXTRA_INLINE
u32 execute_exception(s32 vect, u32 oldPC, u32 oldSR
)
\r
{
\r
{
\r
- extern u32 flag_S;
\r
-#ifndef FAMEC_IRQ_CYCLES
\r
- if ((vect<24)||(vect>31))
\r
-#endif
\r
+ u32 newPC;
\r
+ //u32 oldSR = GET_SR;
\r
+
\r
m68kcontext.io_cycle_counter -= exception_cycle_table[vect];
\r
m68kcontext.io_cycle_counter -= exception_cycle_table[vect];
\r
- {
\r
- u32 newPC;
\r
- u32 oldPC;
\r
- u32 oldSR = GET_SR;
\r
\r
\r
-
PRE_IO
\r
+ PRE_IO
\r
\r
\r
-
READ_LONG_F(vect * 4, newPC)
\r
+ READ_LONG_F(vect * 4, newPC)
\r
\r
\r
-
/* swap A7 and USP */
\r
-
if (!flag_S)
\r
-
{
\r
-
u32 tmpSP;
\r
+ /* swap A7 and USP */
\r
+ if (!flag_S)
\r
+ {
\r
+ u32 tmpSP;
\r
\r
\r
-
tmpSP = ASP;
\r
-
ASP = AREG(7);
\r
-
AREG(7) = tmpSP;
\r
-
}
\r
+ tmpSP = ASP;
\r
+ ASP = AREG(7);
\r
+ AREG(7) = tmpSP;
\r
+ }
\r
\r
\r
-
oldPC = (u32)(PC) - Base
PC;
\r
-
PUSH_32_F(oldPC)
\r
-
PUSH_16_F(oldSR)
\r
+
//oldPC = GET_
PC;
\r
+ PUSH_32_F(oldPC)
\r
+ PUSH_16_F(oldSR)
\r
\r
\r
-
/* adjust SR */
\r
-
flag_S = M68K_SR_S;
\r
+ /* adjust SR */
\r
+ flag_S = M68K_SR_S;
\r
\r
\r
- newPC&=M68K_ADR_MASK&~1; // don't crash on games with bad vector tables
\r
+#ifndef FAMEC_32BIT_PC
\r
+ newPC&=M68K_ADR_MASK
\r
+#endif
\r
+ newPC&=~1; // don't crash on games with bad vector tables
\r
\r
\r
-
SET_PC(newPC)
\r
+
//
SET_PC(newPC)
\r
\r
\r
- POST_IO
\r
- }
\r
+ POST_IO
\r
+
\r
+ return newPC;
\r
}
\r
\r
}
\r
\r
-static FAMEC_EXTRA_INLINE
void execute_exception_group_0(s32 vect, u16 inst_reg, s32 addr, u16 spec_info
)
\r
+static FAMEC_EXTRA_INLINE
u32 execute_exception_group_0(s32 vect, s32 addr, u16 spec_info, u32 oldSR
)
\r
{
\r
{
\r
- execute_exception(vect);
\r
+ u32 newPC;
\r
+ u16 inst_reg = 0;
\r
+ newPC = execute_exception(vect, addr, oldSR);
\r
//if (!(m68kcontext.icust_handler && m68kcontext.icust_handler[vect]))
\r
{
\r
PUSH_16_F(inst_reg);
\r
PUSH_32_F(addr);
\r
PUSH_16_F(spec_info);
\r
}
\r
//if (!(m68kcontext.icust_handler && m68kcontext.icust_handler[vect]))
\r
{
\r
PUSH_16_F(inst_reg);
\r
PUSH_32_F(addr);
\r
PUSH_16_F(spec_info);
\r
}
\r
+ return newPC;
\r
}
\r
\r
\r
static void setup_jumptable(void);
\r
}
\r
\r
\r
static void setup_jumptable(void);
\r
-static u32 Opcode;
\r
\r
#ifdef FAMEC_NO_GOTOS
\r
\r
\r
#ifdef FAMEC_NO_GOTOS
\r
\r
@@
-753,6
+767,18
@@
static u32 Opcode;
\r
int fm68k_emulate(s32 cycles)
\r
{
\r
\r
int fm68k_emulate(s32 cycles)
\r
{
\r
+#ifndef FAMEC_NO_GOTOS
\r
+ u32 Opcode;
\r
+ s32 cycles_needed;
\r
+ u16 *PC;
\r
+ u32 BasePC;
\r
+ u32 flag_C;
\r
+ u32 flag_V;
\r
+ u32 flag_NotZ;
\r
+ u32 flag_N;
\r
+ u32 flag_X;
\r
+#endif
\r
+
\r
if (!initialised)
\r
{
\r
#ifdef FAMEC_NO_GOTOS
\r
if (!initialised)
\r
{
\r
#ifdef FAMEC_NO_GOTOS
\r
@@
-813,7
+839,7
@@
int fm68k_emulate(s32 cycles)
else
\r
m68kcontext.interrupts[0] = 0;
\r
\r
else
\r
m68kcontext.interrupts[0] = 0;
\r
\r
-
execute_exception(line + 0x18
);
\r
+
SET_PC(execute_exception(line + 0x18, GET_PC, GET_SR)
);
\r
flag_I = (u32)line;
\r
if (m68kcontext.io_cycle_counter <= 0) goto famec_End;
\r
}
\r
flag_I = (u32)line;
\r
if (m68kcontext.io_cycle_counter <= 0) goto famec_End;
\r
}
\r
@@
-822,7
+848,7
@@
int fm68k_emulate(s32 cycles)
if (flag_T)
\r
{
\r
m68kcontext.execinfo |= FM68K_EMULATE_TRACE;
\r
if (flag_T)
\r
{
\r
m68kcontext.execinfo |= FM68K_EMULATE_TRACE;
\r
- cycles_needed= m68kcontext.io_cycle_counter;
\r
+ cycles_needed
= m68kcontext.io_cycle_counter;
\r
m68kcontext.io_cycle_counter=0;
\r
}
\r
#endif
\r
m68kcontext.io_cycle_counter=0;
\r
}
\r
#endif
\r
@@
-851,22
+877,25
@@
famec_Exec:
#ifdef FAMEC_EMULATE_TRACE
\r
if (m68kcontext.execinfo & FM68K_EMULATE_TRACE)
\r
{
\r
#ifdef FAMEC_EMULATE_TRACE
\r
if (m68kcontext.execinfo & FM68K_EMULATE_TRACE)
\r
{
\r
- m68kcontext.io_cycle_counter= cycles_needed;
\r
+ m68kcontext.io_cycle_counter = cycles_needed;
\r
+ cycles_needed = 0;
\r
m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE;
\r
m68kcontext.execinfo |= FM68K_DO_TRACE;
\r
m68kcontext.execinfo &= ~FM68K_EMULATE_TRACE;
\r
m68kcontext.execinfo |= FM68K_DO_TRACE;
\r
-
execute_exception(M68K_TRACE_EX
);
\r
+
SET_PC(execute_exception(M68K_TRACE_EX, GET_PC, GET_SR)
);
\r
flag_T=0;
\r
if (m68kcontext.io_cycle_counter > 0)
\r
{
\r
flag_T=0;
\r
if (m68kcontext.io_cycle_counter > 0)
\r
{
\r
- NEXT
\r
+ //NEXT
\r
+ goto famec_Exec;
\r
}
\r
}
\r
else
\r
#endif
\r
if (cycles_needed != 0)
\r
{
\r
}
\r
}
\r
else
\r
#endif
\r
if (cycles_needed != 0)
\r
{
\r
+ m68kcontext.io_cycle_counter = cycles_needed;
\r
+ cycles_needed = 0;
\r
s32 line=interrupt_chk__();
\r
s32 line=interrupt_chk__();
\r
- m68kcontext.io_cycle_counter= cycles_needed;
\r
if (line>0)
\r
{
\r
if (m68kcontext.iack_handler != NULL)
\r
if (line>0)
\r
{
\r
if (m68kcontext.iack_handler != NULL)
\r
@@
-874,11
+903,11
@@
famec_Exec:
else
\r
m68kcontext.interrupts[0] = 0;
\r
\r
else
\r
m68kcontext.interrupts[0] = 0;
\r
\r
-
execute_exception(line + 0x18
);
\r
+
SET_PC(execute_exception(line + 0x18, GET_PC, GET_SR)
);
\r
flag_I = (u32)line;
\r
}
\r
#ifdef FAMEC_EMULATE_TRACE
\r
flag_I = (u32)line;
\r
}
\r
#ifdef FAMEC_EMULATE_TRACE
\r
-
else
if (!(flag_T))
\r
+ if (!(flag_T))
\r
#endif
\r
if (m68kcontext.io_cycle_counter > 0)
\r
{
\r
#endif
\r
if (m68kcontext.io_cycle_counter > 0)
\r
{
\r