📄 sym6502.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 + -