Annotation of MiNT/doc/clockdev.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3:  * A simple device driver for u:\dev\clock. Reading from this
        !             4: 
        !             5:  * device produces a single line containing the current time, in the
        !             6: 
        !             7:  * format:
        !             8: 
        !             9:  * MM/DD/YY hh:mm:ss\r\n
        !            10: 
        !            11:  * Writing to it will change the time to the given one.
        !            12: 
        !            13:  *
        !            14: 
        !            15:  * This program is written by Eric R. Smith and is hereby placed in
        !            16: 
        !            17:  * the public domain.
        !            18: 
        !            19:  *
        !            20: 
        !            21:  * COMPILER NOTE: I've assumed that you're using a compiler (like gcc
        !            22: 
        !            23:  * or Lattice) that preserves registers d2 and a2 across function calls.
        !            24: 
        !            25:  * If your compiler uses these registers as scratch registers (e.g.
        !            26: 
        !            27:  * MWC, Alcyon) then you'll have to provide assembly language wrapper
        !            28: 
        !            29:  * functions that the kernel can call.
        !            30: 
        !            31:  * This code also assumes that sizeof(int) == 2.
        !            32: 
        !            33:  *
        !            34: 
        !            35:  * for gcc: compile with gcc -mshort -O clockdev.c -o clockdev.prg
        !            36: 
        !            37:  * for lcc: compile with -bn -b0 -r0 -v -w -t= clockdev.c -oclockdev.prg
        !            38: 
        !            39:  */
        !            40: 
        !            41: 
        !            42: 
        !            43: #ifdef __GNUC__
        !            44: 
        !            45: #include <minimal.h>
        !            46: 
        !            47: #endif
        !            48: 
        !            49: #include <osbind.h>
        !            50: 
        !            51: #include <basepage.h>
        !            52: 
        !            53: #include "mintbind.h"
        !            54: 
        !            55: #include "filesys.h"
        !            56: 
        !            57: #include "atarierr.h"
        !            58: 
        !            59: 
        !            60: 
        !            61: #ifdef LATTICE
        !            62: 
        !            63: #define BP _pbase
        !            64: 
        !            65: #else
        !            66: 
        !            67: #define BP _base
        !            68: 
        !            69: #endif
        !            70: 
        !            71: 
        !            72: 
        !            73: /* the name of the device we're installing */
        !            74: 
        !            75: char name[] = "U:\\DEV\\CLOCK";
        !            76: 
        !            77: 
        !            78: 
        !            79: /* kernel information */
        !            80: 
        !            81: struct kerinfo *kernel;
        !            82: 
        !            83: #define CCONWS (void)(*kernel->dos_tab[0x09])
        !            84: 
        !            85: #define RWABS (*kernel->bios_tab[4])
        !            86: 
        !            87: #define GETBPB (void *)(*kernel->bios_tab[7])
        !            88: 
        !            89: #define TGETTIME (*kernel->dos_tab[0x2c])
        !            90: 
        !            91: #define TGETDATE (*kernel->dos_tab[0x2a])
        !            92: 
        !            93: #define TSETTIME (*kernel->dos_tab[0x2d])
        !            94: 
        !            95: #define TSETDATE (*kernel->dos_tab[0x2b])
        !            96: 
        !            97: 
        !            98: 
        !            99: #define SPRINTF (*kernel->sprintf)
        !           100: 
        !           101: #define DEBUG (*kernel->debug)
        !           102: 
        !           103: #define ALERT (*kernel->alert)
        !           104: 
        !           105: #define TRACE (*kernel->trace)
        !           106: 
        !           107: #define FATAL (*kernel->fatal)
        !           108: 
        !           109: 
        !           110: 
        !           111: /* assumption: 16 bit integers */
        !           112: 
        !           113: #define word int
        !           114: 
        !           115: 
        !           116: 
        !           117: /* device driver information */
        !           118: 
        !           119: static long    clock_open      P_((FILEPTR *)),
        !           120: 
        !           121:                clock_write     P_((FILEPTR *, char *, long)),
        !           122: 
        !           123:                clock_read      P_((FILEPTR *, char *, long)),
        !           124: 
        !           125:                clock_lseek     P_((FILEPTR *, long, word)),
        !           126: 
        !           127:                clock_ioctl     P_((FILEPTR *, word, void *)),
        !           128: 
        !           129:                clock_datime    P_((FILEPTR *, word *, word)),
        !           130: 
        !           131:                clock_close     P_((FILEPTR *));
        !           132: 
        !           133: 
        !           134: 
        !           135: static long    clock_select();
        !           136: 
        !           137: static void    clock_unselect();
        !           138: 
        !           139: 
        !           140: 
        !           141: DEVDRV clock_device = {
        !           142: 
        !           143:        clock_open, clock_write, clock_read, clock_lseek, clock_ioctl,
        !           144: 
        !           145:        clock_datime, clock_close, clock_select, clock_unselect,
        !           146: 
        !           147:        0, 0, 0
        !           148: 
        !           149: };
        !           150: 
        !           151: 
        !           152: 
        !           153: struct dev_descr devinfo = {
        !           154: 
        !           155:        &clock_device, 0, 0, (struct tty *)0, 0L, 0L, 0L, 0L
        !           156: 
        !           157: };
        !           158: 
        !           159: 
        !           160: 
        !           161: #ifdef LATTICE
        !           162: 
        !           163: BASEPAGE *BP;
        !           164: 
        !           165: 
        !           166: 
        !           167: void
        !           168: 
        !           169: start(BASEPAGE *bp)
        !           170: 
        !           171: {
        !           172: 
        !           173:        BP = bp;
        !           174: 
        !           175:        
        !           176: 
        !           177:        main();
        !           178: 
        !           179: }
        !           180: 
        !           181: #endif
        !           182: 
        !           183: 
        !           184: 
        !           185: /*
        !           186: 
        !           187:  * the main program just installs the device, and then does Ptermres
        !           188: 
        !           189:  * to remain resident
        !           190: 
        !           191:  */
        !           192: 
        !           193: 
        !           194: 
        !           195: main()
        !           196: 
        !           197: {
        !           198: 
        !           199:        kernel = (struct kerinfo *)Dcntl(DEV_INSTALL, name, &devinfo);
        !           200: 
        !           201:        if (!kernel || ((long)kernel) == -32) {
        !           202: 
        !           203:                Cconws("Unable to install clock device\r\n");
        !           204: 
        !           205:                Pterm(1);
        !           206: 
        !           207:        }
        !           208: 
        !           209:        Ptermres(256L + BP->p_tlen + BP->p_dlen + BP->p_blen, 0);
        !           210: 
        !           211: }
        !           212: 
        !           213: 
        !           214: 
        !           215: /*
        !           216: 
        !           217:  * here are the actual device driver functions
        !           218: 
        !           219:  */
        !           220: 
        !           221: 
        !           222: 
        !           223: /*
        !           224: 
        !           225:  * utility functions:
        !           226: 
        !           227:  * getclock(buf): get the current date and time and write it into
        !           228: 
        !           229:  * the pointed to buffer in the format "MM/DD/YY hh:mm:ss\r\n"
        !           230: 
        !           231:  *
        !           232: 
        !           233:  * setclock(buf): set the current date and time from the ASCII
        !           234: 
        !           235:  * string pointed to by buf, which must have the same format
        !           236: 
        !           237:  * as that returned by getdate
        !           238: 
        !           239:  */
        !           240: 
        !           241: 
        !           242: 
        !           243: void
        !           244: 
        !           245: getclock(buf)
        !           246: 
        !           247:        char *buf;
        !           248: 
        !           249: {
        !           250: 
        !           251:        int DD, MM, YY, hh, ss, mm;
        !           252: 
        !           253:        unsigned date, time;
        !           254: 
        !           255: 
        !           256: 
        !           257:        date = TGETDATE();
        !           258: 
        !           259:        time = TGETTIME();
        !           260: 
        !           261: 
        !           262: 
        !           263:        DD = date & 31;
        !           264: 
        !           265:        MM = (date >> 5) & 15;
        !           266: 
        !           267:        YY = 80 + ( (date >> 9) & 127 ); if (YY > 99) YY -= 100;
        !           268: 
        !           269: 
        !           270: 
        !           271:        ss = (time & 31) << 1;
        !           272: 
        !           273:        mm = (time >> 5) & 63;
        !           274: 
        !           275:        hh = (time >> 11) & 31;
        !           276: 
        !           277: 
        !           278: 
        !           279:        SPRINTF(buf, "%02d/%02d/%02d %02d:%02d:%02d\r\n", MM, DD, YY,
        !           280: 
        !           281:                hh, mm, ss);
        !           282: 
        !           283: }
        !           284: 
        !           285: 
        !           286: 
        !           287: static int
        !           288: 
        !           289: getint(buf)
        !           290: 
        !           291:        char *buf;
        !           292: 
        !           293: {
        !           294: 
        !           295:        int val = 0;
        !           296: 
        !           297: 
        !           298: 
        !           299:        val = *buf++ - '0';
        !           300: 
        !           301:        val = 10 * val + *buf - '0';
        !           302: 
        !           303:        return val;
        !           304: 
        !           305: }
        !           306: 
        !           307: 
        !           308: 
        !           309: void
        !           310: 
        !           311: setclock(buf)
        !           312: 
        !           313:        char *buf;
        !           314: 
        !           315: {
        !           316: 
        !           317:        int DD, MM, YY, hh, mm, ss;
        !           318: 
        !           319:        unsigned time, date;
        !           320: 
        !           321: 
        !           322: 
        !           323:        MM = getint(buf); buf += 3;
        !           324: 
        !           325:        if (MM < 1 || MM > 12) return;
        !           326: 
        !           327:        DD = getint(buf); buf += 3;
        !           328: 
        !           329:        if (DD < 1 || DD > 31) return;
        !           330: 
        !           331:        YY = getint(buf); buf += 3;
        !           332: 
        !           333:        if (YY < 80 || YY > 99) return;
        !           334: 
        !           335:        hh = getint(buf); buf += 3;
        !           336: 
        !           337:        if (hh < 0 || hh > 23) return;
        !           338: 
        !           339:        mm = getint(buf); buf += 3;
        !           340: 
        !           341:        if (mm < 0 || mm > 59) return;
        !           342: 
        !           343:        ss = getint(buf);
        !           344: 
        !           345:        if (ss < 0 || ss > 59) return;
        !           346: 
        !           347: 
        !           348: 
        !           349:        time = (hh << 11) | (mm << 5) | (ss >> 1);
        !           350: 
        !           351:        date = ((YY - 80) << 9) | (MM << 5) | DD;
        !           352: 
        !           353:        TSETTIME(time);
        !           354: 
        !           355:        TSETDATE(date);
        !           356: 
        !           357: }
        !           358: 
        !           359: 
        !           360: 
        !           361: #define NBYTES 19      /* strlen("DD/MM/YY hh:mm:ss\r\n") */
        !           362: 
        !           363: 
        !           364: 
        !           365: static long
        !           366: 
        !           367: clock_open(f)
        !           368: 
        !           369:        FILEPTR *f;
        !           370: 
        !           371: {
        !           372: 
        !           373:        return 0;
        !           374: 
        !           375: }
        !           376: 
        !           377: 
        !           378: 
        !           379: static long
        !           380: 
        !           381: clock_write(f, buf, bytes)
        !           382: 
        !           383:        FILEPTR *f; char *buf; long bytes;
        !           384: 
        !           385: {
        !           386: 
        !           387:        static char writebuf[NBYTES];
        !           388: 
        !           389:        static int  bufptr = 0;
        !           390: 
        !           391:        long wrote = 0;
        !           392: 
        !           393: 
        !           394: 
        !           395:        while (bytes-- > 0 && bufptr < NBYTES) {
        !           396: 
        !           397: /* ignore CR/LF at beginning of line */
        !           398: 
        !           399:                if (bufptr == 0 && (*buf == '\r' || *buf == '\n'))
        !           400: 
        !           401:                        buf++;
        !           402: 
        !           403:                else
        !           404: 
        !           405:                        writebuf[bufptr++] = *buf++;
        !           406: 
        !           407:                wrote++;
        !           408: 
        !           409:        }
        !           410: 
        !           411: 
        !           412: 
        !           413: /* do we have a complete date now? if so, set the clock */
        !           414: 
        !           415:        if (bufptr == NBYTES) {
        !           416: 
        !           417:                setclock(writebuf);
        !           418: 
        !           419:                bufptr = 0;
        !           420: 
        !           421:        }
        !           422: 
        !           423:        return wrote;
        !           424: 
        !           425: }
        !           426: 
        !           427: 
        !           428: 
        !           429: static long
        !           430: 
        !           431: clock_read(f, buf, bytes)
        !           432: 
        !           433:        FILEPTR *f; char *buf; long bytes;
        !           434: 
        !           435: {
        !           436: 
        !           437: /* SPRINTF will stuff one too many bytes in here (the \0) */
        !           438: 
        !           439:        static char readbuf[NBYTES+1];
        !           440: 
        !           441:        int where;
        !           442: 
        !           443:        long total = 0;
        !           444: 
        !           445: 
        !           446: 
        !           447:        getclock(readbuf);
        !           448: 
        !           449:        while (f->pos < NBYTES) {
        !           450: 
        !           451:                *buf++ = readbuf[f->pos++];
        !           452: 
        !           453:                total++;
        !           454: 
        !           455:        }
        !           456: 
        !           457:        return total;
        !           458: 
        !           459: }
        !           460: 
        !           461: 
        !           462: 
        !           463: static long
        !           464: 
        !           465: clock_lseek(f, where, whence)
        !           466: 
        !           467:        FILEPTR *f; long where; int whence;
        !           468: 
        !           469: {
        !           470: 
        !           471:        long newplace;
        !           472: 
        !           473: 
        !           474: 
        !           475:        switch(whence) {
        !           476: 
        !           477:        case 0:
        !           478: 
        !           479:                newplace = where;
        !           480: 
        !           481:                break;
        !           482: 
        !           483:        case 1:
        !           484: 
        !           485:                newplace = f->pos + where;
        !           486: 
        !           487:                break;
        !           488: 
        !           489:        case 2:
        !           490: 
        !           491:                newplace = (NBYTES-1) - where;
        !           492: 
        !           493:                break;
        !           494: 
        !           495:        }
        !           496: 
        !           497: 
        !           498: 
        !           499:        if (newplace < 0 || newplace >= NBYTES)
        !           500: 
        !           501:                return ERANGE;
        !           502: 
        !           503: 
        !           504: 
        !           505:        f->pos = newplace;
        !           506: 
        !           507:        return newplace;
        !           508: 
        !           509: }
        !           510: 
        !           511: 
        !           512: 
        !           513: static long
        !           514: 
        !           515: clock_ioctl(f, mode, buf)
        !           516: 
        !           517:        FILEPTR *f; int mode; void *buf;
        !           518: 
        !           519: {
        !           520: 
        !           521:        if (mode == FIONREAD || mode == FIONWRITE) {
        !           522: 
        !           523:                *((long *)buf) = (NBYTES-1) - f->pos;
        !           524: 
        !           525:                return 0;
        !           526: 
        !           527:        }
        !           528: 
        !           529:        else
        !           530: 
        !           531:                return EINVFN;
        !           532: 
        !           533: }
        !           534: 
        !           535: 
        !           536: 
        !           537: static long
        !           538: 
        !           539: clock_datime(f, timeptr, rwflag)
        !           540: 
        !           541:        FILEPTR *f;
        !           542: 
        !           543:        word *timeptr;
        !           544: 
        !           545:        int rwflag;
        !           546: 
        !           547: {
        !           548: 
        !           549:        if (rwflag)
        !           550: 
        !           551:                return EACCDN;
        !           552: 
        !           553:        *timeptr++ = TGETTIME();
        !           554: 
        !           555:        *timeptr = TGETDATE();
        !           556: 
        !           557:        return 0;
        !           558: 
        !           559: }
        !           560: 
        !           561: 
        !           562: 
        !           563: static long
        !           564: 
        !           565: clock_close(f)
        !           566: 
        !           567:        FILEPTR *f;
        !           568: 
        !           569: {
        !           570: 
        !           571:        return 0;
        !           572: 
        !           573: }
        !           574: 
        !           575: 
        !           576: 
        !           577: static long
        !           578: 
        !           579: clock_select()
        !           580: 
        !           581: {
        !           582: 
        !           583:        return 1;       /* we're always ready for I/O */
        !           584: 
        !           585: }
        !           586: 
        !           587: 
        !           588: 
        !           589: static void
        !           590: 
        !           591: clock_unselect()
        !           592: 
        !           593: {
        !           594: 
        !           595:        /* nothing for us to do here */
        !           596: 
        !           597: }
        !           598: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.