mn1400: add device skeleton

This commit is contained in:
hap 2023-05-06 18:07:17 +02:00
parent 90e394850a
commit dff3955a3a
8 changed files with 355 additions and 9 deletions

View File

@ -2267,10 +2267,20 @@ if opt_tool(CPUS, "RSP") then
end
--------------------------------------------------
-- Matsushita (Panasonic) MN1400, disassembler only
--@src/devices/cpu/mn1400/mn1400d.h,CPUS["MN1400"] = true
-- Matsushita (Panasonic) MN1400
--@src/devices/cpu/mn1400/mn1400.h,CPUS["MN1400"] = true
--------------------------------------------------
if CPUS["MN1400"] then
files {
MAME_DIR .. "src/devices/cpu/mn1400/mn1400base.cpp",
MAME_DIR .. "src/devices/cpu/mn1400/mn1400base.h",
MAME_DIR .. "src/devices/cpu/mn1400/mn1400.cpp",
MAME_DIR .. "src/devices/cpu/mn1400/mn1400.h",
MAME_DIR .. "src/devices/cpu/mn1400/mn1400op.cpp",
}
end
if opt_tool(CPUS, "MN1400") then
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/mn1400/mn1400d.cpp")
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/mn1400/mn1400d.h")

View File

@ -0,0 +1,62 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Matsushita MN1400 MCU
TODO:
- stuff
*/
#include "emu.h"
#include "mn1400.h"
#include "mn1400d.h"
DEFINE_DEVICE_TYPE(MN1400, mn1400_cpu_device, "mn1400", "Matsushita MN1400")
// constructor
mn1400_cpu_device::mn1400_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
mn1400_base_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
mn1400_cpu_device::mn1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
mn1400_cpu_device(mconfig, MN1400, tag, owner, clock, 10, address_map_constructor(FUNC(mn1400_cpu_device::program_1024x8), this), 6, address_map_constructor(FUNC(mn1400_cpu_device::data_64x4), this))
{ }
// internal memory maps
void mn1400_cpu_device::program_1024x8(address_map &map)
{
map(0x000, 0x3ff).rom();
}
void mn1400_cpu_device::data_64x4(address_map &map)
{
map(0x00, 0x3f).ram();
}
// disasm
std::unique_ptr<util::disasm_interface> mn1400_cpu_device::create_disassembler()
{
return std::make_unique<mn1400_disassembler>();
}
//-------------------------------------------------
// execute
//-------------------------------------------------
bool mn1400_cpu_device::op_has_param(u8 op)
{
return false;
}
void mn1400_cpu_device::execute_one()
{
op_illegal();
}

View File

@ -0,0 +1,49 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Matsushita MN1400 MCU
*/
#ifndef MAME_CPU_MN1400_MN1400_H
#define MAME_CPU_MN1400_MN1400_H
#pragma once
#include "mn1400base.h"
// pinout reference
/*
*/
class mn1400_cpu_device : public mn1400_base_device
{
public:
mn1400_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
mn1400_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
// device_execute_interface overrides
virtual void execute_one() override;
virtual bool op_has_param(u8 op) override;
void program_1024x8(address_map &map);
void data_64x4(address_map &map);
// opcode helpers
void op_illegal();
// opcode handlers
};
DECLARE_DEVICE_TYPE(MN1400, mn1400_cpu_device)
#endif // MAME_CPU_MN1400_MN1400_H

View File

