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

📄 cpu.cpp

📁 著名的任天堂FC游戏机模拟器VirtuaNes 085版的源码!
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*----------------------------------------------------------------------*/
/*                                                                      */
/*      6502 CPU Core v0.00                                             */
/*                                                           Norix      */
/*                                               written     2000/12/23 */
/*                                               last modify ----/--/-- */
/*----------------------------------------------------------------------*/
/*--------------[ INCLUDE               ]-------------------------------*/
#define	WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "VirtuaNESres.h"

#include "typedef.h"
#include "macro.h"

#include "DebugOut.h"
#include "App.h"
#include "Config.h"

#include "nes.h"
#include "mmu.h"
#include "cpu.h"
#include "apu.h"
#include "rom.h"
#include "mapper.h"

/*--------------[ DEFINE                ]-------------------------------*/
#define	DPCM_SYNCCLOCK	FALSE
/*--------------[ EXTERNAL PROGRAM      ]-------------------------------*/
/*--------------[ EXTERNAL WORK         ]-------------------------------*/
/*--------------[ WORK                  ]-------------------------------*/
/*--------------[ CONST                 ]-------------------------------*/
/*--------------[ PROTOTYPE             ]-------------------------------*/
/*--------------[ PROGRAM               ]-------------------------------*/
// 僆儁僐乕僪
//#define	OP6502(A)	RD6502((A))
//#define	OP6502W(A)	RD6502W((A))

// 僛儘儁乕僕儕乕僪
#define	ZPRD(A)		(RAM[(BYTE)(A)])
//#define	ZPRDW(A)	(*((LPWORD)&RAM[(BYTE)(A)]))
#define	ZPRDW(A)	((WORD)RAM[(BYTE)(A)]+((WORD)RAM[(BYTE)((A)+1)]<<8))

#define	ZPWR(A,V)	{ RAM[(BYTE)(A)]=(V); }
#define	ZPWRW(A,V)	{ *((LPWORD)&RAM[(BYTE)(A)])=(WORD)(V); }

// 僒僀僋儖僇僂儞僞
#define	ADD_CYCLE(V)	{ exec_cycles += (V); }
//#define	ADD_CYCLE(V)	{}

// EFFECTIVE ADDRESS儁乕僕嫬奅挻偊僠僃僢僋
#define	CHECK_EA()	{ if( (ET&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); }
//#define	CHECK_EA()	{ if( (R.PC&0xFF00) != (EA&0xFF00) ) ADD_CYCLE(1); }
//#define	CHECK_EA()	{}

// 僼儔僌憖嶌
// 僛儘乛僱僈僥傿僽僼儔僌偺僠僃僢僋偲愝掕
#define	SET_ZN_FLAG(A)	{ R.P &= ~(Z_FLAG|N_FLAG); R.P |= ZN_Table[(BYTE)(A)]; }

// 僼儔僌僙僢僩
#define	SET_FLAG(V)	{ R.P |=  (V); }
// 僼儔僌僋儕傾
#define	CLR_FLAG(V)	{ R.P &= ~(V); }
// 僼儔僌僥僗僩仌僙僢僩乛僋儕傾
#define	TST_FLAG(F,V)	{ R.P &= ~(V); if((F)) R.P |= (V); }
// 僼儔僌僠僃僢僋
#define	CHK_FLAG(V)	(R.P&(V))

// WT .... WORD TEMP
// EA .... EFFECTIVE ADDRESS
// ET .... EFFECTIVE ADDRESS TEMP
// DT .... DATA

#define	MR_IM()	{		\
	DT = OP6502( R.PC++ );	\
}
#define	MR_ZP()	{		\
	EA = OP6502( R.PC++ );	\
	DT = ZPRD( EA );	\
}
#define	MR_ZX()	{		\
	DT = OP6502( R.PC++ );	\
	EA = (BYTE)(DT + R.X);	\
	DT = ZPRD( EA );	\
}
#define	MR_ZY()	{		\
	DT = OP6502( R.PC++ );	\
	EA = (BYTE)(DT + R.Y);	\
	DT = ZPRD( EA );	\
}
#define	MR_AB()	{		\
	EA = OP6502W( R.PC );	\
	R.PC += 2;		\
	DT = RD6502( EA );	\
}
#define	MR_AX()	{		\
	ET = OP6502W( R.PC );	\
	R.PC += 2;		\
	EA = ET + (WORD)R.X;	\
	DT = RD6502( EA );	\
}
#define	MR_AY()	{		\
	ET = OP6502W( R.PC );	\
	R.PC += 2;		\
	EA = ET + (WORD)R.Y;	\
	DT = RD6502( EA );	\
}
#define	MR_IX()	{		\
	DT = OP6502( R.PC++ );	\
	EA = ZPRDW( DT + R.X );	\
	DT = RD6502( EA );	\
}
#define	MR_IY()	{		\
	DT = OP6502( R.PC++ );	\
	ET = ZPRDW( DT );	\
	EA = ET + (WORD)R.Y;	\
	DT = RD6502( EA );	\
}

// EFFECTIVE ADDRESS
#define	EA_ZP()	{		\
	EA = OP6502( R.PC++ );	\
}
#define	EA_ZX()	{		\
	DT = OP6502( R.PC++ );	\
	EA = (BYTE)(DT + R.X);	\
}
#define	EA_ZY()	{		\
	DT = OP6502( R.PC++ );	\
	EA = (BYTE)(DT + R.Y);	\
}
#define	EA_AB()	{		\
	EA = OP6502W( R.PC );	\
	R.PC += 2;		\
}
#define	EA_AX()	{		\
	ET = OP6502W( R.PC );	\
	R.PC += 2;		\
	EA = ET + R.X;		\
}
#define	EA_AY()	{		\
	ET = OP6502W( R.PC );	\
	R.PC += 2;		\
	EA = ET + R.Y;		\
}
#define	EA_IX()	{		\
	DT = OP6502( R.PC++ );	\
	EA = ZPRDW( DT + R.X );	\
}
#define	EA_IY()	{		\
	DT = OP6502( R.PC++ );	\
	ET = ZPRDW( DT );	\
	EA = ET + (WORD)R.Y;	\
}

// 儊儌儕儔僀僩
#define	MW_ZP()		ZPWR(EA,DT)
#define	MW_EA()		WR6502(EA,DT)

// STACK憖嶌
#define	PUSH(V)		{ STACK[(R.S--)&0xFF]=(V); }
#define	POP()		STACK[(++R.S)&0xFF]

// 嶼弍墘嶼宯
/* ADC (NV----ZC) */
#define	ADC() {							\
	WT = R.A+DT+(R.P&C_FLAG);				\
	TST_FLAG( WT > 0xFF, C_FLAG );				\
	TST_FLAG( ((~(R.A^DT))&(R.A^WT)&0x80), V_FLAG );	\
	R.A = (BYTE)WT;						\
	SET_ZN_FLAG(R.A);					\
}

/* SBC (NV----ZC) */
#define	SBC() {						\
	WT = R.A-DT-(~R.P&C_FLAG);			\
	TST_FLAG( ((R.A^DT) & (R.A^WT)&0x80), V_FLAG );	\
	TST_FLAG( WT < 0x100, C_FLAG );			\
	R.A = (BYTE)WT;					\
	SET_ZN_FLAG(R.A);				\
}

/* INC (N-----Z-) */
#define	INC() {			\
	DT++;			\
	SET_ZN_FLAG(DT);	\
}
/* INX (N-----Z-) */
#define	INX() {			\
	R.X++;			\
	SET_ZN_FLAG(R.X);	\
}
/* INY (N-----Z-) */
#define	INY() {			\
	R.Y++;			\
	SET_ZN_FLAG(R.Y);	\
}

/* DEC (N-----Z-) */
#define	DEC() {			\
	DT--;			\
	SET_ZN_FLAG(DT);	\
}
/* DEX (N-----Z-) */
#define	DEX() {			\
	R.X--;			\
	SET_ZN_FLAG(R.X);	\
}
/* DEY (N-----Z-) */
#define	DEY() {			\
	R.Y--;			\
	SET_ZN_FLAG(R.Y);	\
}

// 榑棟墘嶼宯
/* AND (N-----Z-) */
#define	AND() {			\
	R.A &= DT;		\
	SET_ZN_FLAG(R.A);	\
}

/* ORA (N-----Z-) */
#define	ORA() {			\
	R.A |= DT;		\
	SET_ZN_FLAG(R.A);	\
}

/* EOR (N-----Z-) */
#define	EOR() {			\
	R.A ^= DT;		\
	SET_ZN_FLAG(R.A);	\
}

/* ASL_A (N-----ZC) */
#define	ASL_A() {			\
	TST_FLAG( R.A&0x80, C_FLAG );	\
	R.A <<= 1;			\
	SET_ZN_FLAG(R.A);		\
}

