diff options
Diffstat (limited to 'src/srtc.cpp')
-rw-r--r-- | src/srtc.cpp | 528 |
1 files changed, 0 insertions, 528 deletions
diff --git a/src/srtc.cpp b/src/srtc.cpp deleted file mode 100644 index be390f0..0000000 --- a/src/srtc.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. - * - * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and - * Jerremy Koot (jkoot@snes9x.com) - * - * Super FX C emulator code - * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and - * Gary Henderson. - * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. - * - * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. - * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. - * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). - * - * DOS port code contains the works of other authors. See headers in - * individual files. - * - * Snes9x homepage: http://www.snes9x.com - * - * Permission to use, copy, modify and distribute Snes9x in both binary and - * source form, for non-commercial purposes, is hereby granted without fee, - * providing that this license information and copyright notice appear with - * all copies and any derived work. - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event shall the authors be held liable for any damages - * arising from the use of this software. - * - * Snes9x is freeware for PERSONAL USE only. Commercial users should - * seek permission of the copyright holders first. Commercial use includes - * charging money for Snes9x or software derived from Snes9x. - * - * The copyright holders request that bug fixes and improvements to the code - * should be forwarded to them so everyone can benefit from the modifications - * in future versions. - * - * Super NES and Super Nintendo Entertainment System are trademarks of - * Nintendo Co., Limited and its subsidiary companies. - */ -#include <string.h> -#include "snes9x.h" -#include "srtc.h" -#include "memmap.h" - -/*** The format of the rtc_data structure is: - -Index Description Range (nibble) ------ -------------- --------------------------------------- - - 0 Seconds low 0-9 - 1 Seconds high 0-5 - - 2 Minutes low 0-9 - 3 Minutes high 0-5 - - 4 Hour low 0-9 - 5 Hour high 0-2 - - 6 Day low 0-9 - 7 Day high 0-3 - - 8 Month 1-C (0xC is December, 12th month) - - 9 Year ones 0-9 - A Year tens 0-9 - B Year High 9-B (9=19xx, A=20xx, B=21xx) - - C Day of week 0-6 (0=Sunday, 1=Monday,...,6=Saturday) - -***/ - -SRTC_DATA rtc; - - -static int month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 }; - - -/********************************************************************************************* - * - * Note, if you are doing a save state for this game: - * - * On save: - * - * Call S9xUpdateSrtcTime and save the rtc data structure. - * - * On load: - * - * restore the rtc data structure - * rtc.system_timestamp = time (NULL); - * - * - *********************************************************************************************/ - - -void S9xResetSRTC () -{ - rtc.index = -1; - rtc.mode = MODE_READ; -} - -void S9xHardResetSRTC () -{ - ZeroMemory (&rtc, sizeof (rtc)); - rtc.index = -1; - rtc.mode = MODE_READ; - rtc.count_enable = FALSE; - rtc.needs_init = TRUE; - - // Get system timestamp - rtc.system_timestamp = time (NULL); -} - -/**********************************************************************************************/ -/* S9xSRTCComputeDayOfWeek() */ -/* Return 0-6 for Sunday-Saturday */ -/**********************************************************************************************/ -unsigned int S9xSRTCComputeDayOfWeek () -{ - unsigned year = rtc.data[10]*10 + rtc.data[9]; - unsigned month = rtc.data[8]; - unsigned day = rtc.data[7]*10 + rtc.data[6]; - unsigned day_of_week; - - year += (rtc.data[11] - 9) * 100; - - // Range check the month for valid array indicies - if ( month > 12 ) - month = 1; - - day_of_week = year + (year / 4) + month_keys[month-1] + day - 1; - - if(( year % 4 == 0 ) && ( month <= 2 ) ) - day_of_week--; - - day_of_week %= 7; - - return day_of_week; -} - - -/**********************************************************************************************/ -/* S9xSRTCDaysInMonth() */ -/* Return the number of days in a specific month for a certain year */ -/**********************************************************************************************/ -int S9xSRTCDaysInMmonth( int month, int year ) -{ - int mdays; - - switch ( month ) - { - case 2: - if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx - mdays = 29; - else - mdays = 28; - break; - - case 4: - case 6: - case 9: - case 11: - mdays = 30; - break; - - default: // months 1,3,5,7,8,10,12 - mdays = 31; - break; - } - - return mdays; -} - - -#define DAYTICKS (60*60*24) -#define HOURTICKS (60*60) -#define MINUTETICKS 60 - - -/**********************************************************************************************/ -/* S9xUpdateSrtcTime() */ -/* Advance the S-RTC time if counting is enabled */ -/**********************************************************************************************/ -void S9xUpdateSrtcTime () -{ - time_t cur_systime; - long time_diff; - - // Keep track of game time by computing the number of seconds that pass on the system - // clock and adding the same number of seconds to the S-RTC clock structure. - // I originally tried using mktime and localtime library functions to keep track - // of time but some of the GNU time functions fail when the year goes to 2099 - // (and maybe less) and this would have caused a bug with DKJM2 so I'm doing - // it this way to get around that problem. - - // Note: Dai Kaijyu Monogatari II only allows dates in the range 1996-21xx. - - if (rtc.count_enable && !rtc.needs_init) - { - cur_systime = time (NULL); - - // This method assumes one time_t clock tick is one second - // which should work on PCs and GNU systems. - // If your tick interval is different adjust the - // DAYTICK, HOURTICK, and MINUTETICK defines - - time_diff = (long) (cur_systime - rtc.system_timestamp); - rtc.system_timestamp = cur_systime; - - if ( time_diff > 0 ) - { - int seconds; - int minutes; - int hours; - int days; - int month; - int year; - int temp_days; - - int year_hundreds; - int year_tens; - int year_ones; - - - if ( time_diff > DAYTICKS ) - { - days = time_diff / DAYTICKS; - time_diff = time_diff - days * DAYTICKS; - } - else - { - days = 0; - } - - if ( time_diff > HOURTICKS ) - { - hours = time_diff / HOURTICKS; - time_diff = time_diff - hours * HOURTICKS; - } - else - { - hours = 0; - } - - if ( time_diff > MINUTETICKS ) - { - minutes = time_diff / MINUTETICKS; - time_diff = time_diff - minutes * MINUTETICKS; - } - else - { - minutes = 0; - } - - if ( time_diff > 0 ) - { - seconds = time_diff; - } - else - { - seconds = 0; - } - - - seconds += (rtc.data[1]*10 + rtc.data[0]); - if ( seconds >= 60 ) - { - seconds -= 60; - minutes += 1; - } - - minutes += (rtc.data[3]*10 + rtc.data[2]); - if ( minutes >= 60 ) - { - minutes -= 60; - hours += 1; - } - - hours += (rtc.data[5]*10 + rtc.data[4]); - if ( hours >= 24 ) - { - hours -= 24; - days += 1; - } - - if ( days > 0 ) - { - year = rtc.data[10]*10 + rtc.data[9]; - year += ( 1000 + rtc.data[11] * 100 ); - - month = rtc.data[8]; - days += (rtc.data[7]*10 + rtc.data[6]); - while ( days > (temp_days = S9xSRTCDaysInMmonth( month, year )) ) - { - days -= temp_days; - month += 1; - if ( month > 12 ) - { - year += 1; - month = 1; - } - } - - year_tens = year % 100; - year_ones = year_tens % 10; - year_tens /= 10; - year_hundreds = (year - 1000) / 100; - - rtc.data[6] = days % 10; - rtc.data[7] = days / 10; - rtc.data[8] = month; - rtc.data[9] = year_ones; - rtc.data[10] = year_tens; - rtc.data[11] = year_hundreds; - rtc.data[12] = S9xSRTCComputeDayOfWeek (); - } - - rtc.data[0] = seconds % 10; - rtc.data[1] = seconds / 10; - rtc.data[2] = minutes % 10; - rtc.data[3] = minutes / 10; - rtc.data[4] = hours % 10; - rtc.data[5] = hours / 10; - - return; - } - } -} - - -/**********************************************************************************************/ -/* S9xSetSRTC() */ -/* This function sends data to the S-RTC used in Dai Kaijyu Monogatari II */ -/**********************************************************************************************/ -void S9xSetSRTC (uint8 data, uint16 Address) -{ - - data &= 0x0F; // Data is only 4-bits, mask out unused bits. - - if( data >= 0xD ) - { - // It's an RTC command - - switch ( data ) - { - case 0xD: - rtc.mode = MODE_READ; - rtc.index = -1; - break; - - case 0xE: - rtc.mode = MODE_COMMAND; - break; - - default: - // Ignore the write if it's an 0xF ??? - // Probably should switch back to read mode -- but this - // sequence never occurs in DKJM2 - break; - } - - return; - } - - if ( rtc.mode == MODE_LOAD_RTC ) - { - if ( (rtc.index >= 0) || (rtc.index < MAX_RTC_INDEX) ) - { - rtc.data[rtc.index++] = data; - - if ( rtc.index == MAX_RTC_INDEX ) - { - // We have all the data for the RTC load - - rtc.system_timestamp = time (NULL); // Get local system time - - // Get the day of the week - rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek (); - - // Start RTC counting again - rtc.count_enable = TRUE; - rtc.needs_init = FALSE; - } - - return; - } - else - { - // Attempting to write too much data - // error(); // ignore?? - } - } - else if ( rtc.mode == MODE_COMMAND ) - { - switch( data ) - { - case COMMAND_CLEAR_RTC: - // Disable RTC counter - rtc.count_enable = FALSE; - - ZeroMemory (rtc.data, MAX_RTC_INDEX+1); - rtc.index = -1; - rtc.mode = MODE_COMMAND_DONE; - break; - - case COMMAND_LOAD_RTC: - // Disable RTC counter - rtc.count_enable = FALSE; - - rtc.index = 0; // Setup for writing - rtc.mode = MODE_LOAD_RTC; - break; - - default: - rtc.mode = MODE_COMMAND_DONE; - // unrecognized command - need to implement. - } - - return; - } - else - { - if ( rtc.mode == MODE_READ ) - { - // Attempting to write while in read mode. Ignore. - } - - if ( rtc.mode == MODE_COMMAND_DONE ) - { - // Maybe this isn't an error. Maybe we should kick off - // a new E command. But is this valid? - } - } -} - -/**********************************************************************************************/ -/* S9xGetSRTC() */ -/* This function retrieves data from the S-RTC */ -/**********************************************************************************************/ -uint8 S9xGetSRTC (uint16 Address) -{ - if ( rtc.mode == MODE_READ ) - { - if ( rtc.index < 0 ) - { - S9xUpdateSrtcTime (); // Only update it if the game reads it - rtc.index++; - return ( 0x0f ); // Send start marker. - } - else if (rtc.index > MAX_RTC_INDEX) - { - rtc.index = -1; // Setup for next set of reads - return ( 0x0f ); // Data done marker. - } - else - { - // Feed out the data - return rtc.data[rtc.index++]; - } - } - else - { - return 0x0; - } -} - -void S9xSRTCPreSaveState () -{ - if (Settings.SRTC) - { - S9xUpdateSrtcTime (); - - int s = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - if (s > 0x20000) - s = 0x20000; - - SRAM [s + 0] = rtc.needs_init; - SRAM [s + 1] = rtc.count_enable; - memmove (&SRAM [s + 2], rtc.data, MAX_RTC_INDEX + 1); - SRAM [s + 3 + MAX_RTC_INDEX] = rtc.index; - SRAM [s + 4 + MAX_RTC_INDEX] = rtc.mode; - -#ifdef LSB_FIRST - memmove (&SRAM [s + 5 + MAX_RTC_INDEX], &rtc.system_timestamp, 8); -#else - SRAM [s + 5 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 0); - SRAM [s + 6 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 8); - SRAM [s + 7 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 16); - SRAM [s + 8 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 24); - SRAM [s + 9 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 32); - SRAM [s + 10 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 40); - SRAM [s + 11 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 48); - SRAM [s + 12 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 56); -#endif - } -} - -void S9xSRTCPostLoadState () -{ - if (Settings.SRTC) - { - int s = Memory.SRAMSize ? - (1 << (Memory.SRAMSize + 3)) * 128 : 0; - if (s > 0x20000) - s = 0x20000; - - rtc.needs_init = SRAM [s + 0]; - rtc.count_enable = SRAM [s + 1]; - memmove (rtc.data, &SRAM [s + 2], MAX_RTC_INDEX + 1); - rtc.index = SRAM [s + 3 + MAX_RTC_INDEX]; - rtc.mode = SRAM [s + 4 + MAX_RTC_INDEX]; - -#ifdef LSB_FIRST - memmove (&rtc.system_timestamp, &SRAM [s + 5 + MAX_RTC_INDEX], 8); -#else - rtc.system_timestamp |= (SRAM [s + 5 + MAX_RTC_INDEX] << 0); - rtc.system_timestamp |= (SRAM [s + 6 + MAX_RTC_INDEX] << 8); - rtc.system_timestamp |= (SRAM [s + 7 + MAX_RTC_INDEX] << 16); - rtc.system_timestamp |= (SRAM [s + 8 + MAX_RTC_INDEX] << 24); - rtc.system_timestamp |= (SRAM [s + 9 + MAX_RTC_INDEX] << 32); - rtc.system_timestamp |= (SRAM [s + 10 + MAX_RTC_INDEX] << 40); - rtc.system_timestamp |= (SRAM [s + 11 + MAX_RTC_INDEX] << 48); - rtc.system_timestamp |= (SRAM [s + 12 + MAX_RTC_INDEX] << 56); -#endif - S9xUpdateSrtcTime (); - } -} |