1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - af_rtc.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2014 Bobby Smiles *
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 *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include "af_rtc.h"
23
24 #include "api/m64p_types.h"
25 #include "api/callbacks.h"
26
27 #include <time.h>
28
byte2bcd(int n)29 static uint8_t byte2bcd(int n)
30 {
31 n %= 100;
32 return ((n / 10) << 4) | (n % 10);
33 }
34
af_rtc_get_time(struct af_rtc * rtc)35 const struct tm* af_rtc_get_time(struct af_rtc* rtc)
36 {
37 return rtc->get_time(rtc->user_data);
38 }
39
af_rtc_status_command(struct af_rtc * rtc,uint8_t * cmd)40 void af_rtc_status_command(struct af_rtc *rtc, uint8_t *cmd)
41 {
42 /* AF-RTC status query */
43 cmd[3] = 0x00;
44 cmd[4] = 0x10;
45 cmd[5] = 0x00;
46 }
47
af_rtc_read_command(struct af_rtc * rtc,uint8_t * cmd)48 void af_rtc_read_command(struct af_rtc *rtc, uint8_t *cmd)
49 {
50 const struct tm *rtc_time;
51
52 /* read RTC block (cmd[3]: block number) */
53 switch (cmd[3])
54 {
55 case 0:
56 cmd[4] = 0x00;
57 cmd[5] = 0x02;
58 cmd[12] = 0x00;
59 break;
60 case 1:
61 DebugMessage(M64MSG_ERROR, "AF-RTC read command: cannot read block 1");
62 break;
63 case 2:
64 rtc_time = af_rtc_get_time(rtc);
65 cmd[4] = byte2bcd(rtc_time->tm_sec);
66 cmd[5] = byte2bcd(rtc_time->tm_min);
67 cmd[6] = 0x80 + byte2bcd(rtc_time->tm_hour);
68 cmd[7] = byte2bcd(rtc_time->tm_mday);
69 cmd[8] = byte2bcd(rtc_time->tm_wday);
70 cmd[9] = byte2bcd(rtc_time->tm_mon + 1);
71 cmd[10] = byte2bcd(rtc_time->tm_year);
72 cmd[11] = byte2bcd(rtc_time->tm_year / 100);
73 cmd[12] = 0x00; /* status */
74 break;
75 }
76 }
77
af_rtc_write_command(struct af_rtc * rtc,uint8_t * cmd)78 void af_rtc_write_command(struct af_rtc *rtc, uint8_t* cmd)
79 {
80 /* write RTC block */
81 DebugMessage(M64MSG_ERROR, "AF-RTC write command: not yet implemented");
82 }
83
init_af_rtc(struct af_rtc * rtc,void * user_data,const struct tm * (* get_time)(void *))84 void init_af_rtc(struct af_rtc* rtc,
85 void* user_data,
86 const struct tm* (*get_time)(void*))
87 {
88 rtc->user_data = user_data;
89 rtc->get_time = get_time;
90 }
91