1 /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6
7 #include "generator.h"
8 #include "cpu68k.h"
9
10 /* forward references */
11
12 void diss68k_getoperand(char *text, t_ipc * ipc, t_iib * iib, t_type type);
13
14 /* functions */
15
diss68k_gettext(t_ipc * ipc,char * text)16 int diss68k_gettext(t_ipc * ipc, char *text)
17 {
18 t_iib *iib;
19 char *p;
20 const char *c;
21 char src[64], dst[64];
22 char mnemonic[64];
23
24 *text = '\0';
25
26 iib = cpu68k_iibtable[ipc->opcode];
27
28 if (iib == NULL)
29 return 0;
30
31 diss68k_getoperand(dst, ipc, iib, tp_dst);
32 diss68k_getoperand(src, ipc, iib, tp_src);
33
34 if ((iib->mnemonic == i_Bcc) || (iib->mnemonic == i_BSR) ||
35 (iib->mnemonic == i_DBcc)) {
36 sprintf(src, "$%08x", (unsigned)ipc->src);
37 }
38
39 strcpy(mnemonic, mnemonic_table[iib->mnemonic].name);
40
41 if ((p = strstr(mnemonic, "cc")) != NULL) {
42 if (iib->mnemonic == i_Bcc && iib->cc == 0) {
43 p[0] = 'R';
44 p[1] = 'A';
45 } else {
46 c = condition_table[iib->cc];
47 strcpy(p, c);
48 }
49 }
50
51 switch (iib->size) {
52 case sz_byte:
53 strcat(mnemonic, ".B");
54 break;
55 case sz_word:
56 strcat(mnemonic, ".W");
57 break;
58 case sz_long:
59 strcat(mnemonic, ".L");
60 break;
61 default:
62 break;
63 }
64
65 sprintf(text, "%-10s %s%s%s %d", mnemonic, src, dst[0] ? "," : "", dst,iib->funcnum);
66
67 return 1;
68 }
69
diss68k_getoperand(char * text,t_ipc * ipc,t_iib * iib,t_type type)70 void diss68k_getoperand(char *text, t_ipc * ipc, t_iib * iib, t_type type)
71 {
72 int bitpos;
73 uint32 val;
74
75 if (type == tp_src) {
76 bitpos = iib->sbitpos;
77 val = ipc->src;
78 } else {
79 bitpos = iib->dbitpos;
80 val = ipc->dst;
81 }
82
83 switch (type == tp_src ? iib->stype : iib->dtype) {
84 case dt_Dreg:
85 sprintf(text, "D%d", (ipc->opcode >> bitpos) & 7);
86 break;
87 case dt_Areg:
88 sprintf(text, "A%d", (ipc->opcode >> bitpos) & 7);
89 break;
90 case dt_Aind:
91 sprintf(text, "(A%d)", (ipc->opcode >> bitpos) & 7);
92 break;
93 case dt_Ainc:
94 sprintf(text, "(A%d)+", (ipc->opcode >> bitpos) & 7);
95 break;
96 case dt_Adec:
97 sprintf(text, "-(A%d)", (ipc->opcode >> bitpos) & 7);
98 break;
99 case dt_Adis:
100 sprintf(text, "$%04x(A%d)", (uint16)val, (ipc->opcode >> bitpos) & 7);
101 break;
102 case dt_Aidx:
103 sprintf(text, "$%02x(A%d,Rx.X)", (uint8)val, (ipc->opcode >> bitpos) & 7);
104 break;
105 case dt_AbsW:
106 sprintf(text, "$%08x", (unsigned)val);
107 break;
108 case dt_AbsL:
109 sprintf(text, "$%08x", (unsigned)val);
110 break;
111 case dt_Pdis:
112 sprintf(text, "$%08x(pc)", (unsigned)val);
113 break;
114 case dt_Pidx:
115 sprintf(text, "$%08x(pc, Rx.X)", (unsigned)val);
116 break;
117 case dt_ImmB:
118 sprintf(text, "#$%02x", (unsigned)val);
119 break;
120 case dt_ImmW:
121 sprintf(text, "#$%04x", (unsigned)val);
122 break;
123 case dt_ImmL:
124 sprintf(text, "#$%08x", (unsigned)val);
125 break;
126 case dt_ImmS:
127 sprintf(text, "#%d", iib->immvalue);
128 break;
129 case dt_Imm3:
130 sprintf(text, "#%d", (ipc->opcode >> bitpos) & 7);
131 break;
132 case dt_Imm4:
133 sprintf(text, "#%d", (ipc->opcode >> bitpos) & 15);
134 break;
135 case dt_Imm8:
136 sprintf(text, "#%d", (ipc->opcode >> bitpos) & 255);
137 break;
138 case dt_Imm8s:
139 sprintf(text, "#%d", (signed int)val);
140 break;
141 default:
142 strcpy(text, "");
143 break;
144 }
145 }
146
diss68k_getdumpline(uint32 addr68k,uint8 * addr,char * dumpline)147 int diss68k_getdumpline(uint32 addr68k, uint8 *addr, char *dumpline)
148 {
149 t_ipc ipc;
150 t_iib *iibp = cpu68k_iibtable[LOCENDIAN16(*(uint16 *)addr)];
151 int words, i;
152 char dissline[64], *p;
153
154 if (addr68k < 256) {
155 sprintf(dissline, "dc.l $%08x", (unsigned)LOCENDIAN32(*(uint32 *)addr));
156 words = 2;
157 } else {
158 cpu68k_ipc(addr68k, addr, iibp, &ipc);
159 if (!diss68k_gettext(&ipc, dissline))
160 strcpy(dissline, "Illegal Instruction");
161 words = ipc.wordlen;
162 }
163
164 p = dumpline;
165 p += sprintf(p, "%6x : %04x ", (unsigned)addr68k, (addr[0] << 8) + addr[1]);
166 for (i = 1; i < words; i++) {
167 p += sprintf(p, "%04x ", (addr[i * 2] << 8) + addr[i * 2 + 1]);
168 }
169 for (i = 29 - strlen(dumpline); i > 0; i--) {
170 *p++ = ' ';
171 }
172 p += sprintf(p, ": ");
173 for (i = 0; i < words; i++) {
174 if (isalnum(addr[i * 2])) {
175 *p++ = addr[i * 2];
176 } else
177 *p++ = '.';
178 if (isalnum(addr[i * 2 + 1])) {
179 *p++ = addr[i * 2 + 1];
180 } else
181 *p++ = '.';
182 }
183 *p = '\0';
184 for (i = 39 - strlen(dumpline); i > 0; i--) {
185 *p++ = ' ';
186 }
187 if (iibp) {
188 sprintf(p, " : %4d : %s\n", iibp->funcnum, dissline);
189 } else {
190 sprintf(p, " : : %s\n", dissline);
191 }
192
193 return words;
194 }
195