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

📄 make6502.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Multi-6502 32 Bit emulator *//* Copyright 1996, 1997, 1998, Neil Bradley, All rights reserved * * License agreement: * * (M6502 Refers to both the assembly code emitted by make6502.c and make6502.c * itself) * * M6502 May be distributed in unmodified form to any medium. * * M6502 May not be sold, or sold as a part of a commercial package without * the express written permission of Neil Bradley (neil@synthcom.com). This * includes shareware. * * Modified versions of M6502 may not be publicly redistributed without author * approval (neil@synthcom.com). This includes distributing via a publicly * accessible LAN. You may make your own source modifications and distribute * M6502 in source or object form, but if you make modifications to M6502 * then it should be noted in the top as a comment in make6502.c. * * M6502 Licensing for commercial applications is available. Please email * neil@synthcom.com for details. * * Synthcom Systems, Inc, and Neil Bradley will not be held responsible for * any damage done by the use of M6502. It is purely "as-is". * * If you use M6502 in a freeware application, credit in the following text: * * "Multi-6502 CPU emulator by Neil Bradley (neil@synthcom.com)" * * must accompany the freeware application within the application itself or * in the documentation. * * Legal stuff aside: * * If you find problems with M6502, please email the author so they can get * resolved. If you find a bug and fix it, please also email the author so * that those bug fixes can be propogated to the installed base of M6502 * users. If you find performance improvements or problems with M6502, please * email the author with your changes/suggestions and they will be rolled in * with subsequent releases of M6502. * * The whole idea of this emulator is to have the fastest available 32 bit * Multi-6502 emulator for the PC, giving maximum performance.  */ #include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#define	VERSION 	"1.6"#define TRUE            0xff#define FALSE           0x0#define	INVALID	0xff#define UINT32          unsigned long int#define UINT16          unsigned short int#define UINT8                   unsigned charFILE *fp = NULL;char string[150];char cpubasename[150];UINT32 dwPageLabel = 0;UINT32 dwGlobalLabel = 0;UINT32 dwAnotherLabel = 0;UINT8 bPlain = FALSE;				// Do we use plain global names?UINT8 bUseStack = FALSE;			// Use stack calling conventionsUINT8 bZeroDirect = FALSE;			// Zero page directUINT8 bSingleStep = FALSE;			// Here if we want to single step the CPUUINT8 bBankswitch = FALSE;			// Here if we want bankswitchingUINT8 bInvalidAsNop = FALSE;		// Treat invalid instructions as NOPUINT8 bNoDecimal = FALSE;			// Set if we don't want decimal modeUINT8 b6510Instructions = FALSE;	// TRUE If we include 6510 instructionsUINT32 dwBankSize = 12;				// 4K Defaultstatic UINT8 bUsed[256];void BrkHandler(UINT16 dwOpcode);void LdxHandler(UINT16 dwOpcode);void LdyHandler(UINT16 dwOpcode);void LdaHandler(UINT16 dwOpcode);void TxsHandler(UINT16 dwOpcode);void TsxHandler(UINT16 dwOpcode);void TaxHandler(UINT16 dwOpcode);void TxaHandler(UINT16 dwOpcode);void TayHandler(UINT16 dwOpcode);void TyaHandler(UINT16 dwOpcode);void DecxyHandler(UINT16 dwOpcode);void IncxyHandler(UINT16 dwOpcode);void StaHandler(UINT16 dwOpcode);void StxHandler(UINT16 dwOpcode);void StyHandler(UINT16 dwOpcode);void BranchHandler(UINT16 dwOpcode);void AndHandler(UINT16 dwOpcode);void AslHandler(UINT16 dwOpcode);void LsrHandler(UINT16 dwOpcode);void OraHandler(UINT16 dwOpcode);void EorHandler(UINT16 dwOpcode);void JmpHandler(UINT16 dwOpcode);void JsrHandler(UINT16 dwOpcode);void RtsHandler(UINT16 dwOpcode);void IncHandler(UINT16 dwOpcode);void DecHandler(UINT16 dwOpcode);void CmpHandler(UINT16 dwOpcode);void CpyHandler(UINT16 dwOpcode);void CpxHandler(UINT16 dwOpcode);void ClcCldCliClvHandler(UINT16 dwOpcode);void AdcHandler(UINT16 dwOpcode);void SbcHandler(UINT16 dwOpcode);void RolHandler(UINT16 dwOpcode);void RorHandler(UINT16 dwOpcode);void BitHandler(UINT16 dwOpcode);void PhaPhpHandler(UINT16 dwOpcode);void PlaPlpHandler(UINT16 dwOpcode);void RtiHandler(UINT16 dwOpcode);void NopHandler(UINT16 dwOpcode);void DeaInaHandler(UINT16 dwOpcode);void StzHandler(UINT16 dwOpcode);void TrbHandler(UINT16 dwOpcode);void TsbHandler(UINT16 dwOpcode);void BraHandler(UINT16 dwOpcode);struct sOp{	UINT16 bOpCode;	void (*Emitter)(UINT16);	UINT8 b6510Instruction;};struct sOp StandardOps[] ={	{0x00,	BrkHandler,	FALSE},		// Bank mod *	{0x81,	StaHandler,	FALSE},	{0x85,	StaHandler,	FALSE},	{0x8d,	StaHandler,	FALSE},	{0x91,	StaHandler,	FALSE},	{0x95,	StaHandler,	FALSE},	{0x99,	StaHandler,	FALSE},	{0x9d,	StaHandler,	FALSE},	{0x8e,	StxHandler,	FALSE},	{0x86,	StxHandler,	FALSE},	{0x96,	StxHandler,	FALSE},	{0x8c,	StyHandler,	FALSE},	{0x84,	StyHandler,	FALSE},	{0x94,	StyHandler,	FALSE},	{0xa9,	LdaHandler,	FALSE},	{0xad,	LdaHandler,	FALSE},	{0xa5,	LdaHandler,	FALSE},	{0xbd,	LdaHandler,	FALSE},	{0xb9,	LdaHandler,	FALSE},	{0xa1,	LdaHandler,	FALSE},	{0xb1,	LdaHandler,	FALSE},	{0xb5,	LdaHandler,	FALSE},	{0xae,	LdxHandler,	FALSE},	{0xa6,	LdxHandler,	FALSE},	{0xa2,	LdxHandler,	FALSE},	{0xbe,	LdxHandler,	FALSE},	{0xb6,	LdxHandler,	FALSE},	{0xac,	LdyHandler,	FALSE},	{0xa4,	LdyHandler,	FALSE},	{0xa0,	LdyHandler,	FALSE},	{0xbc,	LdyHandler,	FALSE},	{0xb4,	LdyHandler,	FALSE},	{0x88,	DecxyHandler,	FALSE},	{0xca,	DecxyHandler,	FALSE},	{0xe8,	IncxyHandler,	FALSE},	{0xc8,	IncxyHandler,	FALSE},	{0x8a,	TxaHandler,	FALSE},	{0x98,	TyaHandler,	FALSE},	{0x9a,	TxsHandler,	FALSE},	{0xa8,	TayHandler,	FALSE},	{0xaa,	TaxHandler,	FALSE},	{0xba,	TsxHandler,	FALSE},	{0x10,	BranchHandler,	FALSE},		// Bank mod *	{0x30,	BranchHandler,	FALSE},		// Bank mod *	{0x50,	BranchHandler,	FALSE},		// Bank mod *	{0x70,	BranchHandler,	FALSE},		// Bank mod *	{0x90,	BranchHandler,	FALSE},		// Bank mod *	{0xb0,	BranchHandler,	FALSE},		// Bank mod *	{0xd0,	BranchHandler,	FALSE},		// Bank mod *	{0xf0,	BranchHandler,	FALSE},		// Bank mod *	{0x2d,	AndHandler,	FALSE},	{0x25,	AndHandler,	FALSE},	{0x29,	AndHandler,	FALSE},	{0x3d,	AndHandler,	FALSE},	{0x39,	AndHandler,	FALSE},	{0x21,	AndHandler,	FALSE},	{0x31,	AndHandler,	FALSE},	{0x35,	AndHandler,	FALSE},	{0x0a,	AslHandler,	FALSE},	{0x0e,	AslHandler,	FALSE},	{0x06,	AslHandler,	FALSE},	{0x1e,	AslHandler,	FALSE},	{0x16,	AslHandler,	FALSE},	{0x4a,	LsrHandler,	FALSE},	{0x4e,	LsrHandler,	FALSE},	{0x46,	LsrHandler,	FALSE},	{0x5e,	LsrHandler,	FALSE},	{0x56,	LsrHandler,	FALSE},	{0x0d,	OraHandler,	FALSE},	{0x05,	OraHandler,	FALSE},	{0x09,	OraHandler,	FALSE},	{0x1d,	OraHandler,	FALSE},	{0x19,	OraHandler,	FALSE},	{0x01,	OraHandler,	FALSE},	{0x11,	OraHandler,	FALSE},	{0x15,	OraHandler,	FALSE},	{0x4d,	EorHandler,	FALSE},	{0x45,	EorHandler,	FALSE},	{0x49,	EorHandler,	FALSE},	{0x5d,	EorHandler,	FALSE},	{0x59,	EorHandler,	FALSE},	{0x41,	EorHandler,	FALSE},	{0x51,	EorHandler,	FALSE},	{0x55,	EorHandler,	FALSE},	{0xee,	IncHandler,	FALSE},	{0xe6,	IncHandler,	FALSE},	{0xfe,	IncHandler,	FALSE},	{0xf6,	IncHandler,	FALSE},	{0xce,	DecHandler,	FALSE},	{0xc6,	DecHandler,	FALSE},	{0xde,	DecHandler,	FALSE},	{0xd6,	DecHandler,	FALSE},	{0xcd,	CmpHandler,	FALSE},	{0xc5,	CmpHandler,	FALSE},	{0xc9,	CmpHandler,	FALSE},	{0xdd,	CmpHandler,	FALSE},	{0xd9,	CmpHandler,	FALSE},	{0xc1,	CmpHandler,	FALSE},	{0xd1,	CmpHandler,	FALSE},	{0xd5,	CmpHandler,	FALSE},	{0xcc,	CpyHandler,	FALSE},	{0xc4,	CpyHandler,	FALSE},	{0xc0,	CpyHandler,	FALSE},	{0xec,	CpxHandler,	FALSE},	{0xe4,	CpxHandler,	FALSE},	{0xe0,	CpxHandler,	FALSE},	{0x4c,	JmpHandler,	FALSE},			// Bank mod *	{0x6c,	JmpHandler,	FALSE},			// Bank mod *	{0x20,	JsrHandler,	FALSE},			// Bank mod *	{0x60,	RtsHandler,	FALSE},			// Bank mod *	{0x18,	ClcCldCliClvHandler,	FALSE},	{0x58,	ClcCldCliClvHandler,	FALSE},	{0xb8,	ClcCldCliClvHandler,	FALSE},	{0xd8,	ClcCldCliClvHandler,	FALSE},	{0x38,	ClcCldCliClvHandler,	FALSE},	{0x78,	ClcCldCliClvHandler,	FALSE},	{0xf8,	ClcCldCliClvHandler,	FALSE},	{0x6d,	AdcHandler,	FALSE},	{0x65,	AdcHandler,	FALSE},	{0x69,	AdcHandler,	FALSE},	{0x7d,	AdcHandler,	FALSE},	{0x79,	AdcHandler,	FALSE},	{0x61,	AdcHandler,	FALSE},	{0x71,	AdcHandler,	FALSE},	{0x75,	AdcHandler,	FALSE},	{0xed,	SbcHandler,	FALSE},	{0xe5,	SbcHandler,	FALSE},	{0xe9,	SbcHandler,	FALSE},	{0xfd,	SbcHandler,	FALSE},	{0xf9,	SbcHandler,	FALSE},	{0xe1,	SbcHandler,	FALSE},	{0xf1,	SbcHandler,	FALSE},	{0xf5,	SbcHandler,	FALSE},	{0x2a,	RolHandler,	FALSE},	{0x2e,	RolHandler,	FALSE},	{0x26,	RolHandler,	FALSE},	{0x3e,	RolHandler,	FALSE},	{0x36,	RolHandler,	FALSE},	{0x6a,	RorHandler,	FALSE},	{0x6e,	RorHandler,	FALSE},	{0x66,	RorHandler,	FALSE},	{0x7e,	RorHandler,	FALSE},	{0x76,	RorHandler,	FALSE},	{0x2c,	BitHandler,	FALSE},	{0x24,	BitHandler,	FALSE},	{0x48,	PhaPhpHandler,	FALSE},	{0x08,	PhaPhpHandler,	FALSE},	{0x68,	PlaPlpHandler,	FALSE},	{0x28,	PlaPlpHandler,	FALSE},	{0x40,	RtiHandler,	FALSE},			// Bank mod *	{0xea,	NopHandler,	FALSE},	// The remaining instructions are part of the 6510 - not the basic 6502	{0x3a,	DeaInaHandler,	TRUE},	{0x1a,	DeaInaHandler,	TRUE},	{0xda,	PhaPhpHandler,	TRUE},	{0x5a,	PhaPhpHandler,	TRUE},	{0xfa,	PlaPlpHandler,	TRUE},	{0x7a,	PlaPlpHandler,	TRUE},	{0x64,	StzHandler,	TRUE},	{0x74,	StzHandler,	TRUE},	{0x9c,	StzHandler,	TRUE},	{0x9e,	StzHandler,	TRUE},	{0x80,	BraHandler,	TRUE},				// Bank mod	{0x04,	TsbHandler,	TRUE},	{0x0c,	TsbHandler,	TRUE},	{0x14,	TrbHandler,	TRUE},	{0x1c,	TrbHandler,	TRUE},	// Terminator	{0xffff, NULL}  };UINT8 bTimingTable[256] ={	0x07, 0x06, 0x02, 0x02, 0x03, 0x03, 0x05, 0x02, 0x03, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x03, 0x04, 0x06, 0x02, 0x02, 0x04, 0x02, 0x02, 0x04, 0x04, 0x07, 0x02, 	0x06, 0x06, 0x02, 0x02, 0x03, 0x03, 0x05, 0x02, 0x04, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x04, 0x04, 0x06, 0x02, 0x02, 0x04, 0x02, 0x02, 0x04, 0x04, 0x07, 0x02, 	0x06, 0x06, 0x02, 0x02, 0x02, 0x03, 0x05, 0x02, 0x03, 0x02, 0x02, 0x02, 0x03, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x04, 0x07, 0x02, 	0x06, 0x06, 0x02, 0x02, 0x03, 0x03, 0x05, 0x02, 0x04, 0x02, 0x02, 0x02, 0x05, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x04, 0x04, 0x06, 0x02, 0x02, 0x04, 0x04, 0x02, 0x06, 0x04, 0x07, 0x02, 	0x02, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x02, 	0x03, 0x06, 0x03, 0x02, 0x04, 0x04, 0x04, 0x02, 0x02, 0x05, 0x02, 0x02, 0x04, 0x05, 0x05, 0x02, 	0x02, 0x06, 0x02, 0x02, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x04, 0x04, 0x04, 0x02, 0x02, 0x04, 0x02, 0x02, 0x04, 0x04, 0x04, 0x02, 	0x02, 0x06, 0x02, 0x02, 0x03, 0x03, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, 0x04, 0x03, 0x02, 0x02, 0x04, 0x07, 0x02, 	0x02, 0x06, 0x02, 0x02, 0x03, 0x03, 0x05, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x06, 0x02, 	0x03, 0x05, 0x03, 0x02, 0x02, 0x04, 0x06, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x04, 0x07, 0x02 };UINT8 bBit6502tox86[8] = {0, 6, 	  1, 0xff, 0xff, 0xff, 4, 7};UINT8 bBitx86to6502[8] = {0, 0xff, 0xff, 0xff, 	  6, 0xff, 1, 7};Flags6502toX86(){	fprintf(fp, "		xor	edx, edx\n");	fprintf(fp, "		mov	dl, ah\n");	fprintf(fp, "		mov	[_altFlags], dl\n");	fprintf(fp, "		and	[_altFlags], byte 3ch;\n");	fprintf(fp, "		mov	ah, [bit6502tox86+edx]\n");}FlagsX86to6502(){	fprintf(fp, "		xor	edx, edx\n");	fprintf(fp, "		mov	dl, ah\n");	fprintf(fp, "		mov	ah, [bitx86to6502+edx]\n");	fprintf(fp, "		or		ah, [_altFlags]\n");}SetZeroSign(UINT8 *pszRegister){	fprintf(fp, "		mov	dl, ah	; Save flags\n");	fprintf(fp, "		or	%s, %s	; OR Our new value\n", pszRegister, pszRegister);	fprintf(fp, "		lahf		; Restore flags\n");	fprintf(fp, "		and	dl, 03fh	; Original value\n");	fprintf(fp, "		and	ah, 0c0h	; Only zero and sign\n");	fprintf(fp, "		or	ah, dl		; New flags with the old!\n");}SetZero(UINT8 *pszRegister){	fprintf(fp, "		mov	dl, ah	; Save flags\n");	fprintf(fp, "		or	%s, %s	; OR Our new value\n", pszRegister, pszRegister);	fprintf(fp, "		lahf		; Restore flags\n");	fprintf(fp, "		and	dl, 0bfh	; Original value\n");	fprintf(fp, "		and	ah, 040h	; Only zero\n");	fprintf(fp, "		or	ah, dl		; New flags with the old!\n");}DecSetZeroSign(UINT8 *pszRegister){	fprintf(fp, "		mov	dl, ah	; Save flags\n");	fprintf(fp, "		dec	%s	; Decrement\n", pszRegister);	fprintf(fp, "		lahf		; Restore flags\n");	fprintf(fp, "		and	dl, 03fh	; Original value\n");	fprintf(fp, "		and	ah, 0c0h	; Only zero and sign\n");	fprintf(fp, "		or	ah, dl		; New flags with the old!\n");}IncSetZeroSign(UINT8 *pszRegister){	fprintf(fp, "		mov	dl, ah	; Save flags\n");	fprintf(fp, "		inc	%s	; Increment\n", pszRegister);	fprintf(fp, "		lahf		; Restore flags\n");	fprintf(fp, "		and	dl, 03fh	; Original value\n");	fprintf(fp, "		and	ah, 0c0h	; Only zero and sign\n");	fprintf(fp, "		or	ah, dl		; New flags with the old!\n");}void PCToPage(){	fprintf(fp, "		mov	edi, esi	; Here, too\n");	fprintf(fp, "		and	edi, 0%.4xh	; Knock off the unimportant stuff\n", (1 << dwBankSize) - 1);	fprintf(fp, "		and	esi, 0%.4xh	; Knock out the detailed stuff\n", ~((1 << dwBankSize) - 1)); 	fprintf(fp, "		mov	[_%sBasePage], esi	; Store our base page\n", cpubasename);	fprintf(fp, "		shr	esi, %ld	; Get rid of the data we don't need\n", dwBankSize);	fprintf(fp, "		mov	esi, [_%spbBankSwitch+esi*4]	; Get our base address\n", cpubasename);	fprintf(fp, "		mov	[_%sBaseAddr], esi	; Save our base pointer (possibly)\n", cpubasename);	fprintf(fp, "		add	esi, edi	; Add our offset - depaged\n");	fprintf(fp, ";\n; Warning! edi is trashed at this point!\n;\n");	++dwPageLabel;}void PageToPC(){	fprintf(fp, "		sub	esi, [_%sBaseAddr]	; Normalize it!\n", cpubasename);	fprintf(fp, "		add	esi, [_%sBasePage]	; And our base page!\n", cpubasename);}StandardHeader(){	fprintf(fp,"; For assembly by NASM only\n");	fprintf(fp,"bits 32\n");	fprintf(fp, ";\n; %s - V%s - Copyright 1998, Neil Bradley (neil@synthcom.com)\n;\n;\n\n", cpubasename, VERSION);	if (bUseStack)		fprintf(fp, "; Using stack calling conventions\n");	else		fprintf(fp, "; Using register calling conventions\n");	if (bBankswitch)		fprintf(fp, "; Bank switch version - %ld byte banks\n", (1 << dwBankSize));	if (bZeroDirect)		fprintf(fp, "; Zero page version (all zero page accesses are direct)\n");	else		fprintf(fp, "; Non-zero page version (all zero page accesses through handlers)\n");	if (bSingleStep)		fprintf(fp, "; Single step version (debug)\n");	fprintf(fp, "\n\n");}Alignment(){	fprintf(fp, "\ntimes ($$-$) & 3 nop	; pad with NOPs to 4-byte boundary\n\n");}ProcBegin(char *procname, UINT32 dwOpcode){	Alignment();	fprintf(fp, "%s:\n", procname);	if (0xffffffff != dwOpcode)	{		if (FALSE == bSingleStep)		{					fprintf(fp, "		sub	dword [cyclesRemaining], byte %ld\n", bTimingTable[dwOpcode]);			fprintf(fp, "		jc	near noMoreExec	; Can't execute anymore!\n");		}		else		{			fprintf(fp, "		dec	dword [cyclesRemaining]	; Single stepping (debugger)\n");			fprintf(fp, "		jz	near noMoreExec ; No more code!\n", procname);		}		fprintf(fp, "		add	dword [dwElapsedTicks], byte %ld\n", bTimingTable[dwOpcode]);	}}ProcEnd(char *procname){}FetchInstructionByte(){	fprintf(fp,	"		mov	dl, [esi]		; Get the next instruction\n");	fprintf(fp, "		inc	esi		; Advance PC!\n");}FetchAndExec(UINT32 dwClock){	fprintf(fp, "		xor	edx, edx\n");	fprintf(fp, "		mov	dl, [esi]\n");	fprintf(fp, "		inc	esi\n");

⌨️ 快捷键说明

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