Annotation of generator/src/cpu68k.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.