refactoring PPU's unions to be used as intended

This commit is contained in:
Clément Le Bihan
2020-10-11 00:00:18 +02:00
parent 004cdae186
commit 10cead862f
3 changed files with 137 additions and 150 deletions
-2
View File
@@ -159,7 +159,6 @@ namespace ComSquare::PPU
uint8_t PPU::read(uint24_t addr)
{
return 0;
switch (addr) {
case ppuRegisters::mpyl:
return this->_registers._mpy.mpyl;
@@ -188,7 +187,6 @@ namespace ComSquare::PPU
void PPU::write(uint24_t addr, uint8_t data)
{
return;
switch (addr) {
case ppuRegisters::inidisp:
this->_registers._inidisp.raw = data;
+130 -141
View File
@@ -177,9 +177,9 @@ namespace ComSquare::PPU
struct {
//! @brief Store the brightness value (F = max, 0 = off)
uint8_t brightness: 4;
bool _: 3;
uint8_t _: 3;
//! @brief Store the FBlank status
bool fblank: 1;
uint8_t fblank: 1;
};
uint8_t raw = 0;
} _inidisp;
@@ -199,36 +199,36 @@ namespace ComSquare::PPU
union {
struct {
//! @brief Stores the address to write with OAMDATA register
uint32_t oamAddress: 9;
uint8_t _: 6;
uint16_t oamAddress: 9;
uint16_t _: 6;
//! @brief When Obj Priority activation bit is set, an Obj other than Sprite 0 may be given priority
bool objPriorityActivationBit: 1;
uint16_t objPriorityActivationBit: 1;
};
struct {
//! @brief Stores the data written on the OAMADDL register
uint8_t oamaddl;
uint16_t oamaddl: 8;
//! @brief Stores the data written on the OAMADDH register
uint8_t oamaddh;
uint16_t oamaddh: 8;
};
uint32_t raw = 0;
uint16_t raw = 0;
} _oamadd;
//! @brief OAMDATA Register (Data for OAM write)
uint8_t _oamdata;
uint8_t _oamdata = 0;
//! @brief BGMODE Register (OAM Address and Obj Priority)
union {
struct {
//! @brief Stores the current BG Mode (0 - 7)
uint8_t bgMode: 3;
//! @brief When Mode 1 BG3 priority bit is set the BG3 is draw
bool mode1Bg3PriorityBit: 1;
uint8_t mode1Bg3PriorityBit: 1;
//! @brief When The bit is set character size will 16x16 otherwise it is 8x8
bool characterSizeBg1: 1;
uint8_t characterSizeBg1: 1;
//! @brief When The bit is set character size will 16x16 otherwise it is 8x8
bool characterSizeBg2: 1;
uint8_t characterSizeBg2: 1;
//! @brief When The bit is set character size will 16x16 otherwise it is 8x8
bool characterSizeBg3: 1;
uint8_t characterSizeBg3: 1;
//! @brief When The bit is set character size will 16x16 otherwise it is 8x8
bool characterSizeBg4: 1;
uint8_t characterSizeBg4: 1;
};
uint8_t raw = 0;
} _bgmode;
@@ -236,13 +236,13 @@ namespace ComSquare::PPU
union {
struct {
//! @brief Apply mosaic to the BG1
bool affectBg1: 1;
uint8_t affectBg1: 1;
//! @brief Apply mosaic to the BG2
bool affectBg2: 1;
uint8_t affectBg2: 1;
//! @brief Apply mosaic to the BG3
bool affectBg3: 1;
uint8_t affectBg3: 1;
//! @brief Apply mosaic to the BG4
bool affectBg4: 1;
uint8_t affectBg4: 1;
//! @brief Stores the pixel size (0 = 1x1, F = 16x16)
uint8_t pixelSize: 4;
};
@@ -252,9 +252,9 @@ namespace ComSquare::PPU
union {
struct {
//! @brief When tilemap horizontal mirroring bit is set the tilemap is mirrored horizontally
bool tilemapHorizontalMirroring: 1;
uint8_t tilemapHorizontalMirroring: 1;
//! @brief When tilemap vertically mirroring bit is set the tilemap is mirrored vertically
bool tilemapVerticalMirroring: 1;
uint8_t tilemapVerticalMirroring: 1;
//! @brief Address of the tilemap Address (0, 0)
uint8_t tilemapAddress: 6;
};
@@ -274,18 +274,18 @@ namespace ComSquare::PPU
union {
struct {
uint16_t offsetBg: 10;
uint8_t _ : 6;
uint16_t _ : 6;
};
uint16_t raw;
uint16_t raw = 0;
} _bgofs[8];
//! @brief M7HOFS Register (Mode 7 BG Horizontal Scroll)
//! @brief M7VOFS Register (Mode 7 BG Vertical Scroll)
union {
struct {
uint16_t offsetBg : 13;
uint8_t _ : 3;
uint16_t _ : 3;
};
uint8_t raw;
uint16_t raw = 0;
} _m7ofs[2];
//! @brief VMAIN Register (Video Port Control)
union {
@@ -293,106 +293,106 @@ namespace ComSquare::PPU
uint8_t incrementAmount: 2;
uint8_t addressRemapping: 2;
uint8_t _ : 3;
bool incrementMode: 1;
uint8_t incrementMode: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _vmain;
//! @brief Store the real value of the increment Amount (1, 32, 128) instead of 0,1 or 2
uint8_t _incrementAmount = 1;
//! @brief VMADD Register (VRAM Address)
union {
struct {
uint8_t vmaddl;
uint8_t vmaddh;
uint16_t vmaddl: 8;
uint16_t vmaddh: 8;
};
uint16_t vmadd;
uint16_t vmadd = 0;
} _vmadd;
//! @brief VMDATA Register (VRAM Data Write)
union {
struct {
uint8_t vmdatal;
uint8_t vmdatah;
uint16_t vmdatal: 8;
uint16_t vmdatah: 8;
};
uint16_t vmdata;
uint16_t vmdata = 0;
} _vmdata;
//! @brief TODO M7SEL Register (Mode 7 Settings)
union {
struct {
bool horizontalMirroring: 1;
bool verticalMirroring: 1;
uint8_t horizontalMirroring: 1;
uint8_t verticalMirroring: 1;
uint8_t _: 4;
bool emptySpaceFill: 1;
bool playingFieldSize: 1;
uint8_t emptySpaceFill: 1;
uint8_t playingFieldSize: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _m7sel;
//! @brief M7A M7B M7C M7C registers, M7A and M7B are also used with ($2134/6) (multiplactions registers)
union {
struct {
uint8_t m7l;
uint8_t m7h;
uint16_t m7l: 8;
uint16_t m7h: 8;
};
uint16_t m7;
uint16_t m7 = 0;
} _m7[4];
// <to work>
//! @brief M7X Register (Mode 7 Center X)
union { // Not sure if it is done correctly
struct {
uint8_t _: 3;
uint8_t value;
uint16_t _: 3;
uint16_t value: 13;
};
uint32_t center;
uint16_t center = 0;
} _m7x;
//! @brief M7Y Register (Mode 7 Center Y)
union { // Not sure if it is done correctly
struct {
uint8_t _: 3;
uint8_t value;
uint16_t _: 3;
uint16_t value: 13;
};
uint32_t center;
uint16_t center = 0;
} _m7y;
//! @brief CGADD Register (CGRAM Address)
uint8_t _cgadd;
uint8_t _cgadd = 0;
//! @brief CGDATA Register (CGRAM Data write)
union {
struct {
uint8_t red: 5;
uint8_t green: 5;
uint8_t blue: 5;
bool _: 1;
uint16_t red: 5;
uint16_t green: 5;
uint16_t blue: 5;
uint16_t _: 1;
};
struct {
uint8_t cgdatal;
uint8_t cgdatah;
uint16_t cgdatal: 8;
uint16_t cgdatah: 8;
};
uint16_t raw;
uint16_t raw = 0;
} _cgdata;
//! @brief This bool is used for writing either the low byte of the data (first call) or the high byte of the data (second call)
//! @info This bool is set to True when writing to $2121 (CGADD)
bool _isLowByte;
bool _isLowByte = false;
//! @brief W12SEL - W34SEL Registers (Window Mask Settings for BGs) and WOBJSEL Register (Window Mask Settings for OBJ and Color Window)
union {
struct {
bool enableWindow2ForBg2Bg4Color: 1;
bool window2InversionForBg2Bg4Color: 1;
bool enableWindow1ForBg2Bg4Color: 1;
bool window1InversionForBg2Bg4Color: 1;
bool enableWindow2ForBg1Bg3Obj: 1;
bool window2InversionForBg1Bg3Obj: 1;
bool enableWindow1ForBg1Bg2Obj: 1;
bool window1InversionForBg1Bg2Obj: 1;
uint8_t enableWindow2ForBg2Bg4Color: 1;
uint8_t window2InversionForBg2Bg4Color: 1;
uint8_t enableWindow1ForBg2Bg4Color: 1;
uint8_t window1InversionForBg2Bg4Color: 1;
uint8_t enableWindow2ForBg1Bg3Obj: 1;
uint8_t window2InversionForBg1Bg3Obj: 1;
uint8_t enableWindow1ForBg1Bg2Obj: 1;
uint8_t window1InversionForBg1Bg2Obj: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _wsel[3];
//! @brief WH0 Register (Window 1 Left Position)
uint8_t _wh0;
uint8_t _wh0 = 0;
//! @brief WH1 Register (Window 1 Right Position)
uint8_t _wh1;
uint8_t _wh1 = 0;
//! @brief WH2 Register (Window 2 Left Position)
uint8_t _wh2;
uint8_t _wh2 = 0;
//! @brief WH3 Register (Window 2 Right Position)
uint8_t _wh3;
uint8_t _wh3 = 0;
//! @brief WBGLOG Register (Window mask logic for BGs)
union {
struct {
@@ -401,7 +401,7 @@ namespace ComSquare::PPU
uint8_t maskLogicBg2: 2;
uint8_t maskLogicBg1: 2;
};
uint8_t raw;
uint8_t raw = 0;
} _wbglog;
//! @brief WOBJLOG Register (Window mask logic for OBJs and Color Window)
union {
@@ -410,91 +410,79 @@ namespace ComSquare::PPU
uint8_t maskLogicColor: 2;
uint8_t _: 4;
};
uint8_t raw;
uint8_t raw = 0;
} _wobjlog;
//! @brief TM - TS Registers (Main & Sub Screen Designation)
union {
struct {
bool enableWindowDisplayBg1: 1;
bool enableWindowDisplayBg2: 1;
bool enableWindowDisplayBg3: 1;
bool enableWindowDisplayBg4: 1;
bool enableWindowDisplayObj: 1;
uint8_t enableWindowDisplayBg1: 1;
uint8_t enableWindowDisplayBg2: 1;
uint8_t enableWindowDisplayBg3: 1;
uint8_t enableWindowDisplayBg4: 1;
uint8_t enableWindowDisplayObj: 1;
uint8_t _: 3;
};
uint8_t raw;
uint8_t raw = 0;
} _t[2];
//! @brief TMW - TSW Registers (Window Mask Designation for the Main/Sub Screen)
union {
struct {
bool enableWindowMaskingBg1: 1;
bool enableWindowMaskingBg2: 1;
bool enableWindowMaskingBg3: 1;
bool enableWindowMaskingBg4: 1;
bool enableWindowMaskingObj: 1;
uint8_t enableWindowMaskingBg1: 1;
uint8_t enableWindowMaskingBg2: 1;
uint8_t enableWindowMaskingBg3: 1;
uint8_t enableWindowMaskingBg4: 1;
uint8_t enableWindowMaskingObj: 1;
uint8_t _: 3;
};
uint8_t raw;
uint8_t raw = 0;
} _tw[2];
//! @brief TSW Register (Window Mask Designation for the Sub Screen)
union {
struct {
uint8_t _: 3;
bool enableWindowMaskingObj: 1;
bool enableWindowMaskingBg4: 1;
bool enableWindowMaskingBg3: 1;
bool enableWindowMaskingBg2: 1;
bool enableWindowMaskingBg1: 1;
};
uint8_t raw;
} _tsw;
//! @brief CGWSEL Register (Color Addition Select)
union {
struct {
bool directColorMode: 1;
bool addSubscreen: 1;
uint8_t directColorMode: 1;
uint8_t addSubscreen: 1;
uint8_t _: 2;
uint8_t preventColorMath: 2;
uint8_t clipColorToBlackBeforeMath: 2;
};
uint8_t raw;
uint8_t raw = 0;
} _cgwsel;
//! @brief CGADSUB Register (Color Math designation)
union {
struct {
bool enableColorMathBg1: 1;
bool enableColorMathBg2: 1;
bool enableColorMathBg3: 1;
bool enableColorMathBg4: 1;
bool enableColorMathObj: 1;
bool enableColorMathBackdrop: 1;
bool halfColorMath: 1;
bool addSubtractSelect: 1;
uint8_t enableColorMathBg1: 1;
uint8_t enableColorMathBg2: 1;
uint8_t enableColorMathBg3: 1;
uint8_t enableColorMathBg4: 1;
uint8_t enableColorMathObj: 1;
uint8_t enableColorMathBackdrop: 1;
uint8_t halfColorMath: 1;
uint8_t addSubtractSelect: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _cgadsub;
//! @brief COLDATA Register (Fixed Color Data)
union {
struct {
uint8_t colorIntensity: 5;
bool red: 1;
bool green: 1;
bool blue: 1;
uint8_t red: 1;
uint8_t green: 1;
uint8_t blue: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _coldata;
//! @brief SETINI Register (Screen Mode/Video Select)
union {
struct {
bool screenInterlace: 1;
bool objInterlace: 1;
bool overscanMode: 1;
bool enablePseudoHiresMode: 1;
uint8_t screenInterlace: 1;
uint8_t objInterlace: 1;
uint8_t overscanMode: 1;
uint8_t enablePseudoHiresMode: 1;
uint8_t _: 2;
bool mode7ExtBg: 1;
bool externalSync: 1;
uint8_t mode7ExtBg: 1;
uint8_t externalSync: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _setini;
// <READ registers>
@@ -502,61 +490,62 @@ namespace ComSquare::PPU
//! @brief MPYL - MPYM - MPYH Registers (Multiplication Result)
union {
struct {
uint8_t mpyl;
uint8_t mpym;
uint8_t mpyh;
uint32_t mpyl: 8;
uint32_t mpym: 8;
uint32_t mpyh: 8;
uint32_t _: 8;
};
uint32_t mpy;
uint32_t mpy = 0;
} _mpy;
//! @brief SLHV - Software Latch for H/V Counter
uint8_t _slhv;
uint8_t _slhv = 0;
//! @brief OAMDATAREAD - Data for OAM read
uint8_t _oamdataread;
uint8_t _oamdataread = 0;
//! @brief VMDATALREAD/VMDATAHREAD - VRAM Data Read low/high byte
union {
struct {
uint8_t vmDataLRead;
uint8_t vmDataHRead;
uint16_t vmDataLRead: 8;
uint16_t vmDataHRead: 8;
};
uint16_t raw;
uint16_t raw = 0;
} _vmdataread;
//! @brief CGRAM Data read
union {
struct {
uint8_t cgDataLRead;
uint8_t cgDataHRead;
uint16_t cgDataLRead: 8;
uint16_t cgDataHRead: 8;
};
uint16_t raw;
uint16_t raw = 0;
} _cgdataread;
//! @brief OPHCT/OPVCT - Horizontal/Vertical Scanline Location
union {
struct {
uint16_t opct: 9;
uint8_t _: 7;
uint16_t _: 7;
};
uint16_t raw;
uint16_t raw = 0;
} _opct;
//! @brief STAT77 - PPU Status Flag and Version
union {
struct {
uint8_t chipVersionNumber: 4;
bool _: 1;
bool modeSelect: 1;
bool rangeOverFlag: 1;
bool timeOverFlag: 1;
uint8_t _: 1;
uint8_t modeSelect: 1;
uint8_t rangeOverFlag: 1;
uint8_t timeOverFlag: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _stat77;
//! @brief STAT78 - PPU Status Flag and Version
union {
struct {
uint8_t chipVersionNumber: 4;
bool mode: 1;
bool _: 1;
bool externalLatchFlag: 1;
bool interlaceField: 1;
uint8_t mode: 1;
uint8_t _: 1;
uint8_t externalLatchFlag: 1;
uint8_t interlaceField: 1;
};
uint8_t raw;
uint8_t raw = 0;
} _stat78;
};
+7 -7
View File
@@ -11,14 +11,14 @@ namespace ComSquare::PPU
{
union TileMapData {
struct {
uint8_t posX: 4;
uint8_t posY: 6;
uint8_t palette: 3;
bool tilePriority: 1;
bool horizontalFlip: 1;
bool verticalFlip: 1;
uint16_t posX: 4;
uint16_t posY: 6;
uint16_t palette: 3;
uint16_t tilePriority: 1;
uint16_t horizontalFlip: 1;
uint16_t verticalFlip: 1;
};
uint16_t raw;
uint16_t raw = 0;
};
}