mirror of
https://github.com/zoriya/ComSquare.git
synced 2026-06-09 20:59:06 +00:00
Implementing MVP
This commit is contained in:
+6
-1
@@ -450,6 +450,11 @@ namespace ComSquare::CPU
|
|||||||
//! @param Y_register Destination address
|
//! @param Y_register Destination address
|
||||||
//! @param C_register (16 bits accumulator) Length -1
|
//! @param C_register (16 bits accumulator) Length -1
|
||||||
int MVN(uint24_t, AddressingMode);
|
int MVN(uint24_t, AddressingMode);
|
||||||
|
//! @brief Block Move Previous. This instruction is special: it takes parameter in the registers
|
||||||
|
//! @param X_register Source address (last byte)
|
||||||
|
//! @param Y_register Destination address (last byte)
|
||||||
|
//! @param C_register (16 bits accumulator) Length -1
|
||||||
|
int MVP(uint24_t, AddressingMode);
|
||||||
|
|
||||||
//! @brief All the instructions of the CPU.
|
//! @brief All the instructions of the CPU.
|
||||||
//! @info Instructions are indexed by their opcode
|
//! @info Instructions are indexed by their opcode
|
||||||
@@ -522,7 +527,7 @@ namespace ComSquare::CPU
|
|||||||
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 41
|
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 41
|
||||||
{&CPU::WDM, 2, "wdm", AddressingMode::Immediate8bits, 2}, // 42
|
{&CPU::WDM, 2, "wdm", AddressingMode::Immediate8bits, 2}, // 42
|
||||||
{&CPU::EOR, 4, "eor", AddressingMode::StackRelative, 2}, // 43
|
{&CPU::EOR, 4, "eor", AddressingMode::StackRelative, 2}, // 43
|
||||||
{&CPU::BRK, 7, "mvp #-#", AddressingMode::Implied, 2}, // 44
|
{&CPU::MVP, 0, "mvp", AddressingMode::Immediate16bits, 3}, // 44
|
||||||
{&CPU::EOR, 3, "eor", AddressingMode::DirectPage, 2}, // 45
|
{&CPU::EOR, 3, "eor", AddressingMode::DirectPage, 2}, // 45
|
||||||
{&CPU::LSR, 5, "lsr", AddressingMode::DirectPage, 2}, // 46
|
{&CPU::LSR, 5, "lsr", AddressingMode::DirectPage, 2}, // 46
|
||||||
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectLong, 2}, // 47
|
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectLong, 2}, // 47
|
||||||
|
|||||||
@@ -168,4 +168,21 @@ namespace ComSquare::CPU
|
|||||||
}
|
}
|
||||||
return 7 * length;
|
return 7 * length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CPU::MVP(uint24_t params, AddressingMode)
|
||||||
|
{
|
||||||
|
uint8_t srcBank = params;
|
||||||
|
uint8_t destBank = params >> 8u;
|
||||||
|
int length = this->_registers.a + 1;
|
||||||
|
|
||||||
|
this->_registers.dbr = destBank;
|
||||||
|
while (this->_registers.a != 0xFFFF) {
|
||||||
|
uint8_t data = this->_bus->read(srcBank << 24u | this->_registers.x);
|
||||||
|
this->_bus->write(destBank << 24u | this->_registers.y, data);
|
||||||
|
this->_registers.x--;
|
||||||
|
this->_registers.y--;
|
||||||
|
this->_registers.a--;
|
||||||
|
}
|
||||||
|
return 7 * length;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -454,4 +454,23 @@ Test(MVN, hardCase)
|
|||||||
cr_assert_eq(snes.cpu->_registers.y, 0x1011, "The y index should be 0x1011 but it was %x", snes.cpu->_registers.y);
|
cr_assert_eq(snes.cpu->_registers.y, 0x1011, "The y index should be 0x1011 but it was %x", snes.cpu->_registers.y);
|
||||||
for (int i = 0; i < 0x11; i++)
|
for (int i = 0; i < 0x11; i++)
|
||||||
cr_assert_eq(snes.wram->_data[i + 0x1000], i, "The data in ram should be %x but it was %x", i, snes.wram->_data[i + 0x1000]);
|
cr_assert_eq(snes.wram->_data[i + 0x1000], i, "The data in ram should be %x but it was %x", i, snes.wram->_data[i + 0x1000]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Test(MVP, hardCase)
|
||||||
|
{
|
||||||
|
Init()
|
||||||
|
snes.cpu->_registers.a = 0x10;
|
||||||
|
snes.cpu->_registers.x = 0x0010;
|
||||||
|
snes.cpu->_registers.y = 0x1010;
|
||||||
|
for (int i = 0; i <= snes.cpu->_registers.a; i++)
|
||||||
|
snes.wram->_data[i] = i;
|
||||||
|
|
||||||
|
int cycles = snes.cpu->MVP(0x2010, ComSquare::CPU::AddressingMode::Implied);
|
||||||
|
cr_assert_eq(cycles, 0x77, "The MVN should take 0x77 cycles but it took %x.", cycles);
|
||||||
|
cr_assert_eq(snes.cpu->_registers.dbr, 0x20, "The data bank register should be 0x20 but it was %x", snes.cpu->_registers.dbr);
|
||||||
|
cr_assert_eq(snes.cpu->_registers.a, 0xFFFF, "The c accumulator should be 0xFFFF but it was %x", snes.cpu->_registers.a);
|
||||||
|
cr_assert_eq(snes.cpu->_registers.x, 0xFFFF, "The x index should be 0xFFFF but it was %x", snes.cpu->_registers.x);
|
||||||
|
cr_assert_eq(snes.cpu->_registers.y, 0x0FFF, "The y index should be 0x0FFF but it was %x", snes.cpu->_registers.y);
|
||||||
|
for (int i = 0; i < 0x11; i++)
|
||||||
|
cr_assert_eq(snes.wram->_data[i + 0x1000], i, "The data in ram should be %x but it was %x", i, snes.wram->_data[i + 0x1000]);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user