diff --git a/src/lindbergh/baseboard.c b/src/lindbergh/baseboard.c index 973d5d7..135326d 100644 --- a/src/lindbergh/baseboard.c +++ b/src/lindbergh/baseboard.c @@ -135,6 +135,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data) case BASEBOARD_INIT: { + printf("baseboard init\n"); // selectReply = -1; Considering adding this in return 0; } @@ -142,6 +143,8 @@ int baseboardIoctl(int fd, unsigned int request, void *data) case BASEBOARD_READY: // Not sure this is what it should be called { + printf("baseboard read\n"); + selectReply = 0; return 0; } @@ -181,6 +184,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data) case BASEBOARD_GET_SERIAL: // bcCmdSysInfoGetReq { + printf("game asked for serial\n"); serialCommand.destAddress = _data[1]; serialCommand.destSize = _data[2]; } @@ -199,6 +203,13 @@ int baseboardIoctl(int fd, unsigned int request, void *data) jvsCommand.destAddress = _data[3]; jvsCommand.destSize = _data[4]; memcpy(inputBuffer, &sharedMemory[jvsCommand.srcAddress], jvsCommand.srcSize); + printf("TO OPENJVS\n"); + for (int i = 0; i < jvsCommand.srcSize; i++) + { + printf("%X ", sharedMemory[jvsCommand.srcAddress + i] & 0xFF); + } + printf("\n"); + if (getConfig()->emulateJVS) { processPacket(); @@ -224,7 +235,10 @@ int baseboardIoctl(int fd, unsigned int request, void *data) break; case BASEBOARD_GET_SENSE_LINE: - break; + { + printf("REQUEST SENSE LINE\n"); + } + break; default: printf("Error: Unknown baseboard command %X\n", _data[0]); @@ -246,6 +260,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data) case BASEBOARD_GET_SERIAL: { + printf("receive serial\n"); memcpy(&sharedMemory[serialCommand.destAddress + 96], SERIAL_STRING, strlen(SERIAL_STRING)); _data[1] = 1; // Set the status to success } @@ -255,6 +270,7 @@ int baseboardIoctl(int fd, unsigned int request, void *data) { _data[2] = getSenseLine(); _data[1] = 1; // Set the status to success + printf("RECEIVE SENSE LINE\n"); } break; @@ -262,10 +278,19 @@ int baseboardIoctl(int fd, unsigned int request, void *data) { if (getConfig()->emulateJVS) { + printf("FROM OPENJVS\n"); + memcpy(&sharedMemory[jvsCommand.destAddress], outputBuffer, outputPacket.length + 3); + usleep(500); _data[2] = jvsCommand.destAddress; _data[3] = outputPacket.length + 3; _data[1] = 1; // Set the status to success + + for (int i = 0; i < _data[3]; i++) + { + printf("%X ", sharedMemory[jvsCommand.destAddress + i] & 0xFF); + } + printf("\n"); } else if (jvsFileDescriptor >= 0) { diff --git a/src/lindbergh/config.c b/src/lindbergh/config.c index 6e63f66..e7e9bab 100644 --- a/src/lindbergh/config.c +++ b/src/lindbergh/config.c @@ -48,7 +48,7 @@ static int detectGame() return 0; } - if (strstr(program_invocation_name, "Jennifer") || strstr(program_invocation_name, "JenTest")) + if (strstr(program_invocation_name, "Jennifer")) { config.game = OUTRUN; config.emulateDriveboard = 1; @@ -56,6 +56,14 @@ static int detectGame() return 0; } + if (strstr(program_invocation_name, "JenTest")) + { + config.game = OUTRUN_TEST; + config.emulateDriveboard = 1; + config.emulateMotionboard = 1; + return 0; + } + if (strstr(program_invocation_name, "lgj")) { config.game = LETS_GO_JUNGLE; diff --git a/src/lindbergh/config.h b/src/lindbergh/config.h index 38aced7..841605f 100644 --- a/src/lindbergh/config.h +++ b/src/lindbergh/config.h @@ -10,6 +10,7 @@ typedef enum SEGABOOT_2_6, THE_HOUSE_OF_THE_DEAD_4, OUTRUN, + OUTRUN_TEST, LETS_GO_JUNGLE } Game; diff --git a/src/lindbergh/driveboard.c b/src/lindbergh/driveboard.c index df2aaf4..0f8f6f7 100644 --- a/src/lindbergh/driveboard.c +++ b/src/lindbergh/driveboard.c @@ -34,7 +34,7 @@ ssize_t driveboardWrite(int fd, const void *buf, size_t count) if (count != 4) { - printf("Error: Drive board count not what expected\n"); + //printf("Error: Drive board count not what expected\n"); return 1; } @@ -44,21 +44,21 @@ ssize_t driveboardWrite(int fd, const void *buf, size_t count) { case 0xFF: { - printf("Driveboard: Drive board reset\n"); + //printf("Driveboard: Drive board reset\n"); response = DRIVEBOARD_READY; } break; case 0x81: { - printf("Driveboard: Drive board reset 2\n"); + //printf("Driveboard: Drive board reset 2\n"); response = DRIVEBOARD_NOT_INIT; } break; case 0xFC: { - printf("Driveboard: Start wheel bounds testing\n"); + //printf("Driveboard: Start wheel bounds testing\n"); wheelTest = 1; } break; @@ -83,7 +83,7 @@ ssize_t driveboardWrite(int fd, const void *buf, size_t count) setAnalogue(ANALOGUE_1, (int)(steerValue * 1024)); } - printf("Driveboard move %f %f\n", steerValue, force); + //printf("Driveboard move %f %f\n", steerValue, force); } break; @@ -98,14 +98,14 @@ ssize_t driveboardWrite(int fd, const void *buf, size_t count) if (buffer[1] == 0) force = ((1 - ((double)buffer[2] / 128.0)) * 2) / 100; - printf("Driveboard set force%f %f\n", steerValue, force); + //printf("Driveboard set force%f %f\n", steerValue, force); } break; case 0xFA: case 0xFD: { - printf("Driveboard: auto turn wheel mode\n"); + //printf("Driveboard: auto turn wheel mode\n"); if (wheelTest) { @@ -123,7 +123,7 @@ ssize_t driveboardWrite(int fd, const void *buf, size_t count) break; default: - printf("Driveboard: Unknown command received %X\n", buffer[0]); + //printf("Driveboard: Unknown command received %X\n", buffer[0]); break; } diff --git a/src/lindbergh/graphics.c b/src/lindbergh/graphics.c index d8bb015..7bf9f52 100644 --- a/src/lindbergh/graphics.c +++ b/src/lindbergh/graphics.c @@ -29,7 +29,7 @@ FGAPI int FGAPIENTRY glutEnterGameMode() glutCreateWindow(gameTitle); // Outrun doesn't run the glutMainLoop through, so we'll do that here - if (getConfig()->game == OUTRUN) + if (getConfig()->game == OUTRUN || getConfig()->game == OUTRUN_TEST) { pthread_t glutMainLoopID; pthread_create(&glutMainLoopID, NULL, &glutMainLoopThread, NULL); diff --git a/src/lindbergh/hook.c b/src/lindbergh/hook.c index 88fef7d..edcbea8 100644 --- a/src/lindbergh/hook.c +++ b/src/lindbergh/hook.c @@ -126,6 +126,67 @@ void setVariable(uint32_t address, uint32_t value) *variable = value; } +/** + bool Detour(byte_t* src, byte_t* dst, size_t size) +{ + if(size < HOOK_MIN_SIZE) return false; + //mprotect(src, size, PROT_EXEC | PROT_READ | PROT_WRITE); + int out = ProtectMemory((mem_t)src, size, PROT_EXEC | PROT_READ | PROT_WRITE); + //std::cout << out << std::endl; + mem_t jmpAddr = ((mem_t)dst - (mem_t)src) - HOOK_MIN_SIZE; + byte_t CodeCave[] = { JMP, 0x0, 0x0, 0x0, 0x0 }; + *(mem_t*)((mem_t)CodeCave + sizeof(JMP)) = jmpAddr; + memcpy(src, CodeCave, sizeof(CodeCave)); + return true; +} +*/ + +void detourFunction(uint32_t address, void *function) +{ + int pagesize = sysconf(_SC_PAGE_SIZE); + + void *toModify = (void *)(address - (address % pagesize)); + + int prot = mprotect(toModify, pagesize, PROT_EXEC | PROT_WRITE | PROT_READ); + if (prot != 0) + { + printf("unprotect error %d\n", prot); + abort(); + } + + uint32_t jumpAddress = ((uint32_t)function - address) - 5; + + char cave[5] = {0xE9, 0x0, 0x00, 0x00, 0x00}; + memcpy(cave + 1, (void *)jumpAddress, 4); + for (int i = 0; i < 5; i++) + { + printf("%X ", cave[i] & 0xFF); + } + printf("\n"); + + memcpy((void *)address, cave, 5); + + return; +} + +int amDongleInit() +{ + printf("amDongleInit calld\n"); + return 0; +} + +int amDongleIsAvailable() +{ + printf("amDongleIsAvailable calld\n"); + return 1; +} + +int amDongleUpdate() +{ + printf("amDongleUpdate calld\n"); + return 0; +} + void __attribute__((constructor)) hook_init() { printf("SEGA Lindbergh Loader\nRobert Dilley 2022\nNot for public consumption\n\n"); @@ -183,6 +244,27 @@ void __attribute__((constructor)) hook_init() setVariable(0x0a737f20, 2); // bcLibDebugLevel setVariable(0x0a737f24, 0x0FFFFFFF); // s_logMask */ + + if (getConfig()->game == OUTRUN) + { + printf("Enabling game debug features for outrun\n"); + setVariable(0x0893a24c, 2); // amBackupDebugLevel + setVariable(0x0893a260, 2); // amCreditDebugLevel + setVariable(0x0893a4b8, 2); // amDipswDebugLevel + setVariable(0x0893a4bc, 2); // amDongleDebugLevel + setVariable(0x0893a4c0, 2); // amEepromDebugLevel + setVariable(0x0893a4c4, 2); // amHwmonitorDebugLevel + setVariable(0x0893a4c8, 2); // amJvsDebugLevel + setVariable(0x0893a4cc, 2); // amLibDebugLevel + setVariable(0x0893a4d0, 2); // amMiscDebugLevel + setVariable(0x0893a4d4, 2); // amOsinfoDebugLevel + setVariable(0x0893a4d8, 2); // amSysDataDebugLevel + setVariable(0x0893a4e0, 2); // bcLibDebugLevel + + detourFunction(0x08190e80, amDongleInit); // amInit 08190e80 + detourFunction(0x08191201, amDongleIsAvailable); + detourFunction(0x08191125, amDongleUpdate); + } } int open(const char *pathname, int flags) diff --git a/src/lindbergh/jvs.c b/src/lindbergh/jvs.c index cf32551..8b01def 100644 --- a/src/lindbergh/jvs.c +++ b/src/lindbergh/jvs.c @@ -189,7 +189,7 @@ JVSStatus processPacket() size = 2; io.deviceID = -1; senseLine = 3; - // printf("CMD_RESET %d\n", senseLine); + printf("CMD_RESET %d\n", senseLine); } break; @@ -559,9 +559,11 @@ JVSStatus readPacket(JVSPacket *packet) */ JVSStatus writePacket(JVSPacket *packet) { + printf("packet\n"); /* Don't return anything if there isn't anything to write! */ - if (packet->length < 2) - return JVS_STATUS_SUCCESS; + + printf("sent a packet\n"); + /* Get pointer to raw data in packet */ unsigned char *packetPointer = (unsigned char *)packet; @@ -640,5 +642,6 @@ int setAnalogue(JVSInput channel, int value) } void setSenseLine(int _senseLine) { + printf("sense line set to %d\n", _senseLine); senseLine = _senseLine; }