Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
rtc.c
Go to the documentation of this file.
1 /* Minimalistic Enterprise-128 emulator with focus on "exotic" hardware
2  Part of the Xemu project, please visit: https://github.com/lgblgblgb/xemu
3  Copyright (C)2015-2016,2020 LGB (Gábor Lénárt) <lgblgblgb@gmail.com>
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18 
19 
20 #include "xemu/emutools.h"
21 #include "enterprise128.h"
22 #include "rtc.h"
23 #include <time.h>
24 
25 
26 //#define RESET_RTC_INDEX
27 
28 
29 static int _rtc_register;
30 static Uint8 cmos_ram[0x100];
32 
33 
34 void rtc_set_reg(Uint8 val)
35 {
36  _rtc_register = val;
37  DEBUG("RTC: register number %02X has been selected" NL, val);
38 }
39 
40 
42 {
43  DEBUG("RTC: write reg %02X with data %02X" NL, _rtc_register, val);
44  if (_rtc_register == 0xC || _rtc_register == 0xD) return;
45  if (_rtc_register == 0xA) val &= 127;
46  cmos_ram[_rtc_register] = val;
47 #ifdef RESET_RTC_INDEX
48  _rtc_register = 0xD;
49 #endif
50 }
51 
52 
53 static int _rtc_conv(int bin, int is_hour)
54 {
55  int b7 = 0;
56  if (is_hour && (!(cmos_ram[0xB] & 2))) { // AM/PM
57  if (bin == 0) {
58  bin = 12;
59  } else if (bin == 12) {
60  b7 = 128;
61  } else if (bin > 12) {
62  bin -= 12;
63  b7 = 128;
64  }
65  }
66  if (!(cmos_ram[0xB] & 4)) { // do bin->bcd
67  bin = ((bin / 10) << 4) | (bin % 10);
68  }
69  return bin | b7;
70 }
71 
72 
73 static void _rtc_update(void)
74 {
75  struct tm *t = localtime(&unix_time);
76  cmos_ram[ 0] = _rtc_conv(t->tm_sec, 0);
77  cmos_ram[ 2] = _rtc_conv(t->tm_min, 0);
78  cmos_ram[ 4] = _rtc_conv(t->tm_hour, 1);
79  cmos_ram[ 6] = _rtc_conv(t->tm_wday + 1, 0); // day, 1-7 (week)
80  cmos_ram[ 7] = _rtc_conv(t->tm_mday, 0); // date, 1-31
81  cmos_ram[ 8] = _rtc_conv(t->tm_mon + 1, 0); // month, 1 -12
82  cmos_ram[ 9] = _rtc_conv((t->tm_year % 100) + 20, 0); // year, 0 - 99
83  cmos_ram[0x32] = _rtc_conv(21, 0); // century???
84  DEBUG("RTC: time/date has been updated for \"%d-%02d-%02d %02d:%02d:%02d\" at UNIX epoch %ld" NL,
85  t->tm_year + 1900,
86  t->tm_mon + 1,
87  t->tm_mday,
88  t->tm_hour,
89  t->tm_min,
90  t->tm_sec,
91  (long int)unix_time
92  );
93 }
94 
95 
96 void rtc_reset(void)
97 {
98  memset(cmos_ram, 0, 0x100);
99  _rtc_register = 0xD;
100  rtc_update_trigger = 0;
101  cmos_ram[0xA] = 32;
102  cmos_ram[0xB] = 2; // 2 | 4;
103  cmos_ram[0xC] = 0;
104  cmos_ram[0xD] = 128;
105  DEBUG("RTC: reset" NL);
106  _rtc_update();
107 }
108 
109 
111 {
112  int i = _rtc_register;
113 #ifdef RESET_RTC_INDEX
114  _rtc_register = 0xD;
115 #endif
116  if (i > 63)
117  return 0xFF;
118  if (rtc_update_trigger && (cmos_ram[0xB] & 128) == 0 && i < 10) {
119  _rtc_update();
120  rtc_update_trigger = 0;
121  }
122  DEBUG("RTC: reading register %02X, result will be: %02X" NL, i, cmos_ram[i]);
123  return cmos_ram[i];
124 }
unix_time
time_t unix_time
Definition: enterprise128.c:59
emutools.h
rtc_read_reg
Uint8 rtc_read_reg(void)
Definition: rtc.c:110
rtc_reset
void rtc_reset(void)
Definition: rtc.c:96
Uint8
uint8_t Uint8
Definition: fat32.c:51
NL
#define NL
Definition: fat32.c:37
rtc_update_trigger
int rtc_update_trigger
Definition: rtc.c:31
rtc.h
enterprise128.h
DEBUG
#define DEBUG(...)
Definition: emutools_basicdefs.h:167
rtc_set_reg
void rtc_set_reg(Uint8 val)
Definition: rtc.c:34
rtc_write_reg
void rtc_write_reg(Uint8 val)
Definition: rtc.c:41