mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
New disassemblers for unidasm: hp2100, hp21mx, v620, v75
This commit is contained in:
parent
d66a877d0d
commit
c0ace34b7e
@ -3125,6 +3125,16 @@ if opt_tool(CPUS, "ALPHA") then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/alpha/alphad.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Hewlett-Packard HP2100 (disassembler only)
|
||||
--@src/devices/cpu/hp2100/hp2100.h,CPUS["HP2100"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if opt_tool(CPUS, "HP2100") then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/hp2100/hp2100d.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/hp2100/hp2100d.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- National Semiconductor HPC
|
||||
--@src/devices/cpu/hpc/hpc.h,CPUS["HPC"] = true
|
||||
@ -3580,3 +3590,12 @@ if opt_tool(CPUS, "M68HC16") then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/m68hc16/cpu16dasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/m68hc16/cpu16dasm.h")
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
-- Varian 620, disassembler only
|
||||
--------------------------------------------------
|
||||
|
||||
if opt_tool(CPUS, "V620") then
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/v620/v620dasm.cpp")
|
||||
table.insert(disasm_files , MAME_DIR .. "src/devices/cpu/v620/v620dasm.h")
|
||||
end
|
||||
|
551
src/devices/cpu/hp2100/hp2100d.cpp
Normal file
551
src/devices/cpu/hp2100/hp2100d.cpp
Normal file
@ -0,0 +1,551 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Hewlett-Packard HP2100 disassembler
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "hp2100d.h"
|
||||
|
||||
hp2100_disassembler::hp2100_disassembler()
|
||||
: util::disasm_interface()
|
||||
{
|
||||
}
|
||||
|
||||
u32 hp2100_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hp2100_disassembler::format_address(std::ostream &stream, u16 addr) const
|
||||
{
|
||||
if ((addr & 077776) == 0)
|
||||
stream << char('A' + BIT(addr, 0));
|
||||
else
|
||||
util::stream_format(stream, "%05oB", addr & 077777);
|
||||
|
||||
// Indirect addressing?
|
||||
if (BIT(addr, 15))
|
||||
stream << ",I";
|
||||
}
|
||||
|
||||
void hp2100_disassembler::format_sc(std::ostream &stream, u8 sc) const
|
||||
{
|
||||
util::stream_format(stream, "%o", sc);
|
||||
if (sc > 7)
|
||||
stream << 'B';
|
||||
}
|
||||
|
||||
// Memory reference group
|
||||
offs_t hp2100_disassembler::dasm_mrg(std::ostream &stream, u16 inst, offs_t pc) const
|
||||
{
|
||||
offs_t flags = SUPPORTED;
|
||||
switch (BIT(inst, 12, 3))
|
||||
{
|
||||
case 1:
|
||||
if (BIT(inst, 11))
|
||||
{
|
||||
stream << "JSB ";
|
||||
flags |= STEP_OVER;
|
||||
}
|
||||
else
|
||||
stream << "AND ";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (BIT(inst, 11))
|
||||
{
|
||||
stream << "JMP ";
|
||||
if (BIT(inst, 15))
|
||||
flags |= STEP_OUT;
|
||||
}
|
||||
else
|
||||
stream << "XOR ";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (BIT(inst, 11))
|
||||
{
|
||||
stream << "ISZ ";
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
else
|
||||
stream << "IOR ";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
util::stream_format(stream, "AD%c ", cab(inst));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
util::stream_format(stream, "CP%c ", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
util::stream_format(stream, "LD%c ", cab(inst));
|
||||
break;
|
||||
|
||||
case 7:
|
||||
util::stream_format(stream, "ST%c ", cab(inst));
|
||||
break;
|
||||
}
|
||||
|
||||
// Page zero or current page
|
||||
format_address(stream, (BIT(inst, 10) ? (pc & 077600) : 0) | (inst & 0100177));
|
||||
|
||||
return 1 | flags;
|
||||
}
|
||||
|
||||
const char *const hp2100_disassembler::s_shift_ops[2][8] =
|
||||
{
|
||||
{ "ALS", "ARS", "RAR", "RAL", "ALR", "ERA", "ELA", "ALF" },
|
||||
{ "BLS", "BRS", "RBR", "RBL", "BLR", "ERB", "ELB", "BLF" }
|
||||
};
|
||||
|
||||
// Shift-rotate group
|
||||
offs_t hp2100_disassembler::dasm_srg(std::ostream &stream, u16 inst) const
|
||||
{
|
||||
offs_t flags = SUPPORTED;
|
||||
|
||||
if ((inst & 001070) == 0)
|
||||
{
|
||||
if (inst == 0)
|
||||
stream << "NOP";
|
||||
else
|
||||
util::stream_format(stream, "OCT %o", inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIT(inst, 9))
|
||||
stream << s_shift_ops[BIT(inst, 11)][BIT(inst, 6, 3)];
|
||||
|
||||
if (BIT(inst, 5))
|
||||
{
|
||||
if (BIT(inst, 9))
|
||||
stream << ',';
|
||||
stream << "CLE";
|
||||
}
|
||||
|
||||
// Skip on LSB
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
if ((inst & 001040) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "SL%c", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
|
||||
if (BIT(inst, 4))
|
||||
{
|
||||
if ((inst & 001050) != 0)
|
||||
stream << ',';
|
||||
stream << s_shift_ops[BIT(inst, 11)][BIT(inst, 0, 3)];
|
||||
}
|
||||
}
|
||||
|
||||
return 1 | flags;
|
||||
}
|
||||
|
||||
// Alter-skip group
|
||||
offs_t hp2100_disassembler::dasm_asg(std::ostream &stream, u16 inst) const
|
||||
{
|
||||
offs_t flags = SUPPORTED;
|
||||
|
||||
if ((inst & 01777) == 0)
|
||||
util::stream_format(stream, "OCT %o", inst);
|
||||
else
|
||||
{
|
||||
if (BIT(inst, 8, 2) != 0)
|
||||
util::stream_format(stream, "C%c%c", "LMC"[BIT(inst, 8, 2) - 1], cab(inst));
|
||||
|
||||
// Extend skip
|
||||
if (BIT(inst, 5))
|
||||
{
|
||||
if (BIT(inst, 8, 2) != 0)
|
||||
stream << ',';
|
||||
stream << "SEZ";
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
|
||||
if (BIT(inst, 6, 2) != 0)
|
||||
{
|
||||
if ((inst & 01440) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "C%cE", "LMC"[BIT(inst, 6, 2) - 1]);
|
||||
}
|
||||
|
||||
// Accumulator skips
|
||||
if (BIT(inst, 4))
|
||||
{
|
||||
if ((inst & 01740) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "SS%c", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
if ((inst & 01760) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "SL%c", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
if (BIT(inst, 2))
|
||||
{
|
||||
if ((inst & 01770) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "IN%c", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
if (BIT(inst, 1))
|
||||
{
|
||||
if ((inst & 01774) != 0)
|
||||
stream << ',';
|
||||
util::stream_format(stream, "SZ%c", cab(inst));
|
||||
flags |= STEP_COND;
|
||||
}
|
||||
|
||||
// Reverse skip sense
|
||||
if (BIT(inst, 0))
|
||||
{
|
||||
if ((inst & 01776) != 0)
|
||||
stream << ',';
|
||||
stream << "RSS";
|
||||
}
|
||||
}
|
||||
|
||||
return 1 | flags;
|
||||
}
|
||||
|
||||
// Input-output group
|
||||
offs_t hp2100_disassembler::dasm_iog(std::ostream &stream, u16 inst) const
|
||||
{
|
||||
u8 sc = BIT(inst, 0, 6);
|
||||
offs_t flags = SUPPORTED;
|
||||
|
||||
switch (BIT(inst, 6, 3))
|
||||
{
|
||||
case 0:
|
||||
stream << "HLT";
|
||||
if (sc != 0)
|
||||
{
|
||||
stream << ' ';
|
||||
format_sc(stream, sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (sc == 1)
|
||||
{
|
||||
// Clear or set overflow flag
|
||||
if (BIT(inst, 9))
|
||||
stream << "CLO";
|
||||
else
|
||||
stream << "STO";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIT(inst, 9))
|
||||
stream << "CLF ";
|
||||
else
|
||||
stream << "STF ";
|
||||
format_sc(stream, sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (sc == 1)
|
||||
stream << "SOC";
|
||||
else
|
||||
{
|
||||
stream << "SFC ";
|
||||
format_sc(stream, sc);
|
||||
}
|
||||
flags |= STEP_COND;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (sc == 1)
|
||||
stream << "SOS";
|
||||
else
|
||||
{
|
||||
stream << "SFS ";
|
||||
format_sc(stream, sc);
|
||||
}
|
||||
flags |= STEP_COND;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
util::stream_format(stream, "MI%c ", cab(inst));
|
||||
format_sc(stream, sc);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
util::stream_format(stream, "LI%c ", cab(inst));
|
||||
format_sc(stream, sc);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
util::stream_format(stream, "OT%c ", cab(inst));
|
||||
format_sc(stream, sc);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (BIT(inst, 11))
|
||||
stream << "CLC ";
|
||||
else
|
||||
stream << "STC ";
|
||||
format_sc(stream, sc);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear flag
|
||||
if (BIT(inst, 9) && BIT(inst, 6, 3) != 1)
|
||||
stream << ",C";
|
||||
|
||||
return 1 | flags;
|
||||
}
|
||||
|
||||
// Macro instructions (including extended arithmetic group and 12901A floating-point instructions)
|
||||
offs_t hp2100_disassembler::dasm_mac(std::ostream &stream, u16 inst, offs_t pc, const hp2100_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
switch (inst & 05760)
|
||||
{
|
||||
case 00020: case 01020:
|
||||
{
|
||||
u8 n = BIT(inst, 0, 4);
|
||||
util::stream_format(stream, "AS%c %d", BIT(inst, 9) ? 'R' : 'L', n == 0 ? 16 : n);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
case 00040: case 01040:
|
||||
{
|
||||
u8 n = BIT(inst, 0, 4);
|
||||
util::stream_format(stream, "LS%c %d", BIT(inst, 9) ? 'R' : 'L', n == 0 ? 16 : n);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
case 00100: case 01100:
|
||||
{
|
||||
u8 n = BIT(inst, 0, 4);
|
||||
util::stream_format(stream, "RR%c %d", BIT(inst, 9) ? 'R' : 'L', n == 0 ? 16 : n);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
case 00200:
|
||||
stream << "MPY ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 00400:
|
||||
stream << "DIV ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 04000:
|
||||
stream << "DLD ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 04400:
|
||||
stream << "DST ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 05000:
|
||||
stream << "FAD ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 05020:
|
||||
stream << "FSB ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 05040:
|
||||
stream << "FML ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 05060:
|
||||
stream << "FDV ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 05100:
|
||||
stream << "FIX";
|
||||
return 1 | SUPPORTED;
|
||||
|
||||
case 05120:
|
||||
stream << "FLT";
|
||||
return 1 | SUPPORTED;
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "MAC %oB", inst & 05777);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
offs_t hp21mx_disassembler::dasm_mac(std::ostream &stream, u16 inst, offs_t pc, const hp2100_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if ((inst & 01740) == 01740)
|
||||
{
|
||||
// Extended instruction group
|
||||
switch (inst & 04027)
|
||||
{
|
||||
case 0000: case 04000:
|
||||
util::stream_format(stream, "S%c%c ", cab(inst), xy(inst));
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0001: case 04001:
|
||||
util::stream_format(stream, "C%c%c", cab(inst), xy(inst));
|
||||
return 1 | SUPPORTED;
|
||||
|
||||
case 0002: case 04002:
|
||||
util::stream_format(stream, "L%c%c ", cab(inst), xy(inst));
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 04003:
|
||||
util::stream_format(stream, "ST%c ", xy(inst));
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0004: case 04004:
|
||||
util::stream_format(stream, "C%c%c", xy(inst), cab(inst));
|
||||
return 1 | SUPPORTED;
|
||||
|
||||
case 04005:
|
||||
util::stream_format(stream, "LD%c ", xy(inst));
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 04006:
|
||||
util::stream_format(stream, "AD%c ", xy(inst));
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 0007: case 04007:
|
||||
util::stream_format(stream, "X%c%c", cab(inst), xy(inst));
|
||||
return 1 | SUPPORTED;
|
||||
|
||||
case 04020:
|
||||
util::stream_format(stream, "IS%c", xy(inst));
|
||||
return 1 | STEP_COND | SUPPORTED;
|
||||
|
||||
case 04021:
|
||||
util::stream_format(stream, "DS%c", xy(inst));
|
||||
return 1 | STEP_COND | SUPPORTED;
|
||||
|
||||
case 04022:
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
stream << "JPY ";
|
||||
format_address(stream, opcodes.r16(pc + 1) & 077777);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "JLY ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
}
|
||||
return 2 | SUPPORTED;
|
||||
|
||||
case 04023:
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
stream << "SBS ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
stream << ',';
|
||||
format_address(stream, opcodes.r16(pc + 2));
|
||||
return 3 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "LBT";
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
case 04024:
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
stream << "CBS ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
stream << ',';
|
||||
format_address(stream, opcodes.r16(pc + 2));
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "SBT";
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
case 04025:
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
stream << "TBS ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
stream << ',';
|
||||
format_address(stream, opcodes.r16(pc + 2));
|
||||
return 3 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "MBT ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 3 | SUPPORTED; // one extra word reserved for microcode use
|
||||
}
|
||||
|
||||
case 04026:
|
||||
if (BIT(inst, 3))
|
||||
stream << "CMW ";
|
||||
else
|
||||
stream << "CBT ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 3 | STEP_COND | SUPPORTED; // one extra word reserved for microcode use
|
||||
|
||||
case 04027:
|
||||
if (BIT(inst, 3))
|
||||
{
|
||||
stream << "MVW ";
|
||||
format_address(stream, opcodes.r16(pc + 1));
|
||||
return 3 | SUPPORTED; // one extra word reserved for microcode use
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << "SBT";
|
||||
return 1 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "MAC %oB", inst & 05777);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
}
|
||||
else
|
||||
return hp2100_disassembler::dasm_mac(stream, inst, pc, opcodes);
|
||||
}
|
||||
|
||||
offs_t hp2100_disassembler::disassemble(std::ostream &stream, offs_t pc, const hp2100_disassembler::data_buffer &opcodes, const hp2100_disassembler::data_buffer ¶ms)
|
||||
{
|
||||
u16 inst = opcodes.r16(pc);
|
||||
if (BIT(inst, 12, 3) != 0)
|
||||
return dasm_mrg(stream, inst, pc);
|
||||
else if (BIT(inst, 15))
|
||||
{
|
||||
if (BIT(inst, 10))
|
||||
return dasm_iog(stream, inst);
|
||||
else
|
||||
return dasm_mac(stream, inst, pc, opcodes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIT(inst, 10))
|
||||
return dasm_asg(stream, inst);
|
||||
else
|
||||
return dasm_srg(stream, inst);
|
||||
}
|
||||
}
|
50
src/devices/cpu/hp2100/hp2100d.h
Normal file
50
src/devices/cpu/hp2100/hp2100d.h
Normal file
@ -0,0 +1,50 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_HP2100_HP2100D_H
|
||||
#define MAME_CPU_HP2100_HP2100D_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class hp2100_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
hp2100_disassembler();
|
||||
|
||||
protected:
|
||||
// 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;
|
||||
|
||||
static char cab(u16 inst) { return char('A' + BIT(inst, 11)); }
|
||||
|
||||
void format_address(std::ostream &stream, u16 addr) const;
|
||||
virtual offs_t dasm_mac(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
|
||||
|
||||
private:
|
||||
// internal helpers
|
||||
void format_sc(std::ostream &stream, u8 sc) const;
|
||||
offs_t dasm_mrg(std::ostream &stream, u16 inst, offs_t pc) const;
|
||||
offs_t dasm_asg(std::ostream &stream, u16 inst) const;
|
||||
offs_t dasm_srg(std::ostream &stream, u16 inst) const;
|
||||
offs_t dasm_iog(std::ostream &stream, u16 inst) const;
|
||||
|
||||
// internal tables
|
||||
static const char *const s_shift_ops[2][8];
|
||||
};
|
||||
|
||||
class hp21mx_disassembler : public hp2100_disassembler
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
using hp2100_disassembler::hp2100_disassembler;
|
||||
|
||||
protected:
|
||||
virtual offs_t dasm_mac(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
|
||||
|
||||
private:
|
||||
static char xy(u16 inst) { return char('X' + BIT(inst, 3)); }
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_HP2100_HP2100D_H
|
589
src/devices/cpu/v620/v620dasm.cpp
Normal file
589
src/devices/cpu/v620/v620dasm.cpp
Normal file
@ -0,0 +1,589 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
Varian (Data Machines) 620 series disassembler
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "v620dasm.h"
|
||||
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
v620_disassembler::v620_disassembler()
|
||||
: util::disasm_interface()
|
||||
{
|
||||
}
|
||||
|
||||
v75_disassembler::v75_disassembler()
|
||||
: v620_disassembler()
|
||||
{
|
||||
}
|
||||
|
||||
u32 v620_disassembler::opcode_alignment() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
static const char *const s_alu_ops[16] =
|
||||
{
|
||||
"000", "LDA", "LDB", "LDX", "INR", "STA", "STB", "STX",
|
||||
"100", "ORA", "ADD", "ERA", "SUB", "ANA", "MUL", "DIV"
|
||||
};
|
||||
|
||||
static const char *const s_shift_ops[4] =
|
||||
{
|
||||
"ASL", "LRL", "ASR", "LSR"
|
||||
};
|
||||
|
||||
static const char *const s_in_out_ops[12] =
|
||||
{
|
||||
"IME", "INA", "INB", "INAB",
|
||||
"024", "CIA", "CIB", "CIAB",
|
||||
"OME", "OAR", "OBR", "OAB"
|
||||
};
|
||||
|
||||
static const char *const s_index_tags[2] =
|
||||
{
|
||||
",X", ",B"
|
||||
};
|
||||
|
||||
static const char *const s_reg_names[8] =
|
||||
{
|
||||
"A", "B", "X", "R3", "R4", "R5", "R6", "R7"
|
||||
};
|
||||
|
||||
static const char *const s_reg_mem_ops[4] =
|
||||
{
|
||||
"LD", "ST", "AD", "SB"
|
||||
};
|
||||
|
||||
static const char *const s_dp_ops[7] =
|
||||
{
|
||||
"DLD", "DST", "DADD", "DSUB", "DAN", "DOR", "DER"
|
||||
};
|
||||
|
||||
static const char *const s_reg_jumps[6] =
|
||||
{
|
||||
"JZ", "JNZ", "JN", "JP", "JDZ", "JDNZ"
|
||||
};
|
||||
|
||||
static const char *const s_single_reg_ops[3] =
|
||||
{
|
||||
"INC", "DEC", "COM"
|
||||
};
|
||||
|
||||
static const char *const s_rr_ops[3] =
|
||||
{
|
||||
"ADR", "SBR", "T"
|
||||
};
|
||||
|
||||
const std::unordered_map<u16, std::array<const char *, 3>> s_cond_map =
|
||||
{
|
||||
{ 0000, { "JMP", "JMPM", "XEC" } }, // unconditional
|
||||
{ 0001, { "JOF", "JOFM", "XOF" } }, // overflow set
|
||||
{ 0002, { "JAP", "JAPM", "XAP" } }, // A positive
|
||||
{ 0004, { "JAN", "JANM", "XAN" } }, // A negative
|
||||
{ 0007, { "JOFN", "JOFNM", "XOFN" } }, // overflow not set (620/f)
|
||||
{ 0010, { "JAZ", "JAZM", "XAZ" } }, // A zero
|
||||
{ 0016, { "JANZ", "JANZM", "XANZ" } }, // A not zero (620/f)
|
||||
{ 0020, { "JBZ", "JBZM", "XBZ" } }, // B zero
|
||||
{ 0026, { "JBNZ", "JBNZM", "XBNZ" } }, // B not zero (620/f)
|
||||
{ 0040, { "JXZ", "JXZM", "XXZ" } }, // X zero
|
||||
{ 0046, { "JXNZ", "JXNZM", "XXNZ" } }, // X not zero (620/f)
|
||||
{ 0100, { "JSS1", "JS1M", "XS1M" } }, // sense switch 1 set
|
||||
{ 0106, { "JS1N", "JS1NM", "XS1NM" } }, // sense switch 1 not set (620/f)
|
||||
{ 0200, { "JSS2", "JS2M", "XS2M" } }, // sense switch 2 set
|
||||
{ 0206, { "JS2N", "JS2NM", "XS2NM" } }, // sense switch 2 not set (620/f)
|
||||
{ 0400, { "JSS3", "JS3M", "XS3M" } }, // sense switch 3 set
|
||||
{ 0406, { "JS3N", "JS3NM", "XS3NM" } } // sense switch 3 not set (620/f)
|
||||
};
|
||||
|
||||
const std::unordered_map<u8, const char *> s_fpp_map =
|
||||
{
|
||||
{ 0001, "FDV" },
|
||||
{ 0010, "FAD" },
|
||||
{ 0016, "FMU" },
|
||||
{ 0020, "FLD" },
|
||||
{ 0025, "FLT" },
|
||||
{ 0050, "FSB" },
|
||||
{ 0103, "FADD" },
|
||||
{ 0106, "FMUD" },
|
||||
{ 0122, "FLDD" },
|
||||
{ 0135, "FDVD" },
|
||||
{ 0143, "FSBD" },
|
||||
{ 0200, "FST" },
|
||||
{ 0221, "FIX" },
|
||||
{ 0310, "FSTD" }
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void v620_disassembler::format_number(std::ostream &stream, u16 n) const
|
||||
{
|
||||
if (n > 7)
|
||||
stream << '0';
|
||||
util::stream_format(stream, "%o", n);
|
||||
}
|
||||
|
||||
void v620_disassembler::format_address(std::ostream &stream, u16 addr) const
|
||||
{
|
||||
if (addr >= 010000)
|
||||
stream << '0';
|
||||
util::stream_format(stream, "%05o", addr);
|
||||
}
|
||||
|
||||
offs_t v620_disassembler::dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if (inst < 004600)
|
||||
{
|
||||
// Shift instruction group
|
||||
if (BIT(inst, 8))
|
||||
util::stream_format(stream, "L%-7s", s_shift_ops[BIT(inst, 5, 2)]);
|
||||
else
|
||||
util::stream_format(stream, "%s%-5c", s_shift_ops[BIT(inst, 5, 2)], BIT(inst, 7) ? 'A' : 'B');
|
||||
util::stream_format(stream, "%d", BIT(inst, 0, 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "DATA");
|
||||
format_number(stream, inst);
|
||||
}
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
offs_t v75_disassembler::dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const v75_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if (inst >= 004600 && BIT(inst, 3, 3) != 7)
|
||||
{
|
||||
// Double-precision instructions
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-7s ", util::string_format("%s%s,%s", s_dp_ops[BIT(inst, 3, 3)], BIT(addr, 15) ? "*" : "", s_reg_names[BIT(inst, 6) ? 4 : 0]));
|
||||
if (BIT(inst, 0, 3) == 0)
|
||||
format_address(stream, addr & 077777);
|
||||
else
|
||||
{
|
||||
format_number(stream, addr & 077777);
|
||||
stream << ',' << s_reg_names[BIT(inst, 0, 3)];
|
||||
}
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return v620_disassembler::dasm_004xxx(stream, inst, pc, opcodes);
|
||||
}
|
||||
|
||||
offs_t v620_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if ((inst & 0177700) == 006400)
|
||||
{
|
||||
// Bit test (620/f)
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%s%-6c", "BT", BIT(dest, 15) ? '*' : ' ');
|
||||
format_number(stream, BIT(inst, 0, 6));
|
||||
stream << ',';
|
||||
format_address(stream, dest & 077777);
|
||||
return 2 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else if (inst == 006505 || inst == 006506)
|
||||
{
|
||||
// Jump and set return in index (620/f)
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%s%-5c", "JSR", BIT(dest, 15) ? '*' : ' ');
|
||||
format_address(stream, dest & 077777);
|
||||
stream << s_index_tags[inst - 006505];
|
||||
return 2 | STEP_OVER | SUPPORTED;
|
||||
}
|
||||
else if ((inst & 0177704) == 006604)
|
||||
{
|
||||
// Skip on register equal (620/f)
|
||||
u8 mode = BIT(inst, 0, 3);
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%s%-5c", "SRE", BIT(addr, 15) ? '*' : ' ');
|
||||
if (mode == 5 || mode == 6)
|
||||
{
|
||||
format_number(stream, addr & 077777);
|
||||
stream << s_index_tags[mode - 5];
|
||||
}
|
||||
else
|
||||
format_address(stream, (mode == 4 ? pc + 1 + addr : addr) & 077777);
|
||||
stream << ',';
|
||||
format_number(stream, inst & 000070);
|
||||
return 2 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else if ((inst & 0177774) == 006704)
|
||||
{
|
||||
// Indexed jump (620/f)
|
||||
u8 mode = BIT(inst, 0, 3);
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%s%-4c", "IJMP", BIT(dest, 15) ? '*' : ' ');
|
||||
if (mode == 5 || mode == 6)
|
||||
{
|
||||
format_number(stream, dest & 077777);
|
||||
stream << s_index_tags[mode - 5];
|
||||
}
|
||||
else
|
||||
format_address(stream, (mode == 4 ? pc + 1 + dest : dest) & 077777);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inst == 007400)
|
||||
stream << "ROF";
|
||||
else if (inst == 007401)
|
||||
stream << "SOF";
|
||||
else if (inst == 007402)
|
||||
stream << "TSA"; // switches to A (620/f)
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "DATA");
|
||||
format_number(stream, inst);
|
||||
}
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
offs_t v75_disassembler::dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const v75_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if (inst >= 007500)
|
||||
{
|
||||
// Register-to-register instructions
|
||||
util::stream_format(stream, "%s,%s,%s", s_rr_ops[BIT(inst, 6, 2) - 1], s_reg_names[BIT(inst, 3, 3)], s_reg_names[BIT(inst, 0, 3)]);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 007460)
|
||||
{
|
||||
// Byte instructions (register is always R0, i.e. A)
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-8s", util::string_format("%cBT%c", BIT(inst, 3) ? 'S' : 'L', BIT(addr, 15) ? '*' : ' '));
|
||||
if (BIT(inst, 0, 3) == 0)
|
||||
format_address(stream, addr & 077777);
|
||||
else
|
||||
{
|
||||
format_number(stream, addr & 077777);
|
||||
stream << ',' << s_reg_names[BIT(inst, 0, 3)];
|
||||
}
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 007440)
|
||||
{
|
||||
// Immediate instructions
|
||||
util::stream_format(stream, "%-8s", util::string_format("%sI,%s", BIT(inst, 3) ? "AD" : "LD", s_reg_names[BIT(inst, 0, 3)]));
|
||||
format_number(stream, opcodes.r16(pc + 1));
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 007410)
|
||||
{
|
||||
// Single-register instructions
|
||||
util::stream_format(stream, "%s,%s", s_single_reg_ops[BIT(inst, 3, 2) - 1], s_reg_names[BIT(inst, 0, 3)]);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else if ((inst & 0177400) == 007000)
|
||||
{
|
||||
// Register-to-memory instructions
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-8s", util::string_format("%s%s,%s", s_reg_mem_ops[BIT(inst, 6, 2)], BIT(addr, 15) ? "*" : "", s_reg_names[BIT(inst, 3, 3)]));
|
||||
if (BIT(inst, 0, 3) == 0)
|
||||
format_address(stream, addr & 077777);
|
||||
else
|
||||
{
|
||||
format_number(stream, addr & 077777);
|
||||
stream << ',' << s_reg_names[BIT(inst, 0, 3)];
|
||||
}
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 06720 && inst < 07000)
|
||||
{
|
||||
// Jump-if instructions
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%-8s", util::string_format("%s%s,%s", s_reg_jumps[BIT(inst, 3, 3) - 2], BIT(dest, 15) ? "*" : "", s_reg_names[BIT(inst, 0, 3)]));
|
||||
format_address(stream, dest & 077777);
|
||||
return 2 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return v620_disassembler::dasm_misc(stream, inst, pc, opcodes);
|
||||
}
|
||||
|
||||
offs_t v620_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if (inst < 0101000)
|
||||
{
|
||||
// External control
|
||||
util::stream_format(stream, "%-8s", "EXC");
|
||||
format_number(stream, BIT(inst, 0, 9));
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else if (inst < 0102000)
|
||||
{
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%s%-5s", "SEN", BIT(dest, 15) ? '*' : ' ');
|
||||
format_number(stream, BIT(inst, 0, 9));
|
||||
stream << ',';
|
||||
format_address(stream, dest & 077777);
|
||||
return 2 | STEP_COND | SUPPORTED;
|
||||
}
|
||||
else if (inst < 0103400 && BIT(inst, 9, 4) != 4)
|
||||
{
|
||||
util::stream_format(stream, "%-8s", s_in_out_ops[BIT(inst, 9, 4)]);
|
||||
format_number(stream, BIT(inst, 0, 6));
|
||||
if (BIT(inst, 9, 3) == 0)
|
||||
{
|
||||
stream << ',';
|
||||
format_address(stream, opcodes.r16(pc + 1) & 077777);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "DATA");
|
||||
format_number(stream, inst);
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
offs_t v75_disassembler::dasm_io(std::ostream &stream, u16 inst, offs_t pc, const v620_disassembler::data_buffer &opcodes) const
|
||||
{
|
||||
if ((inst & 0177000) == 0104000)
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "EXC2");
|
||||
format_number(stream, BIT(inst, 0, 9));
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
|
||||
if ((inst & 0177400) == 0105400)
|
||||
{
|
||||
// Floating point processor option
|
||||
auto lookup = s_fpp_map.find(BIT(inst, 0, 8));
|
||||
if (lookup != s_fpp_map.end())
|
||||
{
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
if (BIT(addr, 15))
|
||||
util::stream_format(stream, "%-8s", std::string(lookup->second) + "*");
|
||||
else
|
||||
util::stream_format(stream, "%-8s", lookup->second);
|
||||
format_address(stream, addr & 077777);
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return v620_disassembler::dasm_io(stream, inst, pc, opcodes);
|
||||
}
|
||||
|
||||
offs_t v620_disassembler::disassemble(std::ostream &stream, offs_t pc, const v620_disassembler::data_buffer &opcodes, const v620_disassembler::data_buffer ¶ms)
|
||||
{
|
||||
u16 inst = opcodes.r16(pc);
|
||||
if (BIT(inst, 12, 3) != 0)
|
||||
{
|
||||
// Single-word addressing instructions
|
||||
u8 mode = BIT(inst, 9, 3);
|
||||
util::stream_format(stream, "%s%-5c", s_alu_ops[BIT(inst, 12, 4)], mode == 7 ? '*' : ' ');
|
||||
switch (mode)
|
||||
{
|
||||
case 0: case 1: case 2: case 3:
|
||||
format_address(stream, BIT(inst, 0, 11));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
format_address(stream, (pc + 1 + BIT(inst, 0, 9)) & 077777);
|
||||
break;
|
||||
|
||||
case 5: case 6:
|
||||
format_number(stream, BIT(inst, 0, 9));
|
||||
stream << s_index_tags[mode - 5];
|
||||
break;
|
||||
|
||||
case 7:
|
||||
format_address(stream, BIT(inst, 0, 9));
|
||||
break;
|
||||
}
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 0100000)
|
||||
return dasm_io(stream, inst, pc, opcodes);
|
||||
else if (inst >= 006000)
|
||||
{
|
||||
if (inst < (BIT(inst, 2) ? 006400 : 006200) && BIT(inst, 3, 3) != 0)
|
||||
{
|
||||
// Extended-addressing instruction group
|
||||
if (BIT(inst, 2))
|
||||
{
|
||||
u8 mode = BIT(inst, 0, 3);
|
||||
u16 addr = opcodes.r16(pc + 1);
|
||||
util::stream_format(stream, "%sE%-4c", s_alu_ops[BIT(inst, 3, 4)], BIT(addr, 15) ? '*' : ' ');
|
||||
if (mode == 5 || mode == 6)
|
||||
{
|
||||
format_number(stream, addr & 077777);
|
||||
stream << s_index_tags[mode - 5];
|
||||
}
|
||||
else
|
||||
format_address(stream, (mode == 4 ? pc + 1 + addr : addr) & 077777);
|
||||
if (BIT(inst, 7))
|
||||
{
|
||||
// Postindexing (620/f)
|
||||
stream << ',';
|
||||
format_number(stream, 0200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%s%-5c", s_alu_ops[BIT(inst, 3, 4)], 'I');
|
||||
format_number(stream, opcodes.r16(pc + 1));
|
||||
}
|
||||
return 2 | SUPPORTED;
|
||||
}
|
||||
else
|
||||
return dasm_misc(stream, inst, pc, opcodes);
|
||||
}
|
||||
else if (inst >= 005000)
|
||||
{
|
||||
// Register change group
|
||||
if (BIT(inst, 6))
|
||||
{
|
||||
// Increment or decrement
|
||||
switch (inst & 000477)
|
||||
{
|
||||
case 011:
|
||||
util::stream_format(stream, "%cAR", BIT(inst, 7) ? 'D' : 'I');
|
||||
break;
|
||||
|
||||
case 022:
|
||||
util::stream_format(stream, "%cBR", BIT(inst, 7) ? 'D' : 'I');
|
||||
break;
|
||||
|
||||
case 044:
|
||||
util::stream_format(stream, "%cXR", BIT(inst, 7) ? 'D' : 'I');
|
||||
break;
|
||||
|
||||
case 0411:
|
||||
util::stream_format(stream, "%cOFA", BIT(inst, 7) ? 'S' : 'A');
|
||||
break;
|
||||
|
||||
case 0422:
|
||||
util::stream_format(stream, "%cOFB", BIT(inst, 7) ? 'S' : 'A');
|
||||
break;
|
||||
|
||||
case 0444:
|
||||
util::stream_format(stream, "%cOFX", BIT(inst, 7) ? 'S' : 'A');
|
||||
break;
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "%-8s", BIT(inst, 7) ? "DECR" : "INCR");
|
||||
format_number(stream, inst & 000477);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transfer true or complement
|
||||
switch (inst & 000677)
|
||||
{
|
||||
case 000:
|
||||
stream << "NOP";
|
||||
break;
|
||||
|
||||
case 001:
|
||||
stream << "TZA";
|
||||
break;
|
||||
|
||||
case 002:
|
||||
stream << "TZB";
|
||||
break;
|
||||
|
||||
case 004:
|
||||
stream << "TZX";
|
||||
break;
|
||||
|
||||
case 012:
|
||||
stream << "TAB";
|
||||
break;
|
||||
|
||||
case 014:
|
||||
stream << "TAX";
|
||||
break;
|
||||
|
||||
case 021:
|
||||
stream << "TBA";
|
||||
break;
|
||||
|
||||
case 024:
|
||||
stream << "TBX";
|
||||
break;
|
||||
|
||||
case 041:
|
||||
stream << "TXA";
|
||||
break;
|
||||
|
||||
case 042:
|
||||
stream << "TXB";
|
||||
break;
|
||||
|
||||
case 0211:
|
||||
stream << "CPA";
|
||||
break;
|
||||
|
||||
case 0222:
|
||||
stream << "CPB";
|
||||
break;
|
||||
|
||||
case 0244:
|
||||
stream << "CPX";
|
||||
break;
|
||||
|
||||
default:
|
||||
util::stream_format(stream, "%-8s", BIT(inst, 7) ? "COMP" : BIT(inst, 3, 3) == 0 ? "ZERO" : "MERG");
|
||||
format_number(stream, inst & 000477);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
else if (inst >= 004000)
|
||||
return dasm_004xxx(stream, inst, pc, opcodes);
|
||||
else if (inst >= 001000 && inst < 004000)
|
||||
{
|
||||
// Jump and execute instructions
|
||||
u16 dest = opcodes.r16(pc + 1);
|
||||
u16 cond = BIT(inst, 0, 9);
|
||||
auto lookup = s_cond_map.find(cond);
|
||||
if (lookup != s_cond_map.end())
|
||||
{
|
||||
if (BIT(dest, 15))
|
||||
util::stream_format(stream, "%-8s", std::string(lookup->second[BIT(inst, 9, 2) - 1]) + "*");
|
||||
else
|
||||
util::stream_format(stream, "%-8s", lookup->second[BIT(inst, 9, 2) - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = util::string_format("%cIF", inst < 03000 ? 'J' : 'X');
|
||||
if (!BIT(inst, 9))
|
||||
name += 'M';
|
||||
if (BIT(dest, 15))
|
||||
name += '*';
|
||||
util::stream_format(stream, "%-8s", name);
|
||||
format_number(stream, cond);
|
||||
stream << ',';
|
||||
}
|
||||
format_address(stream, dest & 077777);
|
||||
if (inst == 001000 && BIT(dest, 15))
|
||||
return 2 | STEP_OUT | SUPPORTED;
|
||||
else
|
||||
return 2 | (BIT(inst, 10) ? STEP_OVER : 0) | (cond != 0 ? STEP_COND : 0) | SUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inst == 0)
|
||||
stream << "HLT";
|
||||
else
|
||||
{
|
||||
util::stream_format(stream, "%-8s", "DATA");
|
||||
format_number(stream, inst);
|
||||
}
|
||||
return 1 | SUPPORTED;
|
||||
}
|
||||
}
|
41
src/devices/cpu/v620/v620dasm.h
Normal file
41
src/devices/cpu/v620/v620dasm.h
Normal file
@ -0,0 +1,41 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
|
||||
#ifndef MAME_CPU_V620_V620_H
|
||||
#define MAME_CPU_V620_V620_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class v620_disassembler : public util::disasm_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
v620_disassembler();
|
||||
|
||||
protected:
|
||||
// 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;
|
||||
|
||||
virtual offs_t dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
|
||||
virtual offs_t dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
|
||||
virtual offs_t dasm_io(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const;
|
||||
|
||||
// internal helpers
|
||||
void format_number(std::ostream &stream, u16 n) const;
|
||||
void format_address(std::ostream &stream, u16 addr) const;
|
||||
};
|
||||
|
||||
class v75_disassembler : public v620_disassembler
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
v75_disassembler();
|
||||
|
||||
protected:
|
||||
virtual offs_t dasm_004xxx(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
|
||||
virtual offs_t dasm_misc(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
|
||||
virtual offs_t dasm_io(std::ostream &stream, u16 inst, offs_t pc, const data_buffer &opcodes) const override;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_V620_V620_H
|
@ -66,6 +66,7 @@ using util::BIT;
|
||||
#include "cpu/hcd62121/hcd62121d.h"
|
||||
#include "cpu/hd61700/hd61700d.h"
|
||||
#include "cpu/hmcs40/hmcs40d.h"
|
||||
#include "cpu/hp2100/hp2100d.h"
|
||||
#include "cpu/hpc/hpcdasm.h"
|
||||
#include "cpu/hphybrid/hphybrid_dasm.h"
|
||||
#include "cpu/i386/i386dasm.h"
|
||||
@ -186,6 +187,7 @@ using util::BIT;
|
||||
#include "cpu/upd78k/upd78k3d.h"
|
||||
#include "cpu/upd78k/upd78k4d.h"
|
||||
#include "cpu/v60/v60d.h"
|
||||
#include "cpu/v620/v620dasm.h"
|
||||
#include "cpu/v810/v810dasm.h"
|
||||
#include "cpu/v850/v850dasm.h"
|
||||
#include "cpu/vax/vaxdasm.h"
|
||||
@ -448,6 +450,8 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "hd6309", be, 0, []() -> util::disasm_interface * { return new hd6309_disassembler; } },
|
||||
{ "hd63701", be, 0, []() -> util::disasm_interface * { return new m680x_disassembler(63701); } },
|
||||
{ "hmcs40", le, -1, []() -> util::disasm_interface * { return new hmcs40_disassembler; } },
|
||||
{ "hp2100", be, -1, []() -> util::disasm_interface * { return new hp2100_disassembler; } },
|
||||
{ "hp21mx", be, -1, []() -> util::disasm_interface * { return new hp21mx_disassembler; } },
|
||||
{ "hp_5061_3001", be, -1, []() -> util::disasm_interface * { return new hp_5061_3001_disassembler; } },
|
||||
{ "hp_5061_3011", be, -1, []() -> util::disasm_interface * { return new hp_5061_3011_disassembler; } },
|
||||
{ "hp_09825_67907", be, -1, []() -> util::disasm_interface * { return new hp_09825_67907_disassembler; } },
|
||||
@ -655,6 +659,8 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "upd78k0kx2", le, 0, []() -> util::disasm_interface * { return new upd78k0kx2_disassembler; } },
|
||||
{ "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true, false); } },
|
||||
{ "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } },
|
||||
{ "v620", be, -1, []() -> util::disasm_interface * { return new v620_disassembler; } },
|
||||
{ "v75", be, -1, []() -> util::disasm_interface * { return new v75_disassembler; } },
|
||||
{ "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } },
|
||||
{ "v850", le, 0, []() -> util::disasm_interface * { return new v850_disassembler; } },
|
||||
{ "v850es", le, 0, []() -> util::disasm_interface * { return new v850es_disassembler; } },
|
||||
|
Loading…
Reference in New Issue
Block a user