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