Update to v081r04 release.

byuu says:

- GB: square channels cache initial_length and invert the length value
  on writes [Jonas Quinn]
- GB: updated LCD disable to just ignore interrupts and pixel writes,
  fixes Contra
- BPS patch information and cartridge sections are now copied from the
  patch metadata, if it is present
- fixed bpslinear out-of-bounds issue, which will be in snespurify v11
  official [Danish]
- simplified Makefile again since command-line trumps manual assignments
This commit is contained in:
Tim Allen 2011-08-19 21:36:26 +10:00
parent b28c54770c
commit 095181af62
16 changed files with 62 additions and 39 deletions

View File

@ -2,14 +2,8 @@ include nall/Makefile
snes := snes
gameboy := gameboy
ifeq ($(profile),)
profile := accuracy
endif
ifeq ($(ui),)
ui := ui
endif
profile := accuracy
ui := ui
# options += debugger

View File

@ -30,7 +30,6 @@ void APU::Noise::clock_envelope() {
void APU::Noise::write(unsigned r, uint8 data) {
if(r == 1) {
initial_length = 64 - (data & 0x3f);
length = initial_length;
}
@ -45,7 +44,6 @@ void APU::Noise::write(unsigned r, uint8 data) {
narrow_lfsr = data & 0x08;
divisor = (data & 0x07) << 4;
if(divisor == 0) divisor = 8;
period = divisor << frequency;
}
@ -63,7 +61,6 @@ void APU::Noise::write(unsigned r, uint8 data) {
}
void APU::Noise::power() {
initial_length = 0;
envelope_volume = 0;
envelope_direction = 0;
envelope_frequency = 0;
@ -73,6 +70,7 @@ void APU::Noise::power() {
counter = 0;
output = 0;
initial_length = 0;
length = 0;
envelope_period = 0;
volume = 0;
@ -81,7 +79,6 @@ void APU::Noise::power() {
}
void APU::Noise::serialize(serializer &s) {
s.integer(initial_length);
s.integer(envelope_volume);
s.integer(envelope_direction);
s.integer(envelope_frequency);
@ -91,6 +88,7 @@ void APU::Noise::serialize(serializer &s) {
s.integer(counter);
s.integer(output);
s.integer(initial_length);
s.integer(length);
s.integer(envelope_period);
s.integer(volume);

View File

@ -1,5 +1,4 @@
struct Noise {
unsigned initial_length;
unsigned envelope_volume;
bool envelope_direction;
unsigned envelope_frequency;
@ -9,6 +8,7 @@ struct Noise {
bool counter;
int16 output;
unsigned initial_length;
unsigned length;
unsigned envelope_period;
unsigned volume;

View File

@ -66,7 +66,8 @@ void APU::Square1::write(unsigned r, uint8 data) {
if(r == 1) {
duty = data >> 6;
length = data & 0x3f;
initial_length = 64 - (data & 0x3f);
length = initial_length;
}
if(r == 2) {
@ -85,6 +86,7 @@ void APU::Square1::write(unsigned r, uint8 data) {
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
if(initialize) {
length = initial_length;
envelope_period = envelope_frequency;
volume = envelope_volume;
frequency_shadow = frequency;
@ -102,6 +104,7 @@ void APU::Square1::power() {
sweep_direction = 0;
sweep_shift = 0;
duty = 0;
initial_length = 0;
length = 0;
envelope_volume = 0;
envelope_direction = 0;
@ -125,6 +128,7 @@ void APU::Square1::serialize(serializer &s) {
s.integer(sweep_direction);
s.integer(sweep_shift);
s.integer(duty);
s.integer(initial_length);
s.integer(length);
s.integer(envelope_volume);
s.integer(envelope_direction);

View File

@ -3,6 +3,7 @@ struct Square1 {
unsigned sweep_direction;
unsigned sweep_shift;
unsigned duty;
unsigned initial_length;
unsigned length;
unsigned envelope_volume;
unsigned envelope_direction;

View File

@ -33,7 +33,8 @@ void APU::Square2::clock_envelope() {
void APU::Square2::write(unsigned r, uint8 data) {
if(r == 1) {
duty = data >> 6;
length = data & 0x3f;
initial_length = 64 - (data & 0x3f);
length = initial_length;
}
if(r == 2) {
@ -52,6 +53,7 @@ void APU::Square2::write(unsigned r, uint8 data) {
frequency = ((data & 7) << 8) | (frequency & 0x00ff);
if(initialize) {
length = initial_length;
envelope_period = envelope_frequency;
volume = envelope_volume;
}
@ -62,6 +64,7 @@ void APU::Square2::write(unsigned r, uint8 data) {
void APU::Square2::power() {
duty = 0;
initial_length = 0;
length = 0;
envelope_volume = 0;
envelope_direction = 0;
@ -79,6 +82,7 @@ void APU::Square2::power() {
void APU::Square2::serialize(serializer &s) {
s.integer(duty);
s.integer(initial_length);
s.integer(length);
s.integer(envelope_volume);
s.integer(envelope_direction);

View File

@ -1,5 +1,6 @@
struct Square2 {
unsigned duty;
unsigned initial_length;
unsigned length;
unsigned envelope_volume;
unsigned envelope_direction;

View File

@ -28,7 +28,6 @@ void APU::Wave::write(unsigned r, uint8 data) {
if(r == 1) {
initial_length = 256 - data;
length = initial_length;
}
@ -68,7 +67,6 @@ void APU::Wave::write_pattern(unsigned p, uint8 data) {
void APU::Wave::power() {
dac_enable = 0;
initial_length = 0;
volume = 0;
frequency = 0;
counter = 0;
@ -78,6 +76,7 @@ void APU::Wave::power() {
output = 0;
enable = 0;
initial_length = 0;
length = 0;
period = 0;
pattern_offset = 0;
@ -86,7 +85,6 @@ void APU::Wave::power() {
void APU::Wave::serialize(serializer &s) {
s.integer(dac_enable);
s.integer(initial_length);
s.integer(volume);
s.integer(frequency);
s.integer(counter);
@ -94,6 +92,7 @@ void APU::Wave::serialize(serializer &s) {
s.integer(output);
s.integer(enable);
s.integer(initial_length);
s.integer(length);
s.integer(period);
s.integer(pattern_offset);

View File

@ -1,6 +1,5 @@
struct Wave {
bool dac_enable;
unsigned initial_length;
unsigned volume;
unsigned frequency;
bool counter;
@ -8,6 +7,7 @@ struct Wave {
int16 output;
bool enable;
unsigned initial_length;
unsigned length;
unsigned period;
unsigned pattern_offset;

View File

@ -5,7 +5,7 @@
namespace GameBoy {
namespace Info {
static const char Name[] = "bgameboy";
static const char Version[] = "000.20";
static const char Version[] = "000.21";
static unsigned SerializerVersion = 2;
}
}

View File

@ -18,16 +18,14 @@ void LCD::main() {
}
add_clocks(4);
if(status.display_enable == false) continue;
status.lx += 4;
if(status.lx >= 456) scanline();
if(status.lx == 0) {
if(status.display_enable && status.lx == 0) {
if(status.interrupt_oam) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.lx == 252) {
if(status.display_enable && status.lx == 252) {
if(status.interrupt_hblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
}
@ -44,13 +42,13 @@ void LCD::scanline() {
status.lx -= 456;
if(++status.ly == 154) frame();
if(status.interrupt_lyc == true) {
if(status.display_enable && status.interrupt_lyc == true) {
if(status.ly == status.lyc) cpu.interrupt_raise(CPU::Interrupt::Stat);
}
if(status.ly < 144) render();
if(status.ly == 144) {
if(status.display_enable && status.ly == 144) {
cpu.interrupt_raise(CPU::Interrupt::Vblank);
if(status.interrupt_vblank) cpu.interrupt_raise(CPU::Interrupt::Stat);
}

View File

@ -17,8 +17,7 @@ uint8 LCD::mmio_read(uint16 addr) {
if(addr == 0xff41) { //STAT
unsigned mode;
if(status.display_enable == false) mode = 1; //force blank
else if(status.ly >= 144) mode = 1; //Vblank
if(status.ly >= 144) mode = 1; //Vblank
else if(status.lx < 80) mode = 2; //OAM
else if(status.lx < 252) mode = 3; //LCD
else mode = 0; //Hblank
@ -84,6 +83,10 @@ void LCD::mmio_write(uint16 addr, uint8 data) {
if(addr >= 0xfe00 && addr <= 0xfe9f) { oam[addr & 0xff] = data; return; }
if(addr == 0xff40) { //LCDC
if(status.display_enable == false && (data & 0x80)) {
status.lx = 0; //unverified behavior; fixes Super Mario Land 2 - Tree Zone
}
status.display_enable = data & 0x80;
status.window_tilemap_select = data & 0x40;
status.window_display_enable = data & 0x20;

View File

@ -1,7 +1,7 @@
namespace SNES {
namespace Info {
static const char Name[] = "bsnes";
static const char Version[] = "081.03";
static const char Version[] = "081.04";
static const unsigned SerializerVersion = 21;
}
}

View File

@ -83,7 +83,8 @@ bool Cartridge::loadSuperGameBoy(const char *basename, const char *slotname) {
}
void Cartridge::unload() {
patchApplied = false;
patch.applied = false;
patch.information = "";
if(SNES::cartridge.loaded() == false) return;
foreach(memory, SNES::cartridge.nvram) saveMemory(memory);
@ -112,20 +113,36 @@ bool Cartridge::loadCartridge(SNES::MappedRAM &memory, string &XML, const char *
string patchName = { nall::basename(filename), ".bps" };
if(file::exists(patchName)) {
bpspatch patch;
patch.modify(patchName);
bpspatch bps;
bps.modify(patchName);
unsigned targetSize = patch.size();
unsigned targetSize = bps.size();
uint8_t *targetData = new uint8_t[targetSize];
patch.source(data, size);
patch.target(targetData, targetSize);
bps.source(data, size);
bps.target(targetData, targetSize);
if(patch.apply() == bpspatch::result::success) {
if(bps.apply() == bpspatch::result::success) {
delete[] data;
data = targetData;
size = targetSize;
patchApplied = true;
patch.applied = true;
xml_element document = xml_parse(bps.metadata());
foreach(root, document.element) {
if(root.name == "metadata") {
if(auto x = root.content.position("<information>")) {
if(auto y = root.content.position("</information>")) {
patch.information = substr(root.content, x(), y() - x() + 14);
}
}
if(auto x = root.content.position("<cartridge ")) {
if(auto y = root.content.position("</cartridge>")) {
XML = substr(root.content, x(), y() - x() + 12);
}
}
}
}
} else {
delete[] targetData;
}

View File

@ -8,7 +8,11 @@ struct Cartridge {
string baseName, bsxName, sufamiTurboAName, sufamiTurboBName, gameBoyName;
string baseXML, bsxXML, sufamiTurboAXML, sufamiTurboBXML, gameBoyXML;
bool patchApplied;
struct Patch {
bool applied;
string information;
} patch;
private:
bool loadCartridge(SNES::MappedRAM &memory, string &XML, const char *filename);

View File

@ -165,7 +165,7 @@ void Utility::cartridgeLoaded() {
utility.setTitle(notdir(name));
utility.showMessage({
"Loaded ", notdir(name),
cartridge.patchApplied ? ", and applied BPS patch" : ""
cartridge.patch.applied ? ", and applied BPS patch" : ""
});
//NSS