Subversion Repositories shark

Rev

Rev 3 | Rev 120 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/*      Time management code: ll_getttime()     */
23
 
24
#include <ll/i386/pit.h>
25
#include <ll/i386/stdlib.h>
26
#include <ll/i386/error.h>
27
#include <ll/i386/mem.h>
28
#include <ll/sys/ll/ll-data.h>
29
#include <ll/sys/ll/ll-func.h>
30
#include <ll/sys/ll/time.h>
31
 
32
/* These are for the EXECT and TICK modes */
40 pj 33
extern DWORD ticksize;          /* From init.c  */
34
extern struct timespec actTime; /* From event.c */
35
extern WORD  pit_time_const;    /* From init.c  */
36
extern DWORD  timermode;        /* From init.c  */
2 pj 37
 
38
/* These two are for the NEW algorithm */
40 pj 39
extern WORD lastTime;                /* From event.c */
40
extern struct pitspec globalCounter; /* From event.c */
2 pj 41
extern BYTE frc;
42
extern int activeEvent;
43
 
44
FILE(Time);
45
 
46
TIME ll_gettime(int mode, struct timespec *tsres)
47
{
40 pj 48
        DWORD res, tc;
49
        BYTE isr;
50
        struct timespec tmp;
2 pj 51
 
40 pj 52
#if 1
53
        if (activeEvent) {
54
          if (tsres != NULL) {
55
            PITSPEC2TIMESPEC(&globalCounter, tsres);
56
          } else {
57
            struct timespec tmp;
2 pj 58
 
40 pj 59
            PITSPEC2TIMESPEC(&globalCounter, &tmp);
60
            return TIMESPEC2USEC(&tmp);
61
          }
62
          return TIMESPEC2USEC(tsres);
2 pj 63
        }
40 pj 64
#endif
65
 
66
        if (mode == TIME_PTICK) {
67
                if (timermode != LL_PERIODIC) {
68
                        return 0;
69
                }
70
                res = TIMESPEC2USEC(&actTime);
71
                if (tsres != NULL) {
72
                        memcpy(tsres, &actTime, sizeof(struct timespec));
73
                }
74
                return res;
2 pj 75
        }
76
 
40 pj 77
        if (mode == TIME_NEW) {
78
          WORD tmp;
79
 
80
          tmp = pit_read(frc);
81
          ADDPITSPEC((WORD)(lastTime - tmp), &globalCounter);
82
          lastTime = tmp;
83
          if (tsres != NULL) {
2 pj 84
            PITSPEC2TIMESPEC(&globalCounter, tsres);
40 pj 85
          }
86
          return (PITSPEC2USEC(&globalCounter));
2 pj 87
        }
88
 
40 pj 89
        if (mode == TIME_EXACT) {
90
                if (timermode == LL_PERIODIC) {
91
                        memcpy(&tmp, &actTime, sizeof(struct timespec));
92
                        /* How much time has elapsed
93
                         * from the last Tick Boundary?
94
                         */
95
                        tc = pit_read(0);
96
                        if (tc > pit_time_const) {
97
                            error("LL Time Panic!!!\n");
98
                            ll_abort(1);
99
                        }
100
                        res = pit_time_const - tc;
101
                        res *= ticksize;
102
                        res /= pit_time_const;
2 pj 103
 
40 pj 104
                        /* Detect tick boundary and adjust the time... */
105
                        outp(0x20, 0x0A);
106
                        isr = inp(0x20);
107
                        if ((isr & 1) && res < ((8*ticksize)/10)){
108
                              /*
109
                                res += ticksize;
110
                                ADDNANO2TIMESPEC(ticksize * 1000, &tmp);
111
                              */
112
                              res = ticksize;
113
                        }
2 pj 114
 
40 pj 115
                        /* Sum the Tick time... */
116
                        ADDNANO2TIMESPEC(res * 1000, &tmp);
117
                        res += TIMESPEC2USEC(&actTime);
2 pj 118
 
40 pj 119
                        if (tsres != NULL) {
120
                                memcpy(tsres, &tmp, sizeof(struct timespec));
121
                        }
122
                        return res;
123
                } else {
124
                        return 0;
125
                }
2 pj 126
        }
40 pj 127
        return 0;
2 pj 128
}