diff options
Diffstat (limited to 'src/devices/cpu/m6502/m6502.cpp')
-rw-r--r-- | src/devices/cpu/m6502/m6502.cpp | 148 |
1 files changed, 54 insertions, 94 deletions
diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index 18e8b57cd79..c704a114e5e 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -2,55 +2,62 @@ // copyright-holders:Olivier Galibert /*************************************************************************** - m6502.c + m6502.cpp MOS Technology 6502, original NMOS variant ***************************************************************************/ #include "emu.h" -#include "debugger.h" #include "m6502.h" #include "m6502d.h" -DEFINE_DEVICE_TYPE(M6502, m6502_device, "m6502", "MOS Technology M6502") +DEFINE_DEVICE_TYPE(M6502, m6502_device, "m6502", "MOS Technology 6502") +DEFINE_DEVICE_TYPE(M6512, m6512_device, "m6512", "MOS Technology 6512") m6502_device::m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, M6502, tag, owner, clock) { } +m6512_device::m6512_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + m6502_device(mconfig, M6512, tag, owner, clock) +{ +} + m6502_device::m6502_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, type, tag, owner, clock), sync_w(*this), program_config("program", ENDIANNESS_LITTLE, 8, 16), - sprogram_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16), PPC(0), NPC(0), PC(0), SP(0), TMP(0), TMP2(0), A(0), X(0), Y(0), P(0), IR(0), inst_state_base(0), mintf(nullptr), - inst_state(0), inst_substate(0), icount(0), nmi_state(false), irq_state(false), apu_irq_state(false), v_state(false), irq_taken(false), sync(false), inhibit_interrupts(false) + sprogram_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16), + mintf(nullptr), + uses_custom_memory_interface(false) { } void m6502_device::device_start() { - mintf = std::make_unique<mi_default>(); + if(!uses_custom_memory_interface) + mintf = space(AS_PROGRAM).addr_width() > 14 ? std::make_unique<mi_default>() : std::make_unique<mi_default14>(); init(); } void m6502_device::init() { - mintf->program = &space(AS_PROGRAM); - mintf->sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : mintf->program; - - mintf->cache = mintf->program->cache<0, 0, ENDIANNESS_LITTLE>(); - mintf->scache = mintf->sprogram->cache<0, 0, ENDIANNESS_LITTLE>(); - - sync_w.resolve_safe(); + if(mintf) { + space(AS_PROGRAM).cache(mintf->cprogram); + space(has_space(AS_OPCODES) ? AS_OPCODES : AS_PROGRAM).cache(mintf->csprogram); - XPC = 0; + // specific group 1-14 or 15-31 + if(space(AS_PROGRAM).addr_width() > 14) + space(AS_PROGRAM).specific(mintf->program); + else + space(AS_PROGRAM).specific(mintf->program14); + } state_add(STATE_GENPC, "GENPC", XPC).callexport().noshow(); state_add(STATE_GENPCBASE, "CURPC", XPC).callexport().noshow(); - state_add(STATE_GENSP, "GENSP", SP).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", P).callimport().formatstr("%6s").noshow(); state_add(M6502_PC, "PC", NPC).callimport(); state_add(M6502_A, "A", A); @@ -75,14 +82,17 @@ void m6502_device::init() save_item(NAME(irq_state)); save_item(NAME(apu_irq_state)); save_item(NAME(v_state)); + save_item(NAME(nmi_pending)); + save_item(NAME(irq_taken)); save_item(NAME(inst_state)); save_item(NAME(inst_substate)); save_item(NAME(inst_state_base)); - save_item(NAME(irq_taken)); save_item(NAME(inhibit_interrupts)); set_icountptr(icount); + XPC = 0x0000; + PPC = 0x0000; PC = 0x0000; NPC = 0x0000; A = 0x00; @@ -96,8 +106,9 @@ void m6502_device::init() nmi_state = false; irq_state = false; apu_irq_state = false; - irq_taken = false; v_state = false; + nmi_pending = false; + irq_taken = false; inst_state = STATE_RESET; inst_substate = 0; inst_state_base = 0; @@ -111,11 +122,8 @@ void m6502_device::device_reset() inst_state = STATE_RESET; inst_substate = 0; inst_state_base = 0; - nmi_state = false; - irq_state = false; - apu_irq_state = false; + nmi_pending = false; irq_taken = false; - v_state = false; sync = false; sync_w(CLEAR_LINE); inhibit_interrupts = false; @@ -139,7 +147,7 @@ uint32_t m6502_device::execute_input_lines() const noexcept bool m6502_device::execute_input_edge_triggered(int inputnum) const noexcept { - return inputnum == NMI_LINE; + return inputnum == NMI_LINE || inputnum == V_LINE; } void m6502_device::do_adc_d(uint8_t val) @@ -403,9 +411,13 @@ void m6502_device::execute_set_input(int inputnum, int state) switch(inputnum) { case IRQ_LINE: irq_state = state == ASSERT_LINE; break; case APU_IRQ_LINE: apu_irq_state = state == ASSERT_LINE; break; - case NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break; + case NMI_LINE: + if(machine().time() > attotime::zero && !nmi_state && state == ASSERT_LINE) + nmi_pending = true; + nmi_state = state == ASSERT_LINE; + break; case V_LINE: - if(!v_state && state == ASSERT_LINE) + if(machine().time() > attotime::zero && !v_state && state == ASSERT_LINE) P |= F_V; v_state = state == ASSERT_LINE; break; @@ -437,7 +449,9 @@ void m6502_device::state_import(const device_state_entry &entry) case M6502_PC: PC = NPC; irq_taken = false; - prefetch(); + prefetch_start(); + IR = mintf->read_sync(PC); + prefetch_end(); PPC = NPC; inst_state = IR | inst_state_base; break; @@ -468,28 +482,27 @@ void m6502_device::state_string_export(const device_state_entry &entry, std::str } } -void m6502_device::prefetch() +void m6502_device::prefetch_start() { sync = true; sync_w(ASSERT_LINE); NPC = PC; - IR = mintf->read_sync(PC); +} + +void m6502_device::prefetch_end() +{ sync = false; sync_w(CLEAR_LINE); - if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) { + if((nmi_pending || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) { irq_taken = true; IR = 0x00; } else PC++; } -void m6502_device::prefetch_noirq() +void m6502_device::prefetch_end_noirq() { - sync = true; - sync_w(ASSERT_LINE); - NPC = PC; - IR = mintf->read_sync(PC); sync = false; sync_w(CLEAR_LINE); PC++; @@ -522,85 +535,32 @@ void m6502_device::memory_interface::write_9(uint16_t adr, uint8_t val) uint8_t m6502_device::mi_default::read(uint16_t adr) { - return program->read_byte(adr); + return program.read_byte(adr); } uint8_t m6502_device::mi_default::read_sync(uint16_t adr) { - return scache->read_byte(adr); + return csprogram.read_byte(adr); } uint8_t m6502_device::mi_default::read_arg(uint16_t adr) { - return cache->read_byte(adr); + return cprogram.read_byte(adr); } void m6502_device::mi_default::write(uint16_t adr, uint8_t val) { - program->write_byte(adr, val); -} - - -m6502_mcu_device::m6502_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - m6502_device(mconfig, type, tag, owner, clock) -{ -} - - -void m6502_mcu_device::recompute_bcount(uint64_t event_time) -{ - if(!event_time || event_time >= total_cycles() + icount) { - bcount = 0; - return; - } - bcount = total_cycles() + icount - event_time; + program.write_byte(adr, val); } -void m6502_mcu_device::execute_run() +uint8_t m6502_device::mi_default14::read(uint16_t adr) { - internal_update(total_cycles()); - - icount -= count_before_instruction_step; - if(icount < 0) { - count_before_instruction_step = -icount; - icount = 0; - } else - count_before_instruction_step = 0; - - while(bcount && icount <= bcount) - internal_update(total_cycles() + icount - bcount); - - if(icount > 0 && inst_substate) - do_exec_partial(); - - while(icount > 0) { - while(icount > bcount) { - if(inst_state < 0xff00) { - PPC = NPC; - inst_state = IR | inst_state_base; - if(machine().debug_flags & DEBUG_FLAG_ENABLED) - debugger_instruction_hook(NPC); - } - do_exec_full(); - } - if(icount > 0) - while(bcount && icount <= bcount) - internal_update(total_cycles() + icount - bcount); - if(icount > 0 && inst_substate) - do_exec_partial(); - } - if(icount < 0) { - count_before_instruction_step = -icount; - icount = 0; - } + return program14.read_byte(adr); } -void m6502_mcu_device::add_event(uint64_t &event_time, uint64_t new_event) +void m6502_device::mi_default14::write(uint16_t adr, uint8_t val) { - if(!new_event) - return; - if(!event_time || event_time > new_event) - event_time = new_event; + program14.write_byte(adr, val); } |