mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
m68008: Implement as a 68000 variant
m68000mcu: Extract from m68000
This commit is contained in:
parent
9ce44eaf8e
commit
78661e9aa9
@ -1950,10 +1950,18 @@ if CPUS["M680X0"] then
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sif.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sdp.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sip.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sdfm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sifm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sdpm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000-sipm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu-head.h",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu-sdfm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu-sifm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu-sdpm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu-sipm.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu.h",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68000mcu.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008-head.h",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008-sdf8.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008-sif8.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008-sdp8.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008-sip8.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008.h",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68008.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m68000/m68010.h",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,10 +25,12 @@ m68000_device::m68000_device(const machine_config &mconfig, device_type type, co
|
||||
m_opcodes_config("opcodes", ENDIANNESS_BIG, 16, 24),
|
||||
m_uprogram_config("uprogram", ENDIANNESS_BIG, 16, 24),
|
||||
m_uopcodes_config("uopcodes", ENDIANNESS_BIG, 16, 24),
|
||||
m_cpu_space_config("cpu_space", ENDIANNESS_BIG, 16, 24, 0, address_map_constructor(FUNC(m68000_device::default_autovectors_map), this))
|
||||
m_cpu_space_config("cpu_space", ENDIANNESS_BIG, 16, 24, 0, address_map_constructor(FUNC(m68000_device::default_autovectors_map), this)),
|
||||
m_mmu(nullptr),
|
||||
m_disable_spaces(false),
|
||||
m_disable_specifics(false),
|
||||
m_disable_interrupt_callback(false)
|
||||
{
|
||||
m_mmu = nullptr;
|
||||
m_disable_interrupt_callback = false;
|
||||
}
|
||||
|
||||
void m68000_device::abort_access(u32 reason)
|
||||
@ -150,7 +152,7 @@ device_memory_interface::space_config_vector m68000_device::memory_space_config(
|
||||
void m68000_device::default_autovectors_map(address_map &map)
|
||||
{
|
||||
if(m_cpu_space_id == AS_CPU_SPACE && !has_configured_map(AS_CPU_SPACE)) {
|
||||
offs_t mask = make_bitmask<offs_t>(24) - 0xf;
|
||||
offs_t mask = make_bitmask<offs_t>(m_cpu_space_config.m_addr_width) - 0xf;
|
||||
map(mask + 0x3, mask + 0x3).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(1); }));
|
||||
map(mask + 0x5, mask + 0x5).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(2); }));
|
||||
map(mask + 0x7, mask + 0x7).before_time(*this, FUNC(m68000_device::vpa_sync)).after_delay(*this, FUNC(m68000_device::vpa_after)).lr8(NAME([] () -> u8 { return autovector(3); }));
|
||||
@ -170,17 +172,21 @@ void m68000_device::device_start()
|
||||
m_rte_instr_callback.resolve();
|
||||
m_tas_write_callback.resolve();
|
||||
|
||||
m_s_program = &space(AS_PROGRAM);
|
||||
m_s_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_s_program;
|
||||
m_s_uprogram = has_space(AS_USER_PROGRAM) ? &space(AS_USER_PROGRAM) : m_s_program;
|
||||
m_s_uopcodes = has_space(AS_USER_OPCODES) ? &space(AS_USER_OPCODES) : has_space(AS_USER_PROGRAM) ? m_s_uprogram : m_s_opcodes;
|
||||
m_s_cpu_space = &space(m_cpu_space_id);
|
||||
if(!m_disable_spaces) {
|
||||
m_s_program = &space(AS_PROGRAM);
|
||||
m_s_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_s_program;
|
||||
m_s_uprogram = has_space(AS_USER_PROGRAM) ? &space(AS_USER_PROGRAM) : m_s_program;
|
||||
m_s_uopcodes = has_space(AS_USER_OPCODES) ? &space(AS_USER_OPCODES) : has_space(AS_USER_PROGRAM) ? m_s_uprogram : m_s_opcodes;
|
||||
m_s_cpu_space = &space(m_cpu_space_id);
|
||||
}
|
||||
|
||||
m_s_program->specific(m_r_program);
|
||||
m_s_opcodes->specific(m_r_opcodes);
|
||||
m_s_uprogram->specific(m_r_uprogram);
|
||||
m_s_uopcodes->specific(m_r_uopcodes);
|
||||
m_s_cpu_space->specific(m_cpu_space);
|
||||
if(!(m_disable_specifics || m_disable_spaces)) {
|
||||
m_s_program->specific(m_r_program);
|
||||
m_s_opcodes->specific(m_r_opcodes);
|
||||
m_s_uprogram->specific(m_r_uprogram);
|
||||
m_s_uopcodes->specific(m_r_uopcodes);
|
||||
m_s_cpu_space->specific(m_cpu_space);
|
||||
}
|
||||
|
||||
if(m_mmu) {
|
||||
m_handlers_f = s_handlers_if;
|
||||
@ -467,105 +473,3 @@ void m68000_device::end_interrupt_vector_lookup()
|
||||
m_int_vector = (m_edb & 0xff) << 2;
|
||||
m_int_next_state = 0;
|
||||
}
|
||||
|
||||
m68000_mcu_device::m68000_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
|
||||
m68000_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
m_disable_interrupt_callback = true;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::execute_run()
|
||||
{
|
||||
internal_update(total_cycles());
|
||||
|
||||
m_icount -= m_count_before_instruction_step;
|
||||
if(m_icount < 0) {
|
||||
m_count_before_instruction_step = -m_icount;
|
||||
m_icount = 0;
|
||||
} else
|
||||
m_count_before_instruction_step = 0;
|
||||
|
||||
while(m_bcount && m_icount <= m_bcount)
|
||||
internal_update(total_cycles() + m_icount - m_bcount);
|
||||
|
||||
while(m_icount > 0) {
|
||||
for(;;) {
|
||||
if(m_icount > m_bcount && m_inst_substate)
|
||||
(this->*(m_handlers_p[m_inst_state]))();
|
||||
|
||||
while(m_icount > m_bcount) {
|
||||
if(m_inst_state >= S_first_instruction) {
|
||||
m_ipc = m_pc - 2;
|
||||
m_irdi = m_ird;
|
||||
|
||||
if(machine().debug_flags & DEBUG_FLAG_ENABLED)
|
||||
debugger_instruction_hook(m_ipc);
|
||||
}
|
||||
(this->*(m_handlers_f[m_inst_state]))();
|
||||
}
|
||||
|
||||
if(m_post_run)
|
||||
do_post_run();
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(m_icount > 0)
|
||||
while(m_bcount && m_icount <= m_bcount)
|
||||
internal_update(total_cycles() + m_icount - m_bcount);
|
||||
if(m_icount > 0 && m_inst_substate) {
|
||||
(this->*(m_handlers_p[m_inst_state]))();
|
||||
if(m_post_run)
|
||||
do_post_run();
|
||||
}
|
||||
}
|
||||
|
||||
if(m_icount < 0) {
|
||||
m_count_before_instruction_step = -m_icount;
|
||||
m_icount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void m68000_mcu_device::recompute_bcount(uint64_t event_time)
|
||||
{
|
||||
if(!event_time || event_time >= total_cycles() + m_icount) {
|
||||
m_bcount = 0;
|
||||
return;
|
||||
}
|
||||
m_bcount = total_cycles() + m_icount - event_time;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::add_event(uint64_t &event_time, uint64_t new_event)
|
||||
{
|
||||
if(!new_event)
|
||||
return;
|
||||
if(!event_time || event_time > new_event)
|
||||
event_time = new_event;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::device_start()
|
||||
{
|
||||
m68000_device::device_start();
|
||||
|
||||
if(m_mmu) {
|
||||
m_handlers_f = s_handlers_ifm;
|
||||
m_handlers_p = s_handlers_ipm;
|
||||
} else {
|
||||
m_handlers_f = s_handlers_dfm;
|
||||
m_handlers_p = s_handlers_dpm;
|
||||
}
|
||||
}
|
||||
|
||||
void m68000_mcu_device::set_current_interrupt_level(u32 level)
|
||||
{
|
||||
if(level == m_int_level)
|
||||
return;
|
||||
|
||||
m_int_level = level;
|
||||
|
||||
/* A transition from < 7 to 7 always interrupts (NMI) */
|
||||
/* Note: Level 7 can also level trigger like a normal IRQ */
|
||||
if(m_int_level == 7)
|
||||
m_nmi_pending = true;
|
||||
|
||||
update_interrupt();
|
||||
}
|
||||
|
@ -120,10 +120,6 @@ protected:
|
||||
static const handler s_handlers_if[];
|
||||
static const handler s_handlers_dp[];
|
||||
static const handler s_handlers_ip[];
|
||||
static const handler s_handlers_dfm[];
|
||||
static const handler s_handlers_ifm[];
|
||||
static const handler s_handlers_dpm[];
|
||||
static const handler s_handlers_ipm[];
|
||||
|
||||
const handler *m_handlers_f;
|
||||
const handler *m_handlers_p;
|
||||
@ -148,6 +144,9 @@ protected:
|
||||
// MMU, if one present
|
||||
mmu *m_mmu;
|
||||
|
||||
bool m_disable_spaces;
|
||||
bool m_disable_specifics;
|
||||
|
||||
// Internal processor state, in inverse size order
|
||||
|
||||
u32 m_da[17]; // 8 data, 7 address, usp, ssp in that order
|
||||
@ -196,7 +195,7 @@ protected:
|
||||
void end_interrupt_vector_lookup();
|
||||
|
||||
// update needed stuff on priviledge level switch
|
||||
void update_user_super();
|
||||
virtual void update_user_super();
|
||||
|
||||
// update needed stuff on interrupt level switch
|
||||
void update_interrupt();
|
||||
@ -928,22 +927,6 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class m68000_mcu_device : public m68000_device
|
||||
{
|
||||
protected:
|
||||
m68000_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual void execute_run() override;
|
||||
void recompute_bcount(uint64_t event_time);
|
||||
static void add_event(uint64_t &event_time, uint64_t new_event);
|
||||
void internal_update();
|
||||
|
||||
virtual void internal_update(uint64_t current_time) = 0;
|
||||
virtual void device_start() override;
|
||||
|
||||
void set_current_interrupt_level(u32 level);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(M68000, m68000_device)
|
||||
|
||||
#endif
|
||||
|
@ -799,6 +799,7 @@ class GEN(IntEnum):
|
||||
direct = 0x0001
|
||||
full = 0x0002
|
||||
mcu = 0x0004
|
||||
m68008 = 0x0008
|
||||
|
||||
# Load the instruction list
|
||||
|
||||
@ -1906,7 +1907,7 @@ def generate_code_from_blocks(blocks, ir, irmask, tvn, priv, group01):
|
||||
# Propagate bus accesses from bus initiation to access completion in
|
||||
# the code blocks
|
||||
|
||||
def propagate_bus_access(blocks, code, critical):
|
||||
def propagate_bus_access(blocks, code, critical, gen_mode):
|
||||
def propagate(blocks, code, seen, i, bus_access, bid, critical):
|
||||
if i in seen:
|
||||
return bid, critical
|
||||
@ -1920,7 +1921,10 @@ def propagate_bus_access(blocks, code, critical):
|
||||
ci += bus_access[1:]
|
||||
ci.append(critical)
|
||||
bus_access = None
|
||||
bid += 2
|
||||
if (gen_mode & GEN.m68008) and ci[2] != 2 and not ci[3]:
|
||||
bid += 4
|
||||
else:
|
||||
bid += 2
|
||||
elif ci[0] == "drop_critical":
|
||||
critical = False
|
||||
for nc in blocks[i][3]:
|
||||
@ -1947,30 +1951,30 @@ def detect_reset_toggling(blocks, code):
|
||||
|
||||
# Generic code generation
|
||||
|
||||
def generate_intermediate_code(a1, a2, a3, ir, irmask, tvn, critical, priv, group01, name):
|
||||
def generate_intermediate_code(a1, a2, a3, ir, irmask, tvn, critical, priv, group01, gen_mode, name):
|
||||
fwd, suc = generate_forward_graph(a1, a2, a3, ir, irmask)
|
||||
blocks = generate_blocks(fwd)
|
||||
# show_blocks(blocks)
|
||||
code = generate_code_from_blocks(blocks, ir, irmask, tvn, priv, group01)
|
||||
propagate_bus_access(blocks, code, critical)
|
||||
propagate_bus_access(blocks, code, critical, gen_mode)
|
||||
detect_reset_toggling(blocks, code)
|
||||
return code
|
||||
|
||||
|
||||
# Generate the code for an instruction
|
||||
|
||||
def generate_intermediate_code_from_instruction(ir, irmask, name):
|
||||
def generate_intermediate_code_from_instruction(ir, irmask, name, gen_mode):
|
||||
# Avoid the rel16 case when looking for rel8
|
||||
if (ir & 0xf000) == 0x6000 and irmask == 0xff00:
|
||||
ir |= 0x0002
|
||||
a1 = a1_pal_apply(ir)
|
||||
a2, a3 = a23_pal_apply(ir)
|
||||
return generate_intermediate_code(a1, a2, a3, ir, irmask, None, False, priv_test(ir), False, name)
|
||||
return generate_intermediate_code(a1, a2, a3, ir, irmask, None, False, priv_test(ir), False, gen_mode, name)
|
||||
|
||||
# Generate the code for a state
|
||||
|
||||
def generate_intermediate_code_from_state(state):
|
||||
return generate_intermediate_code(state[0], 0x3ff, 0x3ff, 0xffff, 0, state[2], state[3], False, True, "state_" + state[1])
|
||||
def generate_intermediate_code_from_state(state, gen_mode):
|
||||
return generate_intermediate_code(state[0], 0x3ff, 0x3ff, 0xffff, 0, state[2], state[3], False, True, gen_mode, "state_" + state[1])
|
||||
|
||||
|
||||
# Create the base C++ method name for handling a state
|
||||
@ -2002,7 +2006,7 @@ def generate_source_from_code(code, gen_mode):
|
||||
if ci == R.dcro8:
|
||||
return "1 << (m_dcr & 7)"
|
||||
if ci == "ftu-i":
|
||||
return "0xfff0 | ((m_next_state >> 23) & 0xe)"
|
||||
return "0xfff1 | ((m_next_state >> 23) & 0xe)" if gen_mode & GEN.m68008 else "0xfff0 | ((m_next_state >> 23) & 0xe)"
|
||||
if ci == "ftu-ssw":
|
||||
return "(m_ftu & ~0x1f) | m_ssw"
|
||||
if ci == "trap-tvn":
|
||||
@ -2107,77 +2111,122 @@ def generate_source_from_code(code, gen_mode):
|
||||
is_interrupt_vector_lookup = not ci[4] and ci[2] == 2
|
||||
if is_interrupt_vector_lookup:
|
||||
source.append("\tstart_interrupt_vector_lookup();")
|
||||
if not (gen_mode & GEN.full):
|
||||
source.append("\t[[fallthrough]]; case %d:" % (ci[1]))
|
||||
if ci[4]:
|
||||
if ci[3]:
|
||||
if ci[8]:
|
||||
source.append("\tif(!m_tas_write_callback.isnull())")
|
||||
source.append("\t\tm_tas_write_callback(m_aob, m_dbout);")
|
||||
source.append("\telse")
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\t\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
elif gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, 0xffff);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if ci[2] == 2:
|
||||
# cpu space access, e.g. interrupt vector lookup
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = m_cpu_space.read_interruptible(m_aob);")
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_cpu(m_aob, 0xffff);")
|
||||
elif ci[3]:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
source.append("\tif(!(m_aob & 1))")
|
||||
source.append("\t\tm_edb >>= 8;")
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob & ~1);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, 0xffff);" % (["program", "data"][ci[2]]))
|
||||
source.append("\tm_icount -= 4;")
|
||||
if ci[8]:
|
||||
access_steps = 2 if (gen_mode & GEN.m68008) and ci[2] != 2 and not ci[3] else 1
|
||||
cid = ci[1]
|
||||
for access_step in range(access_steps):
|
||||
if not (gen_mode & GEN.full):
|
||||
source.append("\t[[fallthrough]]; case %d:" % (cid))
|
||||
if ci[4]:
|
||||
if ci[3]:
|
||||
if ci[8]:
|
||||
source.append("\tif(!m_tas_write_callback.isnull())")
|
||||
source.append("\t\tm_tas_write_callback(m_aob, m_dbout);")
|
||||
source.append("\telse")
|
||||
if gen_mode & GEN.m68008:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t\t%s.write_interruptible(m_aob, m_dbout);" % (["m_opcodes8", "m_program8"][ci[2]]))
|
||||
else:
|
||||
source.append("\t\tm_mmu8->write_%s(m_aob, m_dbout);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\t\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
elif gen_mode & GEN.m68008:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob, m_dbout);" % (["m_opcodes8", "m_program8"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_mmu8->write_%s(m_aob, m_dbout);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, (m_aob & 1) ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
elif gen_mode & GEN.m68008:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob%s, m_dbout%s);" % (["m_opcodes8", "m_program8"][ci[2]], " | 1" if access_step == 1 else " & ~1", "" if access_step == 1 else " >> 8"))
|
||||
else:
|
||||
source.append("\tm_mmu8->write_%s(m_aob%s, m_dbout%s);" % (["program", "data"][ci[2]], " | 1" if access_step == 1 else " & ~1", "" if access_step == 1 else " >> 8"))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\t%s.write_interruptible(m_aob & ~1, m_dbout);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_mmu->write_%s(m_aob & ~1, m_dbout, 0xffff);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if ci[2] == 2:
|
||||
# cpu space access, e.g. interrupt vector lookup
|
||||
if gen_mode & GEN.m68008:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = m_cpu_space8.read_interruptible(m_aob);")
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu8->read_cpu(m_aob);")
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = m_cpu_space.read_interruptible(m_aob);")
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_cpu(m_aob, 0xffff);")
|
||||
elif ci[3]:
|
||||
if gen_mode & GEN.m68008:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob);" % (["m_opcodes8", "m_program8"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu8->read_%s(m_aob);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, m_aob & 1 ? 0x00ff : 0xff00);" % (["program", "data"][ci[2]]))
|
||||
source.append("\tif(!(m_aob & 1))")
|
||||
source.append("\t\tm_edb >>= 8;")
|
||||
else:
|
||||
if gen_mode & GEN.m68008:
|
||||
if access_step == 1:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb |= %s.read_interruptible(m_aob | 1);" % (["m_opcodes8", "m_program8"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb |= m_mmu8->read_%s(m_aob | 1);" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob & ~1) << 8;" % (["m_opcodes8", "m_program8"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu8->read_%s(m_aob & ~1) << 8;" % (["program", "data"][ci[2]]))
|
||||
else:
|
||||
if gen_mode & GEN.direct:
|
||||
source.append("\tm_edb = %s.read_interruptible(m_aob & ~1);" % (["m_opcodes", "m_program"][ci[2]]))
|
||||
else:
|
||||
source.append("\tm_edb = m_mmu->read_%s(m_aob & ~1, 0xffff);" % (["program", "data"][ci[2]]))
|
||||
source.append("\tm_icount -= 4;")
|
||||
if ci[8]:
|
||||
if ci[4]:
|
||||
source.append("\tif(m_icount <= %s) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
|
||||
source.append("\t\tif(access_to_be_redone()) {")
|
||||
source.append("\t\t\tm_icount += 4;")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (cid-2))
|
||||
source.append("\t\t} else")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (cid+1))
|
||||
source.append("\t\treturn;")
|
||||
source.append("\t}")
|
||||
else:
|
||||
source.append("\tif(m_icount <= %s && access_to_be_redone()) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
|
||||
source.append("\t\tm_icount += 4;")
|
||||
source.append("\t\tm_inst_substate = %d;" % cid)
|
||||
source.append("\t\treturn;")
|
||||
source.append("\t}")
|
||||
else:
|
||||
source.append("\tif(m_icount <= %s) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
|
||||
source.append("\t\tif(access_to_be_redone()) {")
|
||||
source.append("\t\t\tm_icount += 4;")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (ci[1]-2))
|
||||
source.append("\t\t\tm_inst_substate = %d;" % cid)
|
||||
source.append("\t\t} else")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (ci[1]+1))
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (cid+1))
|
||||
source.append("\t\treturn;")
|
||||
source.append("\t}")
|
||||
else:
|
||||
source.append("\tif(m_icount <= %s && access_to_be_redone()) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
|
||||
source.append("\t\tm_icount += 4;")
|
||||
source.append("\t\tm_inst_substate = %d;" % ci[1])
|
||||
source.append("\t\treturn;")
|
||||
source.append("\t}")
|
||||
else:
|
||||
source.append("\tif(m_icount <= %s) {" % ("m_bcount" if gen_mode & GEN.mcu else "0"))
|
||||
source.append("\t\tif(access_to_be_redone()) {")
|
||||
source.append("\t\t\tm_icount += 4;")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % ci[1])
|
||||
source.append("\t\t} else")
|
||||
source.append("\t\t\tm_inst_substate = %d;" % (ci[1]+1))
|
||||
source.append("\t\treturn;")
|
||||
source.append("\t}")
|
||||
if not (gen_mode & GEN.full):
|
||||
source.append("\t[[fallthrough]]; case %d:" % (ci[1]+1))
|
||||
if not (gen_mode & GEN.full):
|
||||
source.append("\t[[fallthrough]]; case %d:" % (cid+1))
|
||||
cid += 2
|
||||
if is_interrupt_vector_lookup:
|
||||
source.append("\tend_interrupt_vector_lookup();")
|
||||
if not ci[3]:
|
||||
if not ci[3] and (ci[2] != 2 or not (gen_mode & GEN.m68008)):
|
||||
source.append("\tif(m_aob & 1) {")
|
||||
source.append("\t\tm_icount -= 4;")
|
||||
source.append("\t\tm_inst_state = %s;" % ("S_DOUBLE_FAULT" if ci[8] else "S_ADDRESS_ERROR"));
|
||||
@ -2312,22 +2361,26 @@ def generate_source_file(fname, cmd, gen_mode):
|
||||
suf = 'd' if gen_mode & GEN.direct else 'i'
|
||||
suf += 'f' if gen_mode & GEN.full else 'p'
|
||||
suf += 'm' if gen_mode & GEN.mcu else ''
|
||||
suf += '8' if gen_mode & GEN.m68008 else ''
|
||||
|
||||
print("Generating %s" % suf)
|
||||
|
||||
cpu = "m68008" if gen_mode & GEN.m68008 else "m68000_mcu" if gen_mode & GEN.mcu else "m68000"
|
||||
head = "m68008" if gen_mode & GEN.m68008 else "m68000mcu" if gen_mode & GEN.mcu else "m68000"
|
||||
|
||||
print("// Instruction handlers for the m68000 (%s, %s, %s)" % ("direct" if gen_mode & GEN.direct else "indirect", "full" if gen_mode & GEN.full else "partial", "mcu" if gen_mode & GEN.mcu else "cpu"), file=out)
|
||||
print("//", file=out)
|
||||
print("// Generated by m68000gen.py %s" % cmd, file=out)
|
||||
print("", file=out)
|
||||
print("#include \"emu.h\"", file=out)
|
||||
print("#include \"m68000.h\"", file=out)
|
||||
print("#include \"%s.h\"" % head, file=out)
|
||||
print("", file=out)
|
||||
|
||||
for st in states:
|
||||
# print(handler_name_for_state(st))
|
||||
code = generate_intermediate_code_from_state(st)
|
||||
code = generate_intermediate_code_from_state(st, gen_mode)
|
||||
source = generate_source_from_code(code, gen_mode)
|
||||
print("void m68000_device::%s_%s()" % (handler_name_for_state(st), suf), file=out)
|
||||
print("void %s_device::%s_%s()" % (cpu, handler_name_for_state(st), suf), file=out)
|
||||
print("{", file=out)
|
||||
for l in source:
|
||||
print(l, file=out)
|
||||
@ -2338,24 +2391,24 @@ def generate_source_file(fname, cmd, gen_mode):
|
||||
if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
|
||||
continue
|
||||
# print(handler_name_for_instruction(ii))
|
||||
code = generate_intermediate_code_from_instruction(ii[0], ii[1], " ".join(ii[2]))
|
||||
code = generate_intermediate_code_from_instruction(ii[0], ii[1], " ".join(ii[2]), gen_mode)
|
||||
source = generate_source_from_code(code, gen_mode)
|
||||
print("void m68000_device::%s_%s() // %04x %04x" % (handler_name_for_instruction(ii), suf, ii[0], ii[1]), file=out)
|
||||
print("void %s_device::%s_%s() // %04x %04x" % (cpu, handler_name_for_instruction(ii), suf, ii[0], ii[1]), file=out)
|
||||
print("{", file=out)
|
||||
for l in source:
|
||||
print(l, file=out)
|
||||
print("}", file=out)
|
||||
print("", file=out)
|
||||
|
||||
print("const m68000_device::handler m68000_device::s_handlers_%s[] = {" % suf, file=out)
|
||||
print("const %s_device::%s %s_device::s_handlers_%s[] = {" % (cpu, "handler8" if gen_mode & GEN.m68008 else "handlerm" if gen_mode & GEN.mcu else "handler", cpu, suf), file=out)
|
||||
for st in states:
|
||||
name = handler_name_for_state(st)
|
||||
print("\t&m68000_device::%s_%s," % (name, suf), file=out)
|
||||
print("\t&%s_device::%s_%s," % (cpu, name, suf), file=out)
|
||||
for ii in instructions:
|
||||
if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
|
||||
continue
|
||||
name = handler_name_for_instruction(ii)
|
||||
print("\t&m68000_device::%s_%s," % (name, suf), file=out)
|
||||
print("\t&%s_device::%s_%s," % (cpu, name, suf), file=out)
|
||||
print("};", file=out)
|
||||
|
||||
|
||||
@ -2373,7 +2426,7 @@ if sys.argv[1] == "i":
|
||||
if line == None or ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
|
||||
print("Illegal instruction")
|
||||
sys.exit(0)
|
||||
code = generate_intermediate_code_from_instruction(ii[0], ii[2], " ".join(ii[2]))
|
||||
code = generate_intermediate_code_from_instruction(ii[0], ii[2], " ".join(ii[2]), 0)
|
||||
source = generate_source_from_code(code, GEN.direct|GEN.full)
|
||||
print("# %s" % handler_name_for_instruction(ii))
|
||||
for l in source:
|
||||
@ -2422,7 +2475,39 @@ if sys.argv[1] == 'header':
|
||||
print("//", file=out)
|
||||
print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
|
||||
print("", file=out)
|
||||
for variant in ["df", "if", "dp", "ip", "dfm", "ifm", "dpm", "ipm"]:
|
||||
for variant in ["df", "if", "dp", "ip"]:
|
||||
for st in states:
|
||||
name = handler_name_for_state(st)
|
||||
print("void %s_%s();" % (name, variant), file=out)
|
||||
for ii in instructions:
|
||||
if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
|
||||
continue
|
||||
name = handler_name_for_instruction(ii)
|
||||
print("void %s_%s();" % (name, variant), file=out)
|
||||
|
||||
if sys.argv[1] == 'headerm':
|
||||
out = open(sys.argv[3], 'wt')
|
||||
print("// Header fragment for the handlers", file=out)
|
||||
print("//", file=out)
|
||||
print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
|
||||
print("", file=out)
|
||||
for variant in ["dfm", "ifm", "dpm", "ipm"]:
|
||||
for st in states:
|
||||
name = handler_name_for_state(st)
|
||||
print("void %s_%s();" % (name, variant), file=out)
|
||||
for ii in instructions:
|
||||
if ii[0] == 0xa000 or ii[0] == 0xf000 or ii[0] == 0x4afc:
|
||||
continue
|
||||
name = handler_name_for_instruction(ii)
|
||||
print("void %s_%s();" % (name, variant), file=out)
|
||||
|
||||
if sys.argv[1] == 'header8':
|
||||
out = open(sys.argv[3], 'wt')
|
||||
print("// Header fragment for the handlers", file=out)
|
||||
print("//", file=out)
|
||||
print("// Generated by m68000gen.py %s" % ' '.join(sys.argv[1:]), file=out)
|
||||
print("", file=out)
|
||||
for variant in ["df8", "if8", "dp8" ,"ip8"]:
|
||||
for st in states:
|
||||
name = handler_name_for_state(st)
|
||||
print("void %s_%s();" % (name, variant), file=out)
|
||||
@ -2457,3 +2542,15 @@ if sys.argv[1] == 'sdpm':
|
||||
|
||||
if sys.argv[1] == 'sipm':
|
||||
generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.mcu)
|
||||
|
||||
if sys.argv[1] == 'sdf8':
|
||||
generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct|GEN.full|GEN.m68008)
|
||||
|
||||
if sys.argv[1] == 'sif8':
|
||||
generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.full|GEN.m68008)
|
||||
|
||||
if sys.argv[1] == 'sdp8':
|
||||
generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.direct|GEN.m68008)
|
||||
|
||||
if sys.argv[1] == 'sip8':
|
||||
generate_source_file(sys.argv[3], ' '.join(sys.argv[1:]), GEN.m68008)
|
||||
|
6144
src/devices/cpu/m68000/m68000mcu-head.h
Normal file
6144
src/devices/cpu/m68000/m68000mcu-head.h
Normal file
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
109
src/devices/cpu/m68000/m68000mcu.cpp
Normal file
109
src/devices/cpu/m68000/m68000mcu.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert
|
||||
|
||||
#include "emu.h"
|
||||
#include "m68000mcu.h"
|
||||
|
||||
m68000_mcu_device::m68000_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
|
||||
m68000_device(mconfig, type, tag, owner, clock)
|
||||
{
|
||||
m_disable_interrupt_callback = true;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::execute_run()
|
||||
{
|
||||
internal_update(total_cycles());
|
||||
|
||||
m_icount -= m_count_before_instruction_step;
|
||||
if(m_icount < 0) {
|
||||
m_count_before_instruction_step = -m_icount;
|
||||
m_icount = 0;
|
||||
} else
|
||||
m_count_before_instruction_step = 0;
|
||||
|
||||
while(m_bcount && m_icount <= m_bcount)
|
||||
internal_update(total_cycles() + m_icount - m_bcount);
|
||||
|
||||
while(m_icount > 0) {
|
||||
for(;;) {
|
||||
if(m_icount > m_bcount && m_inst_substate)
|
||||
(this->*(m_handlers_p[m_inst_state]))();
|
||||
|
||||
while(m_icount > m_bcount) {
|
||||
if(m_inst_state >= S_first_instruction) {
|
||||
m_ipc = m_pc - 2;
|
||||
m_irdi = m_ird;
|
||||
|
||||
if(machine().debug_flags & DEBUG_FLAG_ENABLED)
|
||||
debugger_instruction_hook(m_ipc);
|
||||
}
|
||||
(this->*(m_handlers_f[m_inst_state]))();
|
||||
}
|
||||
|
||||
if(m_post_run)
|
||||
do_post_run();
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(m_icount > 0)
|
||||
while(m_bcount && m_icount <= m_bcount)
|
||||
internal_update(total_cycles() + m_icount - m_bcount);
|
||||
if(m_icount > 0 && m_inst_substate) {
|
||||
(this->*(m_handlers_p[m_inst_state]))();
|
||||
if(m_post_run)
|
||||
do_post_run();
|
||||
}
|
||||
}
|
||||
|
||||
if(m_icount < 0) {
|
||||
m_count_before_instruction_step = -m_icount;
|
||||
m_icount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void m68000_mcu_device::recompute_bcount(uint64_t event_time)
|
||||
{
|
||||
if(!event_time || event_time >= total_cycles() + m_icount) {
|
||||
m_bcount = 0;
|
||||
return;
|
||||
}
|
||||
m_bcount = total_cycles() + m_icount - event_time;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::add_event(uint64_t &event_time, uint64_t new_event)
|
||||
{
|
||||
if(!new_event)
|
||||
return;
|
||||
if(!event_time || event_time > new_event)
|
||||
event_time = new_event;
|
||||
}
|
||||
|
||||
void m68000_mcu_device::device_start()
|
||||
{
|
||||
m68000_device::device_start();
|
||||
|
||||
// Theoretically UB, in practice works, the alternative (putting
|
||||
// everything in m68000_device) is annoying
|
||||
if(m_mmu) {
|
||||
m_handlers_f = reinterpret_cast<const handler *>(s_handlers_ifm);
|
||||
m_handlers_p = reinterpret_cast<const handler *>(s_handlers_ipm);
|
||||
} else {
|
||||
m_handlers_f = reinterpret_cast<const handler *>(s_handlers_dfm);
|
||||
m_handlers_p = reinterpret_cast<const handler *>(s_handlers_dpm);
|
||||
}
|
||||
}
|
||||
|
||||
void m68000_mcu_device::set_current_interrupt_level(u32 level)
|
||||
{
|
||||
if(level == m_int_level)
|
||||
return;
|
||||
|
||||
m_int_level = level;
|
||||
|
||||
/* A transition from < 7 to 7 always interrupts (NMI) */
|
||||
/* Note: Level 7 can also level trigger like a normal IRQ */
|
||||
if(m_int_level == 7)
|
||||
m_nmi_pending = true;
|
||||
|
||||
update_interrupt();
|
||||
}
|
36
src/devices/cpu/m68000/m68000mcu.h
Normal file
36
src/devices/cpu/m68000/m68000mcu.h
Normal file
@ -0,0 +1,36 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert
|
||||
#ifndef MAME_CPU_M68000_M68000mcu_H
|
||||
#define MAME_CPU_M68000_M68000mcu_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "m68000.h"
|
||||
|
||||
class m68000_mcu_device : public m68000_device
|
||||
{
|
||||
protected:
|
||||
// Opcode handlers (d = direct, i = indirect, f = full, p = partial)
|
||||
using handlerm = void (m68000_mcu_device::*)();
|
||||
|
||||
#include "m68000mcu-head.h"
|
||||
|
||||
static const handlerm s_handlers_dfm[];
|
||||
static const handlerm s_handlers_ifm[];
|
||||
static const handlerm s_handlers_dpm[];
|
||||
static const handlerm s_handlers_ipm[];
|
||||
|
||||
m68000_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual void execute_run() override;
|
||||
void recompute_bcount(uint64_t event_time);
|
||||
static void add_event(uint64_t &event_time, uint64_t new_event);
|
||||
void internal_update();
|
||||
|
||||
virtual void internal_update(uint64_t current_time) = 0;
|
||||
virtual void device_start() override;
|
||||
|
||||
void set_current_interrupt_level(u32 level);
|
||||
};
|
||||
|
||||
#endif
|
6144
src/devices/cpu/m68000/m68008-head.h
Normal file
6144
src/devices/cpu/m68000/m68008-head.h
Normal file
File diff suppressed because it is too large
Load Diff
239435
src/devices/cpu/m68000/m68008-sdf8.cpp
Normal file
239435
src/devices/cpu/m68000/m68008-sdf8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274771
src/devices/cpu/m68000/m68008-sdp8.cpp
Normal file
274771
src/devices/cpu/m68000/m68008-sdp8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
239435
src/devices/cpu/m68000/m68008-sif8.cpp
Normal file
239435
src/devices/cpu/m68000/m68008-sif8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
274771
src/devices/cpu/m68000/m68008-sip8.cpp
Normal file
274771
src/devices/cpu/m68000/m68008-sip8.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Karl Stenerud
|
||||
// copyright-holders:Olivier Galibert
|
||||
|
||||
#include "emu.h"
|
||||
#include "m68008.h"
|
||||
@ -19,24 +19,84 @@ std::unique_ptr<util::disasm_interface> m68008fn_device::create_disassembler()
|
||||
}
|
||||
|
||||
m68008_device::m68008_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: m68000_musashi_device(mconfig, tag, owner, clock, M68008, 8,20)
|
||||
: m68008_device(mconfig, M68008, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
m68008_device::m68008_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||
: m68000_device(mconfig, type, tag, owner, clock),
|
||||
m_mmu8(nullptr)
|
||||
{
|
||||
m_cpu_space_config.m_addr_width = m_cpu_space_config.m_logaddr_width = 20;
|
||||
m_program_config.m_addr_width = m_program_config.m_logaddr_width = 20;
|
||||
m_opcodes_config.m_addr_width = m_opcodes_config.m_logaddr_width = 20;
|
||||
m_uprogram_config.m_addr_width = m_uprogram_config.m_logaddr_width = 20;
|
||||
m_uopcodes_config.m_addr_width = m_uopcodes_config.m_logaddr_width = 20;
|
||||
m_cpu_space_config.m_data_width = 8;
|
||||
m_program_config.m_data_width = 8;
|
||||
m_opcodes_config.m_data_width = 8;
|
||||
m_uprogram_config.m_data_width = 8;
|
||||
m_uopcodes_config.m_data_width = 8;
|
||||
|
||||
m_disable_specifics = true;
|
||||
}
|
||||
|
||||
void m68008_device::device_start()
|
||||
{
|
||||
m68000_musashi_device::device_start();
|
||||
init_cpu_m68008();
|
||||
m68000_device::device_start();
|
||||
|
||||
m_s_program->specific(m_r_program8);
|
||||
m_s_opcodes->specific(m_r_opcodes8);
|
||||
m_s_uprogram->specific(m_r_uprogram8);
|
||||
m_s_uopcodes->specific(m_r_uopcodes8);
|
||||
m_s_cpu_space->specific(m_cpu_space8);
|
||||
|
||||
// Theoretically UB, in practice works, the alternative (putting
|
||||
// everything in m68000_device) is annoying
|
||||
if(m_mmu8) {
|
||||
m_handlers_f = reinterpret_cast<const handler *>(s_handlers_if8);
|
||||
m_handlers_p = reinterpret_cast<const handler *>(s_handlers_ip8);
|
||||
} else {
|
||||
m_handlers_f = reinterpret_cast<const handler *>(s_handlers_df8);
|
||||
m_handlers_p = reinterpret_cast<const handler *>(s_handlers_dp8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void m68008_device::update_user_super()
|
||||
{
|
||||
if(m_sr & SR_S) {
|
||||
m_sp = 16;
|
||||
m_program8 = m_r_program8;
|
||||
m_opcodes8 = m_r_opcodes8;
|
||||
if(m_mmu8)
|
||||
m_mmu8->set_super(true);
|
||||
} else {
|
||||
m_sp = 15;
|
||||
m_program8 = m_r_uprogram8;
|
||||
m_opcodes8 = m_r_uopcodes8;
|
||||
if(m_mmu8)
|
||||
m_mmu8->set_super(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m68008fn_device::m68008fn_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: m68000_musashi_device(mconfig, tag, owner, clock, M68008FN, 8,22)
|
||||
: m68008_device(mconfig, M68008FN, tag, owner, clock)
|
||||
{
|
||||
m_cpu_space_config.m_addr_width = m_cpu_space_config.m_logaddr_width = 22;
|
||||
m_program_config.m_addr_width = m_program_config.m_logaddr_width = 22;
|
||||
m_opcodes_config.m_addr_width = m_opcodes_config.m_logaddr_width = 22;
|
||||
m_uprogram_config.m_addr_width = m_uprogram_config.m_logaddr_width = 22;
|
||||
m_uopcodes_config.m_addr_width = m_uopcodes_config.m_logaddr_width = 22;
|
||||
m_cpu_space_config.m_data_width = 8;
|
||||
m_program_config.m_data_width = 8;
|
||||
m_opcodes_config.m_data_width = 8;
|
||||
m_uprogram_config.m_data_width = 8;
|
||||
m_uopcodes_config.m_data_width = 8;
|
||||
}
|
||||
|
||||
void m68008fn_device::device_start()
|
||||
{
|
||||
m68000_musashi_device::device_start();
|
||||
init_cpu_m68008();
|
||||
m68008_device::device_start();
|
||||
}
|
||||
|
@ -1,28 +1,61 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Karl Stenerud
|
||||
// copyright-holders:Olivier Galibert
|
||||
#ifndef MAME_CPU_M68000_M68008_H
|
||||
#define MAME_CPU_M68000_M68008_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "m68kmusashi.h"
|
||||
#include "m68000.h"
|
||||
|
||||
class m68008_device : public m68000_musashi_device
|
||||
class m68008_device : public m68000_device
|
||||
{
|
||||
public:
|
||||
struct mmu8 {
|
||||
virtual u8 read_program(offs_t addr) = 0;
|
||||
virtual void write_program(offs_t addr, u8 data) = 0;
|
||||
virtual u8 read_data(offs_t addr) = 0;
|
||||
virtual void write_data(offs_t addr, u8 data) = 0;
|
||||
virtual u8 read_cpu(offs_t addr) = 0;
|
||||
virtual void set_super(bool super) = 0;
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
m68008_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
virtual u32 execute_min_cycles() const noexcept override { return 4; }
|
||||
virtual u32 execute_max_cycles() const noexcept override { return 158; }
|
||||
void set_current_mmu(mmu8 *m);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
|
||||
protected:
|
||||
// Typed constructor
|
||||
m68008_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
using handler8 = void (m68008_device::*)();
|
||||
|
||||
#include "m68008-head.h"
|
||||
|
||||
static const handler8 s_handlers_df8[];
|
||||
static const handler8 s_handlers_if8[];
|
||||
static const handler8 s_handlers_dp8[];
|
||||
static const handler8 s_handlers_ip8[];
|
||||
|
||||
// Fixed specifics
|
||||
memory_access<24, 0, 0, ENDIANNESS_BIG>::specific m_r_program8, m_r_opcodes8, m_r_uprogram8, m_r_uopcodes8, m_cpu_space8;
|
||||
|
||||
// Dynamic specifics, depending on supervisor state
|
||||
memory_access<24, 0, 0, ENDIANNESS_BIG>::specific m_program8, m_opcodes8;
|
||||
|
||||
// MMU, if one present
|
||||
mmu8 *m_mmu8;
|
||||
|
||||
virtual void update_user_super() override;
|
||||
|
||||
};
|
||||
|
||||
class m68008fn_device : public m68000_musashi_device
|
||||
class m68008fn_device : public m68008_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "m68000.h"
|
||||
#include "m68000mcu.h"
|
||||
|
||||
class tmp68301_device : public m68000_mcu_device
|
||||
{
|
||||
|
@ -237,7 +237,7 @@ uint8_t abc1600_mac_device::read(offs_t offset)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_magic && (fc == M68K_FC_USER_PROGRAM))
|
||||
if (!m_magic && (fc == 2))
|
||||
{
|
||||
task = 0;
|
||||
}
|
||||
@ -245,18 +245,8 @@ uint8_t abc1600_mac_device::read(offs_t offset)
|
||||
bool nonx, wp;
|
||||
offs_t virtual_offset = get_physical_offset(offset, task, nonx, wp);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (nonx)
|
||||
{
|
||||
LOGMASKED(LOG_ERRORS, "%s BUS ERROR R %05x:%06x (NONX %u WP %u TASK %u FC %u MAGIC %u)\n",
|
||||
machine().describe_context(), offset, virtual_offset, nonx, wp, task, fc, m_magic);
|
||||
machine().debug_break();
|
||||
m_cpu->set_buserror_details(offset, 1, m_cpu->get_fc());
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
if (!machine().side_effects_disabled() && nonx)
|
||||
m_cpu->trigger_bus_error();
|
||||
|
||||
return space().read_byte(virtual_offset);
|
||||
}
|
||||
@ -289,27 +279,8 @@ void abc1600_mac_device::write(offs_t offset, uint8_t data)
|
||||
bool nonx, wp;
|
||||
offs_t virtual_offset = get_physical_offset(offset, task, nonx, wp);
|
||||
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (nonx)
|
||||
{
|
||||
LOGMASKED(LOG_ERRORS, "%s BUS ERROR W %05x:%06x (NONX %u WP %u TASK %u FC %u MAGIC %u)\n",
|
||||
machine().describe_context(), offset, virtual_offset, nonx, wp, task, fc, m_magic);
|
||||
machine().debug_break();
|
||||
m_cpu->set_buserror_details(offset, 0, m_cpu->get_fc());
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
|
||||
}
|
||||
if (!wp)
|
||||
{
|
||||
LOGMASKED(LOG_ERRORS, "%s BUS ERROR W %05x:%06x (NONX %u WP %u TASK %u FC %u MAGIC %u)\n",
|
||||
machine().describe_context(), offset, virtual_offset, nonx, wp, task, fc, m_magic);
|
||||
machine().debug_break();
|
||||
m_cpu->set_buserror_details(offset, 0, m_cpu->get_fc());
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
|
||||
m_cpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
if (!machine().side_effects_disabled() && (nonx || !wp))
|
||||
m_cpu->trigger_bus_error();
|
||||
|
||||
space().write_byte(virtual_offset, data);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user