#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
void
delay(int ms)
{
int i;
ms *= 7000; /* experimentally determined */
for(i=0; i<ms; i++)
;
}
/*
* AMD 82C54 timer
*
* ctr2 is clocked at 3.6864 MHz. ctr2 output clocks ctr0 and ctr1.
* ctr0 drives INTR2. ctr1 drives INTR4.
* To get 100Hz, 36864==9*4096=36*1024 so clock ctr2
* every 1024 and ctr0 every 36.
*/
struct Timer{
uchar cnt0,
junk0[3];
uchar cnt1,
junk1[3];
uchar cnt2,
junk2[3];
uchar ctl,
junk3[3];
};
#define TIME0 (36*MS2HZ/10)
#define TIME1 0xFFFFFFFF /* profiling disabled */
#define TIME2 1024
#define CTR(x) ((x)<<6) /* which counter x */
#define SET16 0x30 /* lsbyte then msbyte */
#define MODE2 0x04 /* interval timer */
void
clockinit(void)
{
Timer *t;
int i;
t = TIMERREG;
t->ctl = CTR(2)|SET16|MODE2;
t->cnt2 = TIME2&0xFF;
t->cnt2 = (TIME2>>8)&0xFF;
t->ctl = CTR(1)|SET16|MODE2;
t->cnt1 = TIME1&0xFF;
t->cnt1 = (TIME1>>8)&0xFF;
t->ctl = CTR(0)|SET16|MODE2;
t->cnt0 = TIME0;
t->cnt0 = (TIME0>>8)&0xFF;
i = *CLRTIM0;
USED(i);
i = *CLRTIM1;
USED(i);
m->ticks = 0;
}
void
clock(Ureg *ur)
{
int i;
if((ur->cause&INTR2) == 0) {
if(ur->cause & INTR4) {
i = *CLRTIM1;
USED(i);
}
return;
}
nrun = 0;
i = *CLRTIM0;
USED(i);
m->ticks++;
if(m->proc)
m->proc->pc = ur->pc;
accounttime();
duartslave();
if((active.machs&(1<<m->machno)) == 0)
return;
if(active.exiting && active.machs&(1<<m->machno)) {
print("someone's exiting\n");
exit(0);
}
checkalarms();
kproftimer(ur->pc);
if(up == 0 || (ur->status&IEP) == 0 || up->state != Running)
return;
if(anyready())
sched();
/* user profiling clock */
if(ur->status & KUP)
(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1);
}