static int feature_loop_mode = 0;
static int feature_loop_mode_register = -1;
static int feature_full_extension_format = 0;
+static int feature_test_rounds = 2;
static uae_u32 feature_addressing_modes[2];
static int ad8r[2], pc8r[2];
static int test_exception;
static int exception_stack_frame_size;
static uaecptr test_exception_addr;
-static int test_exception_3_inst;
static int test_exception_3_w;
+static int test_exception_3_fc;
static int test_exception_opcode;
static uae_u8 imm8_cnt;
static uae_u16 imm16_cnt;
testing_active = -1;
int opcode = (opcode_memory[0] << 8) | (opcode_memory[1]);
- int statusormask = 0, statusandmask = 0;
- if (test_exception_opcode >= 0) {
+ if (test_exception_opcode >= 0)
opcode = test_exception_opcode;
- statusormask = (test_exception_opcode >> 16) & 0xff;
- statusandmask = (test_exception_opcode >> 24) & 0xff;
- }
int sv = regs.s;
uaecptr tmp = m68k_areg(regs, 7);
m68k_areg(regs, 7) = test_memory_end + EXTRA_RESERVED_SPACE;
if (cpu_lvl == 0) {
if (test_exception == 3) {
- uae_u16 mode = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1) | statusormask;
- mode &= ~statusandmask;
+ uae_u16 mode = (sv ? 4 : 0) | test_exception_3_fc;
mode |= test_exception_3_w ? 0 : 16;
Exception_build_68000_address_error_stack_frame(mode, opcode, test_exception_addr, regs.pc);
}
} else if (cpu_lvl == 1) {
if (test_exception == 3) {
- uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1);
+ uae_u16 ssw = (sv ? 4 : 0) | test_exception_3_fc;
ssw |= test_exception_3_w ? 0 : 0x100;
- ssw |= test_exception_3_inst ? 0 : 0x2000;
+ ssw |= (test_exception_3_fc & 2) ? 0 : 0x2000;
regs.mmu_fault_addr = test_exception_addr;
Exception_build_stack_frame(regs.instruction_pc, regs.pc, ssw, 3, 0x08);
} else {
}
} else if (cpu_lvl == 2) {
if (test_exception == 3) {
- uae_u16 ssw = (sv ? 4 : 0) | (test_exception_3_inst ? 2 : 1);
+ uae_u16 ssw = (sv ? 4 : 0) | test_exception_3_fc;
ssw |= test_exception_3_w ? 0 : 0x40;
ssw |= 0x20;
regs.mmu_fault_addr = test_exception_addr;
return op_illg_1(opcode);
}
-void exception3_read(uae_u32 opcode, uae_u32 addr)
+void exception3_read(uae_u32 opcode, uae_u32 addr, int fc)
{
test_exception = 3;
- test_exception_3_inst = 0;
test_exception_3_w = 0;
test_exception_addr = addr;
test_exception_opcode = opcode;
+ test_exception_3_fc = fc;
doexcstack();
}
-void exception3_write(uae_u32 opcode, uae_u32 addr)
+void exception3_write(uae_u32 opcode, uae_u32 addr, int fc)
{
test_exception = 3;
- test_exception_3_inst = 0;
test_exception_3_w = 1;
test_exception_addr = addr;
test_exception_opcode = opcode;
+ test_exception_3_fc = fc;
doexcstack();
}
void REGPARAM2 Exception(int n)
{
test_exception = n;
- test_exception_3_inst = 0;
test_exception_addr = m68k_getpci();
test_exception_opcode = -1;
doexcstack();
void REGPARAM2 Exception_cpu(int n)
{
test_exception = n;
- test_exception_3_inst = 0;
test_exception_addr = m68k_getpci();
test_exception_opcode = -1;
void exception3i(uae_u32 opcode, uaecptr addr)
{
test_exception = 3;
- test_exception_3_inst = 1;
+ test_exception_3_fc = 2;
test_exception_3_w = 0;
test_exception_addr = addr;
test_exception_opcode = opcode;
void exception3b(uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
{
test_exception = 3;
- test_exception_3_inst = i;
+ test_exception_3_fc = i ? 2 : 1;
test_exception_3_w = w;
test_exception_addr = addr;
test_exception_opcode = opcode;
abort();
}
}
- if (last_exception_len == exception_stack_frame_size && !memcmp(sf, last_exception, exception_stack_frame_size)) {
+ if (last_exception_len > 0 && last_exception_len == exception_stack_frame_size && !memcmp(sf, last_exception, exception_stack_frame_size)) {
// stack frame was identical to previous
p = op;
*p++ = 0xff;
wprintf(_T("%s\n"), dir);
int quick = 0;
- int rounds = 4;
+ int rounds = feature_test_rounds;
int subtest_count = 0;
int count = 0;
if (regs.sr & 0x2000)
prev_s_cnt++;
- if (subtest_count == 1536)
+ if (subtest_count == 353)
printf("");
execute_ins(opc, pc - 2, branch_target);
}
}
if (test_exception == 3) {
- if (!feature_exception3_data && !test_exception_3_inst) {
+ if (!feature_exception3_data && !(test_exception_3_fc & 2)) {
skipped = 1;
}
- if (!feature_exception3_instruction && test_exception_3_inst) {
+ if (!feature_exception3_instruction && (test_exception_3_fc & 2)) {
skipped = 1;
}
} else {
// Handle special MOVE.W/.L condition codes when destination write causes address error.
-static void move_68000_address_error(amodes mode, int size, int *setapdi)
+static void move_68000_address_error(amodes mode, int size, int *setapdi, int *fcmodeflags)
{
int smode = g_instr->smode;
int dmode = g_instr->dmode;
break;
}
if (dmode == Apdi) {
- // this is buggy, address error stack frame opcode field contains next instruction opcode!
- printf("\t\topcode = regs.irc | 0x00080000;\n");
+ // this is buggy, address error stack frame opcode field contains next
+ // instruction opcode and Instruction/Not field is one!
+ printf("\t\topcode = regs.irc;\n");
+ *fcmodeflags |= 0x08; // "Not instruction" = 1
}
if (set_ccr) {
printf("\t\tccr_68000_word_move_ae_normal((uae_s16)(src));\n");
// check possible address error (if 68000/010 and enabled)
if ((using_prefetch || using_ce) && using_exception_3 && getv != 0 && size != sz_byte && !movem) {
int setapdiback = 0;
+ int fcmodeflags = 0;
printf("\tif (%sa & 1) {\n", name);
if (g_instr->mnemo == i_MOVE) {
if (getv == 2) {
- move_68000_address_error(mode, size, &setapdiback);
+ move_68000_address_error(mode, size, &setapdiback, &fcmodeflags);
}
}
printf("\t\tm68k_areg (regs, %s) = %sa;\n", reg, name);
}
- // PC-relative: FC=2
- if (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r)) {
- printf("\t\topcode |= 0x01020000;\n");
- }
-
// MOVE.L EA,-(An) causing address error: stacked value is original An - 2, not An - 4.
if ((flags & (GF_REVERSE | GF_REVERSE2)) && size == sz_long && mode == Apdi)
printf("\t\t%sa += %d;\n", name, flags & GF_REVERSE2 ? -2 : 2);
- printf("\t\texception3_%s(opcode, %sa);\n", getv == 2 ? "write" : "read", name);
+ printf("\t\texception3_%s(opcode, %sa, %d);\n",
+ getv == 2 ? "write" : "read", name,
+ // PC-relative: FC=2
+ (getv == 1 && (g_instr->smode == PC16 || g_instr->smode == PC8r) ? 2 : 1) | fcmodeflags);
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
printf("\t\topcode |= 0x01020000;\n");
}
}
- printf("\t\texception3_%s(opcode, srca);\n", write ? "write" : "read");
+ printf("\t\texception3_%s(opcode, srca, %d);\n",
+ write ? "write" : "read", (g_instr->dmode == PC16 || g_instr->dmode == PC8r) ? 2 : 1);
printf("\t\tgoto %s;\n", endlabelstr);
printf("\t}\n");
need_endlabel = 1;
printf ("\tuaecptr pc = %s;\n", getpc);
if (cpu_level <= 1 && using_exception_3) {
printf("\tif (m68k_areg(regs, 7) & 1) {\n");
- printf("\t\texception3_read(opcode, m68k_areg(regs, 7));\n");
+ printf("\t\texception3_read(opcode, m68k_areg(regs, 7), 1);\n");
printf("\t\tgoto %s;\n", endlabelstr);
printf("\t}\n");
}
printf("\tm68k_areg (regs, 7) -= 4;\n");
if (using_exception_3 && cpu_level <= 1) {
printf("\tif (m68k_areg(regs, 7) & 1) {\n");
- printf("\t\texception3_write(opcode, m68k_areg(regs, 7));\n");
+ printf("\t\texception3_write(opcode, m68k_areg(regs, 7), 1);\n");
printf("\t\tgoto %s;\n", endlabelstr);
printf("\t}\n");
}
}
printf ("\ts = (uae_s32)src + 2;\n");
if (using_exception_3) {
- printf("\tif (src & 1) {\n");
- printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
- printf("\t\tgoto %s;\n", endlabelstr);
- printf("\t}\n");
if (cpu_level <= 1) {
printf("\tif (m68k_areg(regs, 7) & 1) {\n");
printf("\t\tm68k_areg(regs, 7) -= 4;\n");
printf("\t\texception3b(opcode, m68k_areg(regs, 7), true, false, %s + 2);\n", getpc);
printf("\t\tgoto %s;\n", endlabelstr);
printf("\t}\n");
+ } else {
+ printf("\tif (src & 1) {\n");
+ printf("\t\texception3b(opcode, %s + s, 0, 1, %s + s);\n", getpc, getpc);
+ printf("\t\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
}
need_endlabel = 1;
}
} else {
printf ("\tm68k_do_bsr (nextpc, s);\n");
}
+ if (using_exception_3 && cpu_level <= 1) {
+ printf("\tif (%s & 1) {\n", getpc);
+ printf("\t\texception3b(opcode, %s, 0, 1, %s);\n", getpc, getpc);
+ printf("\t\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
+ }
if (using_debugmem) {
printf("\tif (debugmem_trace)\n");
printf("\t\tbranch_stack_push(oldpc, nextpc);\n");
addcycles000 (2);
push_ins_cnt();
printf ("\tif (!cctrue (%d)) {\n", curi->cc);
+ printf("\t");
incpc ("(uae_s32)offs + 2");
printf ("\t");
- fill_prefetch_1 (0);
- printf ("\t");
- genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src");
-
- printf ("\t\tif (src) {\n");
if (using_exception_3) {
- printf ("\t\t\tif (offs & 1) {\n");
- printf ("\t\t\t\texception3i (opcode, %s + 2 + (uae_s32)offs + 2);\n", getpc);
- printf ("\t\t\t\tgoto %s;\n", endlabelstr);
- printf ("\t\t\t}\n");
+ printf("\tif (offs & 1) {\n");
+ printf("\t\t\texception3i (opcode, %s);\n", getpc);
+ printf("\t\t\tgoto %s;\n", endlabelstr);
+ printf("\t\t}\n");
need_endlabel = 1;
}
+ printf("\t");
+ fill_prefetch_1(0);
+ printf("\t");
+ genastore ("(src - 1)", curi->smode, "srcreg", curi->size, "src");
+ printf ("\t\tif (src) {\n");
irc2ir ();
add_head_cycs (6);
fill_prefetch_1 (2);
extern bool fpu_get_constant(fpdata *fp, int cr);
extern int fpp_cond(int condition);
-extern void exception3_read(uae_u32 opcode, uaecptr addr);
-extern void exception3_write(uae_u32 opcode, uaecptr addr);
+extern void exception3_read(uae_u32 opcode, uaecptr addr, int fc);
+extern void exception3_write(uae_u32 opcode, uaecptr addr, int fc);
extern void exception3_notinstruction(uae_u32 opcode, uaecptr addr);
extern void exception3i (uae_u32 opcode, uaecptr addr);
extern void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc);
static uaecptr last_fault_for_exception_3;
/* read (0) or write (1) access */
static bool last_writeaccess_for_exception_3;
-/* instruction (1) or data (0) access */
-static bool last_instructionaccess_for_exception_3;
+/* FC */
+static int last_fc_for_exception_3;
/* not instruction */
static bool last_notinstruction_for_exception_3;
/* set when writing exception stack frame */
write_log(_T("Exception %d (%08x %x) at %x -> %x!\n"),
nr, last_op_for_exception_3, last_addr_for_exception_3, currpc, get_long_debug(4 * nr));
if (currprefs.cpu_model == 68000) {
- uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ 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
mode |= last_op_for_exception_3 & ~31;
- uae_u16 statusormask = (last_op_for_exception_3 >> 16) & 0xff;
- uae_u16 statusandmask = (last_op_for_exception_3 >> 24) & 0xff;
- mode |= statusormask;
- mode &= ~statusandmask;
m68k_areg(regs, 7) -= 14;
exception_in_exception = -1;
x_put_word(m68k_areg(regs, 7) + 12, last_addr_for_exception_3);
goto kludge_me_do;
} else {
// 68010 address error (partially implemented only)
- uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3;
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100;
- ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000;
+ ssw |= (last_fc_for_exception_3 & 2) ? 0 : 0x2000;
m68k_areg(regs, 7) -= 50;
exception_in_exception = -1;
frame_id = 8;
if (nr == 2 || nr == 3)
cpu_halt (CPU_HALT_DOUBLE_FAULT);
else
- exception3_read(regs.ir, newpc);
+ exception3_read(regs.ir, newpc, 1);
return;
}
if (interrupt)
if (nr == 2 || nr == 3)
cpu_halt (CPU_HALT_DOUBLE_FAULT);
else
- exception3_read(regs.ir, newpc);
+ exception3_read(regs.ir, newpc, 1);
return;
}
if (nr == 2 || nr == 3)
cpu_halt (CPU_HALT_DOUBLE_FAULT);
else
- exception3_read(regs.ir, newpc);
+ exception3_read(regs.ir, newpc, 1);
return;
}
m68k_setpc (newpc);
}
} else if (currprefs.cpu_model >= 68020) {
// 68020/030 odd PC address error (partially implemented only)
- uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3;
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
ssw |= 0x20;
regs.mmu_fault_addr = last_fault_for_exception_3;
used_exception_build_stack_frame = true;
} else {
// 68010 address error (partially implemented only)
- uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ uae_u16 ssw = (sv ? 4 : 0) | last_fc_for_exception_3;
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100;
- ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000;
+ ssw |= (last_fc_for_exception_3 & 2) ? 0 : 0x2000;
regs.mmu_fault_addr = last_addr_for_exception_3;
Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08);
used_exception_build_stack_frame = true;
nextpc = m68k_getpc ();
if (nr == 2 || nr == 3) {
// 68000 bus error/address error
- uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ 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;
- uae_u16 statusormask = (last_op_for_exception_3 >> 16) & 0xff;
- uae_u16 statusandmask = (last_op_for_exception_3 >> 24) & 0xff;
- mode |= statusormask;
- mode &= ~statusandmask;
exception_in_exception = -1;
Exception_build_68000_address_error_stack_frame(mode, last_op_for_exception_3, last_fault_for_exception_3, last_addr_for_exception_3);
write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long_debug (regs.vbr + 4 * vector_nr));
last_addr_for_exception_3 = addr;
last_fault_for_exception_3 = fault;
last_writeaccess_for_exception_3 = 0;
- last_instructionaccess_for_exception_3 = 0;
+ last_fc_for_exception_3 = 0;
Exception (2);
}
#endif
#endif /* SAVESTATE */
-static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool instructionaccess, bool notinstruction, uaecptr pc, bool plus2)
+static void exception3f (uae_u32 opcode, uaecptr addr, bool writeaccess, bool instructionaccess, bool notinstruction, uaecptr pc, bool plus2, int fc)
{
if (currprefs.cpu_model >= 68040)
addr &= ~1;
last_fault_for_exception_3 = addr;
last_op_for_exception_3 = opcode;
last_writeaccess_for_exception_3 = writeaccess;
- last_instructionaccess_for_exception_3 = instructionaccess;
+ last_fc_for_exception_3 = fc >= 0 ? fc : (instructionaccess ? 2 : 1);
last_notinstruction_for_exception_3 = notinstruction;
Exception (3);
#if EXCEPTION3_DEBUGGER
void exception3_notinstruction(uae_u32 opcode, uaecptr addr)
{
- exception3f (opcode, addr, true, false, true, 0xffffffff, false);
+ exception3f (opcode, addr, true, false, true, 0xffffffff, false, -1);
}
-void exception3_read(uae_u32 opcode, uaecptr addr)
+void exception3_read(uae_u32 opcode, uaecptr addr, int fc)
{
- exception3f (opcode, addr, false, 0, false, 0xffffffff, false);
+ exception3f (opcode, addr, false, 0, false, 0xffffffff, false, fc);
}
-void exception3_write(uae_u32 opcode, uaecptr addr)
+void exception3_write(uae_u32 opcode, uaecptr addr, int fc)
{
- exception3f (opcode, addr, true, 0, false, 0xffffffff, false);
+ exception3f (opcode, addr, true, 0, false, 0xffffffff, false, fc);
}
void exception3i (uae_u32 opcode, uaecptr addr)
{
- exception3f (opcode, addr, 0, 1, false, 0xffffffff, true);
+ exception3f (opcode, addr, 0, 1, false, 0xffffffff, true, -1);
}
void exception3b (uae_u32 opcode, uaecptr addr, bool w, bool i, uaecptr pc)
{
- exception3f (opcode, addr, w, i, false, pc, true);
+ exception3f (opcode, addr, w, i, false, pc, true, -1);
}
void exception2_setup(uaecptr addr, bool read, int size, uae_u32 fc)
last_addr_for_exception_3 = m68k_getpc() + bus_error_offset;
last_fault_for_exception_3 = addr;
last_writeaccess_for_exception_3 = read == 0;
- last_instructionaccess_for_exception_3 = (fc & 1) == 0;
+ last_fc_for_exception_3 = fc;
last_op_for_exception_3 = regs.opcode;
last_notinstruction_for_exception_3 = exception_in_exception != 0;
}