mirror of
https://github.com/lindbergh-loader/lindbergh-loader.git
synced 2026-10-13 17:48:27 +03:00
173 lines
4.0 KiB
C
173 lines
4.0 KiB
C
#include <string.h>
|
|
|
|
#include "config.h"
|
|
#include "eepromSettings.h"
|
|
|
|
#define I2C_SMBUS_BLOCK_MAX 32
|
|
#define I2C_GET_FUNCTIONS 0x705
|
|
#define I2C_SMBUS_TRANSFER 0x720
|
|
#define I2C_SET_SLAVE_MODE 0x703
|
|
#define I2C_BUFFER_CLEAR 0x1261
|
|
#define I2C_READ 1
|
|
#define I2C_SEEK 2
|
|
#define I2C_WRITE 3
|
|
|
|
extern uint32_t gId;
|
|
|
|
union i2c_smbus_data {
|
|
uint8_t byte;
|
|
uint16_t word;
|
|
uint8_t block[I2C_SMBUS_BLOCK_MAX + 2];
|
|
};
|
|
|
|
struct i2c_smbus_ioctl_data
|
|
{
|
|
uint8_t read_write;
|
|
uint8_t command;
|
|
uint32_t size;
|
|
union i2c_smbus_data *data;
|
|
};
|
|
|
|
FILE *eeprom = NULL;
|
|
|
|
int initEeprom()
|
|
{
|
|
char *eepromPath = getConfig()->eepromPath;
|
|
|
|
eeprom = fopen(eepromPath, "a");
|
|
|
|
// Create file if it doesn't exist
|
|
if (eeprom == NULL)
|
|
{
|
|
printf("Error: Cannot open %s\n", eepromPath);
|
|
return 1;
|
|
}
|
|
|
|
fclose(eeprom);
|
|
|
|
eeprom = fopen(eepromPath, "rb+");
|
|
|
|
if (eepromSettingsInit(eeprom) != 0)
|
|
{
|
|
printf("Error initializing eeprom settings.");
|
|
fclose(eeprom);
|
|
return 1;
|
|
}
|
|
|
|
if (getConfig()->region != -1)
|
|
{
|
|
if (getRegion() != getConfig()->region)
|
|
setRegion(eeprom, getConfig()->region);
|
|
}
|
|
|
|
if (getConfig()->freeplay != -1)
|
|
{
|
|
if (getFreeplay() != getConfig()->freeplay)
|
|
setFreeplay(eeprom, getConfig()->freeplay);
|
|
}
|
|
|
|
switch (gId)
|
|
{
|
|
case LETS_GO_JUNGLE_SPECIAL:
|
|
case THE_HOUSE_OF_THE_DEAD_EX:
|
|
case THE_HOUSE_OF_THE_DEAD_4_SPECIAL:
|
|
case THE_HOUSE_OF_THE_DEAD_4_SPECIAL_REVB:
|
|
if (fixCreditSection(eeprom) != 0)
|
|
{
|
|
printf("Error initializing eeprom settings.");
|
|
fclose(eeprom);
|
|
return 1;
|
|
}
|
|
break;
|
|
case HUMMER:
|
|
case HUMMER_SDLX:
|
|
case HUMMER_EXTREME:
|
|
case HUMMER_EXTREME_MDX:
|
|
if (fixCoinAssignmentsHummer(eeprom) != 0)
|
|
{
|
|
printf("Error initializing eeprom settings.");
|
|
fclose(eeprom);
|
|
return 1;
|
|
}
|
|
break;
|
|
case OUTRUN_2_SP_SDX:
|
|
case OUTRUN_2_SP_SDX_REVA:
|
|
if (getConfig()->enableNetworkPatches && strcmp(getConfig()->or2IP, "") != 0 && strcmp(getConfig()->or2Netmask, "") != 0)
|
|
{
|
|
if (setIP(eeprom, getConfig()->or2IP, getConfig()->or2Netmask) != 0)
|
|
{
|
|
printf("Error setting the new IP address.");
|
|
fclose(eeprom);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
fseek(eeprom, 0, SEEK_SET);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int eepromIoctl(int fd, unsigned int request, void *data)
|
|
{
|
|
switch (request)
|
|
{
|
|
|
|
case I2C_GET_FUNCTIONS:
|
|
{
|
|
// The below is copied from what SEGABOOT expects
|
|
uint32_t *functions = data;
|
|
functions[0] = 0x20000 | 0x40000 | 0x100000 | 0x400000 | 0x8000000;
|
|
|
|
// The following is taken from the eeprom init sequence in The House Of The Dead 4 so let's add em on!
|
|
functions[0] =
|
|
functions[0] | 0x20000 | 0x40000 | 0x80000 | 0x100000 | 0x200000 | 0x400000 | 0x1000000 | 0x2000000;
|
|
}
|
|
break;
|
|
|
|
case I2C_SMBUS_TRANSFER:
|
|
{
|
|
struct i2c_smbus_ioctl_data *_data = data;
|
|
|
|
switch (_data->size)
|
|
{
|
|
|
|
case I2C_READ:
|
|
{
|
|
fread(&_data->data->byte, 1, sizeof(char), eeprom);
|
|
}
|
|
break;
|
|
|
|
case I2C_SEEK:
|
|
{
|
|
uint16_t address = (_data->command & 0xFF) << 8 | (_data->data->byte & 0xFF);
|
|
fseek(eeprom, address, SEEK_SET);
|
|
}
|
|
break;
|
|
|
|
case I2C_WRITE:
|
|
{
|
|
uint16_t address = (_data->command & 0xFF) << 8 | (_data->data->byte & 0xFF);
|
|
char val = _data->data->word >> 8 & 0xFF;
|
|
fseek(eeprom, address, SEEK_SET);
|
|
fwrite(&val, 1, sizeof(char), eeprom);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
printf("Error: Incorrect I2C transfer size\n");
|
|
}
|
|
}
|
|
break;
|
|
|
|
case I2C_SET_SLAVE_MODE:
|
|
case I2C_BUFFER_CLEAR:
|
|
break;
|
|
|
|
default:
|
|
printf("Error: Unkown I2C ioctl %X\n", request);
|
|
}
|
|
|
|
return 0;
|
|
}
|