Adding most of the transfer instructions

This commit is contained in:
Anonymus Raccoon
2020-04-07 22:40:53 +02:00
parent a40bfd1c3c
commit f35427f28a
3 changed files with 337 additions and 8 deletions
+21 -7
View File
@@ -397,6 +397,20 @@ namespace ComSquare::CPU
int DEC(uint24_t, AddressingMode);
//! @brief XOR, Exclusive OR accumulator with memory.
int EOR(uint24_t, AddressingMode);
//! @brief Transfer 16 bit A to DP
int TCD(uint24_t, AddressingMode);
//! @brief Transfer 16 bit A to SP
int TCS(uint24_t, AddressingMode);
//! @brief Transfer DP to 16 bit A
int TDC(uint24_t, AddressingMode);
//! @brief Transfer DP to 16 bit A
int TSC(uint24_t, AddressingMode);
//! @brief Transfer SP to X
int TSX(uint24_t, AddressingMode);
//! @brief Transfer X to A
int TXA(uint24_t, AddressingMode);
//! @brief Transfer Y to A
int TYA(uint24_t, AddressingMode);
//! @brief All the instructions of the CPU.
//! @info Instructions are indexed by their opcode
@@ -428,7 +442,7 @@ namespace ComSquare::CPU
{&CPU::CLC, 2, "clc", AddressingMode::Implied, 1}, // 18
{&CPU::ORA, 4, "ora", AddressingMode::AbsoluteIndexedByY, 3}, // 19
{&CPU::INC, 2, "inc", AddressingMode::Implied, 1}, // 1A
{&CPU::BRK, 7, "tcs #-#", AddressingMode::Implied, 2}, // 1B
{&CPU::TCS, 2, "tcs", AddressingMode::Implied, 1}, // 1B
{&CPU::BRK, 7, "trb #-#", AddressingMode::Implied, 2}, // 1C
{&CPU::ORA, 4, "ora", AddressingMode::AbsoluteIndexedByX, 3}, // 1D
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 1E
@@ -460,7 +474,7 @@ namespace ComSquare::CPU
{&CPU::SEC, 2, "sec", AddressingMode::Implied, 1}, // 38
{&CPU::AND, 4, "and", AddressingMode::AbsoluteIndexedByY, 3}, // 39
{&CPU::DEC, 2, "dec", AddressingMode::Implied, 1}, // 3A
{&CPU::BRK, 7, "tsc #-#", AddressingMode::Implied, 2}, // 3B
{&CPU::TSC, 2, "tsc", AddressingMode::Implied, 1}, // 3B
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 3C
{&CPU::AND, 4, "and", AddressingMode::AbsoluteIndexedByX, 3}, // 3D
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 3E
@@ -492,7 +506,7 @@ namespace ComSquare::CPU
{&CPU::CLI, 2, "cli", AddressingMode::Implied, 1}, // 58
{&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByY, 3}, // 59
{&CPU::PHY, 3, "phy", AddressingMode::Implied, 1}, // 5A
{&CPU::BRK, 7, "tcd #-#", AddressingMode::Implied, 2}, // 5B
{&CPU::TCD, 2, "tcd", AddressingMode::Implied, 1}, // 5B
{&CPU::JML, 4, "jml", AddressingMode::Implied, 4}, // 5C
{&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByX, 3}, // 5D
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 5E
@@ -524,7 +538,7 @@ namespace ComSquare::CPU
{&CPU::SEI, 2, "sei", AddressingMode::Implied, 1}, // 78
{&CPU::ADC, 4, "adc", AddressingMode::AbsoluteIndexedByY, 2}, // 79
{&CPU::PLY, 4, "ply", AddressingMode::Implied, 1}, // 7A
{&CPU::BRK, 7, "tdc #-#", AddressingMode::Implied, 2}, // 7B
{&CPU::TDC, 2, "tdc", AddressingMode::Implied, 1}, // 7B
{&CPU::JMP, 6, "jmp", AddressingMode::AbsoluteIndirectIndexedByX, 3}, // 7C
{&CPU::ADC, 4, "adc", AddressingMode::AbsoluteIndexedByX, 3}, // 7D
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 7E
@@ -539,7 +553,7 @@ namespace ComSquare::CPU
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndirectLong, 2}, // 87
{&CPU::DEY, 2, "dey", AddressingMode::Implied, 1}, // 88
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 89
{&CPU::BRK, 7, "txa #-#", AddressingMode::Implied, 2}, // 8A
{&CPU::TXA, 2, "txa", AddressingMode::Implied, 2}, // 8A
{&CPU::PHB, 3, "phb", AddressingMode::Implied, 1}, // 8B
{&CPU::STY, 4, "sty", AddressingMode::Absolute, 3}, // 8C
{&CPU::STA, 4, "sta", AddressingMode::Absolute, 3}, // 8D
@@ -553,7 +567,7 @@ namespace ComSquare::CPU
{&CPU::STA, 4, "sta", AddressingMode::DirectPageIndexedByX, 2}, // 95
{&CPU::STX, 4, "stx", AddressingMode::DirectPageIndexedByY, 2}, // 96
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 97
{&CPU::BRK, 7, "tya #-#", AddressingMode::Implied, 2}, // 98
{&CPU::TYA, 2, "tya", AddressingMode::Implied, 1}, // 98
{&CPU::STA, 5, "sta", AddressingMode::AbsoluteIndexedByY, 3}, // 99
{&CPU::TXS, 2, "txs", AddressingMode::Implied, 1}, // 9A
{&CPU::BRK, 7, "txy #-#", AddressingMode::Implied, 2}, // 9B
@@ -587,7 +601,7 @@ namespace ComSquare::CPU
{&CPU::LDA, 6, "lda", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // B7
{&CPU::CLV, 7, "clv", AddressingMode::Implied, 1}, // B8
{&CPU::LDA, 4, "lda", AddressingMode::AbsoluteIndexedByY, 3}, // B9
{&CPU::BRK, 7, "mvn #-#", AddressingMode::Implied, 2}, // BA
{&CPU::TSX, 2, "tsx", AddressingMode::Implied, 1}, // BA
{&CPU::BRK, 7, "tyx #-#", AddressingMode::Implied, 2}, // BB
{&CPU::LDY, 4, "ldy", AddressingMode::AbsoluteIndexedByX, 3}, // BC
{&CPU::LDA, 4, "lda", AddressingMode::AbsoluteIndexedByX, 3}, // BD
@@ -48,4 +48,80 @@ namespace ComSquare::CPU
}
return 0;
}
int CPU::TCD(uint24_t, AddressingMode)
{
this->_registers.d = this->_registers.a;
this->_registers.p.n = this->_registers.d & 0x8000u;
this->_registers.p.z = this->_registers.d == 0;
return 0;
}
int CPU::TCS(uint24_t, AddressingMode)
{
this->_registers.s = this->_registers.a;
if (this->_isEmulationMode)
this->_registers.sh = 1;
return 0;
}
int CPU::TDC(uint24_t, AddressingMode)
{
this->_registers.a = this->_registers.d;
this->_registers.p.n = this->_registers.a & 0x8000u;
this->_registers.p.z = this->_registers.a == 0;
return 0;
}
int CPU::TSC(uint24_t, AddressingMode)
{
this->_registers.a = this->_registers.s;
this->_registers.p.n = this->_registers.a & 0x8000u;
this->_registers.p.z = this->_registers.a == 0;
return 0;
}
int CPU::TSX(uint24_t, AddressingMode)
{
unsigned negativeFlag = this->_registers.p.x_b ? 0x80u : 0x8000u;
this->_registers.x = this->_registers.s;
if (this->_registers.p.x_b)
this->_registers.xh = 0;
this->_registers.p.n = this->_registers.x & negativeFlag;
this->_registers.p.z = this->_registers.x == 0;
return 0;
}
int CPU::TXA(uint24_t, AddressingMode)
{
unsigned negativeFlag = this->_registers.p.m ? 0x80u : 0x8000u;
if (this->_registers.p.m)
this->_registers.al = this->_registers.xl;
else {
this->_registers.a = this->_registers.x;
if (this->_registers.p.x_b)
this->_registers.ah = 0;
}
this->_registers.p.n = this->_registers.a & negativeFlag;
this->_registers.p.z = this->_registers.a == 0;
return 0;
}
int CPU::TYA(uint24_t, AddressingMode)
{
unsigned negativeFlag = this->_registers.p.m ? 0x80u : 0x8000u;
if (this->_registers.p.m)
this->_registers.al = this->_registers.yl;
else {
this->_registers.a = this->_registers.y;
if (this->_registers.p.x_b)
this->_registers.ah = 0;
}
this->_registers.p.n = this->_registers.a & negativeFlag;
this->_registers.p.z = this->_registers.a == 0;
return 0;
}
}
+240 -1
View File
@@ -144,4 +144,243 @@ Test(TXS, 8bitsIndex)
cr_assert_eq(snes.cpu->_registers.s, 0x00CD, "The stack pointer should be 0x00CD but it was %x", snes.cpu->_registers.s);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
}
Test(TCD, emulationMode)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.d = 0x5656;
snes.cpu->_registers.a = 0xABCD;
snes.cpu->TCD(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.d, 0xABCD, "The direct page should be 0xABCD but it was %x", snes.cpu->_registers.d);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TCD, zero)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.d = 0x5656;
snes.cpu->_registers.a = 0x0;
snes.cpu->TCD(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.d, 0, "The direct page should be 0x0 but it was %x", snes.cpu->_registers.d);
cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
}
Test(TCS, emulationMode)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = false;
snes.cpu->_registers.s = 0x0156;
snes.cpu->_registers.a = 0xABCD;
snes.cpu->TCS(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.s, 0x01CD, "The stack pointer should be 0x01CD but it was %x", snes.cpu->_registers.s);
}
Test(TCS, native)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.s = 0x0156;
snes.cpu->_registers.a = 0xABCD;
snes.cpu->TCS(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.s, 0xABCD, "The stack pointer should be 0xABCD but it was %x", snes.cpu->_registers.s);
}
Test(TDC, emulationMode)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.d = 0xABCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TDC(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0xABCD, "The accumulator should be 0xABCD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TDC, zero)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.d = 0x0;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TDC(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0, "The accumulator should be 0x0 but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
}
Test(TSC, emulationMode)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.s = 0xABCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TSC(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0xABCD, "The accumulator should be 0xABCD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TSC, zero)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.s = 0x0;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TSC(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0, "The accumulator should be 0x0 but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.p.z, true, "The zero flag should be set.");
}
Test(TSX, emulationMode)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.x_b = true;
snes.cpu->_registers.s = 0xABCD;
snes.cpu->_registers.x = 0x5656;
snes.cpu->TSX(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.x, 0x00CD, "The x index should be 0x00CD but it was %x", snes.cpu->_registers.x);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TSX, native)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.x_b = false;
snes.cpu->_registers.s = 0x8F00;
snes.cpu->_registers.x = 0x5656;
snes.cpu->TSX(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.x, 0x8F00, "The x index should be 0x8F00 but it was %x", snes.cpu->_registers.x);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TXA, double8bits)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.p.x_b = true;
snes.cpu->_registers.x = 0xABCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TXA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x56CD, "The accumulator should be 0x56CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TXA, index8bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = false;
snes.cpu->_registers.p.x_b = true;
snes.cpu->_registers.x = 0x0BCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TXA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x00CD, "The accumulator should be 0x00CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TXA, accumulator8bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.p.x_b = false;
snes.cpu->_registers.x = 0x0BCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TXA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x56CD, "The accumulator should be 0x56CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TXA, double16bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = false;
snes.cpu->_registers.p.x_b = false;
snes.cpu->_registers.x = 0xAB0D;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TXA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0xAB0D, "The accumulator should be 0xAB0D but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TYA, double8bits)
{
Init()
snes.cpu->_isEmulationMode = true;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.p.x_b = true;
snes.cpu->_registers.y = 0xABCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TYA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x56CD, "The accumulator should be 0x56CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TYA, index8bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = false;
snes.cpu->_registers.p.x_b = true;
snes.cpu->_registers.y = 0x0BCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TYA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x00CD, "The accumulator should be 0x00CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, false, "The negative flag should not be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TYA, accumulator8bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = true;
snes.cpu->_registers.p.x_b = false;
snes.cpu->_registers.y = 0x0BCD;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TYA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0x56CD, "The accumulator should be 0x56CD but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}
Test(TYA, double16bits)
{
Init()
snes.cpu->_isEmulationMode = false;
snes.cpu->_registers.p.m = false;
snes.cpu->_registers.p.x_b = false;
snes.cpu->_registers.y = 0xAB0D;
snes.cpu->_registers.a = 0x5656;
snes.cpu->TYA(0x0, ComSquare::CPU::AddressingMode::Implied);
cr_assert_eq(snes.cpu->_registers.a, 0xAB0D, "The accumulator should be 0xAB0D but it was %x", snes.cpu->_registers.a);
cr_assert_eq(snes.cpu->_registers.p.n, true, "The negative flag should be set.");
cr_assert_eq(snes.cpu->_registers.p.z, false, "The zero flag should be not set.");
}