/* ASL (N-----ZC) */
#define	ASL() {				\
	TST_FLAG( DT&0x80, C_FLAG );	\
	DT <<= 1;			\
	SET_ZN_FLAG(DT);		\
}

/* LSR_A (N-----ZC) */
#define	LSR_A() {			\
	TST_FLAG( R.A&0x01, C_FLAG );	\
	R.A >>= 1;			\
	SET_ZN_FLAG(R.A);		\
}
/* LSR (N-----ZC) */
#define	LSR() {				\
	TST_FLAG( DT&0x01, C_FLAG );	\
	DT >>= 1;			\
	SET_ZN_FLAG(DT);		\
}

/* ROL_A (N-----ZC) */
#define	ROL_A() {				\
	if( R.P & C_FLAG ) {			\
		TST_FLAG(R.A&0x80,C_FLAG);	\
		R.A = (R.A<<1)|0x01;		\
	} else {				\
		TST_FLAG(R.A&0x80,C_FLAG);	\
		R.A <<= 1;			\
	}					\
	SET_ZN_FLAG(R.A);			\
}
/* ROL (N-----ZC) */
#define	ROL() {					\
	if( R.P & C_FLAG ) {			\
		TST_FLAG(DT&0x80,C_FLAG);	\
		DT = (DT<<1)|0x01;		\
	} else {				\
		TST_FLAG(DT&0x80,C_FLAG);	\
		DT <<= 1;			\
	}					\
	SET_ZN_FLAG(DT);			\
}

/* ROR_A (N-----ZC) */
#define	ROR_A() {				\
	if( R.P & C_FLAG ) {			\
		TST_FLAG(R.A&0x01,C_FLAG);	\
		R.A = (R.A>>1)|0x80;		\
	} else {				\
		TST_FLAG(R.A&0x01,C_FLAG);	\
		R.A >>= 1;			\
	}					\
	SET_ZN_FLAG(R.A);			\
}
/* ROR (N-----ZC) */
#define	ROR() {					\
	if( R.P & C_FLAG ) {			\
		TST_FLAG(DT&0x01,C_FLAG);	\
		DT = (DT>>1)|0x80;		\
	} else {				\
		TST_FLAG(DT&0x01,C_FLAG);	\
		DT >>= 1;			\
	}					\
	SET_ZN_FLAG(DT);			\
}

/* BIT (NV----Z-) */
#define	BIT() {					\
	TST_FLAG( (DT&R.A)==0, Z_FLAG );	\
	TST_FLAG( DT&0x80, N_FLAG );		\
	TST_FLAG( DT&0x40, V_FLAG );		\
}

// 儘乕僪乛僗僩傾宯
/* LDA (N-----Z-) */
#define	LDA()	{ R.A = DT; SET_ZN_FLAG(R.A); }
/* LDX (N-----Z-) */
#define	LDX()	{ R.X = DT; SET_ZN_FLAG(R.X); }
/* LDY (N-----Z-) */
#define	LDY()	{ R.Y = DT; SET_ZN_FLAG(R.Y); }

/* STA (--------) */
#define	STA()	{ DT = R.A; }
/* STX (--------) */
#define	STX()	{ DT = R.X; }
/* STY (--------) */
#define	STY()	{ DT = R.Y; }

/* TAX (N-----Z-) */
#define	TAX()	{ R.X = R.A; SET_ZN_FLAG(R.X); }
/* TXA (N-----Z-) */
#define	TXA()	{ R.A = R.X; SET_ZN_FLAG(R.A); }
/* TAY (N-----Z-) */
#define	TAY()	{ R.Y = R.A; SET_ZN_FLAG(R.Y); }
/* TYA (N-----Z-) */
#define	TYA()	{ R.A = R.Y; SET_ZN_FLAG(R.A); }
/* TSX (N-----Z-) */
#define	TSX()	{ R.X = R.S; SET_ZN_FLAG(R.X); }
/* TXS (--------) */
#define	TXS()	{ R.S = R.X; }

