About
MSX F1-Spirit password generator
F1-Spirit was one of my favorite MSX games. You could generate a password to save your result in the races. This page contains a generator and the corresponding javascript code to show how the password was constructed. It has a method of obfuscation which uses a block of bytes in the ROM. This block of data is different in the European and Japanese version (as far as I can tell). Therefor you can select the ROM version you are using.
Please contact me if you have any questions: rainier@meusesoft.com
Built-in cheat codes
MITAIYOENDDEMO: Show the end demo
MAXPOINT: Maximum points for all races
ESCON: Enable F5 to exit race
ESCOFF: Disable F5 to exit race
HYPEROFF: Pits early entry
Password generator
Javascript code
function Generate() {
var password = GeneratePassword();
document.getElementById("password").innerHTML = password;
}
function GeneratePassword() {
var points = [];
const European = [0xcd, 0x01, 0x51, 0xcd, 0xb3, 0x52, 0xc3, 0xd4, 0x52, 0xcd, 0xfc, 0x50, 0x20, 0x05, 0x3a, 0xc8, 0xe1, 0xe6, 0x02, 0xc4, 0x65, 0x50, 0xaf, 0x32, 0x50, 0xea, 0x3a, 0x51, 0xe2, 0x3d, 0x28, 0x4c, 0xf2, 0x7c, 0x50, 0xdd, 0x21, 0xb1, 0xe9, 0x06, 0x02];
const Japanese = [0xcd, 0xf3, 0x50, 0x20, 0x05, 0x3a, 0xc8, 0xe1, 0xe6, 0x02, 0xc4, 0x5c, 0x50, 0xaf, 0x32, 0x50, 0xea, 0x3a, 0x51, 0xe2, 0x3d, 0x28, 0x4c, 0xf2, 0x73, 0x50, 0xdd, 0x21, 0xb1, 0xe9, 0x06, 0x02, 0x11, 0x08, 0x00, 0xdd, 0x7e, 0x05, 0xa7, 0x28, 0x05];
//Initialise variables
EuropeanRom = document.getElementById("version").value == "European";
Random = parseInt(document.getElementById("random").value);
points[0] = Random;
//Populate array with the points per race
for (i = 1; i < 22; i++)
{
var elementId = i.toString();
var element = document.getElementById(elementId);
points[i] = parseInt(element.value);
}
//Checksum
var c1 = 0;
var c2 = 0;
for (i = 0; i < 22; i++) {
var a = points[i];
c1 = a ^ c1;
c2 = a + c2;
c2 = c2 & 0xff;
}
c1 = c1 & 0x0f;
points[22] = c1;
c1 = c1 & 0x0f;
c2 = c1 + c2
c2 = c2 & 0x0f;
points[23] = c2;
//Obfuscate
for (i = 0; i < 23; i++)
{
byteValue = 0;
if (EuropeanRom) {
byteValue = European[i + Random];
}
else {
byteValue = Japanese[i + Random];
}
byteValue = byteValue & 0x0f;
byteValue = byteValue ^ points[i+1];
byteValue = byteValue & 0x1f;
points[i+1] = byteValue;
}
//Add 65 to every value to get them in the ASCII range of capital characters A-Z
for (i = 0; i < 24; i++)
{
points[i] = points[i] + 65;
}
//Construct the password by convert the integer values to chars
password = "";
for (i = 0; i < 24; i++) {
password += String.fromCharCode(points[i]);
}
return password;
}
Addresses
These are addresses of interesting entry points for the European ROM version:
#72A9: start of encoding points per race into a password.
#7467: check if a built-in password is entered.
#EA52: location of generated / entered password.