Revision 5fafdf24 hw/mc146818rtc.c
b/hw/mc146818rtc.c | ||
---|---|---|
1 | 1 |
/* |
2 | 2 |
* QEMU MC146818 RTC emulation |
3 |
*
|
|
3 |
* |
|
4 | 4 |
* Copyright (c) 2003-2004 Fabrice Bellard |
5 |
*
|
|
5 |
* |
|
6 | 6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | 7 |
* of this software and associated documentation files (the "Software"), to deal |
8 | 8 |
* in the Software without restriction, including without limitation the rights |
... | ... | |
75 | 75 |
int64_t cur_clock, next_irq_clock; |
76 | 76 |
|
77 | 77 |
period_code = s->cmos_data[RTC_REG_A] & 0x0f; |
78 |
if (period_code != 0 &&
|
|
78 |
if (period_code != 0 && |
|
79 | 79 |
(s->cmos_data[RTC_REG_B] & REG_B_PIE)) { |
80 | 80 |
if (period_code <= 2) |
81 | 81 |
period_code += 7; |
... | ... | |
110 | 110 |
#ifdef DEBUG_CMOS |
111 | 111 |
printf("cmos: write index=0x%02x val=0x%02x\n", |
112 | 112 |
s->cmos_index, data); |
113 |
#endif
|
|
113 |
#endif |
|
114 | 114 |
switch(s->cmos_index) { |
115 | 115 |
case RTC_SECONDS_ALARM: |
116 | 116 |
case RTC_MINUTES_ALARM: |
... | ... | |
221 | 221 |
/* month is between 0 and 11. */ |
222 | 222 |
static int get_days_in_month(int month, int year) |
223 | 223 |
{ |
224 |
static const int days_tab[12] = {
|
|
225 |
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
224 |
static const int days_tab[12] = { |
|
225 |
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 |
|
226 | 226 |
}; |
227 | 227 |
int d; |
228 | 228 |
if ((unsigned )month >= 12) |
... | ... | |
253 | 253 |
tm->tm_wday++; |
254 | 254 |
if ((unsigned)tm->tm_wday >= 7) |
255 | 255 |
tm->tm_wday = 0; |
256 |
days_in_month = get_days_in_month(tm->tm_mon,
|
|
256 |
days_in_month = get_days_in_month(tm->tm_mon, |
|
257 | 257 |
tm->tm_year + 1900); |
258 | 258 |
tm->tm_mday++; |
259 | 259 |
if (tm->tm_mday < 1) { |
... | ... | |
283 | 283 |
qemu_mod_timer(s->second_timer, s->next_second_time); |
284 | 284 |
} else { |
285 | 285 |
rtc_next_second(&s->current_tm); |
286 |
|
|
286 |
|
|
287 | 287 |
if (!(s->cmos_data[RTC_REG_B] & REG_B_SET)) { |
288 | 288 |
/* update in progress bit */ |
289 | 289 |
s->cmos_data[RTC_REG_A] |= REG_A_UIP; |
... | ... | |
293 | 293 |
delay = (ticks_per_sec * 1) / 100; |
294 | 294 |
if (delay < 1) |
295 | 295 |
delay = 1; |
296 |
qemu_mod_timer(s->second_timer2,
|
|
296 |
qemu_mod_timer(s->second_timer2, |
|
297 | 297 |
s->next_second_time + delay); |
298 | 298 |
} |
299 | 299 |
} |
... | ... | |
315 | 315 |
((s->cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 || |
316 | 316 |
s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) { |
317 | 317 |
|
318 |
s->cmos_data[RTC_REG_C] |= 0xa0;
|
|
318 |
s->cmos_data[RTC_REG_C] |= 0xa0; |
|
319 | 319 |
qemu_irq_raise(s->irq); |
320 | 320 |
} |
321 | 321 |
} |
322 | 322 |
|
323 | 323 |
/* update ended interrupt */ |
324 | 324 |
if (s->cmos_data[RTC_REG_B] & REG_B_UIE) { |
325 |
s->cmos_data[RTC_REG_C] |= 0x90;
|
|
325 |
s->cmos_data[RTC_REG_C] |= 0x90; |
|
326 | 326 |
qemu_irq_raise(s->irq); |
327 | 327 |
} |
328 | 328 |
|
... | ... | |
356 | 356 |
case RTC_REG_C: |
357 | 357 |
ret = s->cmos_data[s->cmos_index]; |
358 | 358 |
qemu_irq_lower(s->irq); |
359 |
s->cmos_data[RTC_REG_C] = 0x00;
|
|
359 |
s->cmos_data[RTC_REG_C] = 0x00; |
|
360 | 360 |
break; |
361 | 361 |
default: |
362 | 362 |
ret = s->cmos_data[s->cmos_index]; |
... | ... | |
411 | 411 |
|
412 | 412 |
qemu_put_buffer(f, s->cmos_data, 128); |
413 | 413 |
qemu_put_8s(f, &s->cmos_index); |
414 |
|
|
414 |
|
|
415 | 415 |
qemu_put_be32s(f, &s->current_tm.tm_sec); |
416 | 416 |
qemu_put_be32s(f, &s->current_tm.tm_min); |
417 | 417 |
qemu_put_be32s(f, &s->current_tm.tm_hour); |
... | ... | |
471 | 471 |
|
472 | 472 |
rtc_set_date_from_host(s); |
473 | 473 |
|
474 |
s->periodic_timer = qemu_new_timer(vm_clock,
|
|
474 |
s->periodic_timer = qemu_new_timer(vm_clock, |
|
475 | 475 |
rtc_periodic_timer, s); |
476 |
s->second_timer = qemu_new_timer(vm_clock,
|
|
476 |
s->second_timer = qemu_new_timer(vm_clock, |
|
477 | 477 |
rtc_update_second, s); |
478 |
s->second_timer2 = qemu_new_timer(vm_clock,
|
|
478 |
s->second_timer2 = qemu_new_timer(vm_clock, |
|
479 | 479 |
rtc_update_second2, s); |
480 | 480 |
|
481 | 481 |
s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100; |
Also available in: Unified diff