Adding all the ADC in the instruction switch case

This commit is contained in:
AnonymusRaccoon
2020-02-11 14:26:39 +01:00
parent 40d7ef1c39
commit 69f9528d20
4 changed files with 65 additions and 37 deletions

View File

@@ -199,24 +199,24 @@ namespace ComSquare::CPU
uint8_t opcode = this->_bus->read(this->_registers.pc); uint8_t opcode = this->_bus->read(this->_registers.pc);
switch (opcode) { switch (opcode) {
case 0x0: case Instructions::BRK: return this->BRK();
return this->BRK();
case 0x61: case Instructions::ADC_DPXi: return this->ADC(this->_getDirectIndirectIndexedXAddr());
case 0x63: case Instructions::ADC_SR: return this->ADC(this->_getStackRelativeAddr());
case 0x65: case Instructions::ADC_DP: return this->ADC(this->_getDirectAddr());
case 0x67: case Instructions::ADC_DPil: return this->ADC(this->_getDirectIndirectLongAddr());
case 0x69: case Instructions::ADC_IM: return this->ADC(this->_getImmediateAddr());
case 0x6D: case Instructions::ADC_ABS: return this->ADC(this->_getAbsoluteAddr());
case 0x6F: case Instructions::ADC_ABSl: return this->ADC(this->_getAbsoluteLongAddr());
case 0x71: case Instructions::ADC_DPYi: return this->ADC(this->_getDirectIndirectIndexedYAddr());
case 0x72: case Instructions::ADC_DPi: return this->ADC(this->_getDirectIndirectAddr());
case 0x73: case Instructions::ADC_SRYi: return this->ADC(this->_getStackRelativeIndirectIndexedYAddr());
case 0x75: case Instructions::ADC_DPX: return this->ADC(this->_getDirectIndexedByXAddr());
case 0x77: case Instructions::ADC_DPYil:return this->ADC(this->_getDirectIndirectIndexedYLongAddr());
case 0x79: case Instructions::ADC_ABSY: return this->ADC(this->_getAbsoluteIndexedByYAddr());
case 0x7D: case Instructions::ADC_ABSX: return this->ADC(this->_getAbsoluteIndexedByXAddr());
case 0x7F: case Instructions::ADC_ABSXl:return this->ADC(this->_getAbsoluteIndexedByXLongAddr());
return this->ADC();
default: default:
throw InvalidOpcode("CPU", opcode); throw InvalidOpcode("CPU", opcode);
} }
@@ -253,7 +253,7 @@ namespace ComSquare::CPU
return addr; return addr;
} }
uint24_t CPU::_getDirectIndirectIndexedAddr() uint24_t CPU::_getDirectIndirectIndexedYAddr()
{ {
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint24_t base = this->_bus->read(dp); uint24_t base = this->_bus->read(dp);
@@ -262,7 +262,7 @@ namespace ComSquare::CPU
return base + this->_registers.y; return base + this->_registers.y;
} }
uint24_t CPU::_getDirectIndirectIndexedLongAddr() uint24_t CPU::_getDirectIndirectIndexedYLongAddr()
{ {
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
uint24_t base = this->_bus->read(dp); uint24_t base = this->_bus->read(dp);
@@ -271,7 +271,7 @@ namespace ComSquare::CPU
return base; return base;
} }
uint24_t CPU::_getDirectIndexedIndirectAddr() uint24_t CPU::_getDirectIndirectIndexedXAddr()
{ {
uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d; uint16_t dp = this->_bus->read(this->_registers.pac++) + this->_registers.d;
dp += this->_registers.x; dp += this->_registers.x;
@@ -311,7 +311,7 @@ namespace ComSquare::CPU
return effective + this->_registers.y; return effective + this->_registers.y;
} }
uint24_t CPU::_getAbsoluteLongIndexedByXAddr() uint24_t CPU::_getAbsoluteIndexedByXLongAddr()
{ {
uint24_t lng = this->_bus->read(this->_registers.pac++); uint24_t lng = this->_bus->read(this->_registers.pac++);
lng += this->_bus->read(this->_registers.pac++) << 8u; lng += this->_bus->read(this->_registers.pac++) << 8u;
@@ -377,7 +377,7 @@ namespace ComSquare::CPU
return this->_bus->read(this->_registers.pac++) + this->_registers.s; return this->_bus->read(this->_registers.pac++) + this->_registers.s;
} }
uint24_t CPU::_getStackRelativeIndirectIndexedAddr() uint24_t CPU::_getStackRelativeIndirectIndexedYAddr()
{ {
uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s; uint24_t base = this->_bus->read(this->_registers.pac++) + this->_registers.s;
base += this->_registers.dbr << 16u; base += this->_registers.dbr << 16u;

View File

@@ -180,6 +180,30 @@ namespace ComSquare::CPU
uint8_t joy4h; uint8_t joy4h;
}; };
//! @brief All the instructions opcode of the main CPI.
//! @info The name of the instruction followed by their parameters (after an underscore) if any.
//! @info Addr mode with an i at the end means indirect.
//! @info Addr mode with an l at the end means long.
enum Instructions
{
BRK = 0x00,
ADC_DPXi = 0x61,
ADC_SR = 0x63,
ADC_DP = 0x65,
ADC_DPil = 0x67,
ADC_IM = 0x69,
ADC_ABS = 0x6D,
ADC_ABSl = 0x6F,
ADC_DPYi = 0x71,
ADC_DPi = 0x72,
ADC_SRYi = 0x73,
ADC_DPX = 0x75,
ADC_DPYil = 0x77,
ADC_ABSY = 0x79,
ADC_ABSX = 0x7D,
ADC_ABSXl = 0x7F
};
//! @brief The main CPU //! @brief The main CPU
class CPU : public CommonInstructions, public Memory::IMemory { class CPU : public CommonInstructions, public Memory::IMemory {
private: private:
@@ -203,11 +227,11 @@ namespace ComSquare::CPU
//! @brief The effective address is the expression. (This functions returns the 24bit space address of the value). //! @brief The effective address is the expression. (This functions returns the 24bit space address of the value).
uint24_t _getAbsoluteLongAddr(); uint24_t _getAbsoluteLongAddr();
//! @brief The address is DBR:$(read($($Value + D)) + Y). (This functions returns the 24bit space address of the value). //! @brief The address is DBR:$(read($($Value + D)) + Y). (This functions returns the 24bit space address of the value).
uint24_t _getDirectIndirectIndexedAddr(); uint24_t _getDirectIndirectIndexedYAddr();
//! @brief This mode is like the previous addressing mode, but the difference is that rather than pulling 2 bytes from the DP address, it pulls 3 bytes to form the effective address. //! @brief This mode is like the previous addressing mode, but the difference is that rather than pulling 2 bytes from the DP address, it pulls 3 bytes to form the effective address.
uint24_t _getDirectIndirectIndexedLongAddr(); uint24_t _getDirectIndirectIndexedYLongAddr();
//! @brief The direct page address is calculated and added with x. 2 bytes from the dp address combined with DBR will form the effective address. //! @brief The direct page address is calculated and added with x. 2 bytes from the dp address combined with DBR will form the effective address.
uint24_t _getDirectIndexedIndirectAddr(); uint24_t _getDirectIndirectIndexedXAddr();
//! @brief The DP address is added to X to form the effective address. The effective address is always in bank 0. //! @brief The DP address is added to X to form the effective address. The effective address is always in bank 0.
uint24_t _getDirectIndexedByXAddr(); uint24_t _getDirectIndexedByXAddr();
//! @brief The DP address is added to Y to form the effective address. The effective address is always in bank 0. //! @brief The DP address is added to Y to form the effective address. The effective address is always in bank 0.
@@ -217,7 +241,7 @@ namespace ComSquare::CPU
//! @brief The absolute expression is added with Y and combined with DBR to form the effective address. //! @brief The absolute expression is added with Y and combined with DBR to form the effective address.
uint24_t _getAbsoluteIndexedByYAddr(); uint24_t _getAbsoluteIndexedByYAddr();
//! @brief The effective address is formed by adding the <long exp> with X. //! @brief The effective address is formed by adding the <long exp> with X.
uint24_t _getAbsoluteLongIndexedByXAddr(); uint24_t _getAbsoluteIndexedByXLongAddr();
//! @brief The <8-bit signed exp> is added to PC (program counter) to form the new location. //! @brief The <8-bit signed exp> is added to PC (program counter) to form the new location.
uint24_t _getProgramCounterRelativeAddr(); uint24_t _getProgramCounterRelativeAddr();
//! @brief The <16-bit signed exp> is added to PC (program counter) to form the new location. //! @brief The <16-bit signed exp> is added to PC (program counter) to form the new location.
@@ -233,17 +257,17 @@ namespace ComSquare::CPU
//! @brief The stack register is added to the <8-bit exp> to form the effective address. //! @brief The stack register is added to the <8-bit exp> to form the effective address.
uint24_t _getStackRelativeAddr(); uint24_t _getStackRelativeAddr();
//! @brief The <8-bit exp> is added to S and combined with DBR to form the base address. Y is added to the base address to form the effective address. //! @brief The <8-bit exp> is added to S and combined with DBR to form the base address. Y is added to the base address to form the effective address.
uint24_t _getStackRelativeIndirectIndexedAddr(); uint24_t _getStackRelativeIndirectIndexedYAddr();
//! @brief Execute a single instruction. //! @brief Execute a single instruction.
//! @return The number of CPU cycles that the instruction took. //! @return The number of CPU cycles that the instruction took.
int executeInstruction(); int executeInstruction();
//! @brief Break instruction (0x00) - Causes a software break. The PC is loaded from a vector table. //! @brief Break instruction - Causes a software break. The PC is loaded from a vector table.
int BRK(); int BRK();
//! @brief Add with carry (0x61, 0x63, 0x65, 0x67, 0x69, 0x6D, 0x6F, 0x71, 0x72, 0x73, 0x75, 0x77, 0x79, 0x7D, 0x7F) - Adds operand to the Accumulator; adds an additional 1 if carry is set. //! @brief Add with carry - Adds operand to the Accumulator; adds an additional 1 if carry is set.
int ADC(); int ADC(uint24_t valueAddr);
public: public:
explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader); explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader);
//! @brief This function continue to execute the Cartridge code. //! @brief This function continue to execute the Cartridge code.

