doexcstack();
}
+void exception3_read_opcode(uae_u32 opcode, uae_u32 addr, int size, int fc)
+{
+ 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)
+{
+ add_memory_cycles(1);
+ exception3_write(opcode, addr, size, val, fc);
+
+}
+
+uae_u16 exception3_word_read(uaecptr addr)
+{
+ add_memory_cycles(1);
+ return 0;
+}
+
void REGPARAM2 Exception(int n)
{
test_exception = n;
*isconstant = 0;
else
*isconstant = -1;
+ } else if (dp->mnemo == i_BSR || dp->mnemo == i_DBcc || dp->mnemo == i_Bcc ||
+ dp->mnemo == i_ORSR || dp->mnemo == i_ANDSR || dp->mnemo == i_EORSR) {
+ // don't try to test all 65536 possibilies..
+ uae_u16 i16 = imm16_cnt;
+ put_word_test(pc, imm16_cnt);
+ imm16_cnt += rand16() & 127;
+ if (i16 > imm16_cnt)
+ *isconstant = 0;
+ else
+ *isconstant = -1;
} else {
put_word_test(pc, imm16_cnt++);
if (imm16_cnt == 0)
if (test_exception != 3) {
skipped = 1;
}
- // need also extra exception
- if (!exception_extra_frame_type) {
- skipped = 1;
- }
}
if (cpu_stopped) {
safe_memory_end = 0xffffffff;
if (ini_getvalx(ini, sections, _T("feature_safe_memory_size"), &v))
safe_memory_end = safe_memory_start + v;
- safe_memory_mode = 7;
+ safe_memory_mode = 0;
if (ini_getstringx(ini, sections, _T("feature_safe_memory_mode"), &vs)) {
- safe_memory_mode = 0;
if (_totupper(vs[0]) == 'R')
safe_memory_mode |= 1;
if (_totupper(vs[0]) == 'W')
}
if (i == 2) {
target_ea_opcode_max = cnt;
- safe_memory_mode = 7;
+ if (cnt > 0) {
+ safe_memory_mode = 7;
+ }
} else if (i) {
target_ea_dst_max = cnt;
} else {
}
if (!_tcsicmp(mode, _T("branch")) || !_tcsicmp(mode, _T("branchj")) || !_tcsicmp(mode, _T("branchs"))) {
+
static const TCHAR *branchs[] = {
_T("RTS"), _T("RTD"), _T("RTR"), _T("RTE"), _T("JSR"), _T("BSR"), NULL
};
test_mnemo_text(path, branchs[i]);
}
}
+ break;
}
if (!_tcsicmp(mode, _T("fall"))) {
strcpy(g_srcname, name);
}
- if (mode >= Ad16) {
+ if (mode >= Ad16 && mode < am_unknown) {
do_instruction_buserror();
}
if (cpu_level == 1) {
int bus_error_reg_add_old = bus_error_reg_add;
- // 68010 does dummy access
- if (getv != 2) {
- if ((flags & GF_REVERSE) && size == sz_long) {
- out("uae_s16 d_%s = %s((%sa + 2) & ~1);\n", name, srcw, name);
- } else {
- out("uae_s16 d_%s = %s(%sa & ~1);\n", name, srcw, name);
- }
- }
if (abs(bus_error_reg_add) == 4)
bus_error_reg_add = 0;
// 68010 CLR <memory>: pre and post are not added yet
if (exp3rw) {
const char *shift = (size == sz_long && !(flags & GF_REVERSE)) ? " >> 16" : "";
- out("exception3_write(opcode, %sa, %d, %s%s, %d);\n",
+ out("exception3_write_opcode(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, %sa, %d, %d);\n",
+ 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);
out("opcode |= 0x00020000;\n");
}
out("uaecptr srcav = srca;\n");
- if (cpu_level == 1) {
- out("uae_s16 dummy = %s(srca & ~1);\n", srcw);
- }
}
if (write) {
- out("exception3_write(opcode, srca, %d, srcav, %d);\n",
+ out("exception3_write_opcode(opcode, srca, %d, srcav, %d);\n",
g_instr->size,
(g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
} else {
- out("exception3_read(opcode, srca, %d, %d);\n",
+ out("exception3_read_opcode(opcode, srca, %d, %d);\n",
g_instr->size,
(g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
}
}
if (cpu_level == 0) {
// 68000
- // Read SR, Read PC high, Read PC low.
- genamode(NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
- genamode(NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
+ // Read SR (SP+=6), Read PC high, Read PC low.
out("uaecptr oldpc = %s;\n", getpc);
+ out("uaecptr a = m68k_areg(regs, 7);\n");
+ out("uae_u16 sr = %s(a);\n", srcw);
+ count_read++;
+ check_bus_error("", 0, 0, 1, NULL, 1);
+
+ out("m68k_areg(regs, 7) += 6;\n");
+
+ out("uae_u32 pc = %s(a + 2) << 16;\n", srcw);
+ count_read++;
+ check_bus_error("", 2, 0, 1, NULL, 1);
+ out("pc |= %s(a + 2 + 2); \n", srcw);
+ count_read++;
+ check_bus_error("", 4, 0, 1, NULL, 1);
+
out("uae_u16 oldt1 = regs.t1;\n");
out("regs.sr = sr;\n");
makefromsr();
}
break;
case i_RTR:
+ if (cpu_level <= 1 && using_exception_3) {
+ // RTR (and RTS) exception3 does not have normal 4 cycle delay
+ out("if (m68k_areg(regs, 7) & 1) {\n");
+ out("exception3_read(opcode, m68k_areg(regs, 7), 1, 1);\n");
+ write_return_cycles(0);
+ out("}\n");
+ }
out("uaecptr oldpc = %s;\n", getpc);
out("MakeSR();\n");
genamode(NULL, Aipi, "7", sz_word, "sr", 1, 0, 0);
Address/Bus Error:
+- [memory access causing bus/address error]
- 8 idle cycles
- write PC low word
- write SR
if (nr == 7) // TRAPV
start = 0;
else if (nr == 2 || nr == 3)
- start = 4 + 8;
+ start = 8;
}
if (start)
uae_u16 mode = (sv ? 4 : 0) | last_fc_for_exception_3;
mode |= last_writeaccess_for_exception_3 ? 0 : 16;
mode |= last_notinstruction_for_exception_3 ? 8 : 0;
- // undocumented bits seem to contain opcode
+ // undocumented bits contain opcode
mode |= last_op_for_exception_3 & ~31;
m68k_areg(regs, 7) -= 14;
exception_in_exception = -1;
{
exception3f(opcode, addr, false, 0, false, 0xffffffff, size, false, fc);
}
+
+// Some hardware accepts address error aborted reads or writes as normal reads/writes.
+void exception3_read_opcode(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)
+{
+ x_do_cycles(4 * cpucycleunit);
+ exception3_write(opcode, addr, size, val, fc);
+}
+
void exception3_read(uae_u32 opcode, uaecptr addr, int size, int fc)
{
bool ni = false;