mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-05-24 15:18:44 +00:00
Implementing PER
This commit is contained in:
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user