ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_disass.cpp
Revision: 1.4
Committed: 2000-10-15T15:07:14Z (24 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
- extended to 8080 disassembler to a Z80 disassembler
- program renamed to "cxmon"

File Contents

# Content
1 /*
2 * mon_disass.cpp - Disassemblers
3 *
4 * cxmon (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 <stdarg.h>
24
25 #include "mon.h"
26 #include "mon_disass.h"
27
28 #include "mon_atraps.h"
29 #include "mon_lowmem.h"
30
31
32 // Flag: enable MacOS A-Trap and LM globals lookup in 68k disassembler
33 bool mon_macos_mode = false;
34
35
36 /*
37 * GNU disassembler callbacks
38 */
39
40 extern "C" {
41 #include "disass/dis-asm.h"
42
43 int buffer_read_memory(bfd_vma from, bfd_byte *to, int length, struct disassemble_info *info)
44 {
45 while (length--)
46 *to++ = mon_read_byte(from++);
47 return 0;
48 }
49
50 void perror_memory(int status, bfd_vma memaddr, struct disassemble_info *info)
51 {
52 info->fprintf_func(info->stream, "Unknown error %d\n", status);
53 }
54
55 bool lookup_lowmem;
56
57 void generic_print_address(bfd_vma addr, struct disassemble_info *info)
58 {
59 if (lookup_lowmem && addr >= 0x100 && addr < 0x3000) {
60 if (((addr >= 0x400 && addr < 0x800) || (addr >= 0xe00 && addr < 0x1e00)) && ((addr & 3) == 0)) {
61 // Look for address in A-Trap table
62 uint16 opcode = (addr < 0xe00 ? 0xa000 + (addr - 0x400) / 4 : 0xa800 + (addr - 0xe00) / 4);
63 uint16 mask = (addr < 0xe00 ? 0xf8ff : 0xffff);
64 const atrap_info *p = atraps;
65 while (p->word) {
66 if ((p->word & mask) == opcode) {
67 info->fprintf_func(info->stream, p->name);
68 return;
69 }
70 p++;
71 }
72 } else {
73 // Look for address in low memory globals table
74 const lowmem_info *p = lowmem;
75 while (p->name) {
76 if (addr >= p[0].addr && addr < p[1].addr) {
77 if (addr == p[0].addr)
78 info->fprintf_func(info->stream, "%s", p->name);
79 else
80 info->fprintf_func(info->stream, "%s+%d", p->name, addr - p->addr);
81 return;
82 }
83 p++;
84 }
85 }
86 }
87 info->fprintf_func(info->stream, "$%08x", addr);
88 }
89
90 int generic_symbol_at_address(bfd_vma addr, struct disassemble_info *info)
91 {
92 return 0;
93 }
94
95 void print_68k_invalid_opcode(unsigned long opcode, struct disassemble_info *info)
96 {
97 if (mon_macos_mode) {
98 // Look for MacOS A-Trap
99 const atrap_info *p = atraps;
100 while (p->word) {
101 if (p->word == opcode) {
102 info->fprintf_func(info->stream, p->name);
103 return;
104 }
105 p++;
106 }
107 }
108 info->fprintf_func(info->stream, "?");
109 }
110
111 };
112
113
114 /*
115 * sprintf into a "stream"
116 */
117
118 struct SFILE {
119 char *buffer;
120 char *current;
121 };
122
123 static int mon_sprintf(SFILE *f, const char *format, ...)
124 {
125 int n;
126 va_list args;
127 va_start(args, format);
128 vsprintf(f->current, format, args);
129 f->current += n = strlen(f->current);
130 va_end(args);
131 return n;
132 }
133
134
135 /*
136 * Disassemble one instruction, return number of bytes
137 */
138
139 int disass_68k(FILE *f, uint32 adr)
140 {
141 // Initialize info for GDB disassembler
142 disassemble_info info;
143 char buf[1024];
144 SFILE sfile = {buf, buf};
145 sfile.buffer = buf;
146 sfile.current = buf;
147 INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
148
149 // Disassemble instruction
150 lookup_lowmem = mon_macos_mode;
151 int num = print_insn_m68k(adr, &info);
152
153 for (int i=0; i<6; i+=2) {
154 if (num > i)
155 fprintf(f, "%04x ", mon_read_half(adr + i));
156 else
157 fprintf(f, " ");
158 }
159 if (num == 8)
160 fprintf(f, "%04x\t%s\n", mon_read_half(adr + 6), buf);
161 else if (num > 8)
162 fprintf(f, "...\t%s\n", buf);
163 else
164 fprintf(f, " \t%s\n", buf);
165
166 return num;
167 }
168
169 int disass_x86(FILE *f, uint32 adr, bool i8086)
170 {
171 // Initialize info for GDB disassembler
172 disassemble_info info;
173 char buf[1024];
174 SFILE sfile = {buf, buf};
175 sfile.buffer = buf;
176 sfile.current = buf;
177 INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
178 if (i8086)
179 info.mach = bfd_mach_i386_i8086;
180
181 // Disassemble instruction
182 lookup_lowmem = false;
183 int num = print_insn_i386(adr, &info);
184
185 for (int i=0; i<6; i++) {
186 if (num > i)
187 fprintf(f, "%02x ", mon_read_byte(adr + i));
188 else
189 fprintf(f, " ");
190 }
191 if (num == 7)
192 fprintf(f, "%02x\t%s\n", mon_read_byte(adr + 7), buf);
193 else if (num > 7)
194 fprintf(f, "..\t%s\n", buf);
195 else
196 fprintf(f, " \t%s\n", buf);
197
198 return num;
199 }