OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [mac/] [tclMacInterupt.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclMacInterupt.c --
3
 *
4
 *      This file contains routines that deal with the Macintosh's low level
5
 *      time manager.  This code provides a better resolution timer than what
6
 *      can be provided by WaitNextEvent.
7
 *
8
 * Copyright (c) 1996 Sun Microsystems, Inc.
9
 *
10
 * See the file "license.terms" for information on usage and redistribution
11
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12
 *
13
 * RCS: @(#) $Id: tclMacInterupt.c,v 1.1.1.1 2002-01-16 10:25:30 markom Exp $
14
 */
15
 
16
#include "tclInt.h"
17
#include "tclMacInt.h"
18
#include <LowMem.h>
19
#include <Processes.h>
20
#include <Timer.h>
21
 
22
/*
23
 * Data structure for timer tasks.
24
 */
25
typedef struct TMInfo {
26
    TMTask              tmTask;
27
    ProcessSerialNumber psn;
28
    Point               lastPoint;
29
    Point               newPoint;
30
    long                currentA5;
31
    long                ourA5;
32
    int                 installed;
33
} TMInfo;
34
 
35
/*
36
 * Globals used within this file.
37
 */
38
 
39
static TimerUPP sleepTimerProc = NULL;
40
static int interuptsInited = false;
41
static ProcessSerialNumber applicationPSN;
42
#define MAX_TIMER_ARRAY_SIZE 16
43
static TMInfo timerInfoArray[MAX_TIMER_ARRAY_SIZE];
44
static int topTimerElement = 0;
45
 
46
/*
47
 * Prototypes for procedures that are referenced only in this file:
48
 */
49
 
50
#if !GENERATINGCFM
51
static TMInfo *         GetTMInfo(void) ONEWORDINLINE(0x2E89); /* MOVE.L A1,(SP) */
52
#endif
53
static void             SleepTimerProc _ANSI_ARGS_((void));
54
static pascal void      CleanUpExitProc _ANSI_ARGS_((void));
55
static void             InitInteruptSystem _ANSI_ARGS_((void));
56
 
57
/*
58
 *----------------------------------------------------------------------
59
 *
60
 * InitInteruptSystem --
61
 *
62
 *      Does various initialization for the functions used in this
63
 *      file.  Sets up Universial Pricedure Pointers, installs a trap
64
 *      patch for ExitToShell, etc.
65
 *
66
 * Results:
67
 *      None.
68
 *
69
 * Side effects:
70
 *      Various initialization.
71
 *
72
 *----------------------------------------------------------------------
73
 */
74
 
75
void
76
InitInteruptSystem()
77
{
78
    int i;
79
 
80
    sleepTimerProc = NewTimerProc(SleepTimerProc);
81
    GetCurrentProcess(&applicationPSN);
82
    for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
83
        timerInfoArray[i].installed = false;
84
    }
85
 
86
    /*
87
     * Install the ExitToShell patch.  We use this patch instead
88
     * of the Tcl exit mechanism because we need to ensure that
89
     * these routines are cleaned up even if we crash or are forced
90
     * to quit.  There are some circumstances when the Tcl exit
91
     * handlers may not fire.
92
     */
93
 
94
    TclMacInstallExitToShellPatch(CleanUpExitProc);
95
    interuptsInited = true;
96
}
97
 
98
/*
99
 *----------------------------------------------------------------------
100
 *
101
 * TclMacStartTimer --
102
 *
103
 *      Install a Time Manager task to wake our process up in the
104
 *      future.  The process should get a NULL event after ms
105
 *      milliseconds.
106
 *
107
 * Results:
108
 *      None.
109
 *
110
 * Side effects:
111
 *      Schedules our process to wake up.
112
 *
113
 *----------------------------------------------------------------------
114
 */
115
 
116
void *
117
TclMacStartTimer(
118
    long ms)            /* Milliseconds. */
119
{
120
    TMInfo *timerInfoPtr;
121
 
122
    if (!interuptsInited) {
123
        InitInteruptSystem();
124
    }
125
 
126
    /*
127
     * Obtain a pointer for the timer.  We only allocate up
128
     * to MAX_TIMER_ARRAY_SIZE timers.  If we are past that
129
     * max we return NULL.
130
     */
131
    if (topTimerElement < MAX_TIMER_ARRAY_SIZE) {
132
        timerInfoPtr = &timerInfoArray[topTimerElement];
133
        topTimerElement++;
134
    } else {
135
        return NULL;
136
    }
137
 
138
    /*
139
     * Install timer to wake process in ms milliseconds.
140
     */
141
    timerInfoPtr->tmTask.tmAddr = sleepTimerProc;
142
    timerInfoPtr->tmTask.tmWakeUp = 0;
143
    timerInfoPtr->tmTask.tmReserved = 0;
144
    timerInfoPtr->psn = applicationPSN;
145
    timerInfoPtr->installed = true;
146
 
147
    InsTime((QElemPtr) timerInfoPtr);
148
    PrimeTime((QElemPtr) timerInfoPtr, (long) ms);
149
 
150
    return (void *) timerInfoPtr;
151
}
152
 
153
/*
154
 *----------------------------------------------------------------------
155
 *
156
 * TclMacRemoveTimer --
157
 *
158
 *      Remove the timer event from the Time Manager.
159
 *
160
 * Results:
161
 *      None.
162
 *
163
 * Side effects:
164
 *      A scheduled timer would be removed.
165
 *
166
 *----------------------------------------------------------------------
167
 */
168
 
169
void
170
TclMacRemoveTimer(
171
    void * timerToken)          /* Token got from start timer. */
172
{
173
    TMInfo *timerInfoPtr = (TMInfo *) timerToken;
174
 
175
    if (timerInfoPtr == NULL) {
176
        return;
177
    }
178
 
179
    RmvTime((QElemPtr) timerInfoPtr);
180
    timerInfoPtr->installed = false;
181
    topTimerElement--;
182
}
183
 
184
/*
185
 *----------------------------------------------------------------------
186
 *
187
 * TclMacTimerExpired --
188
 *
189
 *      Check to see if the installed timer has expired.
190
 *
191
 * Results:
192
 *      True if timer has expired, false otherwise.
193
 *
194
 * Side effects:
195
 *      None.
196
 *
197
 *----------------------------------------------------------------------
198
 */
199
 
200
int
201
TclMacTimerExpired(
202
    void * timerToken)          /* Our token again. */
203
{
204
    TMInfo *timerInfoPtr = (TMInfo *) timerToken;
205
 
206
    if ((timerInfoPtr == NULL) ||
207
        !(timerInfoPtr->tmTask.qType & kTMTaskActive)) {
208
        return true;
209
    } else {
210
        return false;
211
    }
212
}
213
 
214
/*
215
 *----------------------------------------------------------------------
216
 *
217
 * SleepTimerProc --
218
 *
219
 *      Time proc is called by the is a callback routine placed in the
220
 *      system by Tcl_Sleep.  The routine is called at interupt time
221
 *      and threrfor can not move or allocate memory.  This call will
222
 *      schedule our process to wake up the next time the process gets
223
 *      around to consider running it.
224
 *
225
 * Results:
226
 *      None.
227
 *
228
 * Side effects:
229
 *      Schedules our process to wake up.
230
 *
231
 *----------------------------------------------------------------------
232
 */
233
 
234
static void
235
SleepTimerProc()
236
{
237
    /*
238
     * In CFM code we can access our code directly.  In 68k code that
239
     * isn't based on CFM we must do a glorious hack.  The function
240
     * GetTMInfo is an inline assembler call that moves the pointer
241
     * at A1 to the top of the stack.  The Time Manager keeps the TMTask
242
     * info record there before calling this call back.  In order for
243
     * this to work the infoPtr argument must be the *last* item on the
244
     * stack.  If we "piggyback" our data to the TMTask info record we
245
     * can get access to the information we need.  While this is really
246
     * ugly - it's the way Apple recomends it be done - go figure...
247
     */
248
 
249
#if GENERATINGCFM
250
    WakeUpProcess(&applicationPSN);
251
#else
252
    TMInfo * infoPtr;
253
 
254
    infoPtr = GetTMInfo();
255
    WakeUpProcess(&infoPtr->psn);
256
#endif
257
}
258
 
259
/*
260
 *----------------------------------------------------------------------
261
 *
262
 * CleanUpExitProc --
263
 *
264
 *      This procedure is invoked as an exit handler when ExitToShell
265
 *      is called.  It removes the system level timer handler if it
266
 *      is installed.  This must be called or the Mac OS will more than
267
 *      likely crash.
268
 *
269
 * Results:
270
 *      None.
271
 *
272
 * Side effects:
273
 *      None.
274
 *
275
 *----------------------------------------------------------------------
276
 */
277
 
278
static pascal void
279
CleanUpExitProc()
280
{
281
    int i;
282
 
283
    for (i = 0; i < MAX_TIMER_ARRAY_SIZE; i++) {
284
        if (timerInfoArray[i].installed) {
285
            RmvTime((QElemPtr) &timerInfoArray[i]);
286
            timerInfoArray[i].installed = false;
287
        }
288
    }
289
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.