From 53a54b084d1a5e7de8897071eb7e0b5660d7f3e3 Mon Sep 17 00:00:00 2001 From: Selim Mustafaev Date: Sun, 3 Sep 2023 16:03:08 +0300 Subject: [PATCH] Small ppu fixes --- .gitignore | 3 ++- CMakeLists.txt | 2 ++ CMakePresets.json | 59 +++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 3 ++- src/Bus.cpp | 1 - src/Ppu.cpp | 45 ++++++++++++++++++++++++++++++------ src/Ppu.h | 17 ++++++++++++-- 7 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 CMakePresets.json diff --git a/.gitignore b/.gitignore index 8b7d20d..3bdae91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ cmake-build-debug/ .idea/ -.vs/ \ No newline at end of file +.vs/ +out/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f3a11eb..c4e510f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ project(nes) set(CMAKE_CXX_STANDARD 23) +add_compile_definitions(SDL_MAIN_HANDLED) + add_executable(nes main.cpp src/Cartridge.cpp diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..0d75963 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,59 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "windows-base", + "description": "Target Windows with the Visual Studio development environment.", + "hidden": true, + "generator": "Ninja", + "binaryDir": "${sourceDir}/out/build/${presetName}", + "installDir": "${sourceDir}/out/install/${presetName}", + "cacheVariables": { + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" + }, + { + "name": "x64-debug", + "displayName": "x64 Debug", + "description": "Target Windows (64-bit) with the Visual Studio development environment. (Debug)", + "inherits": "windows-base", + "architecture": { + "value": "x64", + "strategy": "external" + }, + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "x64-release", + "displayName": "x64 Release", + "description": "Target Windows (64-bit) with the Visual Studio development environment. (RelWithDebInfo)", + "inherits": "x64-debug", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + }, + { + "name": "x86-debug", + "displayName": "x86 Debug", + "description": "Target Windows (32-bit) with the Visual Studio development environment. (Debug)", + "inherits": "windows-base", + "architecture": { + "value": "x86", + "strategy": "external" + }, + "cacheVariables": { "CMAKE_BUILD_TYPE": "Debug" } + }, + { + "name": "x86-release", + "displayName": "x86 Release", + "description": "Target Windows (32-bit) with the Visual Studio development environment. (RelWithDebInfo)", + "inherits": "x86-debug", + "cacheVariables": { "CMAKE_BUILD_TYPE": "Release" } + } + ] +} \ No newline at end of file diff --git a/main.cpp b/main.cpp index b5471c8..302094a 100644 --- a/main.cpp +++ b/main.cpp @@ -13,7 +13,8 @@ int main() { nes::SdlWindow window(nes::Ppu::SCREEN_WIDTH, nes::Ppu::SCREEN_HEIGHT); device.setNewFrameCallback(std::bind(&nes::SdlWindow::drawFrame, &window, _1)); - device.insertCartridge("/home/selim/Downloads/nestest.nes"); + //device.insertCartridge("/home/selim/Downloads/nestest.nes"); + device.insertCartridge("C:\\Users\\selim\\Documents\\nestest.nes"); uint64_t cycles = 0; while (cycles < 1000000000) { diff --git a/src/Bus.cpp b/src/Bus.cpp index 5abebd9..0fc397b 100644 --- a/src/Bus.cpp +++ b/src/Bus.cpp @@ -32,7 +32,6 @@ namespace nes { _ram[address & 0x07FF] = value; } else if(address >= 0x2000 && address < 0x4000) { - std::cout << "PPU write at address: " << address << std::endl; _ppu->write(address & 0x0007, value); } else if(address >= 0x8000) { diff --git a/src/Ppu.cpp b/src/Ppu.cpp index 51024ab..9c7fc78 100644 --- a/src/Ppu.cpp +++ b/src/Ppu.cpp @@ -4,6 +4,8 @@ #include "Ppu.h" +#include + namespace nes { Ppu::Ppu(): _column{}, _scanline{}, _status{}, _control{}, _mask{} { @@ -84,6 +86,20 @@ namespace nes { _status.verticalBlank = 1; } + // All visible scanlines + if (_scanline >= -1 && _scanline < 240) { + if (_scanline == -1 && _column == 1) { + _status.verticalBlank = 0; + } + + // + if ((_column >= 2 && _column < 258) || (_column >= 321 && _column < 338)) { + switch ((_column - 1) % 8) { + + } + } + } + uint8_t colorIndex = 0; uint8_t palette = 0; @@ -119,6 +135,7 @@ namespace nes { case Status: value = _status.value & 0xE0; _status.verticalBlank = 0; + _addressWriteInProgress = false; break; case PpuData: value = _dataTemp; @@ -126,7 +143,7 @@ namespace nes { if(address >= 0x3F00) { value = _dataTemp; } - _vRamAddress += _control.incrementMode ? 32 : 1; + _vRamAddress.value += _control.incrementMode ? 32 : 1; break; } return value; @@ -136,22 +153,35 @@ namespace nes { switch (address) { case Control: _control.value = value; + _tRamAddress.nameTableX = _control.nameTableX; + _tRamAddress.nameTableY = _control.nameTableY; break; case Mask: _mask.value = value; break; + case Scroll: + if (_addressWriteInProgress) { + _tRamAddress.fineY = value & 0x7; + _tRamAddress.coarseY = value >> 3; + } + else { + _fineX = value & 0x7; + _tRamAddress.coarseX = value >> 3; + } + _addressWriteInProgress = !_addressWriteInProgress; + break; case PpuAddress: if(_addressWriteInProgress) { - _vRamAddressTemp = (_vRamAddressTemp & 0xFF00) | value; - _vRamAddress = _vRamAddressTemp; + _tRamAddress.value = (_tRamAddress.value & 0xFF00) | value; + _vRamAddress.value = _tRamAddress.value; } else { - _vRamAddressTemp = ((value & 0x3F) << 8) | (_vRamAddressTemp & 0x00FF); + _tRamAddress.value = ((value & 0x3F) << 8) | (_tRamAddress.value & 0x00FF); } _addressWriteInProgress = !_addressWriteInProgress; break; case PpuData: - internalWrite(_vRamAddress, value); - _vRamAddress += _control.incrementMode ? 32 : 1; + internalWrite(_vRamAddress.value, value); + _vRamAddress.value += _control.incrementMode ? 32 : 1; break; default: break; @@ -177,7 +207,7 @@ namespace nes { address &= 0x03FF; return _nameTable[address]; } - else if(address >= 0x3F00 && address < 0x4000) { + else if(address >= 0x3F00 && address < 0x4000) { address &= 0x1F; if (address == 0x0010) address = 0x0000; if (address == 0x0014) address = 0x0004; @@ -197,6 +227,7 @@ namespace nes { } else if(address >= 0x2000 && address < 0x3F00) { address &= 0x03FF; + //std::cout << std::hex << "Writing nametable, address: " << (int)address << ", value: " << (int)value << std::endl; _nameTable[address] = value; } else if(address >= 0x3F00 && address < 0x4000) { diff --git a/src/Ppu.h b/src/Ppu.h index 0d455c1..0313b37 100644 --- a/src/Ppu.h +++ b/src/Ppu.h @@ -74,6 +74,18 @@ namespace nes { uint8_t value; }; + union LoopyRegister { + struct { + uint8_t coarseX : 5; + uint8_t coarseY : 5; + uint8_t nameTableX : 1; + uint8_t nameTableY : 1; + uint8_t fineY : 3; + uint8_t unused : 1; + }; + uint16_t value; + }; + public: Ppu(); bool tick(); @@ -97,10 +109,11 @@ namespace nes { ControlRegister _control; MaskRegister _mask; - uint16_t _vRamAddress; - uint16_t _vRamAddressTemp; + LoopyRegister _vRamAddress; + LoopyRegister _tRamAddress; bool _addressWriteInProgress; uint8_t _dataTemp; + uint8_t _fineX; private: std::unique_ptr _nameTable;