ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_8080.cpp
Revision: 1.5
Committed: 2000-10-15T15:07:12Z (23 years, 7 months ago) by cebix
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +0 -0 lines
State: FILE REMOVED
Log Message:
- extended to 8080 disassembler to a Z80 disassembler
- program renamed to "cxmon"

File Contents

# Content
1 /*
2 * mon_8080.cpp - 8080 disassembler
3 *
4 * mon (C) 1997-2000 Christian Bauer, Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22
23 #include "mon.h"
24 #include "mon_disass.h"
25
26
27 // Addressing modes
28 enum {
29 A_IMPL,
30 A_BC, // bc
31 A_DE, // de
32 A_HL, // hl
33 A_SP, // sp
34 A_PSW, // psw
35 A_REG1, // register (bits 0..2 of opcode)
36 A_REG2, // register (bits 3..5 of opcode)
37 A_2REG, // register (bits 3..5 of opcode),register (bits 0..2 of opcode)
38 A_RST, // restart
39 A_BYTE, // xx
40 A_R2_B, // register (bits 3..5 of opcode),xx
41 A_WORD, // xxxx
42 A_BC_W, // bc,xxxx
43 A_DE_W, // de,xxxx
44 A_HL_W, // hl,xxxx
45 A_SP_W // sp,xxxx
46 };
47
48 // Mnemonics
49 enum {
50 M_ACI, M_ADC, M_ADD, M_ADI, M_ANA, M_ANI, M_CALL, M_CC, M_CM, M_CMA, M_CMC,
51 M_CMP, M_CNC, M_CNZ, M_CP, M_CPE, M_CPI, M_CPO, M_CZ, M_DAA, M_DAD, M_DCR,
52 M_DCX, M_DI, M_EI, M_HLT, M_IN, M_INR, M_INX, M_JMP, M_JC, M_JM, M_JNC, M_JNZ,
53 M_JP, M_JPE, M_JPO, M_JZ, M_LDA, M_LDAX, M_LHLD, M_LXI, M_MOV, M_MVI, M_NOP,
54 M_ORA, M_ORI, M_OUT, M_PCHL, M_POP, M_PUSH, M_RAL, M_RAR, M_RET, M_RC, M_RM,
55 M_RNC, M_RNZ, M_RP, M_RPE, M_RPO, M_RZ, M_RLC, M_RRC, M_RST, M_SBB, M_SBI,
56 M_SHLD, M_SPHL, M_STA, M_STAX, M_STC, M_SUB, M_SUI, M_XCHG, M_XRA, M_XRI, M_XTHL,
57 M_ILLEGAL,
58
59 M_MAXIMUM // Highest element
60 };
61
62 // Mnemonic for each opcode
63 static const char mnemonic[256] = {
64 M_NOP , M_LXI , M_STAX, M_INX , M_INR, M_DCR , M_MVI, M_RLC, // 00
65 M_ILLEGAL, M_DAD , M_LDAX, M_DCX , M_INR, M_DCR , M_MVI, M_RRC,
66 M_ILLEGAL, M_LXI , M_STAX, M_INX , M_INR, M_DCR , M_MVI, M_RAL, // 10
67 M_ILLEGAL, M_DAD , M_LDAX, M_DCX , M_INR, M_DCR , M_MVI, M_RAR,
68 M_ILLEGAL, M_LXI , M_SHLD, M_INX , M_INR, M_DCR , M_MVI, M_DAA, // 20
69 M_ILLEGAL, M_DAD , M_LHLD, M_DCX , M_INR, M_DCR , M_MVI, M_CMA,
70 M_ILLEGAL, M_LXI , M_STA , M_INX , M_INR, M_DCR , M_MVI, M_STC, // 30
71 M_ILLEGAL, M_DAD , M_LDA , M_DCX , M_INR, M_DCR , M_MVI, M_CMC,
72 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV, // 40
73 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV,
74 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV, // 50
75 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV,
76 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV, // 60
77 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV,
78 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_HLT, M_MOV, // 70
79 M_MOV , M_MOV , M_MOV , M_MOV , M_MOV, M_MOV , M_MOV, M_MOV,
80 M_ADD , M_ADD , M_ADD , M_ADD , M_ADD, M_ADD , M_ADD, M_ADD, // 80
81 M_ADC , M_ADC , M_ADC , M_ADC , M_ADC, M_ADC , M_ADC, M_ADC,
82 M_SUB , M_SUB , M_SUB , M_SUB , M_SUB, M_SUB , M_SUB, M_SUB, // 90
83 M_SBB , M_SBB , M_SBB , M_SBB , M_SBB, M_SBB , M_SBB, M_SBB,
84 M_ANA , M_ANA , M_ANA , M_ANA , M_ANA, M_ANA , M_ANA, M_ANA, // a0
85 M_XRA , M_XRA , M_XRA , M_XRA , M_XRA, M_XRA , M_XRA, M_XRA,
86 M_ORA , M_ORA , M_ORA , M_ORA , M_ORA, M_ORA , M_ORA, M_ORA, // b0
87 M_CMP , M_CMP , M_CMP , M_CMP , M_CMP, M_CMP , M_CMP, M_CMP,
88 M_RNZ , M_POP , M_JNZ , M_JMP , M_CNZ, M_PUSH , M_ADI, M_RST, // c0
89 M_RZ , M_RET , M_JZ , M_ILLEGAL, M_CZ , M_CALL , M_ACI, M_RST,
90 M_RNC , M_POP , M_JNC , M_OUT , M_CNC, M_PUSH , M_SUI, M_RST, // d0
91 M_RC , M_ILLEGAL, M_JC , M_IN , M_CC , M_ILLEGAL, M_SBI, M_RST,
92 M_RPO , M_POP , M_JPO , M_XTHL , M_CPO, M_PUSH , M_ANI, M_RST, // e0
93 M_RPE , M_PCHL , M_JPE , M_XCHG , M_CPE, M_ILLEGAL, M_XRI, M_RST,
94 M_RP , M_POP , M_JP , M_DI , M_CP , M_PUSH , M_ORI, M_RST, // f0
95 M_RM , M_SPHL , M_JM , M_EI , M_CM , M_ILLEGAL, M_CPI, M_RST
96 };
97
98 // Addressing mode for each opcode
99 static const char adr_mode[256] = {
100 A_IMPL, A_BC_W, A_BC , A_BC , A_REG2, A_REG2, A_R2_B, A_IMPL, // 00
101 A_IMPL, A_BC , A_BC , A_BC , A_REG2, A_REG2, A_R2_B, A_IMPL,
102 A_IMPL, A_DE_W, A_DE , A_DE , A_REG2, A_REG2, A_R2_B, A_IMPL, // 10
103 A_IMPL, A_DE , A_DE , A_DE , A_REG2, A_REG2, A_R2_B, A_IMPL,
104 A_IMPL, A_HL_W, A_WORD, A_HL , A_REG2, A_REG2, A_R2_B, A_IMPL, // 20
105 A_IMPL, A_HL , A_WORD, A_HL , A_REG2, A_REG2, A_R2_B, A_IMPL,
106 A_IMPL, A_SP_W, A_WORD, A_SP , A_REG2, A_REG2, A_R2_B, A_IMPL, // 30
107 A_IMPL, A_SP , A_WORD, A_SP , A_REG2, A_REG2, A_R2_B, A_IMPL,
108 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, // 40
109 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG,
110 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, // 50
111 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG,
112 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, // 60
113 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG,
114 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_IMPL, A_2REG, // 70
115 A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG, A_2REG,
116 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, // 80
117 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1,
118 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, // 90
119 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1,
120 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, // a0
121 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1,
122 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, // b0
123 A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1, A_REG1,
124 A_IMPL, A_BC , A_WORD, A_WORD, A_WORD, A_BC , A_BYTE, A_RST , // c0
125 A_IMPL, A_IMPL, A_WORD, A_IMPL, A_WORD, A_WORD, A_BYTE, A_RST ,
126 A_IMPL, A_DE , A_WORD, A_BYTE, A_WORD, A_DE , A_BYTE, A_RST , // d0
127 A_IMPL, A_IMPL, A_WORD, A_BYTE, A_WORD, A_IMPL, A_BYTE, A_RST ,
128 A_IMPL, A_HL , A_WORD, A_IMPL, A_WORD, A_HL , A_BYTE, A_RST , // e0
129 A_IMPL, A_IMPL, A_WORD, A_IMPL, A_WORD, A_IMPL, A_BYTE, A_RST ,
130 A_IMPL, A_PSW , A_WORD, A_IMPL, A_WORD, A_PSW , A_BYTE, A_RST , // f0
131 A_IMPL, A_IMPL, A_WORD, A_IMPL, A_WORD, A_IMPL, A_BYTE, A_RST
132 };
133
134 // Chars for each mnemonic
135 static const char mnem_1[] = "aaaaaacccccccccccccdddddehiiijjjjjjjjjllllmmnoooppprrrrrrrrrrrrrrsssssssssxxxx?";
136 static const char mnem_2[] = "cdddnnacmmmmnnppppzaacciilnnnmcmnnpppzddhxovorrucouaaecmnnpppzlrsbbhptttuucrrt ";
137 static const char mnem_3[] = "icdiail acpcz eio adrx t rxp cz eo aalivipaithpslrt cz eo cctbilhaacbihaih ";
138 static const char mnem_4[] = " l xd l h dl x g l ";
139
140 // Register names
141 static const char reg_name[] = {"bcdehlma"};
142
143 // Instruction length for each addressing mode
144 static const char adr_length[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3};
145
146
147 /*
148 * Disassemble one instruction, return number of bytes
149 */
150
151 int disass_8080(FILE *f, uint32 adr, uint8 op, uint8 lo, uint8 hi)
152 {
153 char mode = adr_mode[op], mnem = mnemonic[op];
154
155 // Display instruction bytes in hex
156 switch (adr_length[mode]) {
157 case 1:
158 fprintf(f, "%02x\t\t", op);
159 break;
160
161 case 2:
162 fprintf(f, "%02x %02x\t\t", op, lo);
163 break;
164
165 case 3:
166 fprintf(f, "%02x %02x %02x\t", op, lo, hi);
167 break;
168 }
169
170 // Print mnemonic
171 fprintf(f, "%c%c%c%c ", mnem_1[mnem], mnem_2[mnem], mnem_3[mnem], mnem_4[mnem]);
172
173 // Print argument
174 switch (mode) {
175 case A_IMPL:
176 break;
177
178 case A_BC:
179 fprintf(f, "bc");
180 break;
181
182 case A_DE:
183 fprintf(f, "de");
184 break;
185
186 case A_HL:
187 fprintf(f, "hl");
188 break;
189
190 case A_SP:
191 fprintf(f, "sp");
192 break;
193
194 case A_PSW:
195 fprintf(f, "psw");
196 break;
197
198 case A_REG1:
199 fprintf(f, "%c", reg_name[op & 7]);
200 break;
201
202 case A_REG2:
203 fprintf(f, "%c", reg_name[(op >> 3) & 7]);
204 break;
205
206 case A_2REG:
207 fprintf(f, "%c,%c", reg_name[(op >> 3) & 7], reg_name[op & 7]);
208 break;
209
210 case A_RST:
211 fprintf(f, "$%02x", op & 0x38);
212 break;
213
214 case A_BYTE:
215 fprintf(f, "$%02x", lo);
216 break;
217
218 case A_R2_B:
219 fprintf(f, "%c,$%02x", reg_name[(op >> 3) & 7], lo);
220 break;
221
222 case A_WORD:
223 fprintf(f, "$%04x", (hi << 8) | lo);
224 break;
225
226 case A_BC_W:
227 fprintf(f, "bc,$%04x", (hi << 8) | lo);
228 break;
229
230 case A_DE_W:
231 fprintf(f, "de,$%04x", (hi << 8) | lo);
232 break;
233
234 case A_HL_W:
235 fprintf(f, "hl,$%04x", (hi << 8) | lo);
236 break;
237
238 case A_SP_W:
239 fprintf(f, "sp,$%04x", (hi << 8) | lo);
240 break;
241 }
242
243 fputc('\n', f);
244 return adr_length[mode];
245 }