diff --git a/ppu.c b/ppu.c index f2e6732..95c5a6d 100644 --- a/ppu.c +++ b/ppu.c @@ -1,11 +1,69 @@ #include "ppu.h" +#include "common.h" #include "cartridge.h" //needs acces to the cartridge to load CHR maps, since r/w functions are in-house instead of bus-wide like it is for busRead/Write it needs to be imported here too, quite like there are physical wires connecting the cartridge CHR bank pins to the PPU -byte ppuBus[0x3FFF]; +#define PPU_BUS_SIZE (0x3FFF) +byte ppuBus[PPU_BUS_SIZE]; PPU ppu; +inline word resolveNameTableAddress(word regData){ + return (regData & 0b0000111111111111) | (1 << (14 - 1)); +} + +/* +10NNYYYYYXXXXX +10100010100011 ==> $28A3 +--~~-----~~~~~ +^ ^ ^ ^ +| | | | +| | y=5 x=3 +| | +| 3rd name table +| +fixed +*/ + +word resolveAttributeTableAddress(word regData){ + locationRegister n; + n.data = regData; + byte trimmedCoarseX = n.bits.coarseX >> 2; //trim the lowest 2 bits of coarse X + byte trimmedCoarseY = n.bits.coarseY >> 2; //trim the lowest 2 bits of coarse Y + + word ret = trimmedCoarseX | (trimmedCoarseY << 3); //YYYXXX + ret = 0b1111 >> 6 | ret; //1111YYYXXX + ret = n.bits.nameTableID << 10 | ret; //NN1111YYYXXX + ret = 0b10 << 12 | ret; //10NN1111YYYXXX + + return ret; +} + +/* +10NN1111YYYXXX +10101111001000 +--~~----~~~--- +^ ^ ^ ^ ^ +| | | | | +| | | | x=3>>2 +| | | | +| | | y=5>>2 +| | | +| | offset of the attribute table from a name table +| | each name table has 960 bytes, i.e. $3C0 == 1111000000 +| | that's why the address has 1111 in the middle +| | +| 3rd name table +| +fixed +*/ + + +// ---- +// +//BUS ENGINE FUNCTIONS +// +// ---- byte ppuRead(word address){ @@ -212,9 +270,6 @@ void initPpu(){ ppu.dataByteBuffer = 0; ppu.mask.full = 0; ppu.status.full = 0; - - ppu.vReg.bits.fixedOne = 1; - ppu.tReg.bits.fixedOne = 1; } void ppuClock(){ diff --git a/ppu.h b/ppu.h index 4ff909a..3b08023 100644 --- a/ppu.h +++ b/ppu.h @@ -3,6 +3,22 @@ //Credits to wiki.nesdev.com for these register graphs //https://wiki.nesdev.com/w/index.php?title=PPU_registers +typedef struct{ + union{ + struct{ + byte unused : 1; + byte fineY : 3; + byte nameTableID : 2; + byte coarseY : 5; + byte coarseX : 5; + + }bits; + + word data; + }; +}locationRegister; + + //Start of PPU struct typedef struct{ @@ -81,35 +97,9 @@ typedef struct{ byte dataByteBuffer; - struct{ - union{ - struct{ - byte fixedOne : 1; - byte fineY : 3; - byte nameTableID : 2; - byte coarseY : 5; - byte coarseX : 5; - - }bits; - - word data; - }; - }vReg; //Search for: "IMPORTANT V SYNC" in ppu.c to see moments where the 2 sync + locationRegister vReg; //Search for: "IMPORTANT V SYNC" in ppu.c to see moments where the 2 sync - struct{ - union{ - struct{ - byte fixedOne : 1; - byte fineY : 3; - byte nameTableID : 2; - byte coarseY : 5; - byte coarseX : 5; - - }bits; - - word data; - }; - }tReg; //Search for: "IMPORTANT V SYNC" in ppu.c to see moments where the 2 sync + locationRegister tReg; //Search for: "IMPORTANT V SYNC" in ppu.c to see moments where the 2 sync byte xReg;