Annotation of generator/main/cpu68k.c, revision 1.1

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 "mem68k.h"
        !             9: #include "cpu68k.h"
        !            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];
        !            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: unsigned int cpu68k_frozen; /* cpu frozen, do not interrupt, make pending */
        !            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(&regs, 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++) {
        !            59:       switch(j ? iib->stype : iib->dtype) {
        !            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:
        !            67:        if (j) {
        !            68:          bitmap ^= 7<<iib->sbitpos;
        !            69:          sbits = 3;
        !            70:        } else {
        !            71:          bitmap ^= 7<<iib->dbitpos;
        !            72:          dbits = 3;
        !            73:        }
        !            74:        break;
        !            75:       case dt_AbsW:
        !            76:       case dt_AbsL:
        !            77:       case dt_Pdis:
        !            78:       case dt_Pidx:
        !            79:        break;
        !            80:       case dt_ImmB:
        !            81:       case dt_ImmW:
        !            82:       case dt_ImmL:
        !            83:       case dt_ImmS:
        !            84:        break;
        !            85:       case dt_Imm3:
        !            86:        if (j) {
        !            87:          bitmap ^= 7<<iib->sbitpos;
        !            88:          sbits = 3;
        !            89:        } else {
        !            90:          bitmap ^= 7<<iib->dbitpos;
        !            91:          dbits = 3;
        !            92:        }
        !            93:        break;
        !            94:       case dt_Imm4:
        !            95:        if (j) {
        !            96:          bitmap ^= 15<<iib->sbitpos;
        !            97:          sbits = 4;
        !            98:        } else {
        !            99:          bitmap ^= 15<<iib->dbitpos;
        !           100:          dbits = 4;
        !           101:        }
        !           102:        break;
        !           103:       case dt_Imm8:
        !           104:       case dt_Imm8s:
        !           105:        if (j) {
        !           106:          bitmap ^= 255<<iib->sbitpos;
        !           107:          sbits = 8;
        !           108:        } else {
        !           109:          bitmap ^= 255<<iib->dbitpos;
        !           110:          dbits = 8;
        !           111:        }
        !           112:        break;
        !           113:       case dt_ImmV:
        !           114:        sbits = 12;
        !           115:        bitmap ^= 0x0FFF;
        !           116:        break;
        !           117:       case dt_Ill:
        !           118:        /* no src/dst parameter */
        !           119:        break;
        !           120:       default:
        !           121:        LOG_CRITICAL(("CPU definition #%d incorrect", i));
        !           122:        return 1;
        !           123:       }
        !           124:     }
        !           125:     if (bitmap != 0xFFFF) {
        !           126:       LOG_CRITICAL(("CPU definition #%d incorrect (0x%x)", i, bitmap));
        !           127:       return 1;
        !           128:     }
        !           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++;
        !           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",
        !           160:                  cpu68k_totalinstr, i));
        !           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++) {
        !           168:       if (i & 1<<j)
        !           169:        break;
        !           170:     }
        !           171:     movem_bit[i] = j;
        !           172:   }
        !           173: 
        !           174:   LOG_VERBOSE(("CPU: %d instructions supported by %d routines",
        !           175:               cpu68k_totalinstr, cpu68k_totalfuncs));
        !           176:   iib = cpu68k_iibtable[0x2F39];
        !           177:   return 0;
        !           178: }
        !           179: 
        !           180: void cpu68k_printipc(t_ipc *ipc)
        !           181: {
        !           182:   printf("IPC @ 0x%p\n", ipc);
        !           183:   printf("  opcode: %04X, uses %X set %X\n", ipc->opcode, ipc->used, ipc->set);
        !           184:   printf("  src = %08X\n", ipc->src);
        !           185:   printf("  dst = %08X\n", ipc->dst);
        !           186: }
        !           187: 
        !           188: /* fill in ipc */
        !           189: 
        !           190: void cpu68k_ipc(uint32 addr68k, uint8 *addr, t_iib *iib, t_ipc *ipc)
        !           191: {
        !           192:   t_type type;
        !           193:   uint32 *p;
        !           194: 
        !           195:   ipc->opcode = LOCENDIAN16(*(uint16 *)addr);
        !           196:   ipc->wordlen = 1;
        !           197:   if (!iib) {
        !           198:     /* illegal instruction, no further details (wordlen must be set to 1) */
        !           199:     return;
        !           200:   }
        !           201: 
        !           202:   ipc->used = iib->flags.used;
        !           203:   ipc->set = iib->flags.set;
        !           204: 
        !           205:   if ((iib->mnemonic == i_Bcc) || (iib->mnemonic == i_BSR)) {
        !           206:     /* special case - we can calculate the offset now */
        !           207:     /* low 8 bits of current instruction are addr+1 */
        !           208:     ipc->src = (sint32)(*(sint8 *)(addr+1));
        !           209:     if (ipc->src == 0) {
        !           210:       ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr+2));
        !           211:       ipc->wordlen++;
        !           212:     }
        !           213:     ipc->src+= addr68k+2; /* add PC of next instruction */
        !           214:     return;
        !           215:   }
        !           216:   if (iib->mnemonic == i_DBcc || iib->mnemonic == i_DBRA) {
        !           217:     /* special case - we can calculate the offset now */
        !           218:     ipc->src = (sint32)(sint16)LOCENDIAN16(*(uint16 *)(addr+2));
        !           219:     ipc->src+= addr68k+2; /* add PC of next instruction */
        !           220:     ipc->wordlen++;
        !           221:     return;
        !           222:   }
        !           223: 
        !           224:   addr+= 2;
        !           225:   addr68k+= 2;
        !           226: 
        !           227:   for (type = 0; type < 2; type++) {
        !           228:     if (type == tp_src)
        !           229:       p = &(ipc->src);
        !           230:     else
        !           231:       p = &(ipc->dst);
        !           232: 
        !           233:     switch(type == tp_src ? iib->stype : iib->dtype) {
        !           234:     case dt_Adis:
        !           235:       *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
        !           236:       ipc->wordlen++;
        !           237:       addr+= 2;
        !           238:       addr68k+= 2;
        !           239:       break;
        !           240:     case dt_Aidx:
        !           241:       *p = (sint32)(sint8)addr[1];
        !           242:       *p = (*p & 0xFFFFFF) | (*addr)<<24;
        !           243:       ipc->wordlen++;
        !           244:       addr+= 2;
        !           245:       addr68k+= 2;
        !           246:       break;
        !           247:     case dt_AbsW:
        !           248:       *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
        !           249:       ipc->wordlen++;
        !           250:       addr+= 2;
        !           251:       addr68k+= 2;
        !           252:       break;
        !           253:     case dt_AbsL:
        !           254:       *p = (uint32)( (LOCENDIAN16(*(uint16 *)addr)<<16) +
        !           255:                     LOCENDIAN16(*(uint16 *)(addr+2)) );
        !           256:       ipc->wordlen+= 2;
        !           257:       addr+= 4;
        !           258:       addr68k+= 4;
        !           259:       break;
        !           260:     case dt_Pdis:
        !           261:       *p = (sint32)(sint16)LOCENDIAN16(*(uint16 *)addr);
        !           262:       *p+= addr68k; /* add PC of extension word (this word) */
        !           263:       ipc->wordlen++;
        !           264:       addr+= 2;
        !           265:       addr68k+= 2;
        !           266:       break;
        !           267:     case dt_Pidx:
        !           268:       *p = ((sint32)(sint8)addr[1]) + addr68k;
        !           269:       *p = (*p & 0xFFFFFF) | (*addr)<<24;
        !           270:       ipc->wordlen++;
        !           271:       addr+= 2;
        !           272:       addr68k+= 2;
        !           273:       break;
        !           274:     case dt_ImmB:
        !           275:       /* low 8 bits of next 16 bit word is addr+1 */
        !           276:       *p = (uint32)(*(uint8 *)(addr+1));
        !           277:       ipc->wordlen++;
        !           278:       addr+= 2;
        !           279:       addr68k+= 2;
        !           280:       break;
        !           281:     case dt_ImmW:
        !           282:       *p = (uint32)LOCENDIAN16(*(uint16 *)addr);
        !           283:       ipc->wordlen++;
        !           284:       addr+= 2;
        !           285:       addr68k+= 2;
        !           286:       break;
        !           287:     case dt_ImmL:
        !           288:       *p = (uint32)( (LOCENDIAN16(*(uint16 *)addr)<<16) +
        !           289:                     LOCENDIAN16(*(uint16 *)(addr+2)) );
        !           290:       ipc->wordlen+= 2;
        !           291:       addr+= 4;
        !           292:       addr68k+= 4;
        !           293:       break;
        !           294:     case dt_Imm3:
        !           295:       if (type == tp_src)
        !           296:        *p = (ipc->opcode >> iib->sbitpos) & 7;
        !           297:       else
        !           298:        *p = (ipc->opcode >> iib->dbitpos) & 7;
        !           299:       break;
        !           300:     case dt_Imm4:
        !           301:       if (type == tp_src)
        !           302:        *p = (ipc->opcode >> iib->sbitpos) & 15;
        !           303:       else
        !           304:        *p = (ipc->opcode >> iib->dbitpos) & 15;
        !           305:       break;
        !           306:     case dt_Imm8:
        !           307:       if (type == tp_src)
        !           308:        *p = (ipc->opcode >> iib->sbitpos) & 255;
        !           309:       else
        !           310:        *p = (ipc->opcode >> iib->dbitpos) & 255;
        !           311:       break;
        !           312:     case dt_Imm8s:
        !           313:       if (type == tp_src)
        !           314:        *p = (sint32)(sint8)((ipc->opcode >> iib->sbitpos) & 255);
        !           315:       else
        !           316:        *p = (sint32)(sint8)((ipc->opcode >> iib->dbitpos) & 255);
        !           317:       break;
        !           318:     default:
        !           319:       break;
        !           320:     }
        !           321:   }
        !           322: }
        !           323: 
        !           324: t_ipclist *cpu68k_makeipclist(uint32 pc)
        !           325: {
        !           326:   int size = 16;
        !           327:   t_ipclist *list = malloc(sizeof(t_ipclist) + 16*sizeof(t_ipc) + 8);
        !           328:   t_ipc *ipc = (t_ipc *)(list+1);
        !           329:   t_iib *iib;
        !           330:   int instrs = 0;
        !           331:   uint16 required;
        !           332:   int i;
        !           333: 
        !           334:   if (list == NULL)
        !           335:     ui_err("Out of memory");
        !           336: 
        !           337:   pc&= 0xffffff;
        !           338:   list->pc = pc;
        !           339:   list->clocks = 0;
        !           340:   list->norepeat = 0;
        !           341:   do {
        !           342:     instrs++;
        !           343:     if (instrs > size) {
        !           344:       if (size > 10000)
        !           345:         ui_err("Something has gone seriously wrong @ %08X", pc);
        !           346:       size+= 16;
        !           347:       list = realloc(list, sizeof(t_ipclist) + size*sizeof(t_ipc) + 8);
        !           348:       if (list == NULL)
        !           349:         ui_err("Out of memory whilst making ipc list @ %08X", pc);
        !           350:       ipc = ((t_ipc *)(list+1))+instrs-1;
        !           351:     }
        !           352:     if (!(iib = cpu68k_iibtable[fetchword(pc)])) {
        !           353:       ui_err("Invalid instruction @ %08X", pc);
        !           354:     }
        !           355:     cpu68k_ipc(pc, mem68k_memptr[pc>>12](pc), iib, ipc);
        !           356:     list->clocks+= iib->clocks;
        !           357:     pc+= (iib->wordlen)<<1;
        !           358:     ipc++;
        !           359:   } while (!iib->flags.endblk);
        !           360:   *(int *)ipc = 0;
        !           361: 
        !           362:   if (instrs == 2) {
        !           363:     ipc--;
        !           364:     if (iib->mnemonic == i_Bcc && ipc->src == list->pc) {
        !           365:       /* we have a 2-instruction block ending in a branch to start */
        !           366:       ipc = (t_ipc *)(list+1);
        !           367:       iib = cpu68k_iibtable[ipc->opcode];
        !           368:       if (iib->mnemonic == i_TST || iib->mnemonic == i_CMP) {
        !           369:        /* it's a tst/cmp and then a Bcc */
        !           370:        if (!(iib->stype == dt_Ainc || iib->stype == dt_Adec)) {
        !           371:          /* no change could happen during the block */
        !           372:          list->norepeat = 1;
        !           373:        }
        !           374:       }
        !           375:     }
        !           376:   }
        !           377: 
        !           378:   ipc = ((t_ipc *)(list+1))+instrs-1;
        !           379:   required = 0x1F;               /* all 5 flags need to be correct at end */
        !           380:   for (i = 0; i < instrs; i++) {
        !           381:     ipc->set&= required;
        !           382:     required&= ~ipc->set;
        !           383:     required|= ipc->used;
        !           384:     if (ipc->set) {
        !           385:       ipc->function = cpu68k_functable[(ipc->opcode<<1)+1];
        !           386:     } else {
        !           387:       ipc->function = cpu68k_functable[ipc->opcode<<1];
        !           388:     }
        !           389:     ipc--;
        !           390:   }
        !           391:   /* fprintf("Cached %08X to %08X\n", list->pc, pc-((iib->wordlen)<<1)); */
        !           392:   return list;
        !           393: }
        !           394: 
        !           395: void cpu68k_reset(void)
        !           396: {
        !           397:   int i;
        !           398: 
        !           399:   if (!cpu68k_ram) {
        !           400:     if ((cpu68k_ram = malloc(0x10000)) == NULL)
        !           401:       ui_err("Out of memory");
        !           402:   }
        !           403:   memset(cpu68k_ram, 0, 0x10000);
        !           404: 
        !           405:   regs.pc = fetchlong(4);
        !           406:   regs.regs[15] = fetchlong(0);
        !           407:   regs.sr.sr_int = 0;
        !           408:   regs.sr.sr_struct.s = 1; /* Supervisor mode*/
        !           409:   regs.stop = 0;
        !           410:   cpu68k_clocks = 0; 
        !           411:   cpu68k_frames = 0; /* Number of frames */
        !           412: 
        !           413:   for (i = 0; i < LEN_IPCLISTTABLE; i++) {
        !           414:     if (ipclist[i]) {
        !           415:       free(ipclist[i]);
        !           416:       ipclist[i] = NULL;
        !           417:     }
        !           418:   }
        !           419: }
        !           420: 
        !           421: void cpu68k_endfield(void)
        !           422: {
        !           423:   cpu68k_clocks = 0;
        !           424: }

unix.superglobalmegacorp.com

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