From 2d83300235e93320aa61c19e0a1657f6df43e8c5 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Tue, 29 Mar 2016 19:44:03 +1100 Subject: [PATCH] Update to v097r30 release. byuu says: Changelog: - fixed sprite window attribute bit (Final Fantasy, Tekken Card Challenge, etc) - rewrote renderer to support 2bpp color mode (Dark Eyes, Dokodemo Hamster, Flash Koibito-kun, etc) --- higan/emulator/emulator.hpp | 2 +- higan/ws/cpu/io.cpp | 8 +-- higan/ws/memory/memory.cpp | 4 +- higan/ws/ppu/io.cpp | 2 +- higan/ws/ppu/latch.cpp | 2 +- higan/ws/ppu/ppu.cpp | 21 ++---- higan/ws/ppu/ppu.hpp | 23 +++--- higan/ws/ppu/render-color.cpp | 93 ------------------------ higan/ws/ppu/render-mono.cpp | 93 ------------------------ higan/ws/ppu/render.cpp | 114 ++++++++++++++++++++++++++++++ higan/ws/system/io.cpp | 8 +-- higan/ws/system/serialization.cpp | 4 +- higan/ws/system/system.cpp | 6 +- higan/ws/system/system.hpp | 6 +- 14 files changed, 150 insertions(+), 236 deletions(-) delete mode 100644 higan/ws/ppu/render-color.cpp delete mode 100644 higan/ws/ppu/render-mono.cpp create mode 100644 higan/ws/ppu/render.cpp diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index b5886fb1..c143f4c1 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -6,7 +6,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "097.29"; + static const string Version = "097.30"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/ws/cpu/io.cpp b/higan/ws/cpu/io.cpp index 7ba8a580..d9500b98 100644 --- a/higan/ws/cpu/io.cpp +++ b/higan/ws/cpu/io.cpp @@ -39,12 +39,12 @@ auto CPU::portRead(uint16 addr) -> uint8 { if(addr == 0x0047) return r.dmaLength.byte(1); //DMA_CTRL - if(addr == 0x0048) return r.dmaEnable << 7 | r.dmaMode << 0; + if(addr == 0x0048) return r.dmaMode << 0 | r.dmaEnable << 7; //WSC_SYSTEM - if(addr == 0x0062) { - return (system.model() == Model::SwanCrystal) << 7; - } + if(addr == 0x0062) return ( + (system.model() == Model::SwanCrystal) << 7 + ); //HW_FLAGS if(addr == 0x00a0) { diff --git a/higan/ws/memory/memory.cpp b/higan/ws/memory/memory.cpp index c6379c2b..6e5f3604 100644 --- a/higan/ws/memory/memory.cpp +++ b/higan/ws/memory/memory.cpp @@ -17,12 +17,12 @@ auto InternalRAM::read(uint16 addr, uint size) -> uint32 { if(size == Long) return read(addr + 0, Word) << 0 | read(addr + 2, Word) << 16; if(size == Word) return read(addr + 0, Byte) << 0 | read(addr + 1, Byte) << 8; - if(addr >= 0x4000 && !system.r.depth) return 0x90; + if(addr >= 0x4000 && !system.color()) return 0x90; return memory[addr]; } auto InternalRAM::write(uint16 addr, uint8 data) -> void { - if(addr >= 0x4000 && !system.r.depth) return; + if(addr >= 0x4000 && !system.color()) return; memory[addr] = data; } diff --git a/higan/ws/ppu/io.cpp b/higan/ws/ppu/io.cpp index c4117710..f2a009d8 100644 --- a/higan/ws/ppu/io.cpp +++ b/higan/ws/ppu/io.cpp @@ -11,7 +11,7 @@ auto PPU::portRead(uint16 addr) -> uint8 { //BACK_COLOR if(addr == 0x0001) return ( - r.backColor.bits(0, !system.depth() ? 2 : 7) + r.backColor.bits(0, !system.color() ? 2 : 7) ); //LINE_CUR diff --git a/higan/ws/ppu/latch.cpp b/higan/ws/ppu/latch.cpp index 8e07e43d..f75ee7c0 100644 --- a/higan/ws/ppu/latch.cpp +++ b/higan/ws/ppu/latch.cpp @@ -43,7 +43,7 @@ auto PPU::latchSprites() -> void { sprite.hflip = attributes.bit(14); sprite.priority = attributes.bit(13); sprite.window = attributes.bit(12); - if(l.spriteWindowEnable && sprite.window == windowInside) continue; + if(l.spriteWindowEnable && !sprite.window && !windowInside) continue; sprite.palette = 8 + attributes.bits(9,11); sprite.tile = attributes.bits(0,8); diff --git a/higan/ws/ppu/ppu.cpp b/higan/ws/ppu/ppu.cpp index 336e7425..fe5ee14d 100644 --- a/higan/ws/ppu/ppu.cpp +++ b/higan/ws/ppu/ppu.cpp @@ -5,8 +5,7 @@ namespace WonderSwan { PPU ppu; #include "io.cpp" #include "latch.cpp" -#include "render-mono.cpp" -#include "render-color.cpp" +#include "render.cpp" #include "video.cpp" #include "serialization.cpp" @@ -23,18 +22,12 @@ auto PPU::main() -> void { latchRegisters(); latchSprites(); for(auto x : range(224)) { - if(!r.lcdEnable) { - s.pixel = {Pixel::Source::Back, 0x000}; - } else if(!system.color()) { - renderMonoBack(); - renderMonoScreenOne(); - renderMonoScreenTwo(); - renderMonoSprite(); - } else { - renderColorBack(); - renderColorScreenOne(); - renderColorScreenTwo(); - renderColorSprite(); + s.pixel = {Pixel::Source::Back, 0x000}; + if(r.lcdEnable) { + renderBack(); + if(l.screenOneEnable) renderScreenOne(); + if(l.screenTwoEnable) renderScreenTwo(); + if(l.spriteEnable) renderSprite(); } output[s.vclk * 224 + s.hclk] = s.pixel.color; step(1); diff --git a/higan/ws/ppu/ppu.hpp b/higan/ws/ppu/ppu.hpp index e6c33128..f8c2bd47 100644 --- a/higan/ws/ppu/ppu.hpp +++ b/higan/ws/ppu/ppu.hpp @@ -17,21 +17,14 @@ struct PPU : Thread, IO { auto latchSprites() -> void; auto latchOAM() -> void; - //render-mono.cpp - auto renderMonoFetch(uint14 offset, uint3 y, uint3 x) -> uint2; - auto renderMonoPalette(uint4 palette, uint2 index) -> uint12; - auto renderMonoBack() -> void; - auto renderMonoScreenOne() -> void; - auto renderMonoScreenTwo() -> void; - auto renderMonoSprite() -> void; - - //render-color.cpp - auto renderColorFetch(uint16 offset, uint3 y, uint3 x) -> uint4; - auto renderColorPalette(uint4 palette, uint4 index) -> uint12; - auto renderColorBack() -> void; - auto renderColorScreenOne() -> void; - auto renderColorScreenTwo() -> void; - auto renderColorSprite() -> void; + //render.cpp + auto renderFetch(uint10 tile, uint3 y, uint3 x) -> uint4; + auto renderTransparent(bool palette, uint4 color) -> bool; + auto renderPalette(uint4 palette, uint4 color) -> uint12; + auto renderBack() -> void; + auto renderScreenOne() -> void; + auto renderScreenTwo() -> void; + auto renderSprite() -> void; //serialization.cpp auto serialize(serializer&) -> void; diff --git a/higan/ws/ppu/render-color.cpp b/higan/ws/ppu/render-color.cpp deleted file mode 100644 index 38585117..00000000 --- a/higan/ws/ppu/render-color.cpp +++ /dev/null @@ -1,93 +0,0 @@ -auto PPU::renderColorFetch(uint16 offset, uint3 y, uint3 x) -> uint4 { - uint4 color; - - if(system.planar()) { - uint32 data = iram.read(offset + (y << 2), Long); - color |= data.bit( 7 - x) << 0; - color |= data.bit(15 - x) << 1; - color |= data.bit(23 - x) << 2; - color |= data.bit(31 - x) << 3; - } - - if(system.packed()) { - uint8 data = iram.read(offset + (y << 2) + (x >> 1)); - color = data >> (4 - (x.bit(0) << 2)); - } - - return color; -} - -auto PPU::renderColorPalette(uint4 palette, uint4 index) -> uint12 { - return iram.read(0xfe00 + (palette << 5) + (index << 1), Word); -} - -auto PPU::renderColorBack() -> void { - uint12 color = iram.read(0xfe00 + (l.backColor << 1), Word); - s.pixel = {Pixel::Source::Back, color}; -} - -auto PPU::renderColorScreenOne() -> void { - if(!l.screenOneEnable) return; - - uint8 scrollY = s.vclk + l.scrollOneY; - uint8 scrollX = s.hclk + l.scrollOneX; - - uint16 tilemapOffset = l.screenOneMapBase << 11; - tilemapOffset += (scrollY >> 3) << 6; - tilemapOffset += (scrollX >> 3) << 1; - - uint16 tile = iram.read(tilemapOffset, Word); - uint16 tileOffset = 0x4000 + (tile.bit(13) << 14) + (tile.bits(0,8) << 5); - uint3 tileY = (scrollY & 7) ^ (tile.bit(15) ? 7 : 0); - uint3 tileX = (scrollX & 7) ^ (tile.bit(14) ? 7 : 0); - uint4 tileColor = renderColorFetch(tileOffset, tileY, tileX); - if(tileColor == 0) return; - - s.pixel = {Pixel::Source::ScreenOne, renderColorPalette(tile.bits(9, 12), tileColor)}; -} - -auto PPU::renderColorScreenTwo() -> void { - if(!l.screenTwoEnable) return; - - bool windowInside = s.vclk >= l.screenTwoWindowY0 && s.vclk <= l.screenTwoWindowY1 - && s.hclk >= l.screenTwoWindowX0 && s.hclk <= l.screenTwoWindowX1; - windowInside ^= l.screenTwoWindowInvert; - if(l.screenTwoWindowEnable && !windowInside) return; - - uint8 scrollY = s.vclk + l.scrollTwoY; - uint8 scrollX = s.hclk + l.scrollTwoX; - - uint16 tilemapOffset = l.screenTwoMapBase << 11; - tilemapOffset += (scrollY >> 3) << 6; - tilemapOffset += (scrollX >> 3) << 1; - - uint16 tile = iram.read(tilemapOffset, Word); - uint16 tileOffset = 0x4000 + (tile.bit(13) << 14) + (tile.bits(0,8) << 5); - uint3 tileY = (scrollY & 7) ^ (tile.bit(15) ? 7 : 0); - uint3 tileX = (scrollX & 7) ^ (tile.bit(14) ? 7 : 0); - uint4 tileColor = renderColorFetch(tileOffset, tileY, tileX); - if(tileColor == 0) return; - - s.pixel = {Pixel::Source::ScreenTwo, renderColorPalette(tile.bits(9, 12), tileColor)}; -} - -auto PPU::renderColorSprite() -> void { - if(!l.spriteEnable) return; - - bool windowInside = s.hclk >= l.spriteWindowX0 && s.hclk <= l.spriteWindowX1; - for(auto index : range(l.spriteCount)) { - auto& sprite = l.sprite[index]; - if(l.spriteWindowEnable && sprite.window == windowInside) continue; - if((uint8)(s.hclk - sprite.x) > 7) continue; - - uint16 tileOffset = 0x4000 + (sprite.tile << 5); - uint3 tileY = (uint8)(s.vclk - sprite.y) ^ (sprite.vflip ? 7 : 0); - uint3 tileX = (uint8)(s.hclk - sprite.x) ^ (sprite.hflip ? 7 : 0); - uint4 tileColor = renderColorFetch(tileOffset, tileY, tileX); - if(tileColor == 0) continue; - if(!sprite.priority && s.pixel.source == Pixel::Source::ScreenTwo) continue; - - s.pixel = {Pixel::Source::Sprite, renderColorPalette(sprite.palette, tileColor)}; - break; - } -} diff --git a/higan/ws/ppu/render-mono.cpp b/higan/ws/ppu/render-mono.cpp deleted file mode 100644 index de63b0f6..00000000 --- a/higan/ws/ppu/render-mono.cpp +++ /dev/null @@ -1,93 +0,0 @@ -auto PPU::renderMonoFetch(uint14 offset, uint3 y, uint3 x) -> uint2 { - uint2 color; - - if(system.planar()) { - uint16 data = iram.read(offset + (y << 1), Word); - color |= data.bit( 7 - x) << 0; - color |= data.bit(15 - x) << 1; - } - - if(system.packed()) { - uint8 data = iram.read(offset + (y << 1) + (x >> 2)); - color = data >> (6 - (x.bits(0,1) << 1)); - } - - return color; -} - -auto PPU::renderMonoPalette(uint4 palette, uint2 index) -> uint12 { - uint3 paletteColor = r.palette[palette].color[index]; - uint4 poolColor = 15 - r.pool[paletteColor]; - return poolColor << 0 | poolColor << 4 | poolColor << 8; -} - -auto PPU::renderMonoBack() -> void { - uint4 poolColor = 15 - r.pool[l.backColor.bits(0,2)]; - s.pixel = {Pixel::Source::Back, poolColor << 0 | poolColor << 4 | poolColor << 8}; -} - -auto PPU::renderMonoScreenOne() -> void { - if(!l.screenOneEnable) return; - - uint8 scrollY = s.vclk + l.scrollOneY; - uint8 scrollX = s.hclk + l.scrollOneX; - - uint14 tilemapOffset = l.screenOneMapBase.bits(0,2) << 11; - tilemapOffset += (scrollY >> 3) << 6; - tilemapOffset += (scrollX >> 3) << 1; - - uint16 tile = iram.read(tilemapOffset, Word); - uint14 tileOffset = 0x2000 + (tile.bits(0,8) << 4); - uint3 tileY = (scrollY & 7) ^ (tile.bit(15) ? 7 : 0); - uint3 tileX = (scrollX & 7) ^ (tile.bit(14) ? 7 : 0); - uint2 tileColor = renderMonoFetch(tileOffset, tileY, tileX); - if(tile.bit(11) && tileColor == 0) return; - - s.pixel = {Pixel::Source::ScreenOne, renderMonoPalette(tile.bits(9,12), tileColor)}; -} - -auto PPU::renderMonoScreenTwo() -> void { - if(!l.screenTwoEnable) return; - - bool windowInside = s.vclk >= l.screenTwoWindowY0 && s.vclk <= l.screenTwoWindowY1 - && s.hclk >= l.screenTwoWindowX0 && s.hclk <= l.screenTwoWindowX1; - windowInside ^= l.screenTwoWindowInvert; - if(l.screenTwoWindowEnable && !windowInside) return; - - uint8 scrollY = s.vclk + l.scrollTwoY; - uint8 scrollX = s.hclk + l.scrollTwoX; - - uint14 tilemapOffset = l.screenTwoMapBase.bits(0,2) << 11; - tilemapOffset += (scrollY >> 3) << 6; - tilemapOffset += (scrollX >> 3) << 1; - - uint16 tile = iram.read(tilemapOffset, Word); - uint14 tileOffset = 0x2000 + (tile.bits(0,8) << 4); - uint3 tileY = (scrollY & 7) ^ (tile.bit(15) ? 7 : 0); - uint3 tileX = (scrollX & 7) ^ (tile.bit(14) ? 7 : 0); - uint2 tileColor = renderMonoFetch(tileOffset, tileY, tileX); - if(tile.bit(11) && tileColor == 0) return; - - s.pixel = {Pixel::Source::ScreenTwo, renderMonoPalette(tile.bits(9,12), tileColor)}; -} - -auto PPU::renderMonoSprite() -> void { - if(!l.spriteEnable) return; - - bool windowInside = s.hclk >= l.spriteWindowX0 && s.hclk <= l.spriteWindowX1; - for(auto index : range(l.spriteCount)) { - auto& sprite = l.sprite[index]; - if(l.spriteWindowEnable && sprite.window == windowInside) continue; - if((uint8)(s.hclk - sprite.x) > 7) continue; - - uint14 tileOffset = 0x2000 + (sprite.tile << 4); - uint3 tileY = (uint8)(s.vclk - sprite.y) ^ (sprite.vflip ? 7 : 0); - uint3 tileX = (uint8)(s.hclk - sprite.x) ^ (sprite.hflip ? 7 : 0); - uint2 tileColor = renderMonoFetch(tileOffset, tileY, tileX); - if(sprite.palette.bit(2) && tileColor == 0) continue; - if(!sprite.priority && s.pixel.source == Pixel::Source::ScreenTwo) continue; - - s.pixel = {Pixel::Source::Sprite, renderMonoPalette(sprite.palette, tileColor)}; - break; - } -} diff --git a/higan/ws/ppu/render.cpp b/higan/ws/ppu/render.cpp new file mode 100644 index 00000000..977ec3e9 --- /dev/null +++ b/higan/ws/ppu/render.cpp @@ -0,0 +1,114 @@ +auto PPU::renderFetch(uint10 tile, uint3 y, uint3 x) -> uint4 { + uint16 offset = 0x200 + tile << (4 + system.depth()); + uint4 color = 0; + + if(system.planar()) { + if(!system.depth()) { + uint16 data = iram.read(offset + (y << 1), Word); + color |= data.bit( 7 - x) << 0; + color |= data.bit(15 - x) << 1; + } else { + uint32 data = iram.read(offset + (y << 2), Long); + color |= data.bit( 7 - x) << 0; + color |= data.bit(15 - x) << 1; + color |= data.bit(23 - x) << 2; + color |= data.bit(31 - x) << 3; + } + } + + if(system.packed()) { + if(!system.depth()) { + uint8 data = iram.read(offset + (y << 1) + (x >> 2)); + color = data >> (6 - (x.bits(0,1) << 1)); + color = color.bits(0,1); + } else { + uint8 data = iram.read(offset + (y << 2) + (x >> 1)); + color = data >> (4 - (x.bit(0) << 2)); + } + } + + return color; +} + +auto PPU::renderTransparent(bool palette, uint4 color) -> bool { + if(color) return false; + if(!system.depth() && !palette) return false; + return true; +} + +auto PPU::renderPalette(uint4 palette, uint4 color) -> uint12 { + if(!system.color()) { + uint3 paletteColor = r.palette[palette].color[color.bits(0,1)]; + uint4 poolColor = 15 - r.pool[paletteColor]; + return poolColor << 0 | poolColor << 4 | poolColor << 8; + } else { + return iram.read(0xfe00 + (palette << 5) + (color << 1), Word); + } +} + +auto PPU::renderBack() -> void { + if(!system.color()) { + uint4 poolColor = 15 - r.pool[l.backColor.bits(0,2)]; + s.pixel = {Pixel::Source::Back, poolColor << 0 | poolColor << 4 | poolColor << 8}; + } else { + uint12 color = iram.read(0xfe00 + (l.backColor << 1), Word); + s.pixel = {Pixel::Source::Back, color}; + } +} + +auto PPU::renderScreenOne() -> void { + uint8 scrollY = s.vclk + l.scrollOneY; + uint8 scrollX = s.hclk + l.scrollOneX; + + uint16 tilemapOffset = l.screenOneMapBase.bits(0, 2 + system.depth()) << 11; + tilemapOffset += (scrollY >> 3) << 6; + tilemapOffset += (scrollX >> 3) << 1; + + uint16 tile = iram.read(tilemapOffset, Word); + uint3 tileY = scrollY ^ tile.bit(15) * 7; + uint3 tileX = scrollX ^ tile.bit(14) * 7; + uint4 tileColor = renderFetch(tile.bit(13) << 9 | tile.bits(0,8), tileY, tileX); + if(renderTransparent(tile.bit(11), tileColor)) return; + + s.pixel = {Pixel::Source::ScreenOne, renderPalette(tile.bits(9,12), tileColor)}; +} + +auto PPU::renderScreenTwo() -> void { + bool windowInside = s.vclk >= l.screenTwoWindowY0 && s.vclk <= l.screenTwoWindowY1 + && s.hclk >= l.screenTwoWindowX0 && s.hclk <= l.screenTwoWindowX1; + windowInside ^= l.screenTwoWindowInvert; + if(l.screenTwoWindowEnable && !windowInside) return; + + uint8 scrollY = s.vclk + l.scrollTwoY; + uint8 scrollX = s.hclk + l.scrollTwoX; + + uint16 tilemapOffset = l.screenTwoMapBase.bits(0, 2 + system.depth()) << 11; + tilemapOffset += (scrollY >> 3) << 6; + tilemapOffset += (scrollX >> 3) << 1; + + uint16 tile = iram.read(tilemapOffset, Word); + uint3 tileY = scrollY ^ tile.bit(15) * 7; + uint3 tileX = scrollX ^ tile.bit(14) * 7; + uint4 tileColor = renderFetch(tile.bit(13) << 9 | tile.bits(0,8), tileY, tileX); + if(renderTransparent(tile.bit(11), tileColor)) return; + + s.pixel = {Pixel::Source::ScreenTwo, renderPalette(tile.bits(9,12), tileColor)}; +} + +auto PPU::renderSprite() -> void { + bool windowInside = s.hclk >= l.spriteWindowX0 && s.hclk <= l.spriteWindowY0; + for(auto index : range(l.spriteCount)) { + auto& sprite = l.sprite[index]; + if(l.spriteWindowEnable && !sprite.window && !windowInside) continue; + if((uint8)(s.hclk - sprite.x) > 7) continue; + + uint3 tileY = (s.vclk - sprite.y) ^ sprite.vflip * 7; + uint3 tileX = (s.hclk - sprite.x) ^ sprite.hflip * 7; + uint4 tileColor = renderFetch(sprite.tile, tileY, tileX); + if(renderTransparent(sprite.palette.bit(2), tileColor)) continue; + if(!sprite.priority && s.pixel.source == Pixel::Source::ScreenTwo) continue; + + s.pixel = {Pixel::Source::Sprite, renderPalette(sprite.palette, tileColor)}; + break; + } +} diff --git a/higan/ws/system/io.cpp b/higan/ws/system/io.cpp index d1aaadd2..af4c2680 100644 --- a/higan/ws/system/io.cpp +++ b/higan/ws/system/io.cpp @@ -3,8 +3,8 @@ auto System::portRead(uint16 addr) -> uint8 { if(addr == 0x0060) return ( r.unknown << 0 | r.format << 5 - | r.color << 6 - | r.depth << 7 + | r.depth << 6 + | r.color << 7 ); //IEEP_DATA @@ -24,8 +24,8 @@ auto System::portWrite(uint16 addr, uint8 data) -> void { if(addr == 0x0060) { r.unknown = data.bits(0,4) & 0b01011; r.format = data.bit (5); - r.color = data.bit (6); - r.depth = data.bit (7); + r.depth = data.bit (6); + r.color = data.bit (7); return; } diff --git a/higan/ws/system/serialization.cpp b/higan/ws/system/serialization.cpp index 16809479..8259c05a 100644 --- a/higan/ws/system/serialization.cpp +++ b/higan/ws/system/serialization.cpp @@ -59,8 +59,8 @@ auto System::serializeAll(serializer& s) -> void { auto System::serialize(serializer& s) -> void { eeprom.serialize(s); + s.integer(r.unknown); + s.integer(r.format); s.integer(r.depth); s.integer(r.color); - s.integer(r.format); - s.integer(r.unknown); } diff --git a/higan/ws/system/system.cpp b/higan/ws/system/system.cpp index 77efad86..30754614 100644 --- a/higan/ws/system/system.cpp +++ b/higan/ws/system/system.cpp @@ -12,7 +12,7 @@ auto System::orientation() const -> bool { return _orientation; } auto System::color() const -> bool { return r.color; } auto System::planar() const -> bool { return r.format == 0; } auto System::packed() const -> bool { return r.format == 1; } -auto System::depth() const -> bool { return r.depth == 1; } +auto System::depth() const -> bool { return r.color && r.depth == 1; } auto System::init() -> void { assert(interface != nullptr); @@ -67,10 +67,10 @@ auto System::power() -> void { bus.map(this, 0x0060); bus.map(this, 0x00ba, 0x00be); + r.unknown = 0; + r.format = 0; r.depth = 0; r.color = 0; - r.format = 0; - r.unknown = 0; } auto System::run() -> void { diff --git a/higan/ws/system/system.hpp b/higan/ws/system/system.hpp index cf130ee2..9edc1e9d 100644 --- a/higan/ws/system/system.hpp +++ b/higan/ws/system/system.hpp @@ -40,15 +40,15 @@ struct System : IO { bool rotate; } keypad; +privileged: struct Registers { //$0060 DISP_MODE + uint5 unknown; + uint1 format; uint1 depth; uint1 color; - uint1 format; - uint5 unknown; } r; -privileged: bool _loaded = false; Model _model = Model::WonderSwan; bool _orientation = 0; //0 = horizontal, 1 = vertical