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

📄 m6805.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** m6805: Portable 6805 emulator ******************************************

    m6805.c

	References:

		6809 Simulator V09, By L.C. Benschop, Eidnhoven The Netherlands.

		m6809: Portable 6809 emulator, DS (6809 code in MAME, derived from
			the 6809 Simulator V09)

		6809 Microcomputer Programming & Interfacing with Experiments"
			by Andrew C. Staugaard, Jr.; Howard W. Sams & Co., Inc.

	System dependencies:	word must be 16 bit unsigned int
							byte must be 8 bit unsigned int
							long must be more than 16 bits
							arrays up to 65536 bytes must be supported
							machine must be twos complement

*****************************************************************************/


#include <stdio.h>
#include <stdlib.h>
#include "m6805.h"
#include "driver.h"

/* 6805 registers */
static byte cc,areg,xreg,sreg;
static word pcreg;

static word eaddr; /* effective address */
static int pending_interrupts;

/* public globals */
int m6805_ICount=50000;
int m6805_Flags;	/* flags for speed optimization */

/* handlers for speed optimization */
static int (*rd_s_handler)(int);
static int (*rd_s_handler_wd)(int);
static void (*wr_s_handler)(int,int);
static void (*wr_s_handler_wd)(int,int);

/* DS -- THESE ARE RE-DEFINED IN m6805.h TO RAM, ROM or FUNCTIONS IN cpuintrf.c */
#define M_RDMEM(A)      M6805_RDMEM((A)&0x7ff)
#define M_WRMEM(A,V)    M6805_WRMEM((A)&0x7ff,V)
#define M_RDOP(A)       M6805_RDOP((A)&0x7ff)
#define M_RDOP_ARG(A)   M6805_RDOP_ARG((A)&0x7ff)

/* macros to tweak the PC and SP */
#define SP_ADJUST(s) ((s)=((s)&0x07f)|0x60)

/* macros to access memory */
#define IMMBYTE(b) {b=M_RDOP_ARG(pcreg++);}
#define IMMWORD(w) {w = (M_RDOP_ARG(pcreg)<<8) + M_RDOP_ARG(pcreg+1); pcreg+=2;}

#define PUSHBYTE(b) {(*wr_s_handler)(sreg,b);sreg--;SP_ADJUST(sreg);}
#define PUSHWORD(w) {sreg--;(*wr_s_handler_wd)(sreg,w);sreg--;SP_ADJUST(sreg);}
#define PULLBYTE(b) {sreg++;SP_ADJUST(sreg);b=(*rd_s_handler)(sreg);}
#define PULLWORD(w) {sreg++;SP_ADJUST(sreg);w=(*rd_s_handler_wd)(sreg);sreg++;}

/* CC masks      H INZC
              7654 3210	*/
#define CFLAG 0x01
#define ZFLAG 0x02
#define NFLAG 0x04
#define IFLAG 0x08
#define HFLAG 0x10

#define CLR_NZ    cc&=~(NFLAG|ZFLAG)
#define CLR_HNZC  cc&=~(HFLAG|NFLAG|ZFLAG|CFLAG)
#define CLR_Z     cc&=~(ZFLAG)
#define CLR_NZC   cc&=~(NFLAG|ZFLAG|CFLAG)
#define CLR_ZC    cc&=~(ZFLAG|CFLAG)

/* macros for CC -- CC bits affected should be reset before calling */
#define SET_Z(a)       if(!a)SEZ
#define SET_Z8(a)      SET_Z((byte)a)
#define SET_N8(a)      cc|=((a&0x80)>>5)
#define SET_H(a,b,r)   cc|=((a^b^r)&0x10)
#define SET_C8(a)      cc|=((a&0x100)>>8)

static byte flags8i[256]=	/* increment */
{
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
};
static byte flags8d[256]= /* decrement */
{
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,
0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04
};
#define SET_FLAGS8I(a)		{cc|=flags8i[(a)&0xff];}
#define SET_FLAGS8D(a)		{cc|=flags8d[(a)&0xff];}

/* combos */
#define SET_NZ8(a)			{SET_N8(a);SET_Z(a);}
#define SET_FLAGS8(a,b,r)	{SET_N8(r);SET_Z8(r);SET_C8(r);}

/* for treating an unsigned byte as a signed word */
#define SIGNED(b) ((word)(b&0x80?b|0xff00:b))

/* Macros for addressing modes */
#define DIRECT IMMBYTE(eaddr)
#define IMM8 eaddr=pcreg++
#define EXTENDED IMMWORD(eaddr)
#define INDEXED eaddr=xreg
#define INDEXED1 {IMMBYTE(eaddr);eaddr+=xreg;}
#define INDEXED2 {IMMWORD(eaddr);eaddr+=xreg;}

