static int test_exception_3_w;
static int test_exception_3_fc;
static int test_exception_3_size;
-static int test_exception_3_value;
static int test_exception_3_di;
static int test_exception_opcode;
static int test_memory_accessed;
static uae_u16 extra_or, extra_and;
static uae_u32 cur_registers[MAX_REGISTERS];
-static uae_u32 test_last_read, test_last_write;
struct uae_prefs currprefs;
if (cpu_lvl < 2)
o -= 2;
regs.irc = get_iword_test(m68k_getpci() + o + 2);
- test_last_read = regs.irc;
+ regs.read_buffer = regs.irc;
return get_iword_test(m68k_getpci() + o);
}
ah->oldval = *p;
ah->size = sz_byte;
}
- test_last_write = v;
+ regs.write_buffer = v;
*p = v;
}
void put_word_test(uaecptr addr, uae_u32 v)
p[0] = v >> 8;
p[1] = v & 0xff;
}
- test_last_write = v;
+ regs.write_buffer = v;
}
void put_long_test(uaecptr addr, uae_u32 v)
{
p[2] = v >> 8;
p[3] = v >> 0;
}
- test_last_write = v;
+ regs.write_buffer = v;
}
static void undo_memory(struct accesshistory *ahp, int *cntp)
{
check_bus_error(addr, 0, regs.s ? 5 : 1);
uae_u8 *p = get_addr(addr, 1, 0);
- test_last_read = *p;
+ regs.read_buffer = *p;
return *p;
}
uae_u32 get_word_test(uaecptr addr)
uae_u8 *p = get_addr(addr, 2, 0);
v = (p[0] << 8) | (p[1]);
}
- test_last_read = v;
+ regs.read_buffer = v;
return v;
}
uae_u32 get_long_test(uaecptr addr)
uae_u8 *p = get_addr(addr, 4, 0);
v = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]);
}
- test_last_read = v;
+ regs.read_buffer = v;
return v;
}
ssw |= (test_exception_opcode & 0x10000) ? 0x0400 : 0x0000; // HB
ssw |= test_exception_3_size == 0 ? 0x0200 : 0x0000; // BY
ssw |= test_exception_3_w ? 0x0000 : 0x0100; // RW
+ if (test_exception_opcode & 0x20000)
+ ssw &= 0x00ff;
regs.mmu_fault_addr = test_exception_addr;
- regs.mmu_effective_addr = test_exception_3_value;
- regs.mmu_effective_addr = (test_last_read & 0xffff) | ((test_last_write & 0xffff) << 16);
Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x08);
} else {
Exception_build_stack_frame_common(regs.instruction_pc, regs.pc, 0, test_exception);
void exception2_fetch(uae_u32 opcode, uaecptr addr)
{
test_exception = 2;
- test_exception_3_w = 0;
+ test_exception_3_w = 1;
test_exception_addr = addr;
test_exception_opcode = opcode;
test_exception_3_fc = 2;
test_exception_opcode = opcode;
test_exception_3_fc = fc;
test_exception_3_size = size;
- test_exception_3_value = val;
+ regs.write_buffer = val;
test_exception_3_di = 1;
doexcstack();
}
test_exception_opcode = opcode;
test_exception_3_fc = fc;
test_exception_3_size = size;
- test_exception_3_value = val;
+ regs.write_buffer = val;
test_exception_3_di = 1;
doexcstack();
}
testing_active = 1;
testing_active_opcode = opc;
cpu_bus_error = 0;
- test_last_read = regs.irc;
- test_last_write = 0xf00d;
+ regs.read_buffer = regs.irc;
+ regs.write_buffer = 0xf00d;
int cnt = feature_loop_mode * 2;
if (multi_mode)
fc = 2;
}
+ if (cpu_level == 1 && g_instr->mnemo == i_MVSR2 && !write) {
+ printf("\t\topcode |= 0x20000;\n"); // upper byte of SSW is zero -flag.
+ }
+
// 68010 bus/address error HB bit
if (extra && cpu_level == 1)
printf("\t\topcode |= 0x%x;\n", extra);
}
// check possible address error (if 68000/010 and enabled)
- if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte && !movem) {
+ if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && getv != 3 && size != sz_byte && !movem) {
int setapdiback = 0;
int fcmodeflags = 0;
int exp3rw = getv == 2;
if (cpu_level == 1) {
if (bus_error_reg_add == 4)
bus_error_reg_add = 0;
+ // 68010 CLR <memory>: pre and post are not added yet
+ if (g_instr->mnemo == i_CLR) {
+ if (mode == Aipi)
+ bus_error_reg_add = 0;
+ if (mode == Apdi)
+ bus_error_reg_add = 0;
+ }
do_bus_error_fixes(name, 0);
// x,-(an): an is modified
- if (mode == Apdi && g_instr->size == sz_word) {
+ if (mode == Apdi && g_instr->size == sz_word && g_instr->mnemo != i_CLR) {
printf("\t\tm68k_areg (regs, %s) = %sa;\n", reg, name);
}
}
// If MOVE from SR generates address error exception,
// Change it to read because it does dummy read first.
exp3rw = 0;
+ if (cpu_level == 1) {
+ printf("\t\topcode |= 0x20000;\n"); // upper byte of SSW is zero -flag.
+ }
}
if (setapdiback) {
break;
case i_CLR:
next_level_000 ();
- genamode (curi, curi->smode, "srcreg", curi->size, "src", cpu_level == 0 ? 1 : 2, 0, 0);
- fill_prefetch_next ();
- if (isreg (curi->smode) && curi->size == sz_long)
- addcycles000 (2);
- genflags (flag_logical, curi->size, "0", "", "");
- genastore_rev ("0", curi->smode, "srcreg", curi->size, "src");
+ if (cpu_level == 0) {
+ genamode(curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
+ fill_prefetch_next();
+ if (isreg(curi->smode) && curi->size == sz_long)
+ addcycles000(2);
+ genflags(flag_logical, curi->size, "0", "", "");
+ genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+ } else if (cpu_level == 1) {
+ genamode(curi, curi->smode, "srcreg", curi->size, "src", 3, 0, 0);
+ if (isreg(curi->smode) && curi->size == sz_long)
+ addcycles000(2);
+ if (!isreg(curi->smode) && using_exception_3 && (using_prefetch || using_ce)) {
+ printf("\tif(srca & 1) {\n");
+ printf("\t\texception3_write(opcode, srca, 1, 0, 1);\n");
+ printf("\t\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
+ need_endlabel = 1;
+ }
+ genflags(flag_logical, curi->size, "0", "", "");
+ genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+ fill_prefetch_next();
+ } else {
+ genamode(curi, curi->smode, "srcreg", curi->size, "src", 2, 0, 0);
+ fill_prefetch_next();
+ if (isreg(curi->smode) && curi->size == sz_long)
+ addcycles000(2);
+ genflags(flag_logical, curi->size, "0", "", "");
+ genastore_rev("0", curi->smode, "srcreg", curi->size, "src");
+ }
break;
case i_NOT:
genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, GF_RMW);
}
break;
case i_MVSR2: // MOVE FROM SR
- genamode (curi, curi->smode, "srcreg", sz_word, "src", 2, 0, 0);
+ genamode (curi, curi->smode, "srcreg", sz_word, "src", cpu_level == 0 ? 2 : 3, 0, 0);
if (isreg (curi->smode)) {
fill_prefetch_next ();
addcycles000 (2);
} else {
- // read first and ignore result
- if (cpu_level <= 1 && curi->size == sz_word) {
+ // 68000: read first and ignore result
+ if (cpu_level == 0 && curi->size == sz_word) {
printf("\t%s (srca);\n", srcw);
check_bus_error("src", 0, 0, 1, NULL, 1);
count_write++;
fill_prefetch_next ();
}
printf ("\tMakeSR ();\n");
+ if (!isreg(curi->smode) && cpu_level == 1 && using_exception_3 && (using_prefetch || using_ce)) {
+ printf("\tif(srca & 1) {\n");
+ printf("\t\texception3_write(opcode, srca, 1, regs.sr, 1);\n");
+ printf("\t\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
+ need_endlabel = 1;
+ }
// real write
if (curi->size == sz_byte)
genastore ("regs.sr & 0xff", curi->smode, "srcreg", sz_word, "src");
printf("\t%s(dsta + 2, nextpc);\n", dstw);
check_bus_error("dst", 2, 1, 1, "nextpc", 1);
} else {
- printf("\t%s(m68k_areg(regs, 7), nextpc);\n", dstl);
+ if (cpu_level < 4)
+ printf("\t%s(m68k_areg(regs, 7), nextpc);\n", dstl);
+ else
+ printf("\t%s(m68k_areg(regs, 7) - 4, nextpc);\n", dstl);
}
if (cpu_level >= 4)
printf("\tm68k_areg (regs, 7) -= 4;\n");
uae_u32 chipset_latch_rw;
uae_u32 chipset_latch_read;
uae_u32 chipset_latch_write;
+ uae_u16 write_buffer, read_buffer;
uaecptr usp, isp, msp;
uae_u16 sr;
static int last_fc_for_exception_3;
/* Data (1) or instruction fetch (0) */
static int last_di_for_exception_3;
-/* Value */
-static int last_value_for_exception_3;
/* not instruction */
static bool last_notinstruction_for_exception_3;
/* set when writing exception stack frame */
ssw |= (last_op_for_exception_3 & 0x10000) ? 0x0400 : 0x0000; // HB
ssw |= last_size_for_exception_3 == 0 ? 0x0200 : 0x0000; // BY
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x0100; // RW
+ if (last_op_for_exception_3 & 0x20000)
+ ssw &= 0x00ff;
m68k_areg(regs, 7) -= 50;
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_addr_for_exception_3); // fault addr
x_put_word(m68k_areg(regs, 7) + 6, 0); // unused
- x_put_word(m68k_areg(regs, 7) + 8, last_value_for_exception_3); // data output buffer
+ x_put_word(m68k_areg(regs, 7) + 8, regs.write_buffer); // data output buffer
x_put_word(m68k_areg(regs, 7) + 10, 0); // unused
- x_put_word(m68k_areg(regs, 7) + 12, 0); // data input buffer
+ x_put_word(m68k_areg(regs, 7) + 12, regs.read_buffer); // data input buffer
x_put_word(m68k_areg(regs, 7) + 14, 0); // unused
x_put_word(m68k_areg(regs, 7) + 16, last_op_for_exception_3); // instruction input buffer
x_put_word(m68k_areg(regs, 7) + 18, 0); // version
ssw |= (last_op_for_exception_3 & 0x10000) ? 0x0400 : 0x0000; // HB
ssw |= last_size_for_exception_3 == 0 ? 0x0200 : 0x0000; // BY
ssw |= last_writeaccess_for_exception_3 ? 0x0000 : 0x0100; // RW
+ if (last_op_for_exception_3 & 0x20000)
+ ssw &= 0x00ff;
regs.mmu_fault_addr = last_addr_for_exception_3;
- regs.mmu_effective_addr = last_value_for_exception_3;
Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08);
used_exception_build_stack_frame = true;
}
void exception3_write(uae_u32 opcode, uaecptr addr, int size, uae_u32 val, int fc)
{
exception3f (opcode, addr, true, 0, false, 0xffffffff, size, false, fc);
+ regs.write_buffer = val;
}
void exception3i (uae_u32 opcode, uaecptr addr)
{
{
exception2_setup(addr, false, size, fc);
last_op_for_exception_3 = opcode;
+ regs.write_buffer = val;
Exception(2);
}
x_put_long(m68k_areg(regs, 7), regs.mmu_effective_addr);
break;
case 0x8: // address error (68010)
+ {
+ uae_u16 in = regs.read_buffer;
+ uae_u16 out = regs.write_buffer;
for (i = 0; i < 15; i++) {
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), 0);
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), 0); // unused
m68k_areg(regs, 7) -= 2;
- x_put_word(m68k_areg(regs, 7), regs.mmu_effective_addr); // data input buffer
+ 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
m68k_areg(regs, 7) -= 2;
- x_put_word(m68k_areg(regs, 7), regs.mmu_effective_addr >> 16); // data output buffer
+ 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;
m68k_areg(regs, 7) -= 2;
x_put_word(m68k_areg(regs, 7), ssw); // ssw
break;
+ }
case 0x9: // coprocessor mid-instruction stack frame (68020, 68030)
m68k_areg(regs, 7) -= 4;
x_put_long(m68k_areg(regs, 7), regs.fp_ea);