delint
[AROS.git] / arch / m68k-amiga / battclock / battclock_init.c
blobdca41d362bb5b31bdb15d3ef67cf0e4a4b3f0506
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define DEBUG 0
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include <aros/symbolsets.h>
12 #include <hardware/custom.h>
13 #include <proto/exec.h>
15 #include "battclock_intern.h"
17 static int BattClock_Init(struct BattClockBase *BattClockBase)
19 volatile UBYTE *p = (volatile UBYTE*)0xdc0000;
20 volatile struct Custom *cm = (volatile struct Custom*)0xdc0000;
21 volatile struct Custom *c = (volatile struct Custom*)0xdff000;
22 BOOL found = TRUE, didreset = FALSE;
23 BYTE rounds = 2;
25 Disable();
26 for (;;) {
27 UWORD adkcon = c->adkconr;
28 c->adkcon = 0x7fff;
29 if (c->adkconr == cm->adkconr) {
30 c->adkcon = 0x8001;
31 if (c->adkconr == cm->adkconr) {
32 c->adkcon = 0x0001;
33 if (c->adkconr == cm->adkconr)
34 found = FALSE;
37 c->adkcon = 0x7fff;
38 c->adkcon = 0x8000 | adkcon;
39 if (!found) {
40 D(bug("custom chipset detected in clock space\n"));
41 break;
43 // ok, not custom, check if we have a clock
44 found = FALSE;
45 // 10 minutes or hours bit 3 set = not a clock
46 if ((getreg(p, 0x01) & 0x8) || (getreg(p, 0x03) & 8))
47 break;
48 // this is not easy, most UAE versions emulate clock
49 // registers very badly (read-only registers are read-write etc..)
50 // so this needs to be quite stupid.
51 while (rounds-- > 0) {
52 if (getreg(p, 0x0d) == 0x8 && getreg(p, 0x0f) == 0x0) {
53 // RF, maybe
54 BattClockBase->clocktype = RF5C01A;
55 BattClockBase->clockptr = p;
56 found = TRUE;
57 break;
58 } else if (getreg(p, 0x0f) == 0x4) {
59 // MSM
60 BattClockBase->clocktype = MSM6242B;
61 BattClockBase->clockptr = p;
62 found = TRUE;
63 break;
64 } else {
65 // reset clock
66 putreg(p, 0xe, 0);
67 putreg(p, 0xd, 0);
68 putreg(p, 0xd, 4); // set irq flag
69 if (getreg(p, 0xd) == 0) {
70 // was MSM, irq can't be set
71 putreg(p, 0xf, 7); // reset
72 putreg(p, 0xf, 4); // leave 24h on
73 } else { // was alarm en
74 // RF
75 putreg(p, 0xf, 3); // reset
76 putreg(p, 0xf, 0); // reset off
77 putreg(p, 0xd, 8); // timer en
79 didreset = TRUE;
81 if (didreset)
82 resetbattclock(BattClockBase);
84 break;
86 Enable();
87 if (found)
88 BattClockBase->UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library", 0);
89 D(bug("BattClockBase init=%d clock=%d\n", found, BattClockBase->clocktype));
90 return found;
93 ADD2INITLIB(BattClock_Init, 0)