added ppu
This commit is contained in:
parent
1af2c37b70
commit
19d138fb5f
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c" "opcodes.c" "log.c")
|
||||
add_executable (nesemu "main.c" "cpu.h" "types.h" "bus.h" "bus.c" "cartridge.h" "cpu.c" "cartridge.c" "opcodes.c" "log.c" "ppu.h" "ppu.c")
|
||||
|
||||
if(MSVC)
|
||||
target_compile_definitions(nesemu PUBLIC _CRT_SECURE_NO_WARNINGS)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <memory.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "ppu.h"
|
||||
#include "cartridge.h"
|
||||
|
||||
struct Bus* createBus()
|
||||
|
@ -35,6 +36,9 @@ struct Bus* createBus()
|
|||
// Create CPU and attach it
|
||||
bus->cpu = createCPU(bus);
|
||||
|
||||
// Create PPU and attack it
|
||||
bus->ppu = createPPU(bus);
|
||||
|
||||
// Create and insert cartridge
|
||||
bus->cartridge = createCartridge(bus, "roms/nestest.nes");
|
||||
|
||||
|
@ -46,6 +50,7 @@ struct Bus* createBus()
|
|||
void destroyBus(struct Bus* bus)
|
||||
{
|
||||
destroyCartridge(bus->cartridge);
|
||||
destroyPPU(bus->ppu);
|
||||
destroyCPU(bus->cpu);
|
||||
|
||||
free(bus->io);
|
||||
|
@ -104,5 +109,8 @@ void writeBus(struct Bus* bus, Word addr, Byte val)
|
|||
|
||||
void tick(struct Bus* bus)
|
||||
{
|
||||
tickInstr(bus->cpu);
|
||||
for (int i = 0; i < 3; i++)
|
||||
tickPPU(bus->ppu);
|
||||
|
||||
tickCPU(bus->cpu);
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include "types.h"
|
||||
|
||||
struct CPU;
|
||||
struct PPU;
|
||||
struct Cartridge;
|
||||
|
||||
// Main communication path for devices and memory in the NES
|
||||
|
@ -13,6 +14,7 @@ struct Bus
|
|||
Byte* io;
|
||||
|
||||
struct CPU* cpu;
|
||||
struct PPU* ppu;
|
||||
struct Cartridge* cartridge;
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include "bus.h"
|
||||
#include "cpu.h"
|
||||
#include "ppu.h"
|
||||
|
||||
void logBusState(struct Bus* bus)
|
||||
{
|
||||
|
@ -40,5 +41,11 @@ void logBusState(struct Bus* bus)
|
|||
|
||||
printf("%-28s", buffer);
|
||||
|
||||
printf("A:%02X X:%02X Y:%02X SP:%02X P:%02X CYC:%zu\n", bus->cpu->acc, bus->cpu->x, bus->cpu->y, bus->cpu->sp, bus->cpu->status.raw, bus->cpu->totalCycles);
|
||||
printf("A:%02X X:%02X Y:%02X SP:%02X P:%02X PPU:%3d,%3d CYC:%zu\n",
|
||||
bus->cpu->acc,
|
||||
bus->cpu->x, bus->cpu->y,
|
||||
bus->cpu->sp,
|
||||
bus->cpu->status.raw,
|
||||
bus->ppu->y, bus->ppu->x,
|
||||
bus->cpu->totalCycles);
|
||||
}
|
101
NES Emulator/ppu.c
Normal file
101
NES Emulator/ppu.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include "ppu.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include "bus.h"
|
||||
|
||||
struct PPU* createPPU(struct Bus* parent)
|
||||
{
|
||||
struct PPU* ppu = (struct PPU*)malloc(sizeof(struct PPU));
|
||||
if (ppu == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate memory for PPU object.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ppu->bus = parent;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
ppu->patternTables[i] = (Byte*)malloc(0x1000);
|
||||
if (ppu->patternTables[i] == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate memory for PPU pattern table #%d object.\n", i);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(ppu->patternTables[i], 0, 0x1000);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ppu->nametables[i] = (Byte*)malloc(0x0400);
|
||||
if (ppu->nametables[i] == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate memory for PPU nametable #%d object.\n", i);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(ppu->nametables[i], 0, 0x0400);
|
||||
}
|
||||
|
||||
ppu->paletteIndexes = (Byte*)malloc(0x20);
|
||||
if (ppu->paletteIndexes == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate memory for PPU palette RAM indexes.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ppu->oam = (Byte*)malloc(0x100);
|
||||
if (ppu->oam == NULL)
|
||||
{
|
||||
fprintf(stderr, "Failed to allocate memory for PPU OAM.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ppu->ppuctrl.raw = 0b00000000;
|
||||
ppu->ppumask.raw = 0b00000000;
|
||||
ppu->ppustatus.raw = 0b10100000;
|
||||
ppu->oamaddr = 0x00;
|
||||
ppu->ppuAddr = 0x00;
|
||||
ppu->ppuData = 0x00;
|
||||
|
||||
ppu->x = 0;
|
||||
ppu->y = 0;
|
||||
|
||||
return ppu;
|
||||
}
|
||||
|
||||
void destroyPPU(struct PPU* ppu)
|
||||
{
|
||||
free(ppu->oam);
|
||||
free(ppu->paletteIndexes);
|
||||
free(ppu->nametables);
|
||||
free(ppu->patternTables);
|
||||
|
||||
free(ppu);
|
||||
}
|
||||
|
||||
Byte ppuRead(struct PPU* ppu, Word addr)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void ppuWrite(struct PPU* ppu, Word addr, Byte val)
|
||||
{
|
||||
}
|
||||
|
||||
void tickPPU(struct PPU* ppu)
|
||||
{
|
||||
ppu->x++;
|
||||
|
||||
if (ppu->x == 341)
|
||||
{
|
||||
ppu->x = 0;
|
||||
ppu->y++;
|
||||
|
||||
if (ppu->y == 261)
|
||||
ppu->y = 0;
|
||||
}
|
||||
}
|
95
NES Emulator/ppu.h
Normal file
95
NES Emulator/ppu.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef _PPU_H_
|
||||
#define _PPU_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct Bus;
|
||||
|
||||
struct PPU
|
||||
{
|
||||
// REGISTERS
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Byte nametable : 2;
|
||||
Byte increment : 1;
|
||||
Byte spriteTile : 1;
|
||||
Byte bgTile : 1;
|
||||
Byte spriteHeight : 1;
|
||||
Byte master : 1;
|
||||
Byte nmiEnable : 1;
|
||||
};
|
||||
|
||||
Byte raw;
|
||||
|
||||
} ppuctrl;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Byte greyscale : 1;
|
||||
Byte bgLeftColumn : 1;
|
||||
Byte spriteLeftColumn : 1;
|
||||
Byte bgEnable : 1;
|
||||
Byte spriteEnable : 1;
|
||||
Byte colorEmphasis : 3;
|
||||
};
|
||||
|
||||
Byte raw;
|
||||
|
||||
} ppumask;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Byte padding : 5;
|
||||
Byte overflow : 1;
|
||||
Byte spriteZeroHit : 1;
|
||||
Byte vBlank : 1;
|
||||
};
|
||||
|
||||
Byte raw;
|
||||
|
||||
} ppustatus;
|
||||
|
||||
Byte oamaddr;
|
||||
Byte oamdata;
|
||||
Byte ppuScroll;
|
||||
Byte ppuAddr;
|
||||
Byte ppuData;
|
||||
Byte oamdma;
|
||||
|
||||
Byte* patternTables[2];
|
||||
Byte* nametables[4];
|
||||
Byte* paletteIndexes;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Byte y;
|
||||
Byte tile;
|
||||
Byte attr;
|
||||
Byte x;
|
||||
};
|
||||
|
||||
DWord raw;
|
||||
}* oam;
|
||||
|
||||
Word x, y;
|
||||
|
||||
struct Bus* bus;
|
||||
};
|
||||
|
||||
struct PPU* createPPU(struct Bus* parent);
|
||||
void destroyPPU(struct PPU* ppu);
|
||||
|
||||
Byte ppuRead(struct PPU* ppu, Word addr);
|
||||
void ppuWrite(struct PPU* ppu, Word addr, Byte val);
|
||||
|
||||
void tickPPU(struct PPU* ppu);
|
||||
|
||||
#endif // _PPU_H_
|
Loading…
Reference in a new issue