Skip to content

Commit

Permalink
v6.0 WIP: Konami Ultimate Collection cartridge support
Browse files Browse the repository at this point in the history
  • Loading branch information
ppeccin committed Feb 22, 2020
1 parent 025195f commit 22c2678
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/main/WMSX.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ WMSX = {
KEYBOARD_JAPAN_LAYOUT: 1, // 0: ANSI; 1: JIS
DEBUG_MODE: 0, // 0: off; 1..7: debug mode. Don't change! :-)
SPRITES_DEBUG_MODE: 0, // 0: off; 1: unlimited; 2: no collisions; 3: both. May cause problems :-)
ROM_MAX_HASH_SIZE_KB: 4096, // Maximum ROM size for Hash calculation
ROM_MAX_HASH_SIZE_KB: 5120, // Maximum ROM size for Hash calculation
HARDDISK_MIN_SIZE_KB: 720, // Minimum file size to be accepted as HardDisk image (besides all valid Floppy formats)
DISK_ROM_START_PAGE: 0, // 0..1: Change starting page for ROMs > 16KB when format is DiskPatch
LIGHT_STATES: true,
Expand Down
2 changes: 1 addition & 1 deletion src/main/WMSXCBios.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ WMSX = {
KEYBOARD_JAPAN_LAYOUT: 1, // 0: ANSI; 1: JIS
DEBUG_MODE: 0, // 0: off; 1..7: debug mode. Don't change! :-)
SPRITES_DEBUG_MODE: 0, // 0: off; 1: unlimited; 2: no collisions; 3: both. May cause problems :-)
ROM_MAX_HASH_SIZE_KB: 4096, // Maximum ROM size for Hash calculation
ROM_MAX_HASH_SIZE_KB: 5120, // Maximum ROM size for Hash calculation
HARDDISK_MIN_SIZE_KB: 720, // Minimum file size to be accepted as HardDisk image (besides all valid Floppy formats)
DISK_ROM_START_PAGE: 0, // 0..1: Change starting page for ROMs > 16KB when format is DiskPatch
LIGHT_STATES: true,
Expand Down
1 change: 0 additions & 1 deletion src/main/msx/rom/SlotFormatsNotSupported.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ wmsx.SlotFormatsNotSupported = {

"MSXAUDIO": 0, // Make Support? System ROM
"SuperPierrot": 0, // Make Support? 1 game, no alts.
"KonamiUltimateCollection": 0, // Make Support? 1 cart Special flash cart with built-in utils
"Generic16k": 0, // Make Support? ?

"Manbow2_2": 0, // Points to Manbow2 1 game, has alts. Can't find ROM. Same mapper as Manbow2? (MegaFlash SCC)
Expand Down
2 changes: 1 addition & 1 deletion src/main/msx/slots/SlotCreator.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ wmsx.SlotCreator = function () {
var FORMAT_PRIORITY_BOOST = 1000;
var FORMAT_FORCE_PRIORITY_BOOST = 5000;

var MAX_HASH_CONTENT_SIZE = (WMSX.ROM_MAX_HASH_SIZE_KB || 4096) * 1024;
var MAX_HASH_CONTENT_SIZE = (WMSX.ROM_MAX_HASH_SIZE_KB || 5120) * 1024;

this.FORMAT_PRIORITY_BOOST = FORMAT_PRIORITY_BOOST;

Expand Down
16 changes: 16 additions & 0 deletions src/main/msx/slots/SlotFormats.js
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,22 @@ wmsx.SlotFormats = {
}
},

"KonamiUltimateCollection": {
name: "KonamiUltimateCollection",
desc: "Konami Ultimate Collection SCC+ Sound Mapper Cartridge",
priority: 1109,
priorityForRom: function (rom) {
// Any > 0 & <= 5M content, multiple of 8K. Must be selected via info format hint
return (rom.content.length > 0 && rom.content.length <= 5242880 && (rom.content.length & 0x1fff) === 0) ? this.priority : null;
},
createFromROM: function (rom) {
return new wmsx.CartridgeKonamiUltimateCollection(rom);
},
recreateFromSaveState: function (state, previousSlot) {
return wmsx.CartridgeKonamiUltimateCollection.recreateFromSaveState(state, previousSlot);
}
},

"RType": {
name: "RType",
desc: "R-Type Mapper Cartridge",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
// Copyright 2015 by Paulo Augusto Peccin. See license.txt distributed with this file.

// Controls an internal SCC-I sound chip (in SCC or SCC-I mode)
// 0x4000 - 0xbfff

// TODO DAC

wmsx.CartridgeKonamiUltimateCollection = function(rom) {
"use strict";

function init(self) {
self.rom = rom;
bytes = wmsx.Util.asNormalArray(rom.content);
self.bytes = bytes;
}

this.connect = function(machine) {
scc.setAudioSocket(machine.getAudioSocket());
if (sccConnected) connectSCC(); // needed in LoadStates
};

this.disconnect = function(machine) {
scc.disconnectAudio();
};

this.powerOn = function() {
this.reset();
};

this.powerOff = function() {
scc.disconnectAudio();
};

this.reset = function() {
mapperMode = 0; banksOffset = 0; addressOffset = 0;
bank1No = 0; bank2No = 1; bank3No = 2; bank4No = 3;
sccSelected = scciSelected = sccConnected = false;
scc.reset();
setSCCMode(0);
};

this.read = function(address) {
// wmsx.Util.log("Read: " + wmsx.Util.toHex4(address));

// SCC Read
if (!(address & 0x0100)) {
if ((address >= 0x9800 && address < 0x9ffe && sccSelected && sccMode === 0x00)
|| (address >= 0xb800 && address < 0xbffe && scciSelected && sccMode === 0x20))
return scc.read(address);
}

switch (address & 0xe000) {
case 0x4000:
return bytes[addressOffset | (((bank1No + banksOffset) & 0xff) << 13) | (address & 0x1fff)];
case 0x6000:
return bytes[addressOffset | (((bank2No + banksOffset) & 0xff) << 13) | (address & 0x1fff)];
case 0x8000:
return bytes[addressOffset | (((bank3No + banksOffset) & 0xff) << 13) | (address & 0x1fff)];
case 0xa000:
return bytes[addressOffset | (((bank4No + banksOffset) & 0xff) << 13) | (address & 0x1fff)];
default:
return 0xff;
}
};

this.write = function(address, value) {
// wmsx.Util.log("Write: " + wmsx.Util.toHex4(address) + ', ' + value);

// SCC Write
if (!(address & 0x0100)) {
if ((sccMode === 0x00 && address >= 0x9800 && address < 0x9ffe && sccSelected)
|| (sccMode === 0x20 && address >= 0xb800 && address < 0xbffe && scciSelected))
return scc.write(address, value);
}

// Mapper and Offset registers
if (!(mapperMode & 0x04)) { // mapper reg enabled
if (address === 0x7fff) setMapperMode(value);
else if (address === 0x7ffe) setMapperOffset(value);
}

// Bank Switching
if (!(mapperMode & 0x02)) { // bank switching enabled
if (!(mapperMode & 0x20)) {
// KonamiSCC
switch (address & 0xe000) {
case 0x4000:
if (address >= 0x5000 && address <= 0x57ff)
bank1No = value;
break;
case 0x6000:
if (address >= 0x7000 && address <= 0x77ff)
bank2No = value;
break;
case 0x8000:
if (address >= 0x9000 && address <= 0x97ff) {
bank3No = value;
sccSelected = (value & 0x3f) === 0x3f; // Special value to activate the SCC
}
break;
case 0xa000:
if (address >= 0xb000 && address <= 0xb7ff) {
bank4No = value;
scciSelected = (value & 0x80) === 0x80; // Special value to activate the SCC-I
}
break;
}
} else {
// Konami
switch (address & 0xe000) {
case 0x4000:
if ((mapperMode & 0x08) === 0 && address >= 0x5000 && address <= 0x57ff) // DAC disabled?
bank1No = value;
break;
case 0x6000:
bank2No = value;
break;
case 0x8000:
bank3No = value;
sccSelected = (value & 0x3f) === 0x3f; // Special value to activate the SCC
break;
case 0xa000:
bank4No = value;
scciSelected = (value & 0x80) === 0x80; // Special value to activate the SCC-I
break;
}
}

// SCC Mode register
if (address === 0xbffe || address === 0xbfff)
setSCCMode(value);

if ((sccSelected || scciSelected) && !sccConnected) connectSCC();
}
};

function setMapperMode(value) {
mapperMode = value;
addressOffset = (value & 0xc0) << 15;

// console.log("MapperMode:", value.toString(16));
}

function setMapperOffset(value) {
banksOffset = value;

// console.log("MapperOffset:", value);
}

function setSCCMode(pMode) {
sccMode = pMode & 0x30; // sccMode & 0x10 disables SCC access!
scc.setSCCIMode((pMode & 0x20) !== 0);

// console.log("SCCMode:", sccMode);
}

function connectSCC() {
scc.connectAudio();
sccConnected = true;
}


var bytes;
this.bytes = null;

var sccMode, mapperMode, banksOffset, addressOffset;

var bank1No, bank2No, bank3No, bank4No;

var scc = new wmsx.SCCIAudio();
var sccSelected, scciSelected = false;
var sccConnected = false;

this.rom = null;
this.format = wmsx.SlotFormats.KonamiUltimateCollection;


// TODO Savestate -------------------------------------------

this.saveState = function() {
return {
f: this.format.name,
r: this.rom.saveState(),
b: wmsx.Util.compressInt8BitArrayToStringBase64(bytes),
m: sccMode,
b1: bank1No,
b2: bank2No,
b3: bank3No,
b4: bank4No,
scc: scc.saveState(),
scs: sccSelected,
sis: scciSelected,
scn: sccConnected
};
};

this.loadState = function(s) {
this.format = wmsx.SlotFormats[s.f];
this.rom = wmsx.ROM.loadState(s.r);
bytes = wmsx.Util.uncompressStringBase64ToInt8BitArray(s.b, bytes);
this.bytes = bytes;
bank1No = s.b1;
bank2No = s.b2;
bank3No = s.b3;
bank4No = s.b4;
setSCCMode(s.m);
scc.loadState(s.scc);
sccSelected = s.scs;
scciSelected = s.sis;
sccConnected = s.scn;

if (sccConnected) connectSCC();
};

this.eval = function(str) {
return eval(str);
};


if (rom) init(this);

};

wmsx.CartridgeKonamiUltimateCollection.prototype = wmsx.Slot.base;

wmsx.CartridgeKonamiUltimateCollection.recreateFromSaveState = function(state, previousSlot) {
var cart = previousSlot || new wmsx.CartridgeKonamiUltimateCollection();
cart.loadState(state);
return cart;
};


/*
Documentation from Manuel Pazos (producer of the cartridge)
Konami Ultimate Collection shares some features of MegaFlashROM SCC+ SD.
It uses the same flashROM, SCC/SCC+, Konami and Konami SCC mappers, etc.
[OFFSET REGISTER (#7FFE)]
7-0: Bank offset
[MAPPER REGISTER (#7FFF)]
7 A21 \
6 A20 / FlashROM address lines to switch 2 MB banks.
5 Mapper mode : Select Konami mapper (0=SCC or 1=normal). [1]
4 Flash write enable
3 Disable #4000-#5FFF mapper in Konami mode, Enable DAC (works like the DAC of Synthesizer or Majutsushi)
2 Disable mapper register
1 Disable mapper (bank switching)
0 no function anymore (was mapper limits)
*/
1 change: 1 addition & 0 deletions test/cbios/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<script src="../../src/main/msx/slots/cartridges/special/scc/CartridgeSCCExpansion.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/scc/CartridgeSCCIExpansion.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/scc/CartridgeManbow2.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/scc/CartridgeKonamiUltimateCollection.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/kanji/CartridgeKanjiFont.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/sram/CartridgePAC.js"></script>
<script src="../../src/main/msx/slots/cartridges/special/msx-music/CartridgeMSXMUSIC.js"></script>
Expand Down
1 change: 1 addition & 0 deletions test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
<script src="../src/main/msx/slots/cartridges/special/scc/CartridgeSCCExpansion.js"></script>
<script src="../src/main/msx/slots/cartridges/special/scc/CartridgeSCCIExpansion.js"></script>
<script src="../src/main/msx/slots/cartridges/special/scc/CartridgeManbow2.js"></script>
<script src="../src/main/msx/slots/cartridges/special/scc/CartridgeKonamiUltimateCollection.js"></script>
<script src="../src/main/msx/slots/cartridges/special/kanji/CartridgeKanjiFont.js"></script>
<script src="../src/main/msx/slots/cartridges/special/sram/CartridgePAC.js"></script>
<script src="../src/main/msx/slots/cartridges/special/msx-music/CartridgeMSXMUSIC.js"></script>
Expand Down

0 comments on commit 22c2678

Please sign in to comment.