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

📄 m6502ops.h

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 H
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 *
 *	 m6502ops.h
 *	 Addressing mode and opcode macros for 6502,65c02,6510 CPUs
 *
 *	 Copyright (c) 1998 Juergen Buchmueller, all rights reserved.
 *
 *	 - This source code is released as freeware for non-commercial purposes.
 *	 - You are free to use and redistribute this code in modified or
 *	   unmodified form, provided you list me in the credits.
 *	 - If you modify this source code, you must add a notice to each modified
 *	   source file that it has been changed.  If you're a nice person, you
 *	   will clearly mark each change too.  :)
 *	 - If you wish to use this for commercial purposes, please contact me at
 *	   pullmoll@t-online.de
 *	 - The author of this copywritten work reserves the right to change the
 *     terms of its usage and license at any time, including retroactively
 *   - This entire notice must remain in the source code.
 *
 *****************************************************************************/

/* 6502 flags */
#define _fC 0x01
#define _fZ 0x02
#define _fI 0x04
#define _fD 0x08
#define _fB 0x10
#define _fT 0x20
#define _fV 0x40
#define _fN 0x80

/* some shortcuts for improved readability */
#define A	m6502.a
#define X	m6502.x
#define Y	m6502.y
#define P	m6502.p
#define S	m6502.sp.B.l
#define SPD m6502.sp.D

#if LAZY_FLAGS

#define NZ  m6502.nz

#define SET_NZ(n)   NZ = (((n) & _fN) << 8) | (n)
#define SET_Z(n)	NZ = (NZ & 0x100) | (n)

#else

#define SET_NZ(n)				\
	P = (P & ~(_fN | _fZ)) |  ((n) & _fN) | (((n) == 0) ? _fZ : 0)
#define SET_Z(n)				\
    P = (P & ~_fZ) | ((n) == 0) ? _fZ : 0)

#endif

#define EAL m6502.ea.B.l
#define EAH m6502.ea.B.h
#define EAW m6502.ea.W.l
#define EAD m6502.ea.D

#define ZPL m6502.zp.B.l
#define ZPH m6502.zp.B.h
#define ZPW m6502.zp.W.l
#define ZPD m6502.zp.D

#define PCL m6502.pc.B.l
#define PCH m6502.pc.B.h
#define PCW m6502.pc.W.l
#define PCD m6502.pc.D

#if FAST_MEMORY
extern  MHELE   *cur_mwhard;
extern	MHELE	*cur_mrhard;
extern	byte	*RAM;
#endif

/***************************************************************
 *  RDOP    read an opcode
 ***************************************************************/
#define RDOP() cpu_readop(PCW++)

/***************************************************************
 *  RDOPARG read an opcode argument
 ***************************************************************/
#define RDOPARG() cpu_readop_arg(PCW++)

/***************************************************************
 *  RDMEM   read memory
 ***************************************************************/
#if FAST_MEMORY
#define RDMEM(addr)                                             \
	((cur_mrhard[(addr) >> (ABITS2_16 + ABITS_MIN_16)]) ?		\
		cpu_readmem16(addr) : RAM[addr])
#else
#define RDMEM(addr) cpu_readmem16(addr)
#endif

/***************************************************************
 *  WRMEM   write memory
 ***************************************************************/
#if FAST_MEMORY
#define WRMEM(addr,data)                                        \
	if (cur_mwhard[(addr) >> (ABITS2_16 + ABITS_MIN_16)])		\
		cpu_writemem16(addr,data);								\
	else														\
		RAM[addr] = data
#else
#define WRMEM(addr,data) cpu_writemem16(addr,data)
#endif

/***************************************************************
 *	BRA  branch relative
 *	extra cycle if page boundary is crossed
 ***************************************************************/
#define BRA(cond)                                               \
	if (cond)													\
	{															\
		tmp = RDOPARG();										\
		EAW = PCW + (signed char)tmp;							\
		M6502_ICount -= (PCH == EAH) ? 3 : 4;					\
		PCD = EAD;												\
		change_pc16(PCD);										\
	}															\
	else														\
	{															\
		PCW++;													\
		M6502_ICount -= 2;										\
	}

