1
0
Fork 0
This commit is contained in:
Austin Morlan 2019-09-11 16:20:30 -07:00
parent b1265da7d3
commit f6e339105a
Signed by: austin
GPG Key ID: FD6B27654AF5E348
7 changed files with 198 additions and 4 deletions

View File

@ -14,6 +14,7 @@ target_sources(
Source/CPU/CPU.cpp
Source/CPU/AddressModes.cpp
Source/CPU/Instructions.cpp
Source/Input.cpp
Source/NES.cpp
Source/Platform.cpp
Source/PPU/PPU.cpp

40
Source/Input.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "Input.hpp"
void Input::Strobe(uint8_t* but)
{
if (strobe)
{
for (int i = 0; i < 8; ++i)
{
buttons[i] = but[i];
}
}
}
uint8_t Input::Poll()
{
uint8_t buttonState;
// Strobe set - return state of A button
if (strobe)
{
buttonState = buttons[Buttons::A];
}
// All 8 bits read - return 1u
else if (buttonIndex > Buttons::Right)
{
buttonState = 1u;
}
// Return next bit
else
{
buttonState = buttons[buttonIndex];
++buttonIndex;
}
return buttonState;
}

32
Source/Input.hpp Normal file
View File

@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <cstdio>
enum Buttons
{
A = 0,
B = 1,
Select = 2,
Start = 3,
Up = 4,
Down = 5,
Left = 6,
Right = 7
};
class Input
{
public:
void Strobe(uint8_t* but);
uint8_t Poll();
private:
friend class NES;
bool strobe{};
uint8_t buttonIndex{};
uint8_t buttons[8]{};
};

View File

@ -44,7 +44,8 @@ NES::NES()
: cpu(std::make_unique<CPU>()),
ppu(std::make_unique<PPU>()),
cartridge(std::make_unique<Cartridge>()),
platform(std::make_unique<Platform>("NES", WINDOW_WIDTH, WINDOW_HEIGHT, VIDEO_WIDTH, VIDEO_HEIGHT))
platform(std::make_unique<Platform>("NES", WINDOW_WIDTH, WINDOW_HEIGHT, VIDEO_WIDTH, VIDEO_HEIGHT)),
input(std::make_unique<Input>())
{
ppu->nes = this;
@ -123,10 +124,14 @@ void NES::InsertCartridge(char const* filename)
void NES::Run()
{
while (!platform->ProcessInput())
uint8_t buttons[8]{};
while (!platform->ProcessInput(buttons))
{
cpu->Cycle();
input->Strobe(buttons);
uint8_t cpuCyclesTaken = (cpu->cycles - cpu->prevCycles) * 3u;
ppu->Cycle(cpuCyclesTaken);
@ -166,6 +171,7 @@ void NES::Write(BusSource source, uint16_t address, uint8_t value)
{
uint16_t index = address & 0x1Fu;
// PPU OAM
if (index == 0x14u)
{
uint8_t addrMsb = value;
@ -177,6 +183,20 @@ void NES::Write(BusSource source, uint16_t address, uint8_t value)
ppu->oam[ppu->oamAddr + addrLsb] = Read(BusSource::CPU, addr);
}
}
// Controller
else if (index == 0x16u)
{
if (value & 0x1u)
{
input->strobe = true;
}
else
{
input->strobe = false;
input->buttonIndex = 0u;
}
}
}
// Expansion I/O
@ -253,6 +273,13 @@ uint8_t NES::Read(BusSource source, uint16_t address)
// APU and IO
else if (address < 0x4020u)
{
uint16_t index = address & 0x1Fu;
// Controller
if (index == 0x16u)
{
byte = input->Poll();
}
}
// Expansion I/O

View File

@ -2,6 +2,7 @@
#include "Cartridge.hpp"
#include "CPU/CPU.hpp"
#include "Input.hpp"
#include "Platform.hpp"
#include "PPU/PPU.hpp"
#include <memory>
@ -45,6 +46,7 @@ public:
std::unique_ptr<PPU> ppu;
std::unique_ptr<Cartridge> cartridge;
std::unique_ptr<Platform> platform;
std::unique_ptr<Input> input;
bool nmi{};
Color palette[64];

View File

@ -1,4 +1,5 @@
#include "Platform.hpp"
#include "Input.hpp"
#include <SDL2/SDL.h>
@ -30,7 +31,7 @@ void Platform::Update(void const* buffer, int pitch)
SDL_RenderPresent(renderer);
}
bool Platform::ProcessInput()
bool Platform::ProcessInput(uint8_t* buttons)
{
bool quit = false;
@ -55,6 +56,95 @@ bool Platform::ProcessInput()
quit = true;
break;
}
case SDLK_UP:
{
{buttons[Buttons::Up] = 1u;}
break;
}
case SDLK_DOWN:
{
{buttons[Buttons::Down] = 1u;}
break;
}
case SDLK_LEFT:
{
{buttons[Buttons::Left] = 1u;}
break;
}
case SDLK_RIGHT:
{
{buttons[Buttons::Right] = 1u;}
break;
}
case SDLK_LSHIFT:
{
buttons[Buttons::Select] = 1u;
break;
}
case SDLK_RETURN:
{
{buttons[Buttons::Start] = 1u;}
break;
}
case SDLK_z:
{
{buttons[Buttons::A] = 1u;}
break;
}
case SDLK_x:
{
{buttons[Buttons::B] = 1u;}
break;
}
}
break;
}
case SDL_KEYUP:
{
switch (event.key.keysym.sym)
{
case SDLK_UP:
{
{buttons[Buttons::Up] = 0u;}
break;
}
case SDLK_DOWN:
{
{buttons[Buttons::Down] = 0u;}
break;
}
case SDLK_LEFT:
{
{buttons[Buttons::Left] = 0u;}
break;
}
case SDLK_RIGHT:
{
{buttons[Buttons::Right] = 0u;}
break;
}
case SDLK_LSHIFT:
{
{buttons[Buttons::Select] = 0u;}
break;
}
case SDLK_RETURN:
{
{buttons[Buttons::Start] = 0u;}
break;
}
case SDLK_z:
{
{buttons[Buttons::A] = 0u;}
break;
}
case SDLK_x:
{
{buttons[Buttons::B] = 0u;}
break;
}
}
break;
@ -62,5 +152,6 @@ bool Platform::ProcessInput()
}
}
return quit;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <cstdint>
#include "Input.hpp"
class SDL_Window;
@ -14,7 +15,7 @@ public:
Platform(char const* title, int windowWidth, int windowHeight, int textureWidth, int textureHeight);
~Platform();
void Update(void const* buffer, int pitch);
bool ProcessInput();
bool ProcessInput(uint8_t* buttons);
SDL_Window* window{};
SDL_Renderer* renderer{};