home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / HSRC_100 / SYSPC.C < prev   
C/C++ Source or Header  |  1993-01-11  |  14KB  |  494 lines

  1. /*=============================================================================
  2.  
  3.                               HydraCom Version 1.00
  4.  
  5.                          A sample implementation of the
  6.                    HYDRA Bi-Directional File Transfer Protocol
  7.  
  8.                              HydraCom was written by
  9.                    Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
  10.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  11.  
  12.                        The HYDRA protocol was designed by
  13.                  Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
  14.                              Joaquim H. Homrighausen
  15.                   COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
  16.  
  17.  
  18.   Revision history:
  19.   06 Sep 1991 - (AGL) First tryout
  20.   .. ... .... - Internal development
  21.   11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
  22.  
  23.  
  24.   For complete details of the Hydra and HydraCom licensing restrictions,
  25.   please refer to the license agreements which are published in their entirety
  26.   in HYDRACOM.C and LICENSE.DOC, and also contained in the documentation file
  27.   HYDRACOM.DOC
  28.  
  29.   Use of this file is subject to the restrictions contained in the Hydra and
  30.   HydraCom licensing agreements. If you do not find the text of this agreement
  31.   in any of the aforementioned files, or if you do not have these files, you
  32.   should immediately contact LENTZ SOFTWARE-DEVELOPMENT and/or Joaquim
  33.   Homrighausen at one of the addresses listed below. In no event should you
  34.   proceed to use this file without having accepted the terms of the Hydra and
  35.   HydraCom licensing agreements, or such other agreement as you are able to
  36.   reach with LENTZ SOFTWARE-DEVELOMENT and Joaquim Homrighausen.
  37.  
  38.  
  39.   Hydra protocol design and HydraCom driver:         Hydra protocol design:
  40.   Arjen G. Lentz                                     Joaquim H. Homrighausen
  41.   LENTZ SOFTWARE-DEVELOPMENT                         389, route d'Arlon
  42.   Langegracht 7B                                     L-8011 Strassen
  43.   3811 BT  Amersfoort                                Luxembourg
  44.   The Netherlands
  45.   FidoNet 2:283/512, AINEX-BBS +31-33-633916         FidoNet 2:270/17
  46.   arjen_lentz@f512.n283.z2.fidonet.org               joho@ae.lu
  47.  
  48.   Please feel free to contact us at any time to share your comments about our
  49.   software and/or licensing policies.
  50.  
  51. =============================================================================*/
  52.  
  53. #include <time.h>
  54. #include <stdio.h>
  55. #include <stdarg.h>
  56. #include <ctype.h>
  57. #include <dir.h>
  58. #include <dos.h>
  59. #include <io.h>
  60. #include <process.h>
  61. #include <signal.h>
  62. #include <alloc.h>
  63. #include <sys\stat.h>
  64. #include "hydracom.h"
  65. #include "async.h"
  66.  
  67.  
  68. struct _fos_info {
  69.        word      strsize;       /* size of the structure in bytes     */
  70.        byte      majver;        /* FOSSIL spec driver conforms to     */
  71.        byte      minver;        /* rev level of this specific driver  */
  72.        char far *ident;         /* FAR pointer to ASCII ID string     */
  73.        word      ibufr;         /* size of the input buffer (bytes)   */
  74.        word      ifree;         /* number of bytes left in buffer     */
  75.        word      obufr;         /* size of the output buffer (bytes)  */
  76.        word      ofree;         /* number of bytes left in the buffer */
  77.        byte      swidth;        /* width of screen on this adapter    */
  78.        byte      sheight;       /* height of screen    "      "       */
  79.        byte      speed;         /* ACTUAL speed, computer to modem    */
  80. };
  81.  
  82. struct _fos_speedtable {
  83.         word speed;
  84.         byte bits;
  85. };
  86.  
  87.  
  88. /* HJW 1/4/93
  89.    NOTE:  The topspeed compiler generates for _DX = port the following
  90.           assembler instructions:
  91.  
  92.           Mov AX,[port]
  93.           Mov DX, AX
  94.  
  95.           Thus AX is overwritten. Any construct that loads a register
  96.           using the _XX register indicators should be examined carefully.
  97.           It is very likely that other compilers use the same strategy.
  98.           Example:
  99.           #define fossil_int(func)   { _AH = func; _DX = port; geninterrupt(0x14); }
  100.           should be changed to:
  101. */
  102. #define fossil_int(func)   { _DX = port; _AH = func; geninterrupt(0x14); }
  103. #define dosext_int(func)   { _AH = func;             geninterrupt(0x15); }
  104. #define dos_int(func)      { _AH = func;             geninterrupt(0x21); }
  105. #define dossched_int()     {                         geninterrupt(0x28); }
  106. #define FOS_SIGNATURE   0x1954
  107. #define FOS_SETSPEED    0x00
  108. #define FOS_PUTC        0x01
  109. #define FOS_GETSTATUS   0x03
  110. #define FOS_INIT        0x04
  111. #define FOS_DEINIT      0x05
  112. #define FOS_SETDTR      0x06
  113. #define FOS_DUMP        0x09
  114. #define FOS_PURGE       0x0a
  115. #define FOS_SETFLOW     0x0f
  116. #define FOS_MAXBUFLEN   1024
  117.  
  118. static boolean dv_active;
  119. static boolean fossil;
  120. static struct _fos_info fos_info;
  121. static byte    fos_inbuf[FOS_MAXBUFLEN];
  122. static word    fos_inwrite,
  123.                fos_inread;
  124. static struct _fos_speedtable fos_speedtable [] = {
  125.         {   300U, 0x40 },
  126.         {  1200U, 0x80 },
  127.         {  2400U, 0xA0 },
  128.         {  4800U, 0xC0 },
  129.         {  9600U, 0xE0 },
  130.         { 19200U, 0x00 },
  131.         { 38400U, 0x20 },
  132.         {     0U,    0 }
  133. };
  134.  
  135.  
  136. void dtr_out (byte flag)
  137. {
  138.         if (fossil) {
  139.            _AL = flag;
  140.            fossil_int(FOS_SETDTR);
  141.         }
  142.         else
  143.            AsyncHand(flag ? (DTR | RTS) : RTS);
  144. }
  145.  
  146.  
  147. void com_flow (byte flags)
  148. {
  149.         if (fossil) {
  150.            _AL = flags;
  151.            fossil_int(FOS_SETFLOW);
  152.         }
  153.         else {
  154.            AsyncCTS(flags & 0x02);
  155.         }
  156. }
  157.  
  158.  
  159. void com_setspeed (word speed)                       /* set speed of comport */
  160. {
  161.         register byte i;
  162.  
  163.         if (!speed) return;
  164.  
  165.         if (fossil) {
  166.            for (i = 0; fos_speedtable[i].speed; i++) {
  167.                if (speed == fos_speedtable[i].speed) {
  168.                   _AL = (fos_speedtable[i].bits | (parity ? 0x1a : 0x03));
  169.                   fossil_int(FOS_SETSPEED);
  170.                   break;
  171.                }
  172.            }
  173.         }
  174.         else
  175.            AsyncSet(speed,(parity ? (BITS_7 | EVEN_PARITY) : BITS_8) | STOP_1);
  176. }
  177.  
  178.  
  179. static word fos_getstatus (void)
  180. {
  181.         fossil_int(FOS_GETSTATUS);
  182.         return (_AX);
  183. }
  184.  
  185.  
  186. static int get_fos_info (void)
  187. {
  188.         struct SREGS sregs;
  189.         union  REGS  regs;
  190.  
  191.         regs.x.ax = 0x1b00;
  192.         regs.x.cx = sizeof (struct _fos_info);
  193.         regs.x.dx = port;
  194.         segread(&sregs);
  195.         sregs.es  = FP_SEG(&fos_info);
  196.         regs.x.di = FP_OFF(&fos_info);
  197.         int86x(0x14,®s,®s,&sregs);
  198.  
  199.         return (regs.x.ax == sizeof (struct _fos_info));
  200. }
  201.  
  202.  
  203. static int fos_fillinbuf (void)
  204. {
  205.         struct SREGS sregs;
  206.         union  REGS  regs;
  207.  
  208.         if (!(fos_getstatus() & 0x0100))
  209.            return (0);
  210.  
  211.         regs.x.ax = 0x1800;
  212.         regs.x.dx = port;
  213.         regs.x.cx = FOS_MAXBUFLEN;
  214.         segread(&sregs);
  215.         sregs.es  = FP_SEG(fos_inbuf);
  216.         regs.x.di = FP_OFF(fos_inbuf);
  217.         int86x(0x14,®s,®s,&sregs);
  218.         fos_inwrite = regs.x.ax;
  219.         fos_inread = 0;
  220.  
  221.         return (fos_inwrite);
  222. }
  223.  
  224.  
  225. void com_putblock (byte *s, word len)
  226. {
  227.         if (fossil) {
  228.            struct SREGS sregs;
  229.            union  REGS  regs;
  230.  
  231.            while (len && carrier()) {
  232.                  regs.x.ax = 0x1900;
  233.                  regs.x.dx = port;
  234.                  regs.x.cx = len;
  235.                  segread(&sregs);
  236.                  sregs.es  = FP_SEG(s);
  237.                  regs.x.di = FP_OFF(s);
  238.                  int86x(0x14,®s,®s,&sregs);
  239.                  len -= regs.x.ax;
  240.                  s += regs.x.ax;
  241.            }
  242.         }
  243.         else {
  244.            while (len-- > 0 && carrier()) com_putbyte(*s++);
  245.         }
  246. }
  247.  
  248.  
  249. static int fos_init (void)
  250. {
  251.         fossil_int(FOS_INIT);
  252.         return ((_AX != FOS_SIGNATURE || _BH < 5 || _BL < 0x1b) ? 0 : 1);
  253. }
  254.  
  255.  
  256. void sys_init(void)         /* all system dependent init should be done here */
  257. {
  258.         _CX = 0x4445;   /* DE */                /* DESQview presence check   */
  259.         _DX = 0x5351;   /* SQ */
  260.         _AL = 0x01;
  261.         dos_int(0x2b);
  262.         dv_active = (_AL != 0xff && _BX) ? true : false;
  263.  
  264.         fossil = true;
  265.         if (!noinit && !fos_init()) {
  266.            if (AsyncInit(port)) {
  267.               cprint("%s internal com-routines can't find a comport %u\n",
  268.                      PRGNAME, port + 1);
  269.               endprog(2);
  270.            }
  271.            fossil = false;
  272.         }
  273.         else if (!get_fos_info() || fos_info.majver < 5) {
  274.            if (!noinit) fossil_int(FOS_DEINIT);
  275.            cprint("%s requires a revision 5 FOSSIL driver (funcs upto 1B)\n",PRGNAME);
  276.            endprog(2);
  277.         }
  278.  
  279.         if (fossil) {
  280.            if (fos_info.obufr < 4096)
  281.               message(6,"!FOSSIL transmit buffer size %u, should be >= 4096",fos_info.obufr);
  282.            if (fos_info.ibufr < 4096)
  283.               message(6,"!FOSSIL receive buffer size %u, should be >= 4096",fos_info.ibufr);
  284.         }
  285.  
  286.         if (!noinit) com_flow(flowflags);
  287.         fos_inread = fos_inwrite = 0;
  288. }
  289.  
  290.  
  291. void sys_reset(void)                            /* same as above for de-init */
  292. {
  293.         if (!noinit) com_flow(0);
  294.  
  295.         if (fossil) {
  296.            if (!noinit) fossil_int(FOS_DEINIT);
  297.         }
  298.         else
  299.            AsyncStop();
  300. }
  301.  
  302.  
  303. void sys_idle (void)
  304. {
  305. #if WIN_AGL
  306.         win_idle();
  307. #else
  308.         if (dv_active) {
  309.            _AL = 0;             /* int15 ax=1000 */
  310.            dosext_int(0x10);    /* dv time slice */
  311.         }
  312.         else
  313.            dossched_int();      /* DOS scheduler */
  314. #endif
  315. }/*sys_idle()*/
  316.  
  317.  
  318. int com_outfull (void)          /* Return the amount in fossil output buffer */
  319. {                               /* Ie. remaining no. bytes to be transmitted */
  320.         if (fossil) {
  321.            get_fos_info();
  322.            return (fos_info.obufr - fos_info.ofree);
  323.         }
  324.         else
  325.            return (AsyncOutStat());
  326. }
  327.  
  328.  
  329. int carrier(void)                                   /* Return carrier status */
  330. {
  331.         int i;
  332.  
  333.         if (nocarrier) return (1);
  334.  
  335.         if (fossil) {
  336.            fossil_int(FOS_GETSTATUS);
  337. /* HJW 4/1/93
  338.    Here we have the same problem, machinecode generated for
  339.            return (_AX & dcdmask);
  340.    is
  341.            Mov AX,[dcdmask]
  342.            And AX,AX
  343.  
  344.    so it should be changed to:
  345. */
  346.            i = _AX;
  347.            return(i & dcdmask);
  348.         }
  349.         else {
  350.            i = AsyncStat();
  351.            return (((i >> 8) & dcdmask) | ((i << 8) & dcdmask));
  352.         }
  353. }  
  354.  
  355.  
  356. void com_flush(void)              /* wait till all characters have been sent */
  357. {
  358.         if (fossil) {
  359.            while (!(fos_getstatus() & 0x4000) && carrier());
  360.         }
  361.         else {
  362.            while (AsyncOutStat() && carrier());
  363.         }
  364. }
  365.  
  366.  
  367. void com_putbyte (byte c)
  368. {
  369.         if (fossil) {
  370.            _AL = c;
  371.            fossil_int(FOS_PUTC);
  372.         }
  373.         else
  374.            AsyncOut(c);
  375. }
  376.  
  377.  
  378. void com_purge (void)
  379. {
  380.         if (fossil) {
  381.            fossil_int(FOS_PURGE);
  382.            fos_inread = fos_inwrite = 0;
  383.         }
  384.         else
  385.            AsyncPurge();
  386. }
  387.  
  388.  
  389. void com_dump (void)
  390. {
  391.         if (fossil) {
  392.            fossil_int(FOS_DUMP);
  393.         }
  394.         else
  395.            AsyncDump();
  396. }
  397.  
  398.  
  399. int com_getbyte(void)
  400. {
  401.         if (fossil) {
  402.            return (((fos_inread < fos_inwrite) || fos_fillinbuf()) ?
  403.                    fos_inbuf[fos_inread++] : EOF);
  404.         }
  405.         else
  406.            return (AsyncInStat() ? AsyncIn() : EOF);
  407. }
  408.  
  409.  
  410. void setstamp(char *name,long tim)                  /* Set time/date of file */
  411. {
  412.         int fd;
  413.         struct tm *t;
  414.         union REGS regs;
  415.  
  416.         if ((fd = dos_open(name,0)) < 0)
  417.            return;
  418.  
  419.         if (tim == 0L)
  420.            time(&tim);
  421.         t = localtime((time_t *) &tim);
  422.  
  423.         regs.x.cx = (t->tm_hour << 11) |
  424.                     (t->tm_min << 5) |
  425.                     (t->tm_sec/2);
  426.         regs.x.dx = ((t->tm_year-80) << 9) |
  427.                     ((t->tm_mon+1) << 5) |
  428.                     (t->tm_mday);
  429.         regs.x.bx = fd;
  430.         regs.x.ax = 0x5701;     /* DOS int 21 fn 57 sub 1 */
  431.         intdos(®s,®s);    /* Set a file's date/time */
  432.  
  433.         close(fd);
  434. }
  435.  
  436.  
  437. long freespace(char *drivepath)    /* get free diskspace for specified drive */
  438. {
  439.         union REGS regs;
  440.  
  441.         if (drivepath[0] && drivepath[1] == ':' && isalpha(drivepath[0]))
  442.            regs.h.dl = (toupper(drivepath[0]) - 64);
  443.         else
  444.            regs.h.dl = 0;
  445.         regs.h.ah = 0x36;
  446.         intdos(®s,®s);
  447.         return ((long)regs.x.cx * (long)regs.x.ax * (long)regs.x.bx);
  448. }
  449.  
  450.  
  451. static char ff_dta[58];
  452.  
  453. char *ffirst(char *filespec)
  454. {
  455.         struct SREGS sregs;
  456.         union  REGS  regs;
  457.  
  458.         regs.h.ah = 0x1a;
  459.         segread(&sregs);
  460.         sregs.ds  = FP_SEG(ff_dta);
  461.         regs.x.dx = FP_OFF(ff_dta);
  462.         intdosx(®s,®s,&sregs);
  463.  
  464.         regs.x.cx = 0;
  465.         regs.h.ah = 0x4e;
  466.         sregs.ds  = FP_SEG(filespec);
  467.         regs.x.dx = FP_OFF(filespec);
  468.         intdosx(®s,®s,&sregs);
  469.         if (regs.x.cflag)
  470.            return (NULL);
  471.         return (ff_dta+0x1e);
  472. }
  473.  
  474.  
  475. char *fnext(void)
  476. {
  477.         struct SREGS sregs;
  478.         union  REGS  regs;
  479.  
  480.         regs.h.ah = 0x1a;
  481.         segread(&sregs);
  482.         sregs.ds  = FP_SEG(ff_dta);
  483.         regs.x.dx = FP_OFF(ff_dta);
  484.         intdosx(®s,®s,&sregs);
  485.  
  486.         regs.h.ah = 0x4f;
  487.         intdosx(®s,®s,&sregs);
  488.         if (regs.x.cflag)
  489.            return (NULL);
  490.         return (ff_dta+0x1e);
  491. }
  492.  
  493. /* end of syspc.c */
  494.