@ -0,0 +1,131 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Matsushita (Panasonic) MN1400 family MCU cores
x
*/
#include "emu.h"
#include "mn1400base.h"
mn1400_base_device::mn1400_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
cpu_device(mconfig, type, tag, owner, clock),
m_program_config("program", ENDIANNESS_LITTLE, 8, prgwidth, 0, program),
m_data_config("data", ENDIANNESS_LITTLE, 8, datawidth, 0, data),
m_prgwidth(prgwidth),
m_datawidth(datawidth)
{ }
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void mn1400_base_device::device_start()
{
m_program = &space(AS_PROGRAM);
m_data = &space(AS_DATA);
m_prgmask = (1 << m_prgwidth) - 1;
m_datamask = (1 << m_datawidth) - 1;
// resolve callbacks
// zerofill
m_pc = 0;
m_prev_pc = 0;
m_op = 0;
m_prev_op = 0;
m_param = 0;
m_a = 0;
m_x = 0;
m_y = 0;
// register for savestates
save_item(NAME(m_pc));
save_item(NAME(m_prev_pc));
save_item(NAME(m_op));
save_item(NAME(m_prev_op));
save_item(NAME(m_param));
save_item(NAME(m_a));
save_item(NAME(m_x));
save_item(NAME(m_y));
// register state for debugger
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%03X").noshow();
state_add(STATE_GENPCBASE, "CURPC", m_prev_pc).formatstr("%03X").noshow();
m_state_count = 0;
state_add(++m_state_count, "PC", m_pc).formatstr("%03X"); // 1
state_add(++m_state_count, "A", m_a).formatstr("%01X"); // 2
state_add(++m_state_count, "X", m_x).formatstr("%01X"); // 3
state_add(++m_state_count, "Y", m_y).formatstr("%01X"); // 4
set_icountptr(m_icount);
}
device_memory_interface::space_config_vector mn1400_base_device::memory_space_config() const
{
return space_config_vector {
std::make_pair(AS_PROGRAM, &m_program_config),
std::make_pair(AS_DATA, &m_data_config)
};
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void mn1400_base_device::device_reset()
{
m_pc = m_prev_pc = 0;
m_op = m_prev_op = 0;
m_param = 0;
}
//-------------------------------------------------
// execute
//-------------------------------------------------
void mn1400_base_device::cycle()
{
m_icount--;
}
void mn1400_base_device::increment_pc()
{
m_pc = (m_pc + 1) & m_prgmask;
}
void mn1400_base_device::execute_run()
{
while (m_icount > 0)
{
// remember previous state
m_prev_op = m_op;
m_prev_pc = m_pc;
// fetch next opcode
m_op = m_program->read_byte(m_pc);
debugger_instruction_hook(m_pc);
increment_pc();
cycle();
// 2-byte opcodes
if (op_has_param(m_op))
{
m_param = m_program->read_byte(m_pc);
increment_pc();
cycle();
}
execute_one();
}
}

View File

@ -0,0 +1,74 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Matsushita (Panasonic) MN1400 family MCU cores
Don't include this file, include the specific device header instead,
for example mn1400.h
*/
#ifndef MAME_CPU_MN1400_MN1400BASE_H
#define MAME_CPU_MN1400_MN1400BASE_H
#pragma once
class mn1400_base_device : public cpu_device
{
public:
// configuration helpers
// I/O ports:
protected:
// construction/destruction
mn1400_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 3 - 1) / 3; } // 3-phase clock
virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 3); }
virtual u32 execute_min_cycles() const noexcept override { return 1; }
virtual u32 execute_max_cycles() const noexcept override { return 2; }
virtual void execute_run() override;
virtual void execute_one() = 0;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
address_space_config m_program_config;
address_space_config m_data_config;
address_space *m_program;
address_space *m_data;
int m_icount;
int m_state_count;
int m_prgwidth; // ROM/RAM address size
int m_datawidth; // "
u16 m_prgmask; // "
u16 m_datamask; // "
virtual void cycle();
virtual void increment_pc();
virtual bool op_has_param(u8 op) = 0;
u16 m_pc;
u16 m_prev_pc;
u8 m_op;
u8 m_prev_op;
u8 m_param;
u8 m_a;
u8 m_x;
u8 m_y;
// i/o handlers
};
#endif // MAME_CPU_MN1400_MN1400BASE_H

View File

