⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newcpu.c

📁 树大根深三棱尽所标杆ssfsfsa fdsafs
💻 C
字号:
/*****************************************************************************			       XCopilotThis code is part of XCopilot, a port of copilot     Portions of this code are Copyright (C) 1997 Ivan A. Curtis		       icurtis@radlogic.com.auThe original MS-Windows95 copilot emulator was written by Greg Hewgill.The following copyright notice appeared on the original copilot sources:		  Copyright (c) 1996 Greg Hewgill MC68000 Emulation code is from Bernd Schmidt's Unix Amiga Emulator.       The following copyright notice appeared in those files:	  Original UAE code Copyright (c) 1995 Bernd SchmidtThis code must not be distributed without these copyright notices intact.**************************************************************************************************************************************************************Filename:	newcpu.cDescription:	MC68000 emulationUpdate History:   (most recent first)   Ian Goldberg 10-Apr-97 16:53 -- added support for logging flow traces   I. Curtis    26-Feb-97 15:00 -- modified from win95 version******************************************************************************/#include <assert.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include "sysdeps.h"#include "shared.h"#include "memory.h"#include "custom.h"#include "newcpu.h"#include "dragonball.h"int areg_byteinc[] = { 1,1,1,1,1,1,1,2 };int imm8_table[] = { 8,1,2,3,4,5,6,7 };UWORD *InstructionStart_p;shared_img *Shptr;int exectrace = 0;#ifdef COUNT_INSTRSstatic unsigned long int instrcount[65536];static UWORD opcodenums[65536];int compfn(const void *el1, const void *el2){  return instrcount[*(const UWORD *)el1] < instrcount[*(const UWORD *)el2];}void dump_counts(void){  FILE *f = fopen("insncount", "w");  unsigned long int total = 0;  int i;    for(i=0; i < 65536; i++) {    opcodenums[i] = i;    total += instrcount[i];  }  qsort(opcodenums, 65536, sizeof(UWORD), compfn);    fprintf(f, "Total: %ld\n", total);  for(i=0; i < 65536; i++) {    unsigned long int cnt = instrcount[opcodenums[i]];    if (!cnt)      break;    fprintf(f, "%04x: %ld\n", opcodenums[i], cnt);  }  fclose(f);}#endif#ifdef INTEL_FLAG_OPTunion flagu intel_flag_lookup[256];#endifvoid fatal(char *file, int line){	if (file) {		fprintf(stderr, "Fatal(%s,%d)\n", file, line);		return;	}    Shptr->CpuReq = cpuExit;    exit(1);}UWORD nextiword(void){  UWORD r = *(Shptr->regs).pc_p++;  return r;}ULONG nextilong(void){  ULONG r = *(Shptr->regs).pc_p++;  r = (r << 16) + *(Shptr->regs).pc_p++;  return r;}void MC68000_setpc(CPTR newpc){    if (!get_real_address(newpc)) {	fprintf(stderr, "FATAL: weird setpc(%08lx) at %08lx!\n",	    (unsigned long)newpc, MC68000_getpc());	abort();    }    if (Shptr->logF) {	fprintf(Shptr->logF, "setpc %08lx -> %08lx\n",	    MC68000_getpc(), (unsigned long)newpc);    }    (Shptr->regs).pc = newpc;    (Shptr->regs).pc_p = (Shptr->regs).pc_oldp = get_real_address(newpc);}CPTR MC68000_getpc(void){    return (Shptr->regs).pc +      ((char *)(Shptr->regs).pc_p - (char *)(Shptr->regs).pc_oldp);}void MC68000_setstopped(int stop){    (Shptr->regs).stopped = stop;    if (stop)      specialflags |= SPCFLAG_STOP;}int cctrue(const int cc){  switch(cc) {  case 0: return 1;                       /* T */  case 1: return 0;                       /* F */  case 2: return !CFLG && !ZFLG;          /* HI */  case 3: return CFLG || ZFLG;            /* LS */  case 4: return !CFLG;                   /* CC */  case 5: return CFLG;                    /* CS */  case 6: return !ZFLG;                   /* NE */  case 7: return ZFLG;                    /* EQ */  case 8: return !VFLG;                   /* VC */  case 9: return VFLG;                    /* VS */  case 10:return !NFLG;                   /* PL */  case 11:return NFLG;                    /* MI */  case 12:return NFLG == VFLG;            /* GE */  case 13:return NFLG != VFLG;            /* LT */  case 14:return !ZFLG && (NFLG == VFLG); /* GT */  case 15:return ZFLG || (NFLG != VFLG);  /* LE */  }  fatal(NULL, 0);  return 0;}extern ULONG get_disp_ea (ULONG base, UWORD dp){    int reg = (dp >> 12) & 7;    LONG regd;        if (dp & 0x8000)	regd = (Shptr->regs).a[reg];    else	regd = (Shptr->regs).d[reg];    if (!(dp & 0x800))	regd = (LONG)(WORD)regd;    return base + (BYTE)(dp) + regd;}void MC68000_setshare(shared_img *shptr){  Shptr = shptr;}void MC68000_init(shared_img *shptr){  Shptr = shptr;#ifdef COUNT_INSTRS  memset(instrcount, 0, sizeof instrcount);#endif#ifdef INTEL_FLAG_OPT  for (i = 0; i < 256; i++) {    intel_flag_lookup[i].flags.c = !!(i & 1);    intel_flag_lookup[i].flags.z = !!(i & 64);    intel_flag_lookup[i].flags.n = !!(i & 128);    intel_flag_lookup[i].flags.v = 0;  }#endif  /*    printf("Building CPU table...\n");	read_table68k ();	do_merges ();	for (opcode = 0; opcode < 65536; opcode++)	cpufunctbl[opcode] = op_illg;	for (i = 0; smallcputbl[i].handler != NULL; i++) {	if (!smallcputbl[i].specific)	cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;	}	for (opcode = 0; opcode < 65536; opcode++) {	cpuop_func *f;		if (table68k[opcode].mnemo == i_ILLG)	continue;		if (table68k[opcode].handler != -1) {	f = cpufunctbl[table68k[opcode].handler];	if (f == op_illg)	fatal(NULL, 0);	cpufunctbl[opcode] = f;	}	}		for (i = 0; smallcputbl[i].handler != NULL; i++) {	if (smallcputbl[i].specific)	cpufunctbl[smallcputbl[i].opcode] = smallcputbl[i].handler;	}*/}/************ these two moved into shared_imgstruct regstruct regs;union flagu regflags;********************************************/#if CPU_LEVEL > 1ULONG get_disp_ea (ULONG base, UWORD dp){  int reg = (dp >> 12) & 7;  LONG regd;  if (dp & 0x8000)    regd = (Shptr->regs).a[reg];  else    regd = (Shptr->regs).d[reg];  if (!(dp & 0x800))    regd = (LONG)(WORD)regd;  if (dp & 0x100) {    LONG extraind = 0;    printf("020\n");    regd <<= (dp >> 9) & 3;    if (dp & 0x80)      base = 0;    if (dp & 0x40)      regd = 0;    if ((dp & 0x30) == 0x20)      base += (LONG)(WORD)nextiword();    if ((dp & 0x30) == 0x30)      base += nextilong();        if ((dp & 0x3) == 0x2)      extraind = (LONG)(WORD)nextiword();    if ((dp & 0x3) == 0x3)      extraind = nextilong();        if (!(dp & 4))      base += regd;    if (dp & 3)      base = get_long (base);    if (dp & 4)      base += regd;        return base + extraind;    /* Yikes, that's complicated */  } else {    return base + (BYTE)(dp) + regd;  }}#endifvoid MakeSR(void){#if 0  assert((NFLG & 1) == NFLG);  assert(((Shptr->regs).s & 1) == (Shptr->regs).s);  assert(((Shptr->regs).x & 1) == (Shptr->regs).x);  assert((CFLG & 1) == CFLG);  assert((VFLG & 1) == VFLG);  assert((ZFLG & 1) == ZFLG);#endif  (Shptr->regs).sr = (((Shptr->regs).t << 15) | ((Shptr->regs).s << 13) |		      ((Shptr->regs).intmask << 8) | ((Shptr->regs).x << 4) |		      (NFLG << 3) | (ZFLG << 2) | (VFLG << 1) |  CFLG);}void MakeFromSR(void){  int olds = (Shptr->regs).s;    (Shptr->regs).t = ((Shptr->regs).sr >> 15) & 1;  (Shptr->regs).s = ((Shptr->regs).sr >> 13) & 1;  (Shptr->regs).intmask = ((Shptr->regs).sr >> 8) & 7;  (Shptr->regs).x = ((Shptr->regs).sr >> 4) & 1;  NFLG = ((Shptr->regs).sr >> 3) & 1;  ZFLG = ((Shptr->regs).sr >> 2) & 1;  VFLG = ((Shptr->regs).sr >> 1) & 1;  CFLG = (Shptr->regs).sr & 1;  if (olds != (Shptr->regs).s) {    CPTR temp = (Shptr->regs).usp;    (Shptr->regs).usp = (Shptr->regs).a[7];    (Shptr->regs).a[7] = temp;  }  specialflags |= SPCFLAG_INT;  if ((Shptr->regs).t)    specialflags |= SPCFLAG_TRACE;  else    specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);}void MC68000_exception(int nr){  if (nr < 48 && Shptr->ExceptionFlags[nr] && InstructionStart_p) {    (Shptr->regs).pc_p = InstructionStart_p;    Shptr->CpuState = cpuException + nr;    return;  }  if (nr == 32 + 0xF && do_api(*(Shptr->regs).pc_p)) {    nextiword();    return;  }  MakeSR();  if (!(Shptr->regs).s) {    CPTR temp = (Shptr->regs).usp;    (Shptr->regs).usp = (Shptr->regs).a[7];    (Shptr->regs).a[7] = temp;    (Shptr->regs).s = 1;  }  if (CPU_LEVEL > 0) {    (Shptr->regs).a[7] -= 2;    put_word ((Shptr->regs).a[7], nr * 4);  }  (Shptr->regs).a[7] -= 4;  put_long ((Shptr->regs).a[7], MC68000_getpc ());  (Shptr->regs).a[7] -= 2;  put_word ((Shptr->regs).a[7], (Shptr->regs).sr);  MC68000_setpc(get_long(4*nr));  (Shptr->regs).t = 0;  specialflags &= ~(SPCFLAG_TRACE | SPCFLAG_DOTRACE);}static void MC68000_interrupt(int nr){  assert(nr < 8 && nr >= 0);  MC68000_exception(nr + intbase());      (Shptr->regs).intmask = nr;  specialflags |= SPCFLAG_INT;}void MC68000_reset(void){  (Shptr->regs).a[7] = get_long(0x10c00000);  MC68000_setpc(get_long(0x10c00004));  (Shptr->regs).s = 1;  (Shptr->regs).stopped = 0;  (Shptr->regs).t = 0;  specialflags = 0;  Shptr->CpuState = cpuStopped;  (Shptr->regs).intmask = 7;  customreset();}void op_illg(ULONG opcode){  (Shptr->regs).pc_p--;  if ((opcode & 0xF000) == 0xF000) {    if ((opcode & 0xE00) == 0x200)      MC68000_exception(0xB);    else       switch (opcode & 0x1FF) {      case 0x17:	(Shptr->regs).pc_p+=2;	break;      default:	(Shptr->regs).pc_p++;      }    return;  }  if ((opcode & 0xF000) == 0xA000) {    MC68000_exception(0xA);    return;  }  if (opcode == 0x4AFC) { /* breakpoint */    Shptr->CpuState = cpuBreakpoint;    /*     *     fprintf(stderr, "I - CpuState = cpuBreakpoint\n");     *     fflush(stderr);     */    return;  }  fprintf(stderr, "Illegal instruction: %04x\n", (unsigned int)opcode);fprintf(stderr, "ILL at 0x%x\n", (Shptr->regs).pc);exit(1);  MC68000_exception(4);}void updateisr();void maybe_updateisr();#ifndef DEFPILOTLOG#define DEFPILOTLOG "xcopilot.log"#endifvoid MC68000_run(void){  UWORD opcode;  int i;  Shptr->CpuState = cpuRunning;       /* start running */  for(;;) {// fprintf(stderr, "."); fflush(stderr);    if (Shptr->CpuReq != cpuNone) {   /* check for a request */// fprintf(stderr, "not None %d\n", Shptr->CpuReq); fflush(stderr);      return;			      /* bail out if requested */    }    if (Shptr->dolog == !Shptr->logF) {	/* We need to turn logging on or off */	if (Shptr->dolog) {	    char *pilotdir = getenv("XCOPILOTDIR");	    char *fname = getenv("XCOPILOTLOG");	    char *fbuf = NULL;	    if (!fname) fname = DEFPILOTLOG;	    if (fname[0] != '/' && pilotdir) {		fbuf = malloc(strlen(pilotdir)+strlen(fname)+2);		if (fbuf) {		    sprintf("%s/%s", pilotdir, fname);		    fname = fbuf;		}	    }	    Shptr->logF = fopen(fname, "a");	    if (fbuf) {		free(fbuf);		fbuf = NULL;	    }	} else {	    fclose(Shptr->logF);	    Shptr->logF = NULL;	}    }    InstructionStart_p = (Shptr->regs).pc_p;    if (exectrace ||        check_break(MC68000_getpc())) {#if 1 // def GDB_VERBOSE      fprintf(stderr,"GDB Break\n");#endif      exectrace = gdb_break(MC68000_getpc(),                            (Shptr->regs).sr,                            (Shptr->regs).a,                            (Shptr->regs).d);#if 1 // def GDB_VERBOSE      fprintf(stderr,"GDB %s\n",exectrace ? "step" : "restart");      fflush(stderr);#endif    }    opcode = nextiword();    (*cpufunctbl[opcode])(opcode);    maybe_updateisr();if (buserr) { /* DAVIDM */	int i, j;	fprintf(stderr, "BUSERR at 0x%x\n\r", MC68000_getpc());	fprintf(stderr, "SR 0x%.8x\n\r", (Shptr->regs).sr);	for (i=0;i<8;i++)		fprintf(stderr,"A%d[0x%.8x] ",i,(Shptr->regs).a[i]);	fprintf(stderr,"\n\r");	for (i=0;i<8;i++)		fprintf(stderr,"D%d[0x%.8x] ",i,(Shptr->regs).d[i]);	fprintf(stderr,"\n\r");	for (i = 0; i < 128; ) {		fprintf(stderr, "0x%8x: ", (Shptr->regs).a[7] + i);		for (j = 0; i < 128 && j < 4; j++, i += 4)			if (valid_address((Shptr->regs).a[7] + i, 4))				fprintf(stderr, "0x%8x ", get_long((Shptr->regs).a[7] + i));			else				fprintf(stderr, "%10.10s ", "-");		fprintf(stderr, "\n\r");	}	kill(0, 1);	exit(1);}#ifndef NO_EXCEPTION_3    if (buserr) {      MC68000_exception(3);      buserr = 0;    }#endif    InstructionStart_p = NULL;    do_cycles(0);	    if (specialflags) {      if (specialflags & SPCFLAG_DOTRACE) {	MC68000_exception(9);      }      while (specialflags & SPCFLAG_STOP) {	usleep(100);	maybe_updateisr();	do_cycles(1);	if (specialflags & (SPCFLAG_INT | SPCFLAG_DOINT)){	  int intr = intlev();	  specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);	  if (intr != -1 && intr > (Shptr->regs).intmask) {	    MC68000_interrupt(intr);	    (Shptr->regs).stopped = 0;	    specialflags &= ~SPCFLAG_STOP;	  }	    	}	if (Shptr->CpuState > cpuRunning || Shptr->CpuReq != cpuNone) {// fprintf(stderr, "not None 2 %d, %d\n", Shptr->CpuReq, Shptr->CpuState); fflush(stderr);	  return;	}      }      if (specialflags & SPCFLAG_TRACE) {	specialflags &= ~SPCFLAG_TRACE;	specialflags |= SPCFLAG_DOTRACE;      }            if (specialflags & SPCFLAG_DOINT) {	int intr = intlev();	specialflags &= ~(SPCFLAG_INT | SPCFLAG_DOINT);	if (intr != -1 && intr > (Shptr->regs).intmask) {	  MC68000_interrupt(intr);	  (Shptr->regs).stopped = 0;	}	          }      if (specialflags & SPCFLAG_INT) {	specialflags &= ~SPCFLAG_INT;	specialflags |= SPCFLAG_DOINT;      }      if (specialflags & SPCFLAG_BRK) {	specialflags &= ~SPCFLAG_BRK;	return;		      }    }    if (Shptr->CpuState > cpuRunning) {// fprintf(stderr, "not None 3 %d\n", Shptr->CpuState); fflush(stderr);      return;    }  }}void MC68000_step(void){    specialflags |= SPCFLAG_BRK;    MC68000_run();}void MC68000_skip(CPTR nextpc){    specialflags |= SPCFLAG_BRK;    do {      MC68000_step();    } while (nextpc != MC68000_getpc());    Shptr->CpuState = cpuStopped;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -