initial commit

This commit is contained in:
c1m5j 2021-07-30 13:44:51 +02:00
commit ae2b3d3451
40 changed files with 55111 additions and 0 deletions

26
include/audio.hpp Normal file
View file

@ -0,0 +1,26 @@
#pragma once
/**
* The Bytepusher's audio device. 8-bit mono sound with 256 samples
* per frame, their location in memory being indicated by bytes 6
* and 7 in the memory map.
* With the audio I largely helped myself with David Jolly's (majestic53)
* implementation `bpvm` which you can find on his GitHub. Thanks David!
*/
#include <stdlib.h>
#include <SDL2/SDL.h>
class Bus;
class Audio {
public:
Audio(Bus* bus);
~Audio();
void Play();
private:
Bus* bus;
SDL_AudioSpec spec;
SDL_AudioDeviceID device;
};

25
include/bus.hpp Normal file
View file

@ -0,0 +1,25 @@
#pragma once
/**
* A simple "system bus" which allows for interconnection between
* components, saving us passing pointers or references to each
* other every function call.
*/
class CPU;
class Display;
class Audio;
class Memory;
class Input;
class Bus {
public:
Bus();
~Bus();
Memory* memory;
CPU* cpu;
Display* display;
Audio* audio;
Input* input;
};

29
include/cpu.hpp Normal file
View file

@ -0,0 +1,29 @@
#pragma once
/**
* The Bytepusher's CPU, powered by a OISC (one instruction-set computer)
* called ByteByteJump. During an instruction, the CPU reads in three 3-byte values
* from memory (pointed to by the PC, program counter) A, B, and C. It then performs two steps,
* 1. copy the value from memory[A] to memory[B],
* 2. set the PC to C.
*/
#include <iostream>
#include "memory.hpp"
class Bus;
class CPU {
public:
CPU(Bus* bus);
~CPU();
void Step();
void Reset();
void setKeyBit(uint8_t index);
void clearKeyBit(uint8_t index);
private:
Bus* bus;
uint8_t* pc;
};

40
include/display.hpp Normal file
View file

@ -0,0 +1,40 @@
#pragma once
/**
* The Bytepusher has a display of dimensions 256 x 256,
* 1 byte per pixel (we scale it to 512x512 anyway). That makes
* the display data 65 536 bytes large. The location of that display
* data is indicated by byte 5 in the memory map.
* The color palette has 216 colors, leaving the remaining 256-216=40 colors
* simply black.
* Each color is a combination of red, green, and blue, of which each
* can have an intensity from 0 to 5. That makes the increment 0x33:
*
* ---------------------------------------------------------
* intensity || 0 || 1 || 2 || 3 || 4 || 5
* value || 0x00 || 0x33 || 0x66 || 0x99 || 0xCC || 0xFF
* ---------------------------------------------------------
*/
#include <SDL2/SDL.h>
class Bus;
class Display {
public:
Display(Bus* bus, SDL_Renderer* ren);
~Display();
void PrepareColorPalette();
void UpdateTexture();
void Reset();
SDL_Texture* displayTexture;
static const int width = 256;
static const int height = 256;
SDL_Color display[width * height];
private:
Bus* bus;
SDL_Color colorPalette[256];
};

36
include/input.hpp Normal file
View file

@ -0,0 +1,36 @@
#pragma once
/**
* The Bytepusher's controller consists of 16 keys
* in a 4x4 keyboard labelled 0-F;
*
* 1 (1) || 2 (2) || 3 (3) || C (4)
* --------------------------------
* 4 (Q) || 5 (W) || 6 (E) || D (R)
* --------------------------------
* 7 (A) || 8 (S) || 9 (D) || E (F)
* --------------------------------
* A (Z) || 0 (X) || B (C) || C (V)
*
* whose states correspond to those of their respective
* bits in the first two bytes of memory. The actual
* keyboard state can be seen in the debug window.
*/
#include <SDL2/SDL.h>
class Bus;
class Input {
public:
Input(Bus* bus);
~Input();
void HandleKeyDown(SDL_Keycode keycode);
void HandleKeyUp(SDL_Keycode keycode);
void SetKeyBit(uint8_t bit);
void UnsetKeyBit(uint8_t bit);
private:
Bus* bus;
};

49
include/memory.hpp Normal file
View file

@ -0,0 +1,49 @@
#pragma once
/**
* The memory of the Bytepusher. 16 MiB (0x1000008 bytes).
* The memory map is located at the beginning of memory and
* looks like this:
*
* memory (byte) | description
* --------------|----------------
* 0, 1 | Keyboard state, if key X is
* | pressed then bit X is on
* |
* 2, 3, 4 | The program counter starts here
* |
* 5 | Graphics block location. A value
* | of ZZ means color of pixel at coordinate (XX, YY)
* | is at ZZYYXX
* |
* 6, 7 | Sound block location. A value of XXYY
* | means audio sample ZZ is at address XXYY
* -------------------------------
* The byte ordering used by Bytepusher is big-endian.
*/
#include <stdlib.h>
#include <string>
class Bus;
class Memory {
public:
Memory(Bus* bus);
~Memory();
static const size_t MEMORY_SIZE = 0x1000008;
uint8_t mem[MEMORY_SIZE];
bool ROMLoaded;
std::string ROMFilepath;
size_t ROMSize;
std::string ROMLoadError;
std::string snapshotError;
std::string snapshotLast;
void Reset();
bool LoadROM(std::string filepath);
bool SnapshotRAM(std::string filepath);
private:
Bus* bus;
};