// 斾妑宯
/* CMP (N-----ZC) */
#define	CMP_() {				\
	WT = (WORD)R.A - (WORD)DT;		\
	TST_FLAG( (WT&0x8000)==0, C_FLAG );	\
	SET_ZN_FLAG( (BYTE)WT );		\
}
/* CPX (N-----ZC) */
#define	CPX() {					\
	WT = (WORD)R.X - (WORD)DT;		\
	TST_FLAG( (WT&0x8000)==0, C_FLAG );	\
	SET_ZN_FLAG( (BYTE)WT );		\
}
/* CPY (N-----ZC) */
#define	CPY() {					\
	WT = (WORD)R.Y - (WORD)DT;		\
	TST_FLAG( (WT&0x8000)==0, C_FLAG );	\
	SET_ZN_FLAG( (BYTE)WT );		\
}

// 僕儍儞僾乛儕僞乕儞宯
#if	1
#define	JMP_ID() {				\
	WT = OP6502W(R.PC);			\
	EA = RD6502(WT);			\
	WT = (WT&0xFF00)|((WT+1)&0x00FF);	\
	R.PC = EA+RD6502(WT)*0x100;		\
}
#else
#define	JMP_ID() {		\
	ET = OP6502W(R.PC);	\
	EA = RD6502W(ET);	\
	R.PC = EA;		\
}
#endif
#define	JMP() {			\
	R.PC = OP6502W( R.PC );	\
}
#define	JSR() {			\
	EA = OP6502W( R.PC );	\
	R.PC++;			\
	PUSH( R.PC>>8 );	\
	PUSH( R.PC&0xFF );	\
	R.PC = EA;		\
}
#define	RTS() {			\
	R.PC  = POP();		\
	R.PC |= POP()*0x0100;	\
	R.PC++;			\
}
#define	RTI() {			\
	R.P   = POP() | R_FLAG;	\
	R.PC  = POP();		\
	R.PC |= POP()*0x0100;	\
}
#define	_NMI() {			\
	PUSH( R.PC>>8 );		\
	PUSH( R.PC&0xFF );		\
	CLR_FLAG( B_FLAG );		\
	PUSH( R.P );			\
	SET_FLAG( I_FLAG );		\
	R.PC = RD6502W(NMI_VECTOR);	\
	exec_cycles += 7;		\
}
#define	_IRQ() {			\
	PUSH( R.PC>>8 );		\
	PUSH( R.PC&0xFF );		\
	CLR_FLAG( B_FLAG );		\
	PUSH( R.P );			\
	SET_FLAG( I_FLAG );		\
	R.PC = RD6502W(IRQ_VECTOR);	\
	exec_cycles += 7;		\
}
#define	BRK() {				\
	R.PC++;				\
	PUSH( R.PC>>8 );		\
	PUSH( R.PC&0xFF );		\
	SET_FLAG( B_FLAG );		\
	PUSH( R.P );			\
	SET_FLAG( I_FLAG );		\
	R.PC = RD6502W(IRQ_VECTOR);	\
}

#if	1
#define	REL_JUMP() {		\
	ET = R.PC;		\
	EA = R.PC + (SBYTE)DT;	\
	R.PC = EA;		\
	ADD_CYCLE(1);		\
	CHECK_EA();		\
}
#else
#define	REL_JUMP() {			\
	R.PC = R.PC + (SBYTE)DT;	\
	ADD_CYCLE(1);			\
}
#endif

#define	BCC()	{ if( !(R.P & C_FLAG) ) REL_JUMP(); }
#define	BCS()	{ if(  (R.P & C_FLAG) ) REL_JUMP(); }
#define	BNE()	{ if( !(R.P & Z_FLAG) ) REL_JUMP(); }
#define	BEQ()	{ if(  (R.P & Z_FLAG) ) REL_JUMP(); }
#define	BPL()	{ if( !(R.P & N_FLAG) ) REL_JUMP(); }
#define	BMI()	{ if(  (R.P & N_FLAG) ) REL_JUMP(); }
#define	BVC()	{ if( !(R.P & V_FLAG) ) REL_JUMP(); }
#define	BVS()	{ if(  (R.P & V_FLAG) ) REL_JUMP(); }

// 僼儔僌惂屼宯
#define	CLC()	{ R.P &= ~C_FLAG; }
#define	CLD()	{ R.P &= ~D_FLAG; }
#define	CLI()	{ R.P &= ~I_FLAG; }
#define	CLV()	{ R.P &= ~V_FLAG; }
#define	SEC()	{ R.P |= C_FLAG; }
#define	SED()	{ R.P |= D_FLAG; }
#define	SEI()	{ R.P |= I_FLAG; }

// Unofficial柦椷
#define	ANC()	{			\
	R.A &= DT;			\
	SET_ZN_FLAG( R.A );		\
	TST_FLAG( R.P&N_FLAG, C_FLAG );	\
}

#define	ANE()	{			\
	R.A = (R.A|0xEE)&R.X&DT;	\
	SET_ZN_FLAG( R.A );		\
}

#define	ARR()	{				\
	DT &= R.A;				\
	R.A = (DT>>1)|((R.P&C_FLAG)<<7);	\
	SET_ZN_FLAG( R.A );			\
	TST_FLAG( R.A&0x40, C_FLAG );		\
	TST_FLAG( (R.A>>6)^(R.A>>5), V_FLAG );	\
}

#define	ASR()	{			\
	DT &= R.A;			\
	TST_FLAG( DT&0x01, C_FLAG );	\
	R.A = DT>>1;			\
	SET_ZN_FLAG( R.A );		\
}

#define	DCP()	{			\
	DT--;				\
	CMP_();				\
}

#define	DOP()	{			\
	R.PC++;				\
}

#define	ISB()	{			\
	DT++;				\
	SBC();				\
}

#define	LAS()	{			\
	R.A = R.X = R.S = (R.S & DT);	\
	SET_ZN_FLAG( R.A );		\
}

#define	LAX()	{			\
	R.A = DT;			\
	R.X = R.A;			\
	SET_ZN_FLAG( R.A );		\
}

#define	LXA()	{			\
	R.A = R.X = ((R.A|0xEE)&DT);	\
	SET_ZN_FLAG( R.A );		\
}

#define	RLA()	{				\
	if( R.P & C_FLAG ) {			\
		TST_FLAG( DT&0x80, C_FLAG );	\
		DT = (DT<<1)|1;			\
	} else {				\
		TST_FLAG( DT&0x80, C_FLAG );	\
		DT <<= 1;			\
	}					\
	R.A &= DT;				\
	SET_ZN_FLAG( R.A );			\
}

#define	RRA()	{				\
	if( R.P & C_FLAG ) {			\
		TST_FLAG( DT&0x01, C_FLAG );	\
		DT = (DT>>1)|0x80;		\
	} else {				\
		TST_FLAG( DT&0x01, C_FLAG );	\
		DT >>= 1;			\
	}					\
	ADC();					\
}

#define	SAX()	{			\
	DT = R.A & R.X;			\
}

#define	SBX()	{			\
	WT = (R.A&R.X)-DT;		\
	TST_FLAG( WT < 0x100, C_FLAG );	\
	R.X = WT&0xFF;			\
	SET_ZN_FLAG( R.X );		\
}

#define	SHA()	{				\
	DT = R.A & R.X & (BYTE)((EA>>8)+1);	\
}

#define	SHS()	{			\
	R.S = R.A & R.X;		\
	DT = R.S & (BYTE)((EA>>8)+1);	\
}

#define	SHX()	{			\
	DT = R.X & (BYTE)((EA>>8)+1);	\
}

#define	SHY()	{			\
	DT = R.Y & (BYTE)((EA>>8)+1);	\
}

#define	SLO()	{			\
	TST_FLAG( DT&0x80, C_FLAG );	\
	DT <<= 1;			\
	R.A |= DT;			\
	SET_ZN_FLAG( R.A );		\
}

#define	SRE()	{			\
	TST_FLAG( DT&0x01, C_FLAG );	\
	DT >>= 1;			\
	R.A ^= DT;			\
	SET_ZN_FLAG( R.A );		\
}

#define	TOP()	{			\
	R.PC += 2;			\
}

//
// 僐儞僗僩儔僋僞/僨僗僩儔僋僞
//
//CPU::CPU( NES* parent )
CPU::CPU( NES* parent ) : nes(parent)
{
//	nes = parent;
	m_bClockProcess = FALSE;
}

CPU::~CPU()
{
}

// 儊儌儕傾僋僙僗
//#define	OP6502(A)	(CPU_MEM_BANK[(A)>>13][(A)&0x1FFF])
//#define	OP6502W(A)	(*((WORD*)&CPU_MEM_BANK[(A)>>13][(A)&0x1FFF]))

#if	0
#define	OP6502(A)	RD6502((A))
#define	OP6502W(A)	RD6502W((A))
#else
inline	BYTE	OP6502( WORD addr )
{
	return	CPU_MEM_BANK[addr>>13][addr&0x1FFF];

⌨️ 快捷键说明

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