summaryrefslogtreecommitdiff
path: root/src/srtc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/srtc.cpp')
-rw-r--r--src/srtc.cpp528
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 ();
- }
-}