-
Notifications
You must be signed in to change notification settings - Fork 5
/
RealTimeClock.patch
86 lines (83 loc) · 2.79 KB
/
RealTimeClock.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
--- 1/Kernel.Mod.txt
+++ 2/Kernel.Mod.txt
@@ -11,7 +11,7 @@
VAR allocated*, NofSectors*: INTEGER;
heapOrg*, heapLim*: INTEGER;
stackOrg* , stackSize*, MemLim*: INTEGER;
- clock: INTEGER;
+ clock, clockTime: INTEGER;
list0, list1, list2, list3: INTEGER; (*lists of free blocks of size n*256, 128, 64, 32 bytes*)
data: INTEGER; (*SPI data in*)
sectorMap: ARRAY mapsize DIV 32 OF SET;
@@ -239,12 +239,64 @@
BEGIN SYSTEM.GET(timer, t); RETURN t
END Time;
+ PROCEDURE AddDays(clockPart, days: INTEGER) : INTEGER;
+ VAR year, month, day, monthLength : INTEGER;
+ BEGIN
+ year := clockPart DIV 200H;
+ month := clockPart DIV 20H MOD 10H;
+ day := clockPart MOD 20H + days;
+ REPEAT
+ IF month # 2 THEN
+ monthLength := 30 + (month + month DIV 8) MOD 2
+ ELSIF (year MOD 4 = 0) & ((year MOD 100 # 0) OR (year MOD 400 = 0)) THEN
+ monthLength := 29
+ ELSE
+ monthLength := 28
+ END;
+ IF day > monthLength THEN
+ INC(month); DEC(day, monthLength);
+ IF month = 13 THEN INC(year); month := 1 END;
+ monthLength := 28 (* will recalculate in next loop run, if required *)
+ END
+ UNTIL day <= monthLength;
+ RETURN (year * 10H + month) * 20H + day
+ END AddDays;
+
+ PROCEDURE UpdateClock;
+ VAR value, rest: INTEGER;
+ BEGIN
+ IF clock = 0 THEN
+ value := 0 (* avoid ticking if not set *)
+ ELSE
+ value := (Time() - clockTime) DIV 1000;
+ clockTime := clockTime + value * 1000;
+ value := clock MOD 40H + value
+ END;
+ IF value < 60 THEN
+ clock := clock DIV 40H * 40H + value
+ ELSE
+ rest := value MOD 60;
+ value := value DIV 60 + clock DIV 40H MOD 40H;
+ IF value < 60 THEN
+ clock := clock DIV 1000H * 1000H + value * 40H + rest
+ ELSE
+ rest := (value MOD 60) * 40H + rest;
+ value := value DIV 60 + clock DIV 1000H MOD 32;
+ IF value < 24 THEN
+ clock := clock DIV 20000H * 20000H + value * 1000H + rest
+ ELSE
+ clock := AddDays(clock DIV 20000H, value DIV 24) * 20000H + (value MOD 24) * 1000H + rest;
+ END
+ END
+ END
+ END UpdateClock;
+
PROCEDURE Clock*(): INTEGER;
- BEGIN RETURN clock
+ BEGIN UpdateClock; RETURN clock
END Clock;
PROCEDURE SetClock*(dt: INTEGER);
- BEGIN clock := dt
+ BEGIN clock := dt; clockTime := Time()
END SetClock;
PROCEDURE Install*(Padr, at: INTEGER);
@@ -264,6 +316,7 @@
SYSTEM.GET(12, MemLim); SYSTEM.GET(24, heapOrg);
stackOrg := heapOrg; stackSize := 8000H; heapLim := MemLim;
list1 := 0; list2 := 0; list3 := 0; list0 := heapOrg;
+ clockTime := Time();
SYSTEM.PUT(list0, heapLim - heapOrg); SYSTEM.PUT(list0+4, -1); SYSTEM.PUT(list0+8, 0);
allocated := 0; clock := 0; InitSecMap
END Init;