mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
pic1670: Add a disassembler [O. Galibert]
This commit is contained in:
parent
757c179183
commit
1edc4eb359
@ -1281,6 +1281,16 @@ if (CPUS["PIC16C5X"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/pic16c5x/16c5xdsm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- PIC1670 - Disassembler only temporarily
|
||||
--@src/devices/cpu/pic1670/pic1670.h,CPUS["PIC1670"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (CPUS["PIC1670"]~=null or _OPTIONS["with-tools"]) then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/pic1670/pic1670d.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/pic1670/pic1670d.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Microchip PIC16C62x
|
||||
--@src/devices/cpu/pic16c62x/pic16c62x.h,CPUS["PIC16C62X"] = true
|
||||
|
103
src/devices/cpu/pic1670/pic1670d.cpp
Normal file
103
src/devices/cpu/pic1670/pic1670d.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert
|
||||
|
||||
// PIC1670 disassembler
|
||||
|
||||
#include "emu.h"
|
||||
#include "pic1670d.h"
|
||||
|
||||
u32 pic1670_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
char pic1670_disassembler::fw(u16 opcode)
|
||||
{
|
||||
return opcode & 0x40 ? 'f' : 'w';
|
||||
}
|
||||
|
||||
std::string pic1670_disassembler::freg(u16 opcode) const
|
||||
{
|
||||
static const char *const fnames[0x10] = {
|
||||
"(fsr)", "w", "pc", "asr", "fsr", "isr", "rtcca", "rtccb",
|
||||
"riopa", "iopa", "riopb" "iopb", "riorpc", "iopc", "riopd", "iopd"
|
||||
};
|
||||
u16 reg = opcode & 0x3f;
|
||||
if(reg < 0x10)
|
||||
return fnames[reg];
|
||||
return util::string_format("f_%02x", reg);
|
||||
}
|
||||
|
||||
std::string pic1670_disassembler::imm8(u16 opcode)
|
||||
{
|
||||
if((opcode & 0xff) < 10)
|
||||
return util::string_format("%d", opcode & 0xff);
|
||||
else
|
||||
return util::string_format("'h'%02x", opcode & 0xff);
|
||||
}
|
||||
|
||||
// Note: the decodes have more don't care than the manual, they reflect the
|
||||
// reality of the opcode decode of the die, e.g. bits 3,4,5 are not used there
|
||||
|
||||
#define P std::ostream &stream, const pic1670_disassembler *d, u16 opcode, u16 pc
|
||||
const pic1670_disassembler::instruction pic1670_disassembler::instructions[] {
|
||||
{ 0x0004, 0x1fc7, [](P) -> u32 { util::stream_format(stream, "daw" ); return 1; } },
|
||||
{ 0x0040, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "movwf %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x0080, 0x1f80, [](P) -> u32 { util::stream_format(stream, "subbwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0100, 0x1f80, [](P) -> u32 { util::stream_format(stream, "subwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0180, 0x1f80, [](P) -> u32 { util::stream_format(stream, "decf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0200, 0x1f80, [](P) -> u32 { util::stream_format(stream, "iorwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0280, 0x1f80, [](P) -> u32 { util::stream_format(stream, "andwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0300, 0x1f80, [](P) -> u32 { util::stream_format(stream, "xorwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0380, 0x1f80, [](P) -> u32 { util::stream_format(stream, "addwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0400, 0x1f80, [](P) -> u32 { util::stream_format(stream, "adcwf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0480, 0x1f80, [](P) -> u32 { util::stream_format(stream, "comf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0500, 0x1f80, [](P) -> u32 { util::stream_format(stream, "incf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0580, 0x1f80, [](P) -> u32 { util::stream_format(stream, "decfsz %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0600, 0x1f80, [](P) -> u32 { util::stream_format(stream, "rlcf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0680, 0x1f80, [](P) -> u32 { util::stream_format(stream, "rrcf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0700, 0x1f80, [](P) -> u32 { util::stream_format(stream, "swapf %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
{ 0x0780, 0x1f80, [](P) -> u32 { util::stream_format(stream, "incfsz %s, %c", d->freg(opcode), fw(opcode)); return 1; } },
|
||||
|
||||
{ 0x1000, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "movfw %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x1040, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "clrf %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x1080, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "rrncf %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x10c0, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "rlncf %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x1100, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "cpfslt %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x1140, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "cpfseq %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x1180, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "cpfsgt %s", d->freg(opcode) ); return 1; } },
|
||||
{ 0x11c0, 0x1fc0, [](P) -> u32 { util::stream_format(stream, "testf %s", d->freg(opcode) ); return 1; } },
|
||||
|
||||
{ 0x0800, 0x1e00, [](P) -> u32 { util::stream_format(stream, "bcf %d, %s", (opcode >> 6) & 7, d->freg(opcode)); return 1; } },
|
||||
{ 0x0a00, 0x1e00, [](P) -> u32 { util::stream_format(stream, "bsf %d, %s", (opcode >> 6) & 7, d->freg(opcode)); return 1; } },
|
||||
{ 0x0c00, 0x1e00, [](P) -> u32 { util::stream_format(stream, "btfsc %d, %s", (opcode >> 6) & 7, d->freg(opcode)); return 1; } },
|
||||
{ 0x0e00, 0x1e00, [](P) -> u32 { util::stream_format(stream, "btfss %d, %s", (opcode >> 6) & 7, d->freg(opcode)); return 1; } },
|
||||
|
||||
{ 0x0000, 0x1fc7, [](P) -> u32 { util::stream_format(stream, "nop" ); return 1; } },
|
||||
{ 0x0001, 0x1fc7, [](P) -> u32 { util::stream_format(stream, "halt" ); return 1; } },
|
||||
{ 0x0002, 0x1fc7, [](P) -> u32 { util::stream_format(stream, "retfi" ); return 1 | STEP_OUT; } },
|
||||
{ 0x0003, 0x1fc7, [](P) -> u32 { util::stream_format(stream, "retfs" ); return 1 | STEP_OUT; } },
|
||||
{ 0x1200, 0x1f00, [](P) -> u32 { util::stream_format(stream, "movlw %s", imm8(opcode)); return 1; } },
|
||||
{ 0x1300, 0x1f00, [](P) -> u32 { util::stream_format(stream, "addlw %s", imm8(opcode)); return 1; } },
|
||||
{ 0x1400, 0x1f00, [](P) -> u32 { util::stream_format(stream, "iorlw %s", imm8(opcode)); return 1; } },
|
||||
{ 0x1500, 0x1f00, [](P) -> u32 { util::stream_format(stream, "andlw %s", imm8(opcode)); return 1; } },
|
||||
{ 0x1600, 0x1f00, [](P) -> u32 { util::stream_format(stream, "xorlw %s", imm8(opcode)); return 1; } },
|
||||
{ 0x1700, 0x1f00, [](P) -> u32 { util::stream_format(stream, "retlw %s", imm8(opcode)); return 1 | STEP_OUT; } },
|
||||
|
||||
{ 0x1800, 0x1c00, [](P) -> u32 { util::stream_format(stream, "goto %03x", opcode & 0x3ff); return 1; } },
|
||||
{ 0x1c00, 0x1c00, [](P) -> u32 { util::stream_format(stream, "call %03x", opcode & 0x3ff); return 1 | STEP_OVER; } },
|
||||
|
||||
{ 0x0000, 0x0000, [](P) -> u32 { util::stream_format(stream, "?%04x", opcode); return 1; } },
|
||||
};
|
||||
|
||||
#undef P
|
||||
|
||||
offs_t pic1670_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
|
||||
{
|
||||
u16 opcode = opcodes.r16(pc);
|
||||
|
||||
for(u32 i=0;; i++)
|
||||
if((opcode & instructions[i].mask) == instructions[i].value)
|
||||
return instructions[i].cb(stream, this, opcode, pc) | SUPPORTED;
|
||||
return 0;
|
||||
}
|
34
src/devices/cpu/pic1670/pic1670d.h
Normal file
34
src/devices/cpu/pic1670/pic1670d.h
Normal file
@ -0,0 +1,34 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Olivier Galibert
|
||||
|
||||
// PIC1670 disassembler
|
||||
|
||||
#ifndef MAME_CPU_PIC1670_PIC1670D_H
|
||||
#define MAME_CPU_PIC1670_PIC1670D_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class pic1670_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
pic1670_disassembler() = default;
|
||||
virtual ~pic1670_disassembler() = default;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
struct instruction {
|
||||
u16 value;
|
||||
u16 mask;
|
||||
u32 (*cb)(std::ostream &, const pic1670_disassembler *, u16, u16);
|
||||
};
|
||||
|
||||
static const instruction instructions[];
|
||||
|
||||
std::string freg(u16 opcode) const;
|
||||
static char fw(u16 opcode);
|
||||
static std::string imm8(u16 opcode);
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_PIC1670_PIC1670D_H
|
@ -118,6 +118,7 @@ using util::BIT;
|
||||
#include "cpu/pdp1/tx0dasm.h"
|
||||
#include "cpu/pdp8/pdp8dasm.h"
|
||||
#include "cpu/pic16/pic16d.h"
|
||||
#include "cpu/pic1670/pic1670d.h"
|
||||
#include "cpu/pic16c5x/16c5xdsm.h"
|
||||
#include "cpu/pic16c62x/16c62xdsm.h"
|
||||
#include "cpu/pic17/pic17d.h"
|
||||
@ -484,6 +485,7 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } },
|
||||
{ "pic16", le, -1, []() -> util::disasm_interface * { return new pic16_disassembler; } },
|
||||
{ "pic16c5x", le, -1, []() -> util::disasm_interface * { return new pic16c5x_disassembler; } },
|
||||
{ "pic1670", le, -1, []() -> util::disasm_interface * { return new pic1670_disassembler; } },
|
||||
{ "pic16c62x", le, -1, []() -> util::disasm_interface * { return new pic16c62x_disassembler; } },
|
||||
{ "pic17", le, -1, []() -> util::disasm_interface * { return new pic17_disassembler; } },
|
||||
{ "powerpc", be, 0, []() -> util::disasm_interface * { return new powerpc_disassembler; } },
|
||||
|
Loading…
Reference in New Issue
Block a user