home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2425 < prev    next >
Internet Message Format  |  1990-12-29  |  25KB

  1. From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
  2. Newsgroups: alt.sources
  3. Subject: cmostime3 part 02/02 (was Re: Program to set clock to NBS time)
  4. Message-ID: <277@n4hgf.Mt-Park.GA.US>
  5. Date: 29 Dec 90 03:09:29 GMT
  6.  
  7. ---- Cut Here and unpack ----
  8. #!/bin/sh
  9. # this is cmostime3.02 (part 2 of cmostime3)
  10. # do not concatenate these parts, unpack them in order with /bin/sh
  11. # file NBSsetclk.c continued
  12. #
  13. touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
  14. if [ -s /tmp/s3_touch$$ ]
  15. then
  16.     TOUCH=can
  17. else
  18.     TOUCH=cannot
  19. fi
  20. rm -f /tmp/s3_touch$$
  21. CurArch=2
  22. if test ! -r s3_seq_.tmp
  23. then echo "Please unpack part 1 first!"
  24.      exit 1; fi
  25. ( read Scheck
  26.   if test "$Scheck" != $CurArch
  27.   then echo "Please unpack part $Scheck next!"
  28.        exit 1;
  29.   else exit 0; fi
  30. ) < s3_seq_.tmp || exit 1
  31. echo "x - Continuing file NBSsetclk.c"
  32. sed 's/^X//' << 'SHAR_EOF' >> NBSsetclk.c
  33. X    lclose()
  34. X------------------------------------------------------------------------*/
  35. Xvoid
  36. Xlclose()
  37. X{
  38. X    if(Liofd < 0)
  39. X        return;
  40. X    ioctl(Liofd,(int)TCGETA,(char *)&Ltermio); /* save initial state */
  41. X    Ltermio.c_cflag |= HUPCL;
  42. X    ioctl(Liofd,(int)TCSETA,(char *)&Ltermio);
  43. X    close(Liofd);
  44. X    Liofd = -1;
  45. X    unlock_tty();        /* kill lock file */
  46. X
  47. X}    /* end of lclose */
  48. X
  49. X/*+-------------------------------------------------------------------------
  50. X    ltoggle_dtr()
  51. X--------------------------------------------------------------------------*/
  52. Xvoid
  53. Xltoggle_dtr()
  54. X{
  55. X    lclose();
  56. X    nap(300L);
  57. X    lopen();
  58. X    ioctl(Liofd,TCSETA,(char *)&Ltermio);
  59. X    nap(100L);
  60. X}    /* end of ltoggle_dtr */
  61. X
  62. X/*+-------------------------------------------------------------------------
  63. X    hayes_modem_init(cmd)
  64. X--------------------------------------------------------------------------*/
  65. Xhayes_modem_init(cmd)
  66. Xchar *cmd;
  67. X{
  68. Xregister char *cptr;
  69. Xint retry_count = 0;
  70. Xint itmp;
  71. Xchar s32[32];
  72. X
  73. XLRWT    lr;
  74. X
  75. X    while(!Lmodem_already_init)
  76. X    {
  77. X        lkill_buf();
  78. X        lputs_paced(20,"ATQ0V1E1\r");
  79. X        itmp = 0;
  80. X        while(itmp != '\r')
  81. X        {
  82. X            if((itmp = lgetc_timeout(300L)) < 0)
  83. X            {
  84. X                if(retry_count > 3)
  85. X                    return(-1);
  86. X                retry_count++;
  87. X                ltoggle_dtr();
  88. X                break;
  89. X            }
  90. X        }
  91. X        if(itmp < 0)
  92. X            continue;
  93. X
  94. X        lr.to1 = 300L;
  95. X        lr.to2 = 100L;
  96. X        lr.raw_flag = 0;
  97. X        lr.buffer = s32;
  98. X        lr.bufsize = sizeof(s32);
  99. X        fflush(se);
  100. X        lgets_timeout(&lr);
  101. X        if(strcmp(s32,"OK"))
  102. X        {
  103. X            if(retry_count > 3)
  104. X                return(-1);
  105. X            retry_count++;
  106. X                ltoggle_dtr();
  107. X            continue;
  108. X        }
  109. X        nap(300L);
  110. X        Lmodem_already_init = 1;
  111. X    }
  112. X
  113. X    return(0);
  114. X
  115. X}    /* end of hayes_modem_init */
  116. X
  117. X/*+-------------------------------------------------------------------------
  118. X    hayes_send_cmd(cmd)
  119. X--------------------------------------------------------------------------*/
  120. Xhayes_send_cmd(cmd)
  121. Xchar *cmd;
  122. X{
  123. Xregister char *cptr;
  124. Xint itmp;
  125. Xchar s32[32];
  126. X
  127. X    hayes_modem_init();
  128. X    cptr = cmd;
  129. X    while(*cptr)
  130. X    {
  131. X        lputc(*cptr++);
  132. X        if(lgetc_timeout(500L) < 0)
  133. X            return(-1);
  134. X    }
  135. X    lputc('\r');
  136. X    if(lgetc_timeout(500L) < 0)
  137. X        return(-1);
  138. X    return(0);
  139. X
  140. X}    /* end of hayes_send_cmd */
  141. X
  142. X/*+-----------------------------------------------------------------------
  143. X    hayes_dial()
  144. Xreturns 1 on success (CONNECT), 
  145. X        0 if failure to connect
  146. X        -1 if cannot talk to modem
  147. X------------------------------------------------------------------------*/
  148. Xint
  149. Xhayes_dial()
  150. X{
  151. Xregister int itmp;
  152. Xchar s128[128];
  153. Xint rtn_code = -1;    /* assume fail, CONNECT will chg to zero */
  154. Xint s7;
  155. XLRWT    lr;
  156. X
  157. X    s7 = 30;
  158. X    strcpy(s128,"ATV1E1S11=45DT" );
  159. X    strcat(s128,Ltelno);
  160. X
  161. X    if(itmp = hayes_send_cmd(s128))
  162. X        return(itmp);
  163. X
  164. X/* some modems (ahem, the older Hayes 2400) do not accurately honor S7 */
  165. X    lr.to1 = s7 * 2 * 1000L;
  166. X    lr.to2 = 100L;
  167. X    lr.raw_flag = 0;
  168. X    lr.buffer = s128;
  169. X    lr.bufsize = sizeof(s128);
  170. X    ff(se,"dialing %s ... INT to abort ... ",Ltelno);
  171. X    fflush(se);
  172. X    lgets_timeout(&lr);
  173. X    if(lr.count)
  174. X        ff(se,"%s\n",s128);
  175. X    if(strncmp(s128,"CONNECT",7) == 0)
  176. X        return(1);
  177. X    return(0);
  178. X
  179. X}    /* end of hayes_dial */
  180. X
  181. X/*+-------------------------------------------------------------------------
  182. X    main(argc,argv,envp)
  183. X
  184. X  main() program forks to create rcvr process; then main()
  185. X  becomes the xmtr process
  186. X------------------------------------------------------------------------*/
  187. Xmain(argc,argv,envp)
  188. Xint argc;
  189. Xchar **argv;
  190. Xchar **envp;
  191. X{
  192. Xchar *cptr;
  193. Xint iargv;
  194. Xint swchar;
  195. Xint itmp;
  196. XLRWT lr;
  197. Xchar rd_buf[64];
  198. Xlong now;
  199. Xlong julian;
  200. Xlong time_at_connect;
  201. Xint day_of_year,year,month,day,hour,min,sec;
  202. Xint fdcmos;
  203. Xint have_time = 0;
  204. Xint max_tries;
  205. Xstruct tm *lt;
  206. Xstruct tm *gmtime();
  207. Xstruct tm *localtime();
  208. Xextern char *optarg;
  209. X
  210. X    setbuf(stderr,NULL);
  211. X    setbuf(stdout,NULL);
  212. X
  213. X/* init line variables */
  214. X    strcpy(Lline,"/dev/tty1a");
  215. X    strcpy(Ltelno,"1(202)653-0351");
  216. X    Liofd = -1;
  217. X    Lbaud = 1200;
  218. X    Lparity = 0;
  219. X
  220. X    if(argc < 2)
  221. X        usage();
  222. X
  223. X    if((argc == 2) && (!strcmp(argv[1],"-")))
  224. X        ;
  225. X    else
  226. X    {
  227. X        while((swchar = getopt(argc,argv,"eonb:t:l:")) != -1)
  228. X        {
  229. X            switch(swchar)
  230. X            {
  231. X                case 'e': Lparity = 'e'; break;
  232. X                case 'o': Lparity = 'o'; break;
  233. X                case 'n': Lparity =  0 ; break;
  234. X                case 'b': Lbaud = atoi(optarg); break;
  235. X                case 't': strcpy(Ltelno,optarg); break;
  236. X                case 'l': strcpy(Lline,optarg); break;
  237. X                default:  usage();
  238. X            }
  239. X        }
  240. X    }
  241. X
  242. X    uid = getuid();
  243. X    euid = geteuid();
  244. X    if((euid == 0) || (uid == 0))    /* if root running or prog text ... */
  245. X        nice(-40);
  246. X    else
  247. X    {
  248. X        ff(se,"must be root\n");
  249. X        exit(252);
  250. X    }
  251. X
  252. X    if((fdcmos = open(cmos,O_RDWR,0)) < 0)
  253. X    {
  254. X        perror(cmos);
  255. X        exit(251);
  256. X    }
  257. X
  258. X    signal(SIGHUP,hangup);
  259. X    signal(SIGQUIT,hangup);
  260. X    signal(SIGINT,hangup);
  261. X    signal(SIGTERM,hangup);
  262. X
  263. X    ff(se,"using %s, ",Lline);
  264. X    if(itmp = lopen())
  265. X    {
  266. X        switch(itmp)
  267. X        {
  268. X            case LOPEN_INVALID:
  269. X                ff(se,"invalid line name\n"); break;
  270. X            case LOPEN_UNKPID:
  271. X                ff(se,"unknown pid is using line\n"); break;
  272. X            case LOPEN_LCKERR:
  273. X                ff(se,"lock file error\n"); break;
  274. X            case LOPEN_NODEV:
  275. X                ff(se,"line does not exist\n"); break;
  276. X            case LOPEN_ALREADY:
  277. X                ff(se,"line already open\n"); break;
  278. X            case LOPEN_OPNFAIL:
  279. X                ff(se,"line open error\n"); break;
  280. X            default:
  281. X                ff(se,"pid %d using line\n",itmp); break;
  282. X        }
  283. X        exit(250);
  284. X    }
  285. X
  286. X    lr.to1 = 1100L;
  287. X    lr.to2 =  100L;
  288. X    lr.raw_flag = 0;    /* full raw read */
  289. X    lr.buffer = rd_buf;
  290. X    lr.bufsize = sizeof(rd_buf);
  291. X
  292. X/* spend money on long distance call ... only time freaks can understand */
  293. X    if(!hayes_dial())
  294. X    {
  295. X        fputs("\ndial failed\n",se);
  296. X        hangup(255);
  297. X    }
  298. X
  299. X    time_at_connect = time((long *)0);
  300. X
  301. X    max_tries = 40;        /* 40 sec max connect time (charged for 1 min anyway) */
  302. X    while(!have_time)
  303. X    {
  304. X        for(itmp = 0; itmp < 30; itmp++)        /* look for asterisk */
  305. X        {
  306. X            if(lgetc_timeout(500L) == NBSTONE)
  307. X                break;
  308. X        }
  309. X
  310. X        lgets_timeout(&lr);        /* get date/time string */
  311. X
  312. X        if(sscanf(lr.buffer,NBSFMT,&julian,&day_of_year,&hour,&min,&sec) != 5)
  313. X        {
  314. X            ff(se,"garbled result: '%s'  ",lr.buffer);
  315. X            if(--max_tries)
  316. X            {
  317. X                puts("... retrying");
  318. X                continue;
  319. X            }
  320. X            puts("... aborting");
  321. X            break;        /* too many retries ... BAAAAD line condx */
  322. X        }
  323. X        have_time = 1;
  324. X    }
  325. X
  326. X    lclose();
  327. X
  328. X/* no longer spending money */
  329. X
  330. X    fprintf(stdout,"Connect time %ld second(s)\n",
  331. X        time((long *)0) - time_at_connect);
  332. X
  333. X    if(have_time)
  334. X    {
  335. X        now = (((julian - EPOCH) * 24 + hour) * 60 + min) * 60 + sec;
  336. X        now--; /* off by one */
  337. X        if(stime(&now) < 0)
  338. X        {
  339. X            perror("stime");
  340. X            exit(249);
  341. X        }
  342. X        fputs("Time retrieved from standard: ",stdout);
  343. X        fputs(ctime(&now),stdout);
  344. X        time(&now);
  345. X        get_clock(fdcmos,&year,&month,&day,&hour,&min,&sec);
  346. X        printf("cmos time before setting: %02d/%02d/%04d %02d:%02d:%02d %s\n",
  347. X            month+1,day+1,year,hour,min,sec,
  348. X#if defined(M_UNIX)
  349. X            "UTC"
  350. X#else
  351. X            "local"
  352. X#endif
  353. X            );
  354. X        fputs("           after setting: ",stdout);
  355. X#if defined(M_UNIX)
  356. X        lt = gmtime(&now);
  357. X#else
  358. X        lt = localtime(&now);
  359. X#endif
  360. X        set_clock(fdcmos,lt->tm_year,lt->tm_mon,lt->tm_mday,
  361. X                lt->tm_hour,lt->tm_min,lt->tm_sec);
  362. X        get_clock(fdcmos,&year,&month,&day,&hour,&min,&sec);
  363. X        printf("%02d/%02d/%04d %02d:%02d:%02d %s\n",
  364. X            month+1,day+1,year,hour,min,sec,
  365. X#if defined(M_UNIX)
  366. X            "UTC"
  367. X#else
  368. X            "local"
  369. X#endif
  370. X            );
  371. X        exit(0);
  372. X    }
  373. X    else
  374. X    {
  375. X        puts("Did not get time ... sorry");
  376. X        exit(254);
  377. X    }
  378. X
  379. X}    /* end of main */
  380. X/* end of NBSsetclk.c */
  381. X
  382. SHAR_EOF
  383. echo "File NBSsetclk.c is complete"
  384. chmod 0644 NBSsetclk.c || echo "restore of NBSsetclk.c fails"
  385. if [ $TOUCH = can ]
  386. then
  387.     touch -m 0105205390 NBSsetclk.c
  388. fi
  389. echo "x - extracting at_cmos.h (Text)"
  390. sed 's/^X//' << 'SHAR_EOF' > at_cmos.h &&
  391. X/* CHK=0x9C84 */
  392. X/* vi: set tabstop=4 shiftwidth=4: */
  393. X/*+-------------------------------------------------------------------------
  394. X    at_cmos.h -- AT 286/386 cmos ram definitions (some problems in here)
  395. X    ...!gatech!kd4nc!n4hgf!wht
  396. X--------------------------------------------------------------------------*/
  397. X/*+:EDITS:*/
  398. X/*:02-03-1989-19:50-wht-386 release */
  399. X/*:07-23-1988-19:06-wht-release */
  400. X/*:07-23-1988-15:12-wht-break out from cmos_disp.c */
  401. X
  402. X#ifndef uchar
  403. X#define uchar    unsigned char
  404. X#endif
  405. X
  406. Xtypedef struct at_cmos
  407. X{
  408. X    uchar    sec;
  409. X    uchar    sec_alarm;
  410. X    uchar    min;
  411. X    uchar    min_alarm;
  412. X    uchar    hour;
  413. X    uchar    hour_alarm;
  414. X    uchar    day;            /* 0-6 */
  415. X    uchar    date;            /* 1-31 */
  416. X    uchar    month;
  417. X    uchar    year;
  418. X    uchar    srA;            /* status register A */
  419. X    uchar    srB;            /* status register B */
  420. X    uchar    srC;            /* status register C */
  421. X    uchar    srD;            /* status register D */
  422. X
  423. X    uchar    dsb;            /* diagnostic status byte */
  424. X    uchar    ssb;            /* shutdown status byte */
  425. X    uchar    ddtb;            /* diskette drive type byte */
  426. X    uchar    rsvd11;            /* byte at address 0x11 reserved */
  427. X    uchar    fdtb;            /* fixed disk type byte */
  428. X    uchar    rsvd13;            /* byte at address 0x13 reserved */
  429. X    uchar    equip;            /* equipment byte */
  430. X
  431. X/* base size of memory = (contents(byte 0x16) << 8) + contents(byte 0x15) */
  432. X    uchar    base_low;        /* low base memory byte */
  433. X    uchar    base_high;        /* hi base memory byte */
  434. X    
  435. X/* memory expansion size similar calculation (0x17 low order byte, 0x18 hi) */
  436. X    uchar    expand_low;
  437. X    uchar    expand_high;
  438. X
  439. X/* reserved bytes */
  440. X    uchar    rsvd19_2D[ 0x2D - 0x19 + 1 ];
  441. X
  442. X/* checksum (on bytes in addresses 0x10 - 0x20) */
  443. X    uchar    cksum_high;        /* tech ref sez these bytes in other order */
  444. X    uchar    cksum_low;
  445. X
  446. X/* > 1 mb expansion size (in cmos ram addresses 0x30-31) */
  447. X    uchar    exp2_low;
  448. X    uchar    exp2_high;
  449. X
  450. X    uchar    century;        /* date century byte */
  451. X    uchar    info_flag;        /* see IF_ bits below */
  452. X
  453. X    uchar    rsvd34_3F[ 0x3F - 0x34 + 1];
  454. X
  455. X} AT_CMOS;
  456. X
  457. Xunion cmos_union
  458. X{
  459. X    uchar        a[64];
  460. X    AT_CMOS        s;
  461. X};
  462. X
  463. X/*+-----------------------------------------------------------------------
  464. X    AT Real Time Clock Status Register bit assignments
  465. X------------------------------------------------------------------------*/
  466. X#define SRA_UIP        0x80    /* update in progress */
  467. X#define SRA_DV22    0x70    /* 3-bit time-base divider */
  468. X#define SRA_DVOUT    0x0F    /* 4-bit time-base divider output freq */
  469. X
  470. X#define SRB_SET        0x80    /* when 1, no tick advance (set mode) */
  471. X#define SRB_PIE        0x40    /* when 1, periodic interrupt */
  472. X#define SRB_AIE        0x20    /* when 1, alarm enabled */
  473. X#define SRB_UIE        0x10    /* enabled update-ended interrupt */
  474. X#define SRB_SQWE    0x08    /* square wave enabled */
  475. X#define SRB_DM        0x04    /* data mode 1==binary, 0==BCD */
  476. X#define SRB_24HR    0x02    /* 1==24 hour mode, 0==12 hour mode */
  477. X#define SRB_DSE        0x01    /* daylight savings time enabled */
  478. X
  479. X#define SRC_IRQF    0x80
  480. X#define SRC_PF        0x40
  481. X#define SRC_AF        0x20
  482. X#define SRC_UF        0x10
  483. X                            /* remaining bits in status register C reserved */
  484. X
  485. X#define SRD_VRB        0x80    /* valid ram (==0 when power has been lost)
  486. X                             * remaining bits in status register D reserved */
  487. X
  488. X/*+-----------------------------------------------------------------------
  489. X    Diagnostic Status Byte
  490. X------------------------------------------------------------------------*/
  491. X#define DSB_RTLOST    0x80    /* ==1 if real time clock chip lost power */
  492. X#define DSB_CSI        0x40    /* checksum status indicator == 1 if bad */
  493. X#define DSB_ICI        0x20    /* invalid configuration information (if ==1) */
  494. X#define DSB_MSM        0x10    /* memory size miscompare (==1 if different) */
  495. X#define DSB_HDBAD    0x08    /* fixed disk bad if == 1 */
  496. X#define DSB_TSI        0x04    /* time status indicator (==1 if time bad) */
  497. X
  498. X#ifdef NEEDED    /* not under XENIX! */
  499. X#define        cmos_ctrl_dev        0x70        /* cmos address control port */
  500. X#define        cmos_data_dev        0x71        /* cmos data i/o port */
  501. X#endif
  502. X
  503. SHAR_EOF
  504. chmod 0644 at_cmos.h || echo "restore of at_cmos.h fails"
  505. if [ $TOUCH = can ]
  506. then
  507.     touch -m 0105205390 at_cmos.h
  508. fi
  509. echo "x - extracting cmos_disp.c (Text)"
  510. sed 's/^X//' << 'SHAR_EOF' > cmos_disp.c &&
  511. X/* CHK=0x373F */
  512. X/* vi: set tabstop=4 shiftwidth=4: */
  513. X/*+-------------------------------------------------------------------------
  514. X    cmos_disp.c -- interprets /dev/cmos 286/386 AT CMOS ram
  515. X    ...!gatech!kd4nc!n4hgf!wht
  516. X--------------------------------------------------------------------------*/
  517. X/*+:EDITS:*/
  518. X/*:02-03-1989-19:50-wht-386 release */
  519. X/*:02-03-1989-19:28-wht-fix bad itmp assigned,used in same func call */
  520. X/*:07-23-1988-19:05-wht-release */
  521. X/*:07-23-1988-14:17-wht-BIG face life on old program */
  522. X
  523. X#include <stdio.h>
  524. X#include <fcntl.h>
  525. X#include "at_cmos.h"
  526. X#include "dev_cmos.h"
  527. X
  528. Xunion cmos_union    cmos;
  529. X
  530. Xchar    *day_of_week[] =
  531. X{
  532. X    "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
  533. X};
  534. X
  535. Xchar    *cmosname = "/dev/cmos";
  536. X
  537. Xmain(argc,argv)
  538. Xint argc;
  539. Xchar    **argv;
  540. X{
  541. Xregister int icmos;
  542. Xregister int itmp;
  543. Xchar    *format;
  544. Xint fdcmos;
  545. Xint clock_bcd_mode;            /* true if clock in bcd mode */
  546. Xunsigned short calc_cksum;        /* calculated checksum */
  547. Xunsigned short cmos_cksum;        /* checksum in cmos */
  548. X
  549. X    if((fdcmos = open(cmosname,O_RDONLY)) < 0)
  550. X    {
  551. X        perror(cmosname);
  552. X        exit(1);
  553. X    }
  554. X    get_cmos(fdcmos,&cmos);
  555. X    close(fdcmos);
  556. X
  557. X    for(icmos = 0; icmos < 64; icmos++)
  558. X    {
  559. X        if(icmos % 16 == 0)
  560. X            printf("\n %02x:  ",icmos);
  561. X        printf("%02x ",cmos.a[icmos]);
  562. X        if(icmos % 4 == 3)
  563. X            printf(" ");
  564. X    }
  565. X    printf("\n\n");
  566. X
  567. X    clock_bcd_mode = (cmos.s.srB & SRB_DM) ? 0 : 1;
  568. X
  569. X    itmp = cmos.s.base_high << 8 | cmos.s.base_low;
  570. X    printf("Base memory:       %6dk  (%8lx bytes hex)\n",
  571. X                    itmp,(long)itmp * (long)1024);
  572. X
  573. X    itmp = cmos.s.expand_high << 8 | cmos.s.expand_low;
  574. X    printf("Expansion memory:  %6dk  (%8lx bytes hex)\n",
  575. X                    itmp,(long)itmp * (long)1024);
  576. X
  577. X    itmp = cmos.s.exp2_high << 8 | cmos.s.exp2_low;
  578. X    printf("Memory above 1MB:  %6dk  (%8lx bytes hex)\n",
  579. X                    itmp,(long)itmp * (long)1024);
  580. X
  581. X    printf("\n");
  582. X
  583. X    printf("Diag status byte: %02x  Shutdown status byte: %02x\n",
  584. X                    cmos.s.dsb,cmos.s.ssb);
  585. X
  586. X    if(cmos.s.dsb)
  587. X    {
  588. X        itmp = cmos.s.dsb;
  589. X        printf("  Diagnostic Status Byte (DSB) says:\n");
  590. X        if(itmp & 0x80)
  591. X            printf("      Real-time clock has lost power.\n");
  592. X        if(itmp & 0x40)
  593. X            printf("      Bad configuration record checksum.\n");
  594. X        if(itmp & 0x20)
  595. X            printf("      Incorrect configuration information.\n");
  596. X        if(itmp & 0x10)
  597. X            printf("      Memory size miscompare.\n");
  598. X        if(itmp & 0x08)
  599. X            printf("      Fixed disk adapter failed init.\n");
  600. X        if(itmp & 0x04)
  601. X            printf("      Time is invalid.\n");
  602. X        printf("\n");
  603. X    }
  604. X
  605. X    printf("Clock: %d-hour mode, %s time, alarm %s, %s mode\n",
  606. X                    (cmos.s.srB & SRB_24HR) ? 24 : 12,
  607. X                    (cmos.s.srB & SRB_DSE) ? "daylight" : "standard",
  608. X                    (cmos.s.srB & SRB_AIE) ? "enabled" : "disabled",
  609. X                    (clock_bcd_mode) ? "bcd" : "hex");
  610. X
  611. X    if(clock_bcd_mode)
  612. X        format = "Date: %02x-%02x-%02x%02x  ";
  613. X    else
  614. X        format = "Date: %02d-%02d-%02d%02d  ";
  615. X    printf(format,cmos.s.month,cmos.s.date,cmos.s.century,cmos.s.year);
  616. X
  617. X    if(clock_bcd_mode)
  618. X        format = "Time: %02x:%02x:%02x  Alarm: %02x:%02x:%02x\n";
  619. X    else
  620. X        format = "Time: %02d:%02d:%02d  Alarm: %02d:%02d:%02d\n";
  621. X    printf(format,cmos.s.hour,cmos.s.min,cmos.s.sec,
  622. X        cmos.s.hour_alarm,cmos.s.min_alarm,cmos.s.sec_alarm);
  623. X
  624. X    printf("Number of diskette drives: %d   Math coprocessor %s\n",
  625. X                    (int)(cmos.s.equip & 0xC0) >> 6,
  626. X                    (cmos.s.equip & 0x02) ? "present" : "not present"
  627. X                    );
  628. X
  629. X    printf("Primary display:  ");
  630. X    switch( itmp = (cmos.s.equip & 0x30) >> 4)
  631. X    {
  632. X        case 1:
  633. X            format = "Color/Graphics 40 column\n";
  634. X            break;
  635. X        case 2:
  636. X            format = "Color/Graphics 80 column\n";
  637. X            break;
  638. X        case 3:
  639. X            format = "Monochrome display\n";
  640. X            break;
  641. X        default:
  642. X            format = "unknown type: %d\n";
  643. X            break;
  644. X    }
  645. X    printf(format,itmp);
  646. X
  647. X/* tech ref doesn't say: empirically determined checksum algorithm (correct?) */
  648. X    calc_cksum = 0;
  649. X    for(itmp = 0x10; itmp < 0x21; itmp++)
  650. X        calc_cksum += cmos.a[itmp];
  651. X    calc_cksum++;
  652. X
  653. X    cmos_cksum = (cmos.s.cksum_high << 8) | cmos.s.cksum_low;
  654. X    printf("Checksum: in ram: %04x  calculated: %04x\n",cmos_cksum,calc_cksum);
  655. X
  656. X    exit(0);    /* for now */
  657. X    
  658. X}    /* end of main() */
  659. X
  660. SHAR_EOF
  661. chmod 0644 cmos_disp.c || echo "restore of cmos_disp.c fails"
  662. if [ $TOUCH = can ]
  663. then
  664.     touch -m 0105205390 cmos_disp.c
  665. fi
  666. echo "x - extracting dev_cmos.c (Text)"
  667. sed 's/^X//' << 'SHAR_EOF' > dev_cmos.c &&
  668. X/* CHK=0x1DB0 */
  669. X/* vi: set tabstop=4 shiftwidth=4: */
  670. X/*+-------------------------------------------------------------------------
  671. X    dev_cmos.c -- XENIX /dev/cmos routines
  672. X    ...!gatech!kd4nc!n4hgf!wht
  673. X
  674. X  Defined functions:
  675. X    bcdch_to_uchar(bcdch)
  676. X    get_clock(fdcmos,year,month,day,hour,min,sec)
  677. X    get_cmos(fdcmos,cmosbuf)
  678. X    set_clock(fdcmos,year,month,day,hour,min,sec)
  679. X    uchar_to_bcdch(uch)
  680. X
  681. X--------------------------------------------------------------------------*/
  682. X/*+:EDITS:*/
  683. X/*:02-03-1989-19:50-wht-386 release */
  684. X/*:07-23-1988-19:06-wht-release */
  685. X/*:07-23-1988-13:53-wht-creation */
  686. X
  687. X#include "at_cmos.h"
  688. X#include "dev_cmos.h"
  689. X
  690. Xlong seek(int,long,int);
  691. Xint read(int,char *,int);
  692. X
  693. Xunion cmos_union cu;
  694. X
  695. X#define SEEKPOS(elem)    ((long)((char *)&cu.s.elem - (char *)&cu))
  696. X
  697. X/*+-------------------------------------------------------------------------
  698. X    bcdch_to_uchar(bcdch) -- convert two-nibble bcd to binary
  699. X--------------------------------------------------------------------------*/
  700. Xunsigned char
  701. Xbcdch_to_uchar(bcdch)
  702. Xunsigned char bcdch;
  703. X{
  704. X    return((((bcdch & 0xF0) >> 4) * 10) + (bcdch & 0x0F));
  705. X}    /* end of bcdch_to_uchar */
  706. X
  707. X/*+-------------------------------------------------------------------------
  708. X    uchar_to_bcdch(uch) -- convert binary to two-nibble bcd
  709. X--------------------------------------------------------------------------*/
  710. Xunsigned char
  711. Xuchar_to_bcdch(uch)
  712. Xunsigned char uch;
  713. X{
  714. X    return(((uch / 10) << 4) | (uch % 10));
  715. X}    /* end of uchar_to_bcdch */
  716. X
  717. X/*+-------------------------------------------------------------------------
  718. X    get_cmos(fdcmos,cmosbuf)
  719. X--------------------------------------------------------------------------*/
  720. Xvoid
  721. Xget_cmos(fdcmos,cmosbuf)
  722. Xint fdcmos;
  723. Xunion cmos_union *cmosbuf;
  724. X{
  725. Xunsigned int wait_counter;
  726. Xunsigned char stat_reg_A;
  727. X
  728. X/* check for clock update in progress and wait til done */
  729. X    wait_counter = 32768;
  730. X    while(1)
  731. X    {
  732. X        if(--wait_counter == 0)
  733. X        {
  734. X            puts("/dev/cmos: clock update in progress for too long");
  735. X            exit(200);
  736. X        }
  737. X        
  738. X        lseek(fdcmos,SEEKPOS(srA),0);        /* position to status register A */
  739. X        read(fdcmos,&stat_reg_A,1);
  740. X        if(!(stat_reg_A & SRA_UIP))            /* check update bit */
  741. X            break;                            /* and break out of loop if not */
  742. X    }
  743. X
  744. X/* read the cmos ram */
  745. X    lseek(fdcmos,0L,0);
  746. X    read(fdcmos,(char *)cmosbuf,sizeof(AT_CMOS));
  747. X
  748. X}    /* end of get_cmos */
  749. X
  750. X/*+-------------------------------------------------------------------------
  751. X    get_clock(fdcmos,year,month,day,hour,min,sec) -- read /dev/cmos clock
  752. X
  753. Xfdcmos open fd to /dev/cmos
  754. Xreturn values:
  755. Xyear is full year (e.g., 1988)
  756. Xmonth is 0-11
  757. Xday is 0-30
  758. Xhour is 0-23
  759. Xmin is 0-59
  760. X--------------------------------------------------------------------------*/
  761. Xvoid
  762. Xget_clock(fdcmos,year,month,day,hour,min,sec)
  763. Xint fdcmos;
  764. Xint *year;
  765. Xint *month;
  766. Xint *day;
  767. Xint *hour;
  768. Xint *min;
  769. Xint *sec;
  770. X{
  771. X    get_cmos(fdcmos,&cu);
  772. X
  773. X    *year  = (int)bcdch_to_uchar(cu.s.year) + 1900;
  774. X    *month = (int)bcdch_to_uchar(cu.s.month) - 1;
  775. X    *day   = (int)bcdch_to_uchar(cu.s.date) - 1;
  776. X    *hour  = (int)bcdch_to_uchar(cu.s.hour);
  777. X    *min   = (int)bcdch_to_uchar(cu.s.min);
  778. X    *sec   = (int)bcdch_to_uchar(cu.s.sec);
  779. X
  780. X}    /* end of get_clock */
  781. X
  782. X/*+-------------------------------------------------------------------------
  783. X    set_clock(fdcmos,year,month,day,hour,min,sec) -- write /dev/cmos clock
  784. Xfdcmos open fd to /dev/cmos
  785. Xother values: as returned by localtime()
  786. X--------------------------------------------------------------------------*/
  787. Xvoid
  788. Xset_clock(fdcmos,year,month,day,hour,min,sec)
  789. Xint fdcmos;
  790. Xint year;
  791. Xint month;
  792. Xint day;
  793. Xint hour;
  794. Xint min;
  795. X{
  796. Xunsigned char stat_reg_B;
  797. Xunsigned char wchar;
  798. X
  799. X    month++;            /* month to 1-n */
  800. X    year %= 100;        /* think ahead (ha) */
  801. X
  802. X/* set no tick advance */
  803. X    lseek(fdcmos,SEEKPOS(srB),0);
  804. X    read(fdcmos,&stat_reg_B,1);        /* get current value */
  805. X    stat_reg_B |= SRB_SET;
  806. X    lseek(fdcmos,SEEKPOS(srB),0);
  807. X    write(fdcmos,&stat_reg_B,1);    /* plug new value */
  808. X
  809. X/* set clock */
  810. X    wchar = uchar_to_bcdch((uchar)year);
  811. X    lseek(fdcmos,SEEKPOS(year),0);
  812. X    write(fdcmos,&wchar,1);
  813. X
  814. X    wchar = uchar_to_bcdch((uchar)month);
  815. X    lseek(fdcmos,SEEKPOS(month),0);
  816. X    write(fdcmos,&wchar,1);
  817. X
  818. X    wchar = uchar_to_bcdch((uchar)day);
  819. X    lseek(fdcmos,SEEKPOS(date),0);
  820. X    write(fdcmos,&wchar,1);
  821. X
  822. X    wchar = uchar_to_bcdch((uchar)hour);
  823. X    lseek(fdcmos,SEEKPOS(hour),0);
  824. X    write(fdcmos,&wchar,1);
  825. X
  826. X    wchar = uchar_to_bcdch((uchar)min);
  827. X    lseek(fdcmos,SEEKPOS(min),0);
  828. X    write(fdcmos,&wchar,1);
  829. X
  830. X    wchar = uchar_to_bcdch((uchar)sec);
  831. X    lseek(fdcmos,SEEKPOS(sec),0);
  832. X    write(fdcmos,&wchar,1);
  833. X    
  834. X/* set no tick advance */
  835. X    lseek(fdcmos,SEEKPOS(srB),0);
  836. X    stat_reg_B &= ~SRB_SET;
  837. X    write(fdcmos,&stat_reg_B,1);    /* plug new value */
  838. X
  839. X}    /* end of set_clock */
  840. X
  841. SHAR_EOF
  842. chmod 0644 dev_cmos.c || echo "restore of dev_cmos.c fails"
  843. if [ $TOUCH = can ]
  844. then
  845.     touch -m 0105205490 dev_cmos.c
  846. fi
  847. echo "x - extracting dev_cmos.h (Text)"
  848. sed 's/^X//' << 'SHAR_EOF' > dev_cmos.h &&
  849. X/* CHK=0xB3E6 */
  850. X/* vi: set tabstop=4 shiftwidth=4: */
  851. X/*+-------------------------------------------------------------------------
  852. X    dev_cmos.h -- prototypes for dev_cmos.c functions
  853. X    ...!gatech!kd4nc!n4hgf!wht
  854. X--------------------------------------------------------------------------*/
  855. X/*+:EDITS:*/
  856. X/*:02-03-1989-19:50-wht-386 release */
  857. X/*:07-23-1988-19:07-wht-release */
  858. X/*:07-23-1988-13:55-wht-creation */
  859. X
  860. Xunsigned char bcdch_to_uchar(unsigned char );
  861. Xunsigned char uchar_to_bcdch(unsigned char );
  862. Xvoid get_cmos(int ,union cmos_union  *);
  863. Xvoid get_clock(int ,int  *,int  *,int  *,int  *,int  *,int  *);
  864. Xvoid set_clock(int ,int ,int ,int ,int ,int ,int );
  865. SHAR_EOF
  866. chmod 0644 dev_cmos.h || echo "restore of dev_cmos.h fails"
  867. if [ $TOUCH = can ]
  868. then
  869.     touch -m 0105205490 dev_cmos.h
  870. fi
  871. echo "x - extracting set_24hr.c (Text)"
  872. sed 's/^X//' << 'SHAR_EOF' > set_24hr.c &&
  873. X/* CHK=0x0EC7 */
  874. X/*+-------------------------------------------------------------------------
  875. X    set_24hr.c
  876. X    ...!gatech!kd4nc!n4hgf!wht
  877. X--------------------------------------------------------------------------*/
  878. X/*+:EDITS:*/
  879. X/*:05-18-1989-13:03-wht-creation */
  880. X
  881. X#include <stdio.h>
  882. X#include <fcntl.h>
  883. X#include <sys/types.h>
  884. X
  885. X#include "at_cmos.h"
  886. X
  887. Xchar    *cmos = "/dev/cmos";
  888. X
  889. X/*+-------------------------------------------------------------------------
  890. X    main(argc,argv,envp)
  891. X--------------------------------------------------------------------------*/
  892. Xmain(argc,argv,envp)
  893. Xint argc;
  894. Xchar **argv;
  895. Xchar **envp;
  896. X{
  897. Xint fdcmos;
  898. XAT_CMOS *base;
  899. Xlong srB_pos = (long)((char *)&base->srB - (char *)base);
  900. Xuchar srB;
  901. Xlong lseek();
  902. X
  903. X    setbuf(stdout,NULL);
  904. X    setbuf(stderr,NULL);
  905. X
  906. X    if((fdcmos = open(cmos,O_RDWR,0)) < 0)
  907. X    {
  908. X        perror("/dev/cmos open");
  909. X        exit(1);
  910. X    }
  911. X
  912. X    if(lseek(fdcmos,srB_pos,0) != srB_pos)
  913. X    {
  914. X        perror("/dev/cmos seek 1");
  915. X        exit(1);
  916. X    }
  917. X
  918. X    if(read(fdcmos,&srB,1) != 1)
  919. X    {
  920. X        perror("/dev/cmos read");
  921. X        exit(1);
  922. X    }
  923. X
  924. X    srB |= SRB_24HR;
  925. X
  926. X    if(lseek(fdcmos,srB_pos,0) != srB_pos)
  927. X    {
  928. X        perror("/dev/cmos seek 2");
  929. X        exit(1);
  930. X    }
  931. X
  932. X    if(write(fdcmos,&srB,1) != 1)
  933. X    {
  934. X        perror("/dev/cmos write");
  935. X        exit(1);
  936. X    }
  937. X
  938. X    system("cmos_disp");
  939. X    exit(0);
  940. X}    /* end of main */
  941. SHAR_EOF
  942. chmod 0644 set_24hr.c || echo "restore of set_24hr.c fails"
  943. if [ $TOUCH = can ]
  944. then
  945.     touch -m 0105205590 set_24hr.c
  946. fi
  947. rm -f s3_seq_.tmp
  948. echo "You have unpacked the last part"
  949. exit 0
  950.  
  951. ----------------------------------------------------------------------------
  952. Warren Tucker                     emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
  953. "I was 35 years old before I knew a pie was meant to be eaten." - Moe Howard
  954.