1
0
mirror of synced 2025-02-17 10:38:32 +01:00

Added eeprom settings.

This commit is contained in:
dkeruza 2023-12-04 02:08:38 -05:00
parent bb5ff8b27d
commit 9c6116ee05
10 changed files with 400 additions and 3 deletions

View File

@ -9,5 +9,6 @@
"ioctl.h": "c",
"segaeax.h": "c",
"passthrough.h": "c"
}
},
"C_Cpp.errorSquiggles": "disabled"
}

View File

@ -26,3 +26,6 @@ libkswapapi.so: src/libkswapapi/libkswapapi.o
clean:
rm -rf $(BUILD)
rm -f src/lindbergh/*.o
rm -f src/libsegaapi/*.o
rm -f src/libkswapapi/*.o

View File

@ -64,3 +64,9 @@ HEIGHT 480
# PATCH A0000 909090
# Set the Region ( JP/US/EX )
REGION US
# Set if you want the game to be Free Play
FREEPLAY 1

Binary file not shown.

View File

@ -233,6 +233,19 @@ int readConfig(FILE *configFile, EmulatorConfig *config)
if (strcmp(colour, "RED") == 0)
config->lindberghColour = RED;
}
else if (strcmp(command, "REGION") == 0)
{
char region[256];
strcpy(region, getNextToken(NULL, " ", &saveptr));
if (strcmp(region, "JP") == 0)
config->region = JP;
else if (strcmp(region, "US") == 0)
config->region = US;
else
config->region = EX;
}
else if (strcmp(command, "FREEPLAY") == 0)
config->freeplay = atoi(getNextToken(NULL, " ", &saveptr));
else
printf("Error: Unknown settings command %s\n", command);
}
@ -257,6 +270,8 @@ int initConfig()
config.width = 1024;
config.height = 768;
config.crc32 = elf_crc;
config.region = US;
config.freeplay = 1;
if (detectGame(config.crc32) != 0)
{
printf("Warning: Unsure what game this is, using default configuration values.\n");

View File

@ -35,6 +35,13 @@ typedef enum
NOT_WORKING
}GameStatus;
typedef enum
{
JP,
US,
EX
}gameRegion;
typedef struct
{
int emulateRideboard;
@ -54,7 +61,8 @@ typedef struct
Colour lindberghColour;
GameStatus gameStatus;
uint32_t crc32;
gameRegion region;
int freeplay;
} EmulatorConfig;
int initConfig();

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include "eeprom.h"
#include "eeprom_settings.h"
#include "config.h"
#define I2C_SMBUS_BLOCK_MAX 32
@ -46,6 +47,19 @@ int initEeprom()
eeprom = fopen(eepromPath, "rb+");
if(eepromSettingsInit(eeprom) !=0)
{
printf("Error initializing eeprom settings.");
fclose(eeprom);
return 1;
}
if(getRegion() != getConfig()->region)
setRegion(eeprom, getConfig()->region);
if(getFreeplay() != getConfig()->freeplay)
setFreeplay(eeprom, getConfig()->freeplay);
fseek(eeprom, 0, SEEK_SET);
return 0;

View File

@ -0,0 +1,332 @@
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "eeprom_settings.h"
uint32_t crc32_table[255];
typedef struct
{
uint16_t offset;
uint16_t size;
} eepromOffsets;
typedef enum
{
STATIC,
NETWORK_TYPE,
ETH0,
ETH1,
CREDIT,
BACKUP
} eepromSection;
eepromOffsets eepromOffsetTable[] = {
{0x0000, 0x0020}, // amSysDataRecord_Static
{0x00A0, 0x0010}, // amSysDataRecord_NetworkType
{0x00B0, 0x0020}, // amSysDataRecord_Eth0
{0x00D0, 0x0020}, // amSysDataRecord_Eth1
{0x0100, 0x0040}, // amSysDataRecord_Credit
{0x0400, 0x0060}}; // amSysDataRecord_Backup
unsigned char eepromBuffer[512];
void build_crc32_table()
{
for (uint32_t i = 0; i < 256; i++)
{
uint32_t ch = i;
uint32_t crc = 0;
for (size_t j = 0; j < 8; j++)
{
uint32_t b = (ch ^ crc) & 1;
crc >>= 1;
if (b)
crc = crc ^ 0xEDB88320;
ch >>= 1;
}
crc32_table[i] = crc;
}
}
uint32_t gen_crc(int section, size_t n)
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset + 4];
unsigned long crc = 0xfffffffful;
size_t i;
for (i = 0; i < n; i++)
crc = crc32_table[*buff++ ^ (crc & 0xff)] ^ (crc >> 8);
return (crc);
}
void addCRCtoBuffer(int section)
{
uint32_t crc = gen_crc(section, eepromOffsetTable[section].size - 4);
memcpy(&eepromBuffer[eepromOffsetTable[section].offset], &crc, sizeof(uint32_t));
}
int fillBuffer(FILE *file)
{
fseek(file, 0, SEEK_SET);
int b = fread(eepromBuffer, 1, 512, file);
if (b < 512)
return 1;
return 0;
}
int checkCRCinBuffer(int section)
{
uint32_t crc;
memcpy(&crc, &eepromBuffer[eepromOffsetTable[section].offset], 4);
if (crc != gen_crc(section, eepromOffsetTable[section].size - 4))
return 1;
return 0;
}
int createStaticSection()
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[STATIC].offset];
memset(buff, 0, eepromOffsetTable[STATIC].size);
buff[14] = 0;
memcpy(buff + 15, "AAGX-01A00009999", 16);
return 0;
}
int createNetworkTypeSection()
{
memset(&eepromBuffer[eepromOffsetTable[NETWORK_TYPE].offset], 0,
eepromOffsetTable[NETWORK_TYPE].size);
return 0;
}
int createEthSection(int section)
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset];
memset(buff, 0, eepromOffsetTable[section].size);
uint32_t value = 1;
memcpy(buff + 8, &value, sizeof(uint32_t));
value = inet_addr("10.0.0.1");
if (section == ETH1)
value += (1 << 24);
memcpy(buff + 12, &value, sizeof(uint32_t));
value = inet_addr("255.255.255.0");
memcpy(buff + 16, &value, sizeof(uint32_t));
value = inet_addr("0.0.0.0");
memcpy(buff + 20, &value, sizeof(uint32_t));
memcpy(buff + 24, &value, sizeof(uint32_t));
memcpy(buff + 28, &value, sizeof(uint32_t));
return 0;
}
int createCreditSection()
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[CREDIT].offset];
memset(buff, 0, eepromOffsetTable[CREDIT].size);
buff[32] = 99;
buff[33] = 9;
buff[34] = 4;
buff[35] = 0; // Coin chute type [COMMON (Default) / INDIVIDUAL]
buff[36] = 1; // Service Type [COMMON / INDIVIDUAL (Default)]
buff[38] = 1; //
buff[39] = 0; // Freeplay set to 1
buff[40] = 1; // Credits Chute #1
buff[41] = 1; // Credits Chute #1
buff[42] = 0; //
buff[43] = 1; // Coins
for (size_t i = 0; i < 8; i++)
{
buff[44 + i] = 1;
}
return 0;
}
int writeSectiontoFile(FILE *file, int section)
{
unsigned char *buff = &eepromBuffer[eepromOffsetTable[section].offset];
// Original
if (fseek(file, eepromOffsetTable[section].offset, SEEK_SET) != 0)
return 1;
if (fwrite(buff, eepromOffsetTable[section].size, 1, file) != 1)
return 1;
// Duplicate
if (fseek(file, eepromOffsetTable[section].offset + 0x200, SEEK_SET) != 0)
return 1;
if (fwrite(buff, eepromOffsetTable[section].size, 1, file) != 1)
return 1;
return 0;
}
int getRegion()
{
return eepromBuffer[14];
}
int setRegion(FILE *eeprom, int region)
{
eepromBuffer[14] = region;
addCRCtoBuffer(STATIC);
if (writeSectiontoFile(eeprom, STATIC) != 0)
{
printf("Error setting the .");
return 1;
}
return 0;
}
int getFreeplay()
{
return eepromBuffer[eepromOffsetTable[CREDIT].offset + 39];
}
int setFreeplay(FILE *eeprom, int freeplay)
{
if (createCreditSection() != 0)
{
printf("Error setting Free Play.");
return 1;
}
eepromBuffer[eepromOffsetTable[CREDIT].offset + 39] = freeplay;
addCRCtoBuffer(CREDIT);
if (writeSectiontoFile(eeprom, CREDIT) != 0)
{
printf("Error setting Free Play.");
return 1;
}
return 0;
}
int eepromSettingsInit( FILE *eeprom)
{
build_crc32_table();
eeprom = fopen("eeprom.bin", "r+b");
if (eeprom == NULL)
{
printf("eeprom.bin cannot be opened, let's create a new one.\n");
eeprom = fopen("eeprom.bin", "w+b");
}
fseek(eeprom, 0, SEEK_END);
int size = ftell(eeprom);
fseek(eeprom, 0, SEEK_SET);
if (size >= 832) // eeprom initialized at least by SEGABOOT
{
fillBuffer(eeprom); // Fills buffer with 1st 512 bytes of the eeprom file
if (checkCRCinBuffer(STATIC) != 0)
{
// Create section from scratch
if (createStaticSection() != 0)
{
printf("Error creating Static Section.\n");
return 1;
}
else
{
addCRCtoBuffer(STATIC);
if (writeSectiontoFile(eeprom, STATIC) != 0)
{
printf("Error writing to eeprom.bin [STATIC].");
return 1;
}
}
}
if (checkCRCinBuffer(NETWORK_TYPE) != 0)
{
// Create section from scratch
if (createNetworkTypeSection() != 0)
{
printf("Error creating NetworkType Section.\n");
return 1;
}
else
{
addCRCtoBuffer(NETWORK_TYPE);
if (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0)
{
printf("Error writing to eeprom.bin [NETWORK_TYPE].");
return 1;
}
}
}
if (checkCRCinBuffer(ETH0) != 0)
{
// Create section from scratch
if (createEthSection(ETH0) != 0)
{
printf("Error creating Eth0 Section.\n");
return 1;
}
else
{
addCRCtoBuffer(ETH0);
if (writeSectiontoFile(eeprom, ETH0) != 0)
{
printf("Error writing to eeprom.bin [ETH0].");
return 1;
}
}
}
if (checkCRCinBuffer(ETH1) != 0)
{
// Create section from scratch
if (createEthSection(ETH1) != 0)
{
printf("Error creating Eth0 Section.\n");
return 1;
}
else
{
addCRCtoBuffer(ETH1);
if (writeSectiontoFile(eeprom, ETH1) != 0)
{
printf("Error writing to eeprom.bin [ETH1].");
return 1;
}
}
}
if (checkCRCinBuffer(CREDIT) != 0)
{
// Create section from scratch
if (createCreditSection() != 0)
{
printf("Error creating CREDIT Section.\n");
return 1;
}
else
{
addCRCtoBuffer(CREDIT);
if (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0)
{
printf("Error writing to eeprom.bin [CREDIT]].");
return 1;
}
}
}
}
else
{
// Create all sections from scratch
if ((createStaticSection() != 0) || (createNetworkTypeSection() != 0) ||
(createEthSection(ETH0) != 0) || (createEthSection(ETH1) != 0) || (createCreditSection() != 0))
{
printf("Error creating section from scratch.\n");
return 1;
}
addCRCtoBuffer(STATIC);
addCRCtoBuffer(NETWORK_TYPE);
addCRCtoBuffer(ETH0);
addCRCtoBuffer(ETH1);
addCRCtoBuffer(CREDIT);
if ((writeSectiontoFile(eeprom, STATIC) != 0) || (writeSectiontoFile(eeprom, NETWORK_TYPE) != 0) ||
(writeSectiontoFile(eeprom, ETH0) != 0) || (writeSectiontoFile(eeprom, ETH1) != 0) ||
(writeSectiontoFile(eeprom, CREDIT) != 0))
{
printf("Error writing section from scratch.\n");
return 1;
}
}
return 0;
}

View File

@ -0,0 +1,5 @@
int eepromSettingsInit(FILE *eeprom);
int getRegion();
int getFreeplay();
int setRegion(FILE *eeprom, int region);
int setFreeplay(FILE *eeprom, int freeplay);

View File

@ -256,7 +256,7 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
return _fopen("lindbergrc", mode);
}
if (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0)
if ((strcmp(pathname, "/usr/lib/boot/logo.tga") == 0) || (strcmp(pathname, "/usr/lib/boot/logo.tga") == 0))
{
return _fopen("logo.tga", mode);
}
@ -278,6 +278,19 @@ FILE *fopen(const char *restrict pathname, const char *restrict mode)
return fileHooks[CPUINFO];
}
if (strcmp(pathname, "/usr/lib/boot/logo_red.tga") == 0)
{
return _fopen("logo_red.tga", mode);
}
if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.tga") == 0)
{
return _fopen("SEGA_KakuGothic-DB-Roman_12.tga", mode);
}
if (strcmp(pathname, "/usr/lib/boot/SEGA_KakuGothic-DB-Roman_12.abc") == 0)
{
return _fopen("SEGA_KakuGothic-DB-Roman_12.abc", mode);
}
return _fopen(pathname, mode);
}