Lib65816/src/opcodes/OpCode_StatusReg.cpp

127 lines
3.8 KiB
C++

/*
* This file is part of the 65816 Emulator Library.
* Copyright (c) 2018 Francesco Rigoni.
*
* https://github.com/FrancescoRigoni/Lib65816
*
* 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, version 3.
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#include "../Cpu65816.hpp"
#define LOG_TAG "Cpu::executeStatusReg"
/**
* This file contains the implementation for all OpCodes
* that deal directly with the status register.
*/
void Cpu65816::executeStatusReg(OpCode &opCode) {
switch (opCode.getCode()) {
case(0xC2): // REP #const
{
uint8_t value = mSystemBus.readByte(getAddressOfOpCodeData(opCode));
uint8_t statusByte = mCpuStatus.getRegisterValue();
mCpuStatus.setRegisterValue(statusByte & ~value);
addToProgramAddressAndCycles(2, 3);
break;
}
case(0x38): // SEC
{
mCpuStatus.setCarryFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0xF8): // SED
{
mCpuStatus.setDecimalFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0x78): // SEI
{
mCpuStatus.setInterruptDisableFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0x58): // CLI
{
mCpuStatus.clearInterruptDisableFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0xE2): // SEP
{
uint8_t value = mSystemBus.readByte(getAddressOfOpCodeData(opCode));
if (mCpuStatus.emulationFlag()) {
// In emulation mode status bits 4 and 5 are not affected
// 0xCF = 11001111
value &= 0xCF;
}
uint8_t statusReg = mCpuStatus.getRegisterValue();
statusReg |= value;
mCpuStatus.setRegisterValue(statusReg);
addToProgramAddressAndCycles(2, 3);
break;
}
case(0x18): // CLC
{
mCpuStatus.clearCarryFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0xD8): // CLD
{
mCpuStatus.clearDecimalFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0xB8): // CLV
{
mCpuStatus.clearOverflowFlag();
addToProgramAddressAndCycles(1, 2);
break;
}
case(0xFB): // XCE
{
bool oldCarry = mCpuStatus.carryFlag();
bool oldEmulation = mCpuStatus.emulationFlag();
if (oldCarry) mCpuStatus.setEmulationFlag();
else mCpuStatus.clearEmulationFlag();
if (oldEmulation) mCpuStatus.setCarryFlag();
else mCpuStatus.clearCarryFlag();
mX &= 0xFF;
mY &= 0xFF;
if (mCpuStatus.emulationFlag()) {
mCpuStatus.setAccumulatorWidthFlag();
mCpuStatus.setIndexWidthFlag();
} else {
mCpuStatus.clearAccumulatorWidthFlag();
mCpuStatus.clearIndexWidthFlag();
}
// New stack
mStack = Stack(&mSystemBus);
addToProgramAddressAndCycles(1,2);
break;
}
default: {
LOG_UNEXPECTED_OPCODE(opCode);
}
}
}