/***************************************************************
 *
 * Helper macros to build the effective address
 *
 ***************************************************************/

/***************************************************************
 *  EA = zero page address
 ***************************************************************/
#define EA_ZPG													\
	ZPL = RDOPARG();											\
	EAD = ZPD

/***************************************************************
 *  EA = zero page address + X
 ***************************************************************/
#define EA_ZPX													\
	ZPL = RDOPARG() + X;										\
	EAD = ZPD

/***************************************************************
 *  EA = zero page address + Y
 ***************************************************************/
#define EA_ZPY													\
	ZPL = RDOPARG() + Y;										\
	EAD = ZPD

/***************************************************************
 *  EA = absolute address
 ***************************************************************/
#define EA_ABS													\
	EAL = RDOPARG();											\
	EAH = RDOPARG()

/***************************************************************
 *  EA = absolute address + X
 ***************************************************************/
#define EA_ABX													\
    EA_ABS;                                                     \
    EAW += X

/***************************************************************
 *	EA = absolute address + Y
 ***************************************************************/
#define EA_ABY                                                  \
	EA_ABS; 													\
	EAW += Y

/***************************************************************
 *	EA = zero page indirect (65c02 pre indexed w/o X)
 ***************************************************************/
#define EA_ZPI													\
	ZPL = RDOPARG();											\
	EAL = RDMEM(ZPD);											\
	ZPL++;														\
	EAH = RDMEM(ZPD)

/***************************************************************
 *  EA = zero page + X indirect (pre indexed)
 ***************************************************************/
#define EA_IDX													\
	ZPL = RDOPARG() + X;										\
	EAL = RDMEM(ZPD);											\
	ZPL++;														\
    EAH = RDMEM(ZPD)

/***************************************************************
 *  EA = zero page indirect + Y (post indexed)
 *	subtract 1 cycle if page boundary is crossed
 ***************************************************************/
#define EA_IDY													\
	ZPL = RDOPARG();											\
	EAL = RDMEM(ZPD);											\
	ZPL++;														\
	EAH = RDMEM(ZPD);											\
    if (EAL + Y > 0xff)                                         \
		M6502_ICount--; 										\
	EAW += Y

/***************************************************************
 *	EA = indirect (only used by JMP)
 ***************************************************************/
#define EA_IND													\
	EA_ABS; 													\
	tmp = RDMEM(EAD);											\
	EAL++;	/* booby trap: stay in same page! ;-) */			\
	EAH = RDMEM(EAD);											\
	EAL = tmp

/***************************************************************
 *	EA = indirect plus x (only used by 65c02 JMP)
 ***************************************************************/
#define EA_IAX                                                  \
	EA_IND; 													\
	if (EAL + X > 0xff) /* assumption; probably wrong ? */		\
		M6502_ICount--; 										\
    EAW += X

/* read a value into tmp */
#define RD_IMM	tmp = RDOPARG()
#define RD_ACC	tmp = A
#define RD_ZPG	EA_ZPG; tmp = RDMEM(EAD)
#define RD_ZPX	EA_ZPX; tmp = RDMEM(EAD)
#define RD_ZPY	EA_ZPY; tmp = RDMEM(EAD)
#define RD_ABS	EA_ABS; tmp = RDMEM(EAD)
#define RD_ABX	EA_ABX; tmp = RDMEM(EAD)
#define RD_ABY	EA_ABY; tmp = RDMEM(EAD)
#define RD_ZPI	EA_ZPI; tmp = RDMEM(EAD)
#define RD_IDX	EA_IDX; tmp = RDMEM(EAD)
#define RD_IDY	EA_IDY; tmp = RDMEM(EAD)

