mirror of https://github.com/bsnes-emu/bsnes.git
Update to release v000r10.
byuu says: Changelog: - fixed LYC interrupt at LY=0 (fixes Makai Toushi SaGa) - fixed MBC3 ROM bank mapping (fixes Harvest Moon GBC) - added Super Game Boy MLT_REQ support to JOYP, needed for ICD2-R emulation - temporarily changed System::run() to execute only four cycles before exiting for bsnes, will make two versions later - uses actual boot ROMs, has DMG+SGB1 for now. Need SGB2, don't care about CGB. Defaults to SGB1, no way to select just yet. DMG 4-second wait is annoying. Does not force games to act like SGB on bgameboy itself, because that has no ICD2 and fails the required MLT_REQ check
This commit is contained in:
parent
2d49a4408d
commit
f0796e546e
4
Makefile
4
Makefile
|
@ -7,7 +7,7 @@ c := $(compiler) -std=gnu99
|
|||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -I.
|
||||
link :=
|
||||
objects :=
|
||||
objects := libco
|
||||
|
||||
# profile-guided instrumentation
|
||||
# flags += -fprofile-generate
|
||||
|
@ -44,6 +44,8 @@ compile = \
|
|||
|
||||
all: build;
|
||||
|
||||
obj/libco.o: libco/libco.c libco/*
|
||||
|
||||
include $(gameboy)/Makefile
|
||||
include $(ui)/Makefile
|
||||
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
gameboy_objects := libco
|
||||
gameboy_objects += gameboy-system gameboy-scheduler
|
||||
gameboy_objects := gameboy-system gameboy-scheduler
|
||||
gameboy_objects += gameboy-memory gameboy-cartridge
|
||||
gameboy_objects += gameboy-cpu gameboy-lcd
|
||||
objects += $(gameboy_objects)
|
||||
|
||||
obj/libco.o: libco/libco.c libco/*
|
||||
|
||||
obj/gameboy-system.o: $(gameboy)/system/system.cpp $(call rwildcard,$(gameboy)/system/)
|
||||
obj/gameboy-scheduler.o: $(gameboy)/scheduler/scheduler.cpp $(call rwildcard,$(gameboy)/scheduler/)
|
||||
obj/gameboy-cartridge.o: $(gameboy)/cartridge/cartridge.cpp $(call rwildcard,$(gameboy)/cartridge/)
|
||||
|
|
|
@ -64,7 +64,7 @@ void Cartridge::load(uint8_t *data, unsigned size) {
|
|||
case 0xfe: info.mapper = Mapper::HuC3; break;
|
||||
case 0xff: info.mapper = Mapper::HuC1; info.ram = true; info.battery = true; break;
|
||||
}
|
||||
print("Mapper: ", hex<2>(romdata[0x0147]), "\n");
|
||||
//print("Mapper: ", hex<2>(romdata[0x0147]), "\n");
|
||||
|
||||
switch(romdata[0x0148]) { default:
|
||||
case 0x00: info.romsize = 2 * 16 * 1024; break;
|
||||
|
@ -103,8 +103,6 @@ void Cartridge::unload() {
|
|||
}
|
||||
|
||||
uint8 Cartridge::rom_read(unsigned addr) {
|
||||
//if(addr >= 0x028000) print(hex<6>(addr), " - ", romsize, "\n");
|
||||
|
||||
if(addr >= romsize) addr %= romsize;
|
||||
return romdata[addr];
|
||||
}
|
||||
|
@ -135,7 +133,10 @@ void Cartridge::power() {
|
|||
mmm01.power();
|
||||
huc1.power();
|
||||
huc3.power();
|
||||
map();
|
||||
}
|
||||
|
||||
void Cartridge::map() {
|
||||
MMIO *mapper = 0;
|
||||
switch(info.mapper) { default:
|
||||
case Mapper::MBC0: mapper = &mbc0; break;
|
||||
|
|
|
@ -52,6 +52,7 @@ struct Cartridge : property<Cartridge> {
|
|||
void ram_write(unsigned addr, uint8 data);
|
||||
|
||||
void power();
|
||||
void map();
|
||||
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
|
|
|
@ -24,7 +24,7 @@ uint8 Cartridge::MBC3::mmio_read(uint16 addr) {
|
|||
}
|
||||
|
||||
if((addr & 0xc000) == 0x4000) { //4000-7fff
|
||||
return cartridge.rom_read((rom_select << 13) | (addr & 0x3fff));
|
||||
return cartridge.rom_read((rom_select << 14) | (addr & 0x3fff));
|
||||
}
|
||||
|
||||
if((addr & 0xe000) == 0xa000) { //a000-bfff
|
||||
|
|
|
@ -82,9 +82,9 @@ void CPU::power() {
|
|||
for(unsigned n = 0; n < 8192; n++) wram[n] = 0x00;
|
||||
for(unsigned n = 0; n < 128; n++) hram[n] = 0x00;
|
||||
|
||||
r[PC] = 0x0100;
|
||||
r[SP] = 0xfffe;
|
||||
r[AF] = 0x0100;
|
||||
r[PC] = 0x0000;
|
||||
r[SP] = 0x0000;
|
||||
r[AF] = 0x0000;
|
||||
r[BC] = 0x0000;
|
||||
r[DE] = 0x0000;
|
||||
r[HL] = 0x0000;
|
||||
|
@ -102,6 +102,7 @@ void CPU::power() {
|
|||
status.p15 = 0;
|
||||
status.p14 = 0;
|
||||
status.joyp = 0;
|
||||
status.mlt_req = 0;
|
||||
|
||||
status.div = 0;
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ struct CPU : Processor, MMIO {
|
|||
bool p15;
|
||||
bool p14;
|
||||
uint8 joyp;
|
||||
uint8 mlt_req;
|
||||
|
||||
//$ff04 DIV
|
||||
uint8 div;
|
||||
|
|
|
@ -14,6 +14,7 @@ void CPU::mmio_joyp_poll() {
|
|||
dpad |= system.interface->input_poll((unsigned)Input::Right) << 0;
|
||||
|
||||
status.joyp = 0x0f;
|
||||
if(status.p15 == 1 && status.p14 == 1) status.joyp -= status.mlt_req;
|
||||
if(status.p15 == 0) status.joyp &= button ^ 0x0f;
|
||||
if(status.p14 == 0) status.joyp &= dpad ^ 0x0f;
|
||||
if(status.joyp != 0x0f) interrupt_raise(Interrupt::Joypad);
|
||||
|
@ -74,6 +75,7 @@ void CPU::mmio_write(uint16 addr, uint8 data) {
|
|||
if(addr == 0xff00) { //JOYP
|
||||
status.p15 = data & 0x20;
|
||||
status.p14 = data & 0x10;
|
||||
system.interface->joyp_write(status.p15, status.p14);
|
||||
mmio_joyp_poll();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#include "opcode.cpp"
|
||||
|
||||
void CPU::add_clocks(unsigned clocks) {
|
||||
system.clocks_executed += clocks;
|
||||
scheduler.exit();
|
||||
|
||||
status.clock += clocks;
|
||||
if(status.clock >= 4 * 1024 * 1024) {
|
||||
status.clock -= 4 * 1024 * 1024;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
namespace GameBoy {
|
||||
namespace Info {
|
||||
static const char Name[] = "bgameboy";
|
||||
static const char Version[] = "000.09";
|
||||
static const char Version[] = "000.10";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,9 @@ namespace GameBoy {
|
|||
inline Processor() : thread(0) {}
|
||||
};
|
||||
|
||||
#include <gameboy/memory/memory.hpp>
|
||||
#include <gameboy/system/system.hpp>
|
||||
#include <gameboy/scheduler/scheduler.hpp>
|
||||
#include <gameboy/memory/memory.hpp>
|
||||
#include <gameboy/cartridge/cartridge.hpp>
|
||||
#include <gameboy/cpu/cpu.hpp>
|
||||
#include <gameboy/lcd/lcd.hpp>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
class Interface {
|
||||
public:
|
||||
virtual void joyp_write(bool p15, bool p14) {}
|
||||
|
||||
virtual void video_refresh(const uint8_t *data) {}
|
||||
virtual void audio_sample(signed left, signed right) {}
|
||||
virtual void input_poll() {}
|
||||
|
|
|
@ -30,19 +30,18 @@ void LCD::add_clocks(unsigned clocks) {
|
|||
|
||||
void LCD::scanline() {
|
||||
status.lx -= 456;
|
||||
status.ly++;
|
||||
if(++status.ly == 154) frame();
|
||||
|
||||
if(status.interrupt_lyc == true) {
|
||||
if(status.ly == status.lyc) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
|
||||
if(status.ly < 144) render();
|
||||
|
||||
if(status.ly == 144) {
|
||||
cpu.interrupt_raise(CPU::Interrupt::Vblank);
|
||||
if(status.interrupt_vblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
|
||||
}
|
||||
if(status.ly == 154) frame();
|
||||
|
||||
if(status.ly < 144) render();
|
||||
}
|
||||
|
||||
void LCD::frame() {
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#ifdef SYSTEM_CPP
|
||||
|
||||
//MD5SUM = 32fbbd84168d3482956eb3c5051637f5
|
||||
const uint8_t System::BootROM::dmg[256] = {
|
||||
0x31,0xfe,0xff,0xaf,0x21,0xff,0x9f,0x32,0xcb,0x7c,0x20,0xfb,0x21,0x26,0xff,0x0e,
|
||||
0x11,0x3e,0x80,0x32,0xe2,0x0c,0x3e,0xf3,0xe2,0x32,0x3e,0x77,0x77,0x3e,0xfc,0xe0,
|
||||
0x47,0x11,0x04,0x01,0x21,0x10,0x80,0x1a,0xcd,0x95,0x00,0xcd,0x96,0x00,0x13,0x7b,
|
||||
0xfe,0x34,0x20,0xf3,0x11,0xd8,0x00,0x06,0x08,0x1a,0x13,0x22,0x23,0x05,0x20,0xf9,
|
||||
0x3e,0x19,0xea,0x10,0x99,0x21,0x2f,0x99,0x0e,0x0c,0x3d,0x28,0x08,0x32,0x0d,0x20,
|
||||
0xf9,0x2e,0x0f,0x18,0xf3,0x67,0x3e,0x64,0x57,0xe0,0x42,0x3e,0x91,0xe0,0x40,0x04,
|
||||
0x1e,0x02,0x0e,0x0c,0xf0,0x44,0xfe,0x90,0x20,0xfa,0x0d,0x20,0xf7,0x1d,0x20,0xf2,
|
||||
0x0e,0x13,0x24,0x7c,0x1e,0x83,0xfe,0x62,0x28,0x06,0x1e,0xc1,0xfe,0x64,0x20,0x06,
|
||||
0x7b,0xe2,0x0c,0x3e,0x87,0xe2,0xf0,0x42,0x90,0xe0,0x42,0x15,0x20,0xd2,0x05,0x20,
|
||||
0x4f,0x16,0x20,0x18,0xcb,0x4f,0x06,0x04,0xc5,0xcb,0x11,0x17,0xc1,0xcb,0x11,0x17,
|
||||
0x05,0x20,0xf5,0x22,0x23,0x22,0x23,0xc9,0xce,0xed,0x66,0x66,0xcc,0x0d,0x00,0x0b,
|
||||
0x03,0x73,0x00,0x83,0x00,0x0c,0x00,0x0d,0x00,0x08,0x11,0x1f,0x88,0x89,0x00,0x0e,
|
||||
0xdc,0xcc,0x6e,0xe6,0xdd,0xdd,0xd9,0x99,0xbb,0xbb,0x67,0x63,0x6e,0x0e,0xec,0xcc,
|
||||
0xdd,0xdc,0x99,0x9f,0xbb,0xb9,0x33,0x3e,0x3c,0x42,0xb9,0xa5,0xb9,0xa5,0x42,0x3c,
|
||||
0x21,0x04,0x01,0x11,0xa8,0x00,0x1a,0x13,0xbe,0x20,0xfe,0x23,0x7d,0xfe,0x34,0x20,
|
||||
0xf5,0x06,0x19,0x78,0x86,0x23,0x05,0x20,0xfb,0x86,0x20,0xfe,0x3e,0x01,0xe0,0x50,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,23 @@
|
|||
#ifdef SYSTEM_CPP
|
||||
|
||||
//MD5SUM = d574d4f9c12f305074798f54c091a8b4
|
||||
const uint8_t System::BootROM::sgb[256] = {
|
||||
0x31,0xfe,0xff,0x3e,0x30,0xe0,0x00,0xaf,0x21,0xff,0x9f,0x32,0xcb,0x7c,0x20,0xfb,
|
||||
0x21,0x26,0xff,0x0e,0x11,0x3e,0x80,0x32,0xe2,0x0c,0x3e,0xf3,0xe2,0x32,0x3e,0x77,
|
||||
0x77,0x3e,0xfc,0xe0,0x47,0x21,0x5f,0xc0,0x0e,0x08,0xaf,0x32,0x0d,0x20,0xfc,0x11,
|
||||
0x4f,0x01,0x3e,0xfb,0x0e,0x06,0xf5,0x06,0x00,0x1a,0x1b,0x32,0x80,0x47,0x0d,0x20,
|
||||
0xf8,0x32,0xf1,0x32,0x0e,0x0e,0xd6,0x02,0xfe,0xef,0x20,0xea,0x11,0x04,0x01,0x21,
|
||||
0x10,0x80,0x1a,0xcd,0xd3,0x00,0xcd,0xd4,0x00,0x13,0x7b,0xfe,0x34,0x20,0xf3,0x11,
|
||||
0xe6,0x00,0x06,0x08,0x1a,0x13,0x22,0x23,0x05,0x20,0xf9,0x3e,0x19,0xea,0x10,0x99,
|
||||
0x21,0x2f,0x99,0x0e,0x0c,0x3d,0x28,0x08,0x32,0x0d,0x20,0xf9,0x2e,0x0f,0x18,0xf3,
|
||||
0x3e,0x91,0xe0,0x40,0x21,0x00,0xc0,0x0e,0x00,0x3e,0x00,0xe2,0x3e,0x30,0xe2,0x06,
|
||||
0x10,0x1e,0x08,0x2a,0x57,0xcb,0x42,0x3e,0x10,0x20,0x02,0x3e,0x20,0xe2,0x3e,0x30,
|
||||
0xe2,0xcb,0x1a,0x1d,0x20,0xef,0x05,0x20,0xe8,0x3e,0x20,0xe2,0x3e,0x30,0xe2,0xcd,
|
||||
0xc2,0x00,0x7d,0xfe,0x60,0x20,0xd2,0x0e,0x13,0x3e,0xc1,0xe2,0x0c,0x3e,0x07,0xe2,
|
||||
0x18,0x3a,0x16,0x04,0xf0,0x44,0xfe,0x90,0x20,0xfa,0x1e,0x00,0x1d,0x20,0xfd,0x15,
|
||||
0x20,0xf2,0xc9,0x4f,0x06,0x04,0xc5,0xcb,0x11,0x17,0xc1,0xcb,0x11,0x17,0x05,0x20,
|
||||
0xf5,0x22,0x23,0x22,0x23,0xc9,0x3c,0x42,0xb9,0xa5,0xb9,0xa5,0x42,0x3c,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x01,0xe0,0x50,
|
||||
};
|
||||
|
||||
#endif
|
|
@ -3,8 +3,23 @@
|
|||
#define SYSTEM_CPP
|
||||
namespace GameBoy {
|
||||
|
||||
#include "bootrom-dmg.cpp"
|
||||
#include "bootrom-sgb.cpp"
|
||||
System system;
|
||||
|
||||
uint8 System::mmio_read(uint16 addr) {
|
||||
if((addr & 0xff00) == 0x0000) {
|
||||
return BootROM::sgb[addr];
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void System::mmio_write(uint16 addr, uint8 data) {
|
||||
if(addr == 0xff50) {
|
||||
if(data == 0x01) cartridge.map();
|
||||
}
|
||||
}
|
||||
|
||||
void System::init(Interface *interface_) {
|
||||
interface = interface_;
|
||||
}
|
||||
|
@ -15,6 +30,11 @@ void System::power() {
|
|||
cpu.power();
|
||||
lcd.power();
|
||||
scheduler.init();
|
||||
|
||||
for(unsigned n = 0x0000; n <= 0x00ff; n++) bus.mmio[n] = this;
|
||||
bus.mmio[0xff50] = this;
|
||||
|
||||
system.clocks_executed = 0;
|
||||
}
|
||||
|
||||
void System::run() {
|
||||
|
|
|
@ -4,14 +4,21 @@ enum class Input : unsigned {
|
|||
Up, Down, Left, Right, B, A, Select, Start,
|
||||
};
|
||||
|
||||
class System {
|
||||
public:
|
||||
struct System : MMIO {
|
||||
struct BootROM {
|
||||
static const uint8 dmg[256];
|
||||
static const uint8 sgb[256];
|
||||
} bootROM;
|
||||
|
||||
uint8 mmio_read(uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
void init(Interface*);
|
||||
void power();
|
||||
void run();
|
||||
|
||||
//private:
|
||||
Interface *interface;
|
||||
unsigned clocks_executed;
|
||||
};
|
||||
|
||||
#include <gameboy/interface/interface.hpp>
|
||||
|
|
|
@ -46,7 +46,7 @@ void Application::main(int argc, char **argv) {
|
|||
OS::run();
|
||||
|
||||
if(GameBoy::cartridge.loaded()) {
|
||||
GameBoy::system.run();
|
||||
for(unsigned n = 0; n < 1024 * 1024; n++) GameBoy::system.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue