Fixed eeprom saving on VC (#334)

* Fixed eeprom saving on VC

* Specify SM for EEP4K, for any other savetype use ED

* Moved IS_VC() check to an earlier point, switch IS_VC()->gIsVC

* Moved binary VC files to bin folder, added checks for EEP

* Do not keep vc_bin if EEP is not set
This commit is contained in:
Denis Kopyrin
2022-03-27 10:39:44 +08:00
committed by GitHub
parent 4b9a0b89a0
commit 4a3ef802d5
12 changed files with 128 additions and 3 deletions

View File

@@ -17,7 +17,11 @@
.ascii INTERNAL_ROM_NAME /* Internal ROM name */
.word 0x00000000 /* Unknown */
.word 0x0000004E /* Cartridge */
#if defined(EEP4K)
.ascii "SM" /* Cartridge ID */
#else
.ascii "ED" /* Cartridge ID */
#endif
/* Region */
#if defined(VERSION_JP) || defined(VERSION_SH)

23
asm/vc_bin.s Normal file
View File

@@ -0,0 +1,23 @@
// VC is using binary matching to stub functions - this hex was copied from SM64
// osEepromRead/Write are performing infinite cycle inside them which causes recompiler do go crazy
// _osEepStatus does not have any suspicious asm in it but it is just VC hacked anyways
// If it is not replaced with a VC variant, EEP probe fails
.include "macros.inc"
.section .text
#if defined(EEP)
// 0x80329150 = 0xE4150
.balign 16
glabel osEepromReadVC
.incbin "bin/vc/osEepromReadVC.bin"
// 0x80328af0 = 0xE3AF0
.balign 16
glabel osEepromWriteVC
.incbin "bin/vc/osEepromWriteVC.bin"
.balign 16
glabel __osEepStatusVC
.incbin "bin/vc/osEepStatusVC.bin"
#endif

BIN
bin/vc/osEepStatusVC.bin Normal file

Binary file not shown.

BIN
bin/vc/osEepromReadVC.bin Normal file

Binary file not shown.

BIN
bin/vc/osEepromWriteVC.bin Normal file

Binary file not shown.

View File

@@ -159,6 +159,9 @@ SECTIONS
{
KEEP(BUILD_DIR/asm/entry.o(.text*));
KEEP(BUILD_DIR/asm/n64_assert.o(.text*));
#ifdef EEP
KEEP(BUILD_DIR/asm/vc_bin.o(.text*));
#endif
BUILD_DIR/src/boot*.o(.text*);
BUILD_DIR/src/hvqm*.o(.text*);

View File

@@ -21,6 +21,8 @@
#include "game/puppyprint.h"
#include "game/puppylights.h"
#include "game/vc_check.h"
// Message IDs
enum MessageIDs {
MESG_SP_COMPLETE = 100,
@@ -302,6 +304,7 @@ void thread3_main(UNUSED void *arg) {
setup_mesg_queues();
alloc_pool();
load_engine_code_segment();
gIsVC = IS_VC();
#ifndef UNF
crash_screen_init();
#endif

View File

@@ -29,6 +29,7 @@
#include "puppycam2.h"
#include "debug_box.h"
#include "vc_check.h"
#include "vc_ultra.h"
// First 3 controller slots
struct Controller gControllers[3];
@@ -653,7 +654,9 @@ void init_controllers(void) {
#ifdef EEP
// strangely enough, the EEPROM probe for save data is done in this function.
// save pak detection?
gEepromProbe = osEepromProbe(&gSIEventMesgQueue);
gEepromProbe = gIsVC
? osEepromProbeVC(&gSIEventMesgQueue)
: osEepromProbe (&gSIEventMesgQueue);
#endif
#ifdef SRAM
gSramProbe = nuPiInitSram();

View File

@@ -52,6 +52,9 @@ s8 gLevelToCourseNumTable[] = {
STATIC_ASSERT(ARRAY_COUNT(gLevelToCourseNumTable) == LEVEL_COUNT - 1,
"change this array if you are adding levels");
#ifdef EEP
#include "vc_check.h"
#include "vc_ultra.h"
/**
* Read from EEPROM to a given address.
* The EEPROM address is computed using the offset of the destination address from gSaveBuffer.
@@ -70,7 +73,9 @@ static s32 read_eeprom_data(void *buffer, s32 size) {
block_until_rumble_pak_free();
#endif
triesLeft--;
status = osEepromLongRead(&gSIEventMesgQueue, offset, buffer, size);
status = gIsVC
? osEepromLongReadVC(&gSIEventMesgQueue, offset, buffer, size)
: osEepromLongRead (&gSIEventMesgQueue, offset, buffer, size);
#if ENABLE_RUMBLE
release_rumble_pak_control();
#endif
@@ -98,7 +103,9 @@ static s32 write_eeprom_data(void *buffer, s32 size) {
block_until_rumble_pak_free();
#endif
triesLeft--;
status = osEepromLongWrite(&gSIEventMesgQueue, offset, buffer, size);
status = gIsVC
? osEepromLongWriteVC(&gSIEventMesgQueue, offset, buffer, size)
: osEepromLongWrite (&gSIEventMesgQueue, offset, buffer, size);
#if ENABLE_RUMBLE
release_rumble_pak_control();
#endif

7
src/game/vc_bin.h Normal file
View File

@@ -0,0 +1,7 @@
// These functions are actually fully binary, I use these invokations for my convenience
#include <ultra64.h>
s32 osEepromReadVC(OSMesgQueue *mq, u8 address, u8 *buffer);
s32 osEepromWriteVC(OSMesgQueue *mq, u8 address, u8 *buffer);
s32 __osEepStatusVC(OSMesgQueue *mq, OSContStatus *data);

68
src/game/vc_ultra.c Normal file
View File

@@ -0,0 +1,68 @@
#include "vc_ultra.h"
#include "vc_bin.h"
#ifdef EEP
// These functions are real implementations of libultra functions
// with an exception that some VC useless code was dropped from them
// for the cleaner understanding purposes.
// These functions are generally wrappers around binary stubs from vc_bin
s32 osEepromProbeVC(OSMesgQueue *mq)
{
s32 ret;
u16 type;
ret = 0;
OSContStatus sdata;
ret = __osEepStatusVC(mq, &sdata); // call to binary stub
type = sdata.type & (CONT_EEPROM | CONT_EEP16K);
if (ret != 0)
{
ret = 0;
}
else
{
switch (type)
{
case CONT_EEPROM:
ret = EEPROM_TYPE_4K;
break;
case CONT_EEPROM | CONT_EEP16K:
ret = EEPROM_TYPE_16K;
break;
default:
ret = 0;
break;
}
}
return ret;
}
s32 osEepromLongReadVC(OSMesgQueue *mq, u8 address, u8 *buffer, int length)
{
s32 ret;
ret = 0;
while (length > 0)
{
osEepromReadVC(mq, address, buffer); // call to binary stub
length -= EEPROM_BLOCK_SIZE;
address++;
buffer += EEPROM_BLOCK_SIZE;
}
return ret;
}
s32 osEepromLongWriteVC(OSMesgQueue *mq, u8 address, u8 *buffer, int length)
{
s32 ret;
ret = 0;
while (length > 0)
{
osEepromWriteVC(mq, address, buffer); // call to binary stub
length -= EEPROM_BLOCK_SIZE;
address++;
buffer += EEPROM_BLOCK_SIZE;
}
return ret;
}
#endif

7
src/game/vc_ultra.h Normal file
View File

@@ -0,0 +1,7 @@
// Some libultra functions that use VC alternatives
#include <ultra64.h>
s32 osEepromProbeVC(OSMesgQueue *mq);
s32 osEepromLongReadVC(OSMesgQueue *mq, u8 address, u8 *buffer, int length);
s32 osEepromLongWriteVC(OSMesgQueue *mq, u8 address, u8 *buffer, int length);