/* write a value from tmp */
#define WR_ZPG	EA_ZPG; WRMEM(EAD, tmp)
#define WR_ZPX	EA_ZPX; WRMEM(EAD, tmp)
#define WR_ZPY	EA_ZPY; WRMEM(EAD, tmp)
#define WR_ABS	EA_ABS; WRMEM(EAD, tmp)
#define WR_ABX	EA_ABX; WRMEM(EAD, tmp)
#define WR_ABY	EA_ABY; WRMEM(EAD, tmp)
#define WR_ZPI	EA_ZPI; WRMEM(EAD, tmp)
#define WR_IDX	EA_IDX; WRMEM(EAD, tmp)
#define WR_IDY	EA_IDY; WRMEM(EAD, tmp)

/* write back a value from tmp to the last EA */
#define WB_ACC	A = (byte)tmp;
#define WB_EA	WRMEM(EAD, tmp)

/***************************************************************
 ***************************************************************
 *			Macros to emulate the plain 6502 opcodes
 ***************************************************************
 ***************************************************************/

/***************************************************************
 * compose the real flag register by
 * including N and Z and set any
 * SET and clear any CLR bits also
 ***************************************************************/
#if LAZY_FLAGS

#define COMPOSE_P												\
	P = (P & ~(_fN|_fZ)) | (NZ >> 8) | ((NZ&0xff) ? 0:_fZ)

#else

#define COMPOSE_P

#endif

/***************************************************************
 * push a register onto the stack
 ***************************************************************/
#define PUSH(Rg) WRMEM(SPD, Rg); S--

/***************************************************************
 * pull a register from the stack
 ***************************************************************/
#define PULL(Rg) S++; Rg = RDMEM(SPD)

/* 6502 ********************************************************
 *	ADC Add with carry
 ***************************************************************/
#define ADC 													\
	if (P & _fD)												\
	{															\
	int c = (P & _fC);											\
	int lo = (A & 0x0f) + (tmp & 0x0f) + c; 					\
	int hi = (A & 0xf0) + (tmp & 0xf0); 						\
		P &= ~(_fV | _fC);										\
		if (lo > 0x09)											\
		{														\
			hi += 0x10; 										\
			lo += 0x06; 										\
		}														\
		if (~(A^tmp) & (A^hi) & _fN)							\
			P |= _fV;											\
		if (hi > 0x90)											\
			hi += 0x60; 										\
		if (hi & 0xff00)										\
			P |= _fC;											\
		A = (lo & 0x0f) + (hi & 0xf0);							\
	}															\
	else														\
	{															\
	int c = (P & _fC);											\
	int sum = A + tmp + c;										\
		P &= ~(_fV | _fC);										\
		if (~(A^tmp) & (A^sum) & _fN)							\
			P |= _fV;											\
		if (sum & 0xff00)										\
			P |= _fC;											\
		A = (byte) sum; 										\
	}															\
	SET_NZ(A)

/* 6502 ********************************************************
 *	AND Logical and
 ***************************************************************/
#define AND 													\
	A = (byte)(A & tmp);										\
	SET_NZ(A)

/* 6502 ********************************************************
 *	ASL Arithmetic shift left
 ***************************************************************/
#define ASL 													\
	P = (P & ~_fC) | ((tmp >> 7) & _fC);						\
	tmp = (byte)(tmp << 1); 									\
	SET_NZ(tmp)

/* 6502 ********************************************************
 *	BCC Branch if carry clear
 ***************************************************************/
#define BCC BRA(!(P & _fC))

/* 6502 ********************************************************
 *	BCS Branch if carry set
 ***************************************************************/
#define BCS BRA(P & _fC)

/* 6502 ********************************************************
 *	BEQ Branch if equal
 ***************************************************************/
#if LAZY_FLAGS
#define BEQ BRA(!(NZ & 0xff))
#else
#define BEQ BRA(P & _fZ)
#endif

/* 6502 ********************************************************
 *	BIT Bit test
 ***************************************************************/
#if LAZY_FLAGS

#define BIT 													\
	P = (P & ~_fV) | (tmp & _fV);								\
	NZ = (tmp & _fN) << 8;										\

⌨️ 快捷键说明

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