mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
Add Fujitsu FR disassembler and skeleton CPU device
This commit is contained in:
parent
d7f1b7ae49
commit
41a333e791
@ -567,6 +567,23 @@ if (CPUS["F8"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/f8/f8dasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Fujitsu FR
|
||||
--@src/devices/cpu/fr/fr.h,CPUS["FR"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["FR"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/cpu/fr/fr.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/fr/fr.h",
|
||||
}
|
||||
end
|
||||
|
||||
if (CPUS["FR"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/fr/frdasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/fr/frdasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- G65816
|
||||
--@src/devices/cpu/g65816/g65816.h,CPUS["G65816"] = true
|
||||
|
@ -137,6 +137,7 @@ CPUS["HPC"] = true
|
||||
--CPUS["RII"] = true
|
||||
--CPUS["BCP"] = true
|
||||
--CPUS["CR16B"] = true
|
||||
CPUS["FR"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores
|
||||
|
@ -146,6 +146,7 @@ CPUS["RII"] = true
|
||||
CPUS["BCP"] = true
|
||||
CPUS["F2MC16"] = true
|
||||
CPUS["CR16B"] = true
|
||||
CPUS["FR"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available sound cores; some of these are
|
||||
|
137
src/devices/cpu/fr/fr.cpp
Normal file
137
src/devices/cpu/fr/fr.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Fujitsu FR series
|
||||
|
||||
Currently this device is just a stub with no actual execution core.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "fr.h"
|
||||
#include "frdasm.h"
|
||||
|
||||
// device type definitions
|
||||
DEFINE_DEVICE_TYPE(MB91101A, mb91101a_device, "mb91101a", "Fujitsu MB91101A")
|
||||
|
||||
fr_cpu_device::fr_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, address_map_constructor map)
|
||||
: cpu_device(mconfig, type, tag, owner, clock)
|
||||
, m_space_config("program", ENDIANNESS_BIG, 32, addrbits, 0, map)
|
||||
, m_space(nullptr)
|
||||
, m_cache(nullptr)
|
||||
, m_regs{0}
|
||||
, m_pc(0)
|
||||
, m_ps(0)
|
||||
, m_tbr(0)
|
||||
, m_rp(0)
|
||||
, m_md(0)
|
||||
, m_icount(0)
|
||||
{
|
||||
}
|
||||
|
||||
mb91101a_device::mb91101a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: fr_cpu_device(mconfig, MB91101A, tag, owner, clock, 32, address_map_constructor())
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<util::disasm_interface> fr_cpu_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<fr_disassembler>();
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector fr_cpu_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &m_space_config),
|
||||
};
|
||||
}
|
||||
|
||||
void fr_cpu_device::device_start()
|
||||
{
|
||||
m_space = &space(AS_PROGRAM);
|
||||
m_cache = m_space->cache<2, 0, ENDIANNESS_BIG>();
|
||||
|
||||
set_icountptr(m_icount);
|
||||
|
||||
state_add(FR_PC, "PC", m_pc).mask(0xfffffffe);
|
||||
state_add(STATE_GENPC, "GENPC", m_pc).mask(0xfffffffe).noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_pc).mask(0xfffffffe).noshow();
|
||||
state_add(FR_PS, "PS", m_ps).mask(0x001f073f).formatstr("%08X");
|
||||
state_add(STATE_GENFLAGS, "CURFLAGS", m_ps).mask(0x001f073f).noshow().formatstr("%19s");
|
||||
state_add<u8>(FR_CCR, "CCR",
|
||||
[this]() { return u8(m_ps & 0x0000003f); },
|
||||
[this](u8 value) { m_ps = (m_ps & 0x001f0700) | value; }).mask(0x3f).noshow();
|
||||
state_add<u8>(FR_ILM, "ILM",
|
||||
[this]() { return u8((m_ps & 0x001f0000) >> 16); },
|
||||
[this](u8 value) { m_ps = (m_ps & 0x0000073f) | u32(value) << 16; }).mask(0x1f).noshow();
|
||||
state_add(FR_TBR, "TBR", m_tbr);
|
||||
state_add(FR_RP, "RP", m_rp);
|
||||
state_add(FR_SSP, "SSP", m_regs[15]);
|
||||
state_add(FR_USP, "USP", m_regs[16]);
|
||||
state_add(FR_MD, "MD", m_md);
|
||||
state_add<u32>(FR_MDH, "MDH",
|
||||
[this]() { return u32(m_md >> 32); },
|
||||
[this](u32 value) { m_md = (m_md & 0x00000000ffffffffULL) | u64(value) << 32; }).noshow();
|
||||
state_add<u32>(FR_MDL, "MDL",
|
||||
[this]() { return u32(m_md & 0x00000000ffffffffULL); },
|
||||
[this](u32 value) { m_md = (m_md & 0xffffffff00000000ULL) | value; }).noshow();
|
||||
for (int i = 0; i < 15; i++)
|
||||
state_add(FR_R0 + i, string_format("R%d", i).c_str(), m_regs[i]);
|
||||
state_add<u32>(FR_R15, "R15",
|
||||
[this]() { return m_regs[BIT(m_ps, 5) ? 16 : 15]; },
|
||||
[this](u32 value) { m_regs[BIT(m_ps, 5) ? 16 : 15] = value; });
|
||||
|
||||
save_item(NAME(m_regs));
|
||||
save_item(NAME(m_pc));
|
||||
save_item(NAME(m_ps));
|
||||
save_item(NAME(m_tbr));
|
||||
save_item(NAME(m_rp));
|
||||
save_item(NAME(m_md));
|
||||
}
|
||||
|
||||
void fr_cpu_device::device_reset()
|
||||
{
|
||||
// Only TBR, SSP, ILM and certain CCR and SCR bits are reset here; PC will be reloaded subsequently
|
||||
m_ps = (m_ps & 0x0000060f) | 0x000f0000;
|
||||
m_tbr = 0x000ffc00;
|
||||
m_regs[15] = 0x00000000;
|
||||
}
|
||||
|
||||
void fr_cpu_device::execute_run()
|
||||
{
|
||||
m_pc = m_space->read_dword(m_tbr + 0x3fc);
|
||||
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
m_icount = 0;
|
||||
}
|
||||
|
||||
void fr_cpu_device::execute_set_input(int inputnum, int state)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void fr_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
||||
{
|
||||
switch (entry.index())
|
||||
{
|
||||
case STATE_GENFLAGS:
|
||||
str = string_format("<%d%d%d%d%d> %c%c%c--%c%c%c%c%c%c",
|
||||
BIT(m_ps, 20),
|
||||
BIT(m_ps, 19),
|
||||
BIT(m_ps, 18),
|
||||
BIT(m_ps, 17),
|
||||
BIT(m_ps, 16),
|
||||
BIT(m_ps, 10) ? 'D' : '.',
|
||||
BIT(m_ps, 9) ? 'd' : '.',
|
||||
BIT(m_ps, 8) ? 'T' : '.',
|
||||
BIT(m_ps, 5) ? 'S' : '.',
|
||||
BIT(m_ps, 4) ? 'I' : '.',
|
||||
BIT(m_ps, 3) ? 'N' : '.',
|
||||
BIT(m_ps, 2) ? 'Z' : '.',
|
||||
BIT(m_ps, 1) ? 'V' : '.',
|
||||
BIT(m_ps, 0) ? 'C' : '.');
|
||||
break;
|
||||
}
|
||||
}
|
69
src/devices/cpu/fr/fr.h
Normal file
69
src/devices/cpu/fr/fr.h
Normal file
@ -0,0 +1,69 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_FR_FR_H
|
||||
#define MAME_CPU_FR_FR_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
class fr_cpu_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
FR_PC, FR_PS, FR_CCR, FR_ILM,
|
||||
FR_TBR, FR_RP, FR_SSP, FR_USP,
|
||||
FR_MD, FR_MDH, FR_MDL,
|
||||
FR_R0, FR_R1, FR_R2, FR_R3,
|
||||
FR_R4, FR_R5, FR_R6, FR_R7,
|
||||
FR_R8, FR_R9, FR_R10, FR_R11,
|
||||
FR_R12, FR_R13, FR_R14, FR_R15
|
||||
};
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
fr_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, address_map_constructor map);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual void execute_run() override;
|
||||
virtual void execute_set_input(int inputnum, int state) override;
|
||||
|
||||
// device_disasm_interface overrides
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
|
||||
// device_memory_interface overrides
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
// device_state_interface overrides
|
||||
void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||
|
||||
private:
|
||||
// address space
|
||||
address_space_config m_space_config;
|
||||
address_space *m_space;
|
||||
memory_access_cache<2, 0, ENDIANNESS_BIG> *m_cache;
|
||||
|
||||
// internal state
|
||||
u32 m_regs[17]; // includes both SSP and USP
|
||||
u32 m_pc;
|
||||
u32 m_ps;
|
||||
u32 m_tbr;
|
||||
u32 m_rp;
|
||||
u64 m_md;
|
||||
s32 m_icount;
|
||||
};
|
||||
|
||||
class mb91101a_device : public fr_cpu_device
|
||||
{
|
||||
public:
|
||||
// device type constructor
|
||||
mb91101a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(MB91101A, mb91101a_device)
|
||||
|
||||
#endif // MAME_CPU_FR_FR_H
|
977
src/devices/cpu/fr/frdasm.cpp
Normal file
977
src/devices/cpu/fr/frdasm.cpp
Normal file
@ -0,0 +1,977 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Fujitsu FR family disassembler
|
||||
|
||||
While Fujitsu's manuals also refer to R13, R14 and R15 by function as
|
||||
AC (accumulator), FP (frame pointer) and SP (stack pointer), these
|
||||
aliases do not appear to be commonly used. All indexed addressing modes
|
||||
are based on one of these three registers.
|
||||
|
||||
The PS (program status) register can only be manipulated with special
|
||||
instructions, some of which affect only the sections known as CCR
|
||||
(condition code register) and ILM (interrupt level mask).
|
||||
|
||||
TODO: The FR81 family has extra opcodes (primarily floating-point
|
||||
instructions) which are not included here.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "frdasm.h"
|
||||
|
||||
fr_disassembler::fr_disassembler()
|
||||
: util::disasm_interface()
|
||||
{
|
||||
}
|
||||
|
||||
u32 fr_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
void fr_disassembler::format_u8(std::ostream &stream, u8 value)
|
||||
{
|
||||
util::stream_format(stream, "#0x%02X", value);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_i8(std::ostream &stream, u8 value)
|
||||
{
|
||||
if (value >= 0x0a)
|
||||
util::stream_format(stream, "#0x%X", value);
|
||||
else
|
||||
util::stream_format(stream, "#%d", value);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_disp(std::ostream &stream, u8 offs, unsigned shift)
|
||||
{
|
||||
// 10-bit (word), 9-bit (half-word) or 8-bit (byte) signed displacement
|
||||
u16 disp;
|
||||
if (BIT(offs, 7))
|
||||
{
|
||||
disp = u16(0x100 - offs) << shift;
|
||||
stream << "-";
|
||||
}
|
||||
else
|
||||
disp = u16(offs) << shift;
|
||||
|
||||
if (disp >= 0x0a)
|
||||
util::stream_format(stream, "0x%X", disp);
|
||||
else
|
||||
util::stream_format(stream, "%d", disp);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_u10(std::ostream &stream, u16 value)
|
||||
{
|
||||
if (value >= 0x0a)
|
||||
util::stream_format(stream, "#0x%X", value);
|
||||
else
|
||||
util::stream_format(stream, "#%d", value);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_i20(std::ostream &stream, u32 value)
|
||||
{
|
||||
util::stream_format(stream, "#0x%05X", value);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_i32(std::ostream &stream, u32 value)
|
||||
{
|
||||
util::stream_format(stream, "#0x%08X", value);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_label(std::ostream &stream, offs_t addr)
|
||||
{
|
||||
util::stream_format(stream, "0x%X", u32(addr));
|
||||
}
|
||||
|
||||
void fr_disassembler::format_dir(std::ostream &stream, u16 addr)
|
||||
{
|
||||
if (addr >= 0x100)
|
||||
util::stream_format(stream, "@0x%03X", addr);
|
||||
else
|
||||
util::stream_format(stream, "@0x%02X", addr);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_ac_rdisp(std::ostream &stream, u8 rj)
|
||||
{
|
||||
util::stream_format(stream, "@(R13, R%d)", rj);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_sp_udisp(std::ostream &stream, u8 disp)
|
||||
{
|
||||
// unsigned displacement
|
||||
util::stream_format(stream, "@(R15, %d)", disp);
|
||||
}
|
||||
|
||||
void fr_disassembler::format_rs(std::ostream &stream, u8 reg)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // Table Base Register
|
||||
stream << "TBR";
|
||||
break;
|
||||
|
||||
case 1: // Return Pointer
|
||||
stream << "RP";
|
||||
break;
|
||||
|
||||
case 2: // System Stack Pointer (R15 when S = 0)
|
||||
stream << "SSP";
|
||||
break;
|
||||
|
||||
case 3: // User Stack Pointer (R15 when S = 1)
|
||||
stream << "USP";
|
||||
break;
|
||||
|
||||
case 4: // Multiply/Divide Register (high 32 bits)
|
||||
stream << "MDH";
|
||||
break;
|
||||
|
||||
case 5: // Multiply/Divide Register (low 32 bits)
|
||||
stream << "MDL";
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "reserved";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_invalid(std::ostream &stream, u16 opcode)
|
||||
{
|
||||
util::stream_format(stream, "%-8s0x%04X", ".DATA.H", opcode);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_i4op(std::ostream &stream, u16 opcode, const char *inst)
|
||||
{
|
||||
// Arithmetic instructions with 4-bit (effectively 5-bit) positive or negative immediate offset
|
||||
util::stream_format(stream, "%-8s#", inst);
|
||||
u8 value = (opcode & 0x00f0) >> 4;
|
||||
if (BIT(opcode, 9))
|
||||
{
|
||||
stream << "-";
|
||||
value = 0x10 - value;
|
||||
}
|
||||
if (value >= 0x0a)
|
||||
util::stream_format(stream, "0x%X", value);
|
||||
else
|
||||
util::stream_format(stream, "%d", value);
|
||||
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_shift(std::ostream &stream, u16 opcode, const char *inst)
|
||||
{
|
||||
// Register shifts with 4-bit (effectively 5-bit) immediate offset
|
||||
util::stream_format(stream, "%-8s#%d, R%d", inst, (opcode & 0x01f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_rrop(std::ostream &stream, u16 opcode, const char *inst)
|
||||
{
|
||||
// Simple register-to-register operations (and multiplication)
|
||||
util::stream_format(stream, "%-8sR%d, R%d", inst, (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_ld_fp_disp(std::ostream &stream, u16 opcode, const char *inst, unsigned shift)
|
||||
{
|
||||
// Load (zero extended) from memory at frame pointer ± 10-bit/9-bit/8-bit displacement
|
||||
util::stream_format(stream, "%-8s@(R14, ", inst);
|
||||
format_disp(stream, (opcode & 0x0ff0) >> 4, shift);
|
||||
util::stream_format(stream, "), R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_st_fp_disp(std::ostream &stream, u16 opcode, const char *inst, unsigned shift)
|
||||
{
|
||||
// Store to memory at frame pointer ± 10-bit/9-bit/8-bit displacement
|
||||
util::stream_format(stream, "%-8sR%d, @(R14, ", inst, opcode & 0x000f);
|
||||
format_disp(stream, (opcode & 0x0ff0) >> 4, shift);
|
||||
stream << ")";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_ldstm(std::ostream &stream, u16 opcode, const char *inst)
|
||||
{
|
||||
// Load/store register list in (R0-R7) or (R8-R15)
|
||||
util::stream_format(stream, "%-8s(", inst);
|
||||
int base = BIT(opcode, 8) ? 8 : 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if (BIT(opcode, i))
|
||||
{
|
||||
util::stream_format(stream, "R%d", BIT(opcode, 9) ? base + 7 - i : base + i);
|
||||
opcode &= ~(1 << i);
|
||||
if ((opcode & 0x00ff) != 0)
|
||||
stream << ", ";
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
stream << ")";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_bop(std::ostream &stream, u16 opcode, const char *inst)
|
||||
{
|
||||
// Operands are 4-bit immediate mask and upper or lower nibble of memory
|
||||
util::stream_format(stream, "%-8s#0x%X, @R%d", inst, (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_cop(std::ostream &stream, u16 op1, u16 op2, const char *inst, bool crj, bool cri)
|
||||
{
|
||||
// Coprocessor instructions
|
||||
util::stream_format(stream, "%-8s#%d, ", inst, op1 & 0x000f);
|
||||
format_u8(stream, (op2 & 0xff00) >> 8);
|
||||
util::stream_format(stream, ", %sR%d, %sR%d", crj ? "C" : "", (op2 & 0x00f0) >> 4, cri ? "C" : "", op2 & 0x000f);
|
||||
return 4 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_call(std::ostream &stream, offs_t pc, const char *inst, u16 disp)
|
||||
{
|
||||
// 12-bit relative calls, with or without delay slot
|
||||
util::stream_format(stream, "%-8s", inst);
|
||||
if (disp >= 0x800)
|
||||
format_label(stream, pc + 2 - 0x1000 + disp);
|
||||
else
|
||||
format_label(stream, pc + 2 + disp);
|
||||
return 2 | SUPPORTED | STEP_OVER;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_branch(std::ostream &stream, offs_t pc, const char *inst, u16 disp)
|
||||
{
|
||||
// Conditional/unconditional 9-bit relative branches, with or without delay slot
|
||||
util::stream_format(stream, "%-8s", inst);
|
||||
if (disp >= 0x100)
|
||||
format_label(stream, pc + 2 - 0x200 + disp);
|
||||
else
|
||||
format_label(stream, pc + 2 + disp);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_07(std::ostream &stream, offs_t pc, const fr_disassembler::data_buffer &opcodes, u16 opcode)
|
||||
{
|
||||
switch (opcode & 0x00f0)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "%-8s@R15+, R%d", "LD", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x10:
|
||||
util::stream_format(stream, "%-8sR%d, PS", "MOV", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x80:
|
||||
util::stream_format(stream, "%-8s@R15+, ", "LD");
|
||||
format_rs(stream, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x90:
|
||||
util::stream_format(stream, "%-8s@R15+, PS", "MOV");
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
default:
|
||||
return dasm_invalid(stream, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_17(std::ostream &stream, offs_t pc, const fr_disassembler::data_buffer &opcodes, u16 opcode)
|
||||
{
|
||||
switch (opcode & 0x00f0)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "%-8sR%d, @-R15", "ST", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x10:
|
||||
util::stream_format(stream, "%-8sPS, R%d", "MOV", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x80:
|
||||
util::stream_format(stream, "%-8s", "ST");
|
||||
format_rs(stream, opcode & 0x000f);
|
||||
stream << ", @-R15";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x90:
|
||||
util::stream_format(stream, "%-8sPS, @-R15", "ST");
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
default:
|
||||
return dasm_invalid(stream, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_97(std::ostream &stream, offs_t pc, const fr_disassembler::data_buffer &opcodes, u16 opcode)
|
||||
{
|
||||
switch (opcode & 0x00f0)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "%-8s@R%d", "JMP", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x10:
|
||||
util::stream_format(stream, "%-8s@R%d", "CALL", opcode & 0x000f);
|
||||
return 2 | SUPPORTED | STEP_OVER;
|
||||
|
||||
case 0x20:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "RET";
|
||||
return 2 | SUPPORTED | STEP_OUT;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0x30:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "RETI";
|
||||
return 2 | SUPPORTED | STEP_OUT;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0x40:
|
||||
util::stream_format(stream, "%-8sR%d", "DIV0S", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x50:
|
||||
util::stream_format(stream, "%-8sR%d", "DIV0U", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x60:
|
||||
util::stream_format(stream, "%-8sR%d", "DIV1", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x70:
|
||||
util::stream_format(stream, "%-8sR%d", "DIV2", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x80:
|
||||
util::stream_format(stream, "%-8sR%d", "EXTSB", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x90:
|
||||
util::stream_format(stream, "%-8sR%d", "EXTUB", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xa0:
|
||||
util::stream_format(stream, "%-8sR%d", "EXTSH", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xb0:
|
||||
util::stream_format(stream, "%-8sR%d", "EXTUH", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
default:
|
||||
return dasm_invalid(stream, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::dasm_9f(std::ostream &stream, offs_t pc, const fr_disassembler::data_buffer &opcodes, u16 opcode)
|
||||
{
|
||||
switch (opcode & 0x00f0)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "%-8s@R%d", "JMP:D", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x10:
|
||||
util::stream_format(stream, "%-8s@R%d", "CALL:D", opcode & 0x000f);
|
||||
return 2 | SUPPORTED | STEP_OVER | step_over_extra(1);
|
||||
|
||||
case 0x20:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "RET:D";
|
||||
return 2 | SUPPORTED | STEP_OUT | step_over_extra(1);
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
|
||||
case 0x30:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
// Emulator software interrupt (#0x09)
|
||||
stream << "INTE";
|
||||
return 2 | SUPPORTED | STEP_OVER;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0x60:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "DIV3";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0x70:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "DIV4S";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
|
||||
case 0x80: // LDI:32
|
||||
util::stream_format(stream, "%-8s", "LDI");
|
||||
format_i32(stream, opcodes.r32(pc + 2));
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 6 | SUPPORTED;
|
||||
|
||||
case 0x90:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "LEAVE";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0xa0:
|
||||
if ((opcode & 0x000f) == 0)
|
||||
{
|
||||
stream << "NOP";
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return dasm_invalid(stream, opcode);
|
||||
|
||||
case 0xc0:
|
||||
return dasm_cop(stream, opcode, opcodes.r16(pc + 2), "COPOP", true, true);
|
||||
|
||||
case 0xd0:
|
||||
return dasm_cop(stream, opcode, opcodes.r16(pc + 2), "COPLD", false, true);
|
||||
|
||||
case 0xe0:
|
||||
return dasm_cop(stream, opcode, opcodes.r16(pc + 2), "COPST", true, false);
|
||||
|
||||
case 0xf0:
|
||||
return dasm_cop(stream, opcode, opcodes.r16(pc + 2), "COPSV", true, false);
|
||||
|
||||
default:
|
||||
return dasm_invalid(stream, opcode);
|
||||
}
|
||||
}
|
||||
|
||||
offs_t fr_disassembler::disassemble(std::ostream &stream, offs_t pc, const fr_disassembler::data_buffer &opcodes, const fr_disassembler::data_buffer ¶ms)
|
||||
{
|
||||
u16 opcode = opcodes.r16(pc);
|
||||
|
||||
switch (opcode >> 8)
|
||||
{
|
||||
case 0x00:
|
||||
util::stream_format(stream, "%-8s", "LD");
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x01:
|
||||
util::stream_format(stream, "%-8s", "LDUH");
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x02:
|
||||
util::stream_format(stream, "%-8s", "LDUB");
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x03:
|
||||
util::stream_format(stream, "%-8s", "LD");
|
||||
format_sp_udisp(stream, (opcode & 0x00f0) >> 2);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x04:
|
||||
util::stream_format(stream, "%-8s@R%d, R%d", "LD", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x05:
|
||||
util::stream_format(stream, "%-8s@R%d, R%d", "LDUH", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x06:
|
||||
util::stream_format(stream, "%-8s@R%d, R%d", "LDUB", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x07:
|
||||
return dasm_07(stream, pc, opcodes, opcode);
|
||||
|
||||
case 0x08:
|
||||
util::stream_format(stream, "%-8s", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
stream << ", R13";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x09:
|
||||
util::stream_format(stream, "%-8s", "DMOVH");
|
||||
format_dir(stream, (opcode & 0x00ff) << 1);
|
||||
stream << ", R13";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0a:
|
||||
util::stream_format(stream, "%-8s", "DMOVB");
|
||||
format_dir(stream, opcode & 0x00ff);
|
||||
stream << ", R13";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0b:
|
||||
util::stream_format(stream, "%-8s", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
stream << ", @-R15";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0c:
|
||||
util::stream_format(stream, "%-8s", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
stream << ", @R13+";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0d:
|
||||
util::stream_format(stream, "%-8s", "DMOVH");
|
||||
format_dir(stream, (opcode & 0x00ff) << 1);
|
||||
stream << ", @R13+";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0e:
|
||||
util::stream_format(stream, "%-8s", "DMOVB");
|
||||
format_dir(stream, opcode & 0x00ff);
|
||||
stream << ", @R13+";
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x0f:
|
||||
util::stream_format(stream, "%-8s", "ENTER");
|
||||
format_u10(stream, (opcode & 0x00ff) << 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x10:
|
||||
util::stream_format(stream, "%-8sR%d, ", "ST", opcode & 0x000f);
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x11:
|
||||
util::stream_format(stream, "%-8sR%d, ", "STH", opcode & 0x000f);
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x12:
|
||||
util::stream_format(stream, "%-8sR%d, ", "STB", opcode & 0x000f);
|
||||
format_ac_rdisp(stream, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x13:
|
||||
util::stream_format(stream, "%-8sR%d, ", "ST", opcode & 0x000f);
|
||||
format_sp_udisp(stream, (opcode & 0x00f0) >> 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x14:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "ST", opcode & 0x000f, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x15:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "STH", opcode & 0x000f, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x16:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "STB", opcode & 0x000f, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x17:
|
||||
return dasm_17(stream, pc, opcodes, opcode);
|
||||
|
||||
case 0x18:
|
||||
util::stream_format(stream, "%-8sR13, ", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x19:
|
||||
util::stream_format(stream, "%-8sR13, ", "DMOVH");
|
||||
format_dir(stream, (opcode & 0x00ff) << 1);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1a:
|
||||
util::stream_format(stream, "%-8sR13, ", "DMOVB");
|
||||
format_dir(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1b:
|
||||
util::stream_format(stream, "%-8s@R15+, ", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1c:
|
||||
util::stream_format(stream, "%-8s@R13+, ", "DMOV");
|
||||
format_dir(stream, (opcode & 0x00ff) << 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1d:
|
||||
util::stream_format(stream, "%-8s@R13+, ", "DMOVH");
|
||||
format_dir(stream, (opcode & 0x00ff) << 1);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1e:
|
||||
util::stream_format(stream, "%-8s@R13+, ", "DMOVB");
|
||||
format_dir(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x1f:
|
||||
util::stream_format(stream, "%-8s", "INT");
|
||||
format_u8(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED | STEP_OVER;
|
||||
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
|
||||
return dasm_ld_fp_disp(stream, opcode, "LD", 2);
|
||||
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
||||
return dasm_st_fp_disp(stream, opcode, "ST", 2);
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f:
|
||||
return dasm_ld_fp_disp(stream, opcode, "LDUH", 1);
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
|
||||
return dasm_st_fp_disp(stream, opcode, "STH", 1);
|
||||
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
|
||||
case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
|
||||
return dasm_ld_fp_disp(stream, opcode, "LDUB", 0);
|
||||
|
||||
case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77:
|
||||
case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f:
|
||||
return dasm_st_fp_disp(stream, opcode, "STB", 0);
|
||||
|
||||
case 0x80:
|
||||
return dasm_bop(stream, opcode, "BANDL");
|
||||
|
||||
case 0x81:
|
||||
return dasm_bop(stream, opcode, "BANDH");
|
||||
|
||||
case 0x82:
|
||||
return dasm_rrop(stream, opcode, "AND");
|
||||
|
||||
case 0x83:
|
||||
util::stream_format(stream, "%-8s", "ANDCCR");
|
||||
format_u8(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x84:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "AND", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x85:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "ANDH", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x86:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "ANDB", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x87:
|
||||
util::stream_format(stream, "%-8s", "STILM");
|
||||
format_u8(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x88:
|
||||
return dasm_bop(stream, opcode, "BTSTL");
|
||||
|
||||
case 0x89:
|
||||
return dasm_bop(stream, opcode, "BTSTH");
|
||||
|
||||
case 0x8a:
|
||||
util::stream_format(stream, "%-8s@R%d, R%d", "XCHB", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x8b:
|
||||
return dasm_rrop(stream, opcode, "MOV");
|
||||
|
||||
case 0x8c:
|
||||
return dasm_ldstm(stream, opcode, "LDM0");
|
||||
|
||||
case 0x8d:
|
||||
return dasm_ldstm(stream, opcode, "LDM1");
|
||||
|
||||
case 0x8e:
|
||||
return dasm_ldstm(stream, opcode, "STM0");
|
||||
|
||||
case 0x8f:
|
||||
return dasm_ldstm(stream, opcode, "STM1");
|
||||
|
||||
case 0x90:
|
||||
return dasm_bop(stream, opcode, "BORL");
|
||||
|
||||
case 0x91:
|
||||
return dasm_bop(stream, opcode, "BORH");
|
||||
|
||||
case 0x92:
|
||||
return dasm_rrop(stream, opcode, "OR");
|
||||
|
||||
case 0x93:
|
||||
util::stream_format(stream, "%-8s", "ORCCR");
|
||||
format_u8(stream, opcode & 0x00ff);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x94:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "OR", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x95:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "ORH", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x96:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "ORB", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x97:
|
||||
return dasm_97(stream, pc, opcodes, opcode);
|
||||
|
||||
case 0x98:
|
||||
return dasm_bop(stream, opcode, "BEORL");
|
||||
|
||||
case 0x99:
|
||||
return dasm_bop(stream, opcode, "BEORH");
|
||||
|
||||
case 0x9a:
|
||||
return dasm_rrop(stream, opcode, "EOR");
|
||||
|
||||
case 0x9b: // LDI:20
|
||||
util::stream_format(stream, "%-8s", "LDI");
|
||||
format_i20(stream, u32(opcode & 0x00f0) << 12 | opcodes.r16(pc + 2));
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 4 | SUPPORTED;
|
||||
|
||||
case 0x9c:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "EOR", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x9d:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "EORH", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x9e:
|
||||
util::stream_format(stream, "%-8sR%d, @R%d", "EORB", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0x9f:
|
||||
return dasm_9f(stream, pc, opcodes, opcode);
|
||||
|
||||
case 0xa0:
|
||||
case 0xa1: // ADDN2
|
||||
return dasm_i4op(stream, opcode, "ADDN");
|
||||
|
||||
case 0xa2:
|
||||
return dasm_rrop(stream, opcode, "ADDN");
|
||||
|
||||
case 0xa3:
|
||||
util::stream_format(stream, "%-8s#", "ADDSP");
|
||||
format_disp(stream, opcode & 0x00ff, 2);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xa4:
|
||||
case 0xa5: // ADD2
|
||||
return dasm_i4op(stream, opcode, "ADD");
|
||||
|
||||
case 0xa6:
|
||||
return dasm_rrop(stream, opcode, "ADD");
|
||||
|
||||
case 0xa7:
|
||||
return dasm_rrop(stream, opcode, "ADDC");
|
||||
|
||||
case 0xa8:
|
||||
case 0xa9: // CMP2
|
||||
return dasm_i4op(stream, opcode, "CMP");
|
||||
|
||||
case 0xaa:
|
||||
return dasm_rrop(stream, opcode, "CMP");
|
||||
|
||||
case 0xab:
|
||||
return dasm_rrop(stream, opcode, "MULH");
|
||||
|
||||
case 0xac:
|
||||
return dasm_rrop(stream, opcode, "SUB");
|
||||
|
||||
case 0xad:
|
||||
return dasm_rrop(stream, opcode, "SUBC");
|
||||
|
||||
case 0xae:
|
||||
return dasm_rrop(stream, opcode, "SUBN");
|
||||
|
||||
case 0xaf:
|
||||
return dasm_rrop(stream, opcode, "MUL");
|
||||
|
||||
case 0xb0:
|
||||
case 0xb1: // LSR2
|
||||
return dasm_shift(stream, opcode, "LSR");
|
||||
|
||||
case 0xb2:
|
||||
return dasm_rrop(stream, opcode, "LSR");
|
||||
|
||||
case 0xb3:
|
||||
util::stream_format(stream, "%-8sR%d, ", "MOV", opcode & 0x000f);
|
||||
format_rs(stream, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xb4:
|
||||
case 0xb5: // LSL2
|
||||
return dasm_shift(stream, opcode, "LSL");
|
||||
|
||||
case 0xb6:
|
||||
return dasm_rrop(stream, opcode, "LSL");
|
||||
|
||||
case 0xb7:
|
||||
util::stream_format(stream, "%-8s", "MOV");
|
||||
format_rs(stream, (opcode & 0x00f0) >> 4);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xb8:
|
||||
case 0xb9: // ASR2
|
||||
return dasm_shift(stream, opcode, "ASR");
|
||||
|
||||
case 0xba:
|
||||
return dasm_rrop(stream, opcode, "ASR");
|
||||
|
||||
case 0xbb:
|
||||
return dasm_rrop(stream, opcode, "MULUH");
|
||||
|
||||
case 0xbc:
|
||||
util::stream_format(stream, "%-8s@R%d+, #%d", "LDRES", opcode & 0x000f, (opcode & 0x00f0) >> 4);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xbd:
|
||||
util::stream_format(stream, "%-8s#%d, @R%d+", "STRES", (opcode & 0x00f0) >> 4, opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xbf:
|
||||
return dasm_rrop(stream, opcode, "MULU");
|
||||
|
||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
||||
case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: // LDI:8
|
||||
util::stream_format(stream, "%-8s", "LDI");
|
||||
format_i8(stream, (opcode & 0x0ff0) >> 4);
|
||||
util::stream_format(stream, ", R%d", opcode & 0x000f);
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||
return dasm_call(stream, pc, "CALL", (opcode & 0x07ff) << 1);
|
||||
|
||||
case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||
return dasm_call(stream, pc, "CALL:D", (opcode & 0x07ff) << 1) | step_over_extra(1);
|
||||
|
||||
case 0xe0:
|
||||
return dasm_branch(stream, pc, "BRA", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe1:
|
||||
return dasm_branch(stream, pc, "BNO", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe2:
|
||||
return dasm_branch(stream, pc, "BEQ", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe3:
|
||||
return dasm_branch(stream, pc, "BNE", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe4:
|
||||
return dasm_branch(stream, pc, "BC", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe5:
|
||||
return dasm_branch(stream, pc, "BNC", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe6:
|
||||
return dasm_branch(stream, pc, "BN", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe7:
|
||||
return dasm_branch(stream, pc, "BP", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe8:
|
||||
return dasm_branch(stream, pc, "BV", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xe9:
|
||||
return dasm_branch(stream, pc, "BNV", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xea:
|
||||
return dasm_branch(stream, pc, "BLT", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xeb:
|
||||
return dasm_branch(stream, pc, "BGE", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xec:
|
||||
return dasm_branch(stream, pc, "BLE", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xed:
|
||||
return dasm_branch(stream, pc, "BGT", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xee:
|
||||
return dasm_branch(stream, pc, "BLS", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xef:
|
||||
return dasm_branch(stream, pc, "BHI", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf0:
|
||||
return dasm_branch(stream, pc, "BRA:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf1:
|
||||
return dasm_branch(stream, pc, "BNO:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf2:
|
||||
return dasm_branch(stream, pc, "BEQ:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf3:
|
||||
return dasm_branch(stream, pc, "BNE:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf4:
|
||||
return dasm_branch(stream, pc, "BC:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf5:
|
||||
return dasm_branch(stream, pc, "BNC:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf6:
|
||||
return dasm_branch(stream, pc, "BN:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf7:
|
||||
return dasm_branch(stream, pc, "BP:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf8:
|
||||
return dasm_branch(stream, pc, "BV:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xf9:
|
||||
return dasm_branch(stream, pc, "BNV:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xfa:
|
||||
return dasm_branch(stream, pc, "BLT:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xfb:
|
||||
return dasm_branch(stream, pc, "BGE:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xfc:
|
||||
return dasm_branch(stream, pc, "BLE:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xfd:
|
||||
return dasm_branch(stream, pc, "BGT:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xfe:
|
||||
return dasm_branch(stream, pc, "BLS:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
case 0xff:
|
||||
return dasm_branch(stream, pc, "BHI:D", (opcode & 0x00ff) << 1);
|
||||
|
||||
default:
|
||||
return dasm_invalid(stream, opcode);
|
||||
}
|
||||
}
|
49
src/devices/cpu/fr/frdasm.h
Normal file
49
src/devices/cpu/fr/frdasm.h
Normal file
@ -0,0 +1,49 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_FR_FRDASM_H
|
||||
#define MAME_CPU_FR_FRDASM_H 1
|
||||
|
||||
#pragma once
|
||||
|
||||
class fr_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
fr_disassembler();
|
||||
|
||||
// disassembler overrides
|
||||
virtual u32 opcode_alignment() const override;
|
||||
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
|
||||
|
||||
protected:
|
||||
// internal helpers
|
||||
void format_u8(std::ostream &stream, u8 value);
|
||||
void format_i8(std::ostream &stream, u8 value);
|
||||
void format_disp(std::ostream &stream, u8 offs, unsigned shift);
|
||||
void format_u10(std::ostream &stream, u16 value);
|
||||
void format_i20(std::ostream &stream, u32 value);
|
||||
void format_i32(std::ostream &stream, u32 value);
|
||||
void format_label(std::ostream &stream, offs_t addr);
|
||||
void format_dir(std::ostream &stream, u16 addr);
|
||||
void format_ac_rdisp(std::ostream &stream, u8 rj);
|
||||
void format_sp_udisp(std::ostream &stream, u8 disp);
|
||||
void format_rs(std::ostream &stream, u8 reg);
|
||||
offs_t dasm_invalid(std::ostream &stream, u16 opcode);
|
||||
offs_t dasm_i4op(std::ostream &stream, u16 opcode, const char *inst);
|
||||
offs_t dasm_shift(std::ostream &stream, u16 opcode, const char *inst);
|
||||
offs_t dasm_rrop(std::ostream &stream, u16 opcode, const char *inst);
|
||||
offs_t dasm_ld_fp_disp(std::ostream &stream, u16 opcode, const char *inst, unsigned shift);
|
||||
offs_t dasm_st_fp_disp(std::ostream &stream, u16 opcode, const char *inst, unsigned shift);
|
||||
offs_t dasm_ldstm(std::ostream &stream, u16 opcode, const char *inst);
|
||||
offs_t dasm_bop(std::ostream &stream, u16 opcode, const char *inst);
|
||||
offs_t dasm_cop(std::ostream &stream, u16 op1, u16 op2, const char *inst, bool crj, bool cri);
|
||||
offs_t dasm_call(std::ostream &stream, offs_t pc, const char *inst, u16 disp);
|
||||
offs_t dasm_branch(std::ostream &stream, offs_t pc, const char *inst, u16 disp);
|
||||
offs_t dasm_07(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 opcode);
|
||||
offs_t dasm_17(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 opcode);
|
||||
offs_t dasm_97(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 opcode);
|
||||
offs_t dasm_9f(std::ostream &stream, offs_t pc, const data_buffer &opcodes, u16 opcode);
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_FR_FRDASM_H
|
@ -49,6 +49,7 @@ using util::BIT;
|
||||
#include "cpu/esrip/esripdsm.h"
|
||||
#include "cpu/f2mc16/f2mc16dasm.h"
|
||||
#include "cpu/f8/f8dasm.h"
|
||||
#include "cpu/fr/frdasm.h"
|
||||
#include "cpu/g65816/g65816ds.h"
|
||||
#include "cpu/h6280/6280dasm.h"
|
||||
#include "cpu/h8/h8d.h"
|
||||
@ -359,6 +360,7 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "esrip", be, 0, []() -> util::disasm_interface * { return new esrip_disassembler; } },
|
||||
{ "f2mc16", le, 0, []() -> util::disasm_interface * { return new f2mc16_disassembler; } },
|
||||
{ "f8", be, 0, []() -> util::disasm_interface * { return new f8_disassembler; } },
|
||||
{ "fr", be, 0, []() -> util::disasm_interface * { return new fr_disassembler; } },
|
||||
{ "g65816", le, 0, []() -> util::disasm_interface * { return new g65816_disassembler(&g65816_unidasm); } },
|
||||
{ "h6280", le, 0, []() -> util::disasm_interface * { return new h6280_disassembler; } },
|
||||
{ "h8", be, 0, []() -> util::disasm_interface * { return new h8_disassembler; } },
|
||||
|
Loading…
Reference in New Issue
Block a user