Merge pull request #102 from negativeExponent/huc3

HuC3 Enable save support and update RTC
This commit is contained in:
Autechre 2021-05-25 05:30:51 +02:00 committed by GitHub
commit 5187d70e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 23 deletions

View File

@ -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:

View File

@ -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;
}
}

View File

@ -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

View File

@ -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 (gbRTCPresent)
data = gb_rtcdata_prt();
break;
}
@ -346,7 +357,8 @@ size_t retro_get_memory_size(unsigned id)
size = gbCgbMode ? 0x4000 : 0x2000;
break;
case RETRO_MEMORY_RTC:
size = gb_rtcdata_size();
if (gbRTCPresent)
size = gb_rtcdata_size();
break;
}
break;
@ -1425,6 +1437,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)