bsnes/higan/fc/cartridge/board/nes-sxrom.cpp

100 lines
2.1 KiB
C++
Raw Normal View History

struct NES_SxROM : Board {
NES_SxROM(Markup::Node& document) : Board(document), mmc1(*this) {
revision = Revision::SXROM;
}
auto main() -> void {
return mmc1.main();
Update to v082r31 release. byuu says: Enable Overscan->Mask Overscan [best I'm doing] Video settings -> Overscan mask: (horizontal, vertical: 0-16 on each side) [only works on NES+SNES] BPS patching works for NES+SNES+GB; note that long-term I want BPS to only patch headerless PRG+CHR files, but we'll need a database / completed board mapping system first. MMC1 splits the board/chip markups a bit better. My attempts to emulate the extra CHR bits per hardware fail repeatedly. Docs do not explain how it works at all. Emulated enough of the MMC5 to play Castlevania 3. The MMC5 is easily the most complicated mapper the NES has to offer, and of course, has the most pitifully vague and difficult documentation of any mapper around. It seems the only way anyone is able to emulate this chip is empirically. Everyone else apparently hooks the MMC5 right into the PPU core, which I of course cannot do. So I had to come up with my own (probably wrong) way to synchronize the PPU simply by observing CHR bus accesses. I must say, I over-estimated how well fleshed out the NES hardware documentation was. Shit hits the fan right after MMC3. It's miles beyond the GB scene, but I find myself wanting for someone with the technical writing ability of anomie. I can't find anything at all on how we're supposed to support the $2007 port reads/writes without it extra-clocking the PPU's bus, which could throw off mapper timing. Absolutely nothing at all on the subject anywhere, something everybody is required to do for all cycle-based emulators and ... nada. Anyway, I'd like to refine the MMC5 a bit, getting Just Breed playable even without sound would be really nice (it's a fun game.) Then we need to get libsnes building again (ugh, getting worn out in backporting changes to it.) Once v083 is public, we can start discussing a new API for multiple emulators.
2011-10-06 09:53:16 +00:00
}
auto ram_addr(uint addr) -> uint {
uint bank = 0;
if(revision == Revision::SOROM) bank = (mmc1.chr_bank[0] & 0x08) >> 3;
if(revision == Revision::SUROM) bank = (mmc1.chr_bank[0] & 0x0c) >> 2;
if(revision == Revision::SXROM) bank = (mmc1.chr_bank[0] & 0x0c) >> 2;
return (bank << 13) | (addr & 0x1fff);
Update to v082r31 release. byuu says: Enable Overscan->Mask Overscan [best I'm doing] Video settings -> Overscan mask: (horizontal, vertical: 0-16 on each side) [only works on NES+SNES] BPS patching works for NES+SNES+GB; note that long-term I want BPS to only patch headerless PRG+CHR files, but we'll need a database / completed board mapping system first. MMC1 splits the board/chip markups a bit better. My attempts to emulate the extra CHR bits per hardware fail repeatedly. Docs do not explain how it works at all. Emulated enough of the MMC5 to play Castlevania 3. The MMC5 is easily the most complicated mapper the NES has to offer, and of course, has the most pitifully vague and difficult documentation of any mapper around. It seems the only way anyone is able to emulate this chip is empirically. Everyone else apparently hooks the MMC5 right into the PPU core, which I of course cannot do. So I had to come up with my own (probably wrong) way to synchronize the PPU simply by observing CHR bus accesses. I must say, I over-estimated how well fleshed out the NES hardware documentation was. Shit hits the fan right after MMC3. It's miles beyond the GB scene, but I find myself wanting for someone with the technical writing ability of anomie. I can't find anything at all on how we're supposed to support the $2007 port reads/writes without it extra-clocking the PPU's bus, which could throw off mapper timing. Absolutely nothing at all on the subject anywhere, something everybody is required to do for all cycle-based emulators and ... nada. Anyway, I'd like to refine the MMC5 a bit, getting Just Breed playable even without sound would be really nice (it's a fun game.) Then we need to get libsnes building again (ugh, getting worn out in backporting changes to it.) Once v083 is public, we can start discussing a new API for multiple emulators.
2011-10-06 09:53:16 +00:00
}
auto prg_read(uint addr) -> uint8 {
if((addr & 0xe000) == 0x6000) {
if(revision == Revision::SNROM) {
if(mmc1.chr_bank[0] & 0x10) return cpu.mdr();
}
if(mmc1.ram_disable) return 0x00;
return prgram.read(ram_addr(addr));
}
if(addr & 0x8000) {
addr = mmc1.prg_addr(addr);
if(revision == Revision::SXROM) {
addr |= ((mmc1.chr_bank[0] & 0x10) >> 4) << 18;
}
return prgrom.read(addr);
}
return cpu.mdr();
}
Update to v082r31 release. byuu says: Enable Overscan->Mask Overscan [best I'm doing] Video settings -> Overscan mask: (horizontal, vertical: 0-16 on each side) [only works on NES+SNES] BPS patching works for NES+SNES+GB; note that long-term I want BPS to only patch headerless PRG+CHR files, but we'll need a database / completed board mapping system first. MMC1 splits the board/chip markups a bit better. My attempts to emulate the extra CHR bits per hardware fail repeatedly. Docs do not explain how it works at all. Emulated enough of the MMC5 to play Castlevania 3. The MMC5 is easily the most complicated mapper the NES has to offer, and of course, has the most pitifully vague and difficult documentation of any mapper around. It seems the only way anyone is able to emulate this chip is empirically. Everyone else apparently hooks the MMC5 right into the PPU core, which I of course cannot do. So I had to come up with my own (probably wrong) way to synchronize the PPU simply by observing CHR bus accesses. I must say, I over-estimated how well fleshed out the NES hardware documentation was. Shit hits the fan right after MMC3. It's miles beyond the GB scene, but I find myself wanting for someone with the technical writing ability of anomie. I can't find anything at all on how we're supposed to support the $2007 port reads/writes without it extra-clocking the PPU's bus, which could throw off mapper timing. Absolutely nothing at all on the subject anywhere, something everybody is required to do for all cycle-based emulators and ... nada. Anyway, I'd like to refine the MMC5 a bit, getting Just Breed playable even without sound would be really nice (it's a fun game.) Then we need to get libsnes building again (ugh, getting worn out in backporting changes to it.) Once v083 is public, we can start discussing a new API for multiple emulators.
2011-10-06 09:53:16 +00:00
auto prg_write(uint addr, uint8 data) -> void {
if((addr & 0xe000) == 0x6000) {
if(revision == Revision::SNROM) {
if(mmc1.chr_bank[0] & 0x10) return;
}
if(mmc1.ram_disable) return;
return prgram.write(ram_addr(addr), data);
}
if(addr & 0x8000) return mmc1.mmio_write(addr, data);
}
auto chr_read(uint addr) -> uint8 {
Update to v099r10 release. byuu says: Changelog: - higan/profile/ => higan/systems/ [temporary; unless we can't think of a better base folder name] - god-damn-better-have fixed the input polling bug - re-added command-line and drag-and-drop loading - command-line loading can now load multiple folders at once (SGB+GB game; Sufami Turbo+Slot A+Slot B; etc) - if you load just the base cart, it'll present you with a dialog to optionally load slotted cart(s) - MSU1 now goes through nall/vfs instead of directly accessing the filesystem - Famicom Cartridge, PPU cores updated to newer programming style - there's countless opportunity for BitField and .bits() in the PPU ... but I'm worried about breaking things If anyone has a working MSU1 game and can test the changes out, that'd be appreciated. I still don't have a test ROM on my dev box. I wouldn't worry too much about extensively testing the Famicom PPU changes just yet ... I'm still struggling with what to name the structs inside the classes between all of my emulators, and the BitField/.bits() changes will be much more important to test at a later date. The only use case left for Emulator::Interface::path(uint id) is for 21fx emulation. This peripheral loads a DLL/SO via LoadLibrary/dlopen, which do not have any official ways to open a file in RAM. I'm very hesitant to use the portable trick of writing the memory to a temporary file, loading it, and deleting the temporary file once done ... it's a real waste of disk activity. I might make something like vfs::file::isVirtual->bool,path()->string to get around this. But even once I do, the underlying LoadLibrary/dlopen call is still going to be direct disk access.
2016-06-26 08:54:12 +00:00
if(addr & 0x2000) return ppu.readCIRAM(mmc1.ciram_addr(addr));
return Board::chr_read(mmc1.chr_addr(addr));
}
auto chr_write(uint addr, uint8 data) -> void {
Update to v099r10 release. byuu says: Changelog: - higan/profile/ => higan/systems/ [temporary; unless we can't think of a better base folder name] - god-damn-better-have fixed the input polling bug - re-added command-line and drag-and-drop loading - command-line loading can now load multiple folders at once (SGB+GB game; Sufami Turbo+Slot A+Slot B; etc) - if you load just the base cart, it'll present you with a dialog to optionally load slotted cart(s) - MSU1 now goes through nall/vfs instead of directly accessing the filesystem - Famicom Cartridge, PPU cores updated to newer programming style - there's countless opportunity for BitField and .bits() in the PPU ... but I'm worried about breaking things If anyone has a working MSU1 game and can test the changes out, that'd be appreciated. I still don't have a test ROM on my dev box. I wouldn't worry too much about extensively testing the Famicom PPU changes just yet ... I'm still struggling with what to name the structs inside the classes between all of my emulators, and the BitField/.bits() changes will be much more important to test at a later date. The only use case left for Emulator::Interface::path(uint id) is for 21fx emulation. This peripheral loads a DLL/SO via LoadLibrary/dlopen, which do not have any official ways to open a file in RAM. I'm very hesitant to use the portable trick of writing the memory to a temporary file, loading it, and deleting the temporary file once done ... it's a real waste of disk activity. I might make something like vfs::file::isVirtual->bool,path()->string to get around this. But even once I do, the underlying LoadLibrary/dlopen call is still going to be direct disk access.
2016-06-26 08:54:12 +00:00
if(addr & 0x2000) return ppu.writeCIRAM(mmc1.ciram_addr(addr), data);
return Board::chr_write(mmc1.chr_addr(addr), data);
}
auto power() -> void {
mmc1.power();
}
auto reset() -> void {
mmc1.reset();
}
auto serialize(serializer& s) -> void {
Board::serialize(s);
mmc1.serialize(s);
}
enum class Revision : uint {
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;
};