Adding DMA for OAM
This commit is contained in:
parent
cf0a1a5cfe
commit
c1bd4c863f
@ -26,7 +26,7 @@ add_executable(nes
|
||||
src/Controller.cpp
|
||||
src/Controller.h
|
||||
src/SdlKeyboardController.cpp
|
||||
src/SdlKeyboardController.h)
|
||||
src/SdlKeyboardController.h src/Dma.cpp src/Dma.h)
|
||||
|
||||
find_package(SDL2 CONFIG REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
|
||||
2
main.cpp
2
main.cpp
@ -20,7 +20,7 @@ int main() {
|
||||
while(SDL_PollEvent(&e));
|
||||
});
|
||||
device.connect(std::make_shared<SdlKeyboardController>());
|
||||
device.insertCartridge("/home/selim/Downloads/smb.nes");
|
||||
device.insertCartridge("/home/selim/Downloads/dk.nes");
|
||||
//device.insertCartridge("/Users/selim/Documents/nestest.nes");
|
||||
//device.insertCartridge("C:\\Users\\selim\\Documents\\nestest.nes");
|
||||
|
||||
|
||||
44
src/Dma.cpp
Normal file
44
src/Dma.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by selim on 9/23/23.
|
||||
//
|
||||
|
||||
#include "Dma.h"
|
||||
#include "Ppu.h"
|
||||
#include "Nes.h"
|
||||
|
||||
namespace nes {
|
||||
|
||||
Dma::Dma(Nes *system, Ppu *ppu): _system{system}, _ppu{ppu} {
|
||||
|
||||
}
|
||||
|
||||
bool Dma::active() const {
|
||||
return _active;
|
||||
}
|
||||
|
||||
void Dma::tick(uint64_t cycles) {
|
||||
if(_dummy) {
|
||||
if(cycles % 2 == 1) {
|
||||
_dummy = false;
|
||||
}
|
||||
} else {
|
||||
if(cycles % 2 == 0) {
|
||||
_data = _system->read((_page << 8) | _address);
|
||||
} else {
|
||||
_ppu->writeOam(_address, _data);
|
||||
_address++;
|
||||
|
||||
if(_address == 0) {
|
||||
_active = false;
|
||||
_dummy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dma::start(uint8_t page) {
|
||||
_page = page;
|
||||
_active = true;
|
||||
}
|
||||
|
||||
}
|
||||
38
src/Dma.h
Normal file
38
src/Dma.h
Normal file
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Created by selim on 9/23/23.
|
||||
//
|
||||
|
||||
#ifndef NES_DMA_H
|
||||
#define NES_DMA_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace nes {
|
||||
|
||||
class Nes;
|
||||
class Ppu;
|
||||
|
||||
class Dma {
|
||||
public:
|
||||
Dma(Nes* system, Ppu* ppu);
|
||||
[[nodiscard]] bool active() const;
|
||||
void tick(uint64_t cycles);
|
||||
void start(uint8_t page);
|
||||
|
||||
private:
|
||||
Nes* _system;
|
||||
Ppu* _ppu;
|
||||
|
||||
private:
|
||||
uint8_t _page = 0;
|
||||
uint8_t _address = 0;
|
||||
uint8_t _data = 0;
|
||||
|
||||
private:
|
||||
bool _active = false;
|
||||
bool _dummy = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //NES_DMA_H
|
||||
@ -22,6 +22,7 @@ namespace nes {
|
||||
_ram = std::make_unique<uint8_t[]>(2*1024);
|
||||
_cpu = std::make_unique<Cpu>(this);
|
||||
_ppu = std::make_unique<Ppu>();
|
||||
_dma = std::make_unique<Dma>(this, _ppu.get());
|
||||
}
|
||||
|
||||
void Nes::insertCartridge(const fs::path &path, std::optional<uint16_t> address) {
|
||||
@ -54,6 +55,9 @@ namespace nes {
|
||||
#endif
|
||||
|
||||
if(_cycles % 3 == 0) {
|
||||
if(_dma->active()) {
|
||||
_dma->tick(_cycles);
|
||||
} else {
|
||||
bool instructionExecuted = _cpu->tick();
|
||||
#ifdef NES_LOGGING
|
||||
if(instructionExecuted) {
|
||||
@ -61,6 +65,7 @@ namespace nes {
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(needInterrupt) {
|
||||
_cpu->nmi();
|
||||
@ -111,7 +116,7 @@ namespace nes {
|
||||
std::cout << "Cartridge write at address: " << address << std::endl;
|
||||
}
|
||||
else if(address == 0x4014) {
|
||||
// DMA
|
||||
_dma->start(value);
|
||||
}
|
||||
else if(address == 0x4016) {
|
||||
_controller1->poll();
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include "Cpu.h"
|
||||
#include "Ppu.h"
|
||||
#include "Cartridge.h"
|
||||
#include "Dma.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
@ -40,6 +41,7 @@ namespace nes {
|
||||
std::unique_ptr<Ppu> _ppu;
|
||||
std::unique_ptr<Cartridge> _cartridge;
|
||||
std::shared_ptr<Controller> _controller1;
|
||||
std::unique_ptr<Dma> _dma;
|
||||
|
||||
#ifdef NES_LOGGING
|
||||
Logger _logger;
|
||||
|
||||
@ -415,4 +415,9 @@ namespace nes {
|
||||
_bgAttribShifter._lo,
|
||||
_bgAttribShifter._hi);
|
||||
}
|
||||
|
||||
void Ppu::writeOam(uint8_t address, uint8_t data) {
|
||||
auto oamPtr = reinterpret_cast<uint8_t*>(_oamData.get());
|
||||
oamPtr[address] = data;
|
||||
}
|
||||
}
|
||||
@ -112,7 +112,8 @@ namespace nes {
|
||||
void setPixel(uint16_t row, uint16_t column, Pixel pixel);
|
||||
void connect(Cartridge* cartridge);
|
||||
void reset();
|
||||
std::string state() const;
|
||||
[[nodiscard]] std::string state() const;
|
||||
void writeOam(uint8_t address, uint8_t data);
|
||||
|
||||
public:
|
||||
std::function<void(const Pixel*)> onNewFrame;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user