@ -11,7 +11,7 @@
const char *const mn1400_disassembler::s_mnemonics[] =
{
"?",
"?", "?",
"L", "LD", "LI", "LIC", "LDC", "ST", "STD", "STIC", "STDC",
"LX", "LY", "TAX", "TAY", "TYA", "TACU", "TACL", "TCAU", "TCAL",
"NOP", "AND", "ANDI", "OR", "XOR", "A", "AI", "CPL", "C", "CI", "CY",
@ -27,7 +27,7 @@ const char *const mn1400_disassembler::s_mnemonics[] =
// number of bits per opcode parameter
const u8 mn1400_disassembler::s_bits[] =
{
0,
0, 8,
0, 2, 4, 0, 0, 0, 2, 0, 0,
3, 4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 0, 0, 0, 4, 0, 0, 4, 4,
@ -42,7 +42,7 @@ const u8 mn1400_disassembler::s_bits[] =
const u32 mn1400_disassembler::s_flags[] =
{
0,
0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -62,7 +62,7 @@ const u8 mn1400_disassembler::mn1400_mnemonic[0x100] =
mNOP, mTAX, mTYA, mTAY, mAND, mOR, mXOR, mA, mCPL, mC, mST, mSTIC, mSTDC, mL, mLIC, mLDC, // 0
mOTE, mOTMD, mOTD, mCCO, mINA, mINB, mRCO, mSCO, mTACL, mTACU, mTCAL, mTCAU, mDC, mEC, mSL, mRET, // 1
mLD, mLD, mLD, mLD, mSTD, mSTD, mSTD, mSTD, mRC, mRP, mSC, mSP, mICY, mDCY, mICM, mDCM, // 2
mLX, mLX, mLX, mLX, mLX, mLX, mLX, mLX, 0, 0, mBSN0, mBS0, mBSN1, mBS1, mBSN01,mBS01, // 3
mLX, mLX, mLX, mLX, mLX, mLX, mLX, mLX, 1, 1, mBSN0, mBS0, mBSN1, mBS1, mBSN01,mBS01, // 3
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mCAL, mCAL, mCAL, mCAL, mCAL, mCAL, mCAL, mCAL, // 4
mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, mLI, // 5
@ -76,7 +76,7 @@ const u8 mn1400_disassembler::mn1400_mnemonic[0x100] =
mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, mRM, // C
mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, mTB, // D
0, 0, mBNZ, mBZ, mBNC, mBC, mBNCZ, mBCZ, mBNP, mBP, mBNPZ, mBPZ, mBNPC, mBPC, mBNPCZ,mBPCZ, // E
1, 1, mBNZ, mBZ, mBNC, mBC, mBNCZ, mBCZ, mBNP, mBP, mBNPZ, mBPZ, mBNPC, mBPC, mBNPCZ,mBPCZ, // E
mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE, mOTIE // F
};
@ -100,7 +100,9 @@ offs_t mn1400_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
param |= (op & ((1 << (bits - 8)) - 1)) << 8;
else
param |= pc & 0x700;
util::stream_format(stream, "$%03X", param);
if (instr > 1)
util::stream_format(stream, "$%03X", param);
}
else
{

View File

@ -25,7 +25,7 @@ public:
private:
enum e_mnemonics
{
mILL,
mILL, mILL2,
mL, mLD, mLI, mLIC, mLDC, mST, mSTD, mSTIC, mSTDC,
mLX, mLY, mTAX, mTAY, mTYA, mTACU, mTACL, mTCAU, mTCAL,
mNOP, mAND, mANDI, mOR, mXOR, mA, mAI, mCPL, mC, mCI, mCY,

View File

@ -0,0 +1,18 @@
// license:BSD-3-Clause
// copyright-holders:hap
// MN1400 common opcode handlers
#include "emu.h"
#include "mn1400.h"
// internal helpers
void mn1400_cpu_device::op_illegal()
{
logerror("unknown opcode $%02X at $%03X\n", m_op, m_prev_pc);
}
// opcodes