1 /* Cygne
2 *
3 * Copyright notice for this file:
4 * Copyright (C) 2002 Dox dox@space.pl
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "wswan.h"
22 #include <time.h>
23
24 static uint64 CurrentTime;
25 static uint32 ClockCycleCounter;
26 static uint8 wsCA15;
27 static uint8 Command, Data;
28
WSwan_RTCWrite(uint32 A,uint8 V)29 void WSwan_RTCWrite(uint32 A, uint8 V)
30 {
31 switch(A)
32 {
33 case 0xca:
34 if(V==0x15)
35 wsCA15=0;
36 Command = V;
37 break;
38 case 0xcb:
39 Data = V;
40 break;
41 }
42 }
43
WSwan_RTCRead(uint32 A)44 uint8 WSwan_RTCRead(uint32 A)
45 {
46 time_t long_time;
47 struct tm *newtime;
48
49 switch(A)
50 {
51 case 0xca:
52 return (Command|0x80);
53 case 0xcb:
54 if(Command != 0x15)
55 return Data | 0x80;
56
57 long_time = CurrentTime;
58 newtime = gmtime( &long_time );
59
60 switch(wsCA15)
61 {
62 case 0:
63 wsCA15++;
64 return mBCD(newtime->tm_year-100);
65 case 1:
66 wsCA15++;
67 return mBCD(newtime->tm_mon);
68 case 2:
69 wsCA15++;
70 return mBCD(newtime->tm_mday);
71 case 3:
72 wsCA15++;
73 return mBCD(newtime->tm_wday);
74 case 4:
75 wsCA15++;
76 return mBCD(newtime->tm_hour);
77 case 5:
78 wsCA15++;
79 return mBCD(newtime->tm_min);
80 case 6:
81 wsCA15=0;
82 return mBCD(newtime->tm_sec);
83 }
84 break;
85 }
86
87 return 0;
88 }
89
WSwan_RTCReset(void)90 void WSwan_RTCReset(void)
91 {
92 time_t happy_time = time(NULL);
93
94 CurrentTime = mktime(localtime(&happy_time));
95 ClockCycleCounter = 0;
96 wsCA15 = 0;
97 }
98
WSwan_RTCClock(uint32 cycles)99 void WSwan_RTCClock(uint32 cycles)
100 {
101 ClockCycleCounter += cycles;
102 while(ClockCycleCounter >= 3072000)
103 {
104 ClockCycleCounter -= 3072000;
105 CurrentTime++;
106 }
107 }
108
WSwan_RTCStateAction(StateMem * sm,int load,int data_only)109 int WSwan_RTCStateAction(StateMem *sm, int load, int data_only)
110 {
111 SFORMAT StateRegs[] =
112 {
113 SFVAR(CurrentTime),
114 SFVAR(ClockCycleCounter),
115 SFVAR(wsCA15),
116 SFVAR(Command),
117 SFVAR(Data),
118 SFEND
119 };
120
121 if(!MDFNSS_StateAction(sm, load, data_only, StateRegs, "RTC", false))
122 return(0);
123
124 return(1);
125 }
126