mirror of
https://github.com/FrancescoRigoni/Lib65816.git
synced 2024-11-12 09:05:17 +00:00
185 lines
6.0 KiB
C++
185 lines
6.0 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/>.
|
|
*/
|
|
|
|
#ifndef __CPU_65816__
|
|
#define __CPU_65816__
|
|
|
|
#include <stdint.h>
|
|
|
|
#include "SystemBus.hpp"
|
|
#include "Interrupt.hpp"
|
|
#include "Addressing.hpp"
|
|
#include "Stack.hpp"
|
|
#include "CpuStatus.hpp"
|
|
#include "OpCode.hpp"
|
|
#include "Log.hpp"
|
|
#include "Binary.hpp"
|
|
#include "BuildConfig.hpp"
|
|
|
|
// Macro used by OpCode methods when an unrecognized OpCode is being executed.
|
|
#define LOG_UNEXPECTED_OPCODE(opCode) Log::err(LOG_TAG).str("Unexpected OpCode: ").str(opCode.getName()).show();
|
|
|
|
class Cpu65816Debugger;
|
|
|
|
class Cpu65816 {
|
|
friend class Cpu65816Debugger;
|
|
public:
|
|
Cpu65816(SystemBus &, EmulationModeInterrupts *, NativeModeInterrupts *);
|
|
|
|
void setRESPin(bool);
|
|
void setRDYPin(bool);
|
|
|
|
// Temporary
|
|
bool executeNextInstruction();
|
|
|
|
private:
|
|
SystemBus &mSystemBus;
|
|
EmulationModeInterrupts *mEmulationInterrupts;
|
|
NativeModeInterrupts *mNativeInterrupts;
|
|
|
|
// Accumulator register
|
|
uint16_t mA = 0;
|
|
// X index register
|
|
uint16_t mX = 0;
|
|
// Y index register
|
|
uint16_t mY = 0;
|
|
// Status register
|
|
CpuStatus mCpuStatus;
|
|
// Data bank register
|
|
uint8_t mDB = 0;
|
|
// Direct page register
|
|
uint16_t mD = 0;
|
|
|
|
struct {
|
|
// Reset to true means low power mode (do nothing)
|
|
bool RES = true;
|
|
// Ready to false means CPU is waiting for an NMI/IRQ/ABORT/RESET
|
|
bool RDY = false;
|
|
} mPins;
|
|
|
|
Stack mStack;
|
|
|
|
// Address of the current OpCode
|
|
Address mProgramAddress {0x00, 0x0000};
|
|
|
|
// Total number of cycles
|
|
uint64_t mTotalCyclesCounter = 0;
|
|
|
|
bool accumulatorIs8BitWide();
|
|
bool accumulatorIs16BitWide();
|
|
bool indexIs8BitWide();
|
|
bool indexIs16BitWide();
|
|
|
|
uint16_t indexWithXRegister();
|
|
uint16_t indexWithYRegister();
|
|
|
|
Address getAddressOfOpCodeData(OpCode &);
|
|
bool opCodeAddressingCrossesPageBoundary(OpCode &);
|
|
|
|
void setProgramAddress(const Address &);
|
|
void addToCycles(int);
|
|
void subtractFromCycles(int);
|
|
void addToProgramAddress(int);
|
|
void addToProgramAddressAndCycles(int, int);
|
|
|
|
// OpCode Table.
|
|
static OpCode OP_CODE_TABLE[];
|
|
|
|
// OpCodes handling routines.
|
|
// Implementations for these methods can be found in the corresponding OpCode_XXX.cpp file.
|
|
void executeORA(OpCode &);
|
|
void executeORA8Bit(OpCode &);
|
|
void executeORA16Bit(OpCode &);
|
|
void executeStack(OpCode &);
|
|
void executeStatusReg(OpCode &);
|
|
void executeMemoryROL(OpCode &);
|
|
void executeAccumulatorROL(OpCode &);
|
|
void executeROL(OpCode &);
|
|
void executeMemoryROR(OpCode &);
|
|
void executeAccumulatorROR(OpCode &);
|
|
void executeROR(OpCode &);
|
|
void executeInterrupt(OpCode &);
|
|
void executeJumpReturn(OpCode &);
|
|
void execute8BitSBC(OpCode &);
|
|
void execute16BitSBC(OpCode &);
|
|
void execute8BitBCDSBC(OpCode &);
|
|
void execute16BitBCDSBC(OpCode &);
|
|
void executeSBC(OpCode &);
|
|
void execute8BitADC(OpCode &);
|
|
void execute16BitADC(OpCode &);
|
|
void execute8BitBCDADC(OpCode &);
|
|
void execute16BitBCDADC(OpCode &);
|
|
void executeADC(OpCode &);
|
|
void executeSTA(OpCode &);
|
|
void executeSTX(OpCode &);
|
|
void executeSTY(OpCode &);
|
|
void executeSTZ(OpCode &);
|
|
void executeTransfer(OpCode &);
|
|
void executeMemoryASL(OpCode &);
|
|
void executeAccumulatorASL(OpCode &);
|
|
void executeASL(OpCode &);
|
|
void executeAND8Bit(OpCode &);
|
|
void executeAND16Bit(OpCode &);
|
|
void executeAND(OpCode &);
|
|
void executeLDA8Bit(OpCode &);
|
|
void executeLDA16Bit(OpCode &);
|
|
void executeLDA(OpCode &);
|
|
void executeLDX8Bit(OpCode &);
|
|
void executeLDX16Bit(OpCode &);
|
|
void executeLDX(OpCode &);
|
|
void executeLDY8Bit(OpCode &);
|
|
void executeLDY16Bit(OpCode &);
|
|
void executeLDY(OpCode &);
|
|
void executeEOR8Bit(OpCode &);
|
|
void executeEOR16Bit(OpCode &);
|
|
void executeEOR(OpCode &);
|
|
int executeBranchShortOnCondition(bool, OpCode &);
|
|
int executeBranchLongOnCondition(bool, OpCode &);
|
|
void executeBranch(OpCode &);
|
|
void execute8BitCMP(OpCode &);
|
|
void execute16BitCMP(OpCode &);
|
|
void executeCMP(OpCode &);
|
|
void execute8BitDecInMemory(OpCode &);
|
|
void execute16BitDecInMemory(OpCode &);
|
|
void execute8BitIncInMemory(OpCode &);
|
|
void execute16BitIncInMemory(OpCode &);
|
|
void executeINCDEC(OpCode &);
|
|
void execute8BitCPX(OpCode &);
|
|
void execute16BitCPX(OpCode &);
|
|
void execute8BitCPY(OpCode &);
|
|
void execute16BitCPY(OpCode &);
|
|
void executeCPXCPY(OpCode &);
|
|
void execute8BitTSB(OpCode &);
|
|
void execute16BitTSB(OpCode &);
|
|
void execute8BitTRB(OpCode &);
|
|
void execute16BitTRB(OpCode &);
|
|
void executeTSBTRB(OpCode &);
|
|
void execute8BitBIT(OpCode &);
|
|
void execute16BitBIT(OpCode &);
|
|
void executeBIT(OpCode &);
|
|
void executeMemoryLSR(OpCode &);
|
|
void executeAccumulatorLSR(OpCode &);
|
|
void executeLSR(OpCode &);
|
|
void executeMisc(OpCode &);
|
|
|
|
void reset();
|
|
};
|
|
|
|
#endif
|