\r
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\r
M68KMAKE_OPCODE_HANDLER_HEADER\r
+#include <stdlib.h>\r
\r
#include "m68kcpu.h"\r
extern void m68040_fpu_op0(void);\r
extern void m68040_fpu_op1(void);\r
\r
+/* Count non-0 bits */\r
+INLINE int m68ki_bit_count(uint32 arg)\r
+{\r
+ arg = arg - ((arg>>1)&0x55555555);\r
+ arg = (arg&0x33333333) + ((arg>>2)&0x33333333);\r
+ return (((arg + (arg>>4))&0x0f0f0f0f) * 0x01010101) >> 24;\r
+}\r
+\r
+INLINE int m68ki_mulu_cycles(uint32 arg)\r
+{\r
+ if (CPU_TYPE_IS_000(CPU_TYPE))\r
+ return m68ki_bit_count(arg) * 2;\r
+ else if (CPU_TYPE_IS_010(CPU_TYPE))\r
+ return m68ki_bit_count(arg); /* guesswork */\r
+ else\r
+ return m68ki_bit_count(arg) / 2; /* guesswork */\r
+}\r
+\r
+INLINE int m68ki_muls_cycles(sint32 arg)\r
+{\r
+ if (CPU_TYPE_IS_000(CPU_TYPE))\r
+ return m68ki_bit_count(arg ^ (arg<<1)) * 2;\r
+ else if (CPU_TYPE_IS_010(CPU_TYPE))\r
+ return m68ki_bit_count(arg ^ (arg<<1)); /* guesswork */\r
+ else\r
+ return m68ki_bit_count(arg ^ (arg<<1)) / 2; /* guesswork */\r
+}\r
+\r
+INLINE int m68ki_divu_cycles(uint32 arg)\r
+{\r
+ /* approximation only. Doesn't factor in shorter cycles by carry */\r
+ if (CPU_TYPE_IS_000(CPU_TYPE))\r
+ return 128 - m68ki_bit_count(arg) * 2;\r
+ else if (CPU_TYPE_IS_010(CPU_TYPE))\r
+ return 96; /* guesswork */\r
+ else\r
+ return 32; /* guesswork */\r
+}\r
+\r
+INLINE int m68ki_divs_cycles(uint32 scyc, sint32 arg)\r
+{\r
+ /* approximation only. Doesn't factor in shorter cycles by carry */\r
+ if (CPU_TYPE_IS_000(CPU_TYPE))\r
+ return 128 - m68ki_bit_count(abs(arg)) * 2 + scyc*2 + 8;\r
+ else if (CPU_TYPE_IS_010(CPU_TYPE))\r
+ return 96 + scyc*2 + 8; /* guesswork */\r
+ else\r
+ return 32 + scyc + 4; /* guesswork */\r
+}\r
+\r
/* ======================================================================== */\r
/* ========================= INSTRUCTION HANDLERS ========================= */\r
/* ======================================================================== */\r
andi 8 . . 0000001000...... A+-DXWL... U U U U 12 12 4 4\r
andi 16 . d 0000001001000... .......... U U U U 8 8 2 2\r
andi 16 . . 0000001001...... A+-DXWL... U U U U 12 12 4 4\r
-andi 32 . d 0000001010000... .......... U U U U 14 14 2 2\r
+andi 32 . d 0000001010000... .......... U U U U 16 14 2 2\r
andi 32 . . 0000001010...... A+-DXWL... U U U U 20 20 4 4\r
asr 8 s . 1110...000000... .......... U U U U 6 6 6 6\r
asr 16 s . 1110...001000... .......... U U U U 6 6 6 6\r
bcc 16 . . 0110....00000000 .......... U U U U 10 10 6 6\r
bcc 32 . . 0110....11111111 .......... U U U U 10 10 6 6\r
bchg 8 r . 0000...101...... A+-DXWL... U U U U 8 8 4 4\r
-bchg 32 r d 0000...101000... .......... U U U U 8 8 4 4\r
+bchg 32 r d 0000...101000... .......... U U U U 6 6 4 4\r
bchg 8 s . 0000100001...... A+-DXWL... U U U U 12 12 4 4\r
-bchg 32 s d 0000100001000... .......... U U U U 12 12 4 4\r
-bclr 8 r . 0000...110...... A+-DXWL... U U U U 8 10 4 4\r
-bclr 32 r d 0000...110000... .......... U U U U 10 10 4 4\r
+bchg 32 s d 0000100001000... .......... U U U U 10 10 4 4\r
+bclr 8 r . 0000...110...... A+-DXWL... U U U U 8 8 4 4\r
+bclr 32 r d 0000...110000... .......... U U U U 8 8 4 4\r
bclr 8 s . 0000100010...... A+-DXWL... U U U U 12 12 4 4\r
-bclr 32 s d 0000100010000... .......... U U U U 14 14 4 4\r
+bclr 32 s d 0000100010000... .......... U U U U 12 12 4 4\r
bfchg 32 . d 1110101011000... .......... . . U U . . 12 12 timing not quite correct\r
bfchg 32 . . 1110101011...... A..DXWL... . . U U . . 20 20\r
bfclr 32 . d 1110110011000... .......... . . U U . . 12 12\r
bra 8 . . 01100000........ .......... U U U U 10 10 10 10\r
bra 16 . . 0110000000000000 .......... U U U U 10 10 10 10\r
bra 32 . . 0110000011111111 .......... U U U U 10 10 10 10\r
-bset 32 r d 0000...111000... .......... U U U U 8 8 4 4\r
+bset 32 r d 0000...111000... .......... U U U U 6 6 4 4\r
bset 8 r . 0000...111...... A+-DXWL... U U U U 8 8 4 4\r
bset 8 s . 0000100011...... A+-DXWL... U U U U 12 12 4 4\r
-bset 32 s d 0000100011000... .......... U U U U 12 12 4 4\r
+bset 32 s d 0000100011000... .......... U U U U 10 10 4 4\r
bsr 8 . . 01100001........ .......... U U U U 18 18 7 7\r
bsr 16 . . 0110000100000000 .......... U U U U 18 18 7 7\r
bsr 32 . . 0110000111111111 .......... U U U U 18 18 7 7\r
cas 32 . . 0000111011...... A+-DXWL... . . U U . . 12 12\r
cas2 16 . . 0000110011111100 .......... . . U U . . 12 12\r
cas2 32 . . 0000111011111100 .......... . . U U . . 12 12\r
-chk 16 . d 0100...110000... .......... U U U U 10 8 8 8\r
-chk 16 . . 0100...110...... A+-DXWLdxI U U U U 10 8 8 8\r
+chk 16 . d 0100...110000... .......... U U U U 4 2 2 2\r
+chk 16 . . 0100...110...... A+-DXWLdxI U U U U 4 2 2 2\r
chk 32 . d 0100...100000... .......... . . U U . . 8 8\r
chk 32 . . 0100...100...... A+-DXWLdxI . . U U . . 8 8\r
chk2cmp2 8 . pcdi 0000000011111010 .......... . . U U . . 23 23\r
dbt 16 . . 0101000011001... .......... U U U U 12 12 6 6\r
dbf 16 . . 0101000111001... .......... U U U U 12 12 6 6\r
dbcc 16 . . 0101....11001... .......... U U U U 12 12 6 6\r
-divs 16 . d 1000...111000... .......... U U U U 158 122 56 56\r
-divs 16 . . 1000...111...... A+-DXWLdxI U U U U 158 122 56 56\r
-divu 16 . d 1000...011000... .......... U U U U 140 108 44 44\r
-divu 16 . . 1000...011...... A+-DXWLdxI U U U U 140 108 44 44\r
+divs 16 . d 1000...111000... .......... U U U U 16 16 16 16 cycles depending on operands\r
+divs 16 . . 1000...111...... A+-DXWLdxI U U U U 16 16 16 16 cycles depending on operands\r
+divu 16 . d 1000...011000... .......... U U U U 10 10 10 10 cycles depending on operands\r
+divu 16 . . 1000...011...... A+-DXWLdxI U U U U 10 10 10 10 cycles depending on operands\r
divl 32 . d 0100110001000... .......... . . U U . . 84 84\r
divl 32 . . 0100110001...... A+-DXWLdxI . . U U . . 84 84\r
eor 8 . d 1011...100000... .......... U U U U 4 4 2 2\r
moves 16 . . 0000111001...... A+-DXWL... . S S S . 14 5 5\r
moves 32 . . 0000111010...... A+-DXWL... . S S S . 16 5 5\r
move16 32 . . 1111011000100... .......... . . . U . . . 4 TODO: correct timing\r
-muls 16 . d 1100...111000... .......... U U U U 54 32 27 27\r
-muls 16 . . 1100...111...... A+-DXWLdxI U U U U 54 32 27 27\r
-mulu 16 . d 1100...011000... .......... U U U U 54 30 27 27\r
-mulu 16 . . 1100...011...... A+-DXWLdxI U U U U 54 30 27 27\r
+muls 16 . d 1100...111000... .......... U U U U 38 28 20 20 cycles depending on operands\r
+muls 16 . . 1100...111...... A+-DXWLdxI U U U U 38 28 20 20 cycles depending on operands\r
+mulu 16 . d 1100...011000... .......... U U U U 38 26 20 20 cycles depending on operands\r
+mulu 16 . . 1100...011...... A+-DXWLdxI U U U U 38 26 20 20 cycles depending on operands\r
mull 32 . d 0100110000000... .......... . . U U . . 43 43\r
mull 32 . . 0100110000...... A+-DXWLdxI . . U U . . 43 43\r
nbcd 8 . d 0100100000000... .......... U U U U 6 6 6 6\r
subx 32 mm . 1001...110001... .......... U U U U 30 30 12 12\r
swap 32 . . 0100100001000... .......... U U U U 4 4 4 4\r
tas 8 . d 0100101011000... .......... U U U U 4 4 4 4\r
-tas 8 . . 0100101011...... A+-DXWL... U U U U 14 14 12 12\r
+tas 8 . . 0100101011...... A+-DXWL... U U U U 10 10 8 8\r
trap 0 . . 010011100100.... .......... U U U U 4 4 4 4\r
trapt 0 . . 0101000011111100 .......... . . U U . . 4 4\r
trapt 16 . . 0101000011111010 .......... . . U U . . 6 6\r
uint* r_dst = &DY;\r
uint mask = 1 << (DX & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst ^= mask;\r
}\r
uint* r_dst = &DY;\r
uint mask = 1 << (OPER_I_8() & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst ^= mask;\r
}\r
uint* r_dst = &DY;\r
uint mask = 1 << (DX & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst &= ~mask;\r
}\r
uint* r_dst = &DY;\r
uint mask = 1 << (OPER_I_8() & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst &= ~mask;\r
}\r
uint* r_dst = &DY;\r
uint mask = 1 << (DX & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst |= mask;\r
}\r
uint* r_dst = &DY;\r
uint mask = 1 << (OPER_I_8() & 0x1f);\r
\r
+ if(CPU_TYPE_IS_010_LESS(CPU_TYPE) && mask >= 0x10000)\r
+ USE_CYCLES(2);\r
FLAG_Z = *r_dst & mask;\r
*r_dst |= mask;\r
}\r
\r
if(src >= 0 && src <= bound)\r
{\r
+ USE_CYCLES(6);\r
return;\r
}\r
FLAG_N = (src < 0)<<7;\r
\r
if(src >= 0 && src <= bound)\r
{\r
+ USE_CYCLES(6);\r
return;\r
}\r
FLAG_N = (src < 0)<<7;\r
{\r
uint* r_dst = &DX;\r
sint src = MAKE_INT_16(DY);\r
+ sint dst = MAKE_INT_32(*r_dst);\r
sint quotient;\r
sint remainder;\r
+ int cycles;\r
\r
if(src != 0)\r
{\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = 0;\r
+ USE_CYCLES(m68ki_divs_cycles(2, 0));\r
return;\r
}\r
\r
- quotient = MAKE_INT_32(*r_dst) / src;\r
- remainder = MAKE_INT_32(*r_dst) % src;\r
+ if(abs(dst) >= abs(src<<16))\r
+ {\r
+ FLAG_V = VFLAG_SET;\r
+ USE_CYCLES(2*(dst < 0));\r
+ return;\r
+ }\r
+\r
+ quotient = dst / src;\r
+ remainder = dst % src;\r
\r
+ cycles = m68ki_divs_cycles(2*(dst < 0) + (quotient < 0), quotient);\r
if(quotient == MAKE_INT_16(quotient))\r
{\r
FLAG_Z = quotient;\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));\r
+ USE_CYCLES(cycles);\r
return;\r
}\r
FLAG_V = VFLAG_SET;\r
+ USE_CYCLES(cycles);\r
return;\r
}\r
m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE);\r
+ ADD_CYCLES(12);\r
}\r
\r
\r
{\r
uint* r_dst = &DX;\r
sint src = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16);\r
+ sint dst = MAKE_INT_32(*r_dst);\r
sint quotient;\r
sint remainder;\r
+ int cycles;\r
\r
if(src != 0)\r
{\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = 0;\r
+ USE_CYCLES(m68ki_divs_cycles(2, 0));\r
+ return;\r
+ }\r
+\r
+ if(abs(dst) >= abs(src<<16))\r
+ {\r
+ FLAG_V = VFLAG_SET;\r
+ USE_CYCLES(2*(dst < 0));\r
return;\r
}\r
\r
- quotient = MAKE_INT_32(*r_dst) / src;\r
- remainder = MAKE_INT_32(*r_dst) % src;\r
+ quotient = dst / src;\r
+ remainder = dst % src;\r
\r
+ cycles = m68ki_divs_cycles(2*(dst < 0) + (quotient < 0), quotient);\r
if(quotient == MAKE_INT_16(quotient))\r
{\r
FLAG_Z = quotient;\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));\r
+ USE_CYCLES(cycles);\r
return;\r
}\r
FLAG_V = VFLAG_SET;\r
+ USE_CYCLES(cycles);\r
return;\r
}\r
m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE);\r
+ ADD_CYCLES(12);\r
}\r
\r
\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));\r
+ USE_CYCLES(m68ki_divu_cycles(quotient));\r
return;\r
}\r
FLAG_V = VFLAG_SET;\r
return;\r
}\r
m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE);\r
+ ADD_CYCLES(6);\r
}\r
\r
\r
FLAG_V = VFLAG_CLEAR;\r
FLAG_C = CFLAG_CLEAR;\r
*r_dst = MASK_OUT_ABOVE_32(MASK_OUT_ABOVE_16(quotient) | (remainder << 16));\r
+ USE_CYCLES(m68ki_divu_cycles(quotient));\r
return;\r
}\r
FLAG_V = VFLAG_SET;\r
return;\r
}\r
m68ki_exception_trap(EXCEPTION_ZERO_DIVIDE);\r
+ ADD_CYCLES(6);\r
}\r
\r
\r
M68KMAKE_OP(muls, 16, ., d)\r
{\r
uint* r_dst = &DX;\r
- uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(DY) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst)));\r
+ uint x = MAKE_INT_16(DY);\r
+ uint res = MASK_OUT_ABOVE_32(x * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst)));\r
\r
*r_dst = res;\r
+ USE_CYCLES(m68ki_muls_cycles(x));\r
\r
FLAG_Z = res;\r
FLAG_N = NFLAG_32(res);\r
M68KMAKE_OP(muls, 16, ., .)\r
{\r
uint* r_dst = &DX;\r
- uint res = MASK_OUT_ABOVE_32(MAKE_INT_16(M68KMAKE_GET_OPER_AY_16) * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst)));\r
+ uint x = MAKE_INT_16(M68KMAKE_GET_OPER_AY_16);\r
+ uint res = MASK_OUT_ABOVE_32(x * MAKE_INT_16(MASK_OUT_ABOVE_16(*r_dst)));\r
\r
*r_dst = res;\r
+ USE_CYCLES(m68ki_muls_cycles(x));\r
\r
FLAG_Z = res;\r
FLAG_N = NFLAG_32(res);\r
M68KMAKE_OP(mulu, 16, ., d)\r
{\r
uint* r_dst = &DX;\r
- uint res = MASK_OUT_ABOVE_16(DY) * MASK_OUT_ABOVE_16(*r_dst);\r
+ uint x = MASK_OUT_ABOVE_16(DY);\r
+ uint res = x * MASK_OUT_ABOVE_16(*r_dst);\r
\r
*r_dst = res;\r
+ USE_CYCLES(m68ki_mulu_cycles(x));\r
\r
FLAG_Z = res;\r
FLAG_N = NFLAG_32(res);\r
M68KMAKE_OP(mulu, 16, ., .)\r
{\r
uint* r_dst = &DX;\r
- uint res = M68KMAKE_GET_OPER_AY_16 * MASK_OUT_ABOVE_16(*r_dst);\r
+ uint x = M68KMAKE_GET_OPER_AY_16;\r
+ uint res = x * MASK_OUT_ABOVE_16(*r_dst);\r
\r
*r_dst = res;\r
+ USE_CYCLES(m68ki_mulu_cycles(x));\r
\r
FLAG_Z = res;\r
FLAG_N = NFLAG_32(res);\r