/* This file is in the public domain. */ /* ltc board driver */ #define CSR 017777546 #define LTC_IE 0100 #include "driver.h" #include #include extern DRIVER ltc_driver; static word ltc; static int running; static int tickus = 1000000 / 60; static void startticks(void) { struct itimerval itv; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = tickus; itv.it_value = itv.it_interval; setitimer(ITIMER_REAL,&itv,(struct itimerval *)0); running = 1; } static void stopticks(void) { struct itimerval itv; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 0; itv.it_value = itv.it_interval; setitimer(ITIMER_REAL,&itv,(struct itimerval *)0); running = 0; } static void ltc__sigalrm(UNUSED(int sig)) { extern int halted; if (halted) return; if (ltc & LTC_IE) { interrupt(<c_driver,0100,BR6); } else { stopticks(); } } static void ltc_init(UNUSED(DRIVER *d), char *iomask) { iomask[IOMASK(CSR)] = 1; ltc = 0; signal(SIGALRM,ltc__sigalrm); stopticks(); } static int ltc_io(UNUSED(DRIVER *d), int loc, int op, int data, UNUSED(void (*fxn)(void *))) { int rv; rv = reg_access(loc,<c,op,~LTC_IE,data); if (ltc & LTC_IE) { if (! running) startticks(); } else { if (running) stopticks(); } return(rv); } static void ltc_busreset(UNUSED(DRIVER *d)) { ltc = 0; stopticks(); } static void ltc_reset(UNUSED(DRIVER *d)) { } static int ltc_intchk(UNUSED(INTRQ *irq)) { return(ltc<C_IE); } DRIVER ltc_driver = { DVR_NORMW, "line-time clock", ltc_init, 0, ltc_io, ltc_busreset, ltc_reset, ltc_intchk, 0 };