|
|
1.1 root 1: /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2:
3: #include <stdio.h>
4: #include <string.h>
5: #include <stdlib.h>
6:
7: #include "generator.h"
8: #include "cpu68k.h"
1.1.1.2 root 9: #include "mem68k.h"
1.1 root 10: #include "vdp.h"
11: #include "ui.h"
12: #include "def68k-iibs.h"
13: #include "def68k-proto.h"
14: #include "def68k-funcs.h"
15:
16: /*** externed variables ***/
17:
18: uint8 *cpu68k_rom = NULL;
19: unsigned int cpu68k_romlen = 0;
20: uint8 *cpu68k_ram = NULL;
21: t_iib *cpu68k_iibtable[65536];
1.1.1.2 root 22: void (*cpu68k_functable[65536 * 2]) (t_ipc * ipc);
1.1 root 23: int cpu68k_totalinstr;
24: int cpu68k_totalfuncs;
25: unsigned int cpu68k_clocks;
26: unsigned int cpu68k_frames;
1.1.1.2 root 27: unsigned int cpu68k_frozen; /* cpu frozen, do not interrupt, make pending */
1.1 root 28: t_regs regs;
29: uint8 movem_bit[256];
30: t_ipclist *ipclist[LEN_IPCLISTTABLE];
31:
32: /*** global variables ***/
33:
34: /*** forward references ***/
35:
36: void cpu68k_reset(void);
37:
38: int cpu68k_init(void)
39: {
40: t_iib *iib;
41: uint16 bitmap;
42: int i, j, sbit, dbit, sbits, dbits;
43:
44: memset(cpu68k_iibtable, 0, sizeof(cpu68k_iibtable));
45: memset(cpu68k_functable, 0, sizeof(cpu68k_functable));
46: memset(®s, 0, sizeof(regs));
47:
48: cpu68k_frozen = 0;
49: cpu68k_totalinstr = 0;
50:
51: for (i = 0; i < iibs_num; i++) {
52: iib = &iibs[i];
53:
54: bitmap = iib->mask;
55: sbits = 0;
56: dbits = 0;
57:
58: for (j = 0; j < 2; j++) {
1.1.1.2 root 59: switch (j ? iib->stype : iib->dtype) {
1.1 root 60: case dt_Dreg:
61: case dt_Areg:
62: case dt_Aind:
63: case dt_Ainc:
64: case dt_Adec:
65: case dt_Adis:
66: case dt_Aidx:
1.1.1.2 root 67: if (j) {
68: bitmap ^= 7 << iib->sbitpos;
69: sbits = 3;
70: } else {
71: bitmap ^= 7 << iib->dbitpos;
72: dbits = 3;
73: }
74: break;
1.1 root 75: case dt_AbsW:
76: case dt_AbsL:
77: case dt_Pdis:
78: case dt_Pidx:
1.1.1.2 root 79: break;
1.1 root 80: case dt_ImmB:
81: case dt_ImmW:
82: case dt_ImmL:
83: case dt_ImmS:
1.1.1.2 root 84: break;
1.1 root 85: case dt_Imm3:
1.1.1.2 root 86: if (j) {
87: bitmap ^= 7 << iib->sbitpos;
88: sbits = 3;
89: } else {
90: bitmap ^= 7 << iib->dbitpos;
91: dbits = 3;
92: }
93: break;
1.1 root 94: case dt_Imm4:
1.1.1.2 root 95: if (j) {
96: bitmap ^= 15 << iib->sbitpos;
97: sbits = 4;
98: } else {
99: bitmap ^= 15 << iib->dbitpos;
100: dbits = 4;
101: }
102: break;
1.1 root 103: case dt_Imm8:
104: case dt_Imm8s:
1.1.1.2 root 105: if (j) {
106: bitmap ^= 255 << iib->sbitpos;
107: sbits = 8;
108: } else {
109: bitmap ^= 255 << iib->dbitpos;
110: dbits = 8;
111: }
112: break;
1.1 root 113: case dt_ImmV:
1.1.1.2 root 114: sbits = 12;
115: bitmap ^= 0x0FFF;
116: break;
1.1 root 117: case dt_Ill:
1.1.1.2 root 118: /* no src/dst parameter */
119: break;
1.1 root 120: default:
1.1.1.2 root 121: LOG_CRITICAL(("CPU definition #%d incorrect", i));
122: return 1;
1.1 root 123: }
124: }
125: if (bitmap != 0xFFFF) {
126: LOG_CRITICAL(("CPU definition #%d incorrect (0x%x)", i, bitmap));
127: return 1;
128: }
1.1.1.2 root 129: for (sbit = 0; sbit < (1 << sbits); sbit++) {
130: for (dbit = 0; dbit < (1 << dbits); dbit++) {
131: bitmap = iib->bits | (sbit << iib->sbitpos) | (dbit << iib->dbitpos);
132: if (iib->stype == dt_Imm3 || iib->stype == dt_Imm4
133: || iib->stype == dt_Imm8) {
134: if (sbit == 0 && iib->flags.imm_notzero) {
135: continue;
136: }
137: }
138: if (cpu68k_iibtable[bitmap] != NULL) {
139: LOG_CRITICAL(("CPU definition #%d conflicts (0x%x)", i, bitmap));
140: return 1;
141: }
142: cpu68k_iibtable[bitmap] = iib;
143: /* set both flag and non-flag versions */
144: cpu68k_functable[bitmap * 2] = cpu68k_funcindex[i * 2];
145: cpu68k_functable[bitmap * 2 + 1] = cpu68k_funcindex[i * 2 + 1];
146: cpu68k_totalinstr++;
1.1 root 147: }
148: }
149: }
150:
151: j = 0;
152:
153: for (i = 0; i < 65536; i++) {
154: if (cpu68k_iibtable[i]) {
155: j++;
156: }
157: }
158: if (j != cpu68k_totalinstr) {
159: LOG_CRITICAL(("Instruction count not verified (%d/%d)\n",
1.1.1.2 root 160: cpu68k_totalinstr, i));
1.1 root 161: return 1;
162: }
163:
164: cpu68k_totalfuncs = iibs_num;
165:
166: for (i = 0; i < 256; i++) {
167: for (j = 0; j < 8; j++) {
1.1.1.2 root 168: if (i & (1 << j))
169: break;
1.1 root 170: }
171: movem_bit[i] = j;
172: }
173:
174: LOG_VERBOSE(("CPU: %d instructions supported by %d routines",
1.1.1.2 root 175: cpu68k_totalinstr, cpu68k_totalfuncs));
1.1 root 176: iib = cpu68k_iibtable[0x2F39];
177: return 0;
178: }
179:
1.1.1.2 root 180: void cpu68k_printipc(t_ipc * ipc)
1.1 root 181: {
182: printf("IPC @ 0x%p\n", ipc);
1.1.1.2 root 183: printf(" opcode: %04X, uses %X set %X\n", ipc->opcode, ipc->used,
184: ipc->set);
1.1 root 185: printf(" src = %08X\n", ipc->src);
186: printf(" dst = %08X\n", ipc->dst);
187: }
188:
189: /* fill in ipc */
190:
1.1.1.2 root 191: void cpu68k_ipc(uint32 addr68k, uint8 *addr, t_iib * iib, t_ipc * ipc)
1.1 root 192: {
193: t_type type;
194: uint32 *p;
195:
196: ipc->opcode = LOCENDIAN16(*(uint16 *)addr);
197: ipc->wordlen = 1;
198: if (!iib) {
199: /* illegal instruction, no further details (wordlen must be set to 1) */
200: return;
201: }
202:
203: ipc->used = iib->flags.used;
204: ipc->set = iib->flags.set;
205:
206: if ((iib->mnemonic == i_Bcc) || (iib->mnemonic == i_BSR)) {
207: /* special case - we can calculate the offset now */
208: /* low 8 bits of current instruction are addr+1 */
1.1.1.2 root 209: ipc->src = (sint32)(*(sint8 *)(addr + 1));
1.1 root 210: if (ipc->src == 0) {
1.1.1.2 root 211: ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr + 2));
1.1 root 212: ipc->wordlen++;
213: }
1.1.1.2 root 214: ipc->src += addr68k + 2; /* add PC of next instruction */
1.1 root 215: return;
216: }
217: if (iib->mnemonic == i_DBcc || iib->mnemonic == i_DBRA) {
218: /* special case - we can calculate the offset now */
1.1.1.2 root 219: ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr + 2));
220: ipc->src += addr68k + 2; /* add PC of next instruction */
1.1 root 221: ipc->wordlen++;
222: return;
223: }
224:
1.1.1.2 root 225: addr += 2;
226: addr68k += 2;
1.1 root 227:
228: for (type = 0; type < 2; type++) {
229: if (type == tp_src)
230: p = &(ipc->src);
231: else
232: p = &(ipc->dst);
233:
1.1.1.2 root 234: switch (type == tp_src ? iib->stype : iib->dtype) {
1.1 root 235: case dt_Adis:
236: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
237: ipc->wordlen++;
1.1.1.2 root 238: addr += 2;
239: addr68k += 2;
1.1 root 240: break;
241: case dt_Aidx:
242: *p = (sint32)(sint8)addr[1];
1.1.1.2 root 243: *p = (*p & 0xFFFFFF) | (*addr) << 24;
1.1 root 244: ipc->wordlen++;
1.1.1.2 root 245: addr += 2;
246: addr68k += 2;
1.1 root 247: break;
248: case dt_AbsW:
249: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
250: ipc->wordlen++;
1.1.1.2 root 251: addr += 2;
252: addr68k += 2;
1.1 root 253: break;
254: case dt_AbsL:
1.1.1.2 root 255: *p = (uint32)((LOCENDIAN16(*(uint16 *)addr) << 16) +
256: LOCENDIAN16(*(uint16 *)(addr + 2)));
257: ipc->wordlen += 2;
258: addr += 4;
259: addr68k += 4;
1.1 root 260: break;
261: case dt_Pdis:
262: *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
1.1.1.2 root 263: *p += addr68k; /* add PC of extension word (this word) */
1.1 root 264: ipc->wordlen++;
1.1.1.2 root 265: addr += 2;
266: addr68k += 2;
1.1 root 267: break;
268: case dt_Pidx:
269: *p = ((sint32)(sint8)addr[1]) + addr68k;
1.1.1.2 root 270: *p = (*p & 0xFFFFFF) | (*addr) << 24;
1.1 root 271: ipc->wordlen++;
1.1.1.2 root 272: addr += 2;
273: addr68k += 2;
1.1 root 274: break;
275: case dt_ImmB:
276: /* low 8 bits of next 16 bit word is addr+1 */
1.1.1.2 root 277: *p = (uint32)(*(uint8 *)(addr + 1));
1.1 root 278: ipc->wordlen++;
1.1.1.2 root 279: addr += 2;
280: addr68k += 2;
1.1 root 281: break;
282: case dt_ImmW:
283: *p = (uint32)LOCENDIAN16(*(uint16 *)addr);
284: ipc->wordlen++;
1.1.1.2 root 285: addr += 2;
286: addr68k += 2;
1.1 root 287: break;
288: case dt_ImmL:
1.1.1.2 root 289: *p = (uint32)((LOCENDIAN16(*(uint16 *)addr) << 16) +
290: LOCENDIAN16(*(uint16 *)(addr + 2)));
291: ipc->wordlen += 2;
292: addr += 4;
293: addr68k += 4;
1.1 root 294: break;
295: case dt_Imm3:
296: if (type == tp_src)
1.1.1.2 root 297: *p = (ipc->opcode >> iib->sbitpos) & 7;
1.1 root 298: else
1.1.1.2 root 299: *p = (ipc->opcode >> iib->dbitpos) & 7;
1.1 root 300: break;
301: case dt_Imm4:
302: if (type == tp_src)
1.1.1.2 root 303: *p = (ipc->opcode >> iib->sbitpos) & 15;
1.1 root 304: else
1.1.1.2 root 305: *p = (ipc->opcode >> iib->dbitpos) & 15;
1.1 root 306: break;
307: case dt_Imm8:
308: if (type == tp_src)
1.1.1.2 root 309: *p = (ipc->opcode >> iib->sbitpos) & 255;
1.1 root 310: else
1.1.1.2 root 311: *p = (ipc->opcode >> iib->dbitpos) & 255;
1.1 root 312: break;
313: case dt_Imm8s:
314: if (type == tp_src)
1.1.1.2 root 315: *p = (sint32)(sint8)((ipc->opcode >> iib->sbitpos) & 255);
1.1 root 316: else
1.1.1.2 root 317: *p = (sint32)(sint8)((ipc->opcode >> iib->dbitpos) & 255);
1.1 root 318: break;
319: default:
320: break;
321: }
322: }
323: }
324:
325: t_ipclist *cpu68k_makeipclist(uint32 pc)
326: {
327: int size = 16;
1.1.1.2 root 328: t_ipclist *list = malloc(sizeof(t_ipclist) + 16 * sizeof(t_ipc) + 8);
329: t_ipc *ipc = (t_ipc *) (list + 1);
1.1 root 330: t_iib *iib;
331: int instrs = 0;
332: uint16 required;
333: int i;
334:
335: if (list == NULL)
336: ui_err("Out of memory");
337:
1.1.1.2 root 338: pc &= 0xffffff;
1.1 root 339: list->pc = pc;
340: list->clocks = 0;
341: list->norepeat = 0;
342: do {
343: instrs++;
344: if (instrs > size) {
345: if (size > 10000)
346: ui_err("Something has gone seriously wrong @ %08X", pc);
1.1.1.2 root 347: size += 16;
348: list = realloc(list, sizeof(t_ipclist) + size * sizeof(t_ipc) + 8);
1.1 root 349: if (list == NULL)
350: ui_err("Out of memory whilst making ipc list @ %08X", pc);
1.1.1.2 root 351: ipc = ((t_ipc *) (list + 1)) + instrs - 1;
1.1 root 352: }
353: if (!(iib = cpu68k_iibtable[fetchword(pc)])) {
1.1.1.3 ! root 354: ui_err("Invalid instruction @ %08X [%04X]", pc, fetchword(pc));
1.1 root 355: }
1.1.1.2 root 356: cpu68k_ipc(pc, mem68k_memptr[pc >> 12] (pc), iib, ipc);
357: list->clocks += iib->clocks;
358: pc += (iib->wordlen) << 1;
1.1 root 359: ipc++;
1.1.1.2 root 360: }
361: while (!iib->flags.endblk);
1.1 root 362: *(int *)ipc = 0;
363:
364: if (instrs == 2) {
365: ipc--;
366: if (iib->mnemonic == i_Bcc && ipc->src == list->pc) {
367: /* we have a 2-instruction block ending in a branch to start */
1.1.1.2 root 368: ipc = (t_ipc *) (list + 1);
1.1 root 369: iib = cpu68k_iibtable[ipc->opcode];
370: if (iib->mnemonic == i_TST || iib->mnemonic == i_CMP) {
1.1.1.2 root 371: /* it's a tst/cmp and then a Bcc */
372: if (!(iib->stype == dt_Ainc || iib->stype == dt_Adec)) {
373: /* no change could happen during the block */
374: list->norepeat = 1;
375: }
1.1 root 376: }
377: }
378: }
379:
1.1.1.2 root 380: ipc = ((t_ipc *) (list + 1)) + instrs - 1;
381: required = 0x1F; /* all 5 flags need to be correct at end */
1.1 root 382: for (i = 0; i < instrs; i++) {
1.1.1.2 root 383: ipc->set &= required;
384: required &= ~ipc->set;
385: required |= ipc->used;
1.1 root 386: if (ipc->set) {
1.1.1.2 root 387: ipc->function = cpu68k_functable[(ipc->opcode << 1) + 1];
1.1 root 388: } else {
1.1.1.2 root 389: ipc->function = cpu68k_functable[ipc->opcode << 1];
1.1 root 390: }
391: ipc--;
392: }
393: /* fprintf("Cached %08X to %08X\n", list->pc, pc-((iib->wordlen)<<1)); */
394: return list;
395: }
396:
1.1.1.3 ! root 397: void cpu68k_clearcache(void)
! 398: {
! 399: int i;
! 400:
! 401: for (i = 0; i < LEN_IPCLISTTABLE; i++) {
! 402: if (ipclist[i]) {
! 403: free(ipclist[i]);
! 404: ipclist[i] = NULL;
! 405: }
! 406: }
! 407: }
! 408:
1.1 root 409: void cpu68k_reset(void)
410: {
411: int i;
412:
413: if (!cpu68k_ram) {
1.1.1.2 root 414: /* +4 due to bug in DIRECTRAM hdr/mem68k.h code over-run of buffer */
415: if ((cpu68k_ram = malloc(0x10000 + 4)) == NULL)
1.1 root 416: ui_err("Out of memory");
417: }
418: memset(cpu68k_ram, 0, 0x10000);
419:
420: regs.pc = fetchlong(4);
421: regs.regs[15] = fetchlong(0);
422: regs.sr.sr_int = 0;
1.1.1.2 root 423: regs.sr.sr_struct.s = 1; /* Supervisor mode */
1.1 root 424: regs.stop = 0;
1.1.1.2 root 425: cpu68k_clocks = 0;
426: cpu68k_frames = 0; /* Number of frames */
1.1 root 427:
428: for (i = 0; i < LEN_IPCLISTTABLE; i++) {
429: if (ipclist[i]) {
430: free(ipclist[i]);
431: ipclist[i] = NULL;
432: }
433: }
434: }
435:
436: void cpu68k_endfield(void)
437: {
438: cpu68k_clocks = 0;
439: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.