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

📄 sym6502.cpp

📁 专门为65XX系列芯片设计的变异调试环境的源代码
💻 CPP
字号:
/*-----------------------------------------------------------------------------
	6502 Macroassembler and Simulator

Copyright (C) 1995-2003 Michal Kowalski

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-----------------------------------------------------------------------------*/

#include "stdafx.h"
#include "resource.h"
//#include "6502.h"
#include "MainFrm.h"
#include "Deasm6502Doc.h"
#include "6502View.h"
#include "6502Doc.h"
#include "Deasm.h"

//-----------------------------------------------------------------------------

UINT16 CSym6502::io_addr= 0xE000;		// pocz箃ek obszaru we/wy symulatora
bool CSym6502::io_enabled= true;
int CSym6502::bus_width= 16;
static const int SIM_THREAD_PRIORITY= THREAD_PRIORITY_BELOW_NORMAL; // priorytet (opr骳z animate)
bool CSym6502::s_bWriteProtectArea= false;
UINT16 CSym6502::s_uProtectFromAddr= 0xc000;
UINT16 CSym6502::s_uProtectToAddr= 0xcfff;

//-----------------------------------------------------------------------------

UINT8 CContext::get_status_reg() const
{
	ASSERT(negative==false || negative==true);
	ASSERT(overflow==false || overflow==true);
	ASSERT(zero==false || zero==true);
	ASSERT(carry==false || carry==true);
	ASSERT(reserved==false || reserved==true);
	ASSERT(break_bit==false || break_bit==true);
	ASSERT(decimal==false || decimal==true);
	ASSERT(interrupt==false || interrupt==true);

	return negative<<N_NEGATIVE | overflow<<N_OVERFLOW | zero<<N_ZERO | carry<<N_CARRY |
		reserved<<N_RESERVED | break_bit<<N_BREAK | decimal<<N_DECIMAL | interrupt<<N_INTERRUPT;
}


void CContext::set_status_reg_bits(UINT8 reg)
{
	negative	= !!(reg & NEGATIVE);
	overflow	= !!(reg & OVERFLOW);
	zero		= !!(reg & ZERO);
	carry 	= !!(reg & CARRY);
	reserved	= !!(reg & RESERVED);
	break_bit = 0; //!!(reg & BREAK);
	decimal	= !!(reg & DECIMAL);
	interrupt = !!(reg & INTERRUPT);
}

//=============================================================================


