Annotation of MiNT/doc/clockdev.c, revision 1.1.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.