From 1ba8379421ddce01a5992f792ce6c331cef26751 Mon Sep 17 00:00:00 2001 From: neil Date: Tue, 28 Apr 2009 20:40:06 +0000 Subject: [PATCH] Implemented WriteBattClock() and added check to ReadBattClock() to wait until clock isn't being updated. git-svn-id: https://svn.aros.org/svn/aros/trunk/AROS@31156 fb15a70f-31f2-0310-bbcc-cdcc74a49acc --- arch/i386-pc/battclock/cmos.h | 23 +++++++ arch/i386-pc/battclock/mmakefile.src | 6 +- arch/i386-pc/battclock/readbattclock.c | 15 ++--- arch/i386-pc/battclock/writebattclock.c | 116 ++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 arch/i386-pc/battclock/cmos.h create mode 100644 arch/i386-pc/battclock/writebattclock.c diff --git a/arch/i386-pc/battclock/cmos.h b/arch/i386-pc/battclock/cmos.h new file mode 100644 index 000000000..01d70e922 --- /dev/null +++ b/arch/i386-pc/battclock/cmos.h @@ -0,0 +1,23 @@ +/* + Copyright © 1995-2009, The AROS Development Team. All rights reserved. + $Id$ + + Desc: CMOS offsets. + Lang: English +*/ + +#ifndef CMOS_H +#define CMOS_H + +#define CENTURY 0x32 +#define YEAR 0x09 +#define MONTH 0x08 +#define MDAY 0x07 +#define HOUR 0x04 +#define MIN 0x02 +#define SEC 0x00 +#define STATUS_A 0x0A +#define STATUS_B 0x0B +#define HEALTH 0x0E + +#endif /* CMOS_H */ diff --git a/arch/i386-pc/battclock/mmakefile.src b/arch/i386-pc/battclock/mmakefile.src index 322948c5c..e35b0cb17 100644 --- a/arch/i386-pc/battclock/mmakefile.src +++ b/arch/i386-pc/battclock/mmakefile.src @@ -1,9 +1,11 @@ # $Id$ include $(TOP)/config/make.cfg -USER_CFLAGS := -I$(SRCDIR)/rom/battclock +FILES := readbattclock writebattclock +USER_CFLAGS := -I$(SRCDIR)/rom/battclock + %build_archspecific \ mainmmake=kernel-battclock maindir=rom/battclock arch=pc-i386 \ - files=readbattclock modulename=battclock + files=$(FILES) modulename=battclock #MM- kernel-battclock-pc-i386 : kernel-battclock-includes diff --git a/arch/i386-pc/battclock/readbattclock.c b/arch/i386-pc/battclock/readbattclock.c index ba386f8c1..e771262c7 100644 --- a/arch/i386-pc/battclock/readbattclock.c +++ b/arch/i386-pc/battclock/readbattclock.c @@ -6,17 +6,7 @@ Lang: english */ #include "battclock_intern.h" - -#define CENTURY 0x32 -#define YEAR 0x09 -#define MONTH 0x08 -#define MDAY 0x07 -#define HOUR 0x04 -#define MIN 0x02 -#define SEC 0x00 -#define STATUS_A 0x0A -#define STATUS_B 0x0B -#define HEALTH 0x0E +#include "cmos.h" inline unsigned char read_port(unsigned char port); inline int bcd_to_dec(int x); @@ -73,6 +63,9 @@ inline int bcd_to_dec(int x); UWORD status_b; ULONG secs; + /* Make sure time isn't currently being updated */ + while ((read_port(STATUS_A) & 0x80) != 0); + date.sec = read_port(SEC); date.min = read_port(MIN); date.hour = read_port(HOUR); diff --git a/arch/i386-pc/battclock/writebattclock.c b/arch/i386-pc/battclock/writebattclock.c new file mode 100644 index 000000000..86cf1c403 --- /dev/null +++ b/arch/i386-pc/battclock/writebattclock.c @@ -0,0 +1,116 @@ +/* + Copyright © 2009, The AROS Development Team. All rights reserved. + $Id$ + + Desc: WriteBattClock() + Lang: English +*/ +#include "battclock_intern.h" +#include "cmos.h" + +static UBYTE ReadCMOSByte(UBYTE port); +static VOID WriteCMOSByte(UBYTE port, UBYTE value); +static UBYTE MakeBCDByte(UBYTE n); + + +/***************************************************************************** + + NAME */ +#include +#include +#include + + AROS_LH1(void, WriteBattClock, + +/* SYNOPSIS */ + AROS_LHA(ULONG, time, D0), + +/* LOCATION */ + APTR *, BattClockBase, 3, Battclock) + +/* FUNCTION + Set the system's battery backed up clock to the time specified. The + value should be the number of seconds since 00:00:00 on 1.1.1978. + + INPUTS + time - The number of seconds elapsed since 00:00:00 1.1.1978 + + RESULT + The clock will be set. + + NOTES + This may not do anything on some systems where the battery backed + up clock either doesn't exist, or may not be writable. + + EXAMPLE + + BUGS + + SEE ALSO + ReadBattClock, ResetBattClock + + INTERNALS + +*****************************************************************************/ +{ + AROS_LIBFUNC_INIT + + struct ClockData date; + UBYTE century; + UWORD status_b; + + /* Convert time to the required format */ + + Amiga2Date(time, &date); + + century = date.year / 100; + date.year %= 100; + + status_b = ReadCMOSByte(STATUS_B); + + if ((status_b & 0x04) == 0) + { + date.sec = MakeBCDByte(date.sec); + date.min = MakeBCDByte(date.min); + date.hour = MakeBCDByte(date.hour); + date.mday = MakeBCDByte(date.mday); + date.month = MakeBCDByte(date.month); + date.year = MakeBCDByte(date.year); + century = MakeBCDByte(century); + } + + /* Write new time to the RTC */ + + WriteCMOSByte(SEC, date.sec); + WriteCMOSByte(MIN, date.min); + WriteCMOSByte(HOUR, date.hour); + WriteCMOSByte(MDAY, date.mday); + WriteCMOSByte(MONTH, date.month); + WriteCMOSByte(YEAR, date.year); + WriteCMOSByte(CENTURY, century); + + AROS_LIBFUNC_EXIT +} + +static UBYTE ReadCMOSByte(UBYTE port) +{ + UBYTE value; + + asm volatile("outb %0,$0x70" :: "a"(port)); + asm volatile("inb $0x71,%0" : "=a"(value)); + + return value; +} + +static VOID WriteCMOSByte(UBYTE port, UBYTE value) +{ + asm volatile("outb %0,$0x70" :: "a"(port)); + asm volatile("outb %0,$0x71" :: "a"(value)); + + return; +} + +static UBYTE MakeBCDByte(UBYTE n) +{ + return n / 10 << 4 | n % 10; +} -- 2.11.4.GIT