Re: [hatari-devel] Suspected Hatari 2.3.0 regression (prefetch?)

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Eero Tamminen schrieb:

Because there aren't more programs requiring
MMU with Hatari v2.3, I suspect this issue to
be specific just to certain instructions or
addressing modes.

As I've written before: On the *68000* MOVEM from memory to registers
causes an extra memory access. Of course, in many cases this is not an
issue; however, it becomes a problem if this extra access causes a bus
error.

However, as I've also written before: I'm unsure this is true for the
*68030*. If there's no extra access on a real 68030 (which is what I
suspect), Hatari's emulation should not make this extra access, either.

As for why it does not crash with MMU enabled: This has nothing to do
with the MMU per se but with the fact that Hatari uses different code paths:

Without MMU, 68030 MOVEM.L (Ax)+,... is handled in cpuemu_23.c which is
auto-generated to contain...

/* MVMEL.L #<data>.W,(An)+ */
void REGPARAM2 op_4cd8_23_ff(uae_u32 opcode)
{
	int count_cycles = 0;
	uae_u32 real_opcode = opcode;
	uae_u32 dstreg = real_opcode & 7;
	OpcodeFamily = 37;
	uae_u16 mask = get_word_ce030_prefetch(2);
	uae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;
	uaecptr srca;
	srca = m68k_areg(regs, dstreg);
	while (dmask) {
		m68k_dreg(regs, movem_index1[dmask]) = x_get_long(srca);
		count_cycles += 4 * CYCLE_UNIT / 2;
		srca += 4;
		dmask = movem_next[dmask];
	}
	while (amask) {
		m68k_areg(regs, movem_index1[amask]) = x_get_long(srca);
		count_cycles += 4 * CYCLE_UNIT / 2;
		srca += 4;
		amask = movem_next[amask];
	}
	m68k_areg(regs, dstreg) = srca;
	x_get_word(srca);
	ipl_fetch();
	regs.irc = get_word_ce030_prefetch_opcode(4);
	m68k_incpci(4);
	return;
}

Note the extra access "x_get_word(srca)", which is what causes the bus
error.


With MMU, 68030 MOVEM.L (Ax)+,... is handled in cpuemu_35.c:

/* MVMEL.L #<data>.W,(An)+ */
void REGPARAM2 op_4cd8_35_ff(uae_u32 opcode)
{
	int count_cycles = 0;
	uae_u32 real_opcode = opcode;
	uae_u32 dstreg = real_opcode & 7;
	OpcodeFamily = 37;
	uae_u16 mask = get_iword_mmu030c_state(2);
	uae_u32 dmask = mask & 0xff, amask = (mask >> 8) & 0xff;
	uaecptr srca;
	srca = m68k_areg(regs, dstreg);
	mmu030_state[1] |= MMU030_STATEFLAG1_MOVEM1;
	int movem_cnt = 0;
	uae_u32 val;
	srca = state_store_mmu030(srca);
	while (dmask) {
		uae_u16 nextmask = movem_next[dmask];
		if (mmu030_state[0] == movem_cnt) {
			if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
				mmu030_state[1] &= [...]
				val = mmu030_data_buffer_out;
			} else {
				val = get_long_mmu030c(srca);
			}
			m68k_dreg (regs, movem_index1[dmask]) = val;
			mmu030_state[0]++;
		}
		srca += 4;
		movem_cnt++;
		dmask = nextmask;
	}
	while (amask) {
		uae_u16 nextmask = movem_next[amask];
		if (mmu030_state[0] == movem_cnt) {
			if (mmu030_state[1] & MMU030_STATEFLAG1_MOVEM2) {
				mmu030_state[1] &= [...]
				val = mmu030_data_buffer_out;
			} else {
				val = get_long_mmu030c(srca);
			}
			m68k_areg (regs, movem_index1[amask]) = val;
			mmu030_state[0]++;
		}
		srca += 4;
		movem_cnt++;
		amask = nextmask;
	}
	m68k_areg(regs, dstreg) = srca;
	ipl_fetch();
	regs.irc = get_iword_mmu030c_opcode_state(4);
	m68k_incpci(4);
	return;
}

Notice how this does *not* include the extra access. Which is why there
is no bus error, anymore. Hence, the emulation is contradictory: only
one function can be right about this.

Regards
Christian
--
Christian Zietz  -  CHZ-Soft  -  czietz@xxxxxxx
WWW: https://www.chzsoft.de/
PGP/GnuPG-Key-ID: 0x52CB97F66DA025CA / 0x6DA025CA



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/