} else {
addcycles000_nonces("loop_mode & 0xfffe");
}
- // CLR.L adds 2 extra cycles when loop exits
- if (g_instr->mnemo == i_CLR && g_instr->size == sz_long) {
+ // CLR.x adds 2 extra cycles when loop exits
+ if (g_instr->mnemo == i_CLR) {
out("loop_mode &= 0xffff0000;\n");
out("loop_mode |= 1;\n");
} else {
if (g_instr->mnemo == i_MVSR2 && !write) {
out("opcode |= 0x20000;\n");
}
- // read bus error, -(an).w/.l: pre-decrement is done first.
- if (!write && g_instr->smode == Apdi && g_instr->size == sz_long) {
-
- //out("m68k_areg(regs, %s) = %sa;\n", bus_error_reg, name);
- }
if (g_instr->mnemo == i_MOVES) {
out("regs.irc = extra;\n");
if (!write) {
out("regs.write_buffer = extra;\n");
}
if (g_instr->size == sz_long) {
- // moves.l an,-(an)/(an)+ (same registers): write buffer contains modified value.
- if (g_instr->dmode == Aipi || g_instr->dmode == Apdi) {
- out("if (dstreg + 8 == ((extra >> 12) & 15)) {\n");
- out("src += %d;\n", g_instr->dmode == Aipi ? 2 : -2);
- out("}\n");
- }
if (g_instr->dmode == Apdi) {
if (!write) {
out("m68k_areg(regs, dstreg) = srca;\n");
out("regs.irc = dsta >> 16;\n");
}
}
+ } else if (g_instr->mnemo == i_MVPRM) {
+ if (write) {
+ if (g_instr->size == sz_word) {
+ out("uae_u16 val = src;\n");
+ } else {
+ out("uae_u16 val = src >> %d;\n", offset <= 2 ? 16 : 0);
+ }
+ size |= 0x100;
+ writevar = "val";
+ }
}
}
}
if (write) {
- out("exception2_write(opcode, %sa + %d, %d, %s, %d);\n",
+ out("exception2_write(opcode, %sa + %d, 0x%x, %s, %d);\n",
name, offset, size, writevar,
(!write && (g_instr->smode == PC16 || g_instr->smode == PC8r)) ||
(write && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) ? 2 : fc);
} else {
- out("exception2_read(opcode, %sa + %d, %d, %d);\n",
+ out("exception2_read(opcode, %sa + %d, 0x%x, %d);\n",
name, offset, size,
(!write && (g_instr->smode == PC16 || g_instr->smode == PC8r)) ||
(write && (g_instr->dmode == PC16 || g_instr->dmode == PC8r)) ? 2 : fc);
int old_m68k_pc_offset = m68k_pc_offset;
int old_m68k_pc_total = m68k_pc_total;
clear_m68k_offset();
+ count_cycles -= 4;
get_prefetch_020_continue();
fill_prefetch_full_000_special(1, NULL);
+ count_cycles += 4;
returncycles(8);
m68k_pc_offset = old_m68k_pc_offset;
m68k_pc_total = old_m68k_pc_total;
setpc("oldpc");
check_ipl_always();
- returncycles(0);
+ returncycles(2);
out("}\n");
out("regs.loop_mode = 0;\n");
setpc("oldpc + %d", m68k_pc_offset);
returntail(false);
did_prefetch = 0;
// Earlier models do -(an)/(an)+ EA calculation first
- if (!(cpu_level == 5 || (curi->dmode != Aipi && curi->dmode != Apdi) || (cpu_level == 1 && curi->size == sz_long))) {
+ if (!(cpu_level == 5 || (curi->dmode != Aipi && curi->dmode != Apdi)) || (cpu_level == 1 && curi->size == sz_long)) {
out("src = regs.regs[(extra >> 12) & 15];\n");
}
genastore_fc ("src", curi->dmode, "dstreg", curi->size, "dst");
opcode = regs.ir;
}
last_di_for_exception_3 = 1;
- exception3f(opcode, addr, false, ia, ni, 0xffffffff, size, fc);
+ exception3f(opcode, addr, false, ia, ni, 0xffffffff, size & 15, fc);
}
void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
{
}
last_di_for_exception_3 = 1;
regs.write_buffer = val;
- exception3f(opcode, addr, true, ia, ni, 0xffffffff, size, fc);
+ exception3f(opcode, addr, true, ia, ni, 0xffffffff, size & 15, fc);
}
void exception2_setup(uae_u32 opcode, uaecptr addr, bool read, int size, uae_u32 fc)
last_op_for_exception_3 = opcode;
last_fc_for_exception_3 = fc;
last_notinstruction_for_exception_3 = exception_in_exception != 0;
- last_size_for_exception_3 = size;
+ last_size_for_exception_3 = size & 15;
last_di_for_exception_3 = 1;
hardware_bus_error = 0;
void exception2_read(uae_u32 opcode, uaecptr addr, int size, int fc)
{
- exception2_setup(opcode, addr, true, size, fc);
+ exception2_setup(opcode, addr, true, size & 15, fc);
Exception(2);
}
void exception2_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
{
- exception2_setup(opcode, addr, false, size, fc);
- regs.write_buffer = val;
+ exception2_setup(opcode, addr, false, size & 15, fc);
+ if (size & 0x100) {
+ regs.write_buffer = val;
+ } else {
+ if (size == sz_byte) {
+ regs.write_buffer &= 0xff00;
+ regs.write_buffer |= val & 0xff;
+ } else {
+ regs.write_buffer = val;
+ }
+ }
Exception(2);
}
(Note the difference with the documented range.)
-DIVU:
+DIVU 68000:
Overflow (always): 10 cycles.
Worst case: 136 cycles.
Best case: 76 cycles.
+DIVU 68010:
-DIVS:
+Overflow (always): 8 cycles.
+Wost case: 108 cycles.
+Best case: 78 cycles.
+
+DIVS 68000:
Absolute overflow: 16-18 cycles.
Signed overflow is not detected prematurely.
Best case without signed overflow: 122 cycles.
Best case with signed overflow: 120 cycles
+DIVS 68010:
+
+Absolute overflow: 16 cycles.
+Signed overflow is not detected prematurely.
+
+Worst case: 122 cycles.
+Best case: 120 cycles.
*/
return 0;
if (currprefs.cpu_model == 68010) {
+
// Overflow
- if ((dividend >> 16) >= divisor)
+ if ((dividend >> 16) >= divisor) {
return 4;
- return 104;
- }
+ }
- // Overflow
- if ((dividend >> 16) >= divisor)
- return (mcycles = 5) * 2 - 4;
+ mcycles = 74;
- mcycles = 38;
+ hdivisor = divisor << 16;
- hdivisor = divisor << 16;
+ for (i = 0; i < 15; i++) {
+ uae_u32 temp;
+ temp = dividend;
- for (i = 0; i < 15; i++) {
- uae_u32 temp;
- temp = dividend;
+ dividend <<= 1;
- dividend <<= 1;
+ // If carry from shift
+ if ((uae_s32)temp < 0) {
+ dividend -= hdivisor;
+ } else {
+ mcycles += 2;
+ if (dividend >= hdivisor) {
+ dividend -= hdivisor;
+ }
+ }
+ }
+ return mcycles;
- // If carry from shift
- if ((uae_s32)temp < 0)
- dividend -= hdivisor;
- else {
- mcycles += 2;
- if (dividend >= hdivisor) {
+ } else {
+
+ // Overflow
+ if ((dividend >> 16) >= divisor)
+ return (mcycles = 5) * 2 - 4;
+
+ mcycles = 38;
+
+ hdivisor = divisor << 16;
+
+ for (i = 0; i < 15; i++) {
+ uae_u32 temp;
+ temp = dividend;
+
+ dividend <<= 1;
+
+ // If carry from shift
+ if ((uae_s32)temp < 0)
dividend -= hdivisor;
- mcycles--;
+ else {
+ mcycles += 2;
+ if (dividend >= hdivisor) {
+ dividend -= hdivisor;
+ mcycles--;
+ }
}
}
+ // -4 = remove prefetch cycle
+ return mcycles * 2 - 4;
}
- // -4 = remove prefetch cycle
- return mcycles * 2 - 4;
}
int getDivs68kCycles (uae_s32 dividend, uae_s16 divisor)
/* DIVU overflow
*
* 68000: V=1, N=1, C=0, Z=0
- * 68010: V=1, N=divisor<0x8000, C=0, Z=divided upper word == 0xffff and divisor == 0xffff
+ * 68010: V=1, N=1, C=0, Z=0
* 68020: V=1, C=0, Z=0, N=X
* 68040: V=1, C=0, NZ not modified.
* 68060: V=1, C=0, NZ not modified.
SET_NFLG(1);
} else if (currprefs.cpu_model == 68010) {
SET_VFLG(1);
- SET_NFLG(divisor < 0x8000);
- // can anyone explain this?
- SET_ZFLG((dividend >> 16) == 0xffff && divisor == 0xffff);
+ SET_NFLG(1);
+ SET_ZFLG(0);
SET_CFLG(0);
} else {
// 68000