fruitmachine/M6502EmulatorDll/M6502EmulatorDll/CPU.h

264 lines
5.8 KiB
C++

#include <stdint.h>
#include <vector>
#include "memory.h"
#pragma once
class CPU {
private:
//PSW
bool FLAG_SIGN; //N
bool FLAG_OVERFLOW; //V
//-
bool FLAG_BREAKPOINT; //B
bool FLAG_DECIMAL; //D
bool FLAG_INTERRUPT; //I
bool FLAG_ZERO; //Z
bool FLAG_CARRY; //C
//registers
uint8_t accumulator; //A
uint8_t index_x; //X
uint8_t index_y; //Y
uint8_t stack_pointer; //SP
uint16_t program_counter; //PC
uint16_t old_program_counter; //before this opcode ran
uint16_t last_operand;
int loopCount = 0;
int cycles = 0;
int maxCycles = 17050; //roughly 1MHz
public:
std::string last_executed_opcode;
std::vector<std::string> last_executed_opcodes;
enum ADDRESSING_MODE { ADDRESSING_IMMEDIATE, ADDRESSING_ABSOLUTE, ADDRESSING_ABSOLUTE_X, ADDRESSING_ABSOLUTE_Y, ADDRESSING_ZEROPAGE, ADDRESSING_ZEROPAGE_X, ADDRESSING_ZEROPAGE_Y, ADDRESSING_INDIRECT, ADDRESSING_INDIRECT_X, ADDRESSING_INDIRECT_Y };
enum INDEX_MODE { INDEX_NONE = 0x01, INDEX_X = 0x02, INDEX_Y = 0x03 };
static bool lastInstructionCrossedPageBoundary;
bool frameInstructionsComplete();
void resetCycleCounter();
void reset_processor() {
lastInstructionCrossedPageBoundary = false;
FLAG_SIGN = false;
FLAG_OVERFLOW = false;
FLAG_BREAKPOINT = false;
FLAG_DECIMAL = false;
FLAG_INTERRUPT = true;
FLAG_ZERO = false;
FLAG_CARRY = false;
accumulator = 0;
index_x = 0;
index_y = 0;
stack_pointer = 0xFF;
program_counter = 0xFFFC; //apple
//program_counter = 0x0400; //test
execute_opcode(0x4c); //jump to reset vector destination
}
uint8_t getAccumulator();
void setAccumulator(uint8_t acc) {
accumulator = acc;
}
uint8_t getCarry() {
return FLAG_CARRY;
}
void setCarry(bool val) {
FLAG_CARRY = val;
}
bool getSignFlag();
bool getOverflowFlag();
bool getBreakpointFlag();
bool getDecimalFlag();
bool getInterruptFlag();
bool getZeroFlag();
bool getCarryFlag();
uint8_t getIndexX();
uint8_t getIndexY();
uint8_t getStackPointer();
uint16_t getProgramCounter();
uint16_t getOldProgramCounter();
uint16_t getCycleCount();
uint8_t getProgramStatusWord();
void setProgramStatusWord(uint8_t psw);
void process_instruction();
void execute_opcode(uint8_t opcode);
void set_zero_and_sign_flags(uint8_t data);
void stack_push(uint8_t data);
uint8_t stack_pop();
uint8_t fetch_memory_byte(WideAddress address, bool incrementPc = true);
uint8_t fetch_memory_byte(uint16_t address, bool incrementPc = true);
uint8_t fetch_zero_page_byte(uint8_t);
void write_memory_byte(uint16_t, uint8_t);
void write_memory_byte(WideAddress, uint8_t);
void write_zero_page_byte(uint8_t, uint8_t);
WideAddress fetch_dereferenced_zero_page_pointer(INDEX_MODE mode);
WideAddress dereference_indirect_address(uint8_t zero_page_pointer);
WideAddress dereference_indirect_address(WideAddress pointer);
uint8_t fetch_operand(ADDRESSING_MODE);
WideAddress fetch_operand_address(ADDRESSING_MODE);
uint8_t fetch_destination(ADDRESSING_MODE mode);
void print_status(uint8_t opcode);
/* Opcodes */
void CPU::op_adc(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_adc(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_and(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_and(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_asl(WideAddress address);
void CPU::op_asl();
void CPU::op_bcc(int8_t relative);
void CPU::op_bcs(int8_t relative);
void CPU::op_beq(int8_t relative);
void CPU::op_bit(WideAddress address);
void CPU::op_bmi(int8_t relative);
void CPU::op_bne(int8_t relative);
void CPU::op_bpl(int8_t relative);
void CPU::op_brk();
void CPU::op_bvc(int8_t relative);
void CPU::op_bvs(int8_t relative);
void CPU::op_clc();
void CPU::op_cld();
void CPU::op_cli();
void CPU::op_clv();
void CPU::op_cmp(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_cmp(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_cpx(uint8_t immediate);
void CPU::op_cpx(WideAddress address);
void CPU::op_cpy(uint8_t immediate);
void CPU::op_cpy(WideAddress address);
void CPU::op_dec(WideAddress address);
void CPU::op_dex();
void CPU::op_dey();
void CPU::op_eor(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_eor(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_inc(WideAddress address);
void CPU::op_inx();
void CPU::op_iny();
void CPU::op_jmp(WideAddress address);
void CPU::op_jsr(WideAddress address);
void CPU::op_lda(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_lda(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_ldx(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_ldx(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_ldy(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_ldy(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_lsr();
void CPU::op_lsr(WideAddress address);
void CPU::op_nop();
void CPU::op_ora(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_ora(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_pha();
void CPU::op_php();
void CPU::op_pla();
void CPU::op_plp();
void CPU::op_rol();
void CPU::op_rol(WideAddress address);
void CPU::op_ror();
void CPU::op_ror(WideAddress address);
void CPU::op_rti();
void CPU::op_rts();
void CPU::op_sbc(uint8_t immediate, bool crossedPageBoundary = false);
void CPU::op_sbc(WideAddress address, bool crossedPageBoundary = false);
void CPU::op_sec();
void CPU::op_sed();
void CPU::op_sei();
void CPU::op_sta(WideAddress address);
void CPU::op_stx(WideAddress address);
void CPU::op_sty(WideAddress address);
void CPU::op_tax();
void CPU::op_tay();
void CPU::op_tsx();
void CPU::op_txa();
void CPU::op_txs();
void CPU::op_tya();
};