return buffer;
}
-static void makefromsr (void)
+static void makefromsr(void)
{
printf ("\tMakeFromSR();\n");
if (using_ce || isce020())
printf ("\tregs.ipl_pin = intlev ();\n");
}
+static void makefromsr_t0(void)
+{
+ printf ("\tMakeFromSR_T0();\n");
+ if (using_ce || isce020())
+ printf ("\tregs.ipl_pin = intlev ();\n");
+}
+
static void check_ipl (void)
{
if (ipl_fetched)
}
}
+static void fill_prefetch_full_2 (void)
+{
+ if (using_prefetch) {
+ fill_prefetch_1 (0);
+ irc2ir ();
+ fill_prefetch_1 (2);
+ } else if (isprefetch020()) {
+ did_prefetch = 2;
+ total_ce020 -= 4;
+ returntail (false);
+ if (cpu_level >= 3)
+ printf ("\tfill_prefetch_030();\n");
+ else if (cpu_level == 2)
+ printf ("\tfill_prefetch_020();\n");
+ }
+}
+
+// don't check trace bits
+static void fill_prefetch_full_ntx (void)
+{
+ if (using_prefetch) {
+ fill_prefetch_1 (0);
+ irc2ir ();
+ fill_prefetch_1 (2);
+ } else if (isprefetch020()) {
+ did_prefetch = 2;
+ total_ce020 -= 4;
+ returntail (false);
+ if (cpu_level >= 3)
+ printf ("\tfill_prefetch_030_ntx();\n");
+ else if (cpu_level == 2)
+ printf ("\tfill_prefetch_020_ntx();\n");
+ }
+}
+// check trace bits
static void fill_prefetch_full (void)
{
if (using_prefetch) {
total_ce020 -= 4;
returntail (false);
if (cpu_level >= 3)
- printf ("\tfill_prefetch_030 ();\n");
+ printf ("\tfill_prefetch_030();\n");
else if (cpu_level == 2)
- printf ("\tfill_prefetch_020 ();\n");
+ printf ("\tfill_prefetch_020();\n");
+ } else if (!using_prefetch_020 && cpu_level >= 2) {
+ printf("\tif(regs.t0) check_t0_trace();\n");
}
}
// 68020+
static void fill_prefetch_full_020 (void)
{
- if (!using_prefetch_020)
+ if (!using_prefetch_020) {
+ printf("\tif(regs.t0) check_t0_trace();\n");
return;
+ }
fill_prefetch_full ();
}
printf ("\tsrc &= 0xFF;\n");
}
addcycles000 (8);
- if (cpu_level <= 1) {
- sync_m68k_pc ();
- fill_prefetch_full ();
- } else {
- fill_prefetch_next ();
- }
printf ("\tregs.sr %c= src;\n", curi->mnemo == i_EORSR ? '^' : '|');
- makefromsr ();
+ makefromsr_t0();
+ sync_m68k_pc ();
+ fill_prefetch_full_ntx();
break;
case i_ANDSR:
printf ("\tMakeSR ();\n");
printf ("\tsrc |= 0xFF00;\n");
}
addcycles000 (8);
- if (cpu_level <= 1) {
- sync_m68k_pc ();
- fill_prefetch_full ();
- } else {
- fill_prefetch_next ();
- }
printf ("\tregs.sr &= src;\n");
- makefromsr ();
+ makefromsr_t0();
+ sync_m68k_pc ();
+ fill_prefetch_full_ntx();
break;
case i_SUB:
{
addcycles000 (4);
printf ("\tregs.sr = src;\n");
}
- makefromsr ();
- if (cpu_level <= 1) {
- // 68000 does 2xprefetch
- sync_m68k_pc ();
- fill_prefetch_full ();
- } else {
- fill_prefetch_next ();
- }
+ makefromsr_t0();
+ // does full prefetch because S-bit change may change memory mapping under the CPU
+ sync_m68k_pc ();
+ fill_prefetch_full_ntx();
break;
case i_SWAP:
genamode (curi, curi->smode, "srcreg", sz_long, "src", 1, 0, 0);
genamode (curi, curi->smode, "srcreg", curi->size, "src", 1, 0, 0);
gen_set_fault_pc ();
sync_m68k_pc ();
- printf ("\tException (src + 32);\n");
+ printf ("\tException_cpu(src + 32);\n");
did_prefetch = 1;
clear_m68k_offset();
break;
printf ("\tregs.sr = src;\n");
}
addcycles000(2 * 4);
- makefromsr ();
+ makefromsr();
printf ("\tm68k_setstopped ();\n");
sync_m68k_pc ();
// STOP does not prefetch anything
printf ("\tsr = %s (4);\n", srcwi);
printf ("\tif (!(sr & 0x8000)) { Exception (8); goto %s; }\n", endlabelstr);
printf ("\tregs.sr = sr;\n");
- makefromsr ();
+ makefromsr();
printf ("\tm68k_setstopped();\n");
m68k_pc_offset += 4;
sync_m68k_pc ();
- fill_prefetch_full ();
+ fill_prefetch_full_ntx();
break;
case i_RTE:
addop_ce020 (curi, 0);
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
setpc ("pc");
- makefromsr ();
+ makefromsr();
} else if (cpu_level == 1 && using_prefetch) {
int old_brace_level = n_braces;
printf ("\tuae_u16 newsr; uae_u32 newpc;\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 (14); goto %s; }\n", endlabelstr);
+ printf ("\t\telse { m68k_areg (regs, 7) += offset; 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");
- makefromsr ();
+ makefromsr();
printf ("\tif (newpc & 1) {\n");
printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t\telse if (frame == 0xa) { m68k_areg (regs, 7) += offset + 24; break; }\n");
printf ("\t\telse if (frame == 0xb) { m68k_areg (regs, 7) += offset + 84; break; }\n");
}
- printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception (14); goto %s; }\n", endlabelstr);
+ printf ("\t\telse { m68k_areg (regs, 7) += offset; Exception_cpu(14); goto %s; }\n", endlabelstr);
printf ("\t\tregs.sr = newsr;\n");
- makefromsr ();
+ makefromsr_t0();
printf ("}\n");
pop_braces (old_brace_level);
printf ("\tregs.sr = newsr;\n");
addcycles_ce020 (4);
- makefromsr ();
+ makefromsr_t0();
printf ("\tif (newpc & 1) {\n");
printf ("\t\texception3i (0x%04X, newpc);\n", opcode);
printf ("\t\tgoto %s;\n", endlabelstr);
/* PC is set and prefetch filled. */
clear_m68k_offset();
tail_ce020_done = true;
- fill_prefetch_full ();
+ fill_prefetch_full_ntx();
branch_inst = 1;
break;
case i_RTD:
sync_m68k_pc ();
fill_prefetch_next ();
printf ("\tif (GET_VFLG ()) {\n");
- printf ("\t\tException (7);\n");
+ printf ("\t\tException_cpu(7);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
need_endlabel = 1;
printf ("\tregs.sr &= 0xFF00; sr &= 0xFF;\n");
printf ("\tregs.sr |= sr;\n");
setpc ("pc");
- makefromsr ();
+ makefromsr();
printf ("\tif (%s & 1) {\n", getpc);
printf ("\t\tuaecptr faultpc = %s;\n", getpc);
setpc ("oldpc");
if (cpu_level > 1)
printf ("\t\tdivbyzero_special (0, dst);\n");
incpc ("%d", m68k_pc_offset);
- printf ("\t\tException (5);\n");
+ printf ("\t\tException_cpu(5);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t} else {\n");
printf ("\t\tuae_u32 newv = (uae_u32)dst / (uae_u32)(uae_u16)src;\n");
if (cpu_level > 1)
printf ("\t\tdivbyzero_special (1, dst);\n");
incpc ("%d", m68k_pc_offset);
- printf ("\t\tException (5);\n");
+ printf ("\t\tException_cpu(5);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
printf ("\tCLEAR_CZNV ();\n");
addcycles000 (4);
printf ("\tif (dst > src) {\n");
printf ("\t\tSET_NFLG (0);\n");
- printf ("\t\tException (6);\n");
+ printf ("\t\tException_cpu(6);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
addcycles000 (2);
printf ("\tif ((uae_s32)dst < 0) {\n");
printf ("\t\tSET_NFLG (1);\n");
- printf ("\t\tException (6);\n");
+ printf ("\t\tException_cpu(6);\n");
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
fill_prefetch_next ();
}
printf ("\tSET_ZFLG (upper == reg || lower == reg);\n");
printf ("\tSET_CFLG_ALWAYS (lower <= upper ? reg < lower || reg > upper : reg > upper || reg < lower);\n");
- printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception (6); goto %s; }\n}\n", endlabelstr);
+ printf ("\tif ((extra & 0x800) && GET_CFLG ()) { Exception_cpu(6); goto %s; }\n}\n", endlabelstr);
need_endlabel = 1;
break;
if (curi->smode != am_unknown && curi->smode != am_illg)
genamode (curi, curi->smode, "srcreg", curi->size, "dummy", 1, 0, 0);
fill_prefetch_0 ();
- printf ("\tif (cctrue (%d)) { Exception (7); goto %s; }\n", curi->cc, endlabelstr);
+ printf ("\tif (cctrue (%d)) { Exception_cpu(7); goto %s; }\n", curi->cc, endlabelstr);
need_endlabel = 1;
break;
case i_DIVL:
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
need_endlabel = 1;
+ } else {
+ printf ("\tif (regs.fp_branch) {\n");
+ printf ("\t\tregs.fp_branch = false;\n");
+ printf ("\t\tif(regs.t0) check_t0_trace();\n");
+ printf ("\t}\n");
}
break;
case i_FScc:
printf ("\t\tgoto %s;\n", endlabelstr);
printf ("\t}\n");
need_endlabel = 1;
+ } else {
+ printf ("\tif (regs.fp_branch) {\n");
+ printf ("\t\tregs.fp_branch = false;\n");
+ printf ("\t\tif(regs.t0) check_t0_trace();\n");
+ printf ("\t}\n");
}
break;
case i_FSAVE:
{
fpdata fp;
to_single(&fp, get_ilong_debug(pc));
- _stprintf(buffer, _T("#%e"), fp.fp);
+ _stprintf(buffer, _T("#%s"), fp_print(&fp));
pc += 4;
}
break;
{
fpdata fp;
to_double(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4));
- _stprintf(buffer, _T("#%e"), fp.fp);
+ _stprintf(buffer, _T("#%s"), fp_print(&fp));
pc += 8;
}
break;
{
fpdata fp;
to_exten(&fp, get_ilong_debug(pc), get_ilong_debug(pc + 4), get_ilong_debug(pc + 8));
-#if USE_LONG_DOUBLE
- _stprintf(buffer, _T("#%Le"), fp.fp);
-#else
- _stprintf(buffer, _T("#%e"), fp.fp);
-#endif
+ _stprintf(buffer, _T("#%s"), fp_print(&fp));
pc += 12;
break;
}
cpu_last_stop_vpos = vpos;
}
+static void activate_trace(void)
+{
+ unset_special (SPCFLAG_TRACE);
+ set_special (SPCFLAG_DOTRACE);
+}
+
void REGPARAM2 MakeSR (void)
{
regs.sr = ((regs.t1 << 15) | (regs.t0 << 14)
SET_CFLG (regs.sr & 1);
}
-void REGPARAM2 MakeFromSR (void)
+static void MakeFromSR_x(int t0trace)
{
int oldm = regs.m;
int olds = regs.s;
+ int oldt0 = regs.t0;
+ int oldt1 = regs.t1;
SET_XFLG ((regs.sr >> 4) & 1);
SET_NFLG ((regs.sr >> 3) & 1);
mmu_set_super (regs.s != 0);
doint ();
- if (regs.t1 || regs.t0)
+ if (regs.t1 || regs.t0) {
set_special (SPCFLAG_TRACE);
- else
+ } else {
/* Keep SPCFLAG_DOTRACE, we still want a trace exception for
SR-modifying instructions (including STOP). */
unset_special (SPCFLAG_TRACE);
+ }
+ // Stop SR-modification does not generate T0
+ // If this SR modification set Tx bit, no trace until next instruction.
+ if ((oldt0 && t0trace && currprefs.cpu_model >= 68020) || oldt1) {
+ // Always trace if Tx bits were already set, even if this SR modification cleared them.
+ activate_trace();
+ }
+}
+
+void REGPARAM2 MakeFromSR_T0(void)
+{
+ MakeFromSR_x(1);
+}
+void REGPARAM2 MakeFromSR(void)
+{
+ MakeFromSR_x(0);
}
static void exception_check_trace (int nr)
}
}
+void REGPARAM2 Exception_cpu(int nr)
+{
+ bool t0 = currprefs.cpu_model >= 68020 && regs.t0;
+ ExceptionX (nr, -1);
+ // check T0 trace
+ if (t0) {
+ activate_trace();
+ }
+}
void REGPARAM2 Exception (int nr)
{
ExceptionX (nr, -1);
#endif
-static uaecptr last_trace_ad = 0;
-
static void do_trace (void)
{
if (regs.t0 && currprefs.cpu_model >= 68020) {
- uae_u16 opcode;
- /* should also include TRAP, CHK, SR modification FPcc */
- /* probably never used so why bother */
- /* We can afford this to be inefficient... */
- m68k_setpc_normal (m68k_getpc ());
- fill_prefetch ();
- opcode = x_get_word (regs.pc);
- if (opcode == 0x4e73 /* RTE */
- || opcode == 0x4e74 /* RTD */
- || opcode == 0x4e75 /* RTS */
- || opcode == 0x4e77 /* RTR */
- || opcode == 0x4e76 /* TRAPV */
- || (opcode & 0xffc0) == 0x4e80 /* JSR */
- || (opcode & 0xffc0) == 0x4ec0 /* JMP */
- || (opcode & 0xff00) == 0x6100 /* BSR */
- || ((opcode & 0xf000) == 0x6000 /* Bcc */
- && cctrue ((opcode >> 8) & 0xf))
- || ((opcode & 0xf0f0) == 0x5050 /* DBcc */
- && !cctrue ((opcode >> 8) & 0xf)
- && (uae_s16)m68k_dreg (regs, opcode & 7) != 0))
- {
- last_trace_ad = m68k_getpc ();
- unset_special (SPCFLAG_TRACE);
- set_special (SPCFLAG_DOTRACE);
- }
- } else if (regs.t1) {
- last_trace_ad = m68k_getpc ();
- unset_special (SPCFLAG_TRACE);
- set_special (SPCFLAG_DOTRACE);
+ // this is obsolete
+ return;
+ }
+ if (regs.t1) {
+ activate_trace();
}
}
}
}
-// Not exactly right, requires logic analyzer checks.
-void continue_ce020_prefetch(void)
-{
- fill_prefetch_020();
-}
-void continue_020_prefetch(void)
-{
- fill_prefetch_020();
-}
#endif
uae_u32 get_word_ce020_prefetch (int o)
}
}
-void fill_prefetch_030 (void)
+void check_t0_trace(void)
+{
+ if (regs.t0 && currprefs.cpu_model >= 68020) {
+ unset_special (SPCFLAG_TRACE);
+ set_special (SPCFLAG_DOTRACE);
+ }
+}
+
+void fill_prefetch_030_ntx (void)
{
uaecptr pc = m68k_getpc ();
uaecptr pc2 = pc;
regs.irc = get_word_030_prefetch(0);
}
-void fill_prefetch_020 (void)
+void fill_prefetch_020_ntx(void)
{
uaecptr pc = m68k_getpc ();
uaecptr pc2 = pc;
regs.irc = get_word_020_prefetch (0);
}
+// Not exactly right, requires logic analyzer checks.
+void continue_ce020_prefetch(void)
+{
+ fill_prefetch_020_ntx();
+}
+void continue_020_prefetch(void)
+{
+ fill_prefetch_020_ntx();
+}
+
+void fill_prefetch_020(void)
+{
+ fill_prefetch_020_ntx();
+ check_t0_trace();
+}
+
+void fill_prefetch_030(void)
+{
+ fill_prefetch_030_ntx();
+ check_t0_trace();
+}
+
+
void fill_prefetch (void)
{
regs.pipeline_pos = 0;