From ba2e6b5789aad6ce60062a0a5bd57d4f16b81ee4 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Sat, 1 Oct 2011 22:06:48 +1000 Subject: [PATCH] Update to v082r27 release. byuu says: Finished porting over all mappers to board/chip disambiguations. Had to nearly rewrite the MMC1 code to do it, but all variants should be supported. iNES1 is too stupid to express them all, so you'll need a board markup if you want to play the >8KB PRG RAM games. For whatever reason, they call VRC6's memory WRAM, and MMC1's PRG RAM. I am calling them all PRG RAM, since it's the same damn thing. Board spec is not going to be stable until I have a hell of a lot more mappers implemented, so be wary of that. Anyway, at this time, all games can be loaded sans iNES header, if you have the board markup. I'd also like to have a board database for all commercial titles. I'm treating *.fc as PRG-ROM(+CHR-ROM). Will work on loading the split files later possibly. --- bsnes/nes/cartridge/board/axrom.cpp | 2 + bsnes/nes/cartridge/board/bandai-fcg.cpp | 117 +++++++++ bsnes/nes/cartridge/board/board.cpp | 11 +- bsnes/nes/cartridge/board/board.hpp | 2 +- bsnes/nes/cartridge/board/cnrom.cpp | 2 + bsnes/nes/cartridge/board/konami-vrc6.cpp | 43 ++++ bsnes/nes/cartridge/board/nrom.cpp | 4 + bsnes/nes/cartridge/board/sxrom.cpp | 167 +++++++++++-- bsnes/nes/cartridge/board/txrom.cpp | 117 +++++++++ bsnes/nes/cartridge/board/uxrom.cpp | 2 + bsnes/nes/cartridge/cartridge.cpp | 1 + bsnes/nes/cartridge/cartridge.hpp | 2 +- bsnes/nes/cartridge/chip/chip.cpp | 10 + bsnes/nes/cartridge/chip/chip.hpp | 5 + bsnes/nes/cartridge/chip/mmc1.cpp | 95 ++++++++ bsnes/nes/cartridge/chip/mmc3.cpp | 141 +++++++++++ .../{mapper/vrc6 => cartridge/chip}/vrc6.cpp | 224 +++++++++--------- bsnes/nes/cartridge/ines.cpp | 46 ++-- bsnes/nes/mapper/aorom/aorom.cpp | 40 ---- bsnes/nes/mapper/aorom/aorom.hpp | 18 -- bsnes/nes/mapper/bandai-fcg/bandai-fcg.cpp | 109 --------- bsnes/nes/mapper/bandai-fcg/bandai-fcg.hpp | 26 -- bsnes/nes/mapper/cnrom/cnrom.cpp | 42 ---- bsnes/nes/mapper/cnrom/cnrom.hpp | 17 -- bsnes/nes/mapper/mapper.cpp | 75 ------ bsnes/nes/mapper/mapper.hpp | 37 --- bsnes/nes/mapper/mmc1/mmc1.cpp | 176 -------------- bsnes/nes/mapper/mmc1/mmc1.hpp | 34 --- bsnes/nes/mapper/mmc3/mmc3.cpp | 213 ----------------- bsnes/nes/mapper/mmc3/mmc3.hpp | 41 ---- bsnes/nes/mapper/none/none.cpp | 34 --- bsnes/nes/mapper/none/none.hpp | 14 -- bsnes/nes/mapper/uorom/uorom.cpp | 45 ---- bsnes/nes/mapper/uorom/uorom.hpp | 17 -- bsnes/nes/mapper/vrc6/vrc6.hpp | 69 ------ bsnes/ui/general/main-window.cpp | 2 +- bsnes/ui/interface/interface.cpp | 2 +- bsnes/ui/main.cpp | 2 +- bsnes/ui/tools/cheat-editor.cpp | 6 +- 39 files changed, 843 insertions(+), 1167 deletions(-) create mode 100755 bsnes/nes/cartridge/board/bandai-fcg.cpp create mode 100755 bsnes/nes/cartridge/board/konami-vrc6.cpp create mode 100755 bsnes/nes/cartridge/board/txrom.cpp create mode 100755 bsnes/nes/cartridge/chip/mmc1.cpp create mode 100755 bsnes/nes/cartridge/chip/mmc3.cpp rename bsnes/nes/{mapper/vrc6 => cartridge/chip}/vrc6.cpp (64%) delete mode 100755 bsnes/nes/mapper/aorom/aorom.cpp delete mode 100755 bsnes/nes/mapper/aorom/aorom.hpp delete mode 100755 bsnes/nes/mapper/bandai-fcg/bandai-fcg.cpp delete mode 100755 bsnes/nes/mapper/bandai-fcg/bandai-fcg.hpp delete mode 100755 bsnes/nes/mapper/cnrom/cnrom.cpp delete mode 100755 bsnes/nes/mapper/cnrom/cnrom.hpp delete mode 100755 bsnes/nes/mapper/mapper.cpp delete mode 100755 bsnes/nes/mapper/mapper.hpp delete mode 100755 bsnes/nes/mapper/mmc1/mmc1.cpp delete mode 100755 bsnes/nes/mapper/mmc1/mmc1.hpp delete mode 100755 bsnes/nes/mapper/mmc3/mmc3.cpp delete mode 100755 bsnes/nes/mapper/mmc3/mmc3.hpp delete mode 100755 bsnes/nes/mapper/none/none.cpp delete mode 100755 bsnes/nes/mapper/none/none.hpp delete mode 100755 bsnes/nes/mapper/uorom/uorom.cpp delete mode 100755 bsnes/nes/mapper/uorom/uorom.hpp delete mode 100755 bsnes/nes/mapper/vrc6/vrc6.hpp diff --git a/bsnes/nes/cartridge/board/axrom.cpp b/bsnes/nes/cartridge/board/axrom.cpp index d44f8c1c..2140551b 100755 --- a/bsnes/nes/cartridge/board/axrom.cpp +++ b/bsnes/nes/cartridge/board/axrom.cpp @@ -40,6 +40,8 @@ void reset() { } void serialize(serializer &s) { + Board::serialize(s); + s.integer(prg_bank); s.integer(mirror_select); } diff --git a/bsnes/nes/cartridge/board/bandai-fcg.cpp b/bsnes/nes/cartridge/board/bandai-fcg.cpp new file mode 100755 index 00000000..39399586 --- /dev/null +++ b/bsnes/nes/cartridge/board/bandai-fcg.cpp @@ -0,0 +1,117 @@ +//BANDAI-FCG + +struct BandaiFCG : Board { + +uint8 chr_bank[8]; +uint8 prg_bank; +uint2 mirror; +bool irq_counter_enable; +uint16 irq_counter; +uint16 irq_latch; + +void main() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + if(irq_counter_enable) { + if(--irq_counter == 0xffff) { + cpu.set_irq_line(1); + irq_counter_enable = false; + } + } + + tick(); + } +} + +unsigned ciram_addr(unsigned addr) const { + switch(mirror) { + case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); + case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); + case 2: return 0x0000 | (addr & 0x03ff); + case 3: return 0x0400 | (addr & 0x03ff); + } +} + +uint8 prg_read(unsigned addr) { + if(addr & 0x8000) { + bool region = addr & 0x4000; + unsigned bank = (region == 0 ? prg_bank : 0x0f); + return Board::prg_read((bank << 14) | (addr & 0x3fff)); + } + return cpu.mdr(); +} + +void prg_write(unsigned addr, uint8 data) { + if(addr >= 0x6000) { + switch(addr & 15) { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + chr_bank[addr & 7] = data; + break; + case 0x08: + prg_bank = data & 0x0f; + break; + case 0x09: + mirror = data & 0x03; + break; + case 0x0a: + cpu.set_irq_line(0); + irq_counter_enable = data & 0x01; + irq_counter = irq_latch; + break; + case 0x0b: + irq_latch = (irq_latch & 0xff00) | (data << 0); + break; + case 0x0c: + irq_latch = (irq_latch & 0x00ff) | (data << 8); + break; + case 0x0d: + //TODO: serial EEPROM support + break; + } + } +} + +uint8 chr_read(unsigned addr) { + if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr)); + addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff); + return Board::chr_read(addr); +} + +void chr_write(unsigned addr, uint8 data) { + if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data); + addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff); + return Board::chr_write(addr, data); +} + +void power() { + reset(); +} + +void reset() { + for(auto &n : chr_bank) n = 0; + prg_bank = 0; + mirror = 0; + irq_counter_enable = 0; + irq_counter = 0; + irq_latch = 0; +} + +void serialize(serializer &s) { + Board::serialize(s); + + s.array(chr_bank); + s.integer(prg_bank); + s.integer(mirror); + s.integer(irq_counter_enable); + s.integer(irq_counter); + s.integer(irq_latch); +} + +BandaiFCG(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { +} + +}; diff --git a/bsnes/nes/cartridge/board/board.cpp b/bsnes/nes/cartridge/board/board.cpp index a58a04f7..5b53ba9c 100755 --- a/bsnes/nes/cartridge/board/board.cpp +++ b/bsnes/nes/cartridge/board/board.cpp @@ -2,7 +2,10 @@ #include "cnrom.cpp" #include "nrom.cpp" #include "sxrom.cpp" +#include "txrom.cpp" #include "uxrom.cpp" +#include "bandai-fcg.cpp" +#include "konami-vrc6.cpp" unsigned Board::mirror(unsigned addr, unsigned size) const { unsigned base = 0; @@ -106,10 +109,16 @@ Board* Board::load(const string &markup, const uint8_t *data, unsigned size) { if(type == "NES-AN1ROM" ) return new AxROM(board, data, size); if(type == "NES-AOROM" ) return new AxROM(board, data, size); if(type == "NES-CNROM" ) return new CNROM(board, data, size); - if(type == "NES-NROM-256") return new NROM(board, data, size); + if(type == "NES-NROM-256") return new NROM (board, data, size); if(type == "NES-UNROM" ) return new UxROM(board, data, size); + if(type == "NES-SNROM" ) return new SxROM(board, data, size); if(type == "NES-SXROM" ) return new SxROM(board, data, size); + if(type == "NES-TLROM" ) return new TxROM(board, data, size); if(type == "NES-UOROM" ) return new UxROM(board, data, size); + if(type == "BANDAI-FCG") return new BandaiFCG(board, data, size); + + if(type == "KONAMI-VRC-6") return new KonamiVRC6(board, data, size); + return nullptr; } diff --git a/bsnes/nes/cartridge/board/board.hpp b/bsnes/nes/cartridge/board/board.hpp index 1ce83be7..d55a8756 100755 --- a/bsnes/nes/cartridge/board/board.hpp +++ b/bsnes/nes/cartridge/board/board.hpp @@ -2,6 +2,7 @@ struct Board { struct Memory { uint8_t *data; unsigned size; + inline Memory(uint8_t *data, unsigned size) : data(data), size(size) {} inline Memory() : data(nullptr), size(0u) {} }; @@ -32,7 +33,6 @@ struct Board { bool battery; } information; -protected: Memory prgrom; Memory prgram; Memory chrrom; diff --git a/bsnes/nes/cartridge/board/cnrom.cpp b/bsnes/nes/cartridge/board/cnrom.cpp index fccf5db6..be77de0b 100755 --- a/bsnes/nes/cartridge/board/cnrom.cpp +++ b/bsnes/nes/cartridge/board/cnrom.cpp @@ -44,6 +44,8 @@ void reset() { } void serialize(serializer &s) { + Board::serialize(s); + s.integer(chr_bank); } diff --git a/bsnes/nes/cartridge/board/konami-vrc6.cpp b/bsnes/nes/cartridge/board/konami-vrc6.cpp new file mode 100755 index 00000000..cec08700 --- /dev/null +++ b/bsnes/nes/cartridge/board/konami-vrc6.cpp @@ -0,0 +1,43 @@ +struct KonamiVRC6 : Board { + +VRC6 vrc6; + +uint8 prg_read(unsigned addr) { + if((addr & 0xe000) == 0x6000) return vrc6.ram_read(addr); + if(addr & 0x8000) return Board::prg_read(vrc6.prg_addr(addr)); + return cpu.mdr(); +} + +void prg_write(unsigned addr, uint8 data) { + if((addr & 0xe000) == 0x6000) return vrc6.ram_write(addr, data); + if(addr & 0x8000) { + addr = (addr & 0xf003); + if(prgram.size) addr = (addr & ~3) | ((addr & 2) >> 1) | ((addr & 1) << 1); + return vrc6.reg_write(addr, data); + } +} + +uint8 chr_read(unsigned addr) { + if(addr & 0x2000) return ppu.ciram_read(vrc6.ciram_addr(addr)); + return Board::chr_read(vrc6.chr_addr(addr)); +} + +void chr_write(unsigned addr, uint8 data) { + if(addr & 0x2000) return ppu.ciram_write(vrc6.ciram_addr(addr), data); + return Board::chr_write(vrc6.chr_addr(addr), data); +} + +void serialize(serializer &s) { + Board::serialize(s); + vrc6.serialize(s); +} + +void main() { vrc6.main(); } +void power() { vrc6.power(); } +void reset() { vrc6.reset(); } +Memory memory() { return prgram; } + +KonamiVRC6(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc6(*this) { +} + +}; diff --git a/bsnes/nes/cartridge/board/nrom.cpp b/bsnes/nes/cartridge/board/nrom.cpp index 3a4b6617..eaee9007 100755 --- a/bsnes/nes/cartridge/board/nrom.cpp +++ b/bsnes/nes/cartridge/board/nrom.cpp @@ -31,6 +31,10 @@ void chr_write(unsigned addr, uint8 data) { return Board::chr_write(addr, data); } +void serialize(serializer &s) { + Board::serialize(s); +} + NROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { settings.mirror = board["mirror"].value() == "vertical" ? 1 : 0; } diff --git a/bsnes/nes/cartridge/board/sxrom.cpp b/bsnes/nes/cartridge/board/sxrom.cpp index 3b3bf6fd..0541a9e7 100755 --- a/bsnes/nes/cartridge/board/sxrom.cpp +++ b/bsnes/nes/cartridge/board/sxrom.cpp @@ -1,29 +1,148 @@ -//NES-SAROM -//NES-SBROM -//NES-SCROM -//NES-SC1ROM -//NES-SEROM -//NES-SFROM -//NES-SGROM -//NES-SHROM -//NES-SH1ROM -//NES-SIROM -//NES-SJROM -//NES-SKROM -//NES-SLROM -//NES-SL1ROM -//NES-SL2ROM -//NES-SL3ROM -//NES-SLRROM -//NES-SMROM -//NES-SNROM -//NES-SOROM -//NES-SUROM -//NES-SXROM - struct SxROM : Board { -SxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { +enum class Revision : unsigned { + SAROM, + SBROM, + SCROM, + SC1ROM, + SEROM, + SFROM, + SGROM, + SHROM, + SH1ROM, + SIROM, + SJROM, + SKROM, + SLROM, + SL1ROM, + SL2ROM, + SL3ROM, + SLRROM, + SMROM, + SNROM, + SOROM, + SUROM, + SXROM, +} revision; + +MMC1 mmc1; + +unsigned shiftaddr; +unsigned shiftdata; + +uint8 prg_read(unsigned addr) { + if((addr & 0xe000) == 0x6000) return mmc1.ram_read(addr); + if(addr & 0x8000) return Board::prg_read(mmc1.prg_addr(addr)); + return cpu.mdr(); +} + +void prg_write(unsigned addr, uint8 data) { + if((addr & 0xe000) == 0x6000) return mmc1.ram_write(addr, data); + + if(addr & 0x8000) { + if(data & 0x80) { + shiftaddr = 0; + mmc1.prg_size = 1; + mmc1.prg_mode = 1; + } else { + shiftdata = ((data & 1) << 4) | (shiftdata >> 1); + if(++shiftaddr == 5) { + shiftaddr = 0; + reg_write((addr >> 13) & 3, shiftdata); + } + } + } +} + +uint8 chr_read(unsigned addr) { + if(addr & 0x2000) return ppu.ciram_read(mmc1.ciram_addr(addr)); + return Board::chr_read(mmc1.chr_addr(addr)); +} + +void chr_write(unsigned addr, uint8 data) { + if(addr & 0x2000) return ppu.ciram_write(mmc1.ciram_addr(addr), data); + return Board::chr_write(mmc1.chr_addr(addr), data); +} + +void reg_write(unsigned addr, uint8 data) { + switch(addr) { + case 0: + mmc1.chr_mode = (data & 0x10); + mmc1.prg_size = (data & 0x08); + mmc1.prg_mode = (data & 0x04); + mmc1.mirror = (data & 0x03); + break; + + case 1: + mmc1.chr_bank[0] = (data & 0x1f); + switch(revision) { + case Revision::SNROM: + mmc1.ram_disable[1] = (data & 0x10); + break; + case Revision::SOROM: + mmc1.ram_bank = (data & 0x08) >> 3; + break; + case Revision::SUROM: + mmc1.prg_page = (data & 0x10); + break; + case Revision::SXROM: + mmc1.prg_page = (data & 0x10); + mmc1.ram_bank = (data & 0x0c) >> 2; + break; + } + break; + + case 2: + mmc1.chr_bank[1] = (data & 0x1f); + switch(revision) { + case Revision::SNROM: + mmc1.ram_disable[1] = (data & 0x10); + break; + case Revision::SOROM: + mmc1.ram_bank = (data & 0x08) >> 3; + break; + case Revision::SUROM: + mmc1.prg_page = (data & 0x10); + break; + case Revision::SXROM: + mmc1.prg_page = (data & 0x10); + mmc1.ram_bank = (data & 0x0c) >> 2; + break; + } + break; + + case 3: + mmc1.ram_disable[0] = (data & 0x10); + mmc1.prg_bank = (data & 0x0f); + break; + } +} + +Memory memory() { + return prgram; +} + +void power() { + mmc1.power(); +} + +void reset() { + mmc1.reset(); +} + +void serialize(serializer &s) { + Board::serialize(s); + mmc1.serialize(s); + + s.integer(shiftaddr); + s.integer(shiftdata); +} + +SxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc1(*this) { + revision = Revision::SXROM; + + shiftaddr = 0; + shiftdata = 0; } }; diff --git a/bsnes/nes/cartridge/board/txrom.cpp b/bsnes/nes/cartridge/board/txrom.cpp new file mode 100755 index 00000000..c73ddc0a --- /dev/null +++ b/bsnes/nes/cartridge/board/txrom.cpp @@ -0,0 +1,117 @@ +struct TxROM : Board { + +enum class Revision : unsigned { + TBROM, + TEROM, + TFROM, + TGROM, + TKROM, + TKSROM, + TLROM, + TL1ROM, + TL2ROM, + TLSROM, + TNROM, + TQROM, + TR1ROM, + TSROM, + TVROM, +} revision; + +MMC3 mmc3; + +void main() { + mmc3.main(); +} + +uint8 prg_read(unsigned addr) { + if((addr & 0xe000) == 0x6000) return mmc3.ram_read(addr); + if(addr & 0x8000) return Board::prg_read(mmc3.prg_addr(addr)); + return cpu.mdr(); +} + +void prg_write(unsigned addr, uint8 data) { + if((addr & 0xe000) == 0x6000) return mmc3.ram_write(addr, data); + + switch(addr & 0xe001) { + case 0x8000: + mmc3.chr_mode = data & 0x80; + mmc3.prg_mode = data & 0x40; + mmc3.bank_select = data & 0x07; + break; + + case 0x8001: + switch(mmc3.bank_select) { + case 0: mmc3.chr_bank[0] = data & ~1; break; + case 1: mmc3.chr_bank[1] = data & ~1; break; + case 2: mmc3.chr_bank[2] = data; break; + case 3: mmc3.chr_bank[3] = data; break; + case 4: mmc3.chr_bank[4] = data; break; + case 5: mmc3.chr_bank[5] = data; break; + case 6: mmc3.prg_bank[0] = data & 0x3f; break; + case 7: mmc3.prg_bank[1] = data & 0x3f; break; + } + break; + + case 0xa000: + mmc3.mirror = data & 0x01; + break; + + case 0xa001: + mmc3.ram_enable = data & 0x80; + mmc3.ram_write_protect = data & 0x40; + break; + + case 0xc000: + mmc3.irq_latch = data; + break; + + case 0xc001: + mmc3.irq_counter = 0; + break; + + case 0xe000: + mmc3.irq_enable = false; + mmc3.irq_line = 0; + break; + + case 0xe001: + mmc3.irq_enable = true; + break; + } +} + +uint8 chr_read(unsigned addr) { + mmc3.irq_test(addr); + if(addr & 0x2000) return ppu.ciram_read(mmc3.ciram_addr(addr)); + return Board::chr_read(mmc3.chr_addr(addr)); +} + +void chr_write(unsigned addr, uint8 data) { + mmc3.irq_test(addr); + if(addr & 0x2000) return ppu.ciram_write(mmc3.ciram_addr(addr), data); + return Board::chr_write(mmc3.chr_addr(addr), data); +} + +Memory memory() { + return prgram; +} + +void power() { + mmc3.power(); +} + +void reset() { + mmc3.reset(); +} + +void serialize(serializer &s) { + Board::serialize(s); + mmc3.serialize(s); +} + +TxROM(BML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc3(*this) { + revision = Revision::TLROM; +} + +}; diff --git a/bsnes/nes/cartridge/board/uxrom.cpp b/bsnes/nes/cartridge/board/uxrom.cpp index c7aea46e..b801ba26 100755 --- a/bsnes/nes/cartridge/board/uxrom.cpp +++ b/bsnes/nes/cartridge/board/uxrom.cpp @@ -44,6 +44,8 @@ void reset() { } void serialize(serializer &s) { + Board::serialize(s); + s.integer(prg_bank); } diff --git a/bsnes/nes/cartridge/cartridge.cpp b/bsnes/nes/cartridge/cartridge.cpp index c5a0bfe7..331b750d 100755 --- a/bsnes/nes/cartridge/cartridge.cpp +++ b/bsnes/nes/cartridge/cartridge.cpp @@ -20,6 +20,7 @@ void Cartridge::load(const string &markup, const uint8_t *data, unsigned size) { sha256 = nall::sha256(data, size); board = Board::load(markup, data, size); } else { + sha256 = nall::sha256(data + 16, size - 16); board = Board::load(markup != "" ? markup : iNES(data, size), data + 16, size - 16); } diff --git a/bsnes/nes/cartridge/cartridge.hpp b/bsnes/nes/cartridge/cartridge.hpp index 44198cc6..f6db4b15 100755 --- a/bsnes/nes/cartridge/cartridge.hpp +++ b/bsnes/nes/cartridge/cartridge.hpp @@ -9,7 +9,7 @@ struct Cartridge : Processor, property { void unload(); unsigned ram_size(); - uint8 *ram_data(); + uint8* ram_data(); void power(); void reset(); diff --git a/bsnes/nes/cartridge/chip/chip.cpp b/bsnes/nes/cartridge/chip/chip.cpp index e69de29b..51dc1b7e 100755 --- a/bsnes/nes/cartridge/chip/chip.cpp +++ b/bsnes/nes/cartridge/chip/chip.cpp @@ -0,0 +1,10 @@ +#include "mmc1.cpp" +#include "mmc3.cpp" +#include "vrc6.cpp" + +void Chip::tick() { + board.tick(); +} + +Chip::Chip(Board &board) : board(board) { +} diff --git a/bsnes/nes/cartridge/chip/chip.hpp b/bsnes/nes/cartridge/chip/chip.hpp index b30e88b4..8753c66b 100755 --- a/bsnes/nes/cartridge/chip/chip.hpp +++ b/bsnes/nes/cartridge/chip/chip.hpp @@ -1,2 +1,7 @@ +struct Board; + struct Chip { + Board &board; + void tick(); + Chip(Board &board); }; diff --git a/bsnes/nes/cartridge/chip/mmc1.cpp b/bsnes/nes/cartridge/chip/mmc1.cpp new file mode 100755 index 00000000..1c6bfe61 --- /dev/null +++ b/bsnes/nes/cartridge/chip/mmc1.cpp @@ -0,0 +1,95 @@ +struct MMC1 : Chip { + +enum class Revision : unsigned { + MMC1, + MMC1A, + MMC1B1, + MMC1B2, + MMC1B3, + MMC1C, +} revision; + +bool chr_mode; +bool prg_size; //0 = 32K, 1 = 16K +bool prg_mode; +uint2 mirror; //0 = first, 1 = second, 2 = vertical, 3 = horizontal +uint5 chr_bank[2]; +uint4 prg_bank; +bool prg_page; +uint2 ram_bank; +bool ram_disable[2]; + +unsigned prg_addr(unsigned addr) const { + bool region = addr & 0x4000; + unsigned bank = (prg_bank & ~1) + region; + + if(prg_size) { + bank = (region == 0 ? 0x0 : 0xf); + if(region != prg_mode) bank = prg_bank; + } + + return (prg_page << 18) | (bank << 14) | (addr & 0x3fff); +} + +unsigned chr_addr(unsigned addr) const { + bool region = addr & 0x1000; + unsigned bank = chr_bank[region]; + if(chr_mode == 0) bank = (chr_bank[0] & ~1) | region; + return (bank << 12) | (addr & 0x0fff); +} + +unsigned ciram_addr(unsigned addr) const { + switch(mirror) { + case 0: return 0x0000 | (addr & 0x03ff); + case 1: return 0x0400 | (addr & 0x03ff); + case 2: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); + case 3: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); + } +} + +uint8 ram_read(unsigned addr) { + addr = (ram_bank * 0x2000) | (addr & 0x1fff); + if(ram_disable[0] == false && ram_disable[1] == false) return board.prgram.data[addr]; + return 0x00; +} + +void ram_write(unsigned addr, uint8 data) { + addr = (ram_bank * 0x2000) | (addr & 0x1fff); + if(ram_disable[0] == false && ram_disable[1] == false) board.prgram.data[addr] = data; +} + +void power() { + reset(); +} + +void reset() { + chr_mode = 0; + prg_size = 1; + prg_mode = 1; + mirror = 0; + chr_bank[0] = 0; + chr_bank[1] = 1; + prg_bank = 0; + prg_page = 0; + ram_bank = 0; + ram_disable[0] = 0; + ram_disable[1] = 0; +} + +void serialize(serializer &s) { + s.integer(chr_mode); + s.integer(prg_size); + s.integer(prg_mode); + s.integer(mirror); + s.array(chr_bank); + s.integer(prg_bank); + s.integer(prg_page); + s.integer(ram_bank); + s.array(ram_disable); +} + +MMC1(Board &board) : Chip(board) { + revision = Revision::MMC1B2; +} + +}; diff --git a/bsnes/nes/cartridge/chip/mmc3.cpp b/bsnes/nes/cartridge/chip/mmc3.cpp new file mode 100755 index 00000000..525f296b --- /dev/null +++ b/bsnes/nes/cartridge/chip/mmc3.cpp @@ -0,0 +1,141 @@ +struct MMC3 : Chip { + +bool chr_mode; +bool prg_mode; +uint3 bank_select; +uint8 prg_bank[2]; +uint8 chr_bank[6]; +bool mirror; +bool ram_enable; +bool ram_write_protect; +uint8 irq_latch; +uint8 irq_counter; +bool irq_enable; +unsigned irq_delay; +bool irq_line; + +uint16 chr_abus; + +void main() { + while(true) { + if(scheduler.sync == Scheduler::SynchronizeMode::All) { + scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); + } + + if(irq_delay) irq_delay--; + cpu.set_irq_line(irq_line); + tick(); + } +} + +void irq_test(unsigned addr) { + if(!(chr_abus & 0x1000) && (addr & 0x1000)) { + if(irq_delay == 0) { + if(irq_counter == 0) { + irq_counter = irq_latch; + } else if(--irq_counter == 0) { + if(irq_enable) irq_line = 1; + } + } + irq_delay = 6; + } + chr_abus = addr; +} + +unsigned prg_addr(unsigned addr) const { + switch((addr >> 13) & 3) { + case 0: + if(prg_mode == 1) return (0x3e << 13) | (addr & 0x1fff); + return (prg_bank[0] << 13) | (addr & 0x1fff); + case 1: + return (prg_bank[1] << 13) | (addr & 0x1fff); + case 2: + if(prg_mode == 0) return (0x3e << 13) | (addr & 0x1fff); + return (prg_bank[0] << 13) | (addr & 0x1fff); + case 3: + return (0x3f << 13) | (addr & 0x1fff); + } +} + +unsigned chr_addr(unsigned addr) const { + if(chr_mode == 0) { + if(addr <= 0x07ff) return (chr_bank[0] << 10) | (addr & 0x07ff); + if(addr <= 0x0fff) return (chr_bank[1] << 10) | (addr & 0x07ff); + if(addr <= 0x13ff) return (chr_bank[2] << 10) | (addr & 0x03ff); + if(addr <= 0x17ff) return (chr_bank[3] << 10) | (addr & 0x03ff); + if(addr <= 0x1bff) return (chr_bank[4] << 10) | (addr & 0x03ff); + if(addr <= 0x1fff) return (chr_bank[5] << 10) | (addr & 0x03ff); + } else { + if(addr <= 0x03ff) return (chr_bank[2] << 10) | (addr & 0x03ff); + if(addr <= 0x07ff) return (chr_bank[3] << 10) | (addr & 0x03ff); + if(addr <= 0x0bff) return (chr_bank[4] << 10) | (addr & 0x03ff); + if(addr <= 0x0fff) return (chr_bank[5] << 10) | (addr & 0x03ff); + if(addr <= 0x17ff) return (chr_bank[0] << 10) | (addr & 0x07ff); + if(addr <= 0x1fff) return (chr_bank[1] << 10) | (addr & 0x07ff); + } +} + +unsigned ciram_addr(unsigned addr) const { + if(mirror == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff); + if(mirror == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff); +} + +uint8 ram_read(unsigned addr) { + if(ram_enable) return board.prgram.data[addr & 0x1fff]; + return 0x00; +} + +void ram_write(unsigned addr, uint8 data) { + if(ram_enable && !ram_write_protect) board.prgram.data[addr & 0x1fff] = data; +} + +void power() { + reset(); +} + +void reset() { + chr_mode = 0; + prg_mode = 0; + bank_select = 0; + prg_bank[0] = 0; + prg_bank[1] = 0; + chr_bank[0] = 0; + chr_bank[1] = 0; + chr_bank[2] = 0; + chr_bank[3] = 0; + chr_bank[4] = 0; + chr_bank[5] = 0; + mirror = 0; + ram_enable = 1; + ram_write_protect = 0; + irq_latch = 0; + irq_counter = 0; + irq_enable = false; + irq_delay = 0; + irq_line = 0; + + chr_abus = 0; +} + +void serialize(serializer &s) { + s.integer(chr_mode); + s.integer(prg_mode); + s.integer(bank_select); + s.array(prg_bank); + s.array(chr_bank); + s.integer(mirror); + s.integer(ram_enable); + s.integer(ram_write_protect); + s.integer(irq_latch); + s.integer(irq_counter); + s.integer(irq_enable); + s.integer(irq_delay); + s.integer(irq_line); + + s.integer(chr_abus); +} + +MMC3(Board &board) : Chip(board) { +} + +}; diff --git a/bsnes/nes/mapper/vrc6/vrc6.cpp b/bsnes/nes/cartridge/chip/vrc6.cpp similarity index 64% rename from bsnes/nes/mapper/vrc6/vrc6.cpp rename to bsnes/nes/cartridge/chip/vrc6.cpp index 19f707a1..f872cf23 100755 --- a/bsnes/nes/mapper/vrc6/vrc6.cpp +++ b/bsnes/nes/cartridge/chip/vrc6.cpp @@ -1,32 +1,92 @@ -VRC6 vrc6; +struct VRC6 : Chip { -void VRC6::Pulse::clock() { - if(--divider == 0) { - divider = frequency + 1; - cycle++; - output = (mode == 1 || cycle > duty) ? volume : (uint4)0; +uint8 prg_bank[2]; +uint8 chr_bank[8]; +uint2 mirror; +uint8 irq_latch; +bool irq_mode; +bool irq_enable; +bool irq_acknowledge; + +uint8 irq_counter; +signed irq_scalar; +bool irq_line; + +struct Pulse { + bool mode; + uint3 duty; + uint4 volume; + bool enable; + uint12 frequency; + + uint12 divider; + uint4 cycle; + uint4 output; + + void clock() { + if(--divider == 0) { + divider = frequency + 1; + cycle++; + output = (mode == 1 || cycle > duty) ? volume : (uint4)0; + } + + if(enable == false) output = 0; } - if(enable == false) output = 0; -} + void serialize(serializer &s) { + s.integer(mode); + s.integer(duty); + s.integer(volume); + s.integer(enable); + s.integer(frequency); -void VRC6::Sawtooth::clock() { - if(--divider == 0) { - divider = frequency + 1; - if(++phase == 0) { - accumulator += rate; - if(++stage == 7) { - stage = 0; - accumulator = 0; + s.integer(divider); + s.integer(cycle); + s.integer(output); + } +} pulse1, pulse2; + +struct Sawtooth { + uint6 rate; + bool enable; + uint12 frequency; + + uint12 divider; + uint1 phase; + uint3 stage; + uint8 accumulator; + uint5 output; + + void clock() { + if(--divider == 0) { + divider = frequency + 1; + if(++phase == 0) { + accumulator += rate; + if(++stage == 7) { + stage = 0; + accumulator = 0; + } } } + + output = accumulator >> 3; + if(enable == false) output = 0; } - output = accumulator >> 3; - if(enable == false) output = 0; -} + void serialize(serializer &s) { + s.integer(rate); + s.integer(enable); + s.integer(frequency); -void VRC6::main() { + s.integer(divider); + s.integer(phase); + s.integer(stage); + s.integer(accumulator); + s.integer(output); + } +} sawtooth; + +void main() { while(true) { if(scheduler.sync == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); @@ -67,35 +127,35 @@ void VRC6::main() { } } -uint8 VRC6::prg_read(unsigned addr) { - if((addr & 0xe000) == 0x6000) { - return prg_ram[addr & 0x1fff]; - } - - if((addr & 0xc000) == 0x8000) { - return Mapper::prg_read((prg_bank[0] << 14) | (addr & 0x3fff)); - } - - if((addr & 0xe000) == 0xc000) { - return Mapper::prg_read((prg_bank[1] << 13) | (addr & 0x1fff)); - } - - if((addr & 0xe000) == 0xe000) { - return Mapper::prg_read((0xff << 13) | (addr & 0x1fff)); - } - - return cpu.mdr(); +unsigned prg_addr(unsigned addr) const { + if((addr & 0xc000) == 0x8000) return (prg_bank[0] << 14) | (addr & 0x3fff); + if((addr & 0xe000) == 0xc000) return (prg_bank[1] << 13) | (addr & 0x1fff); + if((addr & 0xe000) == 0xe000) return ( 0xff << 13) | (addr & 0x1fff); } -void VRC6::prg_write(unsigned addr, uint8 data) { - if((addr & 0xe000) == 0x6000) { - prg_ram[addr & 0x1fff] = data; - return; +unsigned chr_addr(unsigned addr) const { + unsigned bank = chr_bank[(addr >> 10) & 7]; + return (bank << 10) | (addr & 0x03ff); +} + +unsigned ciram_addr(unsigned addr) const { + switch(mirror) { + case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring + case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring + case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first) + case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second) } +} - addr = (addr & 0xf003); - if(abus_swap) addr = (addr & ~3) | ((addr & 2) >> 1) | ((addr & 1) << 1); +uint8 ram_read(unsigned addr) { + return board.prgram.data[addr & 0x1fff]; +} +void ram_write(unsigned addr, uint8 data) { + board.prgram.data[addr & 0x1fff] = data; +} + +void reg_write(unsigned addr, uint8 data) { switch(addr) { case 0x8000: case 0x8001: case 0x8002: case 0x8003: prg_bank[0] = data; @@ -145,7 +205,7 @@ void VRC6::prg_write(unsigned addr, uint8 data) { break; case 0xb003: - mirror_select = (data >> 2) & 3; + mirror = (data >> 2) & 3; break; case 0xc000: case 0xc001: case 0xc002: case 0xc003: @@ -182,44 +242,11 @@ void VRC6::prg_write(unsigned addr, uint8 data) { } } -uint8 VRC6::chr_read(unsigned addr) { - if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr)); - - unsigned bank = chr_bank[(addr >> 10) & 7]; - return Mapper::chr_read((bank << 10) | (addr & 0x03ff)); -} - -void VRC6::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data); - - unsigned bank = chr_bank[(addr >> 10) & 7]; - Mapper::chr_write((bank << 10) | (addr & 0x03ff), data); -} - -unsigned VRC6::ciram_addr(unsigned addr) const { - switch(mirror_select) { - case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring - case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring - case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first) - case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second) - } -} - -unsigned VRC6::ram_size() { - return 8192u; -} - -uint8* VRC6::ram_data() { - return prg_ram; -} - -void VRC6::power() { +void power() { reset(); } -void VRC6::reset() { - for(auto &n : prg_ram) n = 0xff; - +void reset() { prg_bank[0] = 0; prg_bank[1] = 0; chr_bank[0] = 0; @@ -230,7 +257,7 @@ void VRC6::reset() { chr_bank[5] = 0; chr_bank[6] = 0; chr_bank[7] = 0; - mirror_select = 0; + mirror = 0; irq_latch = 0; irq_mode = 0; irq_enable = 0; @@ -271,12 +298,14 @@ void VRC6::reset() { sawtooth.output = 0; } -void VRC6::serialize(serializer &s) { - s.array(prg_ram); +void serialize(serializer &s) { + pulse1.serialize(s); + pulse2.serialize(s); + sawtooth.serialize(s); s.array(prg_bank); s.array(chr_bank); - s.integer(mirror_select); + s.integer(mirror); s.integer(irq_latch); s.integer(irq_mode); s.integer(irq_enable); @@ -285,32 +314,9 @@ void VRC6::serialize(serializer &s) { s.integer(irq_counter); s.integer(irq_scalar); s.integer(irq_line); - - pulse1.serialize(s); - pulse2.serialize(s); - sawtooth.serialize(s); } -void VRC6::Pulse::serialize(serializer &s) { - s.integer(mode); - s.integer(duty); - s.integer(volume); - s.integer(enable); - s.integer(frequency); - - s.integer(divider); - s.integer(cycle); - s.integer(output); +VRC6(Board &board) : Chip(board) { } -void VRC6::Sawtooth::serialize(serializer &s) { - s.integer(rate); - s.integer(enable); - s.integer(frequency); - - s.integer(divider); - s.integer(phase); - s.integer(stage); - s.integer(accumulator); - s.integer(output); -} +}; diff --git a/bsnes/nes/cartridge/ines.cpp b/bsnes/nes/cartridge/ines.cpp index 42a9d10e..207c2495 100755 --- a/bsnes/nes/cartridge/ines.cpp +++ b/bsnes/nes/cartridge/ines.cpp @@ -24,23 +24,47 @@ static string iNES(const uint8_t *data, unsigned size) { output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n"); break; - case 1: + case 1: output.append(" board type=NES-SXROM\n"); + output.append(" chip type=MMC1B2\n"); + prgram = 8192; break; - case 2: + case 2: output.append(" board type=NES-UOROM\n"); output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n"); break; - case 3: + case 3: output.append(" board type=NES-CNROM\n"); output.append(" mirror=", mirror == 0 ? "horizontal" : "vertical", "\n"); break; - case 7: + case 4: + output.append(" board type=NES-TLROM\n"); + output.append(" chip type=MMC3B\n"); + prgram = 8192; + break; + + case 7: output.append(" board type=NES-AOROM\n"); break; + + case 16: + output.append(" board type=BANDAI-FCG\n"); + output.append(" chip type=LZ93D50 manufacturer=Sharp\n"); + break; + + case 24: + output.append(" board type=KONAMI-VRC-6\n"); + output.append(" chip type=VRC6\n"); + break; + + case 26: + output.append(" board type=KONAMI-VRC-6\n"); + output.append(" chip type=VRC6\n"); + prgram = 8192; + break; } output.append(" prg rom=", prgrom, " ram=", prgram, "\n"); @@ -50,17 +74,3 @@ static string iNES(const uint8_t *data, unsigned size) { return output; } - -/* - switch(mapperNumber) { -//default : mapper = &Mapper::none; break; -//case 1: mapper = &Mapper::mmc1; break; -//case 2: mapper = &Mapper::uorom; break; -//case 3: mapper = &Mapper::cnrom; break; - case 4: mapper = &Mapper::mmc3; break; -//case 7: mapper = &Mapper::aorom; break; - case 16: mapper = &Mapper::bandaiFCG; break; - case 24: mapper = &Mapper::vrc6; Mapper::vrc6.abus_swap = 0; break; - case 26: mapper = &Mapper::vrc6; Mapper::vrc6.abus_swap = 1; break; - } -*/ diff --git a/bsnes/nes/mapper/aorom/aorom.cpp b/bsnes/nes/mapper/aorom/aorom.cpp deleted file mode 100755 index 646572f7..00000000 --- a/bsnes/nes/mapper/aorom/aorom.cpp +++ /dev/null @@ -1,40 +0,0 @@ -AOROM aorom; - -uint8 AOROM::prg_read(unsigned addr) { - if(addr & 0x8000) { - addr = (prg_bank << 15) | (addr & 0x7fff); - return Mapper::prg_read(addr); - } - return cpu.mdr(); -} - -void AOROM::prg_write(unsigned addr, uint8 data) { - if(addr & 0x8000) { - prg_bank = data & 0x0f; - mirror_select = data & 0x10; - } -} - -uint8 AOROM::chr_read(unsigned addr) { - if(addr & 0x2000) return ppu.ciram_read((mirror_select << 10) | (addr & 0x03ff)); - return Mapper::chr_read(addr); -} - -void AOROM::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) return ppu.ciram_write((mirror_select << 10) | (addr & 0x03ff), data); - return Mapper::chr_write(addr, data); -} - -void AOROM::power() { - reset(); -} - -void AOROM::reset() { - prg_bank = 0x0f; - mirror_select = 0; -} - -void AOROM::serialize(serializer &s) { - s.integer(prg_bank); - s.integer(mirror_select); -} diff --git a/bsnes/nes/mapper/aorom/aorom.hpp b/bsnes/nes/mapper/aorom/aorom.hpp deleted file mode 100755 index 32fd0c60..00000000 --- a/bsnes/nes/mapper/aorom/aorom.hpp +++ /dev/null @@ -1,18 +0,0 @@ -struct AOROM : Mapper { - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - uint4 prg_bank; - bool mirror_select; -}; - -extern AOROM aorom; diff --git a/bsnes/nes/mapper/bandai-fcg/bandai-fcg.cpp b/bsnes/nes/mapper/bandai-fcg/bandai-fcg.cpp deleted file mode 100755 index f00bea12..00000000 --- a/bsnes/nes/mapper/bandai-fcg/bandai-fcg.cpp +++ /dev/null @@ -1,109 +0,0 @@ -BandaiFCG bandaiFCG; - -void BandaiFCG::main() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(irq_counter_enable) { - if(--irq_counter == 0xffff) { - cpu.set_irq_line(1); - irq_counter_enable = false; - } - } - - tick(); - } -} - -uint8 BandaiFCG::prg_read(unsigned addr) { - if((addr & 0xc000) == 0x8000) { - addr = (prg_bank << 14) | (addr & 0x3fff); - return Mapper::prg_read(addr); - } - - if((addr & 0xc000) == 0xc000) { - addr = (0x0f << 14) | (addr & 0x3fff); - return Mapper::prg_read(addr); - } - - return cpu.mdr(); -} - -void BandaiFCG::prg_write(unsigned addr, uint8 data) { - if(addr >= 0x6000) { - addr &= 0x0f; - switch(addr) { - case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - chr_bank[addr] = data; - break; - case 0x8: - prg_bank = data & 0x0f; - break; - case 0x9: - mirror_select = data & 0x03; - break; - case 0xa: - cpu.set_irq_line(0); - irq_counter_enable = data & 0x01; - irq_counter = irq_latch; - break; - case 0xb: - irq_latch = (irq_latch & 0xff00) | (data << 0); - break; - case 0xc: - irq_latch = (irq_latch & 0x00ff) | (data << 8); - break; - case 0xd: - //TODO: serial EEPROM support - break; - } - } -} - -uint8 BandaiFCG::chr_read(unsigned addr) { - if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr)); - - addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff); - return Mapper::chr_read(addr); -} - -void BandaiFCG::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data); - - addr = (chr_bank[addr >> 10] << 10) | (addr & 0x03ff); - Mapper::chr_write(addr, data); -} - -void BandaiFCG::power() { - reset(); -} - -void BandaiFCG::reset() { - for(unsigned n = 0; n < 8; n++) chr_bank[n] = 0x00; - prg_bank = 0x00; - mirror_select = 0; - irq_counter_enable = false; - irq_counter = 0; - irq_latch = 0; -} - -unsigned BandaiFCG::ciram_addr(unsigned addr) const { - switch(mirror_select & 0x03) { - case 0: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring - case 1: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring - case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first) - case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second) - } - throw; -} - -void BandaiFCG::serialize(serializer &s) { - s.array(chr_bank); - s.integer(prg_bank); - s.integer(mirror_select); - s.integer(irq_counter_enable); - s.integer(irq_counter); - s.integer(irq_latch); -} diff --git a/bsnes/nes/mapper/bandai-fcg/bandai-fcg.hpp b/bsnes/nes/mapper/bandai-fcg/bandai-fcg.hpp deleted file mode 100755 index e1fd8b58..00000000 --- a/bsnes/nes/mapper/bandai-fcg/bandai-fcg.hpp +++ /dev/null @@ -1,26 +0,0 @@ -struct BandaiFCG : Mapper { - void main(); - - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - unsigned ciram_addr(unsigned addr) const; - - uint8 chr_bank[8]; - uint8 prg_bank; - uint8 mirror_select; - bool irq_counter_enable; - uint16 irq_counter; - uint16 irq_latch; -}; - -extern BandaiFCG bandaiFCG; diff --git a/bsnes/nes/mapper/cnrom/cnrom.cpp b/bsnes/nes/mapper/cnrom/cnrom.cpp deleted file mode 100755 index df1c1e09..00000000 --- a/bsnes/nes/mapper/cnrom/cnrom.cpp +++ /dev/null @@ -1,42 +0,0 @@ -CNROM cnrom; - -uint8 CNROM::prg_read(unsigned addr) { - if(addr & 0x8000) return Mapper::prg_read(addr & 0x7fff); - return cpu.mdr(); -} - -void CNROM::prg_write(unsigned addr, uint8 data) { - if(addr & 0x8000) chr_bank = data & 0x03; -} - -uint8 CNROM::chr_read(unsigned addr) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_read(addr & 0x07ff); - } - - addr = (chr_bank * 0x2000) + (addr & 0x1fff); - return Mapper::chr_read(addr); -} - -void CNROM::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_write(addr & 0x07ff, data); - } - - addr = (chr_bank * 0x2000) + (addr & 0x1fff); - Mapper::chr_write(addr, data); -} - -void CNROM::power() { - reset(); -} - -void CNROM::reset() { - chr_bank = 0; -} - -void CNROM::serialize(serializer &s) { - s.integer(chr_bank); -} diff --git a/bsnes/nes/mapper/cnrom/cnrom.hpp b/bsnes/nes/mapper/cnrom/cnrom.hpp deleted file mode 100755 index af32d78f..00000000 --- a/bsnes/nes/mapper/cnrom/cnrom.hpp +++ /dev/null @@ -1,17 +0,0 @@ -struct CNROM : Mapper { - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - uint2 chr_bank; -}; - -extern CNROM cnrom; diff --git a/bsnes/nes/mapper/mapper.cpp b/bsnes/nes/mapper/mapper.cpp deleted file mode 100755 index db6ba850..00000000 --- a/bsnes/nes/mapper/mapper.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include - -namespace NES { -namespace Mapper { - -void Mapper::main() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - cartridge.clock += 12 * 4095; - tick(); - } -} - -void Mapper::tick() { - cartridge.clock += 12; - if(cartridge.clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); -} - -unsigned Mapper::mirror(unsigned addr, unsigned size) const { - unsigned base = 0; - if(size) { - unsigned mask = 1 << 23; - while(addr >= size) { - while(!(addr & mask)) mask >>= 1; - addr -= mask; - if(size > mask) { - size -= mask; - base += mask; - } - mask >>= 1; - } - base += addr; - } - return base; -} - -uint8 Mapper::prg_read(unsigned addr) { - return cartridge.prg_data[mirror(addr, cartridge.prg_size)]; -} - -void Mapper::prg_write(unsigned addr, uint8 data) { - cartridge.prg_data[mirror(addr, cartridge.prg_size)] = data; -} - -uint8 Mapper::chr_read(unsigned addr) { - return cartridge.chr_data[mirror(addr, cartridge.chr_size)]; -} - -void Mapper::chr_write(unsigned addr, uint8 data) { - if(cartridge.chr_ram == false) return; - cartridge.chr_data[mirror(addr, cartridge.chr_size)] = data; -} - -unsigned Mapper::ram_size() { - return 0u; -} - -uint8* Mapper::ram_data() { - return 0; -} - -#include "none/none.cpp" -#include "aorom/aorom.cpp" -#include "bandai-fcg/bandai-fcg.cpp" -#include "cnrom/cnrom.cpp" -#include "mmc1/mmc1.cpp" -#include "mmc3/mmc3.cpp" -#include "uorom/uorom.cpp" -#include "vrc6/vrc6.cpp" - -} -} diff --git a/bsnes/nes/mapper/mapper.hpp b/bsnes/nes/mapper/mapper.hpp deleted file mode 100755 index 08e1ef69..00000000 --- a/bsnes/nes/mapper/mapper.hpp +++ /dev/null @@ -1,37 +0,0 @@ -namespace Mapper { - struct Mapper { - virtual void main(); - virtual void tick(); - - unsigned mirror(unsigned addr, unsigned size) const; - - //note: Mapper::{prg,chr}_read() functions take literal ROM addresses; mirroring appropriately - //subclasses of Mapper take 16-bit bus addresses; decode them; and call Mapper read functions - - virtual uint8 prg_read(unsigned addr); - virtual void prg_write(unsigned addr, uint8 data); - - virtual uint8 chr_read(unsigned addr); - virtual void chr_write(unsigned addr, uint8 data); - - virtual uint8 ciram_read(uint13 addr) {} - virtual void ciram_write(uint13 addr, uint8 data) {} - - virtual unsigned ram_size(); - virtual uint8* ram_data(); - - virtual void power() = 0; - virtual void reset() = 0; - - virtual void serialize(serializer&) = 0; - }; - - #include "none/none.hpp" - #include "aorom/aorom.hpp" - #include "bandai-fcg/bandai-fcg.hpp" - #include "cnrom/cnrom.hpp" - #include "mmc1/mmc1.hpp" - #include "mmc3/mmc3.hpp" - #include "uorom/uorom.hpp" - #include "vrc6/vrc6.hpp" -} diff --git a/bsnes/nes/mapper/mmc1/mmc1.cpp b/bsnes/nes/mapper/mmc1/mmc1.cpp deleted file mode 100755 index 11a53149..00000000 --- a/bsnes/nes/mapper/mmc1/mmc1.cpp +++ /dev/null @@ -1,176 +0,0 @@ -MMC1 mmc1; - -unsigned MMC1::ciram_addr(unsigned addr) const { - switch(r[0] & 0x03) { - case 0: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first) - case 1: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second) - case 2: return ((addr & 0x0400) >> 0) | (addr & 0x03ff); //vertical mirroring - case 3: return ((addr & 0x0800) >> 1) | (addr & 0x03ff); //horizontal mirroring - } -} - -//static block: 0 = 8000-ffff, 1 = c000-ffff -bool MMC1::prg_mode() const { - return r[0] & 0x04; -} - -//block size: 0 = 32K, 1 = 16K -bool MMC1::prg_size() const { - return r[0] & 0x08; -} - -unsigned MMC1::prg_addr(bool region) const { - unsigned addr, bank; - - //region(0) = $8000-bfff; region(1) = $c000-ffff - if(prg_size()) { //16K mode - bank = (region == 0 ? 0x0 : 0xf); //8000-bfff defaults to first bank; c000-ffff defaults to last bank - if(region != prg_mode()) { //if this is the active dynamic region ... - bank = prg_bank(); - } - } else { //32K mode - bank = (prg_bank() & ~1) + region; - } - addr = bank << 14; //<<14 = 16K - - //256K page selection (for 512K PRG ROMs) - if(prg_ex_select == 0) { - addr |= (chr_banklo() >> 4) << 18; //<<18 = 256K - } else { - addr |= (chr_bankhi() >> 4) << 18; - } - - return addr; -} - -//0 = 8K, 1 = 4K -bool MMC1::chr_mode() const { - return r[0] & 0x10; -} - -unsigned MMC1::chr_banklo() const { - if(chr_mode() == 0) return (r[1] & ~1) | 0; - return r[1]; -} - -unsigned MMC1::chr_bankhi() const { - if(chr_mode() == 0) return (r[1] & ~1) | 1; - return r[2]; -} - -unsigned MMC1::prg_bank() const { - return r[3] & 0x0f; -} - -bool MMC1::prg_ram_disable() const { - return r[3] & 0x10; -} - -uint8 MMC1::prg_read(unsigned addr) { - if((addr & 0xe000) == 0x6000) { - if(prg_ram_disable() == false) return prg_ram[addr & 0x1fff]; - return 0x00; - } - - if(addr & 0x8000) { - addr = prg_addr(addr & 0x4000) | (addr & 0x3fff); - return Mapper::prg_read(addr); - } - - return cpu.mdr(); -} - -void MMC1::prg_write(unsigned addr, uint8 data) { - if((addr & 0xe000) == 0x6000) { - if(prg_ram_disable() == false) prg_ram[addr & 0x1fff] = data; - return; - } - - if(addr & 0x8000) { - if(data & 0x80) { - shiftaddr = 0; - r[0] |= 0x0c; - } else { - shiftdata >>= 1; - shiftdata |= (data & 1) << 4; - if(++shiftaddr == 5) { - shiftaddr = 0; - r[(addr >> 13) & 3] = shiftdata; - } - } - return; - } -} - -uint8 MMC1::chr_read(unsigned addr) { - if(addr & 0x2000) { - return ppu.ciram_read(ciram_addr(addr)); - } - - prg_ex_select = addr & 0x1000; - - if(addr <= 0x0fff) { - addr = chr_banklo() * 0x1000 + (addr & 0x0fff); - return Mapper::chr_read(addr); - } - - if(addr <= 0x1fff) { - addr = chr_bankhi() * 0x1000 + (addr & 0x0fff); - return Mapper::chr_read(addr); - } - - throw; -} - -void MMC1::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) { - return ppu.ciram_write(ciram_addr(addr), data); - } - - prg_ex_select = addr & 0x1000; - - if(addr <= 0x0fff) { - if(cartridge.chr_ram == false) return; - addr = chr_banklo() * 0x1000 + (addr & 0x0fff); - return Mapper::chr_write(addr, data); - } - - if(addr <= 0x1fff) { - if(cartridge.chr_ram == false) return; - addr = chr_bankhi() * 0x1000 + (addr & 0x0fff); - return Mapper::chr_write(addr, data); - } - - throw; -} - -unsigned MMC1::ram_size() { - return 8192u; -} - -uint8* MMC1::ram_data() { - return prg_ram; -} - -void MMC1::power() { - reset(); -} - -void MMC1::reset() { - prg_ex_select = 0; - shiftaddr = 0; - shiftdata = 0; - - r[0] = 0x0c; - r[1] = 0x00; - r[2] = 0x01; - r[3] = 0x00; -} - -void MMC1::serialize(serializer &s) { - s.array(prg_ram); - s.array(r); - s.integer(prg_ex_select); - s.integer(shiftaddr); - s.integer(shiftdata); -} diff --git a/bsnes/nes/mapper/mmc1/mmc1.hpp b/bsnes/nes/mapper/mmc1/mmc1.hpp deleted file mode 100755 index 446270bf..00000000 --- a/bsnes/nes/mapper/mmc1/mmc1.hpp +++ /dev/null @@ -1,34 +0,0 @@ -struct MMC1 : Mapper { - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - unsigned ram_size(); - uint8* ram_data(); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - uint8 prg_ram[8192]; - uint8 r[4]; - bool prg_ex_select; - unsigned shiftaddr; - unsigned shiftdata; - - unsigned ciram_addr(unsigned addr) const; - bool prg_mode() const; - bool prg_size() const; - unsigned prg_addr(bool region) const; - bool chr_mode() const; - unsigned chr_banklo() const; - unsigned chr_bankhi() const; - unsigned prg_bank() const; - bool prg_ram_disable() const; -}; - -extern MMC1 mmc1; diff --git a/bsnes/nes/mapper/mmc3/mmc3.cpp b/bsnes/nes/mapper/mmc3/mmc3.cpp deleted file mode 100755 index d5a5c0f3..00000000 --- a/bsnes/nes/mapper/mmc3/mmc3.cpp +++ /dev/null @@ -1,213 +0,0 @@ -MMC3 mmc3; - -void MMC3::main() { - while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { - scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); - } - - if(irq_delay) irq_delay--; - cpu.set_irq_line(irq_line); - tick(); - } -} - -void MMC3::irq_test(uint16 addr) { - if(!(chr_abus & 0x1000) && (addr & 0x1000)) { - if(irq_delay == 0) { - if(irq_counter == 0) { - irq_counter = irq_latch; - } else if(--irq_counter == 0) { - if(irq_enable) irq_line = 1; - } - } - irq_delay = 6; - } - chr_abus = addr; -} - -unsigned MMC3::prg_addr(uint16 addr) { - if((addr & 0xe000) == 0x8000) { - if((bank_select & 0x40) != 0) return (0x3e << 13) | (addr & 0x1fff); - return (prg_bank[0] << 13) | (addr & 0x1fff); - } - - if((addr & 0xe000) == 0xa000) { - return (prg_bank[1] << 13) | (addr & 0x1fff); - } - - if((addr & 0xe000) == 0xc000) { - if((bank_select & 0x40) == 0) return (0x3e << 13) | (addr & 0x1fff); - return (prg_bank[0] << 13) | (addr & 0x1fff); - } - - if((addr & 0xe000) == 0xe000) { - return (0x3f << 13) | (addr & 0x1fff); - } - - throw; -} - -uint8 MMC3::prg_read(unsigned addr) { - if((addr & 0xe000) == 0x6000) { //$6000-7fff - if(prg_ram_enable) { - return prg_ram[addr & 0x1fff]; - } - } - - if(addr & 0x8000) { //$8000-ffff - return Mapper::prg_read(prg_addr(addr)); - } - - return cpu.mdr(); -} - -void MMC3::prg_write(unsigned addr, uint8 data) { - if((addr & 0xe000) == 0x6000) { //$6000-7fff - if(prg_ram_enable && prg_ram_write_protect == false) { - prg_ram[addr & 0x1fff] = data; - } - } - - switch(addr & 0xe001) { - case 0x8000: - bank_select = data & 0xc7; - break; - - case 0x8001: - switch(bank_select & 7) { - case 0: chr_bank[0] = data & ~1; break; - case 1: chr_bank[1] = data & ~1; break; - case 2: chr_bank[2] = data; break; - case 3: chr_bank[3] = data; break; - case 4: chr_bank[4] = data; break; - case 5: chr_bank[5] = data; break; - case 6: prg_bank[0] = data & 0x3f; break; - case 7: prg_bank[1] = data & 0x3f; break; - } - break; - - case 0xa000: - mirror_select = data & 0x01; - break; - - case 0xa001: - prg_ram_enable = data & 0x80; - prg_ram_write_protect = data & 0x40; - break; - - case 0xc000: - irq_latch = data; - break; - - case 0xc001: - irq_counter = 0; - break; - - case 0xe000: - irq_enable = false; - irq_line = 0; - cpu.set_irq_line(irq_line); - break; - - case 0xe001: - irq_enable = true; - break; - } -} - -unsigned MMC3::chr_addr(uint16 addr) { - if((bank_select & 0x80) == 0) { - if(addr <= 0x07ff) return (chr_bank[0] << 10) | (addr & 0x07ff); - if(addr <= 0x0fff) return (chr_bank[1] << 10) | (addr & 0x07ff); - if(addr <= 0x13ff) return (chr_bank[2] << 10) | (addr & 0x03ff); - if(addr <= 0x17ff) return (chr_bank[3] << 10) | (addr & 0x03ff); - if(addr <= 0x1bff) return (chr_bank[4] << 10) | (addr & 0x03ff); - if(addr <= 0x1fff) return (chr_bank[5] << 10) | (addr & 0x03ff); - } - - if((bank_select & 0x80) != 0) { - if(addr <= 0x03ff) return (chr_bank[2] << 10) | (addr & 0x03ff); - if(addr <= 0x07ff) return (chr_bank[3] << 10) | (addr & 0x03ff); - if(addr <= 0x0bff) return (chr_bank[4] << 10) | (addr & 0x03ff); - if(addr <= 0x0fff) return (chr_bank[5] << 10) | (addr & 0x03ff); - if(addr <= 0x17ff) return (chr_bank[0] << 10) | (addr & 0x07ff); - if(addr <= 0x1fff) return (chr_bank[1] << 10) | (addr & 0x07ff); - } - - throw; -} - -uint8 MMC3::chr_read(unsigned addr) { - irq_test(addr); - if(addr & 0x2000) return ppu.ciram_read(ciram_addr(addr)); - return Mapper::chr_read(chr_addr(addr)); -} - -void MMC3::chr_write(unsigned addr, uint8 data) { - irq_test(addr); - if(addr & 0x2000) return ppu.ciram_write(ciram_addr(addr), data); - return Mapper::chr_write(chr_addr(addr), data); -} - -unsigned MMC3::ciram_addr(uint13 addr) { - if(mirror_select == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff); - if(mirror_select == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff); - throw; -} - -unsigned MMC3::ram_size() { - return 8192u; -} - -uint8* MMC3::ram_data() { - return prg_ram; -} - -void MMC3::power() { - reset(); -} - -void MMC3::reset() { - bank_select = 0; - - prg_bank[0] = 0; - prg_bank[1] = 0; - - chr_bank[0] = 0; - chr_bank[1] = 0; - chr_bank[2] = 0; - chr_bank[3] = 0; - chr_bank[4] = 0; - chr_bank[5] = 0; - - mirror_select = 0; - prg_ram_enable = 1; - prg_ram_write_protect = 0; - - irq_latch = 0x00; - irq_counter = 0x00; - irq_enable = false; - irq_delay = 0; - irq_line = 0; - - chr_abus = 0; -} - -void MMC3::serialize(serializer &s) { - s.array(prg_ram); - - s.integer(bank_select); - s.array(prg_bank); - s.array(chr_bank); - s.integer(mirror_select); - s.integer(prg_ram_enable); - s.integer(prg_ram_write_protect); - s.integer(irq_latch); - s.integer(irq_counter); - s.integer(irq_enable); - s.integer(irq_delay); - s.integer(irq_line); - - s.integer(chr_abus); -} diff --git a/bsnes/nes/mapper/mmc3/mmc3.hpp b/bsnes/nes/mapper/mmc3/mmc3.hpp deleted file mode 100755 index d6394ff6..00000000 --- a/bsnes/nes/mapper/mmc3/mmc3.hpp +++ /dev/null @@ -1,41 +0,0 @@ -struct MMC3 : Mapper { - void main(); - - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - unsigned ram_size(); - uint8* ram_data(); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - uint8 prg_ram[8192]; - - uint8 bank_select; - uint8 prg_bank[2]; - uint8 chr_bank[6]; - bool mirror_select; - bool prg_ram_enable; - bool prg_ram_write_protect; - uint8 irq_latch; - uint8 irq_counter; - bool irq_enable; - unsigned irq_delay; - bool irq_line; - - uint16 chr_abus; - - void irq_test(uint16 addr); - unsigned prg_addr(uint16 addr); - unsigned chr_addr(uint16 addr); - unsigned ciram_addr(uint13 addr); -}; - -extern MMC3 mmc3; diff --git a/bsnes/nes/mapper/none/none.cpp b/bsnes/nes/mapper/none/none.cpp deleted file mode 100755 index a675da33..00000000 --- a/bsnes/nes/mapper/none/none.cpp +++ /dev/null @@ -1,34 +0,0 @@ -None none; - -uint8 None::prg_read(unsigned addr) { - if(addr & 0x8000) return Mapper::prg_read(addr); - return cpu.mdr(); -} - -void None::prg_write(unsigned addr, uint8 data) { -} - -uint8 None::chr_read(unsigned addr) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_read(addr & 0x07ff); - } - return Mapper::chr_read(addr); -} - -void None::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_write(addr & 0x07ff, data); - } - return Mapper::chr_write(addr, data); -} - -void None::power() { -} - -void None::reset() { -} - -void None::serialize(serializer &s) { -} diff --git a/bsnes/nes/mapper/none/none.hpp b/bsnes/nes/mapper/none/none.hpp deleted file mode 100755 index 957e501c..00000000 --- a/bsnes/nes/mapper/none/none.hpp +++ /dev/null @@ -1,14 +0,0 @@ -struct None : Mapper { - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); -}; - -extern None none; diff --git a/bsnes/nes/mapper/uorom/uorom.cpp b/bsnes/nes/mapper/uorom/uorom.cpp deleted file mode 100755 index 65d9f5a0..00000000 --- a/bsnes/nes/mapper/uorom/uorom.cpp +++ /dev/null @@ -1,45 +0,0 @@ -UOROM uorom; - -uint8 UOROM::prg_read(unsigned addr) { - if((addr & 0xc000) == 0x8000) { - return Mapper::prg_read((prg_bank << 14) | (addr & 0x3fff)); - } - - if((addr & 0xc000) == 0xc000) { - return Mapper::prg_read((0x0f << 14) | (addr & 0x3fff)); - } -} - -void UOROM::prg_write(unsigned addr, uint8 data) { - if(addr & 0x8000) prg_bank = data & 0x0f; -} - -uint8 UOROM::chr_read(unsigned addr) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_read(addr); - } - - return Mapper::chr_read(addr); -} - -void UOROM::chr_write(unsigned addr, uint8 data) { - if(addr & 0x2000) { - if(cartridge.mirroring == 0) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff); - return ppu.ciram_write(addr, data); - } - - return Mapper::chr_write(addr, data); -} - -void UOROM::power() { - reset(); -} - -void UOROM::reset() { - prg_bank = 0; -} - -void UOROM::serialize(serializer &s) { - s.integer(prg_bank); -} diff --git a/bsnes/nes/mapper/uorom/uorom.hpp b/bsnes/nes/mapper/uorom/uorom.hpp deleted file mode 100755 index 1c36c039..00000000 --- a/bsnes/nes/mapper/uorom/uorom.hpp +++ /dev/null @@ -1,17 +0,0 @@ -struct UOROM : Mapper { - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - void power(); - void reset(); - - void serialize(serializer&); - -private: - uint4 prg_bank; -}; - -extern UOROM uorom; diff --git a/bsnes/nes/mapper/vrc6/vrc6.hpp b/bsnes/nes/mapper/vrc6/vrc6.hpp deleted file mode 100755 index 395b52f6..00000000 --- a/bsnes/nes/mapper/vrc6/vrc6.hpp +++ /dev/null @@ -1,69 +0,0 @@ -struct VRC6 : Mapper { - void main(); - - uint8 prg_read(unsigned addr); - void prg_write(unsigned addr, uint8 data); - - uint8 chr_read(unsigned addr); - void chr_write(unsigned addr, uint8 data); - - unsigned ram_size(); - uint8* ram_data(); - - void power(); - void reset(); - - void serialize(serializer&); - -//privileged: - bool abus_swap; - -private: - uint8 prg_ram[8192]; - - uint8 prg_bank[2]; - uint8 chr_bank[8]; - uint2 mirror_select; - uint8 irq_latch; - bool irq_mode; - bool irq_enable; - bool irq_acknowledge; - - uint8 irq_counter; - signed irq_scalar; - bool irq_line; - - struct Pulse { - bool mode; - uint3 duty; - uint4 volume; - bool enable; - uint12 frequency; - - uint12 divider; - uint4 cycle; - uint4 output; - - void clock(); - void serialize(serializer&); - } pulse1, pulse2; - - struct Sawtooth { - uint6 rate; - bool enable; - uint12 frequency; - - uint12 divider; - uint1 phase; - uint3 stage; - uint8 accumulator; - uint5 output; - - void clock(); - void serialize(serializer&); - } sawtooth; - - unsigned ciram_addr(unsigned addr) const; -}; - -extern VRC6 vrc6; diff --git a/bsnes/ui/general/main-window.cpp b/bsnes/ui/general/main-window.cpp index e4b8e31d..c9f5ec73 100755 --- a/bsnes/ui/general/main-window.cpp +++ b/bsnes/ui/general/main-window.cpp @@ -326,7 +326,7 @@ void MainWindow::synchronize() { void MainWindow::setupVideoFilters() { lstring files = directory::files({ application->basepath, "filters/" }, "*.filter"); - if(files.size() == 0) directory::files({ application->userpath, "filters/" }, "*.filter"); + if(files.size() == 0) files = directory::files({ application->userpath, "filters/" }, "*.filter"); reference_array group; settingsVideoFilterList = new RadioItem[files.size()]; diff --git a/bsnes/ui/interface/interface.cpp b/bsnes/ui/interface/interface.cpp index fde7d33f..a42ae023 100755 --- a/bsnes/ui/interface/interface.cpp +++ b/bsnes/ui/interface/interface.cpp @@ -44,7 +44,7 @@ void Interface::setController(unsigned port, unsigned device) { } void Interface::updateDSP() { - dspaudio.setVolume((double)config->audio.volume / 100.0); + dspaudio.setVolume(config->audio.mute == false ? (double)config->audio.volume / 100.0 : 0.0); switch(mode()) { case Mode::NES: return dspaudio.setFrequency(config->audio.frequencyNES); case Mode::SNES: return dspaudio.setFrequency(config->audio.frequencySNES); diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index b227de8d..b331f1f8 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -49,7 +49,7 @@ Application::Application(int argc, char **argv) { inputManager = new InputManager; utility = new Utility; - title = "bsnes v082.26"; + title = "bsnes v082.27"; string fontFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Tahoma, " : "Sans, "; normalFont = { fontFamily, "8" }; diff --git a/bsnes/ui/tools/cheat-editor.cpp b/bsnes/ui/tools/cheat-editor.cpp index 9a517659..a65d789d 100755 --- a/bsnes/ui/tools/cheat-editor.cpp +++ b/bsnes/ui/tools/cheat-editor.cpp @@ -161,11 +161,11 @@ bool CheatEditor::save(const string &filename) { file fp; if(fp.open(filename, file::mode::write) == false) return false; - fp.print("cartridge sha256=", interface->sha256(), "\n"); + fp.print("cartridge sha256=`", interface->sha256(), "`\n"); for(unsigned n = 0; n <= lastSave; n++) { fp.print(" cheat", cheatList.checked(n) ? " enable" : "", "\n"); - fp.print(" description=|", cheatText[n][Desc], "|\n"); - fp.print(" code=|", cheatText[n][Code], "|\n"); + fp.print(" description=`", string{cheatText[n][Desc]}.transform("`", "'"), "`\n"); + fp.print(" code=`", string{cheatText[n][Code]}.transform("`", "'"), "`\n"); } fp.close();