doexcstack();
}
+// load to irc only
+void exception3_read_prefetch_only(uae_u32 opcode, uae_u32 addr)
+{
+ if (cpu_lvl == 1) {
+ uae_u16 prev = regs.read_buffer;
+ get_word_test(addr & ~1);
+ regs.irc = regs.read_buffer;
+ regs.read_buffer = prev;
+ } else {
+ add_memory_cycles(1);
+ }
+
+ test_exception = 3;
+ test_exception_3_w = 0;
+ test_exception_addr = addr;
+ test_exception_opcode = opcode;
+ test_exception_3_fc = 2;
+ test_exception_3_size = sz_word;
+ test_exception_3_di = 0;
+
+ doexcstack();
+}
+
void exception3_read_prefetch(uae_u32 opcode, uae_u32 addr)
{
- add_memory_cycles(1);
+ if (cpu_lvl == 1) {
+ get_word_test(addr & ~1);
+ } else {
+ add_memory_cycles(1);
+ }
test_exception = 3;
test_exception_3_w = 0;
doexcstack();
}
-void exception3_read_opcode(uae_u32 opcode, uae_u32 addr, int size, int fc)
+void exception3_read_access2(uae_u32 opcode, uae_u32 addr, int size, int fc)
{
- add_memory_cycles(1);
+ get_word_test(addr & ~1);
+ get_word_test(addr & ~1);
+ exception3_read(opcode, addr, size, fc);
+}
+
+void exception3_read_access(uae_u32 opcode, uae_u32 addr, int size, int fc)
+{
+ if (cpu_lvl == 1) {
+ get_word_test(addr & ~1);
+ } else {
+ add_memory_cycles(1);
+ }
exception3_read(opcode, addr, size, fc);
}
-void exception3_write_opcode(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int fc)
+void exception3_write_access(uae_u32 opcode, uae_u32 addr, int size, uae_u32 val, int fc)
{
add_memory_cycles(1);
exception3_write(opcode, addr, size, val, fc);
testing_active_opcode = opc;
hardware_bus_error = 0;
hardware_bus_error_fake = 0;
- read_buffer_prev = regs.ir;
+ read_buffer_prev = regs.irc;
regs.read_buffer = regs.irc;
regs.write_buffer = 0xf00d;
exception_extra_frame_size = 0;
if (size == sz_word) {
// Word MOVE is relatively simple
int set_ccr = 0;
+ int reset_ccr = 0;
+ *setapdi = 1;
switch (smode)
{
case Dreg:
case imm:
if (dmode == Apdi || dmode == Ad16 || dmode == Ad8r || dmode == absw || dmode == absl)
set_ccr = 1;
+ else
+ reset_ccr = 1;
break;
case Aind:
case Aipi:
} else if (dmode == absl && smode >= Aind && smode < imm) {
out("regs.irc = dsta >> 16;\n");
}
+ if (reset_ccr) {
+ out("regflags.cznv = oldflags;\n");
+ }
if (set_ccr) {
out("ccr_68000_word_move_ae_normal((uae_s16)(src));\n");
}
int set_ccr = 0;
int set_high_word = 0;
int set_low_word = 0;
+ if (dmode == Apdi) {
+ *setapdi = -4;
+ } else {
+ *setapdi = 1;
+ }
switch (smode)
{
case Dreg:
break;
}
- if (dmode == Apdi) {
- dummy_prefetch(NULL, NULL);
- *setapdi = 0;
- } else if (dmode == absl && smode >= Aind && smode < imm) {
+ if (dmode == absl && smode >= Aind && smode < imm) {
out("regs.irc = dsta >> 16;\n");
}
} else {
do_bus_error_fixes(name, 0, getv == 2);
}
+ if (g_instr->mnemo == i_MOVES) {
+ // MOVES has strange behavior
+ out("regs.irc = extra;\n");
+ if (!exp3rw) {
+ out("regs.write_buffer = extra;\n");
+ } else {
+ // moves.w an,-(an)/(an)+ (same registers): write buffer contains modified value.
+ if (mode == Aipi || mode == Apdi) {
+ out("if (dstreg + 8 == ((extra >> 12) & 15)) {\n");
+ out("src += %d;\n", mode == Aipi ? 2 : -2);
+ out("}\n");
+ }
+ }
+ if (size == sz_long) {
+ if (mode == Aipi) {
+ out("m68k_areg(regs, dstreg) += 4;\n");
+ } else if (mode == Apdi) {
+ setapdiback = 1;
+ }
+ }
+ }
+
// x,-(an): an is modified (MOVE to CCR counts as word sized)
if (mode == Apdi && (g_instr->size == sz_word || g_instr->size == i_MV2SR) && g_instr->mnemo != i_CLR) {
out("m68k_areg(regs, %s) = %sa;\n", reg, name);
} else {
move_68010_address_error(size, &setapdiback, &fcmodeflags);
}
+ if (mode != Apdi && mode != Aipi) {
+ setapdiback = 0;
+ }
}
} else if (g_instr->mnemo == i_MVSR2) {
// If MOVE from SR generates address error exception,
setapdiback = 0;
}
+ // can be used for both Apdi and Aipi
if (setapdiback) {
- out("m68k_areg(regs, %s) = %sa;\n", reg, name);
+ if (setapdiback > 0) {
+ out("m68k_areg(regs, %s) = %sa;\n", reg, name);
+ } else {
+ out("m68k_areg(regs, %s) = %sa + %d;\n", reg, name, -setapdiback);
+ }
}
// MOVE.L EA,-(An) causing address error: stacked value is original An - 2, not An - 4.
if (exp3rw) {
const char *shift = (size == sz_long && !(flags & GF_REVERSE)) ? " >> 16" : "";
- out("exception3_write_opcode(opcode, %sa, %d, %s%s, %d);\n",
+ out("exception3_write_access(opcode, %sa, %d, %s%s, %d);\n",
name, size, g_srcname, shift,
// PC-relative: FC=2
(getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
} else {
- out("exception3_read_opcode(opcode, %sa, %d, %d);\n",
- name, size,
- // PC-relative: FC=2
- (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
+ // 68010 address error: if addressing mode is (An), (An)+ or -(An) and byte or word: CPU does extra read access!
+ if (cpu_level == 1 && (g_instr->smode == Aind || g_instr->smode == Aipi || g_instr->smode == Apdi) && g_instr->size < sz_long) {
+ out("exception3_read_access2(opcode, %sa, %d, %d);\n",
+ name, size,
+ // PC-relative: FC=2
+ (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
+ } else {
+ out("exception3_read_access(opcode, %sa, %d, %d);\n",
+ name, size,
+ // PC-relative: FC=2
+ (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
+ }
}
write_return_cycles_noadd(0);
out("uaecptr srcav = srca;\n");
}
if (write) {
- out("exception3_write_opcode(opcode, srca, %d, srcav, %d);\n",
+ out("exception3_write_access(opcode, srca, %d, srcav, %d);\n",
g_instr->size,
(g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
} else {
- out("exception3_read_opcode(opcode, srca, %d, %d);\n",
+ out("exception3_read_access(opcode, srca, %d, %d);\n",
g_instr->size,
(g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
}
genamode(curi, curi->dmode, "dstreg", curi->size, "dst", 2, 0, flags | GF_NOEXC3);
- if (curi->mnemo == i_MOVEA && curi->size == sz_word)
+ if (curi->mnemo == i_MOVEA && curi->size == sz_word) {
out("src = (uae_s32)(uae_s16)src;\n");
+ }
if (curi->dmode == Apdi) {
// -(an) decrease is not done if bus error
int storeflags = flags & (GF_REVERSE | GF_APDI);
if (curi->mnemo == i_MOVE) {
- if (curi->size == sz_long && cpu_level <= 1 && (using_prefetch || using_ce) && curi->dmode >= Aind) {
+ if (cpu_level == 1 && (isreg(curi->smode) || curi->smode == imm)) {
+ out("uae_u16 oldflags = regflags.cznv;\n");
+ }
+ if (curi->size == sz_long && (using_prefetch || using_ce) && curi->dmode >= Aind) {
// to support bus error exception correct flags, flags needs to be set
// after first word has been written.
storeflags |= GF_SECONDWORDSETFLAGS;
next_level_000();
if (cpu_level <= 1 && using_exception_3) {
out("if (m68k_areg(regs, 7) & 1) {\n");
- out("exception3_read_opcode(opcode, m68k_areg(regs, 7), 1, 1);\n");
+ out("exception3_read_access(opcode, m68k_areg(regs, 7), 1, 1);\n");
write_return_cycles_noadd(0);
out("}\n");
}
out("regs.sr = sr;\n");
makefromsr();
out("if (pc & 1) {\n");
- out("exception3_read_opcode(opcode | 0x20000, pc, 1, 2);\n");
+ out("exception3_read_access(opcode | 0x20000, pc, 1, 2);\n");
write_return_cycles(0);
out("}\n");
setpc ("pc");
out("regs.sr = sr;\n");
makefromsr();
out("if (pc & 1) {\n");
- dummy_prefetch("pc", "oldpc");
- out("exception3_read_prefetch(opcode, pc);\n");
+ out("exception3_read_prefetch_only(opcode, pc);\n");
write_return_cycles(0);
out("}\n");
out("newsr = sr; newpc = pc;\n");
if (cpu_level >= 4) {
out("m68k_areg(regs, 7) -= 4 + offs;\n");
}
- out("exception3_read_prefetch(opcode, pc);\n");
+ out("exception3_read_prefetch_only(opcode, pc);\n");
write_return_cycles(0);
out("}\n");
setpc ("pc");
out("if (olda & 1) {\n");
out("m68k_areg(regs, 7) += 4;\n");
out("m68k_areg(regs, srcreg) = olda;\n");
- out("exception3_write_opcode(opcode, olda, sz_word, src >> 16, 1);\n");
+ out("exception3_write_access(opcode, olda, sz_word, src >> 16, 1);\n");
write_return_cycles(0);
out("}\n");
}
out("uaecptr pc = %s;\n", getpc);
if (cpu_level <= 1 && using_exception_3) {
out("if (m68k_areg(regs, 7) & 1) {\n");
- out("exception3_read_opcode(opcode, m68k_areg(regs, 7), 1, 1);\n");
+ out("exception3_read_access(opcode, m68k_areg(regs, 7), 1, 1);\n");
write_return_cycles(0);
out("}\n");
}
}
out("if (%s & 1) {\n", getpc);
out("uaecptr faultpc = %s;\n", getpc);
- if (cpu_level == 1) {
- dummy_prefetch(NULL, NULL);
- }
setpc("pc");
if (cpu_level >= 4) {
out("m68k_areg(regs, 7) -= 4;\n");
}
- out("exception3_read_prefetch(opcode, faultpc);\n");
+ out("exception3_read_prefetch_only(opcode, faultpc);\n");
write_return_cycles(0);
out("}\n");
clear_m68k_offset();
case i_RTR:
if (cpu_level <= 1 && using_exception_3) {
out("if (m68k_areg(regs, 7) & 1) {\n");
- out("exception3_read_opcode(opcode, m68k_areg(regs, 7), 1, 1);\n");
+ out("exception3_read_access(opcode, m68k_areg(regs, 7), 1, 1);\n");
write_return_cycles(0);
out("}\n");
}
if (cpu_level < 4) {
out("if (%s & 1) {\n", getpc);
out("uaecptr faultpc = %s;\n", getpc);
- if (cpu_level == 1) {
- dummy_prefetch(NULL, NULL);
- }
setpc("oldpc");
- out("exception3_read_prefetch(opcode, faultpc);\n");
+ out("exception3_read_prefetch_only(opcode, faultpc);\n");
write_return_cycles(0);
out("}\n");
}
addcycles000_onlyce(6);
addcycles000_nonce(6);
}
- out("exception3_read_prefetch(opcode, srca);\n");
+ out("exception3_read_prefetch_only(opcode, srca);\n");
write_return_cycles_noadd(0);
out("}\n");
pop_ins_cnt();
out("m68k_areg(regs, 7) -= 4;\n");
if (using_exception_3 && cpu_level <= 1) {
out("if (m68k_areg(regs, 7) & 1) {\n");
- out("exception3_write_opcode(opcode, m68k_areg(regs, 7), 1, m68k_areg(regs, 7) >> 16, 1);\n");
+ out("exception3_write_access(opcode, m68k_areg(regs, 7), 1, m68k_areg(regs, 7) >> 16, 1);\n");
write_return_cycles(0);
out("}\n");
}
if (using_exception_3) {
push_ins_cnt();
out("if (srca & 1) {\n");
- if (curi->smode >= Ad16 && cpu_level == 1 && using_prefetch) {
- dummy_prefetch("srca", NULL);
- }
if (curi->smode == Ad16 || curi->smode == absw || curi->smode == PC16) {
addcycles000_onlyce(2);
addcycles000_nonce(2);
addcycles000_onlyce(6);
addcycles000_nonce(6);
}
- out("exception3_read_prefetch(opcode, srca);\n");
+ out("exception3_read_prefetch_only(opcode, srca);\n");
write_return_cycles_noadd(0);
out("}\n");
pop_ins_cnt();
out("if (m68k_areg(regs, 7) & 1) {\n");
out("m68k_areg(regs, 7) -= 4;\n");
incpc("2");
- out("exception3_write_opcode(opcode, m68k_areg(regs, 7), sz_word, oldpc, 1);\n");
+ out("exception3_write_access(opcode, m68k_areg(regs, 7), sz_word, oldpc, 1);\n");
write_return_cycles(0);
out("}\n");
} else if (cpu_level == 1) {
out("if (m68k_areg(regs, 7) & 1) {\n");
- out("exception3_write_opcode(opcode, m68k_areg(regs, 7), sz_word, oldpc, 1);\n");
+ out("exception3_write_access(opcode, m68k_areg(regs, 7), sz_word, oldpc, 1);\n");
write_return_cycles(0);
out("}\n");
}
if (using_exception_3 && cpu_level == 1) {
// 68010 TODO: looks like prefetches are done first and stack writes last
out("if (s & 1) {\n");
- out("exception3_read_prefetch(opcode, s);\n");
+ out("exception3_read_prefetch_only(opcode, s + oldpc);\n");
write_return_cycles(0);
out("}\n");
}
out("if (src & 1) {\n");
if (cpu_level == 1) {
out("uaecptr oldpc = %s;\n", getpc);
+ out("uae_u16 rb = regs.irc;\n");
incpc("((uae_s32)src + 2) & ~1");
dummy_prefetch(NULL, "oldpc");
+ out("regs.read_buffer = rb;\n");
}
out("exception3_read_prefetch(opcode, %s + 2 + (uae_s32)src);\n", getpc);
write_return_cycles(0);
if (cpu_level <= 1 && using_exception_3) {
out("if (dsta & 1) {\n");
out("regs.ir = old_opcode;\n");
- out("exception3_write_opcode(old_opcode, dsta, sz_word, srca >> 16, 1);\n");
+ out("exception3_write_access(old_opcode, dsta, sz_word, srca >> 16, 1);\n");
write_return_cycles(0);
out("}\n");
}
extern void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc);
extern void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc);
-extern void exception3_read_opcode(uae_u32 opcode, uaecptr addr, int size, int fc);
-extern void exception3_write_opcode(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc);
+extern void exception3_read_access(uae_u32 opcode, uaecptr addr, int size, int fc);
+extern void exception3_read_access2(uae_u32 opcode, uaecptr addr, int size, int fc);
+extern void exception3_write_access(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc);
extern void exception3_read_prefetch(uae_u32 opcode, uaecptr addr);
+extern void exception3_read_prefetch_only(uae_u32 opcode, uaecptr addr);
extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
extern void exception2 (uaecptr addr, bool read, int size, uae_u32 fc);
extern void exception2_setup(uae_u32 opcode, uaecptr addr, bool read, int size, uae_u32 fc);
/*
-Address/Bus Error:
+68000 Address/Bus Error:
- [memory access causing bus/address error]
- 8 idle cycles (+4 if bus error)
- 2 idle cycles
- prefetch
+68010 Address/Bus Error:
+
+- [memory access causing bus/address error]
+- 8 idle cycles (+4 if bus error)
+- write word 28
+- write word 26
+- write word 27
+- write word 25
+- write word 23
+- write word 24
+- write word 22
+- write word 21
+- write word 20
+- write word 19
+- write word 18
+- write word 17
+- write word 16
+- write word 15
+- write word 13
+- write word 14
+- write instruction buffer
+- (skipped)
+- write data input buffer
+- (skipped)
+- write data output buffer
+- (skipped)
+- write fault address low word
+- write fault address high word
+- write special status word
+- write PC low word
+- write SR
+- write PC high word
+- write frame format
+- read exception address high word
+- read exception address low word
+- prefetch
+- 2 idle cycles
+- prefetch
+
+
Division by Zero:
- 4 idle cycles (EA + 4 cycles in cpuemu)
interrupt = nr >= 24 && nr < 24 + 8;
if (!interrupt) {
start = 4;
- if (nr == 7) // TRAPV
+ if (nr == 7) { // TRAPV
start = 0;
- else if (nr == 3)
- start = 8;
- else if (nr == 2)
- start = 12;
+ } else if (nr == 3) {
+ if (currprefs.cpu_model == 68000)
+ start = 8;
+ else
+ start = 4;
+ } else if (nr == 2) {
+ if (currprefs.cpu_model == 68000)
+ start = 12;
+ else
+ start = 8;
+ }
}
if (start)
mode |= last_notinstruction_for_exception_3 ? 8 : 0;
// undocumented bits contain opcode
mode |= last_op_for_exception_3 & ~31;
- m68k_areg(regs, 7) -= 14;
+ m68k_areg(regs, 7) -= 7 * 2;
exception_in_exception = -1;
x_put_word(m68k_areg(regs, 7) + 12, last_addr_for_exception_3);
x_put_word(m68k_areg(regs, 7) + 8, regs.sr);
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x0100; // RW
if (last_op_for_exception_3 & 0x20000)
ssw &= 0x00ff;
- m68k_areg(regs, 7) -= 50;
+ m68k_areg(regs, 7) -= (29 - 4) * 2;
exception_in_exception = -1;
frame_id = 8;
- x_put_word(m68k_areg(regs, 7) + 0, ssw); // ssw
- x_put_long(m68k_areg(regs, 7) + 2, last_fault_for_exception_3); // fault addr
- x_put_word(m68k_areg(regs, 7) + 6, 0); // unused
- x_put_word(m68k_areg(regs, 7) + 8, out); // data output buffer
- x_put_word(m68k_areg(regs, 7) + 10, 0); // unused
- x_put_word(m68k_areg(regs, 7) + 12, in); // data input buffer
- x_put_word(m68k_areg(regs, 7) + 14, 0); // unused
- x_put_word(m68k_areg(regs, 7) + 16, regs.irc); // instruction input buffer
- x_put_word(m68k_areg(regs, 7) + 18, 0); // version
for (int i = 0; i < 15; i++) {
- x_put_word(m68k_areg(regs, 7) + 20 + i * 2, 0);
+ x_put_word(m68k_areg(regs, 7) + 20 + i * 2, ((i + 1) << 8) | ((i + 2) << 0));
}
+ x_put_word(m68k_areg(regs, 7) + 18, 0); // version
+ x_put_word(m68k_areg(regs, 7) + 16, regs.irc); // instruction input buffer
+ x_put_word(m68k_areg(regs, 7) + 12, in); // data input buffer
+ x_put_word(m68k_areg(regs, 7) + 8, out); // data output buffer
+ x_put_word(m68k_areg(regs, 7) + 4, last_fault_for_exception_3); // fault addr
+ x_put_word(m68k_areg(regs, 7) + 2, last_fault_for_exception_3 >> 16);
+ x_put_word(m68k_areg(regs, 7) + 0, ssw); // ssw
}
}
if (currprefs.cpu_model == 68010) {
// 68010 creates only format 0 and 8 stack frames
- m68k_areg (regs, 7) -= 8;
+ m68k_areg (regs, 7) -= 4 * 2;
if (m68k_areg(regs, 7) & 1) {
exception3_notinstruction(regs.ir, m68k_areg(regs, 7) + 4);
return;
x_put_word (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
x_put_word (m68k_areg (regs, 7) + 6, (frame_id << 12) | (vector_nr * 4));
} else {
- m68k_areg (regs, 7) -= 6;
+ m68k_areg (regs, 7) -= 3 * 2;
if (m68k_areg(regs, 7) & 1) {
exception3_notinstruction(regs.ir, m68k_areg(regs, 7) + 4);
return;
m68k_setpc(regs.vbr + 4 * vector_nr);
if (interrupt) {
regs.ir = nr;
- exception3_read_opcode(regs.ir | 0x20000 | 0x10000, newpc, sz_word, 2);
+ exception3_read_access(regs.ir | 0x20000 | 0x10000, newpc, sz_word, 2);
} else {
- exception3_read_opcode(regs.ir | 0x40000 | 0x20000 | (g1 ? 0x10000 : 0), newpc, sz_word, 2);
+ exception3_read_access(regs.ir | 0x40000 | 0x20000 | (g1 ? 0x10000 : 0), newpc, sz_word, 2);
}
} else if (currprefs.cpu_model == 68010) {
// offset, not vbr + offset
regs.write_buffer = 4 * vector_nr;
regs.read_buffer = newpc;
regs.irc = regs.read_buffer;
- exception3_read_opcode(regs.opcode, newpc, sz_word, 2);
+ exception3_read_access(regs.opcode, newpc, sz_word, 2);
} else {
exception3_notinstruction(regs.ir, newpc);
}
} else {
switch (nr)
{
- case 2: cycles = 134; break; /* Bus error */
- case 3: cycles = 130; break; /* Address error */
+ case 2: cycles = 140; break; /* Bus error */
+ case 3: cycles = 136; break; /* Address error */
case 4: cycles = 38; break; /* Illegal instruction */
case 5: cycles = 38; break; /* Division by zero */
case 6: cycles = 38; break; /* CHK */
m68k_setpc(regs.vbr + 4 * vector_nr);
if (interrupt) {
regs.ir = nr;
- exception3_read_opcode(regs.ir | 0x20000 | 0x10000, newpc, sz_word, 2);
+ exception3_read_access(regs.ir | 0x20000 | 0x10000, newpc, sz_word, 2);
} else {
- exception3_read_opcode(regs.ir | 0x40000 | 0x20000 | (g1 ? 0x10000 : 0), newpc, sz_word, 2);
+ exception3_read_access(regs.ir | 0x40000 | 0x20000 | (g1 ? 0x10000 : 0), newpc, sz_word, 2);
}
} else if (currprefs.cpu_model == 68010) {
regs.t1 = 0;
regs.write_buffer = 4 * vector_nr;
regs.read_buffer = newpc;
regs.irc = regs.read_buffer;
- exception3_read_opcode(regs.ir, newpc, sz_word, 2);
+ exception3_read_access(regs.ir, newpc, sz_word, 2);
} else {
exception3_notinstruction(regs.ir, newpc);
}
exception3f(opcode, addr, false, 0, false, 0xffffffff, size, fc);
}
+// 68010 special prefetch handling
+void exception3_read_prefetch_only(uae_u32 opcode, uae_u32 addr)
+{
+ if (currprefs.cpu_model == 68010) {
+ uae_u16 prev = regs.read_buffer;
+ x_get_word(addr & ~1);
+ regs.irc = regs.read_buffer;
+ } else {
+ x_do_cycles(4 * cpucycleunit);
+ }
+ last_di_for_exception_3 = 0;
+ exception3f(opcode, addr, false, true, false, m68k_getpc(), sz_word, -1);
+}
+
// Some hardware accepts address error aborted reads or writes as normal reads/writes.
void exception3_read_prefetch(uae_u32 opcode, uaecptr addr)
{
last_di_for_exception_3 = 0;
exception3f(opcode, addr, false, true, false, m68k_getpc(), sz_word, -1);
}
-void exception3_read_opcode(uae_u32 opcode, uaecptr addr, int size, int fc)
+void exception3_read_access(uae_u32 opcode, uaecptr addr, int size, int fc)
{
x_do_cycles(4 * cpucycleunit);
exception3_read(opcode, addr, size, fc);
}
-void exception3_write_opcode(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
+void exception3_read_access2(uae_u32 opcode, uaecptr addr, int size, int fc)
+{
+ // (An), -(An) and (An)+ and 68010: read happens twice!
+ x_do_cycles(8 * cpucycleunit);
+ exception3_read(opcode, addr, size, fc);
+}
+void exception3_write_access(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
{
x_do_cycles(4 * cpucycleunit);
exception3_write(opcode, addr, size, val, fc);
opcode = regs.ir;
}
last_di_for_exception_3 = 1;
- exception3f(opcode, addr, true, ia, ni, 0xffffffff, size, fc);
regs.write_buffer = val;
+ exception3f(opcode, addr, true, ia, ni, 0xffffffff, size, fc);
}
void exception2_setup(uae_u32 opcode, uaecptr addr, bool read, int size, uae_u32 fc)
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), regs.irc); // instruction input buffer
m68k_areg(regs, 7) -= 2;
- x_put_word(m68k_areg(regs, 7), 0); // unused
+ // unused not written
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), in); // data input buffer
m68k_areg(regs, 7) -= 2;
- x_put_word(m68k_areg(regs, 7), 0); // unused
+ // unused not written
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), out); // data output buffer
m68k_areg(regs, 7) -= 2;
- x_put_word(m68k_areg(regs, 7), 0); // unused
- m68k_areg(regs, 7) -= 4;
- x_put_long(m68k_areg(regs, 7), regs.mmu_fault_addr); // fault addr
+ // unused not written
+ m68k_areg(regs, 7) -= 2;
+ x_put_word(m68k_areg(regs, 7), regs.mmu_fault_addr); // fault addr
+ m68k_areg(regs, 7) -= 2;
+ x_put_word(m68k_areg(regs, 7), regs.mmu_fault_addr >> 16); // fault addr
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), ssw); // ssw
break;