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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
// license:BSD-3-Clause
// copyright-holders:AJR
/***************************************************************************
Gigatron disassembler
***************************************************************************/
#include "emu.h"
#include "gigatrondasm.h"
gigatron_disassembler::gigatron_disassembler()
: util::disasm_interface()
{
}
const char *const gigatron_disassembler::s_ops[7] = {
"ld",
"anda",
"ora",
"xora",
"adda",
"suba",
"st"
};
const char *const gigatron_disassembler::s_jumps[8] = {
"jmp",
"bgt",
"blt",
"bne",
"beq",
"bge",
"ble",
"bra"
};
u32 gigatron_disassembler::opcode_alignment() const
{
return 1;
}
offs_t gigatron_disassembler::disassemble(std::ostream &stream, offs_t pc, const gigatron_disassembler::data_buffer &opcodes, const gigatron_disassembler::data_buffer ¶ms)
{
u16 inst = opcodes.r16(pc);
u32 flags = 0;
if (inst >= 0xe000)
{
// Jump instructions use special format
util::stream_format(stream, "%-5s", s_jumps[(inst & 0x1c00) >> 10]);
if ((inst & 0x1c00) == 0)
stream << "y,";
switch (inst & 0x0300)
{
case 0x0000:
if ((inst & 0x1c00) == 0)
util::stream_format(stream, "$%02x", inst & 0x00ff);
else
util::stream_format(stream, "$%04x", ((pc + 1) & 0x3f00) | (inst & 0x00ff));
break;
case 0x0100:
util::stream_format(stream, "[$%02x]", inst & 0x00ff);
break;
case 0x0200:
stream << "ac";
break;
case 0x0300:
stream << "in";
break;
}
flags = STEP_OVER | step_over_extra(1);
}
else if ((inst & 0xf300) == 0x0200)
stream << "nop";
else
{
if ((inst & 0xe300) == 0xc100)
{
// This was originally an undefined store mode
util::stream_format(stream, "%-5s", "ctrl");
}
else
{
util::stream_format(stream, "%-5s", s_ops[(inst & 0xe000) >> 13]);
// Bus data
switch (inst & 0x0300)
{
case 0x0000:
util::stream_format(stream, "$%02x", inst & 0x00ff);
if (inst >= 0xc000)
stream << ",";
break;
case 0x0100:
break;
case 0x0200:
if (inst < 0xc000)
stream << "ac"; // implicit for store instruction
break;
case 0x0300:
stream << "in";
if (inst >= 0xc000)
stream << ",";
break;
}
}
// RAM source or store destination
if (inst >= 0xc000 || (inst & 0x0300) == 0x0100)
{
if ((inst & 0xe300) != 0xc100)
stream << "[";
switch (inst & 0x1c00)
{
case 0x0000: case 0x1000: case 0x1400: case 0x1800:
util::stream_format(stream, "$%02x", inst & 0x00ff);
break;
case 0x0400:
stream << "x";
break;
case 0x0800:
util::stream_format(stream, "y,$%02x", inst & 0x00ff);
break;
case 0x0c00:
stream << "y,x";
break;
case 0x1c00:
stream << "y,x++";
break;
}
if ((inst & 0xe300) != 0xc100)
stream << "]";
}
// Non-accumulator destinations
if (BIT(inst, 12))
{
if (!BIT(inst, 11))
util::stream_format(stream, ",%c", "xy"[BIT(inst, 10)]);
else if (inst < 0xc000)
stream << ",out";
}
}
return 1 | flags | SUPPORTED;
}
|