cpu/m6502: Template 6502 microcontroller helper on underlying CPU type.

This commit is contained in:
Vas Crabb 2023-04-17 03:30:51 +10:00
parent 60ced2cb0c
commit 864bfe17eb
7 changed files with 129 additions and 84 deletions

View File

@ -1637,6 +1637,8 @@ if CPUS["M6502"] then
MAME_DIR .. "src/devices/cpu/m6502/m6500_1.h",
MAME_DIR .. "src/devices/cpu/m6502/m6502.cpp",
MAME_DIR .. "src/devices/cpu/m6502/m6502.h",
MAME_DIR .. "src/devices/cpu/m6502/m6502mcu.h",
MAME_DIR .. "src/devices/cpu/m6502/m6502mcu.ipp",
MAME_DIR .. "src/devices/cpu/m6502/m6504.cpp",
MAME_DIR .. "src/devices/cpu/m6502/m6504.h",
MAME_DIR .. "src/devices/cpu/m6502/m6507.cpp",

View File

@ -73,6 +73,8 @@
#include "emu.h"
#include "m6500_1.h"
#include "m6502mcu.ipp"
namespace {
@ -92,7 +94,7 @@ DEFINE_DEVICE_TYPE(M6500_1, m6500_1_device, "m6500_1", "MOS Technology 6500/1");
m6500_1_device::m6500_1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: m6502_mcu_device(mconfig, M6500_1, tag, owner, clock)
: m6502_mcu_device_base<m6502_device>(mconfig, M6500_1, tag, owner, clock)
, m_port_in_cb{ *this }
, m_port_out_cb{ *this }
, m_cntr_out_cb{ *this }
@ -142,7 +144,7 @@ WRITE_LINE_MEMBER(m6500_1_device::cntr_w)
void m6500_1_device::device_resolve_objects()
{
m6502_mcu_device::device_resolve_objects();
m6502_mcu_device_base<m6502_device>::device_resolve_objects();
m_port_in_cb.resolve_all();
m_port_out_cb.resolve_all_safe();
@ -151,7 +153,7 @@ void m6500_1_device::device_resolve_objects()
void m6500_1_device::device_start()
{
m6502_mcu_device::device_start();
m6502_mcu_device_base<m6502_device>::device_start();
m_counter_base = 0U;
@ -173,7 +175,7 @@ void m6500_1_device::device_start()
void m6500_1_device::device_reset()
{
m6502_mcu_device::device_reset();
m6502_mcu_device_base<m6502_device>::device_reset();
SP = 0x003fU;
@ -238,7 +240,7 @@ void m6500_1_device::state_import(device_state_entry const &entry)
break;
default:
m6502_mcu_device::state_import(entry);
m6502_mcu_device_base<m6502_device>::state_import(entry);
}
}
@ -269,7 +271,7 @@ void m6500_1_device::state_export(device_state_entry const &entry)
break;
default:
m6502_mcu_device::state_export(entry);
m6502_mcu_device_base<m6502_device>::state_export(entry);
}
}

View File

@ -39,9 +39,9 @@
#pragma once
#include "m6502.h"
#include "m6502mcu.h"
class m6500_1_device : public m6502_mcu_device
class m6500_1_device : public m6502_mcu_device_base<m6502_device>
{
public:
m6500_1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
@ -88,7 +88,7 @@ protected:
virtual void state_export(device_state_entry const &entry) override;
virtual void internal_update(u64 current_time) override;
using m6502_mcu_device::internal_update;
using m6502_mcu_device_base<m6502_device>::internal_update;
u8 read_control_register();
void write_control_register(u8 data);

View File

@ -2,7 +2,7 @@
// copyright-holders:Olivier Galibert
/***************************************************************************
m6502.c
m6502.cpp
MOS Technology 6502, original NMOS variant
@ -565,67 +565,5 @@ void m6502_device::mi_default14::write(uint16_t adr, uint8_t val)
program14.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;
}
void m6502_mcu_device::execute_run()
{
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;
}
}
void m6502_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;
}
#include "cpu/m6502/m6502.hxx"

View File

@ -11,6 +11,9 @@
#ifndef MAME_CPU_M6502_M6502_H
#define MAME_CPU_M6502_M6502_H
#pragma once
class m6502_device : public cpu_device {
public:
enum {
@ -276,18 +279,6 @@ protected:
#undef O
};
class m6502_mcu_device : public m6502_device {
protected:
m6502_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void internal_update() { internal_update(total_cycles()); }
virtual void internal_update(uint64_t current_time) = 0;
void recompute_bcount(uint64_t event_time);
static void add_event(uint64_t &event_time, uint64_t new_event);
virtual void execute_run() override;
};
class m6512_device : public m6502_device {
public:
m6512_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

View File

@ -0,0 +1,37 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/***************************************************************************
m6502mcu.h
Helper for 6502 variants with internal peripherals
***************************************************************************/
#ifndef MAME_CPU_M6502_M6502MCU_H
#define MAME_CPU_M6502_M6502MCU_H
#pragma once
#include "m6502.h"
template <typename Base>
class m6502_mcu_device_base : public Base {
protected:
m6502_mcu_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
void internal_update() { internal_update(this->total_cycles()); }
virtual void internal_update(uint64_t current_time) = 0;
void recompute_bcount(uint64_t event_time);
static void add_event(uint64_t &event_time, uint64_t new_event)
{
if(new_event && (!event_time || event_time > new_event))
event_time = new_event;
}
virtual void execute_run() override;
};
#endif // MAME_CPU_M6502_M6502MCU_H

View File

@ -0,0 +1,75 @@
// license:BSD-3-Clause
// copyright-holders:Olivier Galibert
/***************************************************************************
m6502mcu.ipp
Helper for 6502 variants with internal peripherals
***************************************************************************/
#ifndef MAME_CPU_M6502_M6502MCU_IPP
#define MAME_CPU_M6502_M6502MCU_IPP
#pragma once
#include "m6502mcu.h"
template <typename Base>
m6502_mcu_device_base<Base>::m6502_mcu_device_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
Base(mconfig, type, tag, owner, clock)
{
}
template <typename Base>
void m6502_mcu_device_base<Base>::recompute_bcount(uint64_t event_time)
{
if(!event_time || event_time >= this->total_cycles() + this->icount)
this->bcount = 0;
else
this->bcount = this->total_cycles() + this->icount - event_time;
}
template <typename Base>
void m6502_mcu_device_base<Base>::execute_run()
{
internal_update(this->total_cycles());
this->icount -= this->count_before_instruction_step;
if(this->icount < 0) {
this->count_before_instruction_step = -this->icount;
this->icount = 0;
} else
this->count_before_instruction_step = 0;
while(bcount && icount <= bcount)
internal_update(total_cycles() + icount - bcount);
if(this->icount > 0 && this->inst_substate)
this->do_exec_partial();
while(this->icount > 0) {
while(this->icount > this->bcount) {
if(this->inst_state < 0xff00) {
this->PPC = this->NPC;
this->inst_state = this->IR | this->inst_state_base;
if(this->machine().debug_flags & DEBUG_FLAG_ENABLED)
this->debugger_instruction_hook(NPC);
}
this->do_exec_full();
}
if(this->icount > 0)
while(this->bcount && this->icount <= this->bcount)
internal_update(this->total_cycles() + this->icount - this->bcount);
if(this->icount > 0 && this->inst_substate)
this->do_exec_partial();
}
if(this->icount < 0) {
this->count_before_instruction_step = -this->icount;
this->icount = 0;
}
}
#endif // MAME_CPU_M6502_M6502MCU_IPP