From 2ec24487c3810072c037b7a499879b1df255fee5 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 24 May 2015 13:30:31 +0000 Subject: [PATCH] Fixed the "Solar Sensor is broken" message that appeared in "Boktai - The Sun Is in Your Hand". Cleaned and formatted the code. Fixed a mistake where the RTC was not getting updated. --- src/gba/RTC.cpp | 486 +++++++++++++++++++++++++++--------------------- src/wx/sys.cpp | 20 -- 2 files changed, 277 insertions(+), 229 deletions(-) diff --git a/src/gba/RTC.cpp b/src/gba/RTC.cpp index e641c4ac..5acbce5f 100644 --- a/src/gba/RTC.cpp +++ b/src/gba/RTC.cpp @@ -11,25 +11,26 @@ enum RTCSTATE { - IDLE = 0, - COMMAND, - DATA, - READDATA + IDLE = 0, + COMMAND, + DATA, + READDATA }; -typedef struct { - u8 byte0; - u8 byte1; - u8 byte2; - u8 command; - int dataLen; - int bits; - RTCSTATE state; - u8 data[12]; - // reserved variables for future - u8 reserved[12]; - bool reserved2; - u32 reserved3; +typedef struct +{ + u8 byte0; + u8 select; + u8 enable; + u8 command; + int dataLen; + int bits; + RTCSTATE state; + u8 data[12]; + // reserved variables for future + u8 reserved[12]; + bool reserved2; + u32 reserved3; } RTCCLOCKDATA; struct tm gba_time; @@ -41,12 +42,12 @@ u32 countTicks = 0; void rtcEnable(bool e) { - rtcClockEnabled = e; + rtcClockEnabled = e; } bool rtcIsEnabled() { - return rtcClockEnabled; + return rtcClockEnabled; } void rtcEnableRumble(bool e) @@ -56,248 +57,315 @@ void rtcEnableRumble(bool e) u16 rtcRead(u32 address) { - switch(address){ - case 0x80000c8: - return rtcClockData.byte2; - break; - case 0x80000c6: - return rtcClockData.byte1; - break; - case 0x80000c4: + int res = 0; + + switch (address) + { + case 0x80000c8: + return rtcClockData.enable; + break; + + case 0x80000c6: + return rtcClockData.select; + break; + + case 0x80000c4: + if (!(rtcClockData.enable & 1)) + { + return 0; + } + // Boktai Solar Sensor - if (rtcClockData.byte1 == 7) { - if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) { - rtcClockData.reserved[10] = 0; - rtcClockData.reserved[11] = 0; - return 8; - } - else { - return 0; + if (rtcClockData.select == 0x07) + { + if (rtcClockData.reserved[11] >= systemGetSensorDarkness()) + { + res |= 8; } } + // WarioWare Twisted Tilt Sensor - else if (rtcClockData.byte1 == 0x0b) { - //sprintf(DebugStr, "Reading Twisted Sensor bit %d", rtcClockData.reserved[11]); + if (rtcClockData.select == 0x0b) + { u16 v = systemGetSensorZ(); v = 0x6C0 + v; - return ((v >> rtcClockData.reserved[11]) & 1) << 2; + res |= ((v >> rtcClockData.reserved[11]) & 1) << 2; } - // Real Time Clock - else if (rtcClockEnabled) { - //sprintf(DebugStr, "Reading RTC %02x, %02x, %02x", rtcClockData.byte0, rtcClockData.byte1, rtcClockData.byte2); - return rtcClockData.byte0; - } - break; - } - return READ16LE((&rom[address & 0x1FFFFFE])); + // Real Time Clock + if (rtcClockEnabled && (rtcClockData.select & 0x04)) + { + res |= rtcClockData.byte0; + } + + return res; + break; + } + + return READ16LE((&rom[address & 0x1FFFFFE])); } static u8 toBCD(u8 value) { - value = value % 100; - int l = value % 10; - int h = value / 10; - return h * 16 + l; + value = value % 100; + int l = value % 10; + int h = value / 10; + return h * 16 + l; } void SetGBATime() { time_t long_time; - time(&long_time); /* Get time as long integer. */ gba_time = *localtime(&long_time); /* Convert to local time. */ - countTicks = 0; } void rtcUpdateTime(int ticks) { countTicks += ticks; + if (countTicks > TICKS_PER_SECOND) { countTicks -= TICKS_PER_SECOND; gba_time.tm_sec++; + mktime(&gba_time); } } bool rtcWrite(u32 address, u16 value) { - if(address == 0x80000c8) { - rtcClockData.byte2 = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8 - } - else if (address == 0x80000c6) { - rtcClockData.byte1 = (u8)value; // 0=read/1=write (for each of 4 low bits) - // rumble is off when not writing to that pin - if (rtcRumbleEnabled && !(value & 8)) systemCartridgeRumble(false); - } - else if (address == 0x80000c4) { // 4 bits of I/O Port Data (upper bits not used) - // WarioWare Twisted rumble - if (rtcRumbleEnabled && (rtcClockData.byte1 & 8)) { - systemCartridgeRumble(value & 8); - } - // Boktai solar sensor - if (rtcClockData.byte1 == 7) { - if (value & 2) { - // reset counter to 0 - rtcClockData.reserved[11] = 0; - rtcClockData.reserved[10] = 0; - } - if ((value & 1) && (!(rtcClockData.reserved[10] & 1))) { - // increase counter, ready to do another read - if (rtcClockData.reserved[11]<255) rtcClockData.reserved[11]++; - } - rtcClockData.reserved[10] = value & rtcClockData.byte1; - } - // WarioWare Twisted rotation sensor - if (rtcClockData.byte1 == 0xb) { - if (value & 2) { - // clock goes high in preperation for reading a bit - rtcClockData.reserved[11]--; - } - if (value & 1) { - // start ADC conversion - rtcClockData.reserved[11] = 15; - } - rtcClockData.byte0 = value & rtcClockData.byte1; - // Real Time Clock - } - /**/ + if (address == 0x80000c8) + { + rtcClockData.enable = (u8)value; // bit 0 = enable reading from 0x80000c4 c6 and c8 + } + else if (address == 0x80000c6) + { + rtcClockData.select = (u8)value; // 0=read/1=write (for each of 4 low bits) - if(rtcClockData.byte2 & 1) { - if(rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) { - rtcClockData.state = COMMAND; - rtcClockData.bits = 0; - rtcClockData.command = 0; - } else if(!(rtcClockData.byte0 & 1) && (value & 1)) { // bit transfer - rtcClockData.byte0 = (u8)value; - switch(rtcClockData.state) { - case COMMAND: - rtcClockData.command |= ((value & 2) >> 1) << (7-rtcClockData.bits); - rtcClockData.bits++; - if(rtcClockData.bits == 8) { - rtcClockData.bits = 0; - switch(rtcClockData.command) { - case 0x60: - // not sure what this command does but it doesn't take parameters - // maybe it is a reset or stop - rtcClockData.state = IDLE; - rtcClockData.bits = 0; - break; - case 0x62: - // this sets the control state but not sure what those values are - rtcClockData.state = READDATA; - rtcClockData.dataLen = 1; - break; - case 0x63: - rtcClockData.dataLen = 1; - rtcClockData.data[0] = 0x40; - rtcClockData.state = DATA; - break; - case 0x64: - break; - case 0x65: - { - if (rtcEnabled) - SetGBATime(); - rtcClockData.dataLen = 7; - rtcClockData.data[0] = toBCD(gba_time.tm_year); - rtcClockData.data[1] = toBCD(gba_time.tm_mon+1); - rtcClockData.data[2] = toBCD(gba_time.tm_mday); - rtcClockData.data[3] = toBCD(gba_time.tm_wday); - rtcClockData.data[4] = toBCD(gba_time.tm_hour); - rtcClockData.data[5] = toBCD(gba_time.tm_min); - rtcClockData.data[6] = toBCD(gba_time.tm_sec); - rtcClockData.state = DATA; - } - break; - case 0x67: - { - if (rtcEnabled) - SetGBATime(); - rtcClockData.dataLen = 3; - rtcClockData.data[0] = toBCD(gba_time.tm_hour); - rtcClockData.data[1] = toBCD(gba_time.tm_min); - rtcClockData.data[2] = toBCD(gba_time.tm_sec); - rtcClockData.state = DATA; - } - break; - default: - systemMessage(0, N_("Unknown RTC command %02x"), rtcClockData.command); - rtcClockData.state = IDLE; - break; - } - } - break; - case DATA: - if(rtcClockData.byte1 & 2) { - } else { - rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | - ((rtcClockData.data[rtcClockData.bits >> 3] >> - (rtcClockData.bits & 7)) & 1)*2; - rtcClockData.bits++; - if(rtcClockData.bits == 8*rtcClockData.dataLen) { - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - } - } - break; - case READDATA: - if(!(rtcClockData.byte1 & 2)) { - } else { - rtcClockData.data[rtcClockData.bits >> 3] = - (rtcClockData.data[rtcClockData.bits >> 3] >> 1) | - ((value << 6) & 128); - rtcClockData.bits++; - if(rtcClockData.bits == 8*rtcClockData.dataLen) { - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - } - } - break; - default: - break; - } - } else - rtcClockData.byte0 = (u8)value; - } - } - return true; + // rumble is off when not writing to that pin + if (rtcRumbleEnabled && !(value & 8)) systemCartridgeRumble(false); + } + else if (address == 0x80000c4) // 4 bits of I/O Port Data (upper bits not used) + { + // WarioWare Twisted rumble + if (rtcRumbleEnabled && (rtcClockData.select & 0x08)) + { + systemCartridgeRumble(value & 8); + } + + // Boktai solar sensor + if (rtcClockData.select == 0x07) + { + if (value & 2) + { + // reset counter to 0 + rtcClockData.reserved[11] = 0; + } + + if ((value & 1) && !(rtcClockData.reserved[10] & 1)) + { + // increase counter, ready to do another read + if (rtcClockData.reserved[11] < 255) + { + rtcClockData.reserved[11]++; + } + else + { + rtcClockData.reserved[11] = 0; + } + } + + rtcClockData.reserved[10] = value & rtcClockData.select; + } + + // WarioWare Twisted rotation sensor + if (rtcClockData.select == 0x0b) + { + if (value & 2) + { + // clock goes high in preperation for reading a bit + rtcClockData.reserved[11]--; + } + + if (value & 1) + { + // start ADC conversion + rtcClockData.reserved[11] = 15; + } + + rtcClockData.byte0 = value & rtcClockData.select; + } + + // Real Time Clock + if (rtcClockData.select & 4) + { + if (rtcClockData.state == IDLE && rtcClockData.byte0 == 1 && value == 5) + { + rtcClockData.state = COMMAND; + rtcClockData.bits = 0; + rtcClockData.command = 0; + } + else if (!(rtcClockData.byte0 & 1) && (value & 1)) // bit transfer + { + rtcClockData.byte0 = (u8)value; + + switch (rtcClockData.state) + { + case COMMAND: + rtcClockData.command |= ((value & 2) >> 1) << (7 - rtcClockData.bits); + rtcClockData.bits++; + + if (rtcClockData.bits == 8) + { + rtcClockData.bits = 0; + + switch (rtcClockData.command) + { + case 0x60: + // not sure what this command does but it doesn't take parameters + // maybe it is a reset or stop + rtcClockData.state = IDLE; + rtcClockData.bits = 0; + break; + + case 0x62: + // this sets the control state but not sure what those values are + rtcClockData.state = READDATA; + rtcClockData.dataLen = 1; + break; + + case 0x63: + rtcClockData.dataLen = 1; + rtcClockData.data[0] = 0x40; + rtcClockData.state = DATA; + break; + + case 0x64: + break; + + case 0x65: + { + if (rtcEnabled) + SetGBATime(); + + rtcClockData.dataLen = 7; + rtcClockData.data[0] = toBCD(gba_time.tm_year); + rtcClockData.data[1] = toBCD(gba_time.tm_mon + 1); + rtcClockData.data[2] = toBCD(gba_time.tm_mday); + rtcClockData.data[3] = toBCD(gba_time.tm_wday); + rtcClockData.data[4] = toBCD(gba_time.tm_hour); + rtcClockData.data[5] = toBCD(gba_time.tm_min); + rtcClockData.data[6] = toBCD(gba_time.tm_sec); + rtcClockData.state = DATA; + } + break; + + case 0x67: + { + if (rtcEnabled) + SetGBATime(); + + rtcClockData.dataLen = 3; + rtcClockData.data[0] = toBCD(gba_time.tm_hour); + rtcClockData.data[1] = toBCD(gba_time.tm_min); + rtcClockData.data[2] = toBCD(gba_time.tm_sec); + rtcClockData.state = DATA; + } + break; + + default: + log(N_("Unknown RTC command %02x"), rtcClockData.command); + rtcClockData.state = IDLE; + break; + } + } + + break; + + case DATA: + if (rtcClockData.select & 2) + { + } + else if (rtcClockData.select & 4) + { + rtcClockData.byte0 = (rtcClockData.byte0 & ~2) | + ((rtcClockData.data[rtcClockData.bits >> 3] >> + (rtcClockData.bits & 7)) & 1) * 2; + rtcClockData.bits++; + + if (rtcClockData.bits == 8 * rtcClockData.dataLen) + { + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + } + } + + break; + + case READDATA: + if (!(rtcClockData.select & 2)) + { + } + else + { + rtcClockData.data[rtcClockData.bits >> 3] = + (rtcClockData.data[rtcClockData.bits >> 3] >> 1) | + ((value << 6) & 128); + rtcClockData.bits++; + + if (rtcClockData.bits == 8 * rtcClockData.dataLen) + { + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + } + } + + break; + + default: + break; + } + } + else + rtcClockData.byte0 = (u8)value; + } + } + + return true; } void rtcReset() { - memset(&rtcClockData, 0, sizeof(rtcClockData)); - - rtcClockData.byte0 = 0; - rtcClockData.byte1 = 0; - rtcClockData.byte2 = 0; - rtcClockData.command = 0; - rtcClockData.dataLen = 0; - rtcClockData.bits = 0; - rtcClockData.state = IDLE; - rtcClockData.reserved[11] = 0; - - SetGBATime(); + memset(&rtcClockData, 0, sizeof(rtcClockData)); + rtcClockData.byte0 = 0; + rtcClockData.select = 0; + rtcClockData.enable = 0; + rtcClockData.command = 0; + rtcClockData.dataLen = 0; + rtcClockData.bits = 0; + rtcClockData.state = IDLE; + rtcClockData.reserved[11] = 0; + SetGBATime(); } #ifdef __LIBRETRO__ -void rtcSaveGame(u8 *&data) +void rtcSaveGame(u8* &data) { - utilWriteMem(data, &rtcClockData, sizeof(rtcClockData)); + utilWriteMem(data, &rtcClockData, sizeof(rtcClockData)); } -void rtcReadGame(const u8 *&data) +void rtcReadGame(const u8* &data) { - utilReadMem(&rtcClockData, data, sizeof(rtcClockData)); + utilReadMem(&rtcClockData, data, sizeof(rtcClockData)); } #else void rtcSaveGame(gzFile gzFile) { - utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData)); + utilGzWrite(gzFile, &rtcClockData, sizeof(rtcClockData)); } void rtcReadGame(gzFile gzFile) { - utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData)); + utilGzRead(gzFile, &rtcClockData, sizeof(rtcClockData)); } #endif diff --git a/src/wx/sys.cpp b/src/wx/sys.cpp index bbe2bde1..163dc145 100644 --- a/src/wx/sys.cpp +++ b/src/wx/sys.cpp @@ -570,26 +570,6 @@ void systemUpdateSolarSensor() break; } - struct tm* newtime; - - time_t long_time; - // regardless of the weather, there should be no sun at night time! - time(&long_time); // Get time as long integer. - newtime = localtime(&long_time); // Convert to local time. - - if (newtime->tm_hour > 21 || newtime->tm_hour < 5) - { - sun = 0; // total darkness, 9pm - 5am - } - else if (newtime->tm_hour > 20 || newtime->tm_hour < 6) - { - sun /= 9; // almost total darkness 8pm-9pm, 5am-6am - } - else if (newtime->tm_hour > 18 || newtime->tm_hour < 7) - { - sun >>= 1; - } - sensorDarkness = 0xE8 - sun; }