]> Shamusworld >> Repos - apple2/blob - src/timing.cpp
Fixed stupid bug that caused LC RAM bank #1 to get clobbered when writing
[apple2] / src / timing.cpp
1 //
2 // System time handlers
3 //
4 // by James L. Hammons
5 // (C) 2005 Underground Software
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  01/04/2006  Cosmetic changes (like this one ;-)
12 //
13
14 // STILL TO DO:
15 //
16 // - Handling for an event that occurs NOW
17 //
18
19 #include "timing.h"
20
21 #include "log.h"
22
23 #define EVENT_LIST_SIZE       512
24
25 // NOTE ABOUT TIMING SYSTEM DATA STRUCTURES:
26
27 // A queue won't work for this system because we can't guarantee that an event will go
28 // in with a time that is later than the ones already queued up. So we just use a simple
29 // list.
30
31 // Although if we used an insertion sort we could, but it wouldn't work for adjusting
32 // times...
33
34 struct Event
35 {
36     bool valid;
37     double eventTime;
38     void (* timerCallback)(void);
39 };
40
41 static Event eventList[EVENT_LIST_SIZE];
42 static uint32 nextEvent;
43
44 void InitializeEventList(void)
45 {
46     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
47         eventList[i].valid = false;
48 }
49
50 //We just slap the next event into the list, no checking, no nada...
51 void SetCallbackTime(void (* callback)(void), double time)
52 {
53     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
54     {
55         if (!eventList[i].valid)
56         {
57 //WriteLog("SCT: Found callback slot #%u...\n", i);
58             eventList[i].timerCallback = callback;
59             eventList[i].eventTime = time;
60             eventList[i].valid = true;
61
62             return;
63         }
64     }
65
66     WriteLog("TIMING: SetCallbackTime() failed to find an empty slot in the list!\n");
67 }
68
69 void RemoveCallback(void (* callback)(void))
70 {
71     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
72     {
73         if (eventList[i].valid && eventList[i].timerCallback == callback)
74         {
75             eventList[i].valid = false;
76
77             return;
78         }
79     }
80 }
81
82 void AdjustCallbackTime(void (* callback)(void), double time)
83 {
84     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
85     {
86         if (eventList[i].valid && eventList[i].timerCallback == callback)
87         {
88             eventList[i].eventTime = time;
89
90             return;
91         }
92     }
93 }
94
95 double GetTimeToNextEvent(void)
96 {
97         // Find the next event. Since the events are not necessarily in order of
98         // increasing time, we have to search through the list for the lowest one.
99
100 //ALSO: There's a bug here--nextEvent is getting a bogus value/getting clobbered...
101     double time = 0;
102     bool firstTime = true;
103
104     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
105     {
106         if (eventList[i].valid)
107         {
108             if (firstTime)
109                         {
110                 time = eventList[i].eventTime;
111                                 nextEvent = i;
112                                 firstTime = false;
113                         }
114             else
115             {
116                 if (eventList[i].eventTime < time)
117                                 {
118                     time = eventList[i].eventTime;
119                                         nextEvent = i;
120                                 }
121             }
122         }
123     }
124
125         if (time == 0)
126                 WriteLog("TIMING: GetTimeToNextEvent() failed to find next event!\n");
127
128     return time;
129 }
130
131 void HandleNextEvent(void)
132 {
133     double elapsedTime = eventList[nextEvent].eventTime;
134     void (* event)(void) = eventList[nextEvent].timerCallback;
135
136     for(uint32 i=0; i<EVENT_LIST_SIZE; i++)
137         if (eventList[i].valid)
138             eventList[i].eventTime -= elapsedTime;
139
140     eventList[nextEvent].valid = false;      // Remove event from list...
141
142     (*event)();
143 }