diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index a8f48df5..be833751 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -11,7 +11,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "099.11"; + static const string Version = "099.12"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/fc/cartridge/board/konami-vrc7.cpp b/higan/fc/cartridge/board/konami-vrc7.cpp index 44ced034..1f706c00 100644 --- a/higan/fc/cartridge/board/konami-vrc7.cpp +++ b/higan/fc/cartridge/board/konami-vrc7.cpp @@ -23,7 +23,7 @@ struct KonamiVRC7 : Board { return chrram.read(vrc7.addrCHR(addr)); } - auto chr_write(uint addr, uint8 data) -> void { + auto writeCHR(uint addr, uint8 data) -> void { if(addr & 0x2000) return ppu.writeCIRAM(vrc7.addrCIRAM(addr), data); return chrram.write(vrc7.addrCHR(addr), data); } diff --git a/higan/fc/cartridge/board/nes-axrom.cpp b/higan/fc/cartridge/board/nes-axrom.cpp index 1f3cbfbe..b773a0c1 100644 --- a/higan/fc/cartridge/board/nes-axrom.cpp +++ b/higan/fc/cartridge/board/nes-axrom.cpp @@ -24,7 +24,7 @@ struct NES_AxROM : Board { return Board::readCHR(addr); } - auto chr_write(uint addr, uint8 data) -> void { + auto writeCHR(uint addr, uint8 data) -> void { if(addr & 0x2000) return ppu.writeCIRAM((mirrorSelect << 10) | (addr & 0x03ff), data); return Board::writeCHR(addr, data); } diff --git a/higan/fc/ppu/memory.cpp b/higan/fc/ppu/memory.cpp index 68cc3755..b6441f35 100644 --- a/higan/fc/ppu/memory.cpp +++ b/higan/fc/ppu/memory.cpp @@ -106,25 +106,23 @@ auto PPU::writeIO(uint16 addr, uint8 data) -> void { //PPUSCROLL case 5: - if(!r.v.latch) { + if(r.v.latch++ == 0) { r.v.fineX = data.bits(0,2); r.t.tileX = data.bits(3,7); } else { r.t.fineY = data.bits(0,2); r.t.tileY = data.bits(3,7); } - r.v.latch ^= 1; break; //PPUADDR case 6: - if(!r.v.latch) { + if(r.v.latch++ == 0) { r.t.addressHi = data.bits(0,5); } else { r.t.addressLo = data.bits(0,7); r.v.address = r.t.address; } - r.v.latch ^= 1; break; //PPUDATA diff --git a/higan/fc/ppu/ppu.cpp b/higan/fc/ppu/ppu.cpp index 0a1df587..c0ed0d72 100644 --- a/higan/fc/ppu/ppu.cpp +++ b/higan/fc/ppu/ppu.cpp @@ -44,7 +44,7 @@ auto PPU::scanline() -> void { } auto PPU::frame() -> void { - r.field ^= 1; + r.field++; scheduler.exit(Scheduler::Event::Frame); } diff --git a/higan/fc/ppu/ppu.hpp b/higan/fc/ppu/ppu.hpp index 164fcdab..2b84e1f4 100644 --- a/higan/fc/ppu/ppu.hpp +++ b/higan/fc/ppu/ppu.hpp @@ -35,7 +35,7 @@ struct PPU : Thread { //internal uint8 mdr; - bool field; + uint1 field; uint lx; uint ly; @@ -43,17 +43,17 @@ struct PPU : Thread { union { uint value; - BitField tileX; - BitField tileY; - BitField nametable; - BitField nametableX; - BitField nametableY; - BitField fineY; - BitField address; - BitField addressLo; - BitField addressHi; - BitField latch; - BitField fineX; + NaturalBitField tileX; + NaturalBitField tileY; + NaturalBitField nametable; + NaturalBitField nametableX; + NaturalBitField nametableY; + NaturalBitField fineY; + NaturalBitField address; + NaturalBitField addressLo; + NaturalBitField addressHi; + NaturalBitField latch; + NaturalBitField fineX; } v, t; bool nmiHold; diff --git a/higan/fc/ppu/render.cpp b/higan/fc/ppu/render.cpp index 240b71f4..c5fc26d2 100644 --- a/higan/fc/ppu/render.cpp +++ b/higan/fc/ppu/render.cpp @@ -105,8 +105,8 @@ auto PPU::renderScanline() -> void { renderPixel(); step(1); - if(enable() && ++r.v.tileX == 0) r.v.nametableX ^= 1; - if(enable() && tile == 31 && ++r.v.fineY == 0 && ++r.v.tileY == 30) r.v.nametableY ^= 1, r.v.tileY = 0; + if(enable() && ++r.v.tileX == 0) r.v.nametableX++; + if(enable() && tile == 31 && ++r.v.fineY == 0 && ++r.v.tileY == 30) r.v.nametableY++, r.v.tileY = 0; renderPixel(); renderSprite(); step(1); @@ -179,7 +179,7 @@ auto PPU::renderScanline() -> void { if(r.v.tileX & 2) attribute >>= 2; step(1); - if(enable() && ++r.v.tileX == 0) r.v.nametableX ^= 1; + if(enable() && ++r.v.tileX == 0) r.v.nametableX++; step(1); uint tiledataLo = loadCHR(tileaddr + 0); diff --git a/higan/gb/apu/apu.cpp b/higan/gb/apu/apu.cpp index f7491ecc..ef5182e9 100644 --- a/higan/gb/apu/apu.cpp +++ b/higan/gb/apu/apu.cpp @@ -78,7 +78,7 @@ auto APU::power() -> void { for(auto& n : wave.pattern) n = r(); } -auto APU::mmio_read(uint16 addr) -> uint8 { +auto APU::readIO(uint16 addr) -> uint8 { if(addr >= 0xff10 && addr <= 0xff14) return square1.read(addr); if(addr >= 0xff15 && addr <= 0xff19) return square2.read(addr); if(addr >= 0xff1a && addr <= 0xff1e) return wave.read(addr); @@ -88,7 +88,7 @@ auto APU::mmio_read(uint16 addr) -> uint8 { return 0xff; } -auto APU::mmio_write(uint16 addr, uint8 data) -> void { +auto APU::writeIO(uint16 addr, uint8 data) -> void { if(!sequencer.enable) { bool valid = addr == 0xff26; //NR52 if(!system.cgb()) { diff --git a/higan/gb/apu/apu.hpp b/higan/gb/apu/apu.hpp index a198e3d7..f46dfbce 100644 --- a/higan/gb/apu/apu.hpp +++ b/higan/gb/apu/apu.hpp @@ -6,8 +6,8 @@ struct APU : Thread, MMIO { auto hipass(int16& sample, int64& bias) -> void; auto power() -> void; - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto serialize(serializer&) -> void; diff --git a/higan/gb/cartridge/cartridge.cpp b/higan/gb/cartridge/cartridge.cpp index 38915435..774e6322 100644 --- a/higan/gb/cartridge/cartridge.cpp +++ b/higan/gb/cartridge/cartridge.cpp @@ -40,6 +40,7 @@ auto Cartridge::load(System::Revision revision) -> bool { } else return false; auto document = BML::unserialize(information.manifest); + auto board = document["board"]; information.title = document["information/title"].text(); auto mapperid = document["board/mapper"].text(); @@ -56,29 +57,24 @@ auto Cartridge::load(System::Revision revision) -> bool { information.rtc = false; information.rumble = false; - auto rom = document["board/rom"]; - auto ram = document["board/ram"]; + rom.size = max(32768u, board["rom/size"].natural()); + rom.data = (uint8*)memory::allocate(rom.size, 0xff); - romsize = max(32768u, rom["size"].natural()); - romdata = allocate(romsize, 0xff); + ram.size = board["ram/size"].natural(); + ram.data = (uint8*)memory::allocate(ram.size, 0xff); - ramsize = ram["size"].natural(); - ramdata = allocate(ramsize, 0xff); - - if(auto name = rom["name"].text()) { + if(auto name = board["rom/name"].text()) { if(auto fp = interface->open(pathID(), name, File::Read, File::Required)) { - fp->read(romdata, min(romsize, fp->size())); + fp->read(rom.data, min(rom.size, fp->size())); } } - if(auto name = ram["name"].text()) { + if(auto name = board["ram/name"].text()) { if(auto fp = interface->open(pathID(), name, File::Read, File::Optional)) { - fp->read(ramdata, min(ramsize, fp->size())); + fp->read(ram.data, min(ram.size, fp->size())); } } - information.romsize = romsize; - information.ramsize = ramsize; - information.battery = (bool)ram["name"]; + information.battery = (bool)board["ram/name"]; switch(information.mapper) { default: case Mapper::MBC0: mapper = &mbc0; break; @@ -92,7 +88,7 @@ auto Cartridge::load(System::Revision revision) -> bool { case Mapper::HuC3: mapper = &huc3; break; } - information.sha256 = Hash::SHA256(romdata, romsize).digest(); + information.sha256 = Hash::SHA256(rom.data, rom.size).digest(); return true; } @@ -101,42 +97,44 @@ auto Cartridge::save() -> void { if(auto name = document["board/ram/name"].text()) { if(auto fp = interface->open(pathID(), name, File::Write)) { - fp->write(ramdata, ramsize); + fp->write(ram.data, ram.size); } } } auto Cartridge::unload() -> void { - if(romdata) { delete[] romdata; romdata = nullptr; romsize = 0; } - if(ramdata) { delete[] ramdata; ramdata = nullptr; ramsize = 0; } + delete[] rom.data; + delete[] ram.data; + rom = {}; + ram = {}; } -auto Cartridge::rom_read(uint addr) -> uint8 { - if(addr >= romsize) addr %= romsize; - return romdata[addr]; +auto Cartridge::readROM(uint addr) -> uint8 { + if(addr >= rom.size) addr %= rom.size; + return rom.data[addr]; } -auto Cartridge::rom_write(uint addr, uint8 data) -> void { - if(addr >= romsize) addr %= romsize; - romdata[addr] = data; +auto Cartridge::writeROM(uint addr, uint8 data) -> void { + if(addr >= rom.size) addr %= rom.size; + rom.data[addr] = data; } -auto Cartridge::ram_read(uint addr) -> uint8 { - if(ramsize == 0) return 0xff; - if(addr >= ramsize) addr %= ramsize; - return ramdata[addr]; +auto Cartridge::readRAM(uint addr) -> uint8 { + if(ram.size == 0) return 0xff; + if(addr >= ram.size) addr %= ram.size; + return ram.data[addr]; } -auto Cartridge::ram_write(uint addr, uint8 data) -> void { - if(ramsize == 0) return; - if(addr >= ramsize) addr %= ramsize; - ramdata[addr] = data; +auto Cartridge::writeRAM(uint addr, uint8 data) -> void { + if(ram.size == 0) return; + if(addr >= ram.size) addr %= ram.size; + ram.data[addr] = data; } -auto Cartridge::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::readIO(uint16 addr) -> uint8 { if(addr == 0xff50) return 0xff; - if(bootrom_enable) { + if(bootromEnable) { const uint8* data = nullptr; switch(system.revision()) { default: case System::Revision::GameBoy: data = system.bootROM.dmg; break; @@ -147,20 +145,20 @@ auto Cartridge::mmio_read(uint16 addr) -> uint8 { if(addr >= 0x0200 && addr <= 0x08ff && system.cgb()) return data[addr - 256]; } - return mapper->mmio_read(addr); + return mapper->readIO(addr); } -auto Cartridge::mmio_write(uint16 addr, uint8 data) -> void { - if(bootrom_enable && addr == 0xff50) { - bootrom_enable = false; +auto Cartridge::writeIO(uint16 addr, uint8 data) -> void { + if(bootromEnable && addr == 0xff50) { + bootromEnable = false; return; } - mapper->mmio_write(addr, data); + mapper->writeIO(addr, data); } auto Cartridge::power() -> void { - bootrom_enable = true; + bootromEnable = true; mbc0.power(); mbc1.power(); diff --git a/higan/gb/cartridge/cartridge.hpp b/higan/gb/cartridge/cartridge.hpp index eb35470d..befcf9be 100644 --- a/higan/gb/cartridge/cartridge.hpp +++ b/higan/gb/cartridge/cartridge.hpp @@ -8,13 +8,14 @@ struct Cartridge : MMIO { auto save() -> void; auto unload() -> void; - auto rom_read(uint addr) -> uint8; - auto rom_write(uint addr, uint8 data) -> void; - auto ram_read(uint addr) -> uint8; - auto ram_write(uint addr, uint8 data) -> void; + auto readROM(uint addr) -> uint8; + auto writeROM(uint addr, uint8 data) -> void; - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readRAM(uint addr) -> uint8; + auto writeRAM(uint addr, uint8 data) -> void; + + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; @@ -54,19 +55,15 @@ struct Cartridge : MMIO { boolean battery; boolean rtc; boolean rumble; - - uint romsize = 0; - uint ramsize = 0; } information; - uint8* romdata = nullptr; - uint romsize = 0; - - uint8* ramdata = nullptr; - uint ramsize = 0; + struct Memory { + uint8* data = nullptr; + uint size = 0; + } rom, ram; MMIO* mapper = nullptr; - bool bootrom_enable = true; + bool bootromEnable = true; }; extern Cartridge cartridge; diff --git a/higan/gb/cartridge/huc1/huc1.cpp b/higan/gb/cartridge/huc1/huc1.cpp index fc65d59d..7080c062 100644 --- a/higan/gb/cartridge/huc1/huc1.cpp +++ b/higan/gb/cartridge/huc1/huc1.cpp @@ -1,50 +1,49 @@ -auto Cartridge::HuC1::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::HuC1::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select << 14 | (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); + return cartridge.readRAM(ram.select << 13 | (uint13)addr); } return 0xff; } -auto Cartridge::HuC1::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::HuC1::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - ram_writable = (data & 0x0f) == 0x0a; + ram.writable = data.bits(0,3) == 0x0a; return; } if((addr & 0xe000) == 0x2000) { //$2000-3fff - rom_select = data; - if(rom_select == 0) rom_select = 1; + rom.select = data + (data == 0); return; } if((addr & 0xe000) == 0x4000) { //$4000-5fff - ram_select = data; + ram.select = data; return; } if((addr & 0xe000) == 0x6000) { //$6000-7fff - model = data & 0x01; + model = data.bit(0); return; } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_writable == false) return; - return cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data); + if(!ram.writable) return; + return cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); } } auto Cartridge::HuC1::power() -> void { - ram_writable = false; - rom_select = 0x01; - ram_select = 0x00; + rom.select = 0x01; + ram.writable = false; + ram.select = 0x00; model = 0; } diff --git a/higan/gb/cartridge/huc1/huc1.hpp b/higan/gb/cartridge/huc1/huc1.hpp index 13daff56..3ef4674d 100644 --- a/higan/gb/cartridge/huc1/huc1.hpp +++ b/higan/gb/cartridge/huc1/huc1.hpp @@ -1,10 +1,14 @@ struct HuC1 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_writable; //$0000-1fff - uint8 rom_select; //$2000-3fff - uint8 ram_select; //$4000-5fff - bool model; //$6000-7fff + struct ROM { + uint8 select; + } rom; + struct RAM { + bool writable; + uint8 select; + } ram; + bool model; } huc1; diff --git a/higan/gb/cartridge/huc3/huc3.cpp b/higan/gb/cartridge/huc3/huc3.cpp index 82c294c6..e07cc257 100644 --- a/higan/gb/cartridge/huc3/huc3.cpp +++ b/higan/gb/cartridge/huc3/huc3.cpp @@ -1,33 +1,33 @@ -auto Cartridge::HuC3::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::HuC3::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select << 14 | (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); + if(ram.enable) return cartridge.readRAM(ram.select << 13 | (uint13)addr); return 0x01; //does not return open collection } return 0xff; } -auto Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::HuC3::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - ram_enable = (data & 0x0f) == 0x0a; + ram.enable = data.bits(0,3) == 0x0a; return; } if((addr & 0xe000) == 0x2000) { //$2000-3fff - rom_select = data; + rom.select = data; return; } if((addr & 0xe000) == 0x4000) { //$4000-5fff - ram_select = data; + ram.select = data; return; } @@ -37,13 +37,13 @@ auto Cartridge::HuC3::mmio_write(uint16 addr, uint8 data) -> void { } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data); + if(ram.enable) cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); return; } } auto Cartridge::HuC3::power() -> void { - ram_enable = false; - rom_select = 0x01; - ram_select = 0x00; + rom.select = 0x01; + ram.enable = false; + ram.select = 0x00; } diff --git a/higan/gb/cartridge/huc3/huc3.hpp b/higan/gb/cartridge/huc3/huc3.hpp index 4e793eb0..bc03b3a3 100644 --- a/higan/gb/cartridge/huc3/huc3.hpp +++ b/higan/gb/cartridge/huc3/huc3.hpp @@ -1,9 +1,13 @@ struct HuC3 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_enable; //$0000-1fff - uint8 rom_select; //$2000-3fff - uint8 ram_select; //$4000-5fff + struct ROM { + uint8 select; + } rom; + struct RAM { + bool enable; + uint8 select; + } ram; } huc3; diff --git a/higan/gb/cartridge/mbc0/mbc0.cpp b/higan/gb/cartridge/mbc0/mbc0.cpp index 4d4f71a1..5f6c49ec 100644 --- a/higan/gb/cartridge/mbc0/mbc0.cpp +++ b/higan/gb/cartridge/mbc0/mbc0.cpp @@ -1,18 +1,18 @@ -auto Cartridge::MBC0::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC0::readIO(uint16 addr) -> uint8 { if((addr & 0x8000) == 0x0000) { //$0000-7fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - return cartridge.ram_read(addr & 0x1fff); + return cartridge.readRAM((uint13)addr); } return 0xff; } -auto Cartridge::MBC0::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC0::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0xa000) { //$a000-bfff - cartridge.ram_write(addr & 0x1fff, data); + cartridge.writeRAM((uint13)addr, data); return; } } diff --git a/higan/gb/cartridge/mbc0/mbc0.hpp b/higan/gb/cartridge/mbc0/mbc0.hpp index ccc60070..0f9311e7 100644 --- a/higan/gb/cartridge/mbc0/mbc0.hpp +++ b/higan/gb/cartridge/mbc0/mbc0.hpp @@ -1,5 +1,5 @@ struct MBC0 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; } mbc0; diff --git a/higan/gb/cartridge/mbc1/mbc1.cpp b/higan/gb/cartridge/mbc1/mbc1.cpp index b638324c..3eb57e49 100644 --- a/higan/gb/cartridge/mbc1/mbc1.cpp +++ b/higan/gb/cartridge/mbc1/mbc1.cpp @@ -1,22 +1,22 @@ -auto Cartridge::MBC1::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC1::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - if(mode_select == 0) { - return cartridge.rom_read((ram_select << 19) | (rom_select << 14) | (addr & 0x3fff)); + if(mode == 0) { + return cartridge.readROM(ram.select << 19 | rom.select << 14 | (uint14)addr); } else { - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select << 14 | (uint14)addr); } } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) { - if(mode_select == 0) { - return cartridge.ram_read(addr & 0x1fff); + if(ram.enable) { + if(mode == 0) { + return cartridge.readRAM((uint13)addr); } else { - return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); + return cartridge.readRAM(ram.select << 13 | (uint13)addr); } } return 0xff; @@ -25,33 +25,33 @@ auto Cartridge::MBC1::mmio_read(uint16 addr) -> uint8 { return 0xff; } -auto Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC1::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - ram_enable = (data & 0x0f) == 0x0a; + ram.enable = (data & 0x0f) == 0x0a; return; } if((addr & 0xe000) == 0x2000) { //$2000-3fff - rom_select = (data & 0x1f) + ((data & 0x1f) == 0); + rom.select = (data & 0x1f) + ((data & 0x1f) == 0); return; } if((addr & 0xe000) == 0x4000) { //$4000-5fff - ram_select = data & 0x03; + ram.select = data & 0x03; return; } if((addr & 0xe000) == 0x6000) { //$6000-7fff - mode_select = data & 0x01; + mode = data & 0x01; return; } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) { - if(mode_select == 0) { - cartridge.ram_write(addr & 0x1fff, data); + if(ram.enable) { + if(mode == 0) { + cartridge.writeRAM(addr & 0x1fff, data); } else { - cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data); + cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); } } return; @@ -59,8 +59,8 @@ auto Cartridge::MBC1::mmio_write(uint16 addr, uint8 data) -> void { } auto Cartridge::MBC1::power() -> void { - ram_enable = false; - rom_select = 0x01; - ram_select = 0x00; - mode_select = 0; + rom.select = 0x01; + ram.enable = false; + ram.select = 0x00; + mode = 0; } diff --git a/higan/gb/cartridge/mbc1/mbc1.hpp b/higan/gb/cartridge/mbc1/mbc1.hpp index 7cde13eb..104bef44 100644 --- a/higan/gb/cartridge/mbc1/mbc1.hpp +++ b/higan/gb/cartridge/mbc1/mbc1.hpp @@ -1,10 +1,14 @@ struct MBC1 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_enable; //$0000-1fff - uint8 rom_select; //$2000-3fff - uint8 ram_select; //$4000-5fff - bool mode_select; //$6000-7fff + struct ROM { + uint8 select; + } rom; + struct RAM { + bool enable; + uint8 select; + } ram; + bool mode; } mbc1; diff --git a/higan/gb/cartridge/mbc1m/mbc1m.cpp b/higan/gb/cartridge/mbc1m/mbc1m.cpp index 79fdc6a7..647be028 100644 --- a/higan/gb/cartridge/mbc1m/mbc1m.cpp +++ b/higan/gb/cartridge/mbc1m/mbc1m.cpp @@ -1,40 +1,40 @@ -auto Cartridge::MBC1M::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC1M::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - if(!modeSelect) return cartridge.rom_read(addr & 0x3fff); - return cartridge.rom_read((romHi << 4) * 0x4000 + (addr & 0x3fff)); + if(mode == 0) return cartridge.readROM((uint14)addr); + return cartridge.readROM(rom.hi << 18 | (uint14)addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((romHi << 4 | romLo) * 0x4000 + (addr & 0x3fff)); + return cartridge.readROM(rom.hi << 18 | rom.lo << 14 | (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - return cartridge.ram_read(addr & 0x1fff); + return cartridge.readRAM((uint13)addr); } return 0xff; } -auto Cartridge::MBC1M::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC1M::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x2000) { //$2000-3fff - romLo = data.bits(0,3); + rom.lo = data.bits(0,3); } if((addr & 0xe000) == 0x4000) { //$4000-5fff - romHi = data.bits(0,1); + rom.hi = data.bits(0,1); } if((addr & 0xe000) == 0x6000) { //$6000-7fff - modeSelect = data.bit(0); + mode = data.bit(0); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - cartridge.ram_write(addr & 0x1fff, data); + cartridge.writeRAM((uint13)addr, data); } } auto Cartridge::MBC1M::power() -> void { - romHi = 0; - romLo = 1; - modeSelect = 0; + rom.lo = 1; + rom.hi = 0; + mode = 0; } diff --git a/higan/gb/cartridge/mbc1m/mbc1m.hpp b/higan/gb/cartridge/mbc1m/mbc1m.hpp index 2e1b6249..bf083215 100644 --- a/higan/gb/cartridge/mbc1m/mbc1m.hpp +++ b/higan/gb/cartridge/mbc1m/mbc1m.hpp @@ -1,9 +1,11 @@ struct MBC1M : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - uint4 romLo; - uint2 romHi; - uint1 modeSelect; + struct ROM { + uint4 lo; + uint2 hi; + } rom; + uint1 mode; } mbc1m; diff --git a/higan/gb/cartridge/mbc2/mbc2.cpp b/higan/gb/cartridge/mbc2/mbc2.cpp index b0d9a945..8e1c03bd 100644 --- a/higan/gb/cartridge/mbc2/mbc2.cpp +++ b/higan/gb/cartridge/mbc2/mbc2.cpp @@ -1,38 +1,38 @@ -auto Cartridge::MBC2::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC2::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select << 14 | (uint14)addr); } if((addr & 0xee00) == 0xa000) { //$a000-a1ff - if(ram_enable) return cartridge.ram_read(addr & 0x1ff); + if(ram.enable) return cartridge.readRAM((uint9)addr); return 0xff; } return 0xff; } -auto Cartridge::MBC2::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC2::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - if(!(addr & 0x0100)) ram_enable = (data & 0x0f) == 0x0a; + if(!addr.bit(8)) ram.enable = data.bits(0,3) == 0x0a; return; } if((addr & 0xe000) == 0x2000) { //$2000-3fff - if( (addr & 0x0100)) rom_select = (data & 0x0f) + ((data & 0x0f) == 0); + if( addr.bit(8)) rom.select = data.bits(0,3) + (data.bits(0,3) == 0); return; } if((addr & 0xee00) == 0xa000) { //$a000-a1ff - if(ram_enable) cartridge.ram_write(addr & 0x1ff, data & 0x0f); + if(ram.enable) cartridge.writeRAM((uint9)addr, data.bits(0,3)); return; } } auto Cartridge::MBC2::power() -> void { - ram_enable = false; - rom_select = 0x01; + rom.select = 0x01; + ram.enable = false; } diff --git a/higan/gb/cartridge/mbc2/mbc2.hpp b/higan/gb/cartridge/mbc2/mbc2.hpp index d7ba7932..7f8458c6 100644 --- a/higan/gb/cartridge/mbc2/mbc2.hpp +++ b/higan/gb/cartridge/mbc2/mbc2.hpp @@ -1,8 +1,12 @@ struct MBC2 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_enable; //$0000-1fff - uint8 rom_select; //$2000-3fff + struct ROM { + uint8 select; + } rom; + struct RAM { + bool enable; + } ram; } mbc2; diff --git a/higan/gb/cartridge/mbc3/mbc3.cpp b/higan/gb/cartridge/mbc3/mbc3.cpp index 7681bc37..dd6d3577 100644 --- a/higan/gb/cartridge/mbc3/mbc3.cpp +++ b/higan/gb/cartridge/mbc3/mbc3.cpp @@ -1,14 +1,14 @@ auto Cartridge::MBC3::second() -> void { - if(rtc_halt == false) { - if(++rtc_second >= 60) { - rtc_second = 0; - if(++rtc_minute >= 60) { - rtc_minute = 0; - if(++rtc_hour >= 24) { - rtc_hour = 0; - if(++rtc_day >= 512) { - rtc_day = 0; - rtc_day_carry = true; + if(!rtc.halt) { + if(++rtc.second >= 60) { + rtc.second = 0; + if(++rtc.minute >= 60) { + rtc.minute = 0; + if(++rtc.hour >= 24) { + rtc.hour = 0; + if(++rtc.day >= 512) { + rtc.day = 0; + rtc.dayCarry = true; } } } @@ -16,25 +16,25 @@ auto Cartridge::MBC3::second() -> void { } } -auto Cartridge::MBC3::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC3::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select<< 14 | (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) { - if(ram_select >= 0x00 && ram_select <= 0x03) { - return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); + if(ram.enable) { + if(ram.select <= 0x03) { + return cartridge.readRAM(ram.select << 13 | (uint13)addr); } - if(ram_select == 0x08) return rtc_latch_second; - if(ram_select == 0x09) return rtc_latch_minute; - if(ram_select == 0x0a) return rtc_latch_hour; - if(ram_select == 0x0b) return rtc_latch_day; - if(ram_select == 0x0c) return (rtc_latch_day_carry << 7) | (rtc_latch_day >> 8); + if(ram.select == 0x08) return rtc.latchSecond; + if(ram.select == 0x09) return rtc.latchMinute; + if(ram.select == 0x0a) return rtc.latchHour; + if(ram.select == 0x0b) return rtc.latchDay; + if(ram.select == 0x0c) return rtc.latchDayCarry << 7 | rtc.latchDay >> 8; } return 0xff; } @@ -42,53 +42,53 @@ auto Cartridge::MBC3::mmio_read(uint16 addr) -> uint8 { return 0xff; } -auto Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC3::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - ram_enable = (data & 0x0f) == 0x0a; + ram.enable = (data & 0x0f) == 0x0a; return; } if((addr & 0xe000) == 0x2000) { //$2000-3fff - rom_select = (data & 0x7f) + ((data & 0x7f) == 0); + rom.select = (data & 0x7f) + ((data & 0x7f) == 0); return; } if((addr & 0xe000) == 0x4000) { //$4000-5fff - ram_select = data; + ram.select = data; return; } if((addr & 0xe000) == 0x6000) { //$6000-7fff - if(rtc_latch == 0 && data == 1) { - rtc_latch_second = rtc_second; - rtc_latch_minute = rtc_minute; - rtc_latch_hour = rtc_hour; - rtc_latch_day = rtc_day; - rtc_latch_day_carry = rtc_day_carry; + if(rtc.latch == 0 && data == 1) { + rtc.latchSecond = rtc.second; + rtc.latchMinute = rtc.minute; + rtc.latchHour = rtc.hour; + rtc.latchDay = rtc.day; + rtc.latchDayCarry = rtc.dayCarry; } - rtc_latch = data; + rtc.latch = data; return; } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) { - if(ram_select >= 0x00 && ram_select <= 0x03) { - cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data); - } else if(ram_select == 0x08) { + if(ram.enable) { + if(ram.select <= 0x03) { + cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); + } else if(ram.select == 0x08) { if(data >= 60) data = 0; - rtc_second = data; - } else if(ram_select == 0x09) { + rtc.second = data; + } else if(ram.select == 0x09) { if(data >= 60) data = 0; - rtc_minute = data; - } else if(ram_select == 0x0a) { + rtc.minute = data; + } else if(ram.select == 0x0a) { if(data >= 24) data = 0; - rtc_hour = data; - } else if(ram_select == 0x0b) { - rtc_day = (rtc_day & 0x0100) | data; - } else if(ram_select == 0x0c) { - rtc_day = ((data & 1) << 8) | (rtc_day & 0xff); - rtc_halt = data & 0x40; - rtc_day_carry = data & 0x80; + rtc.hour = data; + } else if(ram.select == 0x0b) { + rtc.day = (rtc.day & 0x0100) | data; + } else if(ram.select == 0x0c) { + rtc.day = ((data & 1) << 8) | (rtc.day & 0xff); + rtc.halt = data & 0x40; + rtc.dayCarry = data & 0x80; } } return; @@ -96,21 +96,23 @@ auto Cartridge::MBC3::mmio_write(uint16 addr, uint8 data) -> void { } auto Cartridge::MBC3::power() -> void { - ram_enable = false; - rom_select = 0x01; - ram_select = 0x00; - rtc_latch = 0; + rom.select = 0x01; - rtc_halt = true; - rtc_second = 0; - rtc_minute = 0; - rtc_hour = 0; - rtc_day = 0; - rtc_day_carry = false; + ram.enable = false; + ram.select = 0x00; - rtc_latch_second = 0; - rtc_latch_minute = 0; - rtc_latch_hour = 0; - rtc_latch_day = 0; - rtc_latch_day_carry = false; + rtc.latch = 0; + + rtc.halt = true; + rtc.second = 0; + rtc.minute = 0; + rtc.hour = 0; + rtc.day = 0; + rtc.dayCarry = false; + + rtc.latchSecond = 0; + rtc.latchMinute = 0; + rtc.latchHour = 0; + rtc.latchDay = 0; + rtc.latchDayCarry = false; } diff --git a/higan/gb/cartridge/mbc3/mbc3.hpp b/higan/gb/cartridge/mbc3/mbc3.hpp index 57057ec5..97cb0d13 100644 --- a/higan/gb/cartridge/mbc3/mbc3.hpp +++ b/higan/gb/cartridge/mbc3/mbc3.hpp @@ -1,24 +1,30 @@ struct MBC3 : MMIO { auto second() -> void; - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_enable; //$0000-1fff - uint8 rom_select; //$2000-3fff - uint8 ram_select; //$4000-5fff - bool rtc_latch; //$6000-7fff + struct ROM { + uint8 select; + } rom; + struct RAM { + bool enable; + uint8 select; + } ram; + struct RTC { + bool latch; - bool rtc_halt; - uint rtc_second; - uint rtc_minute; - uint rtc_hour; - uint rtc_day; - bool rtc_day_carry; + bool halt; + uint second; + uint minute; + uint hour; + uint day; + bool dayCarry; - uint rtc_latch_second; - uint rtc_latch_minute; - uint rtc_latch_hour; - uint rtc_latch_day; - uint rtc_latch_day_carry; + uint latchSecond; + uint latchMinute; + uint latchHour; + uint latchDay; + uint latchDayCarry; + } rtc; } mbc3; diff --git a/higan/gb/cartridge/mbc5/mbc5.cpp b/higan/gb/cartridge/mbc5/mbc5.cpp index f76c3e32..07f2b826 100644 --- a/higan/gb/cartridge/mbc5/mbc5.cpp +++ b/higan/gb/cartridge/mbc5/mbc5.cpp @@ -1,49 +1,49 @@ -auto Cartridge::MBC5::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MBC5::readIO(uint16 addr) -> uint8 { if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(addr); + return cartridge.readROM(addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff)); + return cartridge.readROM(rom.select << 14 | (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) return cartridge.ram_read((ram_select << 13) | (addr & 0x1fff)); + if(ram.enable) return cartridge.readRAM(ram.select << 13 | (uint13)addr); return 0xff; } return 0xff; } -auto Cartridge::MBC5::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MBC5::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - ram_enable = (data & 0x0f) == 0x0a; + ram.enable = data.bits(0,3) == 0x0a; return; } if((addr & 0xf000) == 0x2000) { //$2000-2fff - rom_select = (rom_select & 0x0100) | data; + rom.select.byte(0) = data; return; } if((addr & 0xf000) == 0x3000) { //$3000-3fff - rom_select = ((data & 1) << 8) | (rom_select & 0x00ff); + rom.select.byte(1) = data.bit(0); return; } if((addr & 0xe000) == 0x4000) { //$4000-5fff - ram_select = data & 0x0f; + ram.select = data.bits(0,3); return; } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) cartridge.ram_write((ram_select << 13) | (addr & 0x1fff), data); + if(ram.enable) cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); return; } } auto Cartridge::MBC5::power() -> void { - ram_enable = false; - rom_select = 0x001; - ram_select = 0x00; + rom.select = 0x001; + ram.enable = false; + ram.select = 0x00; } diff --git a/higan/gb/cartridge/mbc5/mbc5.hpp b/higan/gb/cartridge/mbc5/mbc5.hpp index f920fd0d..1d6bcf94 100644 --- a/higan/gb/cartridge/mbc5/mbc5.hpp +++ b/higan/gb/cartridge/mbc5/mbc5.hpp @@ -1,9 +1,13 @@ struct MBC5 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool ram_enable; //$0000-1fff - uint16 rom_select; //$2000-2fff + $3000-3fff - uint8 ram_select; //$4000-5fff + struct ROM { + uint9 select; + } rom; + struct RAM { + bool enable; + uint4 select; + } ram; } mbc5; diff --git a/higan/gb/cartridge/mmm01/mmm01.cpp b/higan/gb/cartridge/mmm01/mmm01.cpp index d70bd3cf..8755aa84 100644 --- a/higan/gb/cartridge/mmm01/mmm01.cpp +++ b/higan/gb/cartridge/mmm01/mmm01.cpp @@ -1,44 +1,44 @@ -auto Cartridge::MMM01::mmio_read(uint16 addr) -> uint8 { +auto Cartridge::MMM01::readIO(uint16 addr) -> uint8 { if((addr & 0x8000) == 0x0000) { //$0000-7fff - if(rom_mode == 0) return cartridge.rom_read(addr); + if(mode == 0) return cartridge.readROM(addr); } if((addr & 0xc000) == 0x0000) { //$0000-3fff - return cartridge.rom_read(0x8000 + (rom_base << 14) + (addr & 0x3fff)); + return cartridge.readROM(0x8000 + (rom.base << 14) + (uint14)addr); } if((addr & 0xc000) == 0x4000) { //$4000-7fff - return cartridge.rom_read(0x8000 + (rom_base << 14) + (rom_select << 14) + (addr & 0x3fff)); + return cartridge.readROM(0x8000 + (rom.base << 14) + (rom.select<< 14) + (uint14)addr); } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) return cartridge.ram_read((ram_select << 13) + (addr & 0x1fff)); + if(ram.enable) return cartridge.readRAM(ram.select << 13 | (uint13)addr); return 0xff; } return 0xff; } -auto Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) -> void { +auto Cartridge::MMM01::writeIO(uint16 addr, uint8 data) -> void { if((addr & 0xe000) == 0x0000) { //$0000-1fff - if(rom_mode == 0) { - rom_mode = 1; + if(mode == 0) { + mode = 1; } else { - ram_enable = (data & 0x0f) == 0x0a; + ram.enable= data.bits(0,3) == 0x0a; } } if((addr & 0xe000) == 0x2000) { //$2000-3fff - if(rom_mode == 0) { - rom_base = data & 0x3f; + if(mode == 0) { + rom.base = data.bits(0,5); } else { - rom_select = data; + rom.select = data; } } if((addr & 0xe000) == 0x4000) { //$4000-5fff - if(rom_mode == 1) { - ram_select = data; + if(mode == 1) { + ram.select = data; } } @@ -47,15 +47,14 @@ auto Cartridge::MMM01::mmio_write(uint16 addr, uint8 data) -> void { } if((addr & 0xe000) == 0xa000) { //$a000-bfff - if(ram_enable) cartridge.ram_write((ram_select << 13) + (addr & 0x1fff), data); + if(ram.enable) cartridge.writeRAM(ram.select << 13 | (uint13)addr, data); } } auto Cartridge::MMM01::power() -> void { - rom_mode = 0; - rom_base = 0; - - ram_enable = false; - rom_select = 0x01; - ram_select = 0x00; + rom.base = 0x00; + rom.select = 0x01; + ram.enable = false; + ram.select = 0x00; + mode = 0; } diff --git a/higan/gb/cartridge/mmm01/mmm01.hpp b/higan/gb/cartridge/mmm01/mmm01.hpp index 94b50011..958f9d06 100644 --- a/higan/gb/cartridge/mmm01/mmm01.hpp +++ b/higan/gb/cartridge/mmm01/mmm01.hpp @@ -1,12 +1,15 @@ struct MMM01 : MMIO { - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; auto power() -> void; - bool rom_mode; - uint8 rom_base; - - bool ram_enable; - uint8 rom_select; - uint8 ram_select; + struct ROM { + uint6 base; + uint8 select; + } rom; + struct RAM { + bool enable; + uint8 select; + } ram; + bool mode; } mmm01; diff --git a/higan/gb/cartridge/serialization.cpp b/higan/gb/cartridge/serialization.cpp index c00b7568..7ea9dc8a 100644 --- a/higan/gb/cartridge/serialization.cpp +++ b/higan/gb/cartridge/serialization.cpp @@ -1,54 +1,51 @@ auto Cartridge::serialize(serializer& s) -> void { - if(information.battery) s.array(ramdata, ramsize); - s.integer(bootrom_enable); + if(information.battery) s.array(ram.data, ram.size); + s.integer(bootromEnable); - s.integer(mbc1.ram_enable); - s.integer(mbc1.rom_select); - s.integer(mbc1.ram_select); - s.integer(mbc1.mode_select); + s.integer(mbc1.rom.select); + s.integer(mbc1.ram.enable); + s.integer(mbc1.ram.select); + s.integer(mbc1.mode); - s.integer(mbc1m.romLo); - s.integer(mbc1m.romHi); - s.integer(mbc1m.modeSelect); + s.integer(mbc1m.rom.lo); + s.integer(mbc1m.rom.hi); + s.integer(mbc1m.mode); - s.integer(mbc2.ram_enable); - s.integer(mbc2.rom_select); + s.integer(mbc2.rom.select); + s.integer(mbc2.ram.enable); - s.integer(mbc3.ram_enable); - s.integer(mbc3.rom_select); - s.integer(mbc3.ram_select); - s.integer(mbc3.rtc_latch); + s.integer(mbc3.rom.select); + s.integer(mbc3.ram.enable); + s.integer(mbc3.ram.select); + s.integer(mbc3.rtc.latch); + s.integer(mbc3.rtc.halt); + s.integer(mbc3.rtc.second); + s.integer(mbc3.rtc.minute); + s.integer(mbc3.rtc.hour); + s.integer(mbc3.rtc.day); + s.integer(mbc3.rtc.dayCarry); + s.integer(mbc3.rtc.latchSecond); + s.integer(mbc3.rtc.latchMinute); + s.integer(mbc3.rtc.latchHour); + s.integer(mbc3.rtc.latchDay); + s.integer(mbc3.rtc.latchDayCarry); - s.integer(mbc3.rtc_halt); - s.integer(mbc3.rtc_second); - s.integer(mbc3.rtc_minute); - s.integer(mbc3.rtc_hour); - s.integer(mbc3.rtc_day); - s.integer(mbc3.rtc_day_carry); + s.integer(mbc5.rom.select); + s.integer(mbc5.ram.enable); + s.integer(mbc5.ram.select); - s.integer(mbc3.rtc_latch_second); - s.integer(mbc3.rtc_latch_minute); - s.integer(mbc3.rtc_latch_hour); - s.integer(mbc3.rtc_latch_day); - s.integer(mbc3.rtc_latch_day_carry); + s.integer(mmm01.rom.base); + s.integer(mmm01.rom.select); + s.integer(mmm01.ram.enable); + s.integer(mmm01.ram.select); + s.integer(mmm01.mode); - s.integer(mbc5.ram_enable); - s.integer(mbc5.rom_select); - s.integer(mbc5.ram_select); - - s.integer(mmm01.rom_mode); - s.integer(mmm01.rom_base); - - s.integer(mmm01.ram_enable); - s.integer(mmm01.rom_select); - s.integer(mmm01.ram_select); - - s.integer(huc1.ram_writable); - s.integer(huc1.rom_select); - s.integer(huc1.ram_select); + s.integer(huc1.rom.select); + s.integer(huc1.ram.writable); + s.integer(huc1.ram.select); s.integer(huc1.model); - s.integer(huc3.ram_enable); - s.integer(huc3.rom_select); - s.integer(huc3.ram_select); + s.integer(huc3.rom.select); + s.integer(huc3.ram.enable); + s.integer(huc3.ram.select); } diff --git a/higan/gb/cpu/cpu.cpp b/higan/gb/cpu/cpu.cpp index 6ce35d5b..0837ccc4 100644 --- a/higan/gb/cpu/cpu.cpp +++ b/higan/gb/cpu/cpu.cpp @@ -13,72 +13,72 @@ auto CPU::Enter() -> void { } auto CPU::main() -> void { - interrupt_test(); + interruptTest(); instruction(); } auto CPU::raise(CPU::Interrupt id) -> void { if(id == Interrupt::Vblank) { - status.interrupt_request_vblank = 1; - if(status.interrupt_enable_vblank) r.halt = false; + status.interruptRequestVblank = 1; + if(status.interruptEnableVblank) r.halt = false; } if(id == Interrupt::Stat) { - status.interrupt_request_stat = 1; - if(status.interrupt_enable_stat) r.halt = false; + status.interruptRequestStat = 1; + if(status.interruptEnableStat) r.halt = false; } if(id == Interrupt::Timer) { - status.interrupt_request_timer = 1; - if(status.interrupt_enable_timer) r.halt = false; + status.interruptRequestTimer = 1; + if(status.interruptEnableTimer) r.halt = false; } if(id == Interrupt::Serial) { - status.interrupt_request_serial = 1; - if(status.interrupt_enable_serial) r.halt = false; + status.interruptRequestSerial = 1; + if(status.interruptEnableSerial) r.halt = false; } if(id == Interrupt::Joypad) { - status.interrupt_request_joypad = 1; - if(status.interrupt_enable_joypad) r.halt = r.stop = false; + status.interruptRequestJoypad = 1; + if(status.interruptEnableJoypad) r.halt = r.stop = false; } } -auto CPU::interrupt_test() -> void { +auto CPU::interruptTest() -> void { if(!r.ime) return; - if(status.interrupt_request_vblank && status.interrupt_enable_vblank) { - status.interrupt_request_vblank = 0; + if(status.interruptRequestVblank && status.interruptEnableVblank) { + status.interruptRequestVblank = 0; return interrupt(0x0040); } - if(status.interrupt_request_stat && status.interrupt_enable_stat) { - status.interrupt_request_stat = 0; + if(status.interruptRequestStat && status.interruptEnableStat) { + status.interruptRequestStat = 0; return interrupt(0x0048); } - if(status.interrupt_request_timer && status.interrupt_enable_timer) { - status.interrupt_request_timer = 0; + if(status.interruptRequestTimer && status.interruptEnableTimer) { + status.interruptRequestTimer = 0; return interrupt(0x0050); } - if(status.interrupt_request_serial && status.interrupt_enable_serial) { - status.interrupt_request_serial = 0; + if(status.interruptRequestSerial && status.interruptEnableSerial) { + status.interruptRequestSerial = 0; return interrupt(0x0058); } - if(status.interrupt_request_joypad && status.interrupt_enable_joypad) { - status.interrupt_request_joypad = 0; + if(status.interruptRequestJoypad && status.interruptEnableJoypad) { + status.interruptRequestJoypad = 0; return interrupt(0x0060); } } auto CPU::stop() -> bool { - if(status.speed_switch) { - status.speed_switch = 0; - status.speed_double ^= 1; - if(status.speed_double == 0) frequency = 4 * 1024 * 1024; - if(status.speed_double == 1) frequency = 8 * 1024 * 1024; + if(status.speedSwitch) { + status.speedSwitch = 0; + status.speedDouble ^= 1; + if(status.speedDouble == 0) frequency = 4 * 1024 * 1024; + if(status.speedDouble == 1) frequency = 8 * 1024 * 1024; return true; } return false; @@ -130,57 +130,9 @@ auto CPU::power() -> void { r[DE] = 0x0000; r[HL] = 0x0000; - status.clock = 0; - - status.p15 = 0; - status.p14 = 0; - status.joyp = 0; - status.mlt_req = 0; - - status.serial_data = 0; - status.serial_bits = 0; - - status.serial_transfer = 0; - status.serial_clock = 0; - - status.div = 0; - - status.tima = 0; - - status.tma = 0; - - status.timer_enable = 0; - status.timer_clock = 0; - - status.interrupt_request_joypad = 0; - status.interrupt_request_serial = 0; - status.interrupt_request_timer = 0; - status.interrupt_request_stat = 0; - status.interrupt_request_vblank = 0; - - status.speed_double = 0; - status.speed_switch = 0; - - status.dma_source = 0; - status.dma_target = 0; - - status.dma_mode = 0; - status.dma_length = 0; - status.dma_completed = true; - - status.ff6c = 0; - status.ff72 = 0; - status.ff73 = 0; - status.ff74 = 0; - status.ff75 = 0; - - status.wram_bank = 1; - - status.interrupt_enable_joypad = 0; - status.interrupt_enable_serial = 0; - status.interrupt_enable_timer = 0; - status.interrupt_enable_stat = 0; - status.interrupt_enable_vblank = 0; + memory::fill(&status, sizeof(Status)); + status.dmaCompleted = true; + status.wramBank = 1; } } diff --git a/higan/gb/cpu/cpu.hpp b/higan/gb/cpu/cpu.hpp index abae6161..da94b2a5 100644 --- a/higan/gb/cpu/cpu.hpp +++ b/higan/gb/cpu/cpu.hpp @@ -4,34 +4,34 @@ struct CPU : Processor::LR35902, Thread, MMIO { static auto Enter() -> void; auto main() -> void; auto raise(Interrupt id) -> void; - auto interrupt_test() -> void; + auto interruptTest() -> void; auto stop() -> bool; auto power() -> void; auto serialize(serializer&) -> void; //mmio.cpp - auto wram_addr(uint16 addr) const -> uint; - auto mmio_joyp_poll() -> void; - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto wramAddress(uint16 addr) const -> uint; + auto joypPoll() -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; //memory.cpp auto io() -> void override; auto read(uint16 addr) -> uint8 override; auto write(uint16 addr, uint8 data) -> void override; - auto cycle_edge() -> void; - auto dma_read(uint16 addr) -> uint8; - auto dma_write(uint16 addr, uint8 data) -> void; - auto debugger_read(uint16 addr) -> uint8; + auto cycleEdge() -> void; + auto readDMA(uint16 addr) -> uint8; + auto writeDMA(uint16 addr, uint8 data) -> void; + auto readDebugger(uint16 addr) -> uint8; //timing.cpp - auto add_clocks(uint clocks) -> void; - auto timer_262144hz() -> void; - auto timer_65536hz() -> void; - auto timer_16384hz() -> void; - auto timer_8192hz() -> void; - auto timer_4096hz() -> void; + auto step(uint clocks) -> void; + auto timer262144hz() -> void; + auto timer65536hz() -> void; + auto timer16384hz() -> void; + auto timer8192hz() -> void; + auto timer4096hz() -> void; auto hblank() -> void; struct Status { @@ -41,15 +41,15 @@ struct CPU : Processor::LR35902, Thread, MMIO { bool p15; bool p14; uint8 joyp; - uint8 mlt_req; + uint8 mltReq; //$ff01 SB - uint8 serial_data; - uint serial_bits; + uint8 serialData; + uint serialBits; //$ff02 SC - bool serial_transfer; - bool serial_clock; + bool serialTransfer; + bool serialClock; //$ff04 DIV uint16 div; @@ -61,36 +61,36 @@ struct CPU : Processor::LR35902, Thread, MMIO { uint8 tma; //$ff07 TAC - bool timer_enable; - uint timer_clock; + bool timerEnable; + uint timerClock; //$ff0f IF - bool interrupt_request_joypad; - bool interrupt_request_serial; - bool interrupt_request_timer; - bool interrupt_request_stat; - bool interrupt_request_vblank; + bool interruptRequestJoypad; + bool interruptRequestSerial; + bool interruptRequestTimer; + bool interruptRequestStat; + bool interruptRequestVblank; //$ff4d KEY1 - bool speed_double; - bool speed_switch; + bool speedDouble; + bool speedSwitch; //$ff51,$ff52 HDMA1,HDMA2 - uint16 dma_source; + uint16 dmaSource; //$ff53,$ff54 HDMA3,HDMA4 - uint16 dma_target; + uint16 dmaTarget; //$ff55 HDMA5 - bool dma_mode; - uint16 dma_length; - bool dma_completed; + bool dmaMode; + uint16 dmaLength; + bool dmaCompleted; //$ff6c ??? uint8 ff6c; //$ff70 SVBK - uint3 wram_bank; + uint3 wramBank; //$ff72-$ff75 ??? uint8 ff72; @@ -99,11 +99,11 @@ struct CPU : Processor::LR35902, Thread, MMIO { uint8 ff75; //$ffff IE - bool interrupt_enable_joypad; - bool interrupt_enable_serial; - bool interrupt_enable_timer; - bool interrupt_enable_stat; - bool interrupt_enable_vblank; + bool interruptEnableJoypad; + bool interruptEnableSerial; + bool interruptEnableTimer; + bool interruptEnableStat; + bool interruptEnableVblank; } status; uint8 wram[32768]; //GB=8192, GBC=32768 diff --git a/higan/gb/cpu/memory.cpp b/higan/gb/cpu/memory.cpp index bb9e62fe..51e40671 100644 --- a/higan/gb/cpu/memory.cpp +++ b/higan/gb/cpu/memory.cpp @@ -1,21 +1,21 @@ auto CPU::io() -> void { - cycle_edge(); - add_clocks(4); + cycleEdge(); + step(4); } auto CPU::read(uint16 addr) -> uint8 { - cycle_edge(); - add_clocks(4); + cycleEdge(); + step(4); return bus.read(addr); } auto CPU::write(uint16 addr, uint8 data) -> void { - cycle_edge(); - add_clocks(4); + cycleEdge(); + step(4); bus.write(addr, data); } -auto CPU::cycle_edge() -> void { +auto CPU::cycleEdge() -> void { if(r.ei) { r.ei = false; r.ime = 1; @@ -23,7 +23,7 @@ auto CPU::cycle_edge() -> void { } //VRAM DMA source can only be ROM or RAM -auto CPU::dma_read(uint16 addr) -> uint8 { +auto CPU::readDMA(uint16 addr) -> uint8 { if(addr < 0x8000) return bus.read(addr); //0000-7fff if(addr < 0xa000) return 0xff; //8000-9fff if(addr < 0xe000) return bus.read(addr); //a000-dfff @@ -31,11 +31,11 @@ auto CPU::dma_read(uint16 addr) -> uint8 { } //VRAM DMA target is always VRAM -auto CPU::dma_write(uint16 addr, uint8 data) -> void { +auto CPU::writeDMA(uint16 addr, uint8 data) -> void { addr = 0x8000 | (addr & 0x1fff); //8000-9fff return bus.write(addr, data); } -auto CPU::debugger_read(uint16 addr) -> uint8 { +auto CPU::readDebugger(uint16 addr) -> uint8 { return bus.read(addr); } diff --git a/higan/gb/cpu/mmio.cpp b/higan/gb/cpu/mmio.cpp index c470c69b..224e3be4 100644 --- a/higan/gb/cpu/mmio.cpp +++ b/higan/gb/cpu/mmio.cpp @@ -1,11 +1,11 @@ -auto CPU::wram_addr(uint16 addr) const -> uint { +auto CPU::wramAddress(uint16 addr) const -> uint { addr &= 0x1fff; if(addr < 0x1000) return addr; - auto bank = status.wram_bank + (status.wram_bank == 0); + auto bank = status.wramBank + (status.wramBank == 0); return (bank * 0x1000) + (addr & 0x0fff); } -auto CPU::mmio_joyp_poll() -> void { +auto CPU::joypPoll() -> void { uint button = 0, dpad = 0; button |= interface->inputPoll(0, 0, (uint)Input::Start) << 3; @@ -26,18 +26,18 @@ auto CPU::mmio_joyp_poll() -> void { } status.joyp = 0x0f; - if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req; + if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mltReq; if(status.p15 == 0) status.joyp &= button ^ 0x0f; if(status.p14 == 0) status.joyp &= dpad ^ 0x0f; if(status.joyp != 0x0f) raise(Interrupt::Joypad); } -auto CPU::mmio_read(uint16 addr) -> uint8 { - if(addr >= 0xc000 && addr <= 0xfdff) return wram[wram_addr(addr)]; +auto CPU::readIO(uint16 addr) -> uint8 { + if(addr >= 0xc000 && addr <= 0xfdff) return wram[wramAddress(addr)]; if(addr >= 0xff80 && addr <= 0xfffe) return hram[addr & 0x7f]; if(addr == 0xff00) { //JOYP - mmio_joyp_poll(); + joypPoll(); return 0xc0 | (status.p15 << 5) | (status.p14 << 4) @@ -49,9 +49,9 @@ auto CPU::mmio_read(uint16 addr) -> uint8 { } if(addr == 0xff02) { //SC - return (status.serial_transfer << 7) + return (status.serialTransfer << 7) | 0x7e - | (status.serial_clock << 0); + | (status.serialClock << 0); } if(addr == 0xff04) { //DIV @@ -68,26 +68,26 @@ auto CPU::mmio_read(uint16 addr) -> uint8 { if(addr == 0xff07) { //TAC return 0xf8 - | (status.timer_enable << 2) - | (status.timer_clock << 0); + | (status.timerEnable << 2) + | (status.timerClock << 0); } if(addr == 0xff0f) { //IF return 0xe0 - | (status.interrupt_request_joypad << 4) - | (status.interrupt_request_serial << 3) - | (status.interrupt_request_timer << 2) - | (status.interrupt_request_stat << 1) - | (status.interrupt_request_vblank << 0); + | (status.interruptRequestJoypad << 4) + | (status.interruptRequestSerial << 3) + | (status.interruptRequestTimer << 2) + | (status.interruptRequestStat << 1) + | (status.interruptRequestVblank << 0); } if(addr == 0xff4d) { //KEY1 - return (status.speed_double << 7); + return (status.speedDouble << 7); } if(addr == 0xff55) { //HDMA5 - return (status.dma_completed << 7) - | (((status.dma_length / 16) - 1) & 0x7f); + return (status.dmaCompleted << 7) + | (((status.dmaLength / 16) - 1) & 0x7f); } if(addr == 0xff56) { //RP @@ -99,7 +99,7 @@ auto CPU::mmio_read(uint16 addr) -> uint8 { } if(addr == 0xff70) { //SVBK - return status.wram_bank; + return status.wramBank; } if(addr == 0xff72) { //??? @@ -128,18 +128,18 @@ auto CPU::mmio_read(uint16 addr) -> uint8 { if(addr == 0xffff) { //IE return 0xe0 - | (status.interrupt_enable_joypad << 4) - | (status.interrupt_enable_serial << 3) - | (status.interrupt_enable_timer << 2) - | (status.interrupt_enable_stat << 1) - | (status.interrupt_enable_vblank << 0); + | (status.interruptEnableJoypad << 4) + | (status.interruptEnableSerial << 3) + | (status.interruptEnableTimer << 2) + | (status.interruptEnableStat << 1) + | (status.interruptEnableVblank << 0); } return 0xff; } -auto CPU::mmio_write(uint16 addr, uint8 data) -> void { - if(addr >= 0xc000 && addr <= 0xfdff) { wram[wram_addr(addr)] = data; return; } +auto CPU::writeIO(uint16 addr, uint8 data) -> void { + if(addr >= 0xc000 && addr <= 0xfdff) { wram[wramAddress(addr)] = data; return; } if(addr >= 0xff80 && addr <= 0xfffe) { hram[addr & 0x7f] = data; return; } if(addr == 0xff00) { //JOYP @@ -150,14 +150,14 @@ auto CPU::mmio_write(uint16 addr, uint8 data) -> void { } if(addr == 0xff01) { //SB - status.serial_data = data; + status.serialData = data; return; } if(addr == 0xff02) { //SC - status.serial_transfer = data & 0x80; - status.serial_clock = data & 0x01; - if(status.serial_transfer) status.serial_bits = 8; + status.serialTransfer = data & 0x80; + status.serialClock = data & 0x01; + if(status.serialTransfer) status.serialBits = 8; return; } @@ -177,58 +177,58 @@ auto CPU::mmio_write(uint16 addr, uint8 data) -> void { } if(addr == 0xff07) { //TAC - status.timer_enable = data & 0x04; - status.timer_clock = data & 0x03; + status.timerEnable = data & 0x04; + status.timerClock = data & 0x03; return; } if(addr == 0xff0f) { //IF - status.interrupt_request_joypad = data & 0x10; - status.interrupt_request_serial = data & 0x08; - status.interrupt_request_timer = data & 0x04; - status.interrupt_request_stat = data & 0x02; - status.interrupt_request_vblank = data & 0x01; + status.interruptRequestJoypad = data & 0x10; + status.interruptRequestSerial = data & 0x08; + status.interruptRequestTimer = data & 0x04; + status.interruptRequestStat = data & 0x02; + status.interruptRequestVblank = data & 0x01; return; } if(addr == 0xff4d) { //KEY1 - status.speed_switch = data & 0x01; + status.speedSwitch = data & 0x01; return; } if(addr == 0xff51) { //HDMA1 - status.dma_source = (status.dma_source & 0x00ff) | (data << 8); + status.dmaSource = (status.dmaSource & 0x00ff) | (data << 8); return; } if(addr == 0xff52) { //HDMA2 - status.dma_source = (status.dma_source & 0xff00) | (data & 0xf0); + status.dmaSource = (status.dmaSource & 0xff00) | (data & 0xf0); return; } if(addr == 0xff53) { //HDMA3 - status.dma_target = (status.dma_target & 0x00ff) | (data << 8); + status.dmaTarget = (status.dmaTarget & 0x00ff) | (data << 8); return; } if(addr == 0xff54) { //HDMA4 - status.dma_target = (status.dma_target & 0xff00) | (data & 0xf0); + status.dmaTarget = (status.dmaTarget & 0xff00) | (data & 0xf0); return; } if(addr == 0xff55) { //HDMA5 - status.dma_mode = data & 0x80; - status.dma_length = ((data & 0x7f) + 1) * 16; - status.dma_completed = !status.dma_mode; + status.dmaMode = data & 0x80; + status.dmaLength = ((data & 0x7f) + 1) * 16; + status.dmaCompleted = !status.dmaMode; - if(status.dma_mode == 0) { + if(status.dmaMode == 0) { do { for(auto n : range(16)) { - dma_write(status.dma_target++, dma_read(status.dma_source++)); + writeDMA(status.dmaTarget++, readDMA(status.dmaSource++)); } - add_clocks(8 << status.speed_double); - status.dma_length -= 16; - } while(status.dma_length); + step(8 << status.speedDouble); + status.dmaLength -= 16; + } while(status.dmaLength); } return; } @@ -263,16 +263,16 @@ auto CPU::mmio_write(uint16 addr, uint8 data) -> void { } if(addr == 0xff70) { //SVBK - status.wram_bank = data & 0x07; + status.wramBank = data & 0x07; return; } if(addr == 0xffff) { //IE - status.interrupt_enable_joypad = data & 0x10; - status.interrupt_enable_serial = data & 0x08; - status.interrupt_enable_timer = data & 0x04; - status.interrupt_enable_stat = data & 0x02; - status.interrupt_enable_vblank = data & 0x01; + status.interruptEnableJoypad = data & 0x10; + status.interruptEnableSerial = data & 0x08; + status.interruptEnableTimer = data & 0x04; + status.interruptEnableStat = data & 0x02; + status.interruptEnableVblank = data & 0x01; return; } } diff --git a/higan/gb/cpu/serialization.cpp b/higan/gb/cpu/serialization.cpp index 33ecf448..017cd1f3 100644 --- a/higan/gb/cpu/serialization.cpp +++ b/higan/gb/cpu/serialization.cpp @@ -10,47 +10,47 @@ auto CPU::serialize(serializer& s) -> void { s.integer(status.p15); s.integer(status.p14); s.integer(status.joyp); - s.integer(status.mlt_req); + s.integer(status.mltReq); - s.integer(status.serial_data); - s.integer(status.serial_bits); + s.integer(status.serialData); + s.integer(status.serialBits); - s.integer(status.serial_transfer); - s.integer(status.serial_clock); + s.integer(status.serialTransfer); + s.integer(status.serialClock); s.integer(status.div); s.integer(status.tima); s.integer(status.tma); - s.integer(status.timer_enable); - s.integer(status.timer_clock); + s.integer(status.timerEnable); + s.integer(status.timerClock); - s.integer(status.interrupt_request_joypad); - s.integer(status.interrupt_request_serial); - s.integer(status.interrupt_request_timer); - s.integer(status.interrupt_request_stat); - s.integer(status.interrupt_request_vblank); + s.integer(status.interruptRequestJoypad); + s.integer(status.interruptRequestSerial); + s.integer(status.interruptRequestTimer); + s.integer(status.interruptRequestStat); + s.integer(status.interruptRequestVblank); - s.integer(status.speed_double); - s.integer(status.speed_switch); + s.integer(status.speedDouble); + s.integer(status.speedSwitch); - s.integer(status.dma_source); - s.integer(status.dma_target); - s.integer(status.dma_mode); - s.integer(status.dma_length); - s.integer(status.dma_completed); + s.integer(status.dmaSource); + s.integer(status.dmaTarget); + s.integer(status.dmaMode); + s.integer(status.dmaLength); + s.integer(status.dmaCompleted); s.integer(status.ff6c); - s.integer(status.wram_bank); + s.integer(status.wramBank); s.integer(status.ff72); s.integer(status.ff73); s.integer(status.ff74); s.integer(status.ff75); - s.integer(status.interrupt_enable_joypad); - s.integer(status.interrupt_enable_serial); - s.integer(status.interrupt_enable_timer); - s.integer(status.interrupt_enable_stat); - s.integer(status.interrupt_enable_vblank); + s.integer(status.interruptEnableJoypad); + s.integer(status.interruptEnableSerial); + s.integer(status.interruptEnableTimer); + s.integer(status.interruptEnableStat); + s.integer(status.interruptEnableVblank); } diff --git a/higan/gb/cpu/timing.cpp b/higan/gb/cpu/timing.cpp index 77af3a7c..d30ebaa3 100644 --- a/higan/gb/cpu/timing.cpp +++ b/higan/gb/cpu/timing.cpp @@ -2,7 +2,7 @@ // 456 clocks/scanline // 154 scanlines/frame -auto CPU::add_clocks(uint clocks) -> void { +auto CPU::step(uint clocks) -> void { for(auto n : range(clocks)) { if(++status.clock == 0) { cartridge.mbc3.second(); @@ -10,11 +10,11 @@ auto CPU::add_clocks(uint clocks) -> void { //4MHz / N(hz) - 1 = mask status.div++; - if((status.div & 15) == 0) timer_262144hz(); - if((status.div & 63) == 0) timer_65536hz(); - if((status.div & 255) == 0) timer_16384hz(); - if((status.div & 511) == 0) timer_8192hz(); - if((status.div & 1023) == 0) timer_4096hz(); + if((status.div & 15) == 0) timer262144hz(); + if((status.div & 63) == 0) timer65536hz(); + if((status.div & 255) == 0) timer16384hz(); + if((status.div & 511) == 0) timer8192hz(); + if((status.div & 1023) == 0) timer4096hz(); ppu.clock -= ppu.frequency; if(ppu.clock < 0) co_switch(ppu.thread); @@ -29,8 +29,8 @@ auto CPU::add_clocks(uint clocks) -> void { } } -auto CPU::timer_262144hz() -> void { - if(status.timer_enable && status.timer_clock == 1) { +auto CPU::timer262144hz() -> void { + if(status.timerEnable && status.timerClock == 1) { if(++status.tima == 0) { status.tima = status.tma; raise(Interrupt::Timer); @@ -38,8 +38,8 @@ auto CPU::timer_262144hz() -> void { } } -auto CPU::timer_65536hz() -> void { - if(status.timer_enable && status.timer_clock == 2) { +auto CPU::timer65536hz() -> void { + if(status.timerEnable && status.timerClock == 2) { if(++status.tima == 0) { status.tima = status.tma; raise(Interrupt::Timer); @@ -47,8 +47,8 @@ auto CPU::timer_65536hz() -> void { } } -auto CPU::timer_16384hz() -> void { - if(status.timer_enable && status.timer_clock == 3) { +auto CPU::timer16384hz() -> void { + if(status.timerEnable && status.timerClock == 3) { if(++status.tima == 0) { status.tima = status.tma; raise(Interrupt::Timer); @@ -56,17 +56,17 @@ auto CPU::timer_16384hz() -> void { } } -auto CPU::timer_8192hz() -> void { - if(status.serial_transfer && status.serial_clock) { - if(--status.serial_bits == 0) { - status.serial_transfer = 0; +auto CPU::timer8192hz() -> void { + if(status.serialTransfer && status.serialClock) { + if(--status.serialBits == 0) { + status.serialTransfer = 0; raise(Interrupt::Serial); } } } -auto CPU::timer_4096hz() -> void { - if(status.timer_enable && status.timer_clock == 0) { +auto CPU::timer4096hz() -> void { + if(status.timerEnable && status.timerClock == 0) { if(++status.tima == 0) { status.tima = status.tma; raise(Interrupt::Timer); @@ -75,11 +75,11 @@ auto CPU::timer_4096hz() -> void { } auto CPU::hblank() -> void { - if(status.dma_mode == 1 && status.dma_length && ppu.status.ly < 144) { + if(status.dmaMode == 1 && status.dmaLength && ppu.status.ly < 144) { for(auto n : range(16)) { - dma_write(status.dma_target++, dma_read(status.dma_source++)); + writeDMA(status.dmaTarget++, readDMA(status.dmaSource++)); } - add_clocks(8 << status.speed_double); - status.dma_length -= 16; + step(8 << status.speedDouble); + status.dmaLength -= 16; } } diff --git a/higan/gb/memory/memory.cpp b/higan/gb/memory/memory.cpp index 06221dd0..42c167b5 100644 --- a/higan/gb/memory/memory.cpp +++ b/higan/gb/memory/memory.cpp @@ -36,7 +36,7 @@ auto Memory::free() -> void { // auto Bus::read(uint16 addr) -> uint8 { - uint8 data = mmio[addr]->mmio_read(addr); + uint8 data = mmio[addr]->readIO(addr); if(cheat.enable()) { if(auto result = cheat.find(addr, data)) return result(); @@ -46,7 +46,7 @@ auto Bus::read(uint16 addr) -> uint8 { } auto Bus::write(uint16 addr, uint8 data) -> void { - mmio[addr]->mmio_write(addr, data); + mmio[addr]->writeIO(addr, data); } auto Bus::power() -> void { diff --git a/higan/gb/memory/memory.hpp b/higan/gb/memory/memory.hpp index 56bd59e4..80a2c47f 100644 --- a/higan/gb/memory/memory.hpp +++ b/higan/gb/memory/memory.hpp @@ -11,13 +11,13 @@ struct Memory { }; struct MMIO { - virtual auto mmio_read(uint16 addr) -> uint8 = 0; - virtual auto mmio_write(uint16 addr, uint8 data) -> void = 0; + virtual auto readIO(uint16 addr) -> uint8 = 0; + virtual auto writeIO(uint16 addr, uint8 data) -> void = 0; }; struct Unmapped : MMIO { - auto mmio_read(uint16) -> uint8 { return 0xff; } - auto mmio_write(uint16, uint8) -> void {} + auto readIO(uint16) -> uint8 { return 0xff; } + auto writeIO(uint16, uint8) -> void {} }; struct Bus { diff --git a/higan/gb/ppu/mmio.cpp b/higan/gb/ppu/mmio.cpp index b77b41b2..da4909f4 100644 --- a/higan/gb/ppu/mmio.cpp +++ b/higan/gb/ppu/mmio.cpp @@ -2,7 +2,7 @@ auto PPU::vram_addr(uint16 addr) const -> uint { return (status.vram_bank * 0x2000) + (addr & 0x1fff); } -auto PPU::mmio_read(uint16 addr) -> uint8 { +auto PPU::readIO(uint16 addr) -> uint8 { if(addr >= 0x8000 && addr <= 0x9fff) { return vram[vram_addr(addr)]; } @@ -100,7 +100,7 @@ auto PPU::mmio_read(uint16 addr) -> uint8 { return 0xff; //should never occur } -auto PPU::mmio_write(uint16 addr, uint8 data) -> void { +auto PPU::writeIO(uint16 addr, uint8 data) -> void { if(addr >= 0x8000 && addr <= 0x9fff) { vram[vram_addr(addr)] = data; return; diff --git a/higan/gb/ppu/ppu.cpp b/higan/gb/ppu/ppu.cpp index e7487bcc..6d9b0d94 100644 --- a/higan/gb/ppu/ppu.cpp +++ b/higan/gb/ppu/ppu.cpp @@ -79,8 +79,8 @@ auto PPU::wait(uint clocks) -> void { stat(); if(status.dma_active) { uint hi = status.dma_clock++; - uint lo = hi & (cpu.status.speed_double ? 1 : 3); - hi >>= cpu.status.speed_double ? 1 : 2; + uint lo = hi & (cpu.status.speedDouble ? 1 : 3); + hi >>= cpu.status.speedDouble ? 1 : 2; if(lo == 0) { if(hi == 0) { //warm-up diff --git a/higan/gb/ppu/ppu.hpp b/higan/gb/ppu/ppu.hpp index af143591..89b55e6b 100644 --- a/higan/gb/ppu/ppu.hpp +++ b/higan/gb/ppu/ppu.hpp @@ -13,8 +13,8 @@ struct PPU : Thread, MMIO { //mmio.cpp auto vram_addr(uint16 addr) const -> uint; - auto mmio_read(uint16 addr) -> uint8; - auto mmio_write(uint16 addr, uint8 data) -> void; + auto readIO(uint16 addr) -> uint8; + auto writeIO(uint16 addr, uint8 data) -> void; //dmg.cpp auto dmg_read_tile(bool select, uint x, uint y, uint& data) -> void; diff --git a/higan/processor/arm/registers.hpp b/higan/processor/arm/registers.hpp index 3e1bd88c..309b9f84 100644 --- a/higan/processor/arm/registers.hpp +++ b/higan/processor/arm/registers.hpp @@ -21,14 +21,14 @@ struct GPR { struct PSR { union { uint32_t data = 0; - BitField n; //negative - BitField z; //zero - BitField c; //carry - BitField v; //overflow - BitField i; //irq - BitField f; //fiq - BitField t; //thumb - BitField m; //mode + BooleanBitField n; //negative + BooleanBitField z; //zero + BooleanBitField c; //carry + BooleanBitField v; //overflow + BooleanBitField i; //irq + BooleanBitField f; //fiq + BooleanBitField t; //thumb + NaturalBitField m; //mode }; PSR() = default; diff --git a/higan/processor/gsu/registers.hpp b/higan/processor/gsu/registers.hpp index 754b48e1..44ad9100 100644 --- a/higan/processor/gsu/registers.hpp +++ b/higan/processor/gsu/registers.hpp @@ -36,19 +36,19 @@ struct Register { struct SFR { union { uint16_t data = 0; - BitField irq; //interrupt flag - BitField b; //with flag - BitField ih; //immediate higher 8-bit flag - BitField il; //immediate lower 8-bit flag - BitField alt2; //alt2 instruction mode - BitField alt1; //alt1 instruction mode - BitField r; //ROM r14 read flag - BitField g; //go flag - BitField ov; //overflow flag - BitField s; //sign flag - BitField cy; //carry flag - BitField z; //zero flag - BitField alt; //instruction mode (composite flag) + BooleanBitField irq; //interrupt flag + BooleanBitField b; //with flag + BooleanBitField ih; //immediate higher 8-bit flag + BooleanBitField il; //immediate lower 8-bit flag + BooleanBitField alt2; //alt2 instruction mode + BooleanBitField alt1; //alt1 instruction mode + BooleanBitField r; //ROM r14 read flag + BooleanBitField g; //go flag + BooleanBitField ov; //overflow flag + BooleanBitField s; //sign flag + BooleanBitField cy; //carry flag + BooleanBitField z; //zero flag + NaturalBitField alt; //instruction mode (composite flag) }; inline operator uint() const { return data & 0x9f7e; } diff --git a/higan/processor/r6502/registers.hpp b/higan/processor/r6502/registers.hpp index 23ab5ae2..9389faad 100644 --- a/higan/processor/r6502/registers.hpp +++ b/higan/processor/r6502/registers.hpp @@ -1,12 +1,12 @@ struct Flags { union { uint8_t data = 0; - BitField n; - BitField v; - BitField d; - BitField i; - BitField z; - BitField c; + BooleanBitField n; + BooleanBitField v; + BooleanBitField d; + BooleanBitField i; + BooleanBitField z; + BooleanBitField c; }; inline operator uint() { return data; } @@ -26,8 +26,8 @@ struct Registers { struct Register16 { union { uint16_t w; - BitField l; - BitField h; + NaturalBitField l; + NaturalBitField h; }; } abs, iabs; diff --git a/higan/processor/r65816/disassembler.cpp b/higan/processor/r65816/disassembler.cpp index c5fbdb2b..f118b2a2 100644 --- a/higan/processor/r65816/disassembler.cpp +++ b/higan/processor/r65816/disassembler.cpp @@ -4,7 +4,7 @@ auto R65816::dreadb(uint24 addr) -> uint8 { //do not read MMIO registers within debugger return 0x00; } - return disassemblerRead(addr); + return readDisassembler(addr); } auto R65816::dreadw(uint24 addr) -> uint16 { diff --git a/higan/processor/r65816/opcode_misc.cpp b/higan/processor/r65816/instructions-misc.cpp similarity index 100% rename from higan/processor/r65816/opcode_misc.cpp rename to higan/processor/r65816/instructions-misc.cpp diff --git a/higan/processor/r65816/opcode_pc.cpp b/higan/processor/r65816/instructions-pc.cpp similarity index 100% rename from higan/processor/r65816/opcode_pc.cpp rename to higan/processor/r65816/instructions-pc.cpp diff --git a/higan/processor/r65816/opcode_read.cpp b/higan/processor/r65816/instructions-read.cpp similarity index 100% rename from higan/processor/r65816/opcode_read.cpp rename to higan/processor/r65816/instructions-read.cpp diff --git a/higan/processor/r65816/opcode_rmw.cpp b/higan/processor/r65816/instructions-rmw.cpp similarity index 100% rename from higan/processor/r65816/opcode_rmw.cpp rename to higan/processor/r65816/instructions-rmw.cpp diff --git a/higan/processor/r65816/opcode_write.cpp b/higan/processor/r65816/instructions-write.cpp similarity index 100% rename from higan/processor/r65816/opcode_write.cpp rename to higan/processor/r65816/instructions-write.cpp diff --git a/higan/processor/r65816/r65816.cpp b/higan/processor/r65816/r65816.cpp index d4117b73..bd3a95d9 100644 --- a/higan/processor/r65816/r65816.cpp +++ b/higan/processor/r65816/r65816.cpp @@ -12,11 +12,11 @@ namespace Processor { #define L lastCycle(); #define call(op) (this->*op)() -#include "opcode_read.cpp" -#include "opcode_write.cpp" -#include "opcode_rmw.cpp" -#include "opcode_pc.cpp" -#include "opcode_misc.cpp" +#include "instructions-read.cpp" +#include "instructions-write.cpp" +#include "instructions-rmw.cpp" +#include "instructions-pc.cpp" +#include "instructions-misc.cpp" #include "switch.cpp" //immediate, 2-cycle opcodes with I/O cycle will become bus read diff --git a/higan/processor/r65816/r65816.hpp b/higan/processor/r65816/r65816.hpp index 1c2809c2..f9f8cb53 100644 --- a/higan/processor/r65816/r65816.hpp +++ b/higan/processor/r65816/r65816.hpp @@ -20,7 +20,7 @@ struct R65816 { virtual auto interruptPending() const -> bool = 0; virtual auto interrupt() -> void; - virtual auto disassemblerRead(uint24 addr) -> uint8 { return 0; } + virtual auto readDisassembler(uint24 addr) -> uint8 { return 0; } //r65816.cpp alwaysinline auto ioIRQ() -> void; diff --git a/higan/processor/r65816/registers.hpp b/higan/processor/r65816/registers.hpp index 2c296be0..2d9baff8 100644 --- a/higan/processor/r65816/registers.hpp +++ b/higan/processor/r65816/registers.hpp @@ -1,14 +1,14 @@ struct Flags { union { uint8_t b = 0; - BitField n; - BitField v; - BitField m; - BitField x; - BitField d; - BitField i; - BitField z; - BitField c; + BooleanBitField n; + BooleanBitField v; + BooleanBitField m; + BooleanBitField x; + BooleanBitField d; + BooleanBitField i; + BooleanBitField z; + BooleanBitField c; }; inline operator uint() const { return b; } @@ -20,8 +20,8 @@ struct Flags { struct Reg16 { union { uint16_t w = 0; - BitField l; - BitField h; + NaturalBitField l; + NaturalBitField h; }; inline operator uint() const { return w; } @@ -41,10 +41,10 @@ struct Reg16 { struct Reg24 { union { uint32_t d = 0; - BitField l; - BitField h; - BitField b; - BitField w; + NaturalBitField l; + NaturalBitField h; + NaturalBitField b; + NaturalBitField w; }; inline operator uint() const { return d; } diff --git a/higan/processor/spc700/disassembler.cpp b/higan/processor/spc700/disassembler.cpp index 0440bec1..96cef88c 100644 --- a/higan/processor/spc700/disassembler.cpp +++ b/higan/processor/spc700/disassembler.cpp @@ -1,6 +1,6 @@ auto SPC700::disassemble(uint16 addr, bool p) -> string { auto read = [&](uint16 addr) -> uint8 { - return disassemblerRead(addr); + return readDisassembler(addr); }; auto relative = [&](uint length, int8 offset) -> uint16 { diff --git a/higan/processor/spc700/registers.hpp b/higan/processor/spc700/registers.hpp index ed224869..622cd43c 100644 --- a/higan/processor/spc700/registers.hpp +++ b/higan/processor/spc700/registers.hpp @@ -1,14 +1,14 @@ struct Flags { union { uint8_t data = 0; - BitField n; - BitField v; - BitField p; - BitField b; - BitField h; - BitField i; - BitField z; - BitField c; + BooleanBitField n; + BooleanBitField v; + BooleanBitField p; + BooleanBitField b; + BooleanBitField h; + BooleanBitField i; + BooleanBitField z; + BooleanBitField c; }; inline operator uint() const { return data; } @@ -21,8 +21,8 @@ struct Flags { struct Register { union { uint16_t w = 0; - BitField l; - BitField h; + NaturalBitField l; + NaturalBitField h; }; inline operator uint() const { return w; } diff --git a/higan/processor/spc700/spc700.hpp b/higan/processor/spc700/spc700.hpp index e2d0de3c..2a1de917 100644 --- a/higan/processor/spc700/spc700.hpp +++ b/higan/processor/spc700/spc700.hpp @@ -6,7 +6,7 @@ struct SPC700 { virtual auto io() -> void = 0; virtual auto read(uint16 addr) -> uint8 = 0; virtual auto write(uint16 addr, uint8 data) -> void = 0; - virtual auto disassemblerRead(uint16 addr) -> uint8 = 0; + virtual auto readDisassembler(uint16 addr) -> uint8 = 0; auto instruction() -> void; diff --git a/higan/processor/upd96050/upd96050.hpp b/higan/processor/upd96050/upd96050.hpp index 97a7e608..c6d0da96 100644 --- a/higan/processor/upd96050/upd96050.hpp +++ b/higan/processor/upd96050/upd96050.hpp @@ -35,12 +35,12 @@ struct uPD96050 { struct Flag { union { uint8_t data = 0; - BitField s1; - BitField s0; - BitField c; - BitField z; - BitField ov1; - BitField ov0; + BooleanBitField s1; + BooleanBitField s0; + BooleanBitField c; + BooleanBitField z; + BooleanBitField ov1; + BooleanBitField ov0; }; inline operator uint() const { return data & 0x3f; } @@ -51,17 +51,17 @@ struct uPD96050 { struct Status { union { uint16_t data = 0; - BitField rqm; - BitField usf1; - BitField usf0; - BitField drs; - BitField dma; - BitField drc; - BitField soc; - BitField sic; - BitField ei; - BitField p1; - BitField p0; + BooleanBitField rqm; + BooleanBitField usf1; + BooleanBitField usf0; + BooleanBitField drs; + BooleanBitField dma; + BooleanBitField drc; + BooleanBitField soc; + BooleanBitField sic; + BooleanBitField ei; + BooleanBitField p1; + BooleanBitField p0; }; inline operator uint() const { return data & 0xff83; } diff --git a/higan/processor/v30mz/v30mz.hpp b/higan/processor/v30mz/v30mz.hpp index 1da6f2e2..af733da7 100644 --- a/higan/processor/v30mz/v30mz.hpp +++ b/higan/processor/v30mz/v30mz.hpp @@ -249,16 +249,16 @@ struct V30MZ { struct Flags { union { uint16_t data = 0; - BitField m; //mode - BitField v; //overflow - BitField d; //direction - BitField i; //interrupt - BitField b; //break - BitField s; //sign - BitField z; //zero - BitField h; //half-carry - BitField p; //parity - BitField c; //carry + BooleanBitField m; //mode + BooleanBitField v; //overflow + BooleanBitField d; //direction + BooleanBitField i; //interrupt + BooleanBitField b; //break + BooleanBitField s; //sign + BooleanBitField z; //zero + BooleanBitField h; //half-carry + BooleanBitField p; //parity + BooleanBitField c; //carry }; operator uint() const { return data & 0x8fd5 | 0x7002; } diff --git a/higan/sfc/coprocessor/icd2/interface.cpp b/higan/sfc/coprocessor/icd2/interface.cpp index be5ed908..a4ca83c6 100644 --- a/higan/sfc/coprocessor/icd2/interface.cpp +++ b/higan/sfc/coprocessor/icd2/interface.cpp @@ -104,7 +104,7 @@ auto ICD2::audioSample(const double* samples, uint channels) -> void { } auto ICD2::inputPoll(uint port, uint device, uint id) -> int16 { - GameBoy::cpu.status.mlt_req = joypID & mltReq; + GameBoy::cpu.status.mltReq = joypID & mltReq; uint data = 0x00; switch(joypID & mltReq) { diff --git a/higan/sfc/cpu/cpu.cpp b/higan/sfc/cpu/cpu.cpp index 6521a590..061481c3 100644 --- a/higan/sfc/cpu/cpu.cpp +++ b/higan/sfc/cpu/cpu.cpp @@ -62,12 +62,10 @@ auto CPU::main() -> void { status.nmiPending = false; r.vector = r.e ? 0xfffa : 0xffea; interrupt(); - debugger.nmi(); } else if(status.irqPending) { status.irqPending = false; r.vector = r.e ? 0xfffe : 0xffee; interrupt(); - debugger.irq(); } else if(status.resetPending) { status.resetPending = false; addClocks(132); @@ -81,7 +79,6 @@ auto CPU::main() -> void { } } - debugger.execute(r.pc.d); instruction(); } diff --git a/higan/sfc/cpu/cpu.hpp b/higan/sfc/cpu/cpu.hpp index 5c9bddf0..eefaab9e 100644 --- a/higan/sfc/cpu/cpu.hpp +++ b/higan/sfc/cpu/cpu.hpp @@ -50,7 +50,7 @@ struct CPU : Processor::R65816, Thread, PPUcounter { auto read(uint24 addr) -> uint8 override; auto write(uint24 addr, uint8 data) -> void override; alwaysinline auto speed(uint24 addr) const -> uint; - auto disassemblerRead(uint24 addr) -> uint8 override; + auto readDisassembler(uint24 addr) -> uint8 override; //mmio.cpp auto readAPU(uint24 addr, uint8 data) -> uint8; @@ -244,14 +244,6 @@ privileged: uint addr; uint8 data; } pipe; - - struct Debugger { - hook void> execute; - hook void> read; - hook void> write; - hook void> nmi; - hook void> irq; - } debugger; }; extern CPU cpu; diff --git a/higan/sfc/cpu/memory.cpp b/higan/sfc/cpu/memory.cpp index d9097a07..0f98b9c0 100644 --- a/higan/sfc/cpu/memory.cpp +++ b/higan/sfc/cpu/memory.cpp @@ -20,7 +20,6 @@ auto CPU::read(uint24 addr) -> uint8 { r.mdr = bus.read(addr, r.mdr); addClocks(4); aluEdge(); - debugger.read(addr, r.mdr); return r.mdr; } @@ -30,7 +29,6 @@ auto CPU::write(uint24 addr, uint8 data) -> void { dmaEdge(); addClocks(status.clockCount); bus.write(addr, r.mdr = data); - debugger.write(addr, r.mdr); } auto CPU::speed(uint24 addr) const -> uint { @@ -43,6 +41,6 @@ auto CPU::speed(uint24 addr) const -> uint { return 12; } -auto CPU::disassemblerRead(uint24 addr) -> uint8 { +auto CPU::readDisassembler(uint24 addr) -> uint8 { return bus.read(addr, r.mdr); } diff --git a/higan/sfc/cpu/mmio.cpp b/higan/sfc/cpu/mmio.cpp index c0692c71..efc9f6bc 100644 --- a/higan/sfc/cpu/mmio.cpp +++ b/higan/sfc/cpu/mmio.cpp @@ -1,6 +1,6 @@ auto CPU::readAPU(uint24 addr, uint8 data) -> uint8 { synchronizeSMP(); - return smp.portRead(addr.bits(0,1)); + return smp.readPort(addr.bits(0,1)); } auto CPU::readCPU(uint24 addr, uint8 data) -> uint8 { diff --git a/higan/sfc/ppu/memory.cpp b/higan/sfc/ppu/memory.cpp deleted file mode 100644 index d47dbff9..00000000 --- a/higan/sfc/ppu/memory.cpp +++ /dev/null @@ -1,49 +0,0 @@ -auto PPU::getVramAddress() -> uint16 { - uint16 address = r.vramAddress; - switch(r.vramMapping) { - case 0: return (address); - case 1: return (address & 0xff00) | ((address & 0x001f) << 3) | ((address >> 5) & 7); - case 2: return (address & 0xfe00) | ((address & 0x003f) << 3) | ((address >> 6) & 7); - case 3: return (address & 0xfc00) | ((address & 0x007f) << 3) | ((address >> 7) & 7); - } - unreachable; -} - -auto PPU::vramRead(bool chip, uint addr) -> uint8 { - uint8 data = 0x00; - if(r.displayDisable || vcounter() >= vdisp()) { - data = vram[addr].byte(chip); - debugger.vramRead(addr << 1 | chip, data); - } - return data; -} - -auto PPU::vramWrite(bool chip, uint addr, uint8 data) -> void { - if(r.displayDisable || vcounter() >= vdisp()) { - vram[addr].byte(chip) = data; - debugger.vramWrite(addr << 1 | chip, data); - } -} - -auto PPU::oamRead(uint addr) -> uint8 { - uint8 data = oam[addr]; - debugger.oamRead(addr, data); - return data; -} - -auto PPU::oamWrite(uint addr, uint8 data) -> void { - oam[addr] = data; - obj.update(addr, data); - debugger.oamWrite(addr, data); -} - -auto PPU::cgramRead(uint addr) -> uint8 { - uint8 data = cgram[addr]; - debugger.cgramRead(addr, data); - return data; -} - -auto PPU::cgramWrite(uint addr, uint8 data) -> void { - cgram[addr] = data; - debugger.cgramWrite(addr, data); -} diff --git a/higan/sfc/ppu/mmio.cpp b/higan/sfc/ppu/mmio.cpp index 35dff131..1b192468 100644 --- a/higan/sfc/ppu/mmio.cpp +++ b/higan/sfc/ppu/mmio.cpp @@ -1,4 +1,24 @@ -auto PPU::read(uint24 addr, uint8 data) -> uint8 { +auto PPU::getVramAddress() -> uint16 { + uint16 address = r.vramAddress; + switch(r.vramMapping) { + case 0: return (address); + case 1: return (address & 0xff00) | ((address & 0x001f) << 3) | ((address >> 5) & 7); + case 2: return (address & 0xfe00) | ((address & 0x003f) << 3) | ((address >> 6) & 7); + case 3: return (address & 0xfc00) | ((address & 0x007f) << 3) | ((address >> 7) & 7); + } + unreachable; +} + +auto PPU::vramAccessible() const -> bool { + return r.displayDisable || vcounter() >= vdisp(); +} + +auto PPU::oamWrite(uint addr, uint8 data) -> void { + oam[addr] = data; + obj.update(addr, data); +} + +auto PPU::readIO(uint24 addr, uint8 data) -> uint8 { cpu.synchronizePPU(); switch((uint16)addr) { @@ -44,18 +64,16 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 { if(!r.displayDisable && vcounter() < vdisp()) address = latch.oamAddress; if(address & 0x0200) address &= 0x021f; - ppu1.mdr = oamRead(address); + ppu1.mdr = oam[address]; obj.setFirstSprite(); return ppu1.mdr; } //VMDATALREAD case 0x2139: { - auto address = getVramAddress(); ppu1.mdr = latch.vram >> 0; if(r.vramIncrementMode == 0) { - latch.vram.byte(0) = vramRead(0, address); - latch.vram.byte(1) = vramRead(1, address); + latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; r.vramAddress += r.vramIncrementSize; } return ppu1.mdr; @@ -63,11 +81,9 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 { //VMDATAHREAD case 0x213a: { - uint16 address = getVramAddress(); ppu1.mdr = latch.vram >> 8; if(r.vramIncrementMode == 1) { - latch.vram.byte(0) = vramRead(0, address); - latch.vram.byte(1) = vramRead(1, address); + latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; r.vramAddress += r.vramIncrementSize; } return ppu1.mdr; @@ -75,18 +91,17 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 { //CGDATAREAD case 0x213b: { - bool l = r.cgramAddress & 1; - uint9 address = r.cgramAddress++; + auto address = r.cgramAddress; if(!r.displayDisable && vcounter() > 0 && vcounter() < vdisp() && hcounter() >= 88 && hcounter() < 1096 ) address = latch.cgramAddress; - if(l == 0) { - ppu2.mdr = cgramRead(address); + if(r.cgramAddressLatch++) { + ppu2.mdr = cgram[address].byte(0); } else { ppu2.mdr &= 0x80; - ppu2.mdr |= cgramRead(address); + ppu2.mdr |= cgram[address].byte(1); } return ppu2.mdr; } @@ -147,7 +162,7 @@ auto PPU::read(uint24 addr, uint8 data) -> uint8 { return data; } -auto PPU::write(uint24 addr, uint8 data) -> void { +auto PPU::writeIO(uint24 addr, uint8 data) -> void { cpu.synchronizePPU(); switch((uint16)addr) { @@ -342,36 +357,28 @@ auto PPU::write(uint24 addr, uint8 data) -> void { //VMADDL case 0x2116: { - r.vramAddress &= 0xff00; - r.vramAddress |= (data << 0); - auto address = getVramAddress(); - latch.vram.byte(0) = vramRead(0, address); - latch.vram.byte(1) = vramRead(1, address); + r.vramAddress.byte(0) = data; + latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; return; } //VMADDH case 0x2117: { - r.vramAddress &= 0x00ff; - r.vramAddress |= (data << 8); - auto address = getVramAddress(); - latch.vram.byte(0) = vramRead(0, address); - latch.vram.byte(1) = vramRead(1, address); + r.vramAddress.byte(1) = data; + latch.vram = vramAccessible() ? vram[getVramAddress()] : (uint16)0; return; } //VMDATAL case 0x2118: { - auto address = getVramAddress(); - vramWrite(0, address, data); + if(vramAccessible()) vram[getVramAddress()].byte(0) = data; if(r.vramIncrementMode == 0) r.vramAddress += r.vramIncrementSize; return; } //VMDATAH case 0x2119: { - auto address = getVramAddress(); - vramWrite(1, address, data); + if(vramAccessible()) vram[getVramAddress()].byte(1) = data; if(r.vramIncrementMode == 1) r.vramAddress += r.vramIncrementSize; return; } @@ -428,24 +435,24 @@ auto PPU::write(uint24 addr, uint8 data) -> void { //CGADD case 0x2121: { - r.cgramAddress = data << 1; + r.cgramAddress = data; + r.cgramAddressLatch = 0; return; } //CGDATA case 0x2122: { - bool l = r.cgramAddress & 1; - uint9 address = r.cgramAddress++; + auto address = r.cgramAddress; if(!r.displayDisable && vcounter() > 0 && vcounter() < vdisp() && hcounter() >= 88 && hcounter() < 1096 ) address = latch.cgramAddress; - if(l == 0) { + if(r.cgramAddressLatch++ == 0) { latch.cgram = data; } else { - cgramWrite((address & ~1) + 0, latch.cgram); - cgramWrite((address & ~1) + 1, data & 0x7f); + cgram[address] = data.bits(0,6) << 8 | latch.cgram; + r.cgramAddress++; } return; } diff --git a/higan/sfc/ppu/ppu.cpp b/higan/sfc/ppu/ppu.cpp index a5ce3b35..9f14a632 100644 --- a/higan/sfc/ppu/ppu.cpp +++ b/higan/sfc/ppu/ppu.cpp @@ -4,7 +4,6 @@ namespace SuperFamicom { PPU ppu; -#include "memory.cpp" #include "mmio.cpp" #include "background/background.cpp" #include "object/object.cpp" @@ -97,8 +96,8 @@ auto PPU::load(Markup::Node node) -> bool { auto PPU::power() -> void { for(auto& n : vram.data) n = random(0x0000); - for(auto& n : oam) n = random(0x00); - for(auto& n : cgram) n = random(0x00); + for(auto& n : oam.data) n = random(0x00); + for(auto& n : cgram.data) n = random(0x0000); } auto PPU::reset() -> void { @@ -106,8 +105,8 @@ auto PPU::reset() -> void { PPUcounter::reset(); memory::fill(output, 512 * 480 * sizeof(uint32)); - function uint8> reader{&PPU::read, this}; - function void> writer{&PPU::write, this}; + function uint8> reader{&PPU::readIO, this}; + function void> writer{&PPU::writeIO, this}; bus.map(reader, writer, "00-3f,80-bf:2100-213f"); ppu1.mdr = random(0xff); @@ -178,7 +177,8 @@ auto PPU::reset() -> void { r.m7y = random(0x0000); //$2121 CGADD - r.cgramAddress = random(0x0000); + r.cgramAddress = random(0x00); + r.cgramAddressLatch = random(0); //$2133 SETINI r.extbg = random(false); diff --git a/higan/sfc/ppu/ppu.hpp b/higan/sfc/ppu/ppu.hpp index ce068db2..e9173b2c 100644 --- a/higan/sfc/ppu/ppu.hpp +++ b/higan/sfc/ppu/ppu.hpp @@ -17,18 +17,12 @@ struct PPU : Thread, PPUcounter { auto serialize(serializer&) -> void; - //memory.cpp - alwaysinline auto getVramAddress() -> uint16; - alwaysinline auto vramRead(bool chip, uint addr) -> uint8; - alwaysinline auto vramWrite(bool chip, uint addr, uint8 data) -> void; - alwaysinline auto oamRead(uint addr) -> uint8; - alwaysinline auto oamWrite(uint addr, uint8 data) -> void; - alwaysinline auto cgramRead(uint addr) -> uint8; - alwaysinline auto cgramWrite(uint addr, uint8 data) -> void; - //mmio.cpp - auto read(uint24 addr, uint8 data) -> uint8; - auto write(uint24 addr, uint8 data) -> void; + alwaysinline auto getVramAddress() -> uint16; + alwaysinline auto vramAccessible() const -> bool; + alwaysinline auto oamWrite(uint addr, uint8 data) -> void; + auto readIO(uint24 addr, uint8 data) -> uint8; + auto writeIO(uint24 addr, uint8 data) -> void; auto latchCounters() -> void; auto updateVideoMode() -> void; @@ -38,8 +32,16 @@ privileged: uint16 data[64 * 1024]; uint mask = 0x7fff; } vram; - uint8 oam[544]; - uint8 cgram[512]; + + struct OAM { + auto& operator[](uint offset) { return data[offset]; } + uint8 data[544]; + } oam; + + struct CGRAM { + auto& operator[](uint8 offset) { return data[offset]; } + uint15 data[256]; + } cgram; uint32* output = nullptr; @@ -70,7 +72,7 @@ privileged: bool vcounter; uint10 oamAddress; - uint9 cgramAddress; + uint8 cgramAddress; } latch; struct Registers { @@ -127,7 +129,8 @@ privileged: uint16 m7y; //$2121 CGADD - uint9 cgramAddress; + uint8 cgramAddress; + uint1 cgramAddressLatch; //$2133 SETINI bool extbg; @@ -160,15 +163,6 @@ privileged: friend class PPU::Window; friend class PPU::Screen; friend class Scheduler; - - struct Debugger { - hook void> vramRead; - hook void> oamRead; - hook void> cgramRead; - hook void> vramWrite; - hook void> oamWrite; - hook void> cgramWrite; - } debugger; }; extern PPU ppu; diff --git a/higan/sfc/ppu/screen/screen.cpp b/higan/sfc/ppu/screen/screen.cpp index ce8802d5..b19daff5 100644 --- a/higan/sfc/ppu/screen/screen.cpp +++ b/higan/sfc/ppu/screen/screen.cpp @@ -58,10 +58,10 @@ auto PPU::Screen::below(bool hires) -> uint16 { if(math.transparent = (priority == 0)) math.below.color = paletteColor(0); if(!hires) return 0; - if(!math.below.colorEnable) return math.above.colorEnable ? math.below.color : (uint16)0; + if(!math.below.colorEnable) return math.above.colorEnable ? math.below.color : (uint15)0; return blend( - math.above.colorEnable ? math.below.color : (uint16)0, + math.above.colorEnable ? math.below.color : (uint15)0, math.blendMode ? math.above.color : fixedColor() ); } @@ -106,7 +106,7 @@ auto PPU::Screen::above() -> uint16 { if(!ppu.window.output.below.colorEnable) math.below.colorEnable = false; math.above.colorEnable = ppu.window.output.above.colorEnable; - if(!math.below.colorEnable) return math.above.colorEnable ? math.above.color : (uint16)0; + if(!math.below.colorEnable) return math.above.colorEnable ? math.above.color : (uint15)0; if(r.blendMode && math.transparent) { math.blendMode = false; @@ -117,12 +117,12 @@ auto PPU::Screen::above() -> uint16 { } return blend( - math.above.colorEnable ? math.above.color : (uint16)0, + math.above.colorEnable ? math.above.color : (uint15)0, math.blendMode ? math.below.color : fixedColor() ); } -auto PPU::Screen::blend(uint x, uint y) const -> uint16 { +auto PPU::Screen::blend(uint x, uint y) const -> uint15 { if(!r.colorMode) { if(!math.colorHalve) { uint sum = x + y; @@ -142,13 +142,12 @@ auto PPU::Screen::blend(uint x, uint y) const -> uint16 { } } -auto PPU::Screen::paletteColor(uint palette) const -> uint16 { - palette <<= 1; +auto PPU::Screen::paletteColor(uint8 palette) const -> uint15 { ppu.latch.cgramAddress = palette; - return ppu.cgram[palette + 0] << 0 | ppu.cgram[palette + 1] << 8; + return ppu.cgram[palette]; } -auto PPU::Screen::directColor(uint palette, uint tile) const -> uint16 { +auto PPU::Screen::directColor(uint palette, uint tile) const -> uint15 { //palette = -------- BBGGGRRR //tile = ---bgr-- -------- //output = 0BBb00GG Gg0RRRr0 @@ -157,7 +156,7 @@ auto PPU::Screen::directColor(uint palette, uint tile) const -> uint16 { + ((palette << 2) & 0x001c) + ((tile >> 9) & 0x0002); } -auto PPU::Screen::fixedColor() const -> uint16 { +auto PPU::Screen::fixedColor() const -> uint15 { return r.colorBlue << 10 | r.colorGreen << 5 | r.colorRed << 0; } diff --git a/higan/sfc/ppu/screen/screen.hpp b/higan/sfc/ppu/screen/screen.hpp index c515c3c7..9df1663a 100644 --- a/higan/sfc/ppu/screen/screen.hpp +++ b/higan/sfc/ppu/screen/screen.hpp @@ -6,10 +6,10 @@ struct Screen { auto below(bool hires) -> uint16; auto above() -> uint16; - auto blend(uint x, uint y) const -> uint16; - alwaysinline auto paletteColor(uint palette) const -> uint16; - alwaysinline auto directColor(uint palette, uint tile) const -> uint16; - alwaysinline auto fixedColor() const -> uint16; + auto blend(uint x, uint y) const -> uint15; + alwaysinline auto paletteColor(uint8 palette) const -> uint15; + alwaysinline auto directColor(uint palette, uint tile) const -> uint15; + alwaysinline auto fixedColor() const -> uint15; auto serialize(serializer&) -> void; @@ -33,7 +33,7 @@ struct Screen { struct Math { struct Screen { - uint16 color; + uint15 color; bool colorEnable; } above, below; bool transparent; diff --git a/higan/sfc/ppu/serialization.cpp b/higan/sfc/ppu/serialization.cpp index f37a29e7..9f6a99d6 100644 --- a/higan/sfc/ppu/serialization.cpp +++ b/higan/sfc/ppu/serialization.cpp @@ -16,8 +16,8 @@ auto PPU::serialize(serializer& s) -> void { s.integer(vram.mask); s.array(vram.data, vram.mask + 1); - s.array(oam); - s.array(cgram); + s.array(oam.data); + s.array(cgram.data); s.integer(ppu1.version); s.integer(ppu1.mdr); @@ -71,6 +71,7 @@ auto PPU::serialize(serializer& s) -> void { s.integer(r.m7y); s.integer(r.cgramAddress); + s.integer(r.cgramAddressLatch); s.integer(r.extbg); s.integer(r.pseudoHires); diff --git a/higan/sfc/smp/memory.cpp b/higan/sfc/smp/memory.cpp index 19ebf54e..d822c129 100644 --- a/higan/sfc/smp/memory.cpp +++ b/higan/sfc/smp/memory.cpp @@ -1,23 +1,23 @@ -alwaysinline auto SMP::ramRead(uint16 addr) -> uint8 { +alwaysinline auto SMP::readRAM(uint16 addr) -> uint8 { if(addr >= 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; if(status.ramDisable) return 0x5a; //0xff on mini-SNES return apuram[addr]; } -alwaysinline auto SMP::ramWrite(uint16 addr, uint8 data) -> void { +alwaysinline auto SMP::writeRAM(uint16 addr, uint8 data) -> void { //writes to $ffc0-$ffff always go to apuram, even if the iplrom is enabled if(status.ramWritable && !status.ramDisable) apuram[addr] = data; } -auto SMP::portRead(uint2 port) const -> uint8 { +auto SMP::readPort(uint2 port) const -> uint8 { return apuram[0xf4 + port]; } -auto SMP::portWrite(uint2 port, uint8 data) -> void { +auto SMP::writePort(uint2 port, uint8 data) -> void { apuram[0xf4 + port] = data; } -auto SMP::busRead(uint16 addr) -> uint8 { +auto SMP::readBus(uint16 addr) -> uint8 { uint result; switch(addr) { @@ -68,10 +68,10 @@ auto SMP::busRead(uint16 addr) -> uint8 { return result; } - return ramRead(addr); + return readRAM(addr); } -auto SMP::busWrite(uint16 addr, uint8 data) -> void { +auto SMP::writeBus(uint16 addr, uint8 data) -> void { switch(addr) { case 0xf0: //TEST if(regs.p.p) break; //writes only valid when P flag is clear @@ -141,7 +141,7 @@ auto SMP::busWrite(uint16 addr, uint8 data) -> void { case 0xf6: //CPUIO2 case 0xf7: //CPUIO3 synchronizeCPU(); - portWrite(addr, data); + writePort(addr, data); break; case 0xf8: //RAM0 @@ -170,7 +170,7 @@ auto SMP::busWrite(uint16 addr, uint8 data) -> void { break; } - ramWrite(addr, data); //all writes, even to MMIO registers, appear on bus + writeRAM(addr, data); //all writes, even to MMIO registers, appear on bus } auto SMP::io() -> void { @@ -180,21 +180,19 @@ auto SMP::io() -> void { auto SMP::read(uint16 addr) -> uint8 { addClocks(12); - uint8 data = busRead(addr); + uint8 data = readBus(addr); addClocks(12); cycleEdge(); - debugger.read(addr, data); return data; } auto SMP::write(uint16 addr, uint8 data) -> void { addClocks(24); - busWrite(addr, data); + writeBus(addr, data); cycleEdge(); - debugger.write(addr, data); } -auto SMP::disassemblerRead(uint16 addr) -> uint8 { +auto SMP::readDisassembler(uint16 addr) -> uint8 { if((addr & 0xfff0) == 0x00f0) return 0x00; if((addr & 0xffc0) == 0xffc0 && status.iplromEnable) return iplrom[addr & 0x3f]; return apuram[addr]; diff --git a/higan/sfc/smp/smp.cpp b/higan/sfc/smp/smp.cpp index c144f76b..15340284 100644 --- a/higan/sfc/smp/smp.cpp +++ b/higan/sfc/smp/smp.cpp @@ -26,7 +26,6 @@ auto SMP::Enter() -> void { } auto SMP::main() -> void { - debugger.execute(regs.pc); instruction(); } diff --git a/higan/sfc/smp/smp.hpp b/higan/sfc/smp/smp.hpp index 8dbbc4df..d24a2160 100644 --- a/higan/sfc/smp/smp.hpp +++ b/higan/sfc/smp/smp.hpp @@ -5,8 +5,8 @@ struct SMP : Processor::SPC700, Thread { alwaysinline auto synchronizeCPU() -> void; alwaysinline auto synchronizeDSP() -> void; - auto portRead(uint2 port) const -> uint8; - auto portWrite(uint2 port, uint8 data) -> void; + auto readPort(uint2 port) const -> uint8; + auto writePort(uint2 port, uint8 data) -> void; auto main() -> void; auto load(Markup::Node) -> bool; @@ -46,24 +46,18 @@ privileged: static auto Enter() -> void; - struct Debugger { - hook void> execute; - hook void> read; - hook void> write; - } debugger; - //memory.cpp - auto ramRead(uint16 addr) -> uint8; - auto ramWrite(uint16 addr, uint8 data) -> void; + auto readRAM(uint16 addr) -> uint8; + auto writeRAM(uint16 addr, uint8 data) -> void; - auto busRead(uint16 addr) -> uint8; - auto busWrite(uint16 addr, uint8 data) -> void; + auto readBus(uint16 addr) -> uint8; + auto writeBus(uint16 addr, uint8 data) -> void; auto io() -> void override; auto read(uint16 addr) -> uint8 override; auto write(uint16 addr, uint8 data) -> void override; - auto disassemblerRead(uint16 addr) -> uint8 override; + auto readDisassembler(uint16 addr) -> uint8 override; //timing.cpp template diff --git a/nall/bit-field.hpp b/nall/bit-field.hpp index 43814159..85ac5a62 100644 --- a/nall/bit-field.hpp +++ b/nall/bit-field.hpp @@ -2,67 +2,21 @@ namespace nall { -template struct BitFieldReference { - BitFieldReference(type& data, uint lo, uint hi) - : data(data), lo(lo), hi(hi), bits(hi + lo - 1), mask((~0ull >> (64 - bits)) << lo) { - } - - inline explicit operator bool() const { return data & mask; } - inline operator type() const { return get(); } - - inline auto& operator=(const BitFieldReference& value) { return set(value.data); } - template inline auto& operator=(const T& value) { return set(value << lo); } - - inline auto operator++(int) { type value = get(); set(data + (1 << lo)); return value; } - inline auto operator--(int) { type value = get(); set(data - (1 << lo)); return value; } - - inline auto& operator++() { return set(data + (1 << lo)); } - inline auto& operator--() { return set(data - (1 << lo)); } - - inline auto& operator &=(const type value) { return set(data & (value << lo)); } - inline auto& operator |=(const type value) { return set(data | (value << lo)); } - inline auto& operator ^=(const type value) { return set(data ^ (value << lo)); } - inline auto& operator<<=(const type value) { return set((data & mask) << value); } - inline auto& operator>>=(const type value) { return set((data & mask) >> value); } - inline auto& operator +=(const type value) { return set(data + (value << lo)); } - inline auto& operator -=(const type value) { return set(data - (value << lo)); } - inline auto& operator *=(const type value) { return set((get() * value) << lo); } - inline auto& operator /=(const type value) { return set((get() / value) << lo); } - inline auto& operator %=(const type value) { return set((get() % value) << lo); } - - const uint lo; - const uint hi; - const uint bits; - const uint mask; - -private: - type& data; - - inline auto get() const -> type { - return (data & mask) >> lo; - } - - inline auto set(type value) -> BitFieldReference& { - return data = (data & ~mask) | (value & mask), *this; - } -}; - -template struct BitField { +template struct NaturalBitField { enum : uint { lo = Lo <= Hi ? Lo : Hi }; enum : uint { hi = Hi >= Lo ? Hi : Lo }; enum : uint { bits = hi - lo + 1 }; enum : uint { mask = (~0ull >> (64 - bits)) << lo }; static_assert(hi < sizeof(type) * 8, ""); - inline BitField() = default; - inline BitField(const BitField& value) { set(value.data); } - template inline BitField(const T& value) { set(value << lo); } + inline NaturalBitField() = default; + inline NaturalBitField(const NaturalBitField& value) { set(value.data); } + template inline NaturalBitField(const T& value) { set(value << lo); } inline explicit operator bool() const { return data & mask; } inline operator type() const { return get(); } - inline operator BitFieldReference() { return {data, lo, hi}; } - inline auto& operator=(const BitField& value) { return set(value.data); } + inline auto& operator=(const NaturalBitField& value) { return set(value.data); } template inline auto& operator=(const T& value) { return set(value << lo); } inline auto operator++(int) { type value = get(); set(data + (1 << lo)); return value; } @@ -89,30 +43,31 @@ private: return (data & mask) >> lo; } - inline auto set(type value) -> BitField& { + inline auto set(type value) -> NaturalBitField& { return data = (data & ~mask) | (value & mask), *this; } }; -template struct BitField { +template struct BooleanBitField { enum : uint { bit = Bit }; enum : uint { mask = 1ull << bit }; static_assert(bit < sizeof(type) * 8, ""); - inline BitField() = default; - inline BitField(const BitField& value) { set(value.get()); } - template inline BitField(const bool value) { set(value); } + inline BooleanBitField() = default; + inline BooleanBitField(const BooleanBitField& value) { set(value.get()); } + template inline BooleanBitField(const bool value) { set(value); } inline operator bool() const { return get(); } - inline operator BitFieldReference() { return {data, bit, bit}; } - inline auto& operator=(const BitField& value) { return set(value.get()); } + inline auto& operator=(const BooleanBitField& value) { return set(value.get()); } inline auto& operator=(const bool value) { return set(value); } inline auto& operator&=(const bool value) { return set(get() & value); } inline auto& operator|=(const bool value) { return set(get() | value); } inline auto& operator^=(const bool value) { return set(get() ^ value); } + inline auto raise() { return get() == 0 ? set(1), true : false; } + inline auto lower() { return get() == 1 ? set(0), true : false; } inline auto& invert() { return set(get() ^ 1); } private: @@ -122,7 +77,7 @@ private: return data & mask; } - inline auto set(bool value) -> BitField& { + inline auto set(bool value) -> BooleanBitField& { return data = (data & ~mask) | (value << bit), *this; } };