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.