summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Olivier Galibert <galibert@pobox.com>2023-10-31 20:28:31 +0100
committer Olivier Galibert <galibert@pobox.com>2023-10-31 20:28:35 +0100
commit74ba1e0e7d34e00c1d0ad306d3675086b561637a (patch)
tree267d6d676ba74d6a3895a767c5271232672967e2 /src
parentb65ec2ff539ecb793aaca73fa7b2998866869578 (diff)
evolution: First stab at understanding the cpu
Diffstat (limited to 'src')
-rw-r--r--src/devices/cpu/evolution/evod.cpp51
-rw-r--r--src/devices/cpu/evolution/evod.h33
-rw-r--r--src/tools/unidasm.cpp2
3 files changed, 86 insertions, 0 deletions
diff --git a/src/devices/cpu/evolution/evod.cpp b/src/devices/cpu/evolution/evod.cpp
new file mode 100644
index 00000000000..776a2bc4509
--- /dev/null
+++ b/src/devices/cpu/evolution/evod.cpp
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// EVOLUTION disassembler
+
+#include "emu.h"
+#include "evod.h"
+
+u32 evolution_disassembler::opcode_alignment() const
+{
+ return 1;
+}
+
+// 3ea2 is table 4x2
+
+const evolution_disassembler::instruction evolution_disassembler::instructions[] = {
+ { 0x9100, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "bne %06x", (pc + 1 + s8(opcode)) & 0x1fffff); }},
+ { 0x9000, 0xf000, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "bxx %x, %06x", (opcode >> 8) & 0xf, (pc + 1 + s8(opcode)) & 0x1fffff); }},
+ { 0xa000, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "stb %02x", opcode & 0xff); }},
+ { 0xa200, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "sta %02x", opcode & 0xff); }},
+ { 0xb000, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "ldb %02x", opcode & 0xff); }},
+ { 0xb200, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "lda %02x", opcode & 0xff); }},
+ { 0xc000, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "ldbh #%02x", opcode & 0xff); }},
+ { 0xc200, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "ldah #%02x", opcode & 0xff); }},
+ { 0xd800, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "ldbl #%02x", opcode & 0xff); }},
+ { 0xda00, 0xff00, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "ldal #%02x", opcode & 0xff); }},
+ { 0xe804, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "dec b", opcode & 0xff); }},
+ { 0xea44, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "dec a", opcode & 0xff); }},
+ { 0xfc8d, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "push a"); }},
+ { 0xfccd, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "pull a"); }},
+ { 0xfd40, 0xffe0, 2, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "jsr %06x", ((opcode & 0x1f) << 16) | arg); }},
+ { 0xfe40, 0xffe0, 2, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "jmp %06x", ((opcode & 0x1f) << 16) | arg); }},
+ { 0xff41, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "rti"); }},
+ { 0xff42, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "rts"); }},
+ { 0xffff, 0xffff, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "nop"); }},
+
+ { 0x0000, 0x0000, 1, [](std::ostream &stream, u16 opcode, u16 arg, u32 pc) { util::stream_format(stream, "? %04x", opcode); }}
+};
+
+offs_t evolution_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
+{
+ u16 opcode = opcodes.r16(pc);
+
+ int i = 0;
+ while((opcode & instructions[i].mask) != instructions[i].value)
+ i++;
+
+ instructions[i].fct(stream, opcode, instructions[i].size >= 2 ? opcodes.r16(pc+1) : 0, pc);
+
+ return instructions[i].size;
+}
diff --git a/src/devices/cpu/evolution/evod.h b/src/devices/cpu/evolution/evod.h
new file mode 100644
index 00000000000..5c4e8b70587
--- /dev/null
+++ b/src/devices/cpu/evolution/evod.h
@@ -0,0 +1,33 @@
+// license:BSD-3-Clause
+// copyright-holders:Olivier Galibert
+
+// EVOLUTION disassembler
+
+#ifndef MAME_CPU_EVOLUTION_EVOD_H
+#define MAME_CPU_EVOLUTION_EVOD_H
+
+#pragma once
+
+#include <functional>
+
+class evolution_disassembler : public util::disasm_interface
+{
+public:
+ evolution_disassembler() = default;
+ virtual ~evolution_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 &params) override;
+
+private:
+ struct instruction {
+ u16 value;
+ u16 mask;
+ int size;
+ std::function<void (std::ostream &, u16, u16, u32)> fct;
+ };
+
+ static const instruction instructions[];
+};
+
+#endif // MAME_CPU_EVOLUTION_EVOD_H
diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp
index a639c963088..f390b9244c3 100644
--- a/src/tools/unidasm.cpp
+++ b/src/tools/unidasm.cpp
@@ -50,6 +50,7 @@ using util::BIT;
#include "cpu/e132xs/32xsdasm.h"
#include "cpu/es5510/es5510d.h"
#include "cpu/esrip/esripdsm.h"
+#include "cpu/evolution/evod.h"
#include "cpu/f2mc16/f2mc16d.h"
#include "cpu/f8/f8dasm.h"
#include "cpu/fr/frdasm.h"
@@ -442,6 +443,7 @@ static const dasm_table_entry dasm_table[] =
{ "epg3231", le, -1, []() -> util::disasm_interface * { return new epg3231_disassembler; } },
// { "es5510", be, 0, []() -> util::disasm_interface * { return new es5510_disassembler; } }, // Currently does nothing
{ "esrip", be, 0, []() -> util::disasm_interface * { return new esrip_disassembler; } },
+ { "evo", le, -1, []() -> util::disasm_interface * { return new evolution_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; } },