Added instructions: LdBU8, RLCA, LdU16Sp and AddHlBc
This commit is contained in:
+2
-1
@@ -21,7 +21,8 @@
|
|||||||
"inherits": "base",
|
"inherits": "base",
|
||||||
"generator": "Ninja",
|
"generator": "Ninja",
|
||||||
"cacheVariables": {
|
"cacheVariables": {
|
||||||
"BUILD_TESTING": "ON"
|
"BUILD_TESTING": "ON",
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ std::uint8_t LdBcA(Processor &processor);
|
|||||||
std::uint8_t IncBc(Processor &processor);
|
std::uint8_t IncBc(Processor &processor);
|
||||||
std::uint8_t IncB(Processor &processor);
|
std::uint8_t IncB(Processor &processor);
|
||||||
std::uint8_t DecB(Processor &processor);
|
std::uint8_t DecB(Processor &processor);
|
||||||
|
std::uint8_t LdBU8(Processor &processor);
|
||||||
|
std::uint8_t RLCA(Processor &processor);
|
||||||
|
std::uint8_t LdU16Sp(Processor &processor);
|
||||||
|
std::uint8_t AddHlBc(Processor &processor);
|
||||||
} // namespace instructions
|
} // namespace instructions
|
||||||
|
|
||||||
} // namespace juiceboy
|
} // namespace juiceboy
|
||||||
@@ -29,17 +29,21 @@ public:
|
|||||||
/// @return The current value of the stack pointer.
|
/// @return The current value of the stack pointer.
|
||||||
[[nodiscard]] std::uint16_t GetStackPointer() const;
|
[[nodiscard]] std::uint16_t GetStackPointer() const;
|
||||||
|
|
||||||
|
void SetStackPointer(std::uint16_t value);
|
||||||
|
|
||||||
[[nodiscard]] std::uint8_t GetA() const;
|
[[nodiscard]] std::uint8_t GetA() const;
|
||||||
[[nodiscard]] std::uint8_t GetF() const;
|
[[nodiscard]] std::uint8_t GetF() const;
|
||||||
[[nodiscard]] std::uint8_t GetB() const;
|
[[nodiscard]] std::uint8_t GetB() const;
|
||||||
|
|
||||||
[[nodiscard]] std::uint16_t GetBC() const;
|
[[nodiscard]] std::uint16_t GetBC() const;
|
||||||
|
[[nodiscard]] std::uint16_t GetHL() const;
|
||||||
|
|
||||||
void SetA(std::uint8_t value);
|
void SetA(std::uint8_t value);
|
||||||
void SetF(std::uint8_t value);
|
void SetF(std::uint8_t value);
|
||||||
void SetB(std::uint8_t value);
|
void SetB(std::uint8_t value);
|
||||||
|
|
||||||
void SetBC(std::uint16_t value);
|
void SetBC(std::uint16_t value);
|
||||||
|
void SetHL(std::uint16_t value);
|
||||||
|
|
||||||
/// @brief Get the current value of the given flag.
|
/// @brief Get the current value of the given flag.
|
||||||
/// @return True if the given flag bit is set, false otherwise.
|
/// @return True if the given flag bit is set, false otherwise.
|
||||||
|
|||||||
@@ -8,15 +8,277 @@
|
|||||||
namespace juiceboy {
|
namespace juiceboy {
|
||||||
|
|
||||||
Instructions::Instructions() {
|
Instructions::Instructions() {
|
||||||
// For now, all not implemented instructions should throw.
|
std::get<0x00>(m_instructions) = &instructions::Nop;
|
||||||
m_instructions.fill(&instructions::NotImplemented);
|
std::get<0x01>(m_instructions) = &instructions::LdBcD16;
|
||||||
|
std::get<0x02>(m_instructions) = &instructions::LdBcA;
|
||||||
|
std::get<0x03>(m_instructions) = &instructions::IncBc;
|
||||||
|
std::get<0x04>(m_instructions) = &instructions::IncB;
|
||||||
|
std::get<0x05>(m_instructions) = &instructions::DecB;
|
||||||
|
std::get<0x06>(m_instructions) = &instructions::LdBU8;
|
||||||
|
std::get<0x07>(m_instructions) = &instructions::RLCA;
|
||||||
|
std::get<0x08>(m_instructions) = &instructions::LdU16Sp;
|
||||||
|
std::get<0x09>(m_instructions) = &instructions::AddHlBc;
|
||||||
|
std::get<0x0A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x0B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x0C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x0D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x0E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x0F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
std::get<0x0>(m_instructions) = &instructions::Nop;
|
std::get<0x10>(m_instructions) = &instructions::NotImplemented;
|
||||||
std::get<0x1>(m_instructions) = &instructions::LdBcD16;
|
std::get<0x11>(m_instructions) = &instructions::NotImplemented;
|
||||||
std::get<0x2>(m_instructions) = &instructions::LdBcA;
|
std::get<0x12>(m_instructions) = &instructions::NotImplemented;
|
||||||
std::get<0x3>(m_instructions) = &instructions::IncBc;
|
std::get<0x13>(m_instructions) = &instructions::NotImplemented;
|
||||||
std::get<0x4>(m_instructions) = &instructions::IncB;
|
std::get<0x14>(m_instructions) = &instructions::NotImplemented;
|
||||||
std::get<0x5>(m_instructions) = &instructions::DecB;
|
std::get<0x15>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x16>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x17>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x18>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x19>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x1F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x20>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x21>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x22>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x23>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x24>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x25>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x26>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x27>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x28>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x29>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x2F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x30>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x31>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x32>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x33>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x34>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x35>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x36>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x37>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x38>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x39>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x3F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x40>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x41>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x42>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x43>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x44>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x45>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x46>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x47>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x48>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x49>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x4F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x50>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x51>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x52>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x53>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x54>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x55>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x56>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x57>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x58>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x59>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x5F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x60>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x61>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x62>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x63>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x64>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x65>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x66>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x67>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x68>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x69>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x6F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x70>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x71>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x72>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x73>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x74>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x75>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x76>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x77>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x78>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x79>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x7F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x80>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x81>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x82>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x83>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x84>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x85>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x86>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x87>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x88>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x89>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x8F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0x90>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x91>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x92>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x93>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x94>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x95>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x96>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x97>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x98>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x99>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9A>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9B>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9C>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9D>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9E>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0x9F>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xA0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xA9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAD>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xAF>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xB0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xB9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBD>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xBF>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xC0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xC9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCD>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xCF>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xD0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xD9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDD>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xDF>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xE0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xE9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xEA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xEB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xEC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xED>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xEE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xEF>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
|
||||||
|
std::get<0xF0>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF1>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF2>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF3>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF4>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF5>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF6>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF7>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF8>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xF9>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFA>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFB>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFC>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFD>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFE>(m_instructions) = &instructions::NotImplemented;
|
||||||
|
std::get<0xFF>(m_instructions) = &instructions::NotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint8_t Instructions::ExecuteInstruction(const std::uint8_t opcode,
|
std::uint8_t Instructions::ExecuteInstruction(const std::uint8_t opcode,
|
||||||
@@ -77,6 +339,52 @@ std::uint8_t DecB(Processor &processor) {
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::uint8_t LdBU8(Processor &processor) {
|
||||||
|
processor.GetRegisters().SetB(processor.FetchByte());
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t RLCA(Processor &processor) {
|
||||||
|
auto value = processor.GetRegisters().GetA();
|
||||||
|
const auto carry = (value & 0x80) != 0;
|
||||||
|
|
||||||
|
value = static_cast<std::uint8_t>(value << 1);
|
||||||
|
value |= carry ? 1 : 0;
|
||||||
|
|
||||||
|
processor.GetRegisters().SetA(value);
|
||||||
|
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::Zero, false);
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::Subtract, false);
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::HalfCarry, false);
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::Carry, carry);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t LdU16Sp(Processor &processor) {
|
||||||
|
const auto address = processor.FetchWord();
|
||||||
|
const auto value = processor.GetRegisters().GetStackPointer();
|
||||||
|
|
||||||
|
processor.GetMemory().WriteByte(address + 0, value & 0xFF);
|
||||||
|
processor.GetMemory().WriteByte(address + 1, value >> 8);
|
||||||
|
|
||||||
|
return 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint8_t AddHlBc(Processor &processor) {
|
||||||
|
|
||||||
|
const auto hl = processor.GetRegisters().GetHL();
|
||||||
|
const auto bc = processor.GetRegisters().GetBC();
|
||||||
|
const auto result = static_cast<std::uint16_t>(hl + bc);
|
||||||
|
|
||||||
|
processor.GetRegisters().SetHL(result);
|
||||||
|
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::Subtract, false);
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::HalfCarry,
|
||||||
|
((hl & 0x0FFF) + (bc & 0x0FFF)) > 0x0FFF);
|
||||||
|
processor.GetRegisters().SetFlag(Registers::Flags::Carry, hl + bc > 0xFFFF);
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace instructions
|
} // namespace instructions
|
||||||
|
|
||||||
} // namespace juiceboy
|
} // namespace juiceboy
|
||||||
@@ -27,11 +27,14 @@ void Registers::IncrementProgramCounter(const std::uint16_t value) {
|
|||||||
|
|
||||||
std::uint16_t Registers::GetStackPointer() const { return m_sp; }
|
std::uint16_t Registers::GetStackPointer() const { return m_sp; }
|
||||||
|
|
||||||
|
void Registers::SetStackPointer(const std::uint16_t value) { m_sp = value; }
|
||||||
|
|
||||||
std::uint8_t Registers::GetA() const { return m_regA; }
|
std::uint8_t Registers::GetA() const { return m_regA; }
|
||||||
std::uint8_t Registers::GetF() const { return m_regF; }
|
std::uint8_t Registers::GetF() const { return m_regF; }
|
||||||
std::uint8_t Registers::GetB() const { return m_regB; }
|
std::uint8_t Registers::GetB() const { return m_regB; }
|
||||||
|
|
||||||
std::uint16_t Registers::GetBC() const { return BytesToWord(m_regB, m_regC); }
|
std::uint16_t Registers::GetBC() const { return BytesToWord(m_regB, m_regC); }
|
||||||
|
std::uint16_t Registers::GetHL() const { return BytesToWord(m_regH, m_regL); }
|
||||||
|
|
||||||
void Registers::SetA(const std::uint8_t value) { m_regA = value; }
|
void Registers::SetA(const std::uint8_t value) { m_regA = value; }
|
||||||
void Registers::SetF(const std::uint8_t value) { m_regF = value; }
|
void Registers::SetF(const std::uint8_t value) { m_regF = value; }
|
||||||
@@ -40,6 +43,9 @@ void Registers::SetB(const std::uint8_t value) { m_regB = value; }
|
|||||||
void Registers::SetBC(const std::uint16_t value) {
|
void Registers::SetBC(const std::uint16_t value) {
|
||||||
std::tie(m_regB, m_regC) = WordToBytes(value);
|
std::tie(m_regB, m_regC) = WordToBytes(value);
|
||||||
}
|
}
|
||||||
|
void Registers::SetHL(const std::uint16_t value) {
|
||||||
|
std::tie(m_regH, m_regL) = WordToBytes(value);
|
||||||
|
}
|
||||||
|
|
||||||
bool Registers::GetFlag(Flags flag) const {
|
bool Registers::GetFlag(Flags flag) const {
|
||||||
return (m_regF & static_cast<std::uint8_t>(flag)) != 0;
|
return (m_regF & static_cast<std::uint8_t>(flag)) != 0;
|
||||||
|
|||||||
@@ -146,4 +146,107 @@ TEST_F(InstructionsTest, DecBPreservesCarry) {
|
|||||||
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, LdBU8) {
|
||||||
|
GetMemory().WriteByte(0x8000, 0x1);
|
||||||
|
GetRegisters().SetProgramCounter(0x8000);
|
||||||
|
|
||||||
|
const auto cycles = instructions::LdBU8(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(cycles, 4);
|
||||||
|
EXPECT_EQ(GetRegisters().GetB(), 0x1);
|
||||||
|
EXPECT_EQ(GetRegisters().GetProgramCounter(), 0x8001);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, RCLA) {
|
||||||
|
GetRegisters().SetA(0b11110000);
|
||||||
|
|
||||||
|
const auto cycles = instructions::RLCA(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(cycles, 4);
|
||||||
|
EXPECT_EQ(GetRegisters().GetA(), 0b11100001);
|
||||||
|
EXPECT_EQ(GetRegisters().GetProgramCounter(), 0);
|
||||||
|
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, RCLAClearsFlags) {
|
||||||
|
GetRegisters().SetA(0b01111111);
|
||||||
|
GetRegisters().SetFlag(Registers::Flags::Zero, true);
|
||||||
|
GetRegisters().SetFlag(Registers::Flags::Subtract, true);
|
||||||
|
GetRegisters().SetFlag(Registers::Flags::HalfCarry, true);
|
||||||
|
|
||||||
|
(void)instructions::RLCA(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(GetRegisters().GetA(), 0b11111110);
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Zero));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Subtract));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::HalfCarry));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, LdU16Sp) {
|
||||||
|
GetRegisters().SetStackPointer(0x1234);
|
||||||
|
GetRegisters().SetProgramCounter(0x8000);
|
||||||
|
GetMemory().WriteByte(0x8000, 0x02);
|
||||||
|
GetMemory().WriteByte(0x8001, 0x80);
|
||||||
|
|
||||||
|
const auto cycles = instructions::LdU16Sp(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(cycles, 20);
|
||||||
|
EXPECT_EQ(GetMemory().ReadByte(0x8002), 0x34);
|
||||||
|
EXPECT_EQ(GetMemory().ReadByte(0x8003), 0x12);
|
||||||
|
EXPECT_EQ(GetRegisters().GetProgramCounter(), 0x8002);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, AddHlBc) {
|
||||||
|
GetRegisters().SetBC(0x1234);
|
||||||
|
GetRegisters().SetHL(0x4321);
|
||||||
|
|
||||||
|
const auto cycles = instructions::AddHlBc(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(cycles, 8);
|
||||||
|
EXPECT_EQ(GetRegisters().GetBC(), 0x1234);
|
||||||
|
EXPECT_EQ(GetRegisters().GetHL(), 0x5555);
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Subtract));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Zero));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::HalfCarry));
|
||||||
|
EXPECT_EQ(GetRegisters().GetProgramCounter(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, AddHlBcSetsCarryFlag) {
|
||||||
|
GetRegisters().SetBC(0xFFFF);
|
||||||
|
GetRegisters().SetHL(0x1);
|
||||||
|
|
||||||
|
(void)instructions::AddHlBc(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(GetRegisters().GetHL(), 0x0);
|
||||||
|
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::Carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, AddHlBcSetsHalfCarryFlag) {
|
||||||
|
GetRegisters().SetBC(0x0FFF);
|
||||||
|
GetRegisters().SetHL(0x1);
|
||||||
|
|
||||||
|
(void)instructions::AddHlBc(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_EQ(GetRegisters().GetHL(), 0x1000);
|
||||||
|
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::HalfCarry));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, AddHlBcClearsSubtractFlag) {
|
||||||
|
GetRegisters().SetFlag(Registers::Flags::Subtract, true);
|
||||||
|
|
||||||
|
(void)instructions::AddHlBc(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_FALSE(GetRegisters().GetFlag(Registers::Flags::Subtract));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(InstructionsTest, AddHlBcPreservesZeroFlag) {
|
||||||
|
GetRegisters().SetFlag(Registers::Flags::Zero, true);
|
||||||
|
|
||||||
|
(void)instructions::AddHlBc(GetProcessor());
|
||||||
|
|
||||||
|
EXPECT_TRUE(GetRegisters().GetFlag(Registers::Flags::Zero));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace juiceboy::test
|
} // namespace juiceboy::test
|
||||||
Reference in New Issue
Block a user