Skip to content

Commit

Permalink
Implemented CPU, with few instructions.
Browse files Browse the repository at this point in the history
  • Loading branch information
subratkatiyar committed May 17, 2024
1 parent caa91df commit fee4c1a
Show file tree
Hide file tree
Showing 17 changed files with 536 additions and 50 deletions.
18 changes: 18 additions & 0 deletions Gameboy/COMPARE.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "CPU.h"
#include <iomanip>
#include <iostream>

void CPU::execute_CP_n(){
MemoryUnitObj->registers.pc++;
uint8_t n = MemoryUnitObj->read_memory(MemoryUnitObj->registers.pc);
uint8_t result = MemoryUnitObj->registers.a - n;

MemoryUnitObj->set_flag(FLAG_Z, MemoryUnitObj->registers.c == 0);
MemoryUnitObj->set_flag(FLAG_N, 1);
MemoryUnitObj->checknset_halfcarry_flag(result);
MemoryUnitObj->set_flag(FLAG_C, MemoryUnitObj->registers.a < n);
MemoryUnitObj->registers.pc++;

std::cout << "cp a," << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(n) << "\n";

}
143 changes: 143 additions & 0 deletions Gameboy/CPU.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
#include "CPU.h"
#include "iostream"
#include <iomanip>
#include <cassert>

void CPU::executeNOP()
{
std::cout << "nop\n";
MemoryUnitObj->registers.pc++;
}

void CPU::execute_XOR_A() {
// XOR A
MemoryUnitObj->registers.a ^= MemoryUnitObj->registers.a;

// Update flags
MemoryUnitObj->set_flag(FLAG_Z, MemoryUnitObj->registers.a == 0);
MemoryUnitObj->set_flag(FLAG_N, 0);
MemoryUnitObj->set_flag(FLAG_H, 0);
MemoryUnitObj->set_flag(FLAG_C, 0);

//Update PC
MemoryUnitObj->registers.pc++;

std::cout << "XOR A\n";
}

void CPU::execute_HL_nn() {
MemoryUnitObj->registers.pc++;
uint16_t nn = MemoryUnitObj->read_memory_16_le(MemoryUnitObj->registers.pc);
MemoryUnitObj->registers.hl = nn;
MemoryUnitObj->registers.pc += 2;
std::cout << "ld hl " << std::setw(4) << std::setfill('0') << std::hex << nn << "\n";

}

CPU::CPU(MemoryUnit *memoryUnitPointer)
{
MemoryUnitObj = memoryUnitPointer;
initialize_memory();
initialize_registers();
MemoryUnitObj->load_rom("..\\roms\\Tetris.gb");
}

void CPU::initialize_memory()
{
MemoryUnitObj->load_vram("..\\roms\\VRAM.dump");
MemoryUnitObj->reset_eram();
MemoryUnitObj->reset_notusuable();
MemoryUnitObj->load_ioregisters("..\\roms\\IO.dump");
MemoryUnitObj->reset_ieregister();
}

void CPU::initialize_registers()
{
MemoryUnitObj->registers.af = 0x01B0; // Example: Set flags (Z=0, N=1, H=1, C=0)
MemoryUnitObj->registers.bc = 0x0013; // Example: Set BC register pair
MemoryUnitObj->registers.de = 0x00D8; // Example: Set DE register pair
MemoryUnitObj->registers.hl = 0x014D; // Example: Set HL register pair
MemoryUnitObj->registers.sp = 0xFFFE; // Example: Set Stack Pointer
MemoryUnitObj->registers.pc = 0x0100; // Example: Set Program Counter
}

void CPU::debug_registers() {
std::cout << "AF = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.af << " ";
std::cout << "BC = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.bc << " ";
std::cout << "DE = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.de << " ";
std::cout << "HL = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.hl << " ";
std::cout << "SP = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.sp << " ";
std::cout << "PC = 0x" << std::setw(4) << std::setfill('0') << std::hex << MemoryUnitObj->registers.pc << " ";
std::cout << "INS = 0x" << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(MemoryUnitObj->read_memory(MemoryUnitObj->registers.pc)) << "\n";
}

void CPU::execute_unimplemented() {
// Print an error message
std::cout<<"Error: Instruction not implemented\n";
assert(0); // This will cause the program to terminate with an error message
}

