1
0
mirror of synced 2025-01-18 17:04:06 +01:00

Add more good stuff

This commit is contained in:
Bobby Dilley 2022-07-08 10:26:16 +01:00
parent f3febb89d8
commit 96f856dca4
6 changed files with 188 additions and 87 deletions

View File

@ -154,14 +154,14 @@ int baseboardIoctl(int fd, unsigned int request, void *data)
switch (_data[0])
{
case BASEBOARD_GET_SERIAL:
case BASEBOARD_GET_SERIAL: // bcCmdSysInfoGetReq
{
serialCommand.destAddress = _data[1];
serialCommand.destSize = _data[2];
}
break;
case BASEBOARD_WRITE_FLASH:
case BASEBOARD_WRITE_FLASH: // bcCmdSysFlashWrite
{
printf("Warning: The game attempted to write to the baseboard flash\n");
}
@ -173,8 +173,8 @@ int baseboardIoctl(int fd, unsigned int request, void *data)
jvsCommand.srcSize = _data[2];
jvsCommand.destAddress = _data[3];
jvsCommand.destSize = _data[4];
// memcpy(inputBuffer, &shm[jvsCommand.srcAddress], jvsCommand.srcSize);
// processPacket(&io);
memcpy(inputBuffer, &sharedMemory[jvsCommand.srcAddress], jvsCommand.srcSize);
processPacket();
}
break;
@ -207,16 +207,15 @@ int baseboardIoctl(int fd, unsigned int request, void *data)
case BASEBOARD_GET_SENSE_LINE:
{
// _data[2] = getSenseLine();
_data[2] = 3;
_data[2] = getSenseLine();
}
break;
case BASEBOARD_PROCESS_JVS:
{
// memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, outputPacket.length + 3);
memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, outputPacket.length + 3);
_data[2] = jvsCommand.destAddress;
// dp[3] = outputPacket.length + 3;
_data[3] = outputPacket.length + 3;
}
break;

View File

