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

📄 k6502.cpp

📁 游戏模拟器InfoNes的原代码。有兴趣的可以将它移植到linux下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*===================================================================*//*                                                                   *//*  K6502.cpp : 6502 Emulator                                        *//*                                                                   *//*  2000/5/10   InfoNES Project ( based on pNesX )                   *//*                                                                   *//*===================================================================*//*-------------------------------------------------------------------*//*  Include files                                                    *//*-------------------------------------------------------------------*/#include "K6502.h"
#include "InfoNES.h"#include "InfoNES_System.h"/*-------------------------------------------------------------------*//*  Operation Macros                                                 *//*-------------------------------------------------------------------*//* Clock Op.  */#define CLK(a)   g_wPassedClocks += (a);/* Addressing Op.  *//* Address  *//* (Indirect,X)  */#define AA_IX    K6502_ReadZpW( K6502_Read_Code( PC++ ) + X )/* (Indirect),Y  */#define AA_IY    K6502_ReadZpW( K6502_Read_Code( PC++ ) ) + Y/* Zero Page  */#define AA_ZP    K6502_Read_Code( PC++ )/* Zero Page,X  */#define AA_ZPX   (BYTE)( K6502_Read_Code( PC++ ) + X )/* Zero Page,Y  */#define AA_ZPY   (BYTE)( K6502_Read_Code( PC++ ) + Y )/* Absolute  */#define AA_ABS   ( K6502_Read_Code( PC++ ) | (WORD)K6502_Read_Code( PC++ ) << 8 )
/* Absolute2 ( PC-- )  */#define AA_ABS2  ( K6502_Read_Code( PC++ ) | (WORD)K6502_Read_Code( PC ) << 8 )/* Absolute,X  */#define AA_ABSX  AA_ABS + X/* Absolute,Y  */#define AA_ABSY  AA_ABS + Y/* Data  *//* (Indirect,X)  */#define A_IX    K6502_Read( AA_IX )/* (Indirect),Y  */#define A_IY    K6502_ReadIY()/* Zero Page  */#define A_ZP    K6502_ReadZp( AA_ZP )/* Zero Page,X  */#define A_ZPX   K6502_ReadZp( AA_ZPX )/* Zero Page,Y  */#define A_ZPY   K6502_ReadZp( AA_ZPY )/* Absolute  */#define A_ABS   K6502_Read( AA_ABS )/* Absolute,X  */#define A_ABSX  K6502_ReadAbsX()/* Absolute,Y  */#define A_ABSY  K6502_ReadAbsY()/* Immediate  */#define A_IMM   K6502_Read_Code( PC++ )/* Flag Op.  */#define SETF(a)  F |= (a)#define RSTF(a)  F &= ~(a)#define TEST(a)  RSTF( FLAG_N | FLAG_Z ); SETF( g_byTestTable[ a ] )/* Load & Store Op.  */#define STA(a)    K6502_Write( (a), A );#define STX(a)    K6502_Write( (a), X );#define STY(a)    K6502_Write( (a), Y );#define LDA(a)    A = (a); TEST( A );#define LDX(a)    X = (a); TEST( X );#define LDY(a)    Y = (a); TEST( Y );/* Stack Op.  */#define PUSH(a)   K6502_WriteZp( BASE_STACK + SP--, (a) )#define PUSHW(a)  PUSH( (a) >> 8 ); PUSH( (a) & 0xff )#define POP(a)    a = K6502_ReadZp( BASE_STACK + ++SP )#define POPW(a)   POP(a); a |= ( K6502_ReadZp( BASE_STACK + ++SP ) << 8 )/* Logical Op.  */#define ORA(a)  A |= (a); TEST( A )#define AND(a)  A &= (a); TEST( A )#define EOR(a)  A ^= (a); TEST( A )#define BIT(a)  byD0 = (a); RSTF( FLAG_N | FLAG_V | FLAG_Z ); SETF( ( byD0 & ( FLAG_N | FLAG_V ) ) | ( ( byD0 & A ) ? 0 : FLAG_Z ) );#define CMP(a)  wD0 = (WORD)A - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );#define CPX(a)  wD0 = (WORD)X - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );#define CPY(a)  wD0 = (WORD)Y - (a); RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_byTestTable[ wD0 & 0xff ] | ( wD0 < 0x100 ? FLAG_C : 0 ) );/* Math Op. (A D flag isn't being supported.)  */#define ADC(a)  byD0 = (a); \	wD0 = A + byD0 + ( F & FLAG_C ); \	byD1 = (BYTE)wD0; \	RSTF( FLAG_N | FLAG_V | FLAG_Z | FLAG_C ); \	SETF( g_byTestTable[ byD1 ] | ( ( ~( A ^ byD0 ) & ( A ^ byD1 ) & 0x80 ) ? FLAG_V : 0 ) | ( wD0 > 0xff ) ); \A = byD1;#define SBC(a)  byD0 = (a); \	wD0 = A - byD0 - ( ~F & FLAG_C ); \	byD1 = (BYTE)wD0; \	RSTF( FLAG_N | FLAG_V | FLAG_Z | FLAG_C ); \	SETF( g_byTestTable[ byD1 ] | ( ( ( A ^ byD0 ) & ( A ^ byD1 ) & 0x80 ) ? FLAG_V : 0 ) | ( wD0 < 0x100 ) ); \A = byD1;#define DEC(a)  wA0 = a; byD0 = K6502_Read( wA0 ); --byD0; K6502_Write( wA0, byD0 ); TEST( byD0 )#define INC(a)  wA0 = a; byD0 = K6502_Read( wA0 ); ++byD0; K6502_Write( wA0, byD0 ); TEST( byD0 )/* Shift Op.  */#define ASLA    RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_ASLTable[ A ].byFlag ); A = g_ASLTable[ A ].byValue #define ASL(a)  RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_ASLTable[ byD0 ].byFlag ); K6502_Write( wA0, g_ASLTable[ byD0 ].byValue )#define LSRA    RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_LSRTable[ A ].byFlag ); A = g_LSRTable[ A ].byValue #define LSR(a)  RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_LSRTable[ byD0 ].byFlag ); K6502_Write( wA0, g_LSRTable[ byD0 ].byValue ) #define ROLA    byD0 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_ROLTable[ byD0 ][ A ].byFlag ); A = g_ROLTable[ byD0 ][ A ].byValue #define ROL(a)  byD1 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_ROLTable[ byD1 ][ byD0 ].byFlag ); K6502_Write( wA0, g_ROLTable[ byD1 ][ byD0 ].byValue )#define RORA    byD0 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); SETF( g_RORTable[ byD0 ][ A ].byFlag ); A = g_RORTable[ byD0 ][ A ].byValue #define ROR(a)  byD1 = F & FLAG_C; RSTF( FLAG_N | FLAG_Z | FLAG_C ); wA0 = a; byD0 = K6502_Read( wA0 ); SETF( g_RORTable[ byD1 ][ byD0 ].byFlag ); K6502_Write( wA0, g_RORTable[ byD1 ][ byD0 ].byValue )/* Jump Op.  */#define JSR     wA0 = AA_ABS2; PUSHW( PC ); PC = wA0; #define BRA(a)  if ( a ) { wA0 = PC; PC += (char)K6502_Read_Code( PC ); CLK( 3 + ( ( wA0 & 0x0100 ) != ( PC & 0x0100 ) ) ); ++PC; } else { ++PC; CLK( 2 ); }#define JMP(a)  PC = a;/*-------------------------------------------------------------------*//*  Global valiables                                                 *//*-------------------------------------------------------------------*//* 6502 Register  */
WORD PC;BYTE SP;BYTE F;BYTE A;BYTE X;BYTE Y;
/* The state of the IRQ pin  */BYTE IRQ_State;/* Wiring of the IRQ pin  */BYTE IRQ_Wiring;/* The state of the NMI pin  */BYTE NMI_State;/* Wiring of the NMI pin  */BYTE NMI_Wiring;/* The number of the clocks that it passed  */WORD g_wPassedClocks;/* A table for the test  */BYTE g_byTestTable[ 256 ];/* Value and Flag Data  */struct value_table_tag{	BYTE byValue;	BYTE byFlag;};/* A table for ASL  */struct value_table_tag g_ASLTable[ 256 ];/* A table for LSR  */struct value_table_tag g_LSRTable[ 256 ];/* A table for ROL  */struct value_table_tag g_ROLTable[ 2 ][ 256 ];/* A table for ROR  */struct value_table_tag g_RORTable[ 2 ][ 256 ];/*===================================================================*//*                                                                   *//*                K6502_Init() : Initialize K6502                    *//*                                                                   *//*===================================================================*/void K6502_Init(){/**  Initialize K6502**  You must call this function only once at first.	*/		BYTE idx;	BYTE idx2;		/* The establishment of the IRQ pin  */	NMI_Wiring = NMI_State = 1;	IRQ_Wiring = IRQ_State = 1;		/* Make a table for the test  */	idx = 0;	do	{		if ( idx == 0 )			g_byTestTable[ 0 ] = FLAG_Z;		else			if ( idx > 127 )				g_byTestTable[ idx ] = FLAG_N;			else				g_byTestTable[ idx ] = 0;						++idx;	} while ( idx != 0 );		/* Make a table ASL  */	idx = 0;	do	{		g_ASLTable[ idx ].byValue = idx << 1;		g_ASLTable[ idx ].byFlag = 0;				if ( idx > 127 )			g_ASLTable[ idx ].byFlag = FLAG_C;				if ( g_ASLTable[ idx ].byValue == 0 )			g_ASLTable[ idx ].byFlag |= FLAG_Z;		else			if ( g_ASLTable[ idx ].byValue & 0x80 )				g_ASLTable[ idx ].byFlag |= FLAG_N;						++idx;	} while ( idx != 0 );		/* Make a table LSR  */	idx = 0;	do	{		g_LSRTable[ idx ].byValue = idx >> 1;		g_LSRTable[ idx ].byFlag = 0;				if ( idx & 1 )			g_LSRTable[ idx ].byFlag = FLAG_C;				if ( g_LSRTable[ idx ].byValue == 0 )			g_LSRTable[ idx ].byFlag |= FLAG_Z;				++idx;	} while ( idx != 0 );		/* Make a table ROL  */	for ( idx2 = 0; idx2 < 2; ++idx2 )	{		idx = 0;		do		{			g_ROLTable[ idx2 ][ idx ].byValue = ( idx << 1 ) | idx2;			g_ROLTable[ idx2 ][ idx ].byFlag = 0;						if ( idx > 127 )				g_ROLTable[ idx2 ][ idx ].byFlag = FLAG_C;						if ( g_ROLTable[ idx2 ][ idx ].byValue == 0 )				g_ROLTable[ idx2 ][ idx ].byFlag |= FLAG_Z;			else				if ( g_ROLTable[ idx2 ][ idx ].byValue & 0x80 )					g_ROLTable[ idx2 ][ idx ].byFlag |= FLAG_N;								++idx;		} while ( idx != 0 );	}		/* Make a table ROR  */	for ( idx2 = 0; idx2 < 2; ++idx2 )	{		idx = 0;		do		{			g_RORTable[ idx2 ][ idx ].byValue = ( idx >> 1 ) | ( idx2 << 7 );			g_RORTable[ idx2 ][ idx ].byFlag = 0;						if ( idx & 1 )				g_RORTable[ idx2 ][ idx ].byFlag = FLAG_C;						if ( g_RORTable[ idx2 ][ idx ].byValue == 0 )				g_RORTable[ idx2 ][ idx ].byFlag |= FLAG_Z;			else				if ( g_RORTable[ idx2 ][ idx ].byValue & 0x80 )					g_RORTable[ idx2 ][ idx ].byFlag |= FLAG_N;								++idx;		} while ( idx != 0 );	}}/*===================================================================*//*                                                                   *//*                K6502_Reset() : Reset a CPU                        *//*                                                                   *//*===================================================================*/void K6502_Reset(){/**  Reset a CPU**/		/* Reset Registers  */	PC = K6502_ReadW_Code( VECTOR_RESET );	SP = 0xFF;	A = X = Y = 0;	F = FLAG_Z | FLAG_R;		/* Set up the state of the Interrupt pin.  */	NMI_State = NMI_Wiring;	IRQ_State = IRQ_Wiring;		/* Reset Passed Clocks  */	g_wPassedClocks = 0;}/*===================================================================*//*                                                                   *//*    K6502_Set_Int_Wiring() : Set up wiring of the interrupt pin    *//*                                                                   *//*===================================================================*/void K6502_Set_Int_Wiring( BYTE byNMI_Wiring, BYTE byIRQ_Wiring ){/** Set up wiring of the interrupt pin*	*/		NMI_Wiring = byNMI_Wiring;	IRQ_Wiring = byIRQ_Wiring;}

