Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Background support only.
No input support.
No sound.
Passes all Blargg instruction tests.
Supports Tetris.
  • Loading branch information
matthewwalsh0 committed Jul 10, 2020
0 parents commit e7c0d1f
Show file tree
Hide file tree
Showing 42 changed files with 4,969 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build
.vscode
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
project(mboy_core)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
include_directories(include)
file(GLOB SOURCES "src/*.cpp")
add_library(mboy_core STATIC ${SOURCES})
40 changes: 40 additions & 0 deletions include/Bytes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_BYTES_H
#define MY_APPLICATION_BYTES_H

#include "Types.h"

class Bytes {
public:
static uint8 setBit_8(uint8 value, uint8 index);
static uint8 getBit_8(uint8 value, uint8 index);
static uint8 clearBit_8(uint8 value, uint8 index);
static uint8 join_4(uint8 upper, uint8 lower);
static uint16 join_8(uint8 upper, uint8 lower);
static uint32 join_32(uint8 first, uint8 second, uint8 third);
static uint8 split_8_upper(uint8 value);
static uint8 split_8_lower(uint8 value);
static uint8 split_16_upper(uint16 value);
static uint8 split_16_lower(uint16 value);
static bool isHalfCarrySub_8(uint8 value_1, uint8 value_2);
static bool isHalfCarrySub_8_three(uint8 value_1, uint8 value_2, uint8 value_3);
static bool isHalfCarryAdd_8(uint8 value_1, uint8 value_2);
static bool isHalfCarryAdd_8_three(uint8 value_1, uint8 value_2, uint8 value_3);
static bool isHalfCarryAdd_16(uint16 value_1, uint16 value_2);
static bool isCarrySub_8_three(uint8 value_1, uint8 value_2, uint8 value_3);
static bool isCarryAdd_8(uint8 value_1, uint8 value_2);
static bool isCarryAdd_8_three(uint8 value_1, uint8 value_2, uint8 value_3);
static bool isCarryAdd_16(uint16 value_1, uint16 value_2);
static uint8 wrappingAdd_8(uint8 value, uint8 add);
static uint16 wrappingAdd_16(uint16 value, uint16 add);
static uint8 wrappingSub_8(uint8 value, uint8 sub);
static uint16 wrappingSub_16(uint16 value, uint16 sub);
static uint8 rotateRight_8(uint8 value, uint8 n);
static uint8 rotateLeft_8(uint8 value, uint8 n);
static int8 toSigned_8(uint8 value);
};

#endif //MY_APPLICATION_BYTES_H
86 changes: 86 additions & 0 deletions include/CPU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//
// Created by matthew on 04/07/2020.
//

#ifndef MY_APPLICATION_CPU_H
#define MY_APPLICATION_CPU_H

#include "Memory.h"
#include "Types.h"
#include "MemoryHook.h"
#include "LogFile.h"

enum Register {
A,
B,
C,
D,
E,
H,
L,
BC,
DE,
HL,
AF
};

class CPU : MemoryHook {

public:
uint8 a;
uint8 b;
uint8 c;
uint8 d;
uint8 e;
uint8 h;
uint8 l;
uint16 sp;
uint16 pc;

bool flag_z;
bool flag_n;
bool flag_h;
bool flag_c;

bool interruptsEnabled;
bool halt;
bool swapSpeed;
bool currentSpeed;

bool interruptEnableVerticalBlank = false;
bool interruptEnableLcd = false;
bool interruptEnableTimer = false;
bool interruptEnableSerial = false;
bool interruptEnableJoypad = false;

bool interruptFlagsVerticalBlank = false;
bool interruptFlagsLcd = false;
bool interruptFlagsTimer = false;
bool interruptFlagsSerial = false;
bool interruptFlagsJoypad = false;

LogFile logFile;

CPU();
uint8 get_8(Register cpuRegister);
uint8 get_f();
void set_f(uint8 value);
uint16 get_16(Register cpuRegister);
void set_8(Register cpuRegister, uint8 value);
void set_16(Register cpuRegister, uint16 value);
uint16 step(Memory* memory, uint32 count, bool debug);
uint8 getInterruptEnable();
uint8 getInterruptFlags();
void setInterruptEnable(uint8 value);
void setInterruptFlags(uint8 value);
void flagInterrupt(uint8 bit);

private:
uint16 checkInterrupts(Memory* memory);
uint8 get_8(uint16 address) override;
bool set_8(uint16 address, uint8 value) override;
void flag_interrupt(uint8 bit) override;
};


#endif //MY_APPLICATION_CPU_H
26 changes: 26 additions & 0 deletions include/Control.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_CONTROL_H
#define MY_APPLICATION_CONTROL_H

#include "Types.h"
#include "Memory.h"

class Control {
public:
bool background;
bool sprites;
bool largeSprites;
bool alternateBackgroundTileMap;
bool alternateBackgroundTileSet;
bool window;
bool alternateWindowTileMap;
bool display;

Control(uint8 value);
Control(Memory* memory);
};

#endif //MY_APPLICATION_CONTROL_H
20 changes: 20 additions & 0 deletions include/CoreMemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_COREMEMORY_H
#define MY_APPLICATION_COREMEMORY_H

#include "Types.h"

