ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_8080.cpp
Revision: 1.4
Committed: 2000-09-25T12:44:33Z (24 years, 2 months ago) by cebix
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
- replaced 680x0 and 80x86 disassemblers with the ones from GNU binutils
- 680x0 disassembler shows symbolic MacOS low memory globals

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * mon_8080.cpp - 8080 disassembler
3     *
4 cebix 1.3 * mon (C) 1997-2000 Christian Bauer, Marc Hellwig
5 cebix 1.2 *
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 cebix 1.1 */
20    
21 cebix 1.2 #include "sysdeps.h"
22 cebix 1.1
23     #include "mon.h"
24 cebix 1.4 #include "mon_disass.h"
25 cebix 1.1
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     }