View File

@@ -6,7 +6,7 @@
namespace ComSquare::CPU namespace ComSquare::CPU
{ {
int CPU::ADC() int CPU::ADC(uint24_t valueAddr)
{ {
// this->_registers.a += // this->_registers.a +=
} }

View File

@@ -75,7 +75,8 @@ Test(AddrMode, DirectIndirectIndexed)
pair.second.cpu->_registers.dbr = 0x80; pair.second.cpu->_registers.dbr = 0x80;
pair.second.cpu->_registers.y = 0x0001; pair.second.cpu->_registers.y = 0x0001;
pair.second.cpu->_registers.d = 0x1000; pair.second.cpu->_registers.d = 0x1000;
cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedAddr(), 0x804031, "Returned address was %x but was expecting 0x804031.", pair.second.cpu->_getDirectIndirectIndexedAddr()); cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedYAddr(), 0x804031, "Returned address was %x but was expecting 0x804031.",
pair.second.cpu->_getDirectIndirectIndexedYAddr());
cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001);
} }
@@ -88,7 +89,8 @@ Test(AddrMode, DirectIndirectIndexedLong)
pair.second.wram->_data[0x1010] = 0x30; pair.second.wram->_data[0x1010] = 0x30;
pair.second.wram->_data[0x1011] = 0x40; pair.second.wram->_data[0x1011] = 0x40;
pair.second.wram->_data[0x1012] = 0x23; pair.second.wram->_data[0x1012] = 0x23;
cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedLongAddr(), 0x234030, "Returned address was %x but was expecting 0x234030.", pair.second.cpu->_getDirectIndirectIndexedLongAddr()); cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedYLongAddr(), 0x234030, "Returned address was %x but was expecting 0x234030.",
pair.second.cpu->_getDirectIndirectIndexedYLongAddr());
cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001);
} }
@@ -102,7 +104,8 @@ Test(AddrMode, DirectIndexedIndirect)
pair.second.wram->_data[0x1013] = 0x40; pair.second.wram->_data[0x1013] = 0x40;
pair.second.cpu->_registers.dbr = 0x80; pair.second.cpu->_registers.dbr = 0x80;
pair.second.cpu->_registers.pac = 0x808000; pair.second.cpu->_registers.pac = 0x808000;
cr_assert_eq(pair.second.cpu->_getDirectIndexedIndirectAddr(), 0x804030, "Returned address was %x but was expecting 0x804030.", pair.second.cpu->_getDirectIndexedIndirectAddr()); cr_assert_eq(pair.second.cpu->_getDirectIndirectIndexedXAddr(), 0x804030, "Returned address was %x but was expecting 0x804030.",
pair.second.cpu->_getDirectIndirectIndexedXAddr());
cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001);
} }
@@ -160,7 +163,8 @@ Test(AddrMode, AbsoluteLongIndexByX)
pair.second.cartridge->_data[1] = 0xAC; pair.second.cartridge->_data[1] = 0xAC;
pair.second.cartridge->_data[2] = 0xEF; pair.second.cartridge->_data[2] = 0xEF;
pair.second.cpu->_registers.x = 0x0005; pair.second.cpu->_registers.x = 0x0005;
cr_assert_eq(pair.second.cpu->_getAbsoluteLongIndexedByXAddr(), 0xEFAC15, "Returned address was %x but was expecting 0xEFAC15.", pair.second.cpu->_getAbsoluteLongIndexedByXAddr()); cr_assert_eq(pair.second.cpu->_getAbsoluteIndexedByXLongAddr(), 0xEFAC15, "Returned address was %x but was expecting 0xEFAC15.",
pair.second.cpu->_getAbsoluteIndexedByXLongAddr());
cr_assert_eq(pair.second.cpu->_registers.pac, 0x808003); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808003);
} }
@@ -278,7 +282,7 @@ Test(AddrMode, StackRelativeIndirectIndexed)
pair.second.cpu->_registers.s = 0x1010; pair.second.cpu->_registers.s = 0x1010;
pair.second.cpu->_registers.y = 0x5; pair.second.cpu->_registers.y = 0x5;
pair.second.cpu->_registers.dbr = 0x88; pair.second.cpu->_registers.dbr = 0x88;
auto addr = pair.second.cpu->_getStackRelativeIndirectIndexedAddr(); auto addr = pair.second.cpu->_getStackRelativeIndirectIndexedYAddr();
cr_assert_eq(addr, 0x88101B, "Returned address was %x but was expecting 0x88101B.", addr); cr_assert_eq(addr, 0x88101B, "Returned address was %x but was expecting 0x88101B.", addr);
cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001); cr_assert_eq(pair.second.cpu->_registers.pac, 0x808001);
} }