@ -6,6 +6,7 @@
#include <errno.h>
#include <linux/sockios.h>
#include <signal.h>
#include <ucontext.h>
#include "hook.h"
@ -14,6 +15,7 @@
#include "rideboard.h"
#include "eeprom.h"
#include "jvs.h"
#include "securityboard.h"
#define HOOK_FILE_NAME "/dev/zero"
@ -24,6 +26,8 @@
int hooks[4] = {-1, -1, -1, -1};
uint16_t basePortAddress = 0xFFFF;
void __attribute__((constructor)) hook_init()
{
printf("SEGA Lindbergh Loader\nRobert Dilley 2022\nNot for public consumption\n\n");
@ -37,6 +41,11 @@ void __attribute__((constructor)) hook_init()
if (initJVS() != 0)
exit(1);
if(initSecurityBoard() != 0)
exit(1);
printf("Loader init success\n");
}
int open(const char *pathname, int flags)
@ -179,9 +188,26 @@ int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set
return _select(nfds, readfds, writefds, exceptfds, timeout);
}
#include <ucontext.h>
int system(const char *command)
{
int (*_system)(const char *command) = dlsym(RTLD_NEXT, "system");
static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
if (strcmp(command, "lsmod | grep basebd > /dev/null") == 0)
return 0;
/*
if (strcmp(command, "lspci | grep \"Multimedia audio controller: %Creative\" > /dev/null") == 0)
return 0;
if (strcmp(command, "lsmod | grep ctaud") == 0)
return 0;
if (strcmp(command, "lspci | grep MPC8272 > /dev/null") == 0)
return 0;
*/
return _system(command);
}
static void handleSegfault(int signal, siginfo_t *info, void *ptr)
{
ucontext_t *ctx = ptr;
@ -193,15 +219,14 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
switch (port)
{
case 0x38:
ctx->uc_mcontext.gregs[REG_EAX] = 0xFFFFFFFF;
break;
default:
break;
}
// printf("Warning: IO READ Port %X\n", port);
if(basePortAddress == 0xFFFF)
basePortAddress = port;
if(port > 0x38)
port = port - basePortAddress;
securityBoardIn(port, (uint32_t *) &(ctx->uc_mcontext.gregs[REG_EAX]));
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
@ -209,7 +234,7 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
case 0xE7:
{
//printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
// printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
@ -217,7 +242,7 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
case 0xE6:
{
//printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
// printf("Warning: IO WRITE IMMIDIATE %X\n", code[1]);
ctx->uc_mcontext.gregs[REG_EIP] += 2;
return;
}
@ -227,7 +252,7 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
uint8_t data = ctx->uc_mcontext.gregs[REG_EAX] & 0xFF;
//printf("Warning: IO WRITE Port %X Data %X\n", port, data);
// printf("Warning: IO WRITE Port %X Data %X\n", port, data);
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
@ -236,7 +261,7 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
case 0xEF:
{
uint16_t port = ctx->uc_mcontext.gregs[REG_EDX] & 0xFFFF;
//printf("Warning: IO WRITE Port %X\n", port);
// printf("Warning: IO WRITE Port %X\n", port);
ctx->uc_mcontext.gregs[REG_EIP]++;
return;
}
@ -250,19 +275,12 @@ static void exceptionTrampoline(int signum, siginfo_t *info, void *ptr)
int iopl(int level)
{
static int hasRunAlready = 0;
struct sigaction act;
if (hasRunAlready == 0)
{
struct sigaction act;
act.sa_sigaction = handleSegfault;
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = exceptionTrampoline;
act.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &act, NULL);
hasRunAlready = 1;
}
sigaction(SIGSEGV, &act, NULL);
return 0;
}

View File

@ -160,12 +160,12 @@ void writeFeatures(JVSPacket *outputPacket, JVSCapabilities *capabilities)
*
* @returns The status of the entire operation
*/
JVSStatus processPacket(JVSIO *jvsIO)
JVSStatus processPacket()
{
readPacket(&inputPacket);
/* Check if the packet is for us */
if (inputPacket.destination != BROADCAST && inputPacket.destination != jvsIO->deviceID)
if (inputPacket.destination != BROADCAST && inputPacket.destination != io.deviceID)
return JVS_STATUS_NOT_FOR_US;
/* Setup the output packet */
@ -209,8 +209,8 @@ JVSStatus processPacket(JVSIO *jvsIO)
{
// printf("CMD_REQUEST_ID\n");
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
memcpy(&outputPacket.data[outputPacket.length + 1], jvsIO->capabilities.name, strlen(jvsIO->capabilities.name) + 1);
outputPacket.length += strlen(jvsIO->capabilities.name) + 2;
memcpy(&outputPacket.data[outputPacket.length + 1], io.capabilities.name, strlen(io.capabilities.name) + 1);
outputPacket.length += strlen(io.capabilities.name) + 2;
}
break;
@ -219,7 +219,7 @@ JVSStatus processPacket(JVSIO *jvsIO)
{
// printf("CMD_COMMAND_VERSION\n");
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
outputPacket.data[outputPacket.length + 1] = jvsIO->capabilities.commandVersion;
outputPacket.data[outputPacket.length + 1] = io.capabilities.commandVersion;
outputPacket.length += 2;
}
break;
@ -227,9 +227,9 @@ JVSStatus processPacket(JVSIO *jvsIO)
/* Asks for version information */
case CMD_JVS_VERSION:
{
////printf("CMD_JVS_VERSION\n");
// printf("CMD_JVS_VERSION\n");
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
outputPacket.data[outputPacket.length + 1] = jvsIO->capabilities.jvsVersion;
outputPacket.data[outputPacket.length + 1] = io.capabilities.jvsVersion;
outputPacket.length += 2;
}
break;
@ -237,9 +237,9 @@ JVSStatus processPacket(JVSIO *jvsIO)
/* Asks for version information */
case CMD_COMMS_VERSION:
{
////printf("CMD_COMMS_VERSION\n");
// printf("CMD_COMMS_VERSION\n");
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
outputPacket.data[outputPacket.length + 1] = jvsIO->capabilities.commsVersion;
outputPacket.data[outputPacket.length + 1] = io.capabilities.commsVersion;
outputPacket.length += 2;
}
break;
@ -248,7 +248,7 @@ JVSStatus processPacket(JVSIO *jvsIO)
case CMD_CAPABILITIES:
{
// printf("CMD_CAPABILITIES\n");
writeFeatures(&outputPacket, &jvsIO->capabilities);
writeFeatures(&outputPacket, &io.capabilities);
}
break;
@ -258,13 +258,13 @@ JVSStatus processPacket(JVSIO *jvsIO)
// printf("CMD_READ_SWITCHES\n");
size = 3;
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
outputPacket.data[outputPacket.length + 1] = jvsIO->state.inputSwitch[0];
outputPacket.data[outputPacket.length + 1] = io.state.inputSwitch[0];
outputPacket.length += 2;
for (int i = 0; i < inputPacket.data[index + 1]; i++)
{
for (int j = 0; j < inputPacket.data[index + 2]; j++)
{
outputPacket.data[outputPacket.length++] = jvsIO->state.inputSwitch[i + 1] >> (8 - (j * 8));
outputPacket.data[outputPacket.length++] = io.state.inputSwitch[i + 1] >> (8 - (j * 8));
}
}
}
@ -279,8 +279,8 @@ JVSStatus processPacket(JVSIO *jvsIO)
for (int i = 0; i < numberCoinSlots; i++)
{
outputPacket.data[outputPacket.length] = (jvsIO->state.coinCount[i] << 8) & 0x1F;
outputPacket.data[outputPacket.length + 1] = jvsIO->state.coinCount[i] & 0xFF;
outputPacket.data[outputPacket.length] = (io.state.coinCount[i] << 8) & 0x1F;
outputPacket.data[outputPacket.length + 1] = io.state.coinCount[i] & 0xFF;
outputPacket.length += 2;
}
}
@ -296,7 +296,7 @@ JVSStatus processPacket(JVSIO *jvsIO)
for (int i = 0; i < inputPacket.data[index + 1]; i++)
{
/* By default left align the data */
int analogueData = jvsIO->state.analogueChannel[i] << jvsIO->analogueRestBits;
int analogueData = io.state.analogueChannel[i] << io.analogueRestBits;
outputPacket.data[outputPacket.length] = analogueData >> 8;
outputPacket.data[outputPacket.length + 1] = analogueData;
outputPacket.length += 2;
@ -313,8 +313,8 @@ JVSStatus processPacket(JVSIO *jvsIO)
for (int i = 0; i < inputPacket.data[index + 1]; i++)
{
outputPacket.data[outputPacket.length] = jvsIO->state.rotaryChannel[i] >> 8;
outputPacket.data[outputPacket.length + 1] = jvsIO->state.rotaryChannel[i];
outputPacket.data[outputPacket.length] = io.state.rotaryChannel[i] >> 8;
outputPacket.data[outputPacket.length + 1] = io.state.rotaryChannel[i];
outputPacket.length += 2;
}
}
@ -414,9 +414,9 @@ JVSStatus processPacket(JVSIO *jvsIO)
outputPacket.data[outputPacket.length++] = REPORT_SUCCESS;
/* Prevent overflow of coins */
if (coin_increment + jvsIO->state.coinCount[slot_index] > 16383)
coin_increment = 16383 - jvsIO->state.coinCount[slot_index];
jvsIO->state.coinCount[slot_index] += coin_increment;
if (coin_increment + io.state.coinCount[slot_index] > 16383)
coin_increment = 16383 - io.state.coinCount[slot_index];
io.state.coinCount[slot_index] += coin_increment;
}
break;
@ -439,9 +439,9 @@ JVSStatus processPacket(JVSIO *jvsIO)
outputPacket.data[outputPacket.length++] = REPORT_SUCCESS;
/* Prevent underflow of coins */
if (coin_decrement > jvsIO->state.coinCount[slot_index])
coin_decrement = jvsIO->state.coinCount[slot_index];
jvsIO->state.coinCount[slot_index] -= coin_decrement;
if (coin_decrement > io.state.coinCount[slot_index])
coin_decrement = io.state.coinCount[slot_index];
io.state.coinCount[slot_index] -= coin_decrement;
}
break;
@ -462,23 +462,6 @@ JVSStatus processPacket(JVSIO *jvsIO)
}
break;
/* The touch screen and light gun input, simply using analogue channels */
case CMD_READ_LIGHTGUN:
{
////printf("CMD_READ_LIGHTGUN\n");
size = 2;
int analogueXData = jvsIO->state.gunChannel[0] << jvsIO->gunXRestBits;
int analogueYData = jvsIO->state.gunChannel[1] << jvsIO->gunYRestBits;
outputPacket.data[outputPacket.length] = REPORT_SUCCESS;
outputPacket.data[outputPacket.length + 1] = analogueXData >> 8;
outputPacket.data[outputPacket.length + 2] = analogueXData;
outputPacket.data[outputPacket.length + 3] = analogueYData >> 8;
outputPacket.data[outputPacket.length + 4] = analogueYData;
outputPacket.length += 5;
}
break;
default:
{
printf("Error: JVS command not supported [0x%02hhX]\n", inputPacket.data[index]);
@ -624,34 +607,34 @@ int getSenseLine()
return senseLine;
}
int setSwitch(JVSIO *io, JVSPlayer player, JVSInput switchNumber, int value)
int setSwitch(JVSPlayer player, JVSInput switchNumber, int value)
{
if (player > io->capabilities.players)
if (player > io.capabilities.players)
return 0;
if (value)
{
io->state.inputSwitch[player] |= switchNumber;
io.state.inputSwitch[player] |= switchNumber;
}
else
{
io->state.inputSwitch[player] &= ~switchNumber;
io.state.inputSwitch[player] &= ~switchNumber;
}
return 1;
}
int incrementCoin(JVSIO *io, JVSPlayer player, int amount)
int incrementCoin(JVSPlayer player, int amount)
{
if (player == SYSTEM)
return 0;
io->state.coinCount[player - 1] = io->state.coinCount[player - 1] + amount;
io.state.coinCount[player - 1] = io.state.coinCount[player - 1] + amount;
return 1;
}
int setAnalogue(JVSIO *io, JVSInput channel, int value)
int setAnalogue(JVSInput channel, int value)
{
io->state.analogueChannel[channel] = value;
io.state.analogueChannel[channel] = value;
return 1;
}

