summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/m6502/m6502.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/m6502/m6502.cpp')
-rw-r--r--src/devices/cpu/m6502/m6502.cpp148
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);
}