HuC3: Enable battery save, update RTC support
- SRAM support is already available, but the battery-enabled flag was not enable for 0xFE (HuC3) rom types. - Hookup rtc support based on local time. This would allow time to sync when starting the game. You need to initially set the time first though on first bootup (RTC support was based on gambatte sources) Fix https://github.com/libretro/vbam-libretro/issues/95
This commit is contained in:
parent
685a495d5c
commit
05a046e7ed
|
@ -4376,6 +4376,7 @@ bool gbUpdateSizes()
|
|||
case 0x1e:
|
||||
case 0x22:
|
||||
case 0xfd:
|
||||
case 0xfe:
|
||||
case 0xff:
|
||||
gbBattery = 1;
|
||||
break;
|
||||
|
@ -4399,6 +4400,7 @@ bool gbUpdateSizes()
|
|||
case 0x0f:
|
||||
case 0x10: // mbc3
|
||||
case 0xfd: // tama5
|
||||
case 0xfe:
|
||||
gbRTCPresent = 1;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1000,14 +1000,33 @@ mapperHuC3 gbDataHuC3 = {
|
|||
0, // RAM read value
|
||||
0, // Register 1
|
||||
0, // Register 2
|
||||
0, // Register 3
|
||||
0, // Register 4
|
||||
0, // Register 5
|
||||
0, // Register 6
|
||||
0, // Register 7
|
||||
0 // Register 8
|
||||
0, // DateTime
|
||||
0, // WritingTime
|
||||
0, // ModeFlag
|
||||
0, // ClockShift
|
||||
0 // lastTime
|
||||
};
|
||||
|
||||
void memoryupdateHuC3Latch() {
|
||||
uint64_t now = time(NULL);
|
||||
uint64_t diff = now - gbDataHuC3.mapperLastTime;
|
||||
|
||||
if (diff > 0) {
|
||||
unsigned minute = (diff / 60) % 1440;
|
||||
unsigned day = (diff / 86400) & 0xFFF;
|
||||
|
||||
gbDataHuC3.mapperDateTime = (day << 12) | minute;
|
||||
}
|
||||
}
|
||||
|
||||
void memoryupdateHuC3Clock() {
|
||||
uint64_t now = time(NULL);
|
||||
unsigned minute = (gbDataHuC3.mapperWritingTime & 0xFFF) % 1440;
|
||||
unsigned day = (gbDataHuC3.mapperWritingTime & 0xFFF000) >> 12;
|
||||
|
||||
gbDataHuC3.mapperLastTime = now - minute * 60 - day * 86400;
|
||||
}
|
||||
|
||||
// HuC3 ROM write registers
|
||||
void mapperHuC3ROM(uint16_t address, uint8_t value)
|
||||
{
|
||||
|
@ -1066,7 +1085,7 @@ uint8_t mapperHuC3ReadRAM(uint16_t address)
|
|||
// HuC3 RAM write
|
||||
void mapperHuC3RAM(uint16_t address, uint8_t value)
|
||||
{
|
||||
int* p;
|
||||
//int* p;
|
||||
|
||||
if (gbDataHuC3.mapperRAMFlag < 0x0b || gbDataHuC3.mapperRAMFlag > 0x0e) {
|
||||
if (gbDataHuC3.mapperRAMEnable) {
|
||||
|
@ -1082,20 +1101,43 @@ void mapperHuC3RAM(uint16_t address, uint8_t value)
|
|||
} else {
|
||||
switch (value & 0xf0) {
|
||||
case 0x10:
|
||||
p = &gbDataHuC3.mapperRegister2;
|
||||
/*p = &gbDataHuC3.mapperRegister2;
|
||||
gbDataHuC3.mapperRAMValue = *(p + gbDataHuC3.mapperRegister1++);
|
||||
if (gbDataHuC3.mapperRegister1 > 6)
|
||||
gbDataHuC3.mapperRegister1 = 0;
|
||||
gbDataHuC3.mapperRegister1 = 0;*/
|
||||
|
||||
// read time
|
||||
memoryupdateHuC3Latch();
|
||||
if (gbDataHuC3.mapperModeFlag == HUC3_READ) {
|
||||
gbDataHuC3.mapperRAMValue = (gbDataHuC3.mapperDateTime >> gbDataHuC3.mapperClockShift) & 0x0F;
|
||||
gbDataHuC3.mapperClockShift += 4;
|
||||
if (gbDataHuC3.mapperClockShift > 24)
|
||||
gbDataHuC3.mapperClockShift = 0;
|
||||
}
|
||||
break;
|
||||
case 0x30:
|
||||
p = &gbDataHuC3.mapperRegister2;
|
||||
/*p = &gbDataHuC3.mapperRegister2;
|
||||
*(p + gbDataHuC3.mapperRegister1++) = value & 0x0f;
|
||||
if (gbDataHuC3.mapperRegister1 > 6)
|
||||
gbDataHuC3.mapperRegister1 = 0;
|
||||
gbDataHuC3.mapperAddress = (gbDataHuC3.mapperRegister6 << 24) | (gbDataHuC3.mapperRegister5 << 16) | (gbDataHuC3.mapperRegister4 << 8) | (gbDataHuC3.mapperRegister3 << 4) | (gbDataHuC3.mapperRegister2);
|
||||
gbDataHuC3.mapperAddress = (gbDataHuC3.mapperRegister6 << 24) | (gbDataHuC3.mapperRegister5 << 16) | (gbDataHuC3.mapperRegister4 << 8) | (gbDataHuC3.mapperRegister3 << 4) | (gbDataHuC3.mapperRegister2);*/
|
||||
|
||||
// write time
|
||||
if (gbDataHuC3.mapperModeFlag == HUC3_WRITE) {
|
||||
if (gbDataHuC3.mapperClockShift == 0)
|
||||
gbDataHuC3.mapperWritingTime = 0;
|
||||
if (gbDataHuC3.mapperClockShift <= 24) {
|
||||
gbDataHuC3.mapperWritingTime |= (value & 0x0F) << gbDataHuC3.mapperClockShift;
|
||||
gbDataHuC3.mapperClockShift += 4;
|
||||
if (gbDataHuC3.mapperClockShift == 24) {
|
||||
memoryupdateHuC3Clock();
|
||||
gbDataHuC3.mapperModeFlag = HUC3_READ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x40:
|
||||
gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0xf0) | (value & 0x0f);
|
||||
/*gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0xf0) | (value & 0x0f);
|
||||
gbDataHuC3.mapperRegister2 = (gbDataHuC3.mapperAddress & 0x0f);
|
||||
gbDataHuC3.mapperRegister3 = ((gbDataHuC3.mapperAddress >> 4) & 0x0f);
|
||||
gbDataHuC3.mapperRegister4 = ((gbDataHuC3.mapperAddress >> 8) & 0x0f);
|
||||
|
@ -1103,13 +1145,35 @@ void mapperHuC3RAM(uint16_t address, uint8_t value)
|
|||
gbDataHuC3.mapperRegister6 = ((gbDataHuC3.mapperAddress >> 24) & 0x0f);
|
||||
gbDataHuC3.mapperRegister7 = 0;
|
||||
gbDataHuC3.mapperRegister8 = 0;
|
||||
gbDataHuC3.mapperRAMValue = 0;
|
||||
gbDataHuC3.mapperRAMValue = 0;*/
|
||||
|
||||
// some kind of mode shift
|
||||
switch(value & 0x0F) {
|
||||
case 0x0:
|
||||
// shift reset?
|
||||
gbDataHuC3.mapperClockShift = 0;
|
||||
break;
|
||||
case 0x3:
|
||||
// write time?
|
||||
gbDataHuC3.mapperModeFlag = HUC3_WRITE;
|
||||
gbDataHuC3.mapperClockShift = 0;
|
||||
break;
|
||||
case 0x7:
|
||||
gbDataHuC3.mapperModeFlag = HUC3_READ;
|
||||
gbDataHuC3.mapperClockShift = 0;
|
||||
break;
|
||||
// others are unimplemented so far
|
||||
}
|
||||
break;
|
||||
case 0x50:
|
||||
gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0x0f) | ((value << 4) & 0x0f);
|
||||
//gbDataHuC3.mapperRegister1 = (gbDataHuC3.mapperRegister1 & 0x0f) | ((value << 4) & 0x0f);
|
||||
break;
|
||||
case 0x60:
|
||||
gbDataHuC3.mapperModeFlag = HUC3_READ; // ???
|
||||
gbDataHuC3.mapperRAMValue = 1;
|
||||
break;
|
||||
default:
|
||||
gbDataHuC3.mapperRAMValue = 1;
|
||||
//gbDataHuC3.mapperRAMValue = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,6 +77,12 @@ struct mapperHuC1 {
|
|||
int mapperRAMAddress;
|
||||
};
|
||||
|
||||
enum {
|
||||
HUC3_READ = 0,
|
||||
HUC3_WRITE = 1,
|
||||
HUC3_NONE = 2
|
||||
};
|
||||
|
||||
struct mapperHuC3 {
|
||||
int mapperRAMEnable;
|
||||
int mapperROMBank;
|
||||
|
@ -87,12 +93,14 @@ struct mapperHuC3 {
|
|||
int mapperRAMValue;
|
||||
int mapperRegister1;
|
||||
int mapperRegister2;
|
||||
int mapperRegister3;
|
||||
int mapperRegister4;
|
||||
int mapperRegister5;
|
||||
int mapperRegister6;
|
||||
int mapperRegister7;
|
||||
int mapperRegister8;
|
||||
int mapperDateTime;
|
||||
int mapperWritingTime;
|
||||
int mapperModeFlag;
|
||||
int mapperClockShift;
|
||||
union {
|
||||
time_t mapperLastTime;
|
||||
uint64_t _time_pad; /* so that 32bit and 64bit saves are compatible */
|
||||
};
|
||||
};
|
||||
|
||||
struct mapperTAMA5 {
|
||||
|
@ -196,4 +204,6 @@ extern void memoryUpdateMapGS3();
|
|||
|
||||
#define TAMA5_RTC_DATA_SIZE sizeof(int) * 14 + sizeof(uint64_t)
|
||||
|
||||
#define HUC3_RTC_DATA_SIZE sizeof(int) * 4 + sizeof(uint64_t)
|
||||
|
||||
#endif // GBMEMORY_H
|
||||
|
|
|
@ -161,6 +161,9 @@ static void set_gbPalette(void)
|
|||
}
|
||||
}
|
||||
|
||||
extern void memoryupdateHuC3Clock();
|
||||
extern void memoryupdateHuC3Latch();
|
||||
|
||||
static void* gb_rtcdata_prt(void)
|
||||
{
|
||||
switch (gbRomType) {
|
||||
|
@ -169,6 +172,8 @@ static void* gb_rtcdata_prt(void)
|
|||
return &gbDataMBC3.mapperSeconds;
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return &gbDataTAMA5.mapperSeconds;
|
||||
case 0xfe: // HuC3 + Clock
|
||||
return &gbDataHuC3.mapperDateTime;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -181,6 +186,8 @@ static size_t gb_rtcdata_size(void)
|
|||
return MBC3_RTC_DATA_SIZE;
|
||||
case 0xfd: // TAMA5 + extended
|
||||
return TAMA5_RTC_DATA_SIZE;
|
||||
case 0xfe: // HuC3 + Clock
|
||||
return HUC3_RTC_DATA_SIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -231,6 +238,10 @@ static void gbInitRTC(void)
|
|||
gbDataTAMA5.mapperControl = (gbDataTAMA5.mapperControl & 0xfe) | (lt->tm_yday > 255 ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
case 0xfe:
|
||||
//memoryupdateHuC3Clock();
|
||||
memoryupdateHuC3Latch();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,7 +309,7 @@ void* retro_get_memory_data(unsigned id)
|
|||
data = (gbCgbMode ? gbVram : (gbMemory + 0x8000));
|
||||
break;
|
||||
case RETRO_MEMORY_RTC:
|
||||
if (gbBattery && gbRTCPresent)
|
||||
//if (gbBattery/* && gbRTCPresent*/)
|
||||
data = gb_rtcdata_prt();
|
||||
break;
|
||||
}
|
||||
|
@ -1425,6 +1436,10 @@ void retro_run(void)
|
|||
if (!gbDataTAMA5.mapperLastTime)
|
||||
initRTC = true;
|
||||
break;
|
||||
case 0xfe:
|
||||
if (!gbDataHuC3.mapperLastTime)
|
||||
initRTC = true;
|
||||
break;
|
||||
}
|
||||
/* Initialize RTC using local time if needed */
|
||||
if (initRTC)
|
||||
|
|
Loading…
Reference in New Issue