Lib65816/src/opcodes/OpCode_BIT.cpp

110 lines
3.5 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 "../Interrupt.hpp"
#include "../Cpu65816.hpp"
#define LOG_TAG "Cpu::executeBIT"
/**
* This file contains the implementation for all BIT OpCodes
*/
void Cpu65816::execute8BitBIT(OpCode &opCode) {
const Address addressOfOpCodeData = getAddressOfOpCodeData(opCode);
uint8_t value = mSystemBus.readByte(addressOfOpCodeData);
bool isHighestBitSet = value & 0x80;
bool isNextToHighestBitSet = value & 0x40;
if (opCode.getAddressingMode() != AddressingMode::Immediate) {
if (isHighestBitSet) mCpuStatus.setSignFlag();
else mCpuStatus.clearSignFlag();
if (isNextToHighestBitSet) mCpuStatus.setOverflowFlag();
else mCpuStatus.clearOverflowFlag();
}
mCpuStatus.updateZeroFlagFrom8BitValue(value & Binary::lower8BitsOf(mA));
}
void Cpu65816::execute16BitBIT(OpCode &opCode) {
const Address addressOfOpCodeData = getAddressOfOpCodeData(opCode);
uint16_t value = mSystemBus.readTwoBytes(addressOfOpCodeData);
bool isHighestBitSet = value & 0x8000;
bool isNextToHighestBitSet = value & 0x4000;
if (opCode.getAddressingMode() != AddressingMode::Immediate) {
if (isHighestBitSet) mCpuStatus.setSignFlag();
else mCpuStatus.clearSignFlag();
if (isNextToHighestBitSet) mCpuStatus.setOverflowFlag();
else mCpuStatus.clearOverflowFlag();
}
mCpuStatus.updateZeroFlagFrom16BitValue(value & mA);
}
void Cpu65816::executeBIT(OpCode &opCode) {
if (accumulatorIs8BitWide()) {
execute8BitBIT(opCode);
} else {
execute16BitBIT(opCode);
addToCycles(1);
}
switch (opCode.getCode()) {
case(0x89): // BIT Immediate
{
if (accumulatorIs16BitWide()) {
addToProgramAddress(1);
}
addToProgramAddressAndCycles(2, 2);
break;
}
case(0x2C): // BIT Absolute
{
addToProgramAddressAndCycles(3, 4);
break;
}
case(0x24): // BIT Direct Page
{
if (Binary::lower8BitsOf(mD) != 0) {
addToCycles(1);
}
addToProgramAddressAndCycles(2, 3);
break;
}
case(0x3C): // BIT Absolute Indexed, X
{
if (opCodeAddressingCrossesPageBoundary(opCode)) {
addToCycles(1);
}
addToProgramAddressAndCycles(3, 4);
break;
}
case(0x34): // BIT Direct Page Indexed, X
{
if (Binary::lower8BitsOf(mD) != 0) {
addToCycles(1);
}
addToProgramAddressAndCycles(2, 4);
break;
}
default: {
LOG_UNEXPECTED_OPCODE(opCode);
}
}
}