Skip to content

Commit

Permalink
MMU/generic CPU mode autovectored interrupt support (from WinUAE 5.1.…
Browse files Browse the repository at this point in the history
…0 beta1+ 2023/09/19)
  • Loading branch information
npomarede committed Sep 19, 2023
1 parent 15e0fea commit eb44676
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 56 deletions.
88 changes: 38 additions & 50 deletions src/cpu/newcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2843,11 +2843,14 @@ Line F:

static int iack_cycle(int nr)
{
int vector;
int vector = nr;

#ifndef WINUAE_FOR_HATARI
if (1) {
// non-autovectored
if (currprefs.cpu_model >= 68020) {
return vector;
}
// this is basically normal memory access and takes 4 cycles (without wait states).
vector = x_get_byte(0x00fffff1 | ((nr - 24) << 1));
x_do_cycles(4 * cpucycleunit);
Expand Down Expand Up @@ -3220,63 +3223,50 @@ static void Exception_ce000 (int nr)
// 68030 MMU
static void Exception_mmu030 (int nr, uaecptr oldpc)
{
uae_u32 currpc = m68k_getpc (), newpc;
int interrupt;
uae_u32 currpc = m68k_getpc (), newpc;
int interrupt, vector_nr = nr;

interrupt = nr >= 24 && nr < 24 + 8;

#ifdef WINUAE_FOR_HATARI
if (interrupt)
nr = iack_cycle(nr);
#endif
vector_nr = iack_cycle(nr);

#ifdef WINUAE_FOR_HATARI
LOG_TRACE(TRACE_CPU_EXCEPTION, "cpu exception %d currpc %x buspc %x newpc %x fault_e3 %x op_e3 %x addr_e3 %x SR %x\n",
nr, currpc, regs.instruction_pc, STMemory_ReadLong (regs.vbr + 4*nr), last_fault_for_exception_3, last_op_for_exception_3, last_addr_for_exception_3, regs.sr);
#endif
exception_debug (nr);
MakeSR ();
exception_debug (nr);
MakeSR ();

if (!regs.s) {
regs.usp = m68k_areg (regs, 7);
m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp;
regs.s = 1;
mmu_set_super (1);
}
if (!regs.s) {
regs.usp = m68k_areg (regs, 7);
m68k_areg(regs, 7) = regs.m ? regs.msp : regs.isp;
regs.s = 1;
mmu_set_super (1);
}

#if 0
if (nr < 24 || nr > 31) { // do not print debugging for interrupts
write_log (_T("Exception_mmu030: Exception %i: %08x %08x %08x\n"),
nr, currpc, oldpc, regs.mmu_fault_addr);
}
#endif

newpc = x_get_long (regs.vbr + 4 * nr);

#if 0
write_log (_T("Exception %d -> %08x\n"), nr, newpc);
#endif
newpc = x_get_long (regs.vbr + 4 * vector_nr);

if (regs.m && interrupt) { /* M + Interrupt */
Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x0);
Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, vector_nr, 0x0);
MakeSR ();
regs.m = 0;
regs.msp = m68k_areg (regs, 7);
m68k_areg (regs, 7) = regs.isp;
Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1);
} else if (nr == 2) {
Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, vector_nr, 0x1);
} else if (nr == 2) {
if (1 && (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) {
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xA);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0xA);
} else {
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xB);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0xB);
}
} else if (nr == 3) {
} else if (nr == 3) {
regs.mmu_fault_addr = last_fault_for_exception_3;
mmu030_state[0] = mmu030_state[1] = 0;
mmu030_data_buffer_out = 0;
Exception_build_stack_frame (last_fault_for_exception_3, currpc, MMU030_SSW_RW | MMU030_SSW_SIZE_W | (regs.s ? 6 : 2), nr, 0xB);
Exception_build_stack_frame(last_fault_for_exception_3, currpc, MMU030_SSW_RW | MMU030_SSW_SIZE_W | (regs.s ? 6 : 2), vector_nr, 0xB);
} else {
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, nr);
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, vector_nr);
}

