From: slack Date: Sat, 19 Jul 2008 22:48:48 +0000 (+0200) Subject: MBC1 Implemented X-Git-Tag: v0.1~17 X-Git-Url: http://slack.codemaniacs.com/git/?a=commitdiff_plain;h=61b02d3ac7c4f20d9a91b99b2bb9c544954109c3;p=wenboi.git MBC1 Implemented --- diff --git a/MBC.cc b/MBC.cc index 5437dbd..6dc90ed 100644 --- a/MBC.cc +++ b/MBC.cc @@ -1,18 +1,15 @@ #include "MBC.h" -#include "Logger.h" -#include -#include -#include -#include +#include "NoMBC.h" +#include "MBC1.h" -using namespace cartridge_types; +#include "Logger.h" MBC *create_MBC(GBRom *rom) { switch (rom->header.cartridge_type) { - case ROM_ONLY: return new NoMBC(rom); - //case MBC1: return new MBC1(rom); + case cartridge_types::ROM_ONLY: return new NoMBC(rom); + case cartridge_types::MBC1: return new MBC1(rom); default: logger.critical("Unsupported cartridge type ", int(rom->header.cartridge_type)); @@ -20,40 +17,3 @@ MBC *create_MBC(GBRom *rom) } } -u8 NoMBC::read(int addr) const -{ - if (addr <= 0x7FFF) - return ROM[addr]; - else //if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) - return RAM[addr-0xA000]; - //else - // logger.error("NoMBC: Incorrect read"); - return 0; -} - -u16 NoMBC::read16(int addr) const -{ - if (addr <= 0x7FFF) - return ROM[addr]+(ROM[addr+1] << 8); - else //if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) - return RAM[addr-0xA000] + (RAM[addr-0xA000+1] << 8); - //else - // logger.error("NoMBC: Incorrect read"); - return 0; -} - -void NoMBC::write(int addr, u8 value) -{ - if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) - { - RAM[addr-0xA000]=value; - return; - } - else - { - std::ostringstream errmsg; - errmsg <<"NoMBC: trying to write in ROM, addr=0x"<data, 32768); } - u8 read (int addr) const; - void write(int addr, u8 value); - - u16 read16(int addr) const; -}; - MBC *create_MBC(GBRom *rom); diff --git a/MBC1.cc b/MBC1.cc new file mode 100644 index 0000000..1b35e02 --- /dev/null +++ b/MBC1.cc @@ -0,0 +1,98 @@ +#include "MBC1.h" +#include "Logger.h" + +#include +#include + +u8 MBC1::read(u16 addr) const +{ + if (addr <= 0x3FFF) // ROM Bank 0 + return ROM[addr]; + else if (addr <= 0x7FFF) // ROM (switchable) + { + u8 rom_bank = rom_bank_low; + if (mode == ROM_BANKING_MODE) rom_bank |= (ram_bank << 5); + + u32 base = 16384*rom_bank; + return ROM[base + (addr-0x4000)]; + } + else // if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + { + if (ram_enabled) + { + u32 base = (mode == RAM_BANKING_MODE ? 8192*ram_bank : 0); + return RAM[base + (addr-0xA000)]; + } + else return 0xFF; + } + //else + // logger.error("MBC1: Incorrect read"); + return 0; +} + +u16 MBC1::read16(u16 addr) const +{ + assert (addr != 0x3FFF); + assert (addr != 0x7FFF); + assert (addr != 0xBFFF); + + if (addr <= 0x3FFF) // ROM Bank 0 + return ROM[addr] | (ROM[addr+1] << 8); + else if (addr <= 0x7FFF) // ROM (switchable) + { + u8 rom_bank = rom_bank_low; + if (mode == ROM_BANKING_MODE) rom_bank |= (ram_bank << 5); + + u32 offset = 16384*rom_bank + (addr-0x4000); + return ROM[offset] | (ROM[offset+1] << 8); + } + else // if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + { + if (ram_enabled) + { + u32 base = (mode == RAM_BANKING_MODE ? 8192*ram_bank : 0); + u32 offset = base + (addr-0xA000); + return RAM[offset] | (RAM[offset+1] << 8); + } + else return 0xFFFF; + } + //else + // logger.error("MBC1: Incorrect read"); + return 0; +} + +void MBC1::write(u16 addr, u8 value) +{ + if (addr <= 0x1FFF) + { + if ((value & 0x0F) == 0x0A) + ram_enabled = true; + else + ram_enabled = false; + } + else if (addr <= 0x3FFF) + { + rom_bank_low = value & 0x1F; + if (rom_bank_low == 0) rom_bank_low = 1; + } + else if (addr <= 0x5FFF) + { + ram_bank = value & 0x03; + } + else if (addr <= 0x7FFF) + { + mode = BankingMode(value & 1); + } + else if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + { + u32 base = (mode == RAM_BANKING_MODE ? 8192*ram_bank : 0); + RAM[base + (addr-0xA000)]=value; + return; + } + else + { + logger.debug("MBC1: trying to write in ROM, addr=0x",std::hex,addr); + } +} + + diff --git a/MBC1.h b/MBC1.h new file mode 100644 index 0000000..ac23e2c --- /dev/null +++ b/MBC1.h @@ -0,0 +1,35 @@ +#ifndef MBC1_H +#define MBC1_H + + +#include "MBC.h" + + +class MBC1: public MBC +{ + u8 ROM[128*16384]; + u8 RAM[ 4* 8192]; + + u8 rom_bank_low; + u8 ram_bank; + bool ram_enabled; + + enum BankingMode + { + ROM_BANKING_MODE=0, + RAM_BANKING_MODE=1 + } mode; + + public: + MBC1(GBRom *rom): rom_bank_low(1), ram_bank(0), ram_enabled(false), mode(ROM_BANKING_MODE) + { + memcpy(ROM, rom->data, 32768 << rom->header.rom_size); + } + + u8 read (u16 addr) const; + u16 read16(u16 addr) const; + void write (u16 addr, u8 value); +}; + +#endif + diff --git a/Makefile b/Makefile index 75f4b6a..b9f3565 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ -CXXFLAGS=-pg -O3 -g -Wall -Weffc++ -Wstrict-null-sentinel -Wold-style-cast \ +#CXXFLAGS=-pg -O3 -g -Wall -Weffc++ -Wstrict-null-sentinel -Wold-style-cast +CXXFLAGS=-pg -O3 -g -Wall -Weffc++ -Wold-style-cast \ -Woverloaded-virtual $(shell sdl-config --cflags) LDFLAGS=-pg -g $(shell sdl-config --libs) @@ -15,7 +16,13 @@ GBVideo.o: GBVideo.cc GBVideo.h Logger.h util.h gbcore.h GBMemory.o: GBMemory.cc GBMemory.h Logger.h MBC.h gbcore.h g++ $(CXXFLAGS) -c -o $@ $< -MBC.o: MBC.cc MBC.h Logger.h +MBC.o: MBC.cc MBC.h Logger.h NoMBC.h MBC1.h + g++ $(CXXFLAGS) -c -o $@ $< + +NoMBC.o: NoMBC.cc NoMBC.h Logger.h + g++ $(CXXFLAGS) -c -o $@ $< + +MBC1.o: MBC1.cc MBC1.h Logger.h g++ $(CXXFLAGS) -c -o $@ $< gbcore.o: gbcore.cc gbcore.h opcodes.h disasm.h \ @@ -23,11 +30,11 @@ gbcore.o: gbcore.cc gbcore.h opcodes.h disasm.h \ g++ $(CXXFLAGS) -c -o $@ $< tests/test_gbrom: GBRom.cc GBRom.h - g++ $(CXXFLAGS) $(LDFLAGS) -DTEST_GBROM -o $@ GBRom.cc + g++ $(CXXFLAGS) -DTEST_GBROM -o $@ GBRom.cc $(LDFLAGS) tests/test_core: tests/test_core.cc gbcore.o MBC.o GBMemory.o GBRom.o \ - GBVideo.o util.o - g++ $(CXXFLAGS) $(LDFLAGS) -o $@ $^ + GBVideo.o util.o NoMBC.o MBC1.o + g++ $(CXXFLAGS) -o $@ $^ $(LDFLAGS) clean: rm -f *.o tests/test_gbrom tests/test_core diff --git a/NoMBC.cc b/NoMBC.cc new file mode 100644 index 0000000..1f13c40 --- /dev/null +++ b/NoMBC.cc @@ -0,0 +1,44 @@ +#include "NoMBC.h" +#include "Logger.h" + +#include + +u8 NoMBC::read(u16 addr) const +{ + if (addr <= 0x7FFF) + return ROM[addr]; + else //if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + return RAM[addr-0xA000]; + //else + // logger.error("NoMBC: Incorrect read"); + return 0; +} + +u16 NoMBC::read16(u16 addr) const +{ + if (addr <= 0x7FFF) + return ROM[addr] | (ROM[addr+1] << 8); + else //if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + { + u16 offset = addr - 0xA000; + return RAM[offset] | (RAM[offset+1] << 8); + } + //else + // logger.error("NoMBC: Incorrect read"); + return 0; +} + +void NoMBC::write(u16 addr, u8 value) +{ + if ((addr&0xE000) == 0xA000) //(addr >= 0xA000 && addr <= 0xBFFF) + { + RAM[addr-0xA000]=value; + return; + } + else + { + logger.debug("NoMBC: trying to write in ROM, addr=0x", std::hex, addr); + } +} + + diff --git a/NoMBC.h b/NoMBC.h new file mode 100644 index 0000000..81b3fd3 --- /dev/null +++ b/NoMBC.h @@ -0,0 +1,19 @@ +#ifndef NOMBC_H +#define NOMBC_H + +#include "MBC.h" + +class NoMBC: public MBC +{ + u8 ROM[32768]; + u8 RAM[8192]; + + public: + NoMBC(GBRom *rom) { memcpy(ROM, rom->data, 32768); } + u8 read (u16 addr) const; + u16 read16(u16 addr) const; + void write (u16 addr, u8 value); + +}; + +#endif