m68000: When a SR S-flag update happens in parallel to a bus access, be careful to delay the update to after the access because it is otherwise seen too early through fc, and acts on mmus&co. Fixes hp_ipc [ajrhacker, O. Galibert]

This commit is contained in:
Olivier Galibert 2023-06-02 11:59:59 +02:00
parent 265d9a542b
commit f4dccdc1c5
15 changed files with 71972 additions and 71933 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -211,6 +211,7 @@ void m68000_device::device_start()
save_item(NAME(m_movems));
save_item(NAME(m_isr));
save_item(NAME(m_sr));
save_item(NAME(m_new_sr));
save_item(NAME(m_dbin));
save_item(NAME(m_dbout));
save_item(NAME(m_edb));
@ -255,6 +256,7 @@ void m68000_device::device_start()
m_movems = 0;
m_isr = 0;
m_sr = 0;
m_new_sr = 0;
m_dbin = 0;
m_dbout = 0;
m_edb = 0;
@ -394,6 +396,8 @@ void m68000_device::execute_set_input(int inputnum, int state)
m_int_level = blevel;
logerror("irq %s %d vstate %02x level %d\n", inputnum, state, vstate, m_int_level);
/* A transition from < 7 to 7 always interrupts (NMI) */
/* Note: Level 7 can also level trigger like a normal IRQ */
// FIXME: This may cause unintended level 7 interrupts if one or two IPL lines are asserted

View File

@ -154,7 +154,7 @@ protected:
u32 m_sp; // 15 or 16, index of currently active sp
int m_icount, m_bcount, m_count_before_instruction_step, m_t;
u32 m_movems;
u16 m_isr, m_sr, m_dbin, m_dbout, m_edb;
u16 m_isr, m_sr, m_new_sr, m_dbin, m_dbout, m_edb;
u16 m_irc, m_ir, m_ird, m_ftu, m_aluo, m_alue, m_alub, m_movemr, m_irdi;
u16 m_base_ssw, m_ssw;
u8 m_dcr;

View File

@ -913,7 +913,7 @@ def code_find_deps(ci):
if t & DEP.atl:
t |= DEP.ath
return [t, expr_deps(ci[2:])]
elif ci[0] == "=sr" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=8h" or ci[0] == "=8xh" or ci[0] == "=8xl" or ci[0] == "=16l" or ci[0] == "=16h":
elif ci[0] == "=sr" or ci[0] == "=srd" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=8h" or ci[0] == "=8xh" or ci[0] == "=8xl" or ci[0] == "=16l" or ci[0] == "=16h":
return [regdep[ci[1]], expr_deps(ci[2:])]
elif ci[0] == "=sri" or ci[0] == "=sri7":
return [regdep[R.sr], 0]
@ -1636,7 +1636,10 @@ def generate_base_code_for_microcode(ir, irmask, madr, tvn, group01):
if ftu_to_sr and not to_ccr:
assert(ftu_to_ccr)
code_to_sort.append(["=sr", R.sr, R.ftu])
if wait_bus_finish:
code_to_sort.append(["=srd", R.sr, R.ftu])
else:
code_to_sort.append(["=sr", R.sr, R.ftu])
elif ftu_to_ccr:
code_to_sort.append(["=ccr", R.sr, R.ftu])
@ -1713,7 +1716,7 @@ def generate_base_code_for_microcode(ir, irmask, madr, tvn, group01):
sort_and_append(code_to_sort, code)
if wait_bus_finish:
code.append(["bus_end"])
code.append(["bus_end", ftu_to_sr and not to_ccr])
if to_irc:
code.append(["=", R.irc, R.edb])
@ -1787,7 +1790,7 @@ def analyze_register_usage(code):
usage = { 'rx': False, 'ry': False, 't': False }
for cib in code:
for ci in cib:
if ci[0] == "=" or ci[0] == "=sr" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=16l" or ci[0] == "=16h" or ci[0] == "=8xl" or ci[0] == "=8xh" or ci[0] == "=8h":
if ci[0] == "=" or ci[0] == "=sr" or ci[0] == "=srd" or ci[0] == "=ccr" or ci[0] == "=8" or ci[0] == "=16l" or ci[0] == "=16h" or ci[0] == "=8xl" or ci[0] == "=8xh" or ci[0] == "=8h":
from_reg(ci[1], usage)
in_expression(ci[2:], usage)
if ci[0] == "=t":
@ -1917,9 +1920,11 @@ def propagate_bus_access(blocks, code, critical, gen_mode):
bus_access = ci
elif ci[0] == 'bus_end':
if bus_access:
sr_update = ci.pop()
ci.append(bid)
ci += bus_access[1:]
ci.append(critical)
ci.append(sr_update)
bus_access = None
if (gen_mode & GEN.m68008) and ci[2] != 2 and not ci[3]:
bid += 4
@ -2223,6 +2228,10 @@ def generate_source_from_code(code, gen_mode):
source.append("\t}")
if not (gen_mode & GEN.full):
source.append("\t[[fallthrough]]; case %d:" % (cid+1))
if ci[10]:
source.append("\tm_sr = m_new_sr;")
source.append("\tupdate_user_super();")
source.append("\tupdate_interrupt();")
cid += 2
if is_interrupt_vector_lookup:
source.append("\tend_interrupt_vector_lookup();")
@ -2236,6 +2245,8 @@ def generate_source_from_code(code, gen_mode):
source.append("\t}")
elif ci[0] == "=":
source.append("\t%s = %s;" % (regname[ci[1]], make_expression(ci[2:])))
elif ci[0] == "=srd":
source.append("\tm_new_sr = m_isr = %s & (SR_CCR|SR_SR);" % make_expression(ci[2:]))
elif ci[0] == "=sr":
source.append("\t%s = m_isr = %s & (SR_CCR|SR_SR);" % (regname[ci[1]], make_expression(ci[2:])))
source.append("\tupdate_user_super();")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff