1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// license:BSD-3-Clause
// copyright-holders:F. Ulivi
// *******************************
// * HP nanoprocessor disassembler
// *******************************
#include "emu.h"
#include "nanoprocessor_dasm.h"
void hp_nanoprocessor_disassembler::param_bitno(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
stream << (char)('0' + (opcode & 7));
}
void hp_nanoprocessor_disassembler::param_ds(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
util::stream_format(stream, "DS%u", opcode & 0xf);
}
void hp_nanoprocessor_disassembler::param_reg(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
util::stream_format(stream, "R%u", opcode & 0xf);
}
void hp_nanoprocessor_disassembler::param_11bit(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
unsigned tmp = ((unsigned)(opcode & 7) << 8) | params.r8(pc);
util::stream_format(stream, "$%03x", tmp);
}
void hp_nanoprocessor_disassembler::param_page_no(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
stream << (char)('0' + (opcode & 7));
}
void hp_nanoprocessor_disassembler::param_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
util::stream_format(stream, "$%02x", params.r8(pc));
}
void hp_nanoprocessor_disassembler::param_ds_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
util::stream_format(stream, "DS%u,$%02x", opcode & 0xf, params.r8(pc));
}
void hp_nanoprocessor_disassembler::param_reg_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms)
{
util::stream_format(stream, "R%u,$%02x", opcode & 0xf, params.r8(pc));
}
const hp_nanoprocessor_disassembler::dis_entry_t hp_nanoprocessor_disassembler::dis_table[] = {
{0xff, 0x00, "INB", nullptr, 1},
{0xff, 0x01, "DEB", nullptr, 1},
{0xff, 0x02, "IND", nullptr, 1},
{0xff, 0x03, "DED", nullptr, 1},
{0xff, 0x04, "CLA", nullptr, 1},
{0xff, 0x05, "CMA", nullptr, 1},
{0xff, 0x06, "RSA", nullptr, 1},
{0xff, 0x07, "LSA", nullptr, 1},
{0xff, 0x08, "SGT", nullptr, 1},
{0xff, 0x09, "SLT", nullptr, 1},
{0xff, 0x0a, "SEQ", nullptr, 1},
{0xff, 0x0b, "SAZ", nullptr, 1},
{0xff, 0x0c, "SLE", nullptr, 1},
{0xff, 0x0d, "SGE", nullptr, 1},
{0xff, 0x0e, "SNE", nullptr, 1},
{0xff, 0x0f, "SAN", nullptr, 1},
{0xf8, 0x10, "SBS", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xff, 0x1f, "SES", nullptr, 1},
{0xf8, 0x18, "SFS", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xf8, 0x20, "SBN", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xff, 0x2f, "ENI", nullptr, 1},
{0xf8, 0x28, "STC", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xf8, 0x30, "SBZ", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xff, 0x3f, "SEZ", nullptr, 1},
{0xf8, 0x38, "SFZ", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xf0, 0x40, "INA", &hp_nanoprocessor_disassembler::param_ds, 1},
{0xff, 0x5f, "NOP", nullptr, 1},
{0xf0, 0x50, "OTA", &hp_nanoprocessor_disassembler::param_ds, 1},
{0xf0, 0x60, "LDA", &hp_nanoprocessor_disassembler::param_reg, 1},
{0xf0, 0x70, "STA", &hp_nanoprocessor_disassembler::param_reg, 1},
{0xf8, 0x80, "JMP", &hp_nanoprocessor_disassembler::param_11bit, 2},
{0xf8, 0x88, "JSB", &hp_nanoprocessor_disassembler::param_11bit, 2 | STEP_OVER},
{0xf8, 0x90, "JAI", &hp_nanoprocessor_disassembler::param_page_no, 1},
{0xf8, 0x98, "JAS", &hp_nanoprocessor_disassembler::param_page_no, 1 | STEP_OVER},
{0xf8, 0xa0, "CBN", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xff, 0xaf, "DSI", nullptr, 1},
{0xf8, 0xa8, "CLC", &hp_nanoprocessor_disassembler::param_bitno, 1},
{0xff, 0xb0, "RTI", nullptr, 1 | STEP_OUT},
{0xff, 0xb1, "RTE", nullptr, 1 | STEP_OUT},
{0xff, 0xb4, "STE", nullptr, 1},
{0xff, 0xb5, "CLE", nullptr, 1},
{0xff, 0xb8, "RTS", nullptr, 1 | STEP_OUT},
{0xff, 0xb9, "RSE", nullptr, 1 | STEP_OUT},
{0xff, 0xcf, "LDR", &hp_nanoprocessor_disassembler::param_byte, 2},
{0xf0, 0xc0, "OTR", &hp_nanoprocessor_disassembler::param_ds_byte, 2},
{0xf0, 0xd0, "STR", &hp_nanoprocessor_disassembler::param_reg_byte, 2},
{0xf0, 0xe0, "LDI", &hp_nanoprocessor_disassembler::param_reg, 1},
{0xf0, 0xf0, "STI", &hp_nanoprocessor_disassembler::param_reg, 1},
// Catchall for undefined opcodes
{0x00, 0x00, "???", nullptr, 1}
};
u32 hp_nanoprocessor_disassembler::opcode_alignment() const
{
return 1;
}
offs_t hp_nanoprocessor_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
{
const uint8_t opcode = opcodes.r8(pc);
for (const dis_entry_t& ent : dis_table) {
if ((opcode & ent.m_op_mask) == ent.m_opcode) {
stream << ent.m_mnemonic << ' ';
if (ent.m_param_fn != nullptr) {
(this->*ent.m_param_fn)(stream, opcode, pc+1, params);
}
return ent.m_dasm_flags | SUPPORTED;
}
}
// Should never ever happen
return 0;
}
|