Clean up ig rom hack a bit, disable map download when selected

This commit is contained in:
Evan Barger
2020-05-23 22:28:09 -04:00
parent 9a78a1217d
commit d5de2f58b5
3 changed files with 81 additions and 73 deletions

View File

@@ -13,7 +13,7 @@
<body>
<h1>GAME BOY Nintendo Power ROM Builder</h1>
<div class='text-container'>
This tool can build the data necessary to flash new games to a <a href="https://en.wikipedia.org/wiki/Nintendo_Power_(cartridge)">Nintendo Power Game Boy cart</a>, as well as the <a href="">insideGadgets Power Cart</a>. The menu can have up to seven roms, or a total of 896KB of game data. For flashing, I recommend the <a href="https://www.gbxcart.com/">GBxCart</a>.
This tool can build the data necessary to flash new games to a <a href="https://en.wikipedia.org/wiki/Nintendo_Power_(cartridge)">Nintendo Power Game Boy cart</a>, as well as the <a href="https://shop.insidegadgets.com/product/gameboy-1mb-128kb-sram-power-cart-multi-game-and-multi-save/">insideGadgets Power Cart</a>. The menu can have up to seven roms, or a total of 896KB of game data. For flashing, I recommend the <a href="https://www.gbxcart.com/">GBxCart</a>.
</div>
<noscript>
Looks like you have JS disabled. This tool needs javascript to function!
@@ -134,7 +134,7 @@
<section>
<a class='download-link' :download="filename + '.gb'" :href="downloadEnabled ? romData : null" type="application/octet-stream" v-on:click="downloadRomFile" :class="{ disabled: !downloadEnabled }">Download GB File</a>
/
<a class='download-link' :download="filename + '.map'" :href="downloadEnabled ? mapData : null" type="application/octet-stream" v-on:click="downloadMapFile" :class="{ disabled: !downloadEnabled }">Download MAP File</a>
<a class='download-link' :download="filename + '.map'" :href="downloadEnabled && mapEnabled ? mapData : null" type="application/octet-stream" v-on:click="downloadMapFile" :class="{ disabled: (!downloadEnabled || !mapEnabled) }">Download MAP File</a>
</section>
</div>

View File

@@ -81,13 +81,15 @@ let app = new Vue({
downloadEnabled: function() {
return this.menu.present() && !this.romOverflow;
},
mapEnabled: function() {
return this.cartType == 0;
},
romOverflow: function() { return this.processor.romOverflow(); }
},
watch: {
fontIndex: function() {
for (let i = 0; i < this.roms.length; i++) { this.roms[i].updateBitmap(this.fontIndex); }
},
disableCGB: function() { this.processor.disableCGB = this.disableCGB; },
forceDMG: function() { this.processor.forceDMG = this.forceDMG; },
cartType: function() { this.processor.cartType = this.cartType; }
},
@@ -137,8 +139,10 @@ let app = new Vue({
this.processor.roms = this.roms;
},
downloadMapFile: function(e) {
if (this.mapData) { URL.revokeObjectURL(this.mapData) }
this.mapData = URL.createObjectURL(new Blob([this.processor.mapData()]));
if (this.cartType == 0) { // regular power cart only
if (this.mapData) { URL.revokeObjectURL(this.mapData) }
this.mapData = URL.createObjectURL(new Blob([this.processor.mapData()]));
}
},
downloadRomFile: function(e) {
if (this.romData) { URL.revokeObjectURL(this.romData) }

View File

@@ -13,7 +13,6 @@ const BITMAP_PREVIEW_BYTES = [
[0x66, 0x66, 0x66, 0xFF], // dark grey
[0x00, 0x00, 0x00, 0xFF] // black
]
const IG_POWER_CART_HACK = [0x3E, 0x01, 0xEA, 0x00, 0x20, 0xF0, 0xFD, 0x01, 0x00, 0x20, 0x4F, 0x0A, 0xEA, 0x00, 0x60];
const FONTS = [
{ style: 'normal 8px Gameboy', y: 7 },
{ style: 'normal 8px PokemonGB', y: 7 },
@@ -304,26 +303,7 @@ class Processor {
// apply iG power cart hack
if (this.cartType == 1) {
romFile.seek(0x130E); // For CGB+
romFile.writeBytes([0xC3, 0x00, 0x1F]); // Jump to 0x1F00
romFile.seek(0x140F); // For DMG/Pocket
romFile.writeBytes([0xC3, 0x00, 0x1F]); // Jump to 0x1F00
// Set rom bank, ram enabled/disabled, 8KB/32KB locked and ram bank
romFile.seek(0x1F00);
romFile.writeBytes([0x3e, 0x01, 0xea, 0x00, 0x20, // Set 0x2000, 1
0xf0, 0xfd, 0x01, 0x00, 0x22, 0x4f, 0x0a, 0xea, 0x00, 0x40, 0x3e, 0x00, 0xea, 0x00, 0x40, // Ram bank set bit 1+. 8KB/32KB locking = bit 0
0xf0, 0xfd, 0x01, 0x00, 0x21, 0x4f, 0x0a, 0xea, 0x00, 0x00, // Ram enable/disable
0xf0, 0xfd, 0x01, 0x00, 0x20, 0x4f, 0x0a, 0xea, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); // Rom bank and restart GB
// Patch out any writes to 0x0000-0x1000
romFile.seek(0x0DDF);
romFile.writeBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
romFile.seek(0x0E22);
romFile.writeBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
this.patchRomHeaderForIG(romFile);
}
// apply dmg menu hack
@@ -348,10 +328,10 @@ class Processor {
romFile.seek(romFileIndex + i * 512);
romFile.writeByte(0xFF);
}
let romOffset = 8;
let ramOffset = 0;
// used in loop for iG power cart hack
let iGOffsets = { rom: 8, ram: 0 };
for (let i = 0; i < this.roms.length; i++) {
const rom = this.roms[i];
@@ -381,50 +361,10 @@ class Processor {
romFile.writeBytes(rom.bitmapBuffer);
romFileIndex += 512
}
// apply iG power cart hack
if (this.cartType == 1) {
// Set rom bank start
romFile.seek(0x2001 + i);
if (rom.typeByte >= 1 && rom.typeByte <= 3) {// MBC1 enabled, setting bank 0 = bank 1
romFile.writeByte(romOffset | 0x01);
}
else {
romFile.writeByte(romOffset);
}
romOffset += Math.trunc(rom.paddedRomSizeKB() / 16);
// Set ram state
romFile.seek(0x2101 + i);
if (rom.ramByte > 0) {
romFile.writeByte(1); // Ram enabled
}
else {
romFile.writeByte(0); // Ram disabled
}
// Set ram bank info
romFile.seek(0x2201 + i);
// Ram offset and if we are 8KB or 32KB locked
if (rom.ramByte == 2) { // 8KB
romFile.writeByte(ramOffset); // 8KB locked
}
else if (rom.ramByte == 3) { // 32KB
romFile.writeByte(ramOffset | 0x01); // 32KB locked
}
else {
romFile.writeByte(0);
}
// Increment ram offset after
if (rom.ramByte == 2) { // 8KB
ramOffset += 2;
}
else if (rom.ramByte == 3) { // 32KB
ramOffset += 8;
// apply iG power cart hack
if (this.cartType == 1) {
this.patchBankInfoForIG(rom, romFile, iGOffsets, i);
}
}
@@ -437,6 +377,70 @@ class Processor {
return new Uint8Array(romBuffer);
}
patchRomHeaderForIG(romFile) {
romFile.seek(0x130E); // For CGB+
romFile.writeBytes([0xC3, 0x00, 0x1F]); // Jump to 0x1F00
romFile.seek(0x140F); // For DMG/Pocket
romFile.writeBytes([0xC3, 0x00, 0x1F]); // Jump to 0x1F00
// Set rom bank, ram enabled/disabled, 8KB/32KB locked and ram bank
romFile.seek(0x1F00);
romFile.writeBytes([0x3e, 0x01, 0xea, 0x00, 0x20, // Set 0x2000, 1
0xf0, 0xfd, 0x01, 0x00, 0x22, 0x4f, 0x0a, 0xea, 0x00, 0x40, 0x3e, 0x00, 0xea, 0x00, 0x40, // Ram bank set bit 1+. 8KB/32KB locking = bit 0
0xf0, 0xfd, 0x01, 0x00, 0x21, 0x4f, 0x0a, 0xea, 0x00, 0x00, // Ram enable/disable
0xf0, 0xfd, 0x01, 0x00, 0x20, 0x4f, 0x0a, 0xea, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); // Rom bank and restart GB
// Patch out any writes to 0x0000-0x1000
romFile.seek(0x0DDF);
romFile.writeBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
romFile.seek(0x0E22);
romFile.writeBytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
}
patchBankInfoForIG(rom, romFile, offsets, i) {
// Set rom bank start
romFile.seek(0x2001 + i);
if (rom.typeByte >= 1 && rom.typeByte <= 3) {// MBC1 enabled, setting bank 0 = bank 1
romFile.writeByte(offsets.rom | 0x01);
}
else {
romFile.writeByte(offsets.rom);
}
offsets.rom += Math.trunc(rom.paddedRomSizeKB() / 16);
// Set ram state
romFile.seek(0x2101 + i);
if (rom.ramByte > 0) {
romFile.writeByte(1); // Ram enabled
}
else {
romFile.writeByte(0); // Ram disabled
}
// Set ram bank info
romFile.seek(0x2201 + i);
// Ram offset and if we are 8KB or 32KB locked
if (rom.ramByte == 2) { // 8KB
romFile.writeByte(offsets.ram); // 8KB locked
}
else if (rom.ramByte == 3) { // 32KB
romFile.writeByte(offsets.ram | 0x01); // 32KB locked
}
else {
romFile.writeByte(0);
}
// Increment ram offset after
if (rom.ramByte == 2) { // 8KB
offsets.ram += 2;
}
else if (rom.ramByte == 3) { // 32KB
offsets.ram += 8;
}
}
parseMenuData(menuBuffer, fontIndex) {
this.roms = [];
const menuFile = new FileSeeker(menuBuffer);