View File

@ -223,7 +223,7 @@ typedef enum
int initJVS();
JVSStatus processPacket(JVSIO *jvsIO);
JVSStatus processPacket();
JVSStatus readPacket(JVSPacket *packet);
JVSStatus writePacket(JVSPacket *packet);
@ -239,9 +239,9 @@ int getSenseLine();
JVSCapabilities *getCapabilities();
JVSState *getState();
int initIO(JVSIO *io);
int setSwitch(JVSIO *io, JVSPlayer player, JVSInput switchNumber, int value);
int incrementCoin(JVSIO *io, JVSPlayer player, int amount);
int setAnalogue(JVSIO *io, JVSInput channel, int value);
int initIO();
int setSwitch(JVSPlayer player, JVSInput switchNumber, int value);
int incrementCoin(JVSPlayer player, int amount);
int setAnalogue(JVSInput channel, int value);
#endif // JVS_H_

View File

@ -0,0 +1,91 @@
#include <stdio.h>
#include <string.h>
#include "securityboard.h"
#define SECURITY_BOARD_FRONT_PANEL 0x38
#define SECURITY_BOARD_KEYCHIP 0xFF
#define DIP_SWITCH_ROTATION 2
typedef struct
{
int serviceSwitch;
int testSwitch;
int dipSwitch[8];
int led[2];
} SecurityBoard;
SecurityBoard securityBoard = {0};
int initSecurityBoard()
{
securityBoard.dipSwitch[DIP_SWITCH_ROTATION] = 0;
return 0;
}
int securityBoardSetRotation(int rotation)
{
securityBoard.dipSwitch[DIP_SWITCH_ROTATION] = rotation;
return 0;
}
int securityBoardSetSwitch(JVSInput switchNumber, int value)
{
switch (switchNumber)
{
case BUTTON_TEST:
securityBoard.testSwitch = value;
break;
case BUTTON_SERVICE:
securityBoard.serviceSwitch = value;
break;
default:
printf("Error: Attempted to set a security board switch incorrectly");
return -1;
}
return 0;
}
int securityBoardOut(uint16_t port, uint32_t *data)
{
return 0;
}
int securityBoardIn(uint16_t port, uint32_t *data)
{
switch (port)
{
case SECURITY_BOARD_FRONT_PANEL:
uint32_t result = 0xFFFFFFFF;
if (securityBoard.serviceSwitch)
result &= ~0x08;
if (securityBoard.testSwitch)
result &= ~0x04;
if (securityBoard.dipSwitch[7])
result &= ~0x800;
if (securityBoard.dipSwitch[0])
result &= ~0x400;
if (securityBoard.dipSwitch[1])
result &= ~0x200;
if (securityBoard.dipSwitch[2])
result &= ~0x100;
if (securityBoard.dipSwitch[3])
result &= ~0x80;
if (securityBoard.dipSwitch[4])
result &= ~0x40;
if (securityBoard.dipSwitch[5])
result &= ~0x20;
if (securityBoard.dipSwitch[6])
result &= ~0x10;
*data = result;
break;
default:
break;
}
return 0;
}

View File

@ -0,0 +1,10 @@
#include <stdint.h>
#include "jvs.h"
int initSecurityBoard();
int securityBoardOut(uint16_t port, uint32_t *data);
int securityBoardIn(uint16_t port, uint32_t *data);
int securityBoardSetSwitch(JVSInput switchNumber, int value);
int securityBoardSetRotation(int rotation);
int securityBoardSetDipSwitch(int switchNumber, int value);