if (newpc & 1) {
Expand All @@ -3298,18 +3288,16 @@ static void Exception_mmu (int nr, uaecptr oldpc)
{
uae_u32 currpc = m68k_getpc (), newpc;
int interrupt;
int vector_nr = nr;

interrupt = nr >= 24 && nr < 24 + 8;
if (interrupt)
nr = iack_cycle(nr);

// exception vector fetch and exception stack frame
// operations don't allocate new cachelines
cache_default_data |= CACHE_DISABLE_ALLOCATE;

#ifdef WINUAE_FOR_HATARI
if (interrupt)
nr = iack_cycle(nr);
#endif

#ifdef WINUAE_FOR_HATARI
LOG_TRACE(TRACE_CPU_EXCEPTION, "cpu exception %d currpc %x buspc %x newpc %x fault_e3 %x op_e3 %x addr_e3 %x SR %x\n",
nr, currpc, regs.instruction_pc, STMemory_ReadLong (regs.vbr + 4*nr), last_fault_for_exception_3, last_op_for_exception_3, last_addr_for_exception_3, regs.sr);
Expand All @@ -3328,30 +3316,30 @@ static void Exception_mmu (int nr, uaecptr oldpc)
mmu_set_super (1);
}

newpc = x_get_long (regs.vbr + 4 * nr);
newpc = x_get_long (regs.vbr + 4 * vector_nr);
#if 0
write_log (_T("Exception %d: %08x -> %08x\n"), nr, currpc, newpc);
#endif

if (nr == 2) { // bus error
//write_log (_T("Exception_mmu %08x %08x %08x\n"), currpc, oldpc, regs.mmu_fault_addr);
if (currprefs.mmu_model == 68040)
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x7);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0x7);
else
Exception_build_stack_frame(regs.mmu_fault_addr, currpc, regs.mmu_fslw, nr, 0x4);
Exception_build_stack_frame(regs.mmu_fault_addr, currpc, regs.mmu_fslw, vector_nr, 0x4);
} else if (nr == 3) { // address error
Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x2);
Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, vector_nr, 0x2);
write_log (_T("Exception %d (%x) at %x -> %x!\n"), nr, last_fault_for_exception_3, currpc, get_long_debug (regs.vbr + 4 * nr));
} else if (regs.m && interrupt) { /* M + Interrupt */
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x0);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0x0);
MakeSR();
regs.m = 0;
if (currprefs.cpu_model < 68060) {
regs.msp = m68k_areg(regs, 7);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0x1);
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, vector_nr, 0x1);
}
} else {
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, nr);
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, vector_nr);
}

if (newpc & 1) {
Expand Down Expand Up @@ -3605,7 +3593,7 @@ static void Exception_normal (int nr)

} else {
// 68040/060 odd PC address error
Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, nr, 0x02);
Exception_build_stack_frame(last_fault_for_exception_3, currpc, 0, vector_nr, 0x02);
used_exception_build_stack_frame = true;
}
} else if (currprefs.cpu_model >= 68020) {
Expand All @@ -3616,7 +3604,7 @@ static void Exception_normal (int nr)
regs.mmu_fault_addr = last_fault_for_exception_3;
mmu030_state[0] = mmu030_state[1] = 0;
mmu030_data_buffer_out = 0;
Exception_build_stack_frame(last_fault_for_exception_3, currpc, ssw, nr, 0x0b);
Exception_build_stack_frame(last_fault_for_exception_3, currpc, ssw, vector_nr, 0x0b);
used_exception_build_stack_frame = true;
} else {
// 68010 bus/address error (partially implemented only)
Expand All @@ -3629,7 +3617,7 @@ static void Exception_normal (int nr)
if (last_op_for_exception_3 & 0x20000)
ssw &= 0x00ff;
regs.mmu_fault_addr = last_fault_for_exception_3;
Exception_build_stack_frame(oldpc, currpc, ssw, nr, 0x08);
Exception_build_stack_frame(oldpc, currpc, ssw, vector_nr, 0x08);
used_exception_build_stack_frame = true;
}
#ifndef WINUAE_FOR_HATARI
Expand Down Expand Up @@ -3658,7 +3646,7 @@ static void Exception_normal (int nr)
x_put_word (m68k_areg (regs, 7), 0x1000 + vector_nr * 4);
}
} else {
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, nr);
Exception_build_stack_frame_common(oldpc, currpc, regs.mmu_ssw, vector_nr);
used_exception_build_stack_frame = true;
}
} else {
Expand Down
6 changes: 0 additions & 6 deletions src/cpu/newcpu_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1408,12 +1408,6 @@ void Exception_build_stack_frame(uae_u32 oldpc, uae_u32 currpc, uae_u32 ssw, int
{
int i;

#if 0
if (nr < 24 || nr > 31) { // do not print debugging for interrupts
write_log(_T("Building exception stack frame (format %X)\n"), format);
}
#endif

switch (format) {
case 0x0: // four word stack frame
case 0x1: // throwaway four word stack frame
Expand Down

0 comments on commit eb44676

Please sign in to comment.