/* macros to set status flags */
#define SEC cc|=CFLAG
#define CLC cc&=~CFLAG
#define SEZ cc|=ZFLAG
#define CLZ cc&=~ZFLAG
#define SEN cc|=NFLAG
#define CLN cc&=~NFLAG
#define SEH cc|=HFLAG
#define CLH cc&=~HFLAG
#define SEI cc|=IFLAG
#define CLI cc&=~IFLAG

/* macros for convenience */
#define DIRBYTE(b) {DIRECT;b=M_RDMEM(eaddr);}
#define EXTBYTE(b) {EXTENDED;b=M_RDMEM(eaddr);}
#define IDXBYTE(b) {INDEXED;b=M_RDMEM(eaddr);}
#define IDX1BYTE(b) {INDEXED1;b=M_RDMEM(eaddr);}
#define IDX2BYTE(b) {INDEXED2;b=M_RDMEM(eaddr);}
/* Macros for branch instructions */
#define BRANCH(f) {IMMBYTE(t);if(f){pcreg+=SIGNED(t);}}

/* what they say it is ... */
static unsigned char cycles1[] =
{
      /* 0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F */
  /*0*/ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
  /*1*/  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  /*2*/  4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  /*3*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 6, 0, 6, 6, 0,
  /*4*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
  /*5*/  4, 0, 0, 4, 4, 0, 4, 4, 4, 4, 4, 0, 4, 4, 0, 4,
  /*6*/  7, 0, 0, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, 0, 7,
  /*7*/  6, 0, 0, 6, 6, 0, 6, 6, 6, 6, 6, 0, 6, 6, 0, 6,
  /*8*/  9, 6, 0,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  /*9*/  0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 2,
  /*A*/  2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 0, 8, 2, 0,
  /*B*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5,
  /*C*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
  /*D*/  6, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 5, 9, 6, 7,
  /*E*/  5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 4, 8, 5, 6,
  /*F*/  4, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 3, 7, 4, 5
};


static int rd_slow( int addr )
{
    return M_RDMEM(addr);
}

static int rd_slow_wd( int addr )
{
    return( (M_RDMEM(addr)<<8) | (M_RDMEM(addr+1)) );
}

static int rd_fast( int addr )
{
	extern unsigned char *RAM;

	return RAM[addr&0x7ff];
}

static int rd_fast_wd( int addr )
{
	extern unsigned char *RAM;

	return( (RAM[addr&0x7ff]<<8) | (RAM[(addr+1)&0x7ff]) );
}

static void wr_slow( int addr, int v )
{
	M_WRMEM(addr,v);
}

static void wr_slow_wd( int addr, int v )
{
	M_WRMEM(addr,v>>8);
	M_WRMEM((addr)+1,v&255);
}

static void wr_fast( int addr, int v )
{
	extern unsigned char *RAM;

	RAM[addr&0x7ff] = v;
}

static void wr_fast_wd( int addr, int v )
{
	extern unsigned char *RAM;

	RAM[addr&0x7ff] = v>>8;
	RAM[(addr+1)&0x7ff] = v&255;
}

INLINE unsigned M_RDMEM_WORD (dword A)
{
	int i;

    i = M_RDMEM(A)<<8;
    i |= M_RDMEM((A)+1);
	return i;
}

INLINE void M_WRMEM_WORD (dword A,word V)
{
	M_WRMEM (A,V>>8);
	M_WRMEM ((A)+1,V&255);
}


/****************************************************************************/
/* Set all registers to given values                                        */
/****************************************************************************/
void m6805_SetRegs(m6805_Regs *Regs)
{
	pcreg = Regs->pc;
	sreg = Regs->s;
	xreg = Regs->x;
	areg = Regs->a;
	cc = Regs->cc;

	pending_interrupts = Regs->pending_interrupts;
}


/****************************************************************************/
/* Get all registers in given buffer                                        */
/****************************************************************************/
void m6805_GetRegs(m6805_Regs *Regs)
{
	Regs->pc = pcreg;
	Regs->s = sreg;
	Regs->x = xreg;
	Regs->a = areg;
	Regs->cc = cc;

	Regs->pending_interrupts = pending_interrupts;
}


/****************************************************************************/
/* Return program counter                                                   */
/****************************************************************************/
unsigned m6805_GetPC(void)
{
	return pcreg & 0x7ff;	/* NS 980731 */
}


/* Generate interrupts */
INLINE void Interrupt(void)
{
	if ((pending_interrupts & M6805_INT_IRQ) != 0 && (cc & IFLAG) == 0)
	{
		pending_interrupts &= ~M6805_INT_IRQ;

		/* standard IRQ */
		PUSHWORD(pcreg|0xf800)
		PUSHBYTE(xreg)
		PUSHBYTE(areg)
		PUSHBYTE(cc)
		SEI;
		pcreg=M_RDMEM_WORD(0x07fa);
		m6805_ICount -= 11;
	}
}


void m6805_reset(void)
{
	pcreg = M_RDMEM_WORD(0x07fe);

	cc = 0x00;    /* Clear all flags */
	SEI;          /* IRQ disabled */

⌨️ 快捷键说明

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