Compare commits
5
Commits
af07357812
...
446a777e40
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
446a777e40 | ||
|
|
1acb5af23e | ||
|
|
a20d756e7b | ||
|
|
80e15531f2 | ||
|
|
16235b4663 |
+97
-5
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
|
#include "ruc/format/color.h"
|
||||||
#include "ruc/format/print.h"
|
#include "ruc/format/print.h"
|
||||||
#include "ruc/meta/assert.h"
|
#include "ruc/meta/assert.h"
|
||||||
|
|
||||||
@@ -65,15 +66,22 @@ void CPU::update()
|
|||||||
case 0x02: ld8(); break;
|
case 0x02: ld8(); break;
|
||||||
case 0x06: ld8(); break;
|
case 0x06: ld8(); break;
|
||||||
case 0x08: ld16(); break;
|
case 0x08: ld16(); break;
|
||||||
|
case 0x0a: ld8(); break;
|
||||||
|
case 0x0e: ld8(); break;
|
||||||
case 0x11: ld16(); break;
|
case 0x11: ld16(); break;
|
||||||
case 0x12: ld8(); break;
|
case 0x12: ld8(); break;
|
||||||
case 0x16: ld8(); break;
|
case 0x16: ld8(); break;
|
||||||
|
case 0x1a: ld8(); break;
|
||||||
|
case 0x1e: ld8(); break;
|
||||||
case 0x21: ld16(); break;
|
case 0x21: ld16(); break;
|
||||||
case 0x22: ld8(); break;
|
case 0x22: ld8(); break;
|
||||||
case 0x26: ld8(); break;
|
case 0x26: ld8(); break;
|
||||||
|
case 0x2a: ld8(); break;
|
||||||
|
case 0x2e: ld8(); break;
|
||||||
case 0x31: ld16(); break;
|
case 0x31: ld16(); break;
|
||||||
case 0x32: ld8(); break;
|
case 0x32: ld8(); break;
|
||||||
case 0x36: ld8(); break;
|
case 0x36: ld8(); break;
|
||||||
|
case 0x3a: ld8(); break;
|
||||||
case 0x3e: ld8(); break;
|
case 0x3e: ld8(); break;
|
||||||
case 0xa8: xor8(); break;
|
case 0xa8: xor8(); break;
|
||||||
case 0xaf: xor8(); break;
|
case 0xaf: xor8(); break;
|
||||||
@@ -153,6 +161,16 @@ void CPU::ld8()
|
|||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
m_b = pcRead();
|
m_b = pcRead();
|
||||||
break;
|
break;
|
||||||
|
case 0x0a:
|
||||||
|
// LD A,(BC)
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
m_a = read(bc());
|
||||||
|
break;
|
||||||
|
case 0x0e:
|
||||||
|
// LD C,n
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
m_c = pcRead();
|
||||||
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
// LD (DE),A
|
// LD (DE),A
|
||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
@@ -163,6 +181,16 @@ void CPU::ld8()
|
|||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
m_d = pcRead();
|
m_d = pcRead();
|
||||||
break;
|
break;
|
||||||
|
case 0x1a:
|
||||||
|
// LD A,(DE)
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
m_a = read(de());
|
||||||
|
break;
|
||||||
|
case 0x1e:
|
||||||
|
// LD E,n
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
m_e = pcRead();
|
||||||
|
break;
|
||||||
case 0x22: {
|
case 0x22: {
|
||||||
// LD (HL+),A == LD (HLI),A == LDI (HL),A
|
// LD (HL+),A == LD (HLI),A == LDI (HL),A
|
||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
@@ -182,6 +210,25 @@ void CPU::ld8()
|
|||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
m_h = pcRead();
|
m_h = pcRead();
|
||||||
break;
|
break;
|
||||||
|
case 0x2a: {
|
||||||
|
// LD A,(HL+) == LD A,(HLI) == LDI A,(HL)
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Put value at address in HL into A
|
||||||
|
uint32_t address = hl();
|
||||||
|
m_a = read(address);
|
||||||
|
|
||||||
|
// Increment HL
|
||||||
|
address = (address + 1) & 0xffff;
|
||||||
|
m_l = address & 0x00ff;
|
||||||
|
m_h = address >> 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x2e:
|
||||||
|
// LD L,n
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
m_l = pcRead();
|
||||||
|
break;
|
||||||
case 0x32: {
|
case 0x32: {
|
||||||
// LD (HL-),A == LD (HLD),A == LDD (HL),A
|
// LD (HL-),A == LD (HLD),A == LDD (HL),A
|
||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
@@ -201,6 +248,20 @@ void CPU::ld8()
|
|||||||
m_wait_cycles += 12;
|
m_wait_cycles += 12;
|
||||||
write(hl(), pcRead());
|
write(hl(), pcRead());
|
||||||
break;
|
break;
|
||||||
|
case 0x3a: {
|
||||||
|
// LD A,(HL-) == LD A,(HLD) == LDD A,(HL)
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Put value at address in HL into A
|
||||||
|
uint32_t address = hl();
|
||||||
|
m_a = read(address);
|
||||||
|
|
||||||
|
// Decrement HL
|
||||||
|
address = (address + 1) & 0xffff;
|
||||||
|
m_l = address & 0x00ff;
|
||||||
|
m_h = address >> 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 0x3e:
|
case 0x3e:
|
||||||
// LD A,n
|
// LD A,n
|
||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
@@ -332,27 +393,58 @@ void CPU::jp16()
|
|||||||
|
|
||||||
uint32_t CPU::pcRead()
|
uint32_t CPU::pcRead()
|
||||||
{
|
{
|
||||||
uint32_t data = Emu::the().readMemory(m_pc);
|
uint32_t data = Emu::the().readMemory(m_pc) & 0x00ff;
|
||||||
m_pc = (m_pc + 1) & 0xffff;
|
m_pc = (m_pc + 1) & 0xffff;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::write(uint32_t address, uint32_t value)
|
void CPU::write(uint32_t address, uint32_t value)
|
||||||
{
|
{
|
||||||
Emu::the().writeMemory(address, value);
|
Emu::the().writeMemory(address, value & 0x00ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CPU::read(uint32_t address)
|
uint32_t CPU::read(uint32_t address)
|
||||||
{
|
{
|
||||||
return Emu::the().readMemory(address);
|
return Emu::the().readMemory(address) & 0x00ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::ffWrite(uint32_t address, uint32_t value)
|
void CPU::ffWrite(uint32_t address, uint32_t value)
|
||||||
{
|
{
|
||||||
Emu::the().writeMemory(address | (0xff << 8), value);
|
Emu::the().writeMemory(address | (0xff << 8), value & 0x00ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CPU::ffRead(uint32_t address)
|
uint32_t CPU::ffRead(uint32_t address)
|
||||||
{
|
{
|
||||||
return Emu::the().readMemory(address | (0xff << 8));
|
return Emu::the().readMemory(address | (0xff << 8)) & 0x00ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------
|
||||||
|
|
||||||
|
void Formatter<CPU>::parse(Parser& parser)
|
||||||
|
{
|
||||||
|
parser.parseSpecifier(specifier, Parser::ParameterType::UserDefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Formatter<CPU>::format(Builder& builder, const CPU& value) const
|
||||||
|
{
|
||||||
|
if (!specifier.alternativeForm) {
|
||||||
|
builder.putString(
|
||||||
|
::format("| AF {:#06x} | BC {:#06x} | DE {:#06x} | HL {:#06x} | PC {:#06x} | SP {:#06x} |",
|
||||||
|
value.af(), value.bc(), value.de(), value.hl(), value.pc(), value.sp()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Formatter<uint32_t> formatter { .specifier = specifier };
|
||||||
|
builder.putString("AF: ");
|
||||||
|
formatter.format(builder, value.af());
|
||||||
|
builder.putString("\nBC: ");
|
||||||
|
formatter.format(builder, value.bc());
|
||||||
|
builder.putString("\nDE: ");
|
||||||
|
formatter.format(builder, value.de());
|
||||||
|
builder.putString("\nHL: ");
|
||||||
|
formatter.format(builder, value.hl());
|
||||||
|
builder.putString("\nPC: ");
|
||||||
|
formatter.format(builder, value.pc());
|
||||||
|
builder.putString("\nSP: ");
|
||||||
|
formatter.format(builder, value.sp());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "processing-unit.h"
|
#include "processing-unit.h"
|
||||||
|
#include "ruc/format/formatter.h"
|
||||||
|
|
||||||
class CPU final : public ProcessingUnit {
|
class CPU final : public ProcessingUnit {
|
||||||
public:
|
public:
|
||||||
@@ -57,6 +58,15 @@ public:
|
|||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// Miscellaneous Instructions
|
// Miscellaneous Instructions
|
||||||
|
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
uint32_t af() const { return (m_cf << 4 | m_hf << 5 | m_nf << 6 | m_zf << 7) | m_a << 8; }
|
||||||
|
uint32_t bc() const { return m_c | m_b << 8; }
|
||||||
|
uint32_t de() const { return m_e | m_d << 8; }
|
||||||
|
uint32_t hl() const { return m_l | m_h << 8; }
|
||||||
|
uint32_t pc() const { return m_pc; }
|
||||||
|
uint32_t sp() const { return m_sp; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t pcRead();
|
uint32_t pcRead();
|
||||||
uint32_t pcRead16() { return pcRead() | (pcRead() << 8); }
|
uint32_t pcRead16() { return pcRead() | (pcRead() << 8); }
|
||||||
@@ -67,10 +77,6 @@ private:
|
|||||||
void ffWrite(uint32_t address, uint32_t value);
|
void ffWrite(uint32_t address, uint32_t value);
|
||||||
uint32_t ffRead(uint32_t address);
|
uint32_t ffRead(uint32_t address);
|
||||||
|
|
||||||
uint32_t bc() const { return m_b << 8 | m_c; }
|
|
||||||
uint32_t de() const { return m_b << 8 | m_c; }
|
|
||||||
uint32_t hl() const { return m_b << 8 | m_c; }
|
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
uint32_t m_a { 0 }; // Accumulator
|
uint32_t m_a { 0 }; // Accumulator
|
||||||
uint32_t m_b { 0 }; // B
|
uint32_t m_b { 0 }; // B
|
||||||
@@ -90,3 +96,9 @@ private:
|
|||||||
|
|
||||||
int8_t m_wait_cycles { 0 };
|
int8_t m_wait_cycles { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct ruc::format::Formatter<CPU> : Formatter<uint32_t> {
|
||||||
|
void parse(Parser& parser);
|
||||||
|
void format(Builder& builder, const CPU& value) const;
|
||||||
|
};
|
||||||
|
|||||||
Vendored
+1
-1
Submodule vendor/ruc updated: 94eb1dd173...27489c6cb4
Reference in New Issue
Block a user