1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont, Karl Stenerud
3 /*
4
5 Mitsubishi 7700 Series CPU disassembler v1.1
6
7 By R. Belmont
8 Based on G65C816 CPU Emulator by Karl Stenerud
9
10 */
11
12 #include "emu.h"
13 #include "m7700ds.h"
14
15 #define ADDRESS_24BIT(A) ((A)&0xffffff)
16
17 const char *const m7700_disassembler::s_opnames[] =
18 {
19 "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRA",
20 "BRK", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "COP", "CPX",
21 "CPY", "DEA", "DEC", "DEX", "DEY", "EOR", "INA", "INC", "INX", "INY", "JML",
22 "JMP", "JSL", "JSR", "LDA", "LDX", "LDY", "LSR", "MVN", "MVP", "NOP", "ORA",
23 "PEA", "PEI", "PER", "PHA", "PHT", "PHD", "PHK", "PHP", "PHX", "PHY", "PLA",
24 "PLT", "PLD", "PLP", "PLX", "PLY", "CLP", "ROL", "ROR", "RTI", "RTL", "RTS",
25 "SBC", "SEC", "SED", "SEI", "SEP", "STA", "STP", "STX", "STY", "STZ", "TAX",
26 "TAY", "TCS", "TCD", "TDC", "TRB", "TSB", "TSC", "TSX", "TXA", "TXS", "TXY",
27 "TYA", "TYX", "WAI", "WDM", "XBA", "XCE", "MPY", "DIV", "MPYS","DIVS","RLA",
28 "EXTS","EXTZ","LDT", "LDM", "UNK", "SEB", "SEM", "CLM", "STB", "LDB", "ADCB",
29 "SBCB","EORB","TBX", "CMPB","INB", "DEB", "TXB", "TYB", "LSRB","ORB", "CLB",
30 "BBC", "BBS", "TBY", "ANDB","PUL", "PSH", "PLB", "XAB", "PHB",
31 };
32
33 const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes[256] =
34 {
35 {op::BRK, I, SIG }, {op::ORA, M, DXI }, {op::UNK, I, SIG }, {op::ORA, M, S },
36 {op::SEB, M, LDM4 }, {op::ORA, M, D }, {op::ASL, M, D }, {op::ORA, M, DLI },
37 {op::PHP, I, IMP }, {op::ORA, M, IMM }, {op::ASL, M, ACC }, {op::PHD, I, IMP },
38 {op::SEB, M, LDM5 }, {op::ORA, M, A }, {op::ASL, M, A }, {op::ORA, M, AL },
39 // 0x10
40 {op::BPL, I, RELB }, {op::ORA, M, DIY }, {op::ORA, M, DI }, {op::ORA, M, SIY },
41 {op::CLB, M, LDM4 }, {op::ORA, M, DX }, {op::ASL, M, DX }, {op::ORA, M, DLIY },
42 {op::CLC, I, IMP }, {op::ORA, M, AY }, {op::DEA, I, IMP }, {op::TCS, I, IMP },
43 {op::CLB, M, LDM5 }, {op::ORA, M, AX }, {op::ASL, M, AX }, {op::ORA, M, ALX },
44 // 0x20
45 {op::JSR, I, A }, {op::AND, M, DXI }, {op::JSL, I, AL }, {op::AND, M, S },
46 {op::BBS, M, BBCD }, {op::AND, M, D }, {op::ROL, M, D }, {op::AND, M, DLI },
47 {op::PLP, I, IMP }, {op::AND, M, IMM }, {op::ROL, M, ACC }, {op::PLD, I, IMP },
48 {op::BBS, M, BBCA }, {op::AND, M, A }, {op::ROL, M, A }, {op::AND, M, AL },
49 // 0x30
50 {op::BMI, I, RELB }, {op::AND, M, DIY }, {op::AND, M, DI }, {op::AND, M, SIY },
51 {op::BBC, M, BBCD }, {op::AND, M, DX }, {op::ROL, M, DX }, {op::AND, M, DLIY },
52 {op::SEC, I, IMP }, {op::AND, M, AY }, {op::INA, I, IMP }, {op::TSC, I, IMP },
53 {op::BBC, M, BBCA }, {op::AND, M, AX }, {op::ROL, M, AX }, {op::AND, M, ALX },
54 // 0x40
55 {op::RTI, I, IMP }, {op::EOR, M, DXI }, {op::WDM, I, IMP }, {op::EOR, M, S },
56 {op::MVP, I, MVP }, {op::EOR, M, D }, {op::LSR, M, D }, {op::EOR, M, DLI },
57 {op::PHA, I, IMP }, {op::EOR, M, IMM }, {op::LSR, M, ACC }, {op::PHK, I, IMP },
58 {op::JMP, I, A }, {op::EOR, M, A }, {op::LSR, M, A }, {op::EOR, M, AL },
59 // 0x50
60 {op::BVC, I, RELB }, {op::EOR, M, DIY }, {op::EOR, M, DI }, {op::EOR, M, SIY },
61 {op::MVN, I, MVN }, {op::EOR, M, DX }, {op::LSR, M, DX }, {op::EOR, M, DLIY },
62 {op::CLI, I, IMP }, {op::EOR, M, AY }, {op::PHY, I, IMP }, {op::TCD, I, IMP },
63 {op::JMP, I, AL }, {op::EOR, M, AX }, {op::LSR, M, AX }, {op::EOR, M, ALX },
64 // 0x60
65 {op::RTS, I, IMP }, {op::ADC, M, DXI }, {op::PER, I, PER }, {op::ADC, M, S },
66 {op::LDM, M, LDM4 }, {op::ADC, M, D }, {op::ROR, M, D }, {op::ADC, M, DLI },
67 {op::PLA, I, IMP }, {op::ADC, M, IMM }, {op::ROR, M, ACC }, {op::RTL, I, IMP },
68 {op::JMP, I, AI }, {op::ADC, M, A }, {op::ROR, M, A }, {op::ADC, M, AL },
69 // 0x70
70 {op::BVS, I, RELB }, {op::ADC, M, DIY }, {op::ADC, M, DI }, {op::ADC, M, SIY },
71 {op::LDM, M, LDM4X}, {op::ADC, M, DX }, {op::ROR, M, DX }, {op::ADC, M, DLIY },
72 {op::SEI, I, IMP }, {op::ADC, M, AY }, {op::PLY, I, IMP }, {op::TDC, I, IMP },
73 {op::JMP, I, AXI }, {op::ADC, M, AX }, {op::ROR, M, AX }, {op::ADC, M, ALX },
74 // 0x80
75 {op::BRA, I, RELB }, {op::STA, M, DXI }, {op::BRL, I, RELW}, {op::STA, M, S },
76 {op::STY, X, D }, {op::STA, M, D }, {op::STX, X, D }, {op::STA, M, DLI },
77 {op::DEY, I, IMP }, {op::BIT, M, IMM }, {op::TXA, I, IMP }, {op::PHT, I, IMP },
78 {op::STY, X, A }, {op::STA, M, A }, {op::STX, X, A }, {op::STA, M, AL },
79 // 0x90
80 {op::BCC, I, RELB }, {op::STA, M, DIY }, {op::STA, M, DI }, {op::STA, M, SIY },
81 {op::STY, X, DX }, {op::STA, M, DX }, {op::STX, X, DY }, {op::STA, M, DLIY },
82 {op::TYA, I, IMP }, {op::STA, M, AY }, {op::TXS, I, IMP }, {op::TXY, I, IMP },
83 {op::LDM, M, LDM5 }, {op::STA, M, AX }, {op::LDM, M, LDM5X},{op::STA, M, ALX },
84 // 0xA0
85 {op::LDY, X, IMM }, {op::LDA, M, DXI }, {op::LDX, X, IMM }, {op::LDA, M, S },
86 {op::LDY, X, D }, {op::LDA, M, D }, {op::LDX, X, D }, {op::LDA, M, DLI },
87 {op::TAY, I, IMP }, {op::LDA, M, IMM }, {op::TAX, I, IMP }, {op::PLB, I, IMP },
88 {op::LDY, X, A }, {op::LDA, M, A }, {op::LDX, X, A }, {op::LDA, M, AL },
89 // 0xB0
90 {op::BCS, I, RELB }, {op::LDA, M, DIY }, {op::LDA, M, DI }, {op::LDA, M, SIY },
91 {op::LDY, X, DX }, {op::LDA, M, DX }, {op::LDX, X, DY }, {op::LDA, M, DLIY },
92 {op::CLV, I, IMP }, {op::LDA, M, AY }, {op::TSX, I, IMP }, {op::TYX, I, IMP },
93 {op::LDY, X, AX }, {op::LDA, M, AX }, {op::LDX, X, AY }, {op::LDA, M, ALX },
94 // 0xC0
95 {op::CPY, X, IMM }, {op::CMP, M, DXI }, {op::CLP, I, IMM }, {op::CMP, M, S },
96 {op::CPY, X, D }, {op::CMP, M, D }, {op::DEC, M, D }, {op::CMP, M, DLI },
97 {op::INY, I, IMP }, {op::CMP, M, IMM }, {op::DEX, I, IMP }, {op::WAI, I, IMP },
98 {op::CPY, X, A }, {op::CMP, M, A }, {op::DEC, M, A }, {op::CMP, M, AL },
99 // 0xD0
100 {op::BNE, I, RELB }, {op::CMP, M, DIY }, {op::CMP, M, DI }, {op::CMP, M, SIY },
101 {op::PEI, I, PEI }, {op::CMP, M, DX }, {op::DEC, M, DX }, {op::CMP, M, DLIY },
102 {op::CLM, I, IMP }, {op::CMP, M, AY }, {op::PHX, I, IMP }, {op::STP, I, IMP },
103 {op::JML, I, AI }, {op::CMP, M, AX }, {op::DEC, M, AX }, {op::CMP, M, ALX },
104 // 0xE0
105 {op::CPX, X, IMM }, {op::SBC, M, DXI }, {op::SEP, I, IMM }, {op::SBC, M, S },
106 {op::CPX, X, D }, {op::SBC, M, D }, {op::INC, M, D }, {op::SBC, M, DLI },
107 {op::INX, M, IMP }, {op::SBC, M, IMM }, {op::NOP, I, IMP }, {op::PSH, I, IMM },
108 {op::CPX, X, A }, {op::SBC, M, A }, {op::INC, M, A }, {op::SBC, M, AL },
109 // 0xF0
110 {op::BEQ, I, RELB }, {op::SBC, M, DIY }, {op::SBC, M, DI }, {op::SBC, M, SIY },
111 {op::PEA, I, PEA }, {op::SBC, M, DX }, {op::INC, M, DX }, {op::SBC, M, DLIY },
112 {op::SEM, I, IMP }, {op::SBC, M, AY }, {op::PLX, I, IMP }, {op::PUL, I, IMM },
113 {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX }
114 };
115
116 const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix42[256] =
117 {
118 {op::BRK, I, SIG }, {op::ORB, M, DXI }, {op::COP, I, SIG }, {op::ORB, M, S },
119 {op::TSB, M, D }, {op::ORB, M, D }, {op::ASL, M, D }, {op::ORB, M, DLI },
120 {op::PHP, I, IMP }, {op::ORB, M, IMM }, {op::ASL, M, ACCB}, {op::PHD, I, IMP },
121 {op::TSB, M, A }, {op::ORB, M, A }, {op::ASL, M, A }, {op::ORB, M, AL },
122 // 0x10
123 {op::BPL, I, RELB }, {op::ORB, M, DIY }, {op::ORB, M, DI }, {op::ORB, M, SIY },
124 {op::TRB, M, D }, {op::ORB, M, DX }, {op::ASL, M, DX }, {op::ORB, M, DLIY},
125 {op::CLC, I, IMP }, {op::ORB, M, AY }, {op::DEB, I, IMP }, {op::TCS, I, IMP },
126 {op::TRB, M, A }, {op::ORB, M, AX }, {op::ASL, M, AX }, {op::ORB, M, ALX },
127 // 0x20
128 {op::JSR, I, A }, {op::ANDB,M, DXI }, {op::JSL, I, AL }, {op::ANDB, M, S },
129 {op::BIT, M, D }, {op::ANDB,M, D }, {op::ROL, M, D }, {op::ANDB, M, DLI },
130 {op::PLP, I, IMP }, {op::ANDB,M, IMM }, {op::ROL, M, ACCB}, {op::PLD, I, IMP },
131 {op::BIT, M, A }, {op::ANDB,M, A }, {op::ROL, M, A }, {op::ANDB, M, AL },
132 // 0x30
133 {op::BMI, I, RELB }, {op::AND, M, DIY }, {op::AND, M, DI }, {op::AND, M, SIY },
134 {op::BIT, M, DX }, {op::AND, M, DX }, {op::ROL, M, DX }, {op::AND, M, DLIY},
135 {op::SEC, I, IMP }, {op::AND, M, AY }, {op::INB, I, IMP }, {op::TSC, I, IMP },
136 {op::BIT, M, AX }, {op::AND, M, AX }, {op::ROL, M, AX }, {op::AND, M, ALX },
137 // 0x40
138 {op::RTI, I, IMP }, {op::EORB,M, DXI }, {op::WDM, I, IMP }, {op::EORB, M, S },
139 {op::MVP, I, MVP }, {op::EORB,M, D }, {op::LSRB,M, D }, {op::EORB, M, DLI },
140 {op::PHB, I, IMP }, {op::EORB,M, IMM }, {op::LSRB,M, ACC }, {op::PHK, I, IMP },
141 {op::JMP, I, A }, {op::EORB,M, A }, {op::LSRB,M, A }, {op::EORB, M, AL },
142 // 0x50
143 {op::BVC, I, RELB }, {op::EORB,M, DIY }, {op::EORB,M, DI }, {op::EORB, M, SIY },
144 {op::MVN, I, MVN }, {op::EORB,M, DX }, {op::LSRB,M, DX }, {op::EORB, M, DLIY},
145 {op::CLI, I, IMP }, {op::EORB,M, AY }, {op::PHY, I, IMP }, {op::TCD, I, IMP },
146 {op::JMP, I, AL }, {op::EORB,M, AX }, {op::LSRB,M, AX }, {op::EORB, M, ALX },
147 // 0x60
148 {op::RTS, I, IMP }, {op::ADCB,M, DXI }, {op::PER, I, PER }, {op::ADCB, M, S },
149 {op::STZ, M, D }, {op::ADCB,M, D }, {op::ROR, M, D }, {op::ADCB, M, DLI },
150 {op::PLAB,I, IMP }, {op::ADCB,M, IMM }, {op::ROR, M, ACC }, {op::RTL, I, IMP },
151 {op::JMP, I, AI }, {op::ADCB,M, A }, {op::ROR, M, A }, {op::ADCB, M, AL },
152 // 0x70
153 {op::BVS, I, RELB }, {op::ADCB,M, DIY }, {op::ADCB,M, DI }, {op::ADCB, M, SIY },
154 {op::STZ, M, DX }, {op::ADCB,M, DX }, {op::ROR, M, DX }, {op::ADCB, M, DLIY},
155 {op::SEI, I, IMP }, {op::ADCB,M, AY }, {op::PLY, I, IMP }, {op::TDC, I, IMP },
156 {op::JMP, I, AXI }, {op::ADCB,M, AX }, {op::ROR, M, AX }, {op::ADCB, M, ALX },
157 // 0x80
158 {op::BRA, I, RELB }, {op::STB, M, DXI }, {op::BRL, I, RELW}, {op::STB, M, S },
159 {op::STY, X, D }, {op::STB, M, D }, {op::STX, X, D }, {op::STB, M, DLI },
160 {op::DEY, I, IMP }, {op::BIT, M, IMM }, {op::TXB, I, IMP }, {op::PHB, I, IMP },
161 {op::STY, X, A }, {op::STB, M, A }, {op::STX, X, A }, {op::STB, M, AL },
162 // 0x90
163 {op::BCC, I, RELB }, {op::STB, M, DIY }, {op::STB, M, DI }, {op::STB, M, SIY },
164 {op::STY, X, DX }, {op::STB, M, DX }, {op::STX, X, DY }, {op::STB, M, DLIY},
165 {op::TYB, I, IMP }, {op::STB, M, AY }, {op::TXS, I, IMP }, {op::TXY, I, IMP },
166 {op::STZ, M, A }, {op::STB, M, AX }, {op::STZ, M, AX }, {op::STB, M, ALX },
167 // 0xA0
168 {op::LDY, X, IMM }, {op::LDB, M, DXI }, {op::LDX, X, IMM }, {op::LDB, M, S },
169 {op::LDY, X, D }, {op::LDB, M, D }, {op::LDX, X, D }, {op::LDB, M, DLI },
170 {op::TBY, I, IMP }, {op::LDB, M, IMM }, {op::TBX, I, IMP }, {op::PLB, I, IMP },
171 {op::LDY, X, A }, {op::LDB, M, A }, {op::LDX, X, A }, {op::LDB, M, AL },
172 // 0xB0
173 {op::BCS, I, RELB }, {op::LDB, M, DIY }, {op::LDB, M, DI }, {op::LDB, M, SIY },
174 {op::LDY, X, DX }, {op::LDB, M, DX }, {op::LDX, X, DY }, {op::LDB, M, DLIY},
175 {op::CLV, I, IMP }, {op::LDB, M, AY }, {op::TSX, I, IMP }, {op::TYX, I, IMP },
176 {op::LDY, X, AX }, {op::LDB, M, AX }, {op::LDX, X, AY }, {op::LDB, M, ALX },
177 // 0xC0
178 {op::CPY, X, IMM }, {op::CMPB,M, DXI }, {op::CLP, I, IMM }, {op::CMPB, M, S },
179 {op::CPY, X, D }, {op::CMPB,M, D }, {op::DEC, M, D }, {op::CMPB, M, DLI },
180 {op::INY, I, IMP }, {op::CMPB,M, IMM }, {op::DEX, I, IMP }, {op::WAI, I, IMP },
181 {op::CPY, X, A }, {op::CMPB,M, A }, {op::DEC, M, A }, {op::CMPB, M, AL },
182 // 0xD0
183 {op::BNE, I, RELB }, {op::CMPB,M, DIY }, {op::CMPB,M, DI }, {op::CMPB, M, SIY },
184 {op::PEI, I, PEI }, {op::CMPB,M, DX }, {op::DEC, M, DX }, {op::CMPB, M, DLIY},
185 {op::CLD, I, IMP }, {op::CMPB,M, AY }, {op::PHX, I, IMP }, {op::STP, I, IMP },
186 {op::JML, I, AI }, {op::CMPB,M, AX }, {op::DEC, M, AX }, {op::CMPB, M, ALX },
187 // 0xE0
188 {op::CPX, X, IMM }, {op::SBCB,M, DXI }, {op::SEP, I, IMM }, {op::SBCB, M, S },
189 {op::CPX, X, D }, {op::SBCB,M, D }, {op::INC, M, D }, {op::SBCB, M, DLI },
190 {op::INX, M, IMP }, {op::SBCB,M, IMM }, {op::NOP, I, IMP }, {op::XBA, I, IMP },
191 {op::CPX, X, A }, {op::SBCB,M, A }, {op::INC, M, A }, {op::SBCB, M, AL },
192 // 0xF0
193 {op::BEQ, I, RELB }, {op::SBCB,M, DIY }, {op::SBCB,M, DI }, {op::SBCB, M, SIY },
194 {op::PEA, I, PEA }, {op::SBCB,M, DX }, {op::INC, M, DX }, {op::SBCB, M, DLIY},
195 {op::SED, I, IMP }, {op::SBCB,M, AY }, {op::PLX, I, IMP }, {op::XCE, I, IMP },
196 {op::JSR, I, AXI }, {op::SBCB,M, AX }, {op::INC, M, AX }, {op::SBCB, M, ALX }
197 };
198
199 const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix89[256] =
200 {
201 {op::BRK, I, SIG }, {op::MPY, M, DXI }, {op::COP, I, SIG }, {op::MPY, M, S },
202 {op::TSB, M, D }, {op::MPY, M, D }, {op::ASL, M, D }, {op::MPY, M, DLI },
203 {op::PHP, I, IMP }, {op::MPY, M, IMM }, {op::ASL, M, ACC }, {op::PHD, I, IMP },
204 {op::TSB, M, A }, {op::MPY, M, A }, {op::ASL, M, A }, {op::MPY, M, AL },
205 // 0x10
206 {op::BPL, I, RELB }, {op::ORA, M, DIY }, {op::ORA, M, DI }, {op::ORA, M, SIY },
207 {op::TRB, M, D }, {op::MPY, M, DX }, {op::ASL, M, DX }, {op::ORA, M, DLIY },
208 {op::CLC, I, IMP }, {op::MPY, M, AY }, {op::INA, I, IMP }, {op::TCS, I, IMP },
209 {op::TRB, M, A }, {op::ORA, M, AX }, {op::ASL, M, AX }, {op::ORA, M, ALX },
210 // 0x20
211 {op::JSR, I, A }, {op::AND, M, DXI }, {op::JSL, I, AL }, {op::AND, M, S },
212 {op::BIT, M, D }, {op::AND, M, D }, {op::ROL, M, D }, {op::AND, M, DLI },
213 {op::XAB, I, IMP }, {op::AND, M, IMM }, {op::ROL, M, ACC }, {op::PLD, I, IMP },
214 {op::BIT, M, A }, {op::AND, M, A }, {op::ROL, M, A }, {op::AND, M, AL },
215 // 0x30
216 {op::BMI, I, RELB }, {op::AND, M, DIY }, {op::AND, M, DI }, {op::AND, M, SIY },
217 {op::BIT, M, DX }, {op::AND, M, DX }, {op::ROL, M, DX }, {op::AND, M, DLIY },
218 {op::SEC, I, IMP }, {op::AND, M, AY }, {op::DEA, I, IMP }, {op::TSC, I, IMP },
219 {op::BIT, M, AX }, {op::AND, M, AX }, {op::ROL, M, AX }, {op::AND, M, ALX },
220 // 0x40
221 {op::RTI, I, IMP }, {op::EOR, M, DXI }, {op::WDM, I, IMP }, {op::EOR, M, S },
222 {op::MVP, I, MVP }, {op::EOR, M, D }, {op::LSR, M, D }, {op::EOR, M, DLI },
223 {op::PHA, I, IMP }, {op::RLA, M, IMM }, {op::LSR, M, ACC }, {op::PHK, I, IMP },
224 {op::JMP, I, A }, {op::EOR, M, A }, {op::LSR, M, A }, {op::EOR, M, AL },
225 // 0x50
226 {op::BVC, I, RELB }, {op::EOR, M, DIY }, {op::EOR, M, DI }, {op::EOR, M, SIY },
227 {op::MVN, I, MVN }, {op::EOR, M, DX }, {op::LSR, M, DX }, {op::EOR, M, DLIY },
228 {op::CLI, I, IMP }, {op::EOR, M, AY }, {op::PHY, I, IMP }, {op::TCD, I, IMP },
229 {op::JMP, I, AL }, {op::EOR, M, AX }, {op::LSR, M, AX }, {op::EOR, M, ALX },
230 // 0x60
231 {op::RTS, I, IMP }, {op::ADC, M, DXI }, {op::PER, I, PER }, {op::ADC, M, S },
232 {op::STZ, M, D }, {op::ADC, M, D }, {op::ROR, M, D }, {op::ADC, M, DLI },
233 {op::PLA, I, IMP }, {op::ADC, M, IMM }, {op::ROR, M, ACC }, {op::RTL, I, IMP },
234 {op::JMP, I, AI }, {op::ADC, M, A }, {op::ROR, M, A }, {op::ADC, M, AL },
235 // 0x70
236 {op::BVS, I, RELB }, {op::ADC, M, DIY }, {op::ADC, M, DI }, {op::ADC, M, SIY },
237 {op::STZ, M, DX }, {op::ADC, M, DX }, {op::ROR, M, DX }, {op::ADC, M, DLIY },
238 {op::SEI, I, IMP }, {op::ADC, M, AY }, {op::PLY, I, IMP }, {op::TDC, I, IMP },
239 {op::JMP, I, AXI }, {op::ADC, M, AX }, {op::ROR, M, AX }, {op::ADC, M, ALX },
240 // 0x80
241 {op::BRA, I, RELB }, {op::STA, M, DXI }, {op::BRL, I, RELW}, {op::STA, M, S },
242 {op::STY, X, D }, {op::STA, M, D }, {op::STX, X, D }, {op::STA, M, DLI },
243 {op::DEY, I, IMP }, {op::BIT, M, IMM }, {op::TXA, I, IMP }, {op::PHB, I, IMP },
244 {op::STY, X, A }, {op::STA, M, A }, {op::STX, X, A }, {op::STA, M, AL },
245 // 0x90
246 {op::BCC, I, RELB }, {op::STA, M, DIY }, {op::STA, M, DI }, {op::STA, M, SIY },
247 {op::STY, X, DX }, {op::STA, M, DX }, {op::STX, X, DY }, {op::STA, M, DLIY },
248 {op::TYA, I, IMP }, {op::STA, M, AY }, {op::TXS, I, IMP }, {op::TXY, I, IMP },
249 {op::STZ, M, A }, {op::STA, M, AX }, {op::STZ, M, AX }, {op::STA, M, ALX },
250 // 0xA0
251 {op::LDY, X, IMM }, {op::LDA, M, DXI }, {op::LDX, X, IMM }, {op::LDA, M, S },
252 {op::LDY, X, D }, {op::LDA, M, D }, {op::LDX, X, D }, {op::LDA, M, DLI },
253 {op::TAY, I, IMP }, {op::LDA, M, IMM }, {op::TAX, I, IMP }, {op::PLB, I, IMP },
254 {op::LDY, X, A }, {op::LDA, M, A }, {op::LDX, X, A }, {op::LDA, M, AL },
255 // 0xB0
256 {op::BCS, I, RELB }, {op::LDA, M, DIY }, {op::LDA, M, DI }, {op::LDA, M, SIY },
257 {op::LDY, X, DX }, {op::LDA, M, DX }, {op::LDX, X, DY }, {op::LDA, M, DLIY },
258 {op::CLV, I, IMP }, {op::LDA, M, AY }, {op::TSX, I, IMP }, {op::TYX, I, IMP },
259 {op::LDY, X, AX }, {op::LDA, M, AX }, {op::LDX, X, AY }, {op::LDA, M, ALX },
260 // 0xC0
261 {op::CPY, X, IMM }, {op::CMP, M, DXI }, {op::LDT, I, IMM }, {op::CMP, M, S },
262 {op::CPY, X, D }, {op::CMP, M, D }, {op::DEC, M, D }, {op::CMP, M, DLI },
263 {op::INY, I, IMP }, {op::CMP, M, IMM }, {op::DEX, I, IMP }, {op::WAI, I, IMP },
264 {op::CPY, X, A }, {op::CMP, M, A }, {op::DEC, M, A }, {op::CMP, M, AL },
265 // 0xD0
266 {op::BNE, I, RELB }, {op::CMP, M, DIY }, {op::CMP, M, DI }, {op::CMP, M, SIY },
267 {op::PEI, I, PEI }, {op::CMP, M, DX }, {op::DEC, M, DX }, {op::CMP, M, DLIY },
268 {op::CLD, I, IMP }, {op::CMP, M, AY }, {op::PHX, I, IMP }, {op::STP, I, IMP },
269 {op::JML, I, AI }, {op::CMP, M, AX }, {op::DEC, M, AX }, {op::CMP, M, ALX },
270 // 0xE0
271 {op::CPX, X, IMM }, {op::SBC, M, DXI }, {op::SEP, I, IMM }, {op::SBC, M, S },
272 {op::CPX, X, D }, {op::SBC, M, D }, {op::INC, M, D }, {op::SBC, M, DLI },
273 {op::INX, M, IMP }, {op::SBC, M, IMM }, {op::NOP, I, IMP }, {op::XBA, I, IMP },
274 {op::CPX, X, A }, {op::SBC, M, A }, {op::INC, M, A }, {op::SBC, M, AL },
275 // 0xF0
276 {op::BEQ, I, RELB }, {op::SBC, M, DIY }, {op::SBC, M, DI }, {op::SBC, M, SIY },
277 {op::PEA, I, PEA }, {op::SBC, M, DX }, {op::INC, M, DX }, {op::SBC, M, DLIY },
278 {op::SEM, I, IMP }, {op::SBC, M, AY }, {op::PLX, I, IMP }, {op::XCE, I, IMP },
279 {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX }
280 };
281
int_8_str(unsigned int val)282 inline std::string m7700_disassembler::int_8_str(unsigned int val)
283 {
284 val &= 0xff;
285
286 if(val & 0x80)
287 return util::string_format("-$%x", (0-val) & 0xff);
288 else
289 return util::string_format("$%x", val & 0xff);
290 }
291
int_16_str(unsigned int val)292 inline std::string m7700_disassembler::int_16_str(unsigned int val)
293 {
294 val &= 0xffff;
295
296 if(val & 0x8000)
297 return util::string_format("-$%x", (0-val) & 0xffff);
298 else
299 return util::string_format("$%x", val & 0xffff);
300 }
301
m7700_disassembler(config * conf)302 m7700_disassembler::m7700_disassembler(config *conf) : m_config(conf)
303 {
304 }
305
opcode_alignment() const306 u32 m7700_disassembler::opcode_alignment() const
307 {
308 return 1;
309 }
310
disassemble(std::ostream & stream,offs_t pc,const data_buffer & opcodes,const data_buffer & params)311 offs_t m7700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
312 {
313 unsigned int instruction;
314 const m7700_opcode_struct *opcode;
315 int var;
316 signed char varS;
317 int length = 1;
318 //unsigned int start;
319 uint32_t flags = 0;
320
321 offs_t address = pc;
322 u32 pg = pc & 0xff0000;
323 pc &= 0xffff;
324 address = pc | pg;
325
326 instruction = opcodes.r8(address);
327
328 int m_flag = m_config->get_m_flag();
329 int x_flag = m_config->get_x_flag();
330
331 // check for prefixes
332 switch (instruction)
333 {
334 case 0x42:
335 address++;
336 length++;
337 instruction = opcodes.r8(address);
338 opcode = &m7700_opcode_struct::get_prefix42(instruction);
339 break;
340
341 case 0x89:
342 address++;
343 length++;
344 instruction = opcodes.r8(address);
345 opcode = &m7700_opcode_struct::get_prefix89(instruction);
346 break;
347
348 default:
349 opcode = &m7700_opcode_struct::get(instruction);
350 break;
351 }
352
353 if (opcode->is_call())
354 flags = STEP_OVER;
355 else if (opcode->is_return())
356 flags = STEP_OUT;
357
358 stream << opcode->name();
359
360 switch(opcode->ea)
361 {
362 case IMP :
363 break;
364 case ACC :
365 util::stream_format(stream, " A");
366 break;
367 case ACCB :
368 util::stream_format(stream, " B");
369 break;
370 case RELB:
371 varS = opcodes.r8(address + 1);
372 length++;
373 util::stream_format(stream, " %06x (%s)", pg | ((pc + length + varS)&0xffff), int_8_str(varS));
374 break;
375 case RELW:
376 case PER :
377 var = opcodes.r16(address + 1);
378 length += 2;
379 util::stream_format(stream, " %06x (%s)", pg | ((pc + length + var)&0xffff), int_16_str(var));
380 break;
381 case IMM :
382 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
383 {
384 util::stream_format(stream, " #$%04x", opcodes.r16(address + 1));
385 length += 2;
386 }
387 else
388 {
389 util::stream_format(stream, " #$%02x", opcodes.r8(address + 1));
390 length++;
391 }
392 break;
393 case BBCD:
394 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
395 {
396 varS = opcodes.r8(address + 4);
397 length += 4;
398 util::stream_format(stream, " #$%04x, $%02x, %06x (%s)", opcodes.r16(address + 2), opcodes.r8(address + 1), pg | ((pc + length + varS)&0xffff), int_8_str(varS));
399 }
400 else
401 {
402 varS = opcodes.r8(address + 3);
403 length += 3;
404 util::stream_format(stream, " #$%02x, $%02x, %06x (%s)", opcodes.r8(address + 2), opcodes.r8(address + 1), pg | ((pc + length + varS)&0xffff), int_8_str(varS));
405 }
406 break;
407 case BBCA:
408 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
409 {
410 length += 5;
411 varS = opcodes.r8(address + 5);
412 util::stream_format(stream, " #$%04x, $%04x, %06x (%s)", opcodes.r16(address + 3), opcodes.r16(address + 1), pg | ((pc + length + varS)&0xffff), int_8_str(varS));
413 }
414 else
415 {
416 length += 4;
417 varS = opcodes.r8(address + 4);
418 util::stream_format(stream, " #$%02x, $%04x, %06x (%s)", opcodes.r8(address + 3), opcodes.r16(address + 1), pg | ((pc + length + varS)&0xffff), int_8_str(varS));
419 }
420 break;
421 case LDM4:
422 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
423 {
424 util::stream_format(stream, " #$%04x, $%02x", opcodes.r16(address + 2), opcodes.r8(address + 1));
425 length += 3;
426 }
427 else
428 {
429 util::stream_format(stream, " #$%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1));
430 length += 2;
431 }
432 break;
433 case LDM5:
434 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
435 {
436 util::stream_format(stream, " #$%04x, $%04x", opcodes.r16(address + 3), opcodes.r16(address + 1));
437 length += 4;
438 }
439 else
440 {
441 util::stream_format(stream, " #$%02x, $%04x", opcodes.r8(address + 3), opcodes.r16(address + 1));
442 length += 3;
443 }
444 break;
445 case LDM4X:
446 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
447 {
448 util::stream_format(stream, " #$%04x, $%02x, X", opcodes.r16(address + 2), opcodes.r8(address + 1));
449 length += 3;
450 }
451 else
452 {
453 util::stream_format(stream, " #$%02x, $%02x, X", opcodes.r8(address + 2), opcodes.r8(address + 1));
454 length += 2;
455 }
456 break;
457 case LDM5X:
458 if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag))
459 {
460 util::stream_format(stream, " #$%04x, $%04x, X", opcodes.r16(address + 3), opcodes.r16(address + 1));
461 length += 4;
462 }
463 else
464 {
465 util::stream_format(stream, " #$%02x, $%04x, X", opcodes.r8(address + 3), opcodes.r16(address + 1));
466 length += 3;
467 }
468 break;
469 case A :
470 case PEA :
471 util::stream_format(stream, " $%04x", opcodes.r16(address + 1));
472 length += 2;
473 break;
474 case AI :
475 util::stream_format(stream, " ($%04x)", opcodes.r16(address + 1));
476 length += 2;
477 break;
478 case AL :
479 util::stream_format(stream, " $%06x", opcodes.r32(address + 1) & 0xffffff);
480 length += 3;
481 break;
482 case ALX :
483 util::stream_format(stream, " $%06x,X", opcodes.r32(address + 1) & 0xffffff);
484 length += 3;
485 break;
486 case AX :
487 util::stream_format(stream, " $%04x,X", opcodes.r16(address + 1));
488 length += 2;
489 break;
490 case AXI :
491 util::stream_format(stream, " ($%04x,X)", opcodes.r16(address + 1));
492 length += 2;
493 break;
494 case AY :
495 util::stream_format(stream, " $%04x,Y", opcodes.r16(address + 1));
496 length += 2;
497 break;
498 case D :
499 util::stream_format(stream, " $%02x", opcodes.r8(address + 1));
500 length++;
501 break;
502 case DI :
503 case PEI :
504 util::stream_format(stream, " ($%02x)", opcodes.r8(address + 1));
505 length++;
506 break;
507 case DIY :
508 util::stream_format(stream, " ($%02x),Y", opcodes.r8(address + 1));
509 length++;
510 break;
511 case DLI :
512 util::stream_format(stream, " [$%02x]", opcodes.r8(address + 1));
513 length++;
514 break;
515 case DLIY:
516 util::stream_format(stream, " [$%02x],Y", opcodes.r8(address + 1));
517 length++;
518 break;
519 case DX :
520 util::stream_format(stream, " $%02x,X", opcodes.r8(address + 1));
521 length++;
522 break;
523 case DXI :
524 util::stream_format(stream, " ($%02x,X)", opcodes.r8(address + 1));
525 length++;
526 break;
527 case DY :
528 util::stream_format(stream, " $%02x,Y", opcodes.r8(address + 1));
529 length++;
530 break;
531 case S :
532 util::stream_format(stream, " %s,S", int_8_str(opcodes.r8(address + 1)));
533 length++;
534 break;
535 case SIY :
536 util::stream_format(stream, " (%s,S),Y", int_8_str(opcodes.r8(address + 1)));
537 length++;
538 break;
539 case SIG :
540 util::stream_format(stream, " #$%02x", opcodes.r8(address + 1));
541 length++;
542 break;
543 case MVN :
544 case MVP :
545 util::stream_format(stream, " $%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1));
546 length += 2;
547 break;
548 }
549
550 return length | flags | SUPPORTED;
551 }
552