class CoreMemory {
private:
uint8 data[64 * 1024] = {0};
public:
CoreMemory();
uint8 get_8(uint16 address);
void set_8(uint16 address, uint8 value);
};


#endif //MY_APPLICATION_COREMEMORY_H
26 changes: 26 additions & 0 deletions include/Display.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by matthew on 06/07/2020.
//

#ifndef MY_APPLICATION_DISPLAY_H
#define MY_APPLICATION_DISPLAY_H

#include "TileMap.h"
#include "Control.h"

class Display : MemoryHook {
private:
Memory* memory;
TileMap tileMap_0;
TileMap tileMap_1;
TileSet tileSet_0;
TileSet tileSet_1;
public:
Display(Memory* memory);
void drawLine(Pixels* pixels, uint8 line, bool isColour, Control* control);
uint8 get_8(uint16 address) override;
bool set_8(uint16 address, uint8 value) override;
};


#endif //MY_APPLICATION_DISPLAY_H
52 changes: 52 additions & 0 deletions include/GPU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_GPU_H
#define MY_APPLICATION_GPU_H

#include "Types.h"
#include "Memory.h"
#include "Control.h"
#include "Pixels.h"
#include "Display.h"
#include "GUI.h"
#include "LogFile.h"
#include <chrono>

const uint8 SCREEN_HEIGHT = 144;
const uint8 SCREEN_WIDTH = 160;

class GPU : MemoryHook {
private:
uint8 mode;
uint16 cycleCount;
uint16 line;
Pixels pixels;
Display display;
Memory* memory;
Control* control;
bool coincidenceInterrupt;
bool oamInterrupt;
bool vblankInterrupt;
bool hblankInterrupt;
uint16 coincidenceLine;
GUI* gui;
LogFile logFile;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
uint16 frameCount = 0;

public:
GPU(Memory* memory, GUI* gui);
void step(uint16 lastInstructionDuration, Memory* memory, bool isColour, uint32 count);
uint8 getStat();
void setStat(uint8 value);
void setControl(uint8 value);

private:
uint8 get_8(uint16 address) override;
bool set_8(uint16 address, uint8 value) override;
};


#endif //MY_APPLICATION_GPU_H
18 changes: 18 additions & 0 deletions include/GUI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Created by matthew on 06/07/2020.
//

#ifndef MY_APPLICATION_GUI_H
#define MY_APPLICATION_GUI_H

#include "Types.h"

class GUI {
public:
virtual void displayBuffer(uint32* pixels) {};
virtual bool isOpen() { return true; }
virtual void displayFPS(uint16 fps) {};
};


#endif //MY_APPLICATION_GUI_H
30 changes: 30 additions & 0 deletions include/Gameboy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_GAMEBOY_H
#define MY_APPLICATION_GAMEBOY_H


#include "Memory.h"
#include "CPU.h"
#include "Timer.h"
#include "GPU.h"
#include "GUI.h"

class Gameboy {
private:
Memory memory;
CPU cpu;
GPU gpu;
CoreMemory coreMemory;
Rom* rom;
Timer timer;
GUI* gui;
public:
Gameboy(Rom rom, GUI* gui);
void run();
};


#endif //MY_APPLICATION_GAMEBOY_H
26 changes: 26 additions & 0 deletions include/Instructions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_INSTRUCTIONS_H
#define MY_APPLICATION_INSTRUCTIONS_H

#include "Types.h"
#include "CPU.h"

struct instructionInfo {
uint8 length;
uint8 cyclesAction;
uint8 cyclesNoAction;
char debug[20];
};

class Instructions {
public:
static instructionInfo getInfo(uint8 index, uint8 arg);
static bool run(uint8 index, CPU* cpu, Memory* memory, uint8 arg_8, uint16 arg_16);
static void call(CPU* cpu, Memory* memory, uint16 value);
};


#endif //MY_APPLICATION_INSTRUCTIONS_H
19 changes: 19 additions & 0 deletions include/LogFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// Created by matthew on 06/07/2020.
//

#ifndef MY_APPLICATION_LOGFILE_H
#define MY_APPLICATION_LOGFILE_H

#include <fstream>

class LogFile {
private:
std::ofstream file;
public:
LogFile(std::string path);
void write(const std::string fmt, ...);
};


#endif //MY_APPLICATION_LOGFILE_H
31 changes: 31 additions & 0 deletions include/Memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Created by matthew on 05/07/2020.
//

#ifndef MY_APPLICATION_MEMORY_H
#define MY_APPLICATION_MEMORY_H

#include "Types.h"
#include "CoreMemory.h"
#include "Rom.h"
#include "MemoryHook.h"
#include "VRAM.h"

class Memory {
public:
CoreMemory* coreMemory;
Rom* rom;
MemoryHook* cpu;
MemoryHook* gpu;
MemoryHook* timer;
uint8 column = 0;

void init(CoreMemory* coreMemory, Rom* rom, MemoryHook* cpu, MemoryHook* gpu, MemoryHook* timer);
uint8 get_8(uint16 address);
void set_8(uint16 address, uint8 value);
void set_16(uint16 address, uint16 value);
void flag_interrupt(uint8 bit);
void dma(uint8 value);
};

#endif //MY_APPLICATION_MEMORY_H
Loading

0 comments on commit e7c0d1f

Please sign in to comment.