mm030_stageb_address = addr;
#if MMUDEBUG
- write_log(_T("MMU: la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x "),
+ write_log(_T("MMU: %02x la=%08X SSW=%04x read=%d size=%d fc=%d pc=%08x ob=%08x "),
+ (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) ? 0xa : 0xb,
addr, regs.mmu_ssw, read, (flags & MMU030_SSW_SIZE_B) ? 1 : (flags & MMU030_SSW_SIZE_W) ? 2 : 4, fc,
regs.instruction_pc, mmu030_data_buffer_out, mmu030_opcode & 0xffff);
dump_opcode(mmu030_opcode & 0xffff);
uae_u16 frame = format >> 12;
uae_u16 ssw = get_word_mmu030(a7 + 10);
uae_u32 fault_addr = get_long_mmu030(a7 + 16);
+ // Data output buffer
+ uae_u32 mmu030_data_buffer_out_v = get_long_mmu030(a7 + 0x18);
+ // Internal register, our opcode storage area
+ uae_u32 oc = get_long_mmu030(a7 + 0x14);
+ int idxsize = -1;
// Fetch last word, real CPU does it to allow OS bus handler to map
// the page if frame crosses pages and following page is not resident.
mmu030_retry = true;
if (frame == 0xa) {
+ // this is always last write data write fault
- // A-frame only in non-prefetch mode and only when
- // instruction's first word fetch caused access fault.
- // mmu030_opcode_v is always -1 here.
- if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) {
- uae_u16 stageb = get_word_mmu030(a7 + 0x0e);
- mmu030_opcode_stageb = stageb;
- write_log(_T("Software fixed stage B! opcode = %04x\n"), stageb);
+ uae_u32 mmu030_state_1 = get_word_mmu030(a7 + 0x8);
+
+#if MMU030_DEBUG
+ if (!(mmu030_state_1 & MMU030_STATEFLAG1_LASTWRITE)) {
+ write_log(_T("68030 MMU short bus fault but no lastwrite set!?\n"));
+ }
+ if (ssw & (MMU030_SSW_FB | MMU030_SSW_FC | MMU030_SSW_FB | MMU030_SSW_RC | MMU030_SSW_RB)) {
+ write_log(_T("68030 MMU short bus fault and pipeline fault?\n"));
+ }
+ if (ssw & MMU030_SSW_RW) {
+ write_log(_T("68030 MMU short bus fault but read fault!?\n"));
}
- mmu030_opcode = -1;
+#endif
- m68k_areg(regs, 7) += 32;
- regs.sr = sr;
- MakeFromSR_T0();
- if (pc & 1) {
- exception3i(0x4E73, pc);
- return;
+ // did we have data fault but DF bit cleared?
+ if (ssw & (MMU030_SSW_DF << 1) && !(ssw & MMU030_SSW_DF)) {
+ // DF not set: mark access as done
+ unalign_clear();
}
- m68k_setpci(pc);
+ mmu030_data_buffer_out = mmu030_data_buffer_out_v;
+ mmu030_state[0] = 0;
+ mmu030_state[1] = mmu030_state_1;
+ mmu030_state[2] = 0;
+ mmu030_opcode = oc;
+ mmu030_idx = 0;
+
+ m68k_areg(regs, 7) += 32;
} else if (frame == 0xb) {
// Internal register, misc flags
uae_u32 ps = get_long_mmu030(a7 + 0x28);
// Data buffer
- uae_u32 mmu030_data_buffer_in_v = get_long_mmu030(a7 + 0x2c);;
+ uae_u32 mmu030_data_buffer_in_v = get_long_mmu030(a7 + 0x2c);
// Misc state data
uae_u32 mmu030_state_0 = get_word_mmu030(a7 + 0x30);
uae_u32 mmu030_state_1 = get_word_mmu030(a7 + 0x32);
uae_u32 mmu030_state_2 = get_word_mmu030(a7 + 0x34);
- // Internal register, our opcode storage area
- uae_u32 oc = get_long_mmu030(a7 + 0x14);
- // Data output buffer
- uae_u32 mmu030_data_buffer_out_v = get_long_mmu030(a7 + 0x18);
-
uae_u32 mmu030_opcode_v = (ps & 0x80000000) ? -1U : (oc & 0xffff);
uae_u32 mmu030_fmovem_store_0 = 0;
mmu030_fmovem_store_1 = get_long_mmu030(a7 + 0x5c - (8 + 1) * 4);
}
- uae_u16 idxsize = get_word_mmu030 (a7 + 0x36);
+ idxsize = get_word_mmu030(a7 + 0x36);
for (int i = 0; i < idxsize + 1; i++) {
mmu030_ad_v[i].done = i < idxsize;
- mmu030_ad_v[i].val = get_long_mmu030 (a7 + 0x5c - (i + 1) * 4);
+ mmu030_ad_v[i].val = get_long_mmu030(a7 + 0x5c - (i + 1) * 4);
}
mmu030_ad_v[idxsize + 1].done = false;
mmu030_data_buffer_out_v = mmu030_data_buffer_in_v;
if (ssw & MMU030_SSW_RM) {
// Read-Modify-Write: whole instruction is considered done
- write_log (_T("Read-Modify-Write and DF bit cleared! PC=%08x\n"), regs.instruction_pc);
+ write_log(_T("Read-Modify-Write and DF bit cleared! PC=%08x\n"), regs.instruction_pc);
mmu030_retry = false;
} else if (mmu030_state_1 & MMU030_STATEFLAG1_MOVEM1) {
// if movem, skip next move
}
// did we have ins fault and RB bit cleared?
if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) {
- uae_u16 stageb = get_word_mmu030 (a7 + 0x0e);
+ uae_u16 stageb = get_word_mmu030(a7 + 0x0e);
if (mmu030_opcode_v == -1U) {
mmu030_opcode_stageb = stageb;
- write_log (_T("Software fixed stage B! opcode = %04x\n"), stageb);
+ write_log(_T("Software fixed stage B! opcode = %04x\n"), stageb);
} else {
mmu030_ad_v[idxsize].done = true;
mmu030_ad_v[idxsize].val = stageb;
- write_log (_T("Software fixed stage B! opcode = %04X, opword = %04x\n"), mmu030_opcode_v, stageb);
+ write_log(_T("Software fixed stage B! opcode = %04X, opword = %04x\n"), mmu030_opcode_v, stageb);
}
}
+#if MMU030_DEBUG
+ if (mmu030_state_1 & MMU030_STATEFLAG1_LASTWRITE) {
+ write_log(_T("68030 MMU long bus fault but lastwrite set!?\n"));
+ }
+#endif
// Retried data access is the only memory access that can be done after this.
// restore global state variables
}
m68k_areg(regs, 7) += 92;
- regs.sr = sr;
- MakeFromSR_T0();
- if (pc & 1) {
- exception3i(0x4E73, pc);
- return;
- }
- m68k_setpci(pc);
- if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) {
+ }
+
+ regs.sr = sr;
+ MakeFromSR_T0();
+ if (pc & 1) {
+ exception3i(0x4E73, pc);
+ return;
+ }
+ m68k_setpci(pc);
+
+ if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) {
- // Locked-Read-Modify-Write restarts whole instruction.
- mmu030_ad[0].done = false;
+ // Locked-Read-Modify-Write restarts whole instruction.
+ mmu030_ad[0].done = false;
- } else if (ssw & MMU030_SSW_DF) {
+ } else if (ssw & MMU030_SSW_DF) {
- // retry faulted access
- uaecptr addr = fault_addr;
- bool read = (ssw & MMU030_SSW_RW) != 0;
- int size = (ssw & MMU030_SSW_SIZE_B) ? sz_byte : ((ssw & MMU030_SSW_SIZE_W) ? sz_word : sz_long);
- int fc = ssw & MMU030_SSW_FC_MASK;
+ // retry faulted access
+ uaecptr addr = fault_addr;
+ bool read = (ssw & MMU030_SSW_RW) != 0;
+ int size = (ssw & MMU030_SSW_SIZE_B) ? sz_byte : ((ssw & MMU030_SSW_SIZE_W) ? sz_word : sz_long);
+ int fc = ssw & MMU030_SSW_FC_MASK;
#if MMU030_DEBUG
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
- write_log(_T("68030 MMU MOVEM %04x retry but MMU030_STATEFLAG1_MOVEM2 was already set!?\n"), mmu030_opcode);
- }
- }
- if (mmu030_ad[idxsize].done) {
- write_log(_T("68030 MMU ins %04x retry but it was already marked as done!?\n"), mmu030_opcode);
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
+ write_log(_T("68030 MMU MOVEM %04x retry but MMU030_STATEFLAG1_MOVEM2 was already set!?\n"), mmu030_opcode);
}
+ }
+ if (idxsize >= 0 && mmu030_ad[idxsize].done) {
+ write_log(_T("68030 MMU ins %04x retry but it was already marked as done!?\n"), mmu030_opcode);
+ }
#endif
#if MMU030_DEBUG
- write_log(_T("%08x %08x %08x %08x %08x %d %d %d %08x %08x %04x\n"),
- mmu030_state[1], mmu030_state[2], mmu030_disp_store[0], mmu030_disp_store[1],
- addr, read, size, fc, mmu030_data_buffer_out, mmu030_ad[idxsize].val, ssw);
+ write_log(_T("%08x %08x %08x %08x %08x %d %d %d %08x %08x %04x\n"),
+ mmu030_state[1], mmu030_state[2], mmu030_disp_store[0], mmu030_disp_store[1],
+ addr, read, size, fc, mmu030_data_buffer_out, idxsize < 0 ? -1 : mmu030_ad[idxsize].val, ssw);
#endif
- if (read) {
- if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
- mmu030_unaligned_read_continue(addr, fc, mmu030_get_generic);
- } else {
- switch (size)
- {
- case sz_byte:
- mmu030_data_buffer_out = uae_mmu030_get_byte_fcx(addr, fc);
- break;
- case sz_word:
- mmu030_data_buffer_out = uae_mmu030_get_word_fcx(addr, fc);
- break;
- case sz_long:
- mmu030_data_buffer_out = uae_mmu030_get_long_fcx(addr, fc);
- break;
- }
- }
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
- } else {
- mmu030_ad[idxsize].val = mmu030_data_buffer_out;
- mmu030_ad[idxsize].done = true;
- }
+ if (read) {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
+ mmu030_unaligned_read_continue(addr, fc, mmu030_get_generic);
} else {
- if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
- mmu030_unaligned_write_continue(addr, fc, mmu030_put_generic);
- } else {
- switch (size)
- {
- case sz_byte:
- uae_mmu030_put_byte_fcx(addr, mmu030_data_buffer_out, fc);
- break;
- case sz_word:
- uae_mmu030_put_word_fcx(addr, mmu030_data_buffer_out, fc);
- break;
- case sz_long:
- uae_mmu030_put_long_fcx(addr, mmu030_data_buffer_out, fc);
- break;
- }
+ switch (size)
+ {
+ case sz_byte:
+ mmu030_data_buffer_out = uae_mmu030_get_byte_fcx(addr, fc);
+ break;
+ case sz_word:
+ mmu030_data_buffer_out = uae_mmu030_get_word_fcx(addr, fc);
+ break;
+ case sz_long:
+ mmu030_data_buffer_out = uae_mmu030_get_long_fcx(addr, fc);
+ break;
}
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
- } else {
- mmu030_ad[idxsize].done = true;
+ }
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
+ } else if (idxsize >= 0) {
+ mmu030_ad[idxsize].val = mmu030_data_buffer_out;
+ mmu030_ad[idxsize].done = true;
+ }
+ } else {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
+ mmu030_unaligned_write_continue(addr, fc, mmu030_put_generic);
+ } else {
+ switch (size)
+ {
+ case sz_byte:
+ uae_mmu030_put_byte_fcx(addr, mmu030_data_buffer_out, fc);
+ break;
+ case sz_word:
+ uae_mmu030_put_word_fcx(addr, mmu030_data_buffer_out, fc);
+ break;
+ case sz_long:
+ uae_mmu030_put_long_fcx(addr, mmu030_data_buffer_out, fc);
+ break;
}
}
-
- }
-
- if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
- mmu030_retry = false;
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
+ } else if (idxsize >= 0) {
+ mmu030_ad[idxsize].done = true;
+ }
}
#if MMU030_DEBUG
write_log(_T("mmu030_idx (RTE) out of bounds! %d >= %d\n"), mmu030_idx, MAX_MMU030_ACCESS);
}
#endif
+ }
+ if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
+ mmu030_retry = false;
}
}
uae_u16 format = get_word_mmu030c (a7 + 6);
uae_u16 frame = format >> 12;
uae_u16 ssw = get_word_mmu030c (a7 + 10);
- uae_u32 stagesbc = get_long_mmu030c(a7 + 12);
uae_u32 fault_addr = get_long_mmu030c(a7 + 16);
+ // Data output buffer
+ uae_u32 mmu030_data_buffer_out_v = get_long_mmu030c(a7 + 0x18);
+ // Internal register, our opcode storage area
+ uae_u32 oc = get_long_mmu030c(a7 + 0x14);
+ uae_u32 stagesbc = get_long_mmu030c(a7 + 12);
+
+ int idxsize = -1;
+ bool doprefetch = true;
// Fetch last word, real CPU does it to allow OS bus handler to map
// the page if frame crosses pages and following page is not resident.
else
get_word_mmu030c(a7 + 32 - 2);
- // Internal register, our opcode storage area
- uae_u32 oc = get_long_mmu030c(a7 + 0x14);
- // Data output buffer
- uae_u32 mmu030_data_buffer_out_v = get_long_mmu030c(a7 + 0x18);
- // get_disp_ea_020
- uae_u32 mmu030_disp_store_0 = get_long_mmu030c(a7 + 0x1c);
- uae_u32 mmu030_disp_store_1 = get_long_mmu030c(a7 + 0x1c + 4);
- // Internal register, misc flags
- uae_u32 ps = get_long_mmu030c(a7 + 0x28);
- // Data buffer
- uae_u32 mmu030_data_buffer_in_v = get_long_mmu030c(a7 + 0x2c);;
-
- uae_u32 mmu030_opcode_v = (ps & 0x80000000) ? -1U : (oc & 0xffff);
- // Misc state data
- uae_u32 mmu030_state_0 = get_word_mmu030c(a7 + 0x30);
- uae_u32 mmu030_state_1 = get_word_mmu030c(a7 + 0x32);
- uae_u32 mmu030_state_2 = get_word_mmu030c(a7 + 0x34);
-
- uae_u32 mmu030_fmovem_store_0 = 0;
- uae_u32 mmu030_fmovem_store_1 = 0;
- if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) {
- mmu030_fmovem_store_0 = get_long_mmu030c(a7 + 0x5c - (7 + 1) * 4);
- mmu030_fmovem_store_1 = get_long_mmu030c(a7 + 0x5c - (8 + 1) * 4);
- }
-
// Rerun "mmu030_opcode" using restored state.
mmu030_retry = true;
- if (frame == 0xb) {
- uae_u16 idxsize = get_word_mmu030c(a7 + 0x36);
+ if (frame == 0xa) {
+ // this is always last write data write fault
+
+ uae_u32 mmu030_state_1 = get_word_mmu030c(a7 + 0x8);
+ uae_u32 ps = get_long_mmu030c(a7 + 0x1c);
+
+#if MMU030_DEBUG
+ if (!(mmu030_state_1 & MMU030_STATEFLAG1_LASTWRITE)) {
+ write_log(_T("68030 MMU short bus fault but no lastwrite set!?\n"));
+ }
+ if (ssw & (MMU030_SSW_FB | MMU030_SSW_FC | MMU030_SSW_FB | MMU030_SSW_RC | MMU030_SSW_RB)) {
+ write_log(_T("68030 MMU short bus fault and pipeline fault?\n"));
+ }
+ if (ssw & MMU030_SSW_RW) {
+ write_log(_T("68030 MMU short bus fault but read fault!?\n"));
+ }
+#endif
+ // did we have data fault but DF bit cleared?
+ if (ssw & (MMU030_SSW_DF << 1) && !(ssw & MMU030_SSW_DF)) {
+ // DF not set: mark access as done
+ unalign_clear();
+ }
+
+ regs.prefetch020_valid[0] = (ps & 1) ? 1 : 0;
+ regs.prefetch020_valid[1] = (ps & 2) ? 1 : 0;
+ regs.prefetch020_valid[2] = (ps & 4) ? 1 : 0;
+
+ regs.pipeline_r8[0] = (ps >> 8) & 7;
+ regs.pipeline_r8[1] = (ps >> 11) & 7;
+ regs.pipeline_pos = (ps >> 16) & 15;
+ regs.pipeline_stop = ((ps >> 20) & 15) == 15 ? -1 : (int)(ps >> 20) & 15;
+
+ regs.prefetch020[2] = stagesbc;
+ regs.prefetch020[1] = stagesbc >> 16;
+ regs.prefetch020[0] = oc >> 16;
+ mmu030_opcode_stageb = (uae_u16)oc;
+
+ mmu030_data_buffer_out = mmu030_data_buffer_out_v;
+ mmu030_state[0] = 0;
+ mmu030_state[1] = mmu030_state_1;
+ mmu030_state[2] = 0;
+ mmu030_idx = 0;
+
+ doprefetch = false;
+
+ m68k_areg(regs, 7) += 32;
+
+ } else if (frame == 0xb) {
+
+ // get_disp_ea_020
+ uae_u32 mmu030_disp_store_0 = get_long_mmu030c(a7 + 0x1c);
+ uae_u32 mmu030_disp_store_1 = get_long_mmu030c(a7 + 0x1c + 4);
+ // Internal register, misc flags
+ uae_u32 ps = get_long_mmu030c(a7 + 0x28);
+ // Data buffer
+ uae_u32 mmu030_data_buffer_in_v = get_long_mmu030c(a7 + 0x2c);;
+ // Misc state data
+ uae_u32 mmu030_state_0 = get_word_mmu030c(a7 + 0x30);
+ uae_u32 mmu030_state_1 = get_word_mmu030c(a7 + 0x32);
+ uae_u32 mmu030_state_2 = get_word_mmu030c(a7 + 0x34);
+
+ uae_u32 mmu030_opcode_v = (ps & 0x80000000) ? -1U : (oc & 0xffff);
+
+ uae_u32 mmu030_fmovem_store_0 = 0;
+ uae_u32 mmu030_fmovem_store_1 = 0;
+ if (mmu030_state[1] & MMU030_STATEFLAG1_FMOVEM) {
+ mmu030_fmovem_store_0 = get_long_mmu030c(a7 + 0x5c - (7 + 1) * 4);
+ mmu030_fmovem_store_1 = get_long_mmu030c(a7 + 0x5c - (8 + 1) * 4);
+ }
+
+ idxsize = get_word_mmu030c(a7 + 0x36);
for (int i = 0; i < idxsize + 1; i++) {
mmu030_ad_v[i].done = i < idxsize;
mmu030_ad_v[i].val = get_long_mmu030c(a7 + 0x5c - (i + 1) * 4);
mmu030_data_buffer_out_v = mmu030_data_buffer_in_v;
if (ssw & MMU030_SSW_RM) {
// Read-Modify-Write: whole instruction is considered done
- write_log (_T("Read-Modify-Write and DF bit cleared! PC=%08x\n"), regs.instruction_pc);
+ write_log(_T("Read-Modify-Write and DF bit cleared! PC=%08x\n"), regs.instruction_pc);
mmu030_retry = false;
} else if (mmu030_state_1 & MMU030_STATEFLAG1_MOVEM1) {
// if movem, skip next move
unalign_clear();
}
+#if MMU030_DEBUG
+ if (mmu030_state_1 & MMU030_STATEFLAG1_LASTWRITE) {
+ write_log(_T("68030 MMU long bus fault but lastwrite set!?\n"));
+ }
+#endif
// Retried data access is the only memory access that can be done after this.
regs.prefetch020_valid[0] = (ps & 1) ? 1 : 0;
if ((ssw & MMU030_SSW_FB) && !(ssw & MMU030_SSW_RB)) {
regs.prefetch020_valid[2] = 1;
- write_log (_T("Software fixed stage B! opcode = %04x\n"), regs.prefetch020[2]);
+ write_log(_T("Software fixed stage B! opcode = %04x\n"), regs.prefetch020[2]);
}
if ((ssw & MMU030_SSW_FC) && !(ssw & MMU030_SSW_RC)) {
regs.prefetch020_valid[1] = 1;
- write_log (_T("Software fixed stage C! opcode = %04x\n"), regs.prefetch020[1]);
+ write_log(_T("Software fixed stage C! opcode = %04x\n"), regs.prefetch020[1]);
}
// restore global state variables
mmu030_ad[i].val = mmu030_ad_v[i].val;
}
- m68k_areg (regs, 7) += 92;
- regs.sr = sr;
- MakeFromSR_T0();
- if (pc & 1) {
- exception3i (0x4E73, pc);
- return;
- }
- m68k_setpci (pc);
-
- if (!(ssw & (MMU030_SSW_DF << 1))) {
- if (!regs.prefetch020_valid[0] && regs.prefetch020_valid[2]) {
- // Prefetch was software fixed, continue pipeline refill
- fill_prefetch_030_ntx_continue();
- } else if (regs.prefetch020_valid[0] && regs.prefetch020_valid[1]) {
- // Finished?
- fill_prefetch_030_ntx_continue();
- } else if (mmu030_opcode == -1) {
- // Previous branch instruction finished successfully but its pipeline refill
- // step caused the exception, retry the refill, do not retry branch instruction.
- fill_prefetch_030_ntx();
- }
+ m68k_areg(regs, 7) += 92;
+
+ }
+
+ regs.sr = sr;
+ MakeFromSR_T0();
+ if (pc & 1) {
+ exception3i (0x4E73, pc);
+ return;
+ }
+ m68k_setpci (pc);
+
+ if (!(ssw & (MMU030_SSW_DF << 1))) {
+ if (!regs.prefetch020_valid[0] && regs.prefetch020_valid[2]) {
+ // Prefetch was software fixed, continue pipeline refill
+ fill_prefetch_030_ntx_continue();
+ } else if (regs.prefetch020_valid[0] && regs.prefetch020_valid[1]) {
+ // Finished?
+ fill_prefetch_030_ntx_continue();
+ } else if (mmu030_opcode == -1) {
+ // Previous branch instruction finished successfully but its pipeline refill
+ // step caused the exception, retry the refill, do not retry branch instruction.
+ fill_prefetch_030_ntx();
}
+ }
- if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) {
+ if ((ssw & MMU030_SSW_DF) && (ssw & MMU030_SSW_RM)) {
- // Locked-Read-Modify-Write restarts whole instruction.
- mmu030_ad[0].done = false;
+ // Locked-Read-Modify-Write restarts whole instruction.
+ mmu030_ad[0].done = false;
- } else if (ssw & MMU030_SSW_DF) {
- // retry faulted access
- uaecptr addr = fault_addr;
- bool read = (ssw & MMU030_SSW_RW) != 0;
- int size = (ssw & MMU030_SSW_SIZE_B) ? sz_byte : ((ssw & MMU030_SSW_SIZE_W) ? sz_word : sz_long);
- int fc = ssw & 7;
+ } else if (ssw & MMU030_SSW_DF) {
+ // retry faulted access
+ uaecptr addr = fault_addr;
+ bool read = (ssw & MMU030_SSW_RW) != 0;
+ int size = (ssw & MMU030_SSW_SIZE_B) ? sz_byte : ((ssw & MMU030_SSW_SIZE_W) ? sz_word : sz_long);
+ int fc = ssw & 7;
#if MMU030_DEBUG
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
- write_log(_T("68030 MMU MOVEM %04x retry but MMU030_STATEFLAG1_MOVEM2 was already set!?\n"), mmu030_opcode);
- }
- } else {
- if (mmu030_ad[idxsize].done) {
- write_log(_T("68030 MMU ins %04x retry but it was already marked as done!?\n"), mmu030_opcode);
- }
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
+ write_log(_T("68030 MMU MOVEM %04x retry but MMU030_STATEFLAG1_MOVEM2 was already set!?\n"), mmu030_opcode);
}
+ } else {
+ if (idxsize >= 0 && mmu030_ad[idxsize].done) {
+ write_log(_T("68030 MMU ins %04x retry but it was already marked as done!?\n"), mmu030_opcode);
+ }
+ }
#endif
- if (read) {
- if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
- mmu030_unaligned_read_continue(addr, fc, read_dcache030_retry);
- } else {
- switch (size)
- {
- case sz_byte:
- mmu030_data_buffer_out = read_data_030_fc_bget(addr, fc);
- break;
- case sz_word:
- mmu030_data_buffer_out = read_data_030_fc_wget(addr, fc);
- break;
- case sz_long:
- mmu030_data_buffer_out = read_data_030_fc_lget(addr, fc);
- break;
- }
- }
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
- } else {
- mmu030_ad[idxsize].val = mmu030_data_buffer_out;
- mmu030_ad[idxsize].done = true;
- }
+ if (read) {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
+ mmu030_unaligned_read_continue(addr, fc, read_dcache030_retry);
} else {
- if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
- mmu030_unaligned_write_continue(addr, fc, write_dcache030_retry);
- } else {
- switch (size)
- {
- case sz_byte:
- write_data_030_fc_bput(addr, mmu030_data_buffer_out, fc);
- break;
- case sz_word:
- write_data_030_fc_wput(addr, mmu030_data_buffer_out, fc);
- break;
- case sz_long:
- write_data_030_fc_lput(addr, mmu030_data_buffer_out, fc);
- break;
- }
+ switch (size)
+ {
+ case sz_byte:
+ mmu030_data_buffer_out = read_data_030_fc_bget(addr, fc);
+ break;
+ case sz_word:
+ mmu030_data_buffer_out = read_data_030_fc_wget(addr, fc);
+ break;
+ case sz_long:
+ mmu030_data_buffer_out = read_data_030_fc_lget(addr, fc);
+ break;
}
- if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
- mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
- } else {
- mmu030_ad[idxsize].done = true;
+ }
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
+ } else if (idxsize >= 0) {
+ mmu030_ad[idxsize].val = mmu030_data_buffer_out;
+ mmu030_ad[idxsize].done = true;
+ }
+ } else {
+ if (mmu030_state[1] & MMU030_STATEFLAG1_SUBACCESS0) {
+ mmu030_unaligned_write_continue(addr, fc, write_dcache030_retry);
+ } else {
+ switch (size)
+ {
+ case sz_byte:
+ write_data_030_fc_bput(addr, mmu030_data_buffer_out, fc);
+ break;
+ case sz_word:
+ write_data_030_fc_wput(addr, mmu030_data_buffer_out, fc);
+ break;
+ case sz_long:
+ write_data_030_fc_lput(addr, mmu030_data_buffer_out, fc);
+ break;
}
}
+ if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM1) {
+ mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM2;
+ } else if (idxsize >= 0) {
+ mmu030_ad[idxsize].done = true;
+ }
}
+ }
- if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
- mmu030_retry = false;
+ if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
+ mmu030_retry = false;
+ if (doprefetch) {
fill_prefetch_030_ntx();
}
-
- } else {
-
- m68k_areg (regs, 7) += 32;
-
- regs.sr = sr;
- MakeFromSR_T0();
- if (pc & 1) {
- exception3i(0x4E73, pc);
- return;
- }
- m68k_setpci(pc);
-
}
}
}
if ((dp & 0x04) == 0x00 && name) {
- _stprintf(p, _T("%s,"), name);
- p += _tcslen(p);
- }
+ _stprintf(p, _T("%s,"), name);
+ p += _tcslen(p);
+ }
if (dr[0] && (dp & 0x04) == 0) {
- _stprintf(p, _T("%s%s,"), dr, mult);
- p += _tcslen(p);
- }
+ _stprintf(p, _T("%s%s,"), dr, mult);
+ p += _tcslen(p);
+ }
if (dp & 3) {
if (p[-1] == ',')
}
if (dr[0] && (dp & 0x04) != 0) {
- _stprintf(p, _T("%s%s,"), dr, mult);
- p += _tcslen(p);
- }
+ _stprintf(p, _T("%s%s,"), dr, mult);
+ p += _tcslen(p);
+ }
if ((dp & 0x03) == 0x02) {
outer = (uae_s32)(uae_s16)get_iword_debug(pc);
x_put_long (m68k_areg (regs, 7), oldpc);
break;
case 0xB: // long bus cycle fault stack frame (68020, 68030)
- // We always use B frame because it is easier to emulate,
- // our PC always points at start of instruction but A frame assumes
- // it is + 2 and handling this properly is not easy.
// Store state information to internal register space
#if MMU030_DEBUG
if (mmu030_idx >= MAX_MMU030_ACCESS) {
m68k_areg (regs, 7) -= 4;
x_put_long (m68k_areg (regs, 7), mmu030_disp_store[1]);
/* fall through */
- case 0xA: // short bus cycle fault stack frame (68020, 68030)
+ case 0xA:
+ // short bus cycle fault stack frame (68020, 68030)
+ // used when instruction's last write causes bus fault
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), mmu030_disp_store[0]);
+ if (format == 0xb) {
+ x_put_long(m68k_areg(regs, 7), mmu030_disp_store[0]);
+ } else {
+ uae_u32 ps = (regs.prefetch020_valid[0] ? 1 : 0) | (regs.prefetch020_valid[1] ? 2 : 0) | (regs.prefetch020_valid[2] ? 4 : 0);
+ ps |= ((regs.pipeline_r8[0] & 7) << 8);
+ ps |= ((regs.pipeline_r8[1] & 7) << 11);
+ ps |= ((regs.pipeline_pos & 15) << 16);
+ ps |= ((regs.pipeline_stop & 15) << 20);
+ x_put_long(m68k_areg(regs, 7), ps);
+ }
m68k_areg (regs, 7) -= 4;
// Data output buffer = value that was going to be written
x_put_long (m68k_areg (regs, 7), regs.wb3_data);
m68k_areg (regs, 7) -= 4;
- x_put_long (m68k_areg (regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16)); // Internal register (opcode storage)
+ if (format == 0xb) {
+ x_put_long(m68k_areg(regs, 7), (mmu030_opcode & 0xffff) | (regs.prefetch020[0] << 16)); // Internal register (opcode storage)
+ } else {
+ x_put_long(m68k_areg(regs, 7), regs.irc | (regs.prefetch020[0] << 16)); // Internal register (opcode storage)
+ }
m68k_areg (regs, 7) -= 4;
x_put_long (m68k_areg (regs, 7), regs.mmu_fault_addr); // data cycle fault address
m68k_areg (regs, 7) -= 2;
m68k_areg (regs, 7) -= 2;
x_put_word (m68k_areg (regs, 7), ssw);
m68k_areg (regs, 7) -= 2;
- x_put_word (m68k_areg (regs, 7), 0); // Internal register
+ x_put_word (m68k_areg (regs, 7), regs.wb2_address); // = mmu030_state[1]);
break;
default:
write_log(_T("Unknown exception stack frame format: %X\n"), format);
m68k_areg (regs, 7) = regs.isp;
Exception_build_stack_frame (oldpc, currpc, regs.mmu_ssw, nr, 0x1);
} else if (nr == 2) {
- if (0) {
- // not that simple
+ if (1 && (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) {
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xA);
} else {
Exception_build_stack_frame(oldpc, currpc, regs.mmu_ssw, nr, 0xB);
if (mmu030_opcode == -1) {
// full prefetch fill access fault
- // TODO: this should create shorter A-frame
mmufixup[0].reg = -1;
mmufixup[1].reg = -1;
- } else if (!(mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE)) {
+ } else if (mmu030_state[1] & MMU030_STATEFLAG1_LASTWRITE) {
+ mmufixup[0].reg = -1;
+ mmufixup[1].reg = -1;
+ } else {
regflags.cznv = f.cznv;
regflags.x = f.x;
static void pipeline_020(uaecptr pc)
{
uae_u16 w = regs.prefetch020[1];
+
if (regs.prefetch020_valid[1] == 0) {
regs.pipeline_stop = -1;
return;