UINT16 CSym6502::get_argument_address(bool bWrite)
{
	UINT8 arg;
	UINT16 addr;

	UINT8 mode= m_vCodeToMode[ctx.mem[ctx.pc]];
	UINT16 pc= ctx.pc;
	inc_prog_counter();			// omini阠ie rozkazu

	switch (mode)
	{
	case A_ZPG:
	case A_ZPG2:
		addr = ctx.mem[ctx.pc];	// adres na str. 0
		inc_prog_counter();
		break;

	case A_ZPG_X:
		addr = UINT8(ctx.mem[ctx.pc] + ctx.x);
		inc_prog_counter();
		break;

	case A_ZPG_Y:
		addr = UINT8(ctx.mem[ctx.pc] + ctx.y);
		inc_prog_counter();
		break;

	case A_ZPGI:
		arg = ctx.mem[ctx.pc];	// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg);
		inc_prog_counter();
		break;

	case A_ABS:
		addr = ctx.mem.GetWord(ctx.pc);
		inc_prog_counter(2);
		break;

	case A_ABS_X:
		addr = ctx.mem.GetWord(ctx.pc) + ctx.x;
		inc_prog_counter(2);
		break;

	case A_ABS_Y:
		addr = ctx.mem.GetWord(ctx.pc) + ctx.y;
		inc_prog_counter(2);
		break;

	case A_ZPGI_X:
		arg = ctx.mem[ctx.pc];			// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg + ctx.x);
		inc_prog_counter();
		break;

	case A_ZPGI_Y:
		arg = ctx.mem[ctx.pc];			// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg) + ctx.y;
		inc_prog_counter();
		break;

	case A_ABSI:						// only JMP(xxxx) supports this addr mode
		addr = ctx.mem.GetWord(ctx.pc);
		if (theApp.m_global.GetProcType() && (addr & 0xFF) == 0xFF)	// LSB == 0xFF?
			addr = ctx.mem.GetWord(addr, addr - 0xFF);	// erroneously just as 6502 would do
		else
			addr = ctx.mem.GetWord(addr);
		inc_prog_counter(2);
		break;

	case A_ABSI_X:
		addr = ctx.mem.GetWord(ctx.pc) + ctx.x;
		addr = ctx.mem.GetWord(addr);
		inc_prog_counter(2);
		break;

	case A_ZREL:		// tu wyj箃kowo: addr = zpg (lo) + relative (hi)
		// na dolnym bajcie zwracany jest numer kom髍ki ze strony zerowej
		// na g髍nym bajcie przesuni阠ie wzgl阣ne
		addr = ctx.mem.GetWord(ctx.pc);
		//		addr = ctx.mem[ctx.pc]; // adres na str. 0
		//		addr += UINT16( ctx.mem[ctx.pc + 1] ) << 8; 	// przesuni阠ie
		inc_prog_counter(2);
		break;

	case A_IMP:
	case A_IMP2:
	case A_ACC:
	case A_IMM:
	default:
		ASSERT(false);
		return 0;
	}

	if (bWrite && addr >= s_uProtectFromAddr && addr <= s_uProtectToAddr)
	{
		ctx.pc = pc;	// restore original value
		throw SYM_ILL_WRITE;
	}

	return addr;
}


UINT8 CSym6502::get_argument_value()
{
	UINT8 arg;
	UINT16 addr;

	UINT8 mode= m_vCodeToMode[ctx.mem[ctx.pc]];
	inc_prog_counter();			// omini阠ie rozkazu

	switch (mode)
	{
	case A_IMP:
	case A_ACC:
		return 0;

	case A_IMP2:
	case A_IMM:
	case A_REL:
		arg = ctx.mem[ctx.pc];
		inc_prog_counter();
		return arg;

	case A_ZPGI:
		arg = ctx.mem[ctx.pc];			// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg);
		inc_prog_counter();
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem

	case A_ZPG:
		arg = ctx.mem[ctx.mem[ctx.pc]];	// liczba pod adresem
		inc_prog_counter();
		return arg;

	case A_ZPG_X:
		addr = (ctx.mem[ctx.pc] + ctx.x) & 0xFF;	// adres
		arg = ctx.mem[addr];						// liczba pod adresem
		inc_prog_counter();
		return arg;

	case A_ZPG_Y:
		arg = ctx.mem[ (ctx.mem[ctx.pc] + ctx.y) & 0xFF ];		// liczba pod adresem
		inc_prog_counter();
		return arg;

	case A_ABS:
		addr = ctx.mem.GetWord(ctx.pc);
		inc_prog_counter(2);
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem
		
//	case A_ABSI:

	case A_ABS_X:
		addr = ctx.mem.GetWord(ctx.pc) + ctx.x;
		inc_prog_counter(2);
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem

	case A_ABS_Y:
		addr = ctx.mem.GetWord(ctx.pc) + ctx.y;
		inc_prog_counter(2);
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem

	case A_ZPGI_X:
		arg = ctx.mem[ctx.pc];	// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg + ctx.x);
		inc_prog_counter();
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem

	case A_ZPGI_Y:
		arg = ctx.mem[ctx.pc];	// adres kom髍ki na str. 0
		addr = ctx.mem.GetWordInd(arg) + ctx.y;
		inc_prog_counter();
		return check_io_read(addr) ? io_function() : ctx.mem[addr]; // liczba pod adresem

	case A_ABSI_X:
	case A_ABSI:		// te tryby s

⌨️ 快捷键说明

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