Small ppu fixes
This commit is contained in:
parent
0019266efe
commit
53a54b084d
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
cmake-build-debug/
|
cmake-build-debug/
|
||||||
.idea/
|
.idea/
|
||||||
.vs/
|
.vs/
|
||||||
|
out/
|
||||||
@ -3,6 +3,8 @@ project(nes)
|
|||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
|
add_compile_definitions(SDL_MAIN_HANDLED)
|
||||||
|
|
||||||
add_executable(nes
|
add_executable(nes
|
||||||
main.cpp
|
main.cpp
|
||||||
src/Cartridge.cpp
|
src/Cartridge.cpp
|
||||||
|
|||||||
59
CMakePresets.json
Normal file
59
CMakePresets.json
Normal file
@ -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" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
main.cpp
3
main.cpp
@ -13,7 +13,8 @@ int main() {
|
|||||||
nes::SdlWindow window(nes::Ppu::SCREEN_WIDTH, nes::Ppu::SCREEN_HEIGHT);
|
nes::SdlWindow window(nes::Ppu::SCREEN_WIDTH, nes::Ppu::SCREEN_HEIGHT);
|
||||||
|
|
||||||
device.setNewFrameCallback(std::bind(&nes::SdlWindow::drawFrame, &window, _1));
|
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;
|
uint64_t cycles = 0;
|
||||||
while (cycles < 1000000000) {
|
while (cycles < 1000000000) {
|
||||||
|
|||||||
@ -32,7 +32,6 @@ namespace nes {
|
|||||||
_ram[address & 0x07FF] = value;
|
_ram[address & 0x07FF] = value;
|
||||||
}
|
}
|
||||||
else if(address >= 0x2000 && address < 0x4000) {
|
else if(address >= 0x2000 && address < 0x4000) {
|
||||||
std::cout << "PPU write at address: " << address << std::endl;
|
|
||||||
_ppu->write(address & 0x0007, value);
|
_ppu->write(address & 0x0007, value);
|
||||||
}
|
}
|
||||||
else if(address >= 0x8000) {
|
else if(address >= 0x8000) {
|
||||||
|
|||||||
45
src/Ppu.cpp
45
src/Ppu.cpp
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "Ppu.h"
|
#include "Ppu.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace nes {
|
namespace nes {
|
||||||
|
|
||||||
Ppu::Ppu(): _column{}, _scanline{}, _status{}, _control{}, _mask{} {
|
Ppu::Ppu(): _column{}, _scanline{}, _status{}, _control{}, _mask{} {
|
||||||
@ -84,6 +86,20 @@ namespace nes {
|
|||||||
_status.verticalBlank = 1;
|
_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 colorIndex = 0;
|
||||||
uint8_t palette = 0;
|
uint8_t palette = 0;
|
||||||
|
|
||||||
@ -119,6 +135,7 @@ namespace nes {
|
|||||||
case Status:
|
case Status:
|
||||||
value = _status.value & 0xE0;
|
value = _status.value & 0xE0;
|
||||||
_status.verticalBlank = 0;
|
_status.verticalBlank = 0;
|
||||||
|
_addressWriteInProgress = false;
|
||||||
break;
|
break;
|
||||||
case PpuData:
|
case PpuData:
|
||||||
value = _dataTemp;
|
value = _dataTemp;
|
||||||
@ -126,7 +143,7 @@ namespace nes {
|
|||||||
if(address >= 0x3F00) {
|
if(address >= 0x3F00) {
|
||||||
value = _dataTemp;
|
value = _dataTemp;
|
||||||
}
|
}
|
||||||
_vRamAddress += _control.incrementMode ? 32 : 1;
|
_vRamAddress.value += _control.incrementMode ? 32 : 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -136,22 +153,35 @@ namespace nes {
|
|||||||
switch (address) {
|
switch (address) {
|
||||||
case Control:
|
case Control:
|
||||||
_control.value = value;
|
_control.value = value;
|
||||||
|
_tRamAddress.nameTableX = _control.nameTableX;
|
||||||
|
_tRamAddress.nameTableY = _control.nameTableY;
|
||||||
break;
|
break;
|
||||||
case Mask:
|
case Mask:
|
||||||
_mask.value = value;
|
_mask.value = value;
|
||||||
break;
|
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:
|
case PpuAddress:
|
||||||
if(_addressWriteInProgress) {
|
if(_addressWriteInProgress) {
|
||||||
_vRamAddressTemp = (_vRamAddressTemp & 0xFF00) | value;
|
_tRamAddress.value = (_tRamAddress.value & 0xFF00) | value;
|
||||||
_vRamAddress = _vRamAddressTemp;
|
_vRamAddress.value = _tRamAddress.value;
|
||||||
} else {
|
} else {
|
||||||
_vRamAddressTemp = ((value & 0x3F) << 8) | (_vRamAddressTemp & 0x00FF);
|
_tRamAddress.value = ((value & 0x3F) << 8) | (_tRamAddress.value & 0x00FF);
|
||||||
}
|
}
|
||||||
_addressWriteInProgress = !_addressWriteInProgress;
|
_addressWriteInProgress = !_addressWriteInProgress;
|
||||||
break;
|
break;
|
||||||
case PpuData:
|
case PpuData:
|
||||||
internalWrite(_vRamAddress, value);
|
internalWrite(_vRamAddress.value, value);
|
||||||
_vRamAddress += _control.incrementMode ? 32 : 1;
|
_vRamAddress.value += _control.incrementMode ? 32 : 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -177,7 +207,7 @@ namespace nes {
|
|||||||
address &= 0x03FF;
|
address &= 0x03FF;
|
||||||
return _nameTable[address];
|
return _nameTable[address];
|
||||||
}
|
}
|
||||||
else if(address >= 0x3F00 && address < 0x4000) {
|
else if(address >= 0x3F00 && address < 0x4000) {
|
||||||
address &= 0x1F;
|
address &= 0x1F;
|
||||||
if (address == 0x0010) address = 0x0000;
|
if (address == 0x0010) address = 0x0000;
|
||||||
if (address == 0x0014) address = 0x0004;
|
if (address == 0x0014) address = 0x0004;
|
||||||
@ -197,6 +227,7 @@ namespace nes {
|
|||||||
}
|
}
|
||||||
else if(address >= 0x2000 && address < 0x3F00) {
|
else if(address >= 0x2000 && address < 0x3F00) {
|
||||||
address &= 0x03FF;
|
address &= 0x03FF;
|
||||||
|
//std::cout << std::hex << "Writing nametable, address: " << (int)address << ", value: " << (int)value << std::endl;
|
||||||
_nameTable[address] = value;
|
_nameTable[address] = value;
|
||||||
}
|
}
|
||||||
else if(address >= 0x3F00 && address < 0x4000) {
|
else if(address >= 0x3F00 && address < 0x4000) {
|
||||||
|
|||||||
17
src/Ppu.h
17
src/Ppu.h
@ -74,6 +74,18 @@ namespace nes {
|
|||||||
uint8_t value;
|
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:
|
public:
|
||||||
Ppu();
|
Ppu();
|
||||||
bool tick();
|
bool tick();
|
||||||
@ -97,10 +109,11 @@ namespace nes {
|
|||||||
ControlRegister _control;
|
ControlRegister _control;
|
||||||
MaskRegister _mask;
|
MaskRegister _mask;
|
||||||
|
|
||||||
uint16_t _vRamAddress;
|
LoopyRegister _vRamAddress;
|
||||||
uint16_t _vRamAddressTemp;
|
LoopyRegister _tRamAddress;
|
||||||
bool _addressWriteInProgress;
|
bool _addressWriteInProgress;
|
||||||
uint8_t _dataTemp;
|
uint8_t _dataTemp;
|
||||||
|
uint8_t _fineX;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<uint8_t[]> _nameTable;
|
std::unique_ptr<uint8_t[]> _nameTable;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user