Implementing PER

This commit is contained in:
Anonymus Raccoon
2020-05-13 17:52:47 +02:00
parent b29d1c4216
commit 876b78a5c9
6 changed files with 39 additions and 7 deletions
+7
View File
@@ -14,6 +14,13 @@ namespace ComSquare::CPU
return ret;
}
uint24_t CPU::_getImmediateAddr16Bits()
{
uint24_t ret = this->_registers.pac;
this->_registers.pc += 2;
return ret;
}
uint24_t CPU::_getImmediateAddrForA()
{
uint24_t effective = this->_registers.pac;
+2 -4
View File
@@ -6,9 +6,7 @@
#include <utility>
#include <iostream>
#include "../Exceptions/NotImplementedException.hpp"
#include "../Exceptions/InvalidAddress.hpp"
#include "../Exceptions/InvalidOpcode.hpp"
namespace ComSquare::CPU
{
@@ -218,6 +216,8 @@ namespace ComSquare::CPU
return 0;
case Immediate8bits:
return this->_getImmediateAddr8Bits();
case Immediate16bits:
return this->_getImmediateAddr16Bits();
case ImmediateForA:
return this->_getImmediateAddrForA();
case ImmediateForX:
@@ -264,8 +264,6 @@ namespace ComSquare::CPU
case AbsoluteIndirectIndexedByX:
return this->_getAbsoluteIndirectIndexedByXAddr();
default:
return 0;
}
}
+7 -3
View File
@@ -198,8 +198,10 @@ namespace ComSquare::CPU
//! @brief True if an addressing mode with an iterator (x, y) has crossed the page. (Used because crossing the page boundary take one more cycle to run certain instructions).
bool _hasIndexCrossedPageBoundary = false;
//! @brief Immediate address mode is specified with a value in 8. (This functions returns the 24bit space address of the value).
//! @brief Immediate address mode is specified with a value in 8 bits. (This functions returns the 24bit space address of the value).
uint24_t _getImmediateAddr8Bits();
//! @brief Immediate address mode is specified with a value in 16 bits. (This functions returns the 24bit space address of the value).
uint24_t _getImmediateAddr16Bits();
//! @brief Immediate address mode is specified with a value in 8 or 16 bits. The value is 16 bits if the m flag is unset. (This functions returns the 24bit space address of the value).
uint24_t _getImmediateAddrForA();
//! @brief Immediate address mode is specified with a value in 8 or 16 bits. The value is 16 bits if the x flag is unset. (This functions returns the 24bit space address of the value).
@@ -431,6 +433,8 @@ namespace ComSquare::CPU
int ROL(uint24_t, AddressingMode);
// !@brief Rotate Right
int ROR(uint24_t, AddressingMode);
//! @brief Push Effective PC Relative Indirect Address
int PER(uint24_t, AddressingMode);
//! @brief All the instructions of the CPU.
//! @info Instructions are indexed by their opcode
@@ -533,7 +537,7 @@ namespace ComSquare::CPU
{&CPU::EOR, 5, "eor", AddressingMode::AbsoluteIndexedByXLong, 4}, // 5F
{&CPU::RTL, 6, "rtl", AddressingMode::Implied, 1}, // 60
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 61
{&CPU::BRK, 7, "per #-#", AddressingMode::Implied, 2}, // 62
{&CPU::PER, 6, "per", AddressingMode::Immediate16bits, 3}, // 62
{&CPU::ADC, 4, "adc", AddressingMode::StackRelative, 2}, // 63
{&CPU::STZ, 3, "stz", AddressingMode::DirectPage, 2}, // 64
{&CPU::ADC, 3, "adc", AddressingMode::DirectPage, 2}, // 65
@@ -606,7 +610,7 @@ namespace ComSquare::CPU
{&CPU::TAY, 2, "tay", AddressingMode::Implied, 1}, // A8
{&CPU::LDA, 2, "lda", AddressingMode::ImmediateForA, 2}, // A9
{&CPU::TAX, 2, "tax", AddressingMode::Implied, 1}, // AA
{&CPU::BRK, 7, "trb #-#", AddressingMode::Implied, 2}, // AB
{&CPU::BRK, 7, "plb #-#", AddressingMode::Implied, 2}, // AB
{&CPU::LDY, 4, "ldy", AddressingMode::Absolute, 4}, // AC
{&CPU::LDA, 4, "lda", AddressingMode::Absolute, 3}, // AD
{&CPU::LDX, 4, "ldx", AddressingMode::Absolute, 3}, // AE
+1
View File
@@ -17,6 +17,7 @@ namespace ComSquare::CPU
Implied,
Immediate8bits,
Immediate16bits,
ImmediateForA,
ImmediateForX,
@@ -184,6 +184,15 @@ namespace ComSquare::CPU
return !this->_registers.p.x_b;
}
int CPU::PER(uint24_t valueAddr, AddressingMode)
{
uint16_t value = this->_bus->read(valueAddr);
value += this->_bus->read(valueAddr + 1) << 8u;
value += this->_registers.pc;
this->_push(value);
return 0;
}
int CPU::XCE(uint24_t, AddressingMode)
{
bool oldCarry = this->_registers.p.c;
+13
View File
@@ -914,4 +914,17 @@ Test(JML, simpleJump)
snes.cpu->_registers.pc = 0x8000;
snes.cpu->JML(0x10AB00, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.pac, 0x10AB00, "The program counter should be equal to 0x10AB00 but it was 0x%x.", snes.cpu->_registers.pac);
}
Test(PER, simple)
{
Init()
snes.cpu->_registers.pac = 0x008005;
snes.cpu->_registers.s = 0x1FFF;
snes.wram->_data[0x0] = 0xFF;
snes.wram->_data[0x1] = 0xFF;
snes.cpu->PER(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.s, 0x1FFD, "The stack pointer should be equal to 0x1FFD but it was 0x%x.", snes.cpu->_registers.s);
uint16_t value = snes.cpu->_pop16();
cr_assert_eq(value, 0x8004, "The pushed value should be equal to 0x8004 but it was 0x%x.", value);
}