2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void UPD4991A::initialize()
15 memset(regs, 0, sizeof(regs));
16 ctrl1 = ctrl2 = mode = 0;
18 get_host_time(&cur_time);
22 register_event(this, 0, 1000000.0, true, ®ister_id);
25 void UPD4991A::write_io8(uint32_t addr, uint32_t data)
29 if(mode == 0 || mode == 3) {
30 if(regs[0][addr] != data) {
34 } else if(mode == 1) {
36 } else if(mode == 2) {
37 uint8_t tmp = regs[2][addr] ^ data;
40 if(addr == 12 && (tmp & 8)) {
45 } else if(addr == 13) {
47 } else if(addr == 14) {
49 } else if(addr == 15) {
54 uint32_t UPD4991A::read_io8(uint32_t addr)
58 if(mode == 0 || mode == 3) {
60 } else if(mode == 1 || mode == 2) {
61 return regs[mode][addr];
63 } else if(addr == 14) {
69 void UPD4991A::event_callback(int event_id, int err)
72 if(cur_time.initialized) {
75 get_host_time(&cur_time); // resync
76 cur_time.initialized = true;
84 #define MODE_12H !(regs[2][12] & 8)
86 void UPD4991A::read_from_cur_time()
88 int hour = MODE_12H ? (cur_time.hour % 12) : cur_time.hour;
89 int ampm = (MODE_12H && cur_time.hour >= 12) ? 4 : 0;
91 regs[0][ 0] = TO_BCD_LO(cur_time.second);
92 regs[0][ 1] = TO_BCD_HI(cur_time.second);
93 regs[0][ 2] = TO_BCD_LO(cur_time.minute);
94 regs[0][ 3] = TO_BCD_HI(cur_time.minute);
95 regs[0][ 4] = TO_BCD_LO(hour);
96 regs[0][ 5] = TO_BCD_HI(hour) | ampm;
97 regs[0][ 6] = cur_time.day_of_week;
98 regs[0][ 7] = TO_BCD_LO(cur_time.day);
99 regs[0][ 8] = TO_BCD_HI(cur_time.day);
100 regs[0][ 9] = TO_BCD_LO(cur_time.month);
101 regs[0][10] = TO_BCD_HI(cur_time.month);
102 regs[0][11] = TO_BCD_LO(cur_time.year);
103 regs[0][12] = TO_BCD_HI(cur_time.year);
108 void UPD4991A::write_to_cur_time()
110 cur_time.second = regs[0][0] + (regs[0][1] & 7) * 10;
111 cur_time.minute = regs[0][2] + (regs[0][3] & 7) * 10;
113 cur_time.hour = regs[0][4] + (regs[0][5] & 1) * 10 + (regs[0][5] & 4 ? 12 : 0);
115 cur_time.hour = regs[0][4] + (regs[0][5] & 3) * 10;
117 // cur_time.day_of_week = regs[0][6];
118 cur_time.day = regs[0][7] + (regs[0][8] & 3) * 10;
119 cur_time.month = regs[0][9] + (regs[0][10] & 1) * 10;
120 cur_time.year = regs[0][11] + regs[0][12] * 10;
121 cur_time.update_year();
122 cur_time.update_day_of_week();
125 cancel_event(this, register_id);
126 register_event(this, 0, 1000000.0, true, ®ister_id);
129 #define STATE_VERSION 1
131 void UPD4991A::save_state(FILEIO* state_fio)
133 state_fio->FputUint32(STATE_VERSION);
134 state_fio->FputInt32(this_device_id);
136 cur_time.save_state((void *)state_fio);
137 state_fio->FputInt32(register_id);
138 state_fio->Fwrite(regs, sizeof(regs), 1);
139 state_fio->FputUint8(ctrl1);
140 state_fio->FputUint8(ctrl2);
141 state_fio->FputUint8(mode);
144 bool UPD4991A::load_state(FILEIO* state_fio)
146 if(state_fio->FgetUint32() != STATE_VERSION) {
149 if(state_fio->FgetInt32() != this_device_id) {
152 if(!cur_time.load_state((void *)state_fio)) {
155 register_id = state_fio->FgetInt32();
156 state_fio->Fread(regs, sizeof(regs), 1);
157 ctrl1 = state_fio->FgetUint8();
158 ctrl2 = state_fio->FgetUint8();
159 mode = state_fio->FgetUint8();