void CPU::start_execution()
{
while (true) {
debug_registers();
uint8_t opcode = MemoryUnitObj->read_memory(MemoryUnitObj->registers.pc);
switch (opcode) {
case 0x00:
executeNOP();
break;
case 0x05:
execute_DEC_B();
break;
case 0x06:
execute_LD_B_n();
break;
case 0x0D:
execute_DEC_C();
break;
case 0x0E:
execute_LD_C_n();
break;
case 0x20:
execute_JR_NZ_n();
break;
case 0x21:
execute_HL_nn();
break;
case 0x32:
execute_LD_HL_dec_A();
break;
case 0x36:
execute_LD_HL_n();
break;
case 0x3E:
execute_LD_A_n();
break;
case 0xAF:
execute_XOR_A();
break;
case 0xC3:
execute_JP_nn();
break;
case 0xE0:
execute_LDH_n_A();
break;
case 0xEA:
execute_LD_nn_A();
break;
case 0xF0:
execute_LDH_A_n();
break;
case 0xF3:
execute_DI();
break;
case 0xFE:
execute_CP_n();
break;
default:
// debug_registers();
execute_unimplemented();
break;
}
}
}
41 changes: 41 additions & 0 deletions Gameboy/CPU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once
#include "MemoryUnit.h"

class CPU {
private:
void executeNOP();
void execute_JP_nn();
void execute_XOR_A();
void execute_HL_nn();
void execute_LD_A_n();
void execute_LD_nn_A();
void execute_LDH_n_A();
void execute_LD_HL_n();
void execute_LDH_A_n();
void execute_LD_B_n();
void execute_LD_C_n();
void execute_LD_HL_dec_A();
void execute_DEC_B();
void execute_DEC_C();
void execute_JR_NZ_n();
void execute_DI();
void execute_CP_n();
public:
MemoryUnit *MemoryUnitObj;
CPU(MemoryUnit*);
void initialize_memory();
void initialize_registers();
void start_execution();
void debug_registers();

void execute_unimplemented();









};
23 changes: 23 additions & 0 deletions Gameboy/DECREASE.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "CPU.h"
#include <iomanip>
#include <iostream>

void CPU::execute_DEC_B() {
MemoryUnitObj->registers.pc++;
MemoryUnitObj->registers.b--;

MemoryUnitObj->set_flag(FLAG_Z, MemoryUnitObj->registers.b == 0);
MemoryUnitObj->set_flag(FLAG_N, 1);
MemoryUnitObj->checknset_halfcarry_flag(MemoryUnitObj->registers.b);
std::cout << "dec b\n";
}

void CPU::execute_DEC_C() {
MemoryUnitObj->registers.pc++;
MemoryUnitObj->registers.c--;

MemoryUnitObj->set_flag(FLAG_Z, MemoryUnitObj->registers.c == 0);
MemoryUnitObj->set_flag(FLAG_N, 1);
MemoryUnitObj->checknset_halfcarry_flag(MemoryUnitObj->registers.c);
std::cout << "dec c\n";
}
6 changes: 3 additions & 3 deletions Gameboy/DisassemblyView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ std::string DisassemblyView::ByteToHexString(uint8_t byte)
return stream.str();
}

DisassemblyView::DisassemblyView(GameboyMemory* memoryPointer)
DisassemblyView::DisassemblyView(MemoryUnit *memoryPointer)
{
// Name your application
sAppName = "Disassembly View";
memory = memoryPointer;
memory = &memoryPointer->memory;
}

void DisassemblyView::DrawMemory()
Expand All @@ -41,7 +41,7 @@ void DisassemblyView::DrawMemory()
if (i + j >= sizeof(GameboyMemory)) break;

// Draw byte value
std::string byteStr = ByteToHexString(*((uint8_t*)memory + i + j));
std::string byteStr = ByteToHexString(*((uint8_t*)&memory + i + j));
DrawString(50 + j * 3 * 5 + j * 3, yPos, byteStr, olc::WHITE);
DrawString(50 + j * 3 * 5 + j * 3 + 10, yPos, " ", olc::WHITE);

