addop_ce020 (curi, 0);
next_level_000 ();
if (cpu_level == 0) {
+ // 68000
genamode (NULL, Aipi, "7", sz_word, "sr", 1, 0, GF_NOREFILL);
genamode (NULL, Aipi, "7", sz_long, "pc", 1, 0, GF_NOREFILL);
printf("\tuaecptr oldpc = %s;\n", getpc);
printf("\tbranch_stack_pop_rte(oldpc);\n");
makefromsr();
} else if (cpu_level == 1 && using_prefetch) {
- int old_brace_level = n_braces;
+ // 68010
+ int old_brace_level = n_braces;
printf("\tuaecptr oldpc = %s;\n", getpc);
printf ("\tuae_u16 newsr; uae_u32 newpc;\n");
printf ("\tfor (;;) {\n");
printf ("\t\tnewsr = sr; newpc = pc;\n");
printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n");
printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n");
- printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception_cpu(14); goto %s; }\n", endlabelstr);
+ printf ("\t\telse { Exception_cpu(14); goto %s; }\n", endlabelstr);
printf ("\t\tregs.sr = newsr; MakeFromSR ();\n}\n");
pop_braces (old_brace_level);
printf ("\tregs.sr = newsr;\n");
printf ("\t\tnewsr = sr; newpc = pc;\n");
addcycles_ce020 (6);
printf ("\t\tif (frame == 0x0) { m68k_areg (regs, 7) += offset; break; }\n");
- printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n");
- printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n");
+ if (cpu_level >= 2) {
+ // 68020+
+ printf ("\t\telse if (frame == 0x1) { m68k_areg (regs, 7) += offset; }\n");
+ printf ("\t\telse if (frame == 0x2) { m68k_areg (regs, 7) += offset + 4; break; }\n");
+ }
if (cpu_level >= 4) {
+ // 68040+
printf ("\t\telse if (frame == 0x3) { m68k_areg (regs, 7) += offset + 4; break; }\n");
}
if (using_mmu == 68060) {
printf ("\t\telse if (frame == 0x4) { m68k_do_rte_mmu060 (a); m68k_areg (regs, 7) += offset + 8; break; }\n");
} else if (cpu_level >= 4) {
+ // 68040+
printf ("\t\telse if (frame == 0x4) { m68k_areg (regs, 7) += offset + 8; break; }\n");
}
- if (cpu_level == 1) // 68010 only
- printf ("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n");
+ if (cpu_level == 1) {
+ // 68010 only
+ printf("\t\telse if (frame == 0x8) { m68k_areg (regs, 7) += offset + 50; break; }\n");
+ }
if (using_mmu == 68040) {
printf ("\t\telse if (frame == 0x7) { m68k_do_rte_mmu040 (a); m68k_areg (regs, 7) += offset + 52; break; }\n");
} else if (cpu_level >= 4) {
+ // 68040+
printf ("\t\telse if (frame == 0x7) { m68k_areg (regs, 7) += offset + 52; break; }\n");
}
- if (cpu_level == 2 || cpu_level == 3) { // 68020/68030 only
+ if (cpu_level == 2 || cpu_level == 3) {
+ // 68020/68030 only
printf ("\t\telse if (frame == 0x9) { m68k_areg (regs, 7) += offset + 12; break; }\n");
if (using_mmu == 68030) {
if (using_prefetch_020) {
printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
}
}
- printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception_cpu(14); goto %s; }\n", endlabelstr);
+ printf ("\t\telse { Exception_cpu(14); goto %s; }\n", endlabelstr);
printf ("\t\tregs.sr = newsr;\n");
makefromsr_t0();
printf ("}\n");
case i_RTS:
addop_ce020 (curi, 0);
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\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
+ }
if (using_indirect > 0 && !using_ce020 && !using_prefetch_020 && !using_ce) {
printf("\tm68k_do_rtsi_jit ();\n");
} else if (using_mmu) {
printf("\tuaecptr oldpc = %s;\n", getpc);
printf("\tuaecptr nextpc = oldpc + %d;\n", m68k_pc_offset);
if (using_exception_3) {
- printf ("\tif (srca & 1) {\n");
- printf ("\t\texception3i (opcode, srca);\n");
- printf ("\t\tgoto %s;\n", endlabelstr);
- printf ("\t}\n");
+ printf("\tif (srca & 1) {\n");
+ printf("\t\texception3i (opcode, srca);\n");
+ printf("\t\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
need_endlabel = 1;
}
if (using_mmu) {
if (cpu_level <= 1 && using_prefetch)
printf ("\tnextpc += 2;\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\tgoto %s;\n", endlabelstr);
+ printf("\t}\n");
+ }
setpc ("srca");
clear_m68k_offset();
fill_prefetch_1 (0);
- printf ("\tm68k_areg (regs, 7) -= 4;\n");
if (using_ce || using_prefetch) {
printf ("\t%s (m68k_areg (regs, 7), nextpc >> 16);\n", dstw);
printf ("\t%s (m68k_areg (regs, 7) + 2, nextpc);\n", dstw);
}
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");
+ 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");
+ }
need_endlabel = 1;
}
addcycles000 (2);
int sv = regs.s;
int start, interrupt;
int vector_nr = nr;
+ int frame_id = 0;
start = 6;
interrupt = nr >= 24 && nr < 24 + 8;
cpu_halt (CPU_HALT_DOUBLE_FAULT);
return;
}
- uae_u16 mode = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
- 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;
- m68k_areg (regs, 7) -= 14;
- 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);
- x_put_word (m68k_areg (regs, 7) + 10, last_addr_for_exception_3 >> 16);
- x_put_word (m68k_areg (regs, 7) + 6, last_op_for_exception_3);
- x_put_word (m68k_areg (regs, 7) + 4, last_fault_for_exception_3);
- x_put_word (m68k_areg (regs, 7) + 0, mode);
- x_put_word (m68k_areg (regs, 7) + 2, last_fault_for_exception_3 >> 16);
- x_do_cycles (2 * cpucycleunit);
- write_log (_T("Exception %d (%04x %x) at %x -> %x!\n"),
- nr, last_op_for_exception_3, last_addr_for_exception_3, currpc, get_long_debug (4 * nr));
- goto kludge_me_do;
+ write_log(_T("Exception %d (%04x %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);
+ 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;
+ m68k_areg(regs, 7) -= 14;
+ 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);
+ x_put_word(m68k_areg(regs, 7) + 10, last_addr_for_exception_3 >> 16);
+ x_put_word(m68k_areg(regs, 7) + 6, last_op_for_exception_3);
+ x_put_word(m68k_areg(regs, 7) + 4, last_fault_for_exception_3);
+ x_put_word(m68k_areg(regs, 7) + 0, mode);
+ x_put_word(m68k_areg(regs, 7) + 2, last_fault_for_exception_3 >> 16);
+ x_do_cycles(2 * cpucycleunit);
+ goto kludge_me_do;
+ } else {
+ // 68010 address error (partially implemented only)
+ uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100;
+ ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000;
+ 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, 0); // 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) + 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
+ for (int i = 0; i < 15; i++) {
+ x_put_word(m68k_areg(regs, 7) + 20 + i * 2, 0);
+ }
+ }
}
if (currprefs.cpu_model == 68010) {
// 68010 creates only format 0 and 8 stack frames
vector_nr = iack_cycle(nr);
x_put_word (m68k_areg (regs, 7) + 0, regs.sr); // write SR
x_put_word (m68k_areg (regs, 7) + 2, currpc >> 16); // write high address
- x_put_word (m68k_areg (regs, 7) + 6, vector_nr * 4);
+ x_put_word (m68k_areg (regs, 7) + 6, (frame_id << 12) | (vector_nr * 4));
} else {
m68k_areg (regs, 7) -= 6;
if (m68k_areg(regs, 7) & 1) {
static void Exception_build_stack_frame_common (uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int nr)
{
if (nr == 5 || nr == 6 || nr == 7 || nr == 9) {
- Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2);
+ if (currprefs.cpu_model <= 68010)
+ Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0);
+ else
+ Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x2);
} else if (nr == 60 || nr == 61) {
Exception_build_stack_frame(oldpc, regs.instruction_pc, regs.mmu_ssw, nr, 0x0);
} else if (nr >= 48 && nr <= 55) {
m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), 0x2000 + vector_nr * 4);
}
- } else {
- // 68020 address error
+ } else if (currprefs.cpu_model >= 68020) {
+ // 68020/030 address error
uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
ssw |= last_writeaccess_for_exception_3 ? 0 : 0x40;
ssw |= 0x20;
x_put_word (m68k_areg (regs, 7), ssw);
m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), 0xb000 + vector_nr * 4);
+ } else {
+ // 68010 address error (partially implemented only)
+ uae_u16 ssw = (sv ? 4 : 0) | (last_instructionaccess_for_exception_3 ? 2 : 1);
+ ssw |= last_writeaccess_for_exception_3 ? 0 : 0x100;
+ ssw |= last_instructionaccess_for_exception_3 ? 0 : 0x2000;
+ 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); // version
+ m68k_areg(regs, 7) -= 2;
+ x_put_word(m68k_areg(regs, 7), last_op_for_exception_3); // instruction 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), 0); // 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), 0); // 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), last_addr_for_exception_3); // fault addr
+ m68k_areg(regs, 7) -= 2;
+ x_put_word(m68k_areg(regs, 7), ssw); // ssw
+ m68k_areg(regs, 7) -= 2;
+ x_put_word(m68k_areg(regs, 7), 0x8000 + vector_nr * 4);
}
write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, regs.instruction_pc, currpc, get_long_debug (regs.vbr + 4 * vector_nr));
} else if (regs.m && interrupt) { /* M + Interrupt */