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

📄 make6502.c

📁 十七种模拟器源代码 非常有用的作课程设计不可缺少的
💻 C
📖 第 1 页 / 共 5 页
字号:
	fprintf(fp, "		jmp	dword [%sregular+edx*4]\n\n", cpubasename);}ReadMemoryByte(UINT8 *pszTargetReg, UINT8 *pszAddress){	fprintf(fp, "		mov	edi, [_%sMemRead]	; Point to the read array\n\n", cpubasename);	fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);	fprintf(fp, "		cmp	[edi], word 0ffffh ; End of the list?\n");	fprintf(fp, "		je		short memoryRead%ld\n", dwGlobalLabel);	fprintf(fp, "		cmp	%s, [edi]	; Are we smaller?\n", pszAddress);	fprintf(fp, "		jb		short nextAddr%ld		; Yes, go to the next address\n", dwGlobalLabel);	fprintf(fp, "		cmp	%s, [edi+4]	; Are we bigger?\n", pszAddress);	fprintf(fp, "		jbe	short callRoutine%ld\n\n", dwGlobalLabel);	fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);	fprintf(fp, "		add	edi, 10h		; Next structure!\n");	fprintf(fp, "		jmp	short checkLoop%ld\n\n", dwGlobalLabel);	fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);	assert(strcmp(pszAddress, "dx") == 0);	fprintf(fp, "		call	ReadMemoryByte	; Standard read routine\n");	if (strcmp(pszTargetReg, "bl") != 0)		fprintf(fp, "		mov	bl, [_%sx]	; Get X back\n", cpubasename);	if (strcmp(pszTargetReg, "cl") != 0)		fprintf(fp, "		mov	cl, [_%sy]	; Get Y back\n", cpubasename);		if (strcmp(pszTargetReg, "al") != 0)	{		fprintf(fp, "		mov	%s, al	; Get our value\n", pszTargetReg);		fprintf(fp, "		mov	ax, [_%saf]	; Get our flags & stuff back\n", cpubasename);	}	else		fprintf(fp, "		mov	ah, [_%saf + 1] ; Get our flags back\n", cpubasename);	fprintf(fp, "		jmp	short readExit%ld\n\n", dwGlobalLabel);	fprintf(fp, "memoryRead%ld:\n", dwGlobalLabel);	if (bBankswitch)	{		fprintf(fp, "		mov	ebp, e%s	; Save our original address in EBP\n", pszAddress);		fprintf(fp, "		and	ebp, 0ffffh ; Mask off the upper bits\n");		fprintf(fp, "		mov	edi, ebp	; Get our address\n");		fprintf(fp, "		shr	edi, %ld	; Find which bank we belong to\n", dwBankSize);		fprintf(fp, "		mov	edi, [_%spbBankSwitch+edi*4] ; Get our base address for this bank\n", cpubasename);		fprintf(fp, "		or	edi, edi	; NULL?\n");		fprintf(fp, "		jz	regularRead%ld	; If so, we're not banking!\n", dwGlobalLabel);		// This is the code that fetches the data from the proper address		fprintf(fp, "		and	ebp, 0%.4xh	; Mask out the unimportant stuff\n", (1 << dwBankSize) - 1);		fprintf(fp, "		mov	%s, [ebp+edi]	; Get our banked data\n", pszTargetReg);		fprintf(fp, "		mov	ebp, [_%sBase]	; Get our base pointer back\n", cpubasename);		fprintf(fp, "		jmp	short readExit%ld\n", dwGlobalLabel);		fprintf(fp, "regularRead%ld:\n", dwGlobalLabel);		fprintf(fp, "		mov	ebp, [_%sBase]	; Get our base pointer back\n", cpubasename);	}	fprintf(fp, "		mov	%s, [ebp + e%s]	; Get our data\n\n", pszTargetReg, pszAddress);	fprintf(fp, "readExit%ld:\n", dwGlobalLabel);	dwGlobalLabel++;}ReadMemoryWord(){	fprintf(fp, "		push	edx	; Save address\n");	fprintf(fp, "		mov	[_%saf], ax	; Store AF\n", cpubasename);	ReadMemoryByte("al", "dx");	fprintf(fp, "		pop	edx	; Restore address\n");	fprintf(fp, "		inc	dx	; Next address\n");	fprintf(fp, "		push	eax	; Save it for later\n");	fprintf(fp, "		mov	ax, [_%saf]	; Restore AF because it gets used later\n", cpubasename);	ReadMemoryByte("dh", "dx");	fprintf(fp, "		pop	eax	; Restore it!\n");	fprintf(fp, "		mov	dl, al	; Restore our word into DX\n");	fprintf(fp, "		mov	ax, [_%saf]	; Restore AF\n", cpubasename);}WriteMemoryByte(UINT8 *pszSourceReg, UINT8 *pszAddress){	fprintf(fp, "		mov	edi, [_%sMemWrite]	; Point to the write array\n\n", cpubasename);	fprintf(fp, "checkLoop%ld:\n", dwGlobalLabel);	fprintf(fp, "		cmp	[edi], word 0ffffh ; End of our list?\n");	fprintf(fp, "		je	near memoryWrite%ld	; Yes - go write it!\n", dwGlobalLabel);	fprintf(fp, "		cmp	%s, [edi]	; Are we smaller?\n", pszAddress);	fprintf(fp, "		jb	nextAddr%ld	; Yes... go to the next addr\n", dwGlobalLabel);	fprintf(fp, "		cmp	%s, [edi+4]	; Are we bigger?\n", pszAddress);	fprintf(fp, "		jbe	callRoutine%ld	; If not, go call it!\n\n", dwGlobalLabel);	fprintf(fp, "nextAddr%ld:\n", dwGlobalLabel);	fprintf(fp, "		add	edi, 10h		; Next structure, please\n");	fprintf(fp, "		jmp	short checkLoop%ld\n\n", dwGlobalLabel);	fprintf(fp, "callRoutine%ld:\n", dwGlobalLabel);	// Save off our registers!	fprintf(fp, "		mov	[_%sx], bl	; Save X\n", cpubasename);	fprintf(fp, "		mov	[_%sy], cl	; Save Y\n", cpubasename);	fprintf(fp, "		mov	[_%saf], ax	; Save Accumulator & flags\n", cpubasename);	if (bBankswitch)		PageToPC();	else		fprintf(fp, "		sub	esi, ebp	; Our program counter\n", cpubasename);	fprintf(fp, "		mov	[_%spc], si	; Save our program counter\n", cpubasename);	if (bUseStack)	{		fprintf(fp, "		push	edi	; Pointer to MemoryWriteByte structure\n");		if (strcmp(pszSourceReg, "bl") == 0)			fprintf(fp, "		push	ebx	; The byte value\n");		if (strcmp(pszSourceReg, "bh") == 0)		{			fprintf(fp, "		mov	bl, bh	; Put a copy here\n");			fprintf(fp, "		push	ebx	; The byte value\n");		}		if (strcmp(pszSourceReg, "cl") == 0)			fprintf(fp, "		push	ecx	; The byte value\n");		if (strcmp(pszSourceReg, "al") == 0)			fprintf(fp, "		push	eax	; The byte value\n");		fprintf(fp, "		and	e%s, 0ffffh	; Only lower 16 bits\n", pszAddress);		fprintf(fp, "		push	e%s	; The address\n", pszAddress);	}	else		// Register calling convention	{		if ((strcmp(pszSourceReg, "al") == 0) && 			 (strcmp(pszAddress, "dx") == 0))			fprintf(fp, "		xchg	eax, edx	; Swap 'em\n");		else		{			if (strcmp(pszAddress, "bx") == 0)				fprintf(fp, "		mov	eax, ebx	; Address\n");			if (strcmp(pszAddress, "cx") == 0)				fprintf(fp, "		mov	eax, ebx	; Address\n");			if (strcmp(pszAddress, "dx") == 0)				fprintf(fp, "		mov	eax, edx	; Address\n");			if (strcmp(pszSourceReg, "bh") == 0)			{				fprintf(fp, "		mov	bl, bh	; Put a copy here\n");				fprintf(fp, "		mov	edx, ebx	; The byte value\n");			}			if (strcmp(pszSourceReg, "bl") == 0)				fprintf(fp, "		mov	edx, ebx	; The byte value\n");			if (strcmp(pszSourceReg, "cl") == 0)				fprintf(fp, "		mov	edx, ecx	; The byte value\n");			if (strcmp(pszSourceReg, "al") == 0)				fprintf(fp, "		mov	edx, eax	; The byte value\n");		}		fprintf(fp, "		mov	ebx, edi	; MemoryWriteByte structure\n");	}	fprintf(fp, "		call	dword [edi + 8] ; Go call our handler\n");	if (bUseStack)		fprintf(fp, "		add	esp, 12	; Get rid of our stack\n");	fprintf(fp, "		xor	ebx, ebx	; Zero this\n");	fprintf(fp, "		xor	ecx, ecx	; This too!\n");	fprintf(fp, "		mov	bl, [_%sx]	; Get X back\n", cpubasename);	fprintf(fp, "		mov	cl, [_%sy]	; Get Y back\n", cpubasename);	fprintf(fp, "		xor	esi, esi	; Zero it!\n");	fprintf(fp, "		mov	si, [_%spc]	; Get our program counter back\n", cpubasename);	fprintf(fp, "		mov	ebp, [_%sBase] ; Base pointer comes back\n", cpubasename);	if (bBankswitch)		PCToPage();	else		fprintf(fp, "		add	esi, ebp	; Rebase it properly\n");	fprintf(fp, "		mov	ax, [_%saf]	; Get our flags & stuff back\n", cpubasename);		fprintf(fp, "		jmp	short writeMacroExit%ld\n\n", dwGlobalLabel);	fprintf(fp, "memoryWrite%ld:\n", dwGlobalLabel);	fprintf(fp, "		mov	[ebp + e%s], %s ; Store the byte\n\n", pszAddress, pszSourceReg);	fprintf(fp, "writeMacroExit%ld:\n", dwGlobalLabel);	++dwGlobalLabel;}void ReadMemoryByteHandler(){	Alignment();	fprintf(fp, "; This is a generic read memory byte handler when a foreign\n");	fprintf(fp, "; handler is to be called\n\n");	fprintf(fp, "ReadMemoryByte:\n");	fprintf(fp, "		mov	[_%sx], bl	; Save X\n", cpubasename);	fprintf(fp, "		mov	[_%sy], cl	; Save Y\n", cpubasename);	fprintf(fp, "		mov	[_%saf], ax	; Save Accumulator & flags\n", cpubasename);	if (bBankswitch)		PageToPC();	else		fprintf(fp, "		sub	esi, ebp	; Our program counter\n", cpubasename);	fprintf(fp, "		mov	[_%spc], si	; Save our program counter\n", cpubasename);	if (bUseStack)	{		fprintf(fp, "		push	edi	; Save our structure address\n");		fprintf(fp, "		and	edx, 0ffffh	; Only the lower 16 bits\n");		fprintf(fp, "		push	edx	; And our desired address\n");	}	else	{		fprintf(fp, "		mov	eax, edx	; Get our desired address reg\n");		fprintf(fp, "		mov	edx, edi	; Pointer to the structure\n");	}	fprintf(fp, "		call	dword [edi + 8]	; Go call our handler\n");	if (bUseStack)		fprintf(fp, "		add	esp, 8	; Get the junk off the stack\n");	fprintf(fp, "		xor	ebx, ebx	; Zero X\n");	fprintf(fp, "		xor	ecx, ecx	; Zero Y\n");	fprintf(fp, "		xor	esi, esi	; Zero it!\n");	fprintf(fp, "		mov	si, [_%spc]	; Get our program counter back\n", cpubasename);	fprintf(fp, "		mov	ebp, [_%sBase] ; Base pointer comes back\n", cpubasename);	if (bBankswitch)		PCToPage();	else		fprintf(fp, "		add	esi, ebp	; Rebase it properly\n");	fprintf(fp, "		ret\n\n");	++dwGlobalLabel;}FetchInstructionWord(){	fprintf(fp, "		mov	dx, [esi]	; Get our address\n");	fprintf(fp, "		add	esi, 2	; Increment past instruction\n");}Absolute(){	FetchInstructionWord();}ZeroPage(){	FetchInstructionByte();}ZeroPageX(){	FetchInstructionByte();	fprintf(fp, "		add	dl, bl	; Add X\n");}ZeroPageY(){	FetchInstructionByte();	fprintf(fp, "		add	dl, cl	; Add Y\n");}AbsoluteX(){	FetchInstructionWord();	fprintf(fp, "		add	dx, bx	 ; Add X\n");}AbsoluteY(){	FetchInstructionWord();	fprintf(fp, "		add	dx, cx	 ; Add Y\n");}IndirectX(){	FetchInstructionByte();	fprintf(fp, "		add	dl, bl	; Add in X\n");	if (bZeroDirect)		fprintf(fp, "		mov	dx, [ebp+edx]	; Get our 16 bit address\n");	else		ReadMemoryWord();}IndirectY(){	FetchInstructionByte();	if (bZeroDirect)		fprintf(fp, "		mov	dx, [ebp+edx]	; Get our 16 bit address\n");	else		ReadMemoryWord();	fprintf(fp, "		add	dx, cx	; Add in Y\n");}DataSegment(){	UINT32 dwLoop = 0;	UINT32 dwBit = 0;	UINT8 bValue = 0;	fprintf(fp, "		section	.data\n");	Alignment();	if (bPlain)		fprintf(fp, "		global	%spc\n\n",cpubasename);	else		fprintf(fp, "		global	_%spc\n\n",cpubasename);	fprintf(fp, "		global	%spbBankSwitch_, _%spbBankSwitch\n\n", cpubasename, cpubasename);	fprintf(fp, "_%scontextBegin:\n", cpubasename);	fprintf(fp, "\n");	fprintf(fp, "; DO NOT CHANGE THE ORDER OF THE FOLLOWING REGISTERS!\n");	fprintf(fp, "\n");	fprintf(fp, "_%sBase	dd	0	; Base address for 6502 stuff\n", cpubasename);	fprintf(fp, "_%sMemRead	dd	0	; Offset of memory read structure array\n", cpubasename);	fprintf(fp, "_%sMemWrite	dd	0	; Offset of memory write structure array\n", cpubasename);	if (bBankswitch)	{		fprintf(fp, "_%spbBankSwitch:\n", cpubasename);		for (dwLoop = 0; dwLoop < 32; dwLoop++)		{			if (dwLoop * (1 << dwBankSize) < 65536)				fprintf(fp, "		dd	0	; Addr=$%.4x\n", dwLoop * (1 << dwBankSize));			else				fprintf(fp, "		dd	0	; Filler\n");		}	}	fprintf(fp, "_%saf	dw	0	; A register and flags\n", cpubasename);	fprintf(fp, "_%spc:\n", cpubasename);	fprintf(fp, "%spc	dw	0	; 6502 Program counter\n", cpubasename);	fprintf(fp, "_%sx		db	0	; X\n", cpubasename);	fprintf(fp, "_%sy		db	0	; Y\n", cpubasename);	fprintf(fp, "_%ss		db	0	; s\n", cpubasename);	fprintf(fp, "_irqPending	db	0	; Non-zero if an IRQ is pending\n");	fprintf(fp, "\n");	fprintf(fp, "_%scontextEnd:\n", cpubasename);		if (bBankswitch)	{		fprintf(fp, "_%sBaseAddr	dd	0	; Temporary base address\n", cpubasename);		fprintf(fp, "_%sBasePage	dd	0	; What page are we on? (ready for use)\n", cpubasename);	}	fprintf(fp, "\n");	Alignment();	fprintf(fp, "_tempAddr	dd	0	; Temporary address storage\n");	fprintf(fp, "dwElapsedTicks	dd 0	; Elapsed ticks!\n");	fprintf(fp, "cyclesRemaining	dd	0	; # Of cycles remaining\n");	fprintf(fp, "_altFlags	db	0	; Storage for I, D, and B\n");		// Now we write out our tables	Alignment();	for (dwLoop = 0; dwLoop < 256; dwLoop++)		bUsed[dwLoop] = 0;	// Create flag translation tables	fprintf(fp,	"bit6502tox86:\n");	for (dwLoop = 0; dwLoop < 256; dwLoop++)	{		bValue = 0;		for (dwBit = 0; dwBit < 8; dwBit++)		{			if (bBit6502tox86[dwBit] != 0xff)			{				if ((1 << dwBit) & dwLoop)					bValue |= (1 << bBit6502tox86[dwBit]);			}		}		if ((dwLoop & 0x0f) == 0)			fprintf(fp, "		db	");		if (bValue < 0xa0)			fprintf(fp, "%.2xh", bValue);		else				fprintf(fp, "0%.2xh", bValue);		if ((dwLoop & 0x0f) != 0xf)			fprintf(fp, ", ");		else			fprintf(fp, "\n");	}	// Create flag translation tables	fprintf(fp,	"\nbitx86to6502:\n");	for (dwLoop = 0; dwLoop < 256; dwLoop++)	{		bValue = 0;		for (dwBit = 0; dwBit < 8; dwBit++)		{			if (bBitx86to6502[dwBit] != 0xff)			{				if ((1 << dwBit) & dwLoop)					bValue |= (1 << bBitx86to6502[dwBit]);			}		}		if ((dwLoop & 0x0f) == 0)			fprintf(fp, "		db	");		if (bValue < 0xa0)			fprintf(fp, "%.2xh", bValue);		else				fprintf(fp, "0%.2xh", bValue);		if ((dwLoop & 0x0f) != 0xf)			fprintf(fp, ", ");		else			fprintf(fp, "\n");	}	fprintf(fp, "\n");	// Now rip through and find out what is and isn't used	dwLoop = 0;	while (StandardOps[dwLoop].Emitter)	{		assert(StandardOps[dwLoop].bOpCode < 0x100);		if (bUsed[StandardOps[dwLoop].bOpCode])		{			fprintf(stderr, "Oops! %.2x\n", StandardOps[dwLoop].bOpCode);			exit(1);		}		if (b6510Instructions)			bUsed[StandardOps[dwLoop].bOpCode] = 1;		else		{			if (StandardOps[dwLoop].b6510Instruction == FALSE)				bUsed[StandardOps[dwLoop].bOpCode] = 1;		}		dwLoop++;	}	fprintf(stderr, "%ld Unique opcodes\n", dwLoop);	// Now that that's taken care of, emit the table	fprintf(fp, "%sregular:\n", cpubasename);	dwLoop = 0;	while (dwLoop < 0x100)	{		fprintf(fp, "		dd	");		if (bUsed[dwLoop])			fprintf(fp, "RegInst%.2x", dwLoop);		else		{			if (bInvalidAsNop)				fprintf(fp, "RegInstea");			else				fprintf(fp, "invalidInsByte");		}		fprintf(fp, "\n");		dwLoop++;	}	fprintf(fp, "\n");}CodeSegmentBegin(){	fprintf(fp, "		section	.text\n");}CodeSegmentEnd(){}ProgramEnd(){	fprintf(fp, "		end\n");}EmitRegularInstructions(){	UINT32 dwLoop = 0;	UINT32 dwLoop2 = 0;	while (dwLoop < 0x100)	{		dwLoop2 = 0;		while (StandardOps[dwLoop2].bOpCode != dwLoop && StandardOps[dwLoop2].bOpCode != 0xffff)			dwLoop2++;		assert(dwLoop2 < 0x100);		if (StandardOps[dwLoop2].Emitter			&& StandardOps[dwLoop2].bOpCode != 0xffff &&			bUsed[dwLoop])			StandardOps[dwLoop2].Emitter((UINT16) dwLoop);		dwLoop++;	}}

⌨️ 快捷键说明

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