Expand Down
4 changes: 2 additions & 2 deletions Gameboy/DisassemblyView.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ class DisassemblyView : public olc::PixelGameEngine
void DrawMemory();
std::string ByteToHexString(uint8_t);
public:
GameboyMemory* memory;
DisassemblyView(GameboyMemory*);
GameboyMemory *memory;
DisassemblyView(MemoryUnit*);
bool OnUserCreate() override;
bool OnUserUpdate(float fElapsedTime) override;
};
8 changes: 4 additions & 4 deletions Gameboy/DisplayUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ void DisplayUnit::DrawTile(int tile_idx) // Function used for TileMap Only.
int tile_xPos = tile_idx % 16;
int tile_yPos = tile_idx / 16;

int memoryStart = (256 * tile_yPos) + (tile_xPos * 16);
int memoryEnd = memoryStart + 16;
uint32_t memoryStart = (256 * tile_yPos) + (tile_xPos * 16);
uint32_t memoryEnd = memoryStart + 16;

//std::cout << tile_idx << "->" << memoryStart << " " << memoryEnd << "\n";
for (uint32_t addr = memoryStart; addr < memoryEnd; addr += 0x02) {
Expand Down Expand Up @@ -67,8 +67,8 @@ void DisplayUnit::DrawTile(uint8_t tile_idx, int tile_xPos, int tile_yPos)
std::pair<int32_t, int32_t> RectangleDimensions = { ScreenWidth(), ScreenHeight() };
std::pair<int32_t, int32_t> pixelSize = { RectangleDimensions.first / 256, RectangleDimensions.second / 192 };

int memoryStart = (256 * (tile_idx / 16)) + ((tile_idx % 16) * 16);
int memoryEnd = memoryStart + 16;
uint32_t memoryStart = (256 * (tile_idx / 16)) + ((tile_idx % 16) * 16);
uint32_t memoryEnd = memoryStart + 16;

//std::cout << tile_idx << "->" << memoryStart << " " << memoryEnd << "\n";
for (uint32_t addr = memoryStart; addr < memoryEnd; addr += 0x02) {
Expand Down
14 changes: 9 additions & 5 deletions Gameboy/Gameboy.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,25 +127,29 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CPU.h" />
<ClInclude Include="DisassemblyView.h" />
<ClInclude Include="DisplayUnit.h" />
<ClInclude Include="MemoryUnit.h" />
<ClInclude Include="olcPixelGameEngine.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="COMPARE.cpp" />
<ClCompile Include="CPU.cpp" />
<ClCompile Include="DECREASE.cpp" />
<ClCompile Include="DisassemblyView.cpp" />
<ClCompile Include="DisplayUnit.cpp" />
<ClCompile Include="JUMP.cpp" />
<ClCompile Include="LOAD.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MemoryUnit.cpp" />
<ClCompile Include="olcPixelGameEngine.cpp" />
<ClCompile Include="UNKNOWN.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\roms\IO.dump" />
<None Include="..\roms\Tetris.gb" />
<None Include="..\roms\VRAM_TEST_DATA\OAM.dump" />
<None Include="..\roms\VRAM_TEST_DATA\OAM_1.dump" />
<None Include="..\roms\VRAM_TEST_DATA\OAM_1_2.dump" />
<None Include="..\roms\VRAM_TEST_DATA\VRAM.dump" />
<None Include="..\roms\VRAM_TEST_DATA\VRAM_1.dump" />
<None Include="..\roms\VRAM.dump" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
34 changes: 23 additions & 11 deletions Gameboy/Gameboy.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<ClInclude Include="DisplayUnit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CPU.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="olcPixelGameEngine.cpp">
Expand All @@ -44,24 +47,33 @@
<ClCompile Include="DisplayUnit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CPU.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LOAD.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DECREASE.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="JUMP.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UNKNOWN.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="COMPARE.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\roms\Tetris.gb">
<Filter>Resource Files</Filter>
</None>
<None Include="..\roms\VRAM_TEST_DATA\VRAM.dump">
<Filter>Resource Files</Filter>
</None>
<None Include="..\roms\VRAM_TEST_DATA\OAM.dump">
<Filter>Resource Files</Filter>
</None>
<None Include="..\roms\VRAM_TEST_DATA\OAM_1.dump">
<Filter>Resource Files</Filter>
</None>
<None Include="..\roms\VRAM_TEST_DATA\OAM_1_2.dump">
<None Include="..\roms\VRAM.dump">
<Filter>Resource Files</Filter>
</None>
<None Include="..\roms\VRAM_TEST_DATA\VRAM_1.dump">
<None Include="..\roms\IO.dump">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
Expand Down
Loading

0 comments on commit fee4c1a

Please sign in to comment.