static BYTE byCode;

static WORD wA0;
static BYTE byD0;
static BYTE byD1;
static WORD wD0;

static  void instruct_00(void)
{
	++PC; PUSHW( PC ); SETF( FLAG_B ); PUSH( F ); SETF( FLAG_I ); RSTF( FLAG_D ); PC = K6502_ReadW_Code( VECTOR_IRQ ); CLK( 7 );
}
static  void instruct_01(void)
{
	ORA( A_IX ); CLK( 6 );
}
static  void instruct_05(void)
{
	ORA( A_ZP ); CLK( 3 );
}
static  void instruct_06(void)
{
	ASL( AA_ZP ); CLK( 5 );
}
static  void instruct_08(void)
{
	PUSH( F ); CLK( 3 );
}

static  void instruct_09(void)
{
	ORA( A_IMM ); CLK( 2 );
}
static  void instruct_0a(void)
{
	ASLA; CLK( 2 );
}
static  void instruct_0d(void)
{
	ORA( A_ABS ); CLK( 4 );	
}
static  void instruct_0e(void)
{
	ASL( AA_ABS ); CLK( 6 );
}
static  void instruct_10(void)
{
	BRA( !( F & FLAG_N ) );	
}
static  void instruct_11(void)
{
	ORA( A_IY ); CLK( 5 );
}
static  void instruct_15(void)
{
	ORA( A_ZPX ); CLK( 4 );	
}
static  void instruct_16(void)
{
	ASL( AA_ZPX ); CLK( 6 );	
}
static  void instruct_18(void)
{
	RSTF( FLAG_C ); CLK( 2 );	
}
static  void instruct_19(void)
{
	ORA( A_ABSY ); CLK( 4 );	
}
static  void instruct_1d(void)
{
	ORA( A_ABSX ); CLK( 4 );	
}
static  void instruct_1e(void)
{
	ASL( AA_ABSX ); CLK( 7 );	
}
static  void instruct_20(void)
{
	JSR; CLK( 6 );	
}
static  void instruct_21(void)
{
	AND( A_IX ); CLK( 6 );
}
static  void instruct_24(void)
{
	BIT( A_ZP ); CLK( 3 );	
}
static  void instruct_25(void)
{
	AND( A_ZP ); CLK( 3 );	
}
static  void instruct_26(void)
{
	ROL( AA_ZP ); CLK( 5 );	
}
static  void instruct_28(void)
{
	POP( F ); SETF( FLAG_R ); CLK( 4 );	
}
static  void instruct_29(void)
{
	AND( A_IMM ); CLK( 2 );	
}
static  void instruct_2a(void)
{
	ROLA; CLK( 2 );
}
static  void instruct_2c(void)
{
	BIT( A_ABS ); CLK( 4 );
}
static  void instruct_2d(void)
{
	AND( A_ABS ); CLK( 4 );
}
static  void instruct_2e(void)
{
	ROL( AA_ABS ); CLK( 6 );	
}
static  void instruct_30(void)
{
	BRA( F & FLAG_N );
}
static   void instruct_31(void)
{
	AND( A_IY ); CLK( 5 );
}
static   void instruct_35(void)
{
	AND( A_ZPX ); CLK( 4 );
}
static   void instruct_36(void)
{
	ROL( AA_ZPX ); CLK( 6 );	
}
static   void instruct_38(void)
{
	SETF( FLAG_C ); CLK( 2 );	
}
static   void instruct_39(void)
{
	AND( A_ABSY ); CLK( 4 );	
}
static   void instruct_3d(void)
{
	AND( A_ABSX ); CLK( 4 );
}
static   void instruct_3e(void)
{
	ROL( AA_ABSX ); CLK( 7 );	
}
static   void instruct_40(void)
{
	POP( F ); SETF( FLAG_R ); POPW( PC ); CLK( 6 );	
}
static   void instruct_41(void)
{
	EOR( A_IX ); CLK( 6 );
}
static   void instruct_45(void)
{
	EOR( A_ZP ); CLK( 3 );	
}
static   void instruct_46(void)
{
	LSR( AA_ZP ); CLK( 5 );
}
static   void instruct_48(void)
{
	PUSH( A ); CLK( 3 );	
}
static   void instruct_49(void)
{
	EOR( A_IMM ); CLK( 2 );	
}
static   void instruct_4a(void)
{
	LSRA; CLK( 2 );
}
static   void instruct_4c(void)
{
	JMP( AA_ABS ); CLK( 3 );	
}
static   void instruct_4d(void)
{
	EOR( A_ABS ); CLK( 4 );	
}
static   void instruct_4e(void)
{
	LSR( AA_ABS ); CLK( 6 );	
}
static   void instruct_50(void)
{
	BRA( !( F & FLAG_V ) );
}
static   void instruct_51(void)
{
	EOR( A_IY ); CLK( 5 );	
}
static   void instruct_55(void)
{
	EOR( A_ZPX ); CLK( 4 );	
}
static   void instruct_56(void)
{
	LSR( AA_ZPX ); CLK( 6 );	
}
static   void instruct_58(void)
{
	byD0 = F;
	RSTF( FLAG_I ); CLK( 2 );
	
	if ( ( byD0 & FLAG_I ) && IRQ_State != IRQ_Wiring )    
        
	{
		/* IRQ Interrupt  */
		/* Execute IRQ if an I flag isn't being set  */
		
		if ( !( byD0 & FLAG_I ) )
			
		{
            CLK( 7 );
			
            PUSHW( PC );
            PUSH( F & ~FLAG_B );
			
            RSTF( FLAG_D );
            SETF( FLAG_I );
			
            PC = K6502_ReadW_Code( VECTOR_IRQ );
		}
	}	
}
static   void instruct_59(void)
{
	EOR( A_ABSY ); CLK( 4 );
}
static   void instruct_5d(void)
{
	EOR( A_ABSX ); CLK( 4 );
}
static   void instruct_5e(void)
{
	LSR( AA_ABSX ); CLK( 7 );	
}
static   void instruct_60(void)
{
	POPW( PC ); ++PC; CLK( 6 );	
}
static   void instruct_61(void)
{
	ADC( A_IX ); CLK( 6 );
}
static   void instruct_65(void)
{
	ADC( A_ZP ); CLK( 3 );	
}
static   void instruct_66(void)
{
	ROR( AA_ZP ); CLK( 5 );
}
static   void instruct_68(void)
{
	POP( A ); TEST( A ); CLK( 4 );	
}
static   void instruct_69(void)
{
	ADC( A_IMM ); CLK( 2 );
}
static   void instruct_6a(void)
{
	RORA; CLK( 2 );
}
static   void instruct_6c(void)
{
	JMP( K6502_ReadW2( AA_ABS ) ); CLK( 5 );
}
static   void instruct_6d(void)
{
	ADC( A_ABS ); CLK( 4 );
}
static   void instruct_6e(void)
{
	ROR( AA_ABS ); CLK( 6 );
}
static   void instruct_70(void)
{
	BRA( F & FLAG_V );
}
static   void instruct_71(void)
{
	ADC( A_IY ); CLK( 5 );
}
static   void instruct_75(void)
{
	ADC( A_ZPX ); CLK( 4 );
}
static   void instruct_76(void)
{
	ROR( AA_ZPX ); CLK( 6 );
}
static   void instruct_78(void)
{
	SETF( FLAG_I ); CLK( 2 );
}
static   void instruct_79(void)
{
	ADC( A_ABSY ); CLK( 4 );
}
static   void instruct_7d(void)
{
	ADC( A_ABSX ); CLK( 4 );
}
static   void instruct_7e(void)
{
	ROR( AA_ABSX ); CLK( 7 );
}
static   void instruct_81(void)
{
	STA( AA_IX ); CLK( 6 );
}
static   void instruct_84(void)
{
	STY( AA_ZP ); CLK( 3 );
}

⌨️ 快捷键说明

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