diff --git a/tools/tools.js b/tools/tools.js index e9704af..ec1db3e 100644 --- a/tools/tools.js +++ b/tools/tools.js @@ -12,6 +12,14 @@ Just like the tools themselves, this file should be considered CC0 Public Domain (https://creativecommons.org/publicdomain/zero/1.0/) + Version 1.4: Re-ordered the getFirmwareHash() zeroing-out checks to match the + expected order to find them in in the BIOS file - just some future-proofing + in case some user-substituted content (e.g., a boot logo) happens to contain + bytes that a subsequent call to findSequence() might accidentally match. I + also added some comments with the rough location of each block within the + file, so if I have to add something else in the future I'll be able to slide + it into the right place :) + Version 1.3: Added support for blanking out the SNES audio bitrate and cycles bits that `bnister` identified as a workaround for the "start-SNES-games- twice" issue that cropped up in firmware versions after March @@ -68,40 +76,11 @@ function getFirmwareHash(data) { dataCopy[398] = 0x00; dataCopy[399] = 0x00; - // Next identify the boot logo position, and blank it out too... - var badExceptionOffset = findSequence([0x62, 0x61, 0x64, 0x5F, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00], dataCopy); - if (badExceptionOffset > -1) { - var bootLogoStart = badExceptionOffset + 16; - for (var i = bootLogoStart; i < (bootLogoStart + 204800); i++) { - dataCopy[i] = 0x00; - } - } - else { - return false; - } - - // Next identify the emulator button mappings (if they exist), and blank - // them out too... - var preButtonMapOffset = findSequence([0x00, 0x00, 0x00, 0x71, 0xDB, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], dataCopy); - if (preButtonMapOffset > -1) { - var postButtonMapOffset = findSequence([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00], dataCopy, preButtonMapOffset); - if (postButtonMapOffset > -1) { - for (var i = preButtonMapOffset + 16; i < postButtonMapOffset; i++) { - dataCopy[i] = 0x00; - } - } - else { - return false; - } - } - else { - return false; - } - // Next we'll look for (and zero out) the five bytes that the power // monitoring functions of the SF2000 use for switching the UI's battery // level indicator. These unfortunately can't be searched for - they're just // in specific known locations for specific firmware versions... + // Location: Approximately 0x35A8F8 (about 25% of the way through the file) var prePowerCurve = findSequence([0x11, 0x05, 0x00, 0x02, 0x24], dataCopy); if (prePowerCurve > -1) { var powerCurveFirstByteLocation = prePowerCurve + 5; @@ -159,9 +138,42 @@ function getFirmwareHash(data) { return false; } + // Next identify the emulator button mappings (if they exist), and blank + // them out too... + // Location: Approximately 0x8D6200 (about 75% of the way through the file) + var preButtonMapOffset = findSequence([0x00, 0x00, 0x00, 0x71, 0xDB, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], dataCopy); + if (preButtonMapOffset > -1) { + var postButtonMapOffset = findSequence([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00], dataCopy, preButtonMapOffset); + if (postButtonMapOffset > -1) { + for (var i = preButtonMapOffset + 16; i < postButtonMapOffset; i++) { + dataCopy[i] = 0x00; + } + } + else { + return false; + } + } + else { + return false; + } + + // Next identify the boot logo position, and blank it out too... + // Location: Approximately 0x9B3520 (about 80% of the way through the file) + var badExceptionOffset = findSequence([0x62, 0x61, 0x64, 0x5F, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00], dataCopy); + if (badExceptionOffset > -1) { + var bootLogoStart = badExceptionOffset + 16; + for (var i = bootLogoStart; i < (bootLogoStart + 204800); i++) { + dataCopy[i] = 0x00; + } + } + else { + return false; + } + // Next we'll look for and zero out the bytes used for SNES audio rate and // CPU cycles, in case folks want to patch those bytes to correct SNES // first-launch issues on newer firmwares... + // Location: Approximately 0xC0A170 (about 99% of the way through the file) var preSNESBytes = findSequence([0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80], dataCopy); if (preSNESBytes > -1) { var snesAudioBitrateBytes = preSNESBytes + 8;