home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 225_01 / deff3.c < prev    next >
Text File  |  1987-06-09  |  25KB  |  720 lines

  1. /*-----------------------------------------------------------------*/
  2. /*  FILE:          DEFF3.C
  3.     ----
  4.     COMPILER:      BDS C  V 1.50
  5.     --------
  6.     WRITTEN:       12th October, 1985
  7.     -------
  8.     REVISED:       10th November, 1986
  9.     -------
  10.     VERSION:       1.4
  11.     -------
  12.     ADDED FCTs:    SCOPY_N, GET_ALV
  13.     ----------                                                     */
  14.  
  15. /*  This file contains the following functions -
  16.  
  17.          BINARY         GET_DEFAULT         RESET_DSK
  18.          BITCOUNT       GET_IOBYTE          REVERSE
  19.          CGET           INDEX               SEARCH_FIRST
  20.          CLOSE_FILE     ISALNUM             SEARCH_NEXT
  21.          CLRSCREEN      ITOA                SELECT_DSK
  22.          CPUT           LISTC               SET_ATTRIBUTES
  23.          CON_STAT       MAKE_RO             SETDMA
  24.          CREATE_FILE    OPEN_FILE           SET_IOBYTE
  25.          DIRECTC        PRINT_DEC           SHELL_SORT
  26.          DPB_ADR        PRT_STR             SWAP_POINTERS
  27.          ERASE_FILE     READ_SEQ_SEC        USER_ID
  28.          GET_CPM        READ_STR            WRITE_SEQ_SEC
  29.  
  30.               ADDED FUNCTIONS
  31.               ---------------
  32.  
  33.          L_SHIFT        R_SHIFT             PRINT_BIN
  34.          BIT_SET        BIT_RESET           ISPRINT
  35.          SCOPY_N        GET_ALV
  36.                                                                    */
  37. /*  all of which are described in DEFF3.TXT and are                */
  38. /*  contained in the linking file  ==>  DEFF3.CRL                  */
  39. /*  Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  40. /*-----------------------------------------------------------------*/
  41. #include "pec.h"    /* definitions required                    */
  42. /*=================================================================*/
  43. /*            CGET                                                 */
  44. /*  Read Console Byte  ==>  CP/M Function No. 1                    */
  45. /*  Note will read any BYTE value from the console                 */
  46. /*-----------------------------------------------------------------*/
  47.  
  48. char cget()
  49. {
  50.     return(bdos(READ,0));
  51. }
  52. /*-----------------------------------------------------------------*/
  53. /*            CPUT                                                 */
  54. /*  Write Console Byte  ==> CP/M Function No. 2                    */
  55. /*  Note will send any BYTE value to the console                   */
  56. /*-----------------------------------------------------------------*/
  57.  
  58. void cput(c)
  59. int c;
  60. {
  61.     bdos(WRITE,c);
  62. }
  63. /*-----------------------------------------------------------------*/
  64. /*            CLRSCREEN                                            */
  65. /*  Clear screen function for Hazeltine Esprit terminal            */
  66. /*-----------------------------------------------------------------*/
  67.  
  68. void clrscreen()
  69. {
  70.     cput(126);
  71.     cput(28);
  72. }
  73. /*-----------------------------------------------------------------*/
  74. /*            LISTC                                                */
  75. /*  List byte to line printer                                      */
  76. /*-----------------------------------------------------------------*/
  77.  
  78. void listc(c)
  79. int c;
  80. {
  81.  
  82.     bdos(LIST, c);
  83. }
  84. /*-----------------------------------------------------------------*/
  85. /*            DIRECTC                                              */
  86. /*  Use direct console IN/OUT  ==>  CP/M function No. 6            */
  87. /*  Note:     DUTY = IN = 0FFH                                     */
  88. /*                 = OUT = character to be printed to screen       */
  89. /*  Returns either the input character or Reg. A = 0               */
  90. /*-----------------------------------------------------------------*/
  91.  
  92.  
  93. char directc(DUTY)
  94. int DUTY;
  95. {
  96.     return(bdos(DCIO,DUTY));
  97. }
  98. /*-----------------------------------------------------------------*/
  99. /*            GET_IOBYTE                                           */
  100. /*  Get IOBYTE setting                                             */
  101. /*  Returns the current IOBYTE setting                             */
  102. /*-----------------------------------------------------------------*/
  103.  
  104. char get_iobyte()
  105. {
  106.     return(bdos(IOBYTE,0));
  107. }
  108. /*-----------------------------------------------------------------*/
  109. /*            SET_IOBYTE                                           */
  110. /*  Sets the IOBYTE                                                */
  111. /*  Doesn't return anything                                        */
  112. /*-----------------------------------------------------------------*/
  113.  
  114. void set_iobyte(IOB)
  115. short IOB;    /* new IOBYTE setting */
  116. {
  117.     bdos(SET_IOBYTE,IOB);
  118. }
  119. /*-----------------------------------------------------------------*/
  120. /*            PRT_STR                                              */
  121. /*  Print a "$" terminated string to the console                   */
  122. /*  Doesn't return anything                                        */
  123. /*-----------------------------------------------------------------*/
  124.  
  125. void prt_str(BUFF)
  126. char *BUFF;    /* pointer to string buffer */
  127. {
  128.     bdos(PRT_STRING,BUFF);
  129. }
  130. /*-----------------------------------------------------------------*/
  131. /*            READ_STR                                             */
  132. /*  Read a "RETURN" terminated string from the console             */
  133. /*  Note:     The CR doesn't form part of the string.   As written */
  134. /*  ----      this function terminates the string with a null.     */
  135. /*-----------------------------------------------------------------*/
  136.  
  137. #define BUFF_LEN    134    /* maximum number of characters */
  138.  
  139. void read_str(BUFF)
  140. short *BUFF;
  141. {
  142.     short n;
  143.     for(n = 0; n <= BUFF_LEN; n++)
  144.     {
  145.         BUFF[n] = '\0';    /* Initialise string with NULL's */
  146.     }
  147.  
  148.     BUFF[0] = BUFF_LEN;    /* must tell CP/M buffer size */
  149.  
  150.     bdos(READ_STRING,BUFF);
  151. }
  152. /*-----------------------------------------------------------------*/
  153. /*            CON_STAT                                             */
  154. /*  Read the console status  ==>  CP/M Function No. 11             */
  155. /*  Returns NULL if no character waiting, else returns 0FFH        */
  156. /*-----------------------------------------------------------------*/
  157.  
  158. char con_stat()
  159. {
  160.     return(bdos(CON_STATUS,0));
  161. }
  162. /*-----------------------------------------------------------------*/
  163. /*            GET_CPM                                              */
  164. /*  Get CP/M Version Number                                        */
  165. /*  Number is returned in HL with the details -                    */
  166. /*                                                                 */
  167. /*     H = 00H for CP/M  or H = 01H for MP/M                       */
  168. /*     L = 00H for all releases prior to 2.0                       */
  169. /*     L = 20H for release 2.0, 21H for release 2.1, 22H for       */
  170. /*         release 2.2, and so on.                                 */
  171. /*-----------------------------------------------------------------*/
  172.  
  173. int get_cpm()
  174. {
  175.     return(bdos(CPM_NUM,0));
  176. }
  177. /*-----------------------------------------------------------------*/
  178. /*            RESET_DSK                                            */
  179. /*  Reset the disk system                                          */
  180. /*  Typically used after a disk is changed                         */
  181. /*  Does not return anything                                       */
  182. /*-----------------------------------------------------------------*/
  183.  
  184. void reset_dsk()
  185. {
  186.     bdos(RESET,0);
  187. }
  188. /*-----------------------------------------------------------------*/
  189. /*            SELECT_DSK                                           */
  190. /*  Select logical disk  ==>  CP/M Function No. 14                 */
  191. /*  This makes the nominated disk the default disk                 */
  192. /*  Note:     Drive A = 00H                                        */
  193. /*  ----      Drive B = 01H, and so on                             */
  194. /*-----------------------------------------------------------------*/
  195.  
  196. void select_dsk(DISK)
  197. char DISK;
  198. {
  199.     char DRIVE;
  200.     toupper(DISK);    /* make this upper case */
  201.     DRIVE = DISK - 65; /* convert to A = 0, B = 1, etc */
  202.  
  203.     bdos(LOGICAL,DRIVE);
  204. }
  205. /*-----------------------------------------------------------------*/
  206. /*            OPEN_FILE                                            */
  207. /*  Open a file  ==>  CP/M Function No. 15                         */
  208. /*  To use this you must have previously formulated a File         */
  209. /*  Control Block (FCB) using setfcb(fcbaddr, filename)            */
  210. /*  Returns the Directory code in Register A, or 0FFH if it failed */
  211. /*  Note particularly the nominated FCB must be declared for use   */
  212. /*  GLOBALLY so that it can be known by other functions.           */
  213. /*-----------------------------------------------------------------*/
  214.  
  215. char open_file(FCB)
  216. char FCB[36];
  217. {
  218.     return(bdos(OPEN_FILE,FCB));
  219. }
  220. /*-----------------------------------------------------------------*/
  221. /*            CLOSE_FILE                                           */
  222. /*  Close a file  ==>  CP/M Function No. 16                        */
  223. /*  Will close the file named in the FCB                           */
  224. /*  Same exit parameters as for "open_file"                        */
  225. /*-----------------------------------------------------------------*/
  226.  
  227. char close_file(FCB)
  228. char FCB[36];
  229. {
  230.     return(bdos(CLOSE_FILE,FCB));
  231. }
  232. /*-----------------------------------------------------------------*/
  233. /*            SEARCH_FIRST                                         */
  234. /*  Search for first match of file name  ==>  CP/M Function No. 17 */
  235. /*  Returns 255 if file name not found in directory                */
  236. /*  Else returns pointer to location of file name.                 */
  237. /*-----------------------------------------------------------------*/
  238.  
  239. char search_first(FCB)
  240. char FCB[36];
  241. {
  242.     return(bdos(SEARCH_FIRST,FCB));
  243. }
  244. /*-----------------------------------------------------------------*/
  245. /*            SEARCH_NEXT                                          */
  246. /*  Search for next match  ==>  CP/M Function No. 18               */
  247. /*  Can ONLY be used after a successful "search_first".            */
  248. /*  Same return paramaters as for search_first.                    */
  249. /*-----------------------------------------------------------------*/
  250.  
  251. char search_next()
  252. {
  253.     return(bdos(SEARCH_NEXT,0));
  254. }
  255. /*-----------------------------------------------------------------*/
  256. /*            ERASE_FILE                                           */
  257. /*  Erase (delete) the named file from directory                   */
  258. /*  Returns 255 if file not found.                                 */
  259. /*-----------------------------------------------------------------*/
  260.  
  261. char erase_file(FCB)
  262. char FCB[36];
  263. {
  264.     return(bdos(ERASE,FCB));
  265. }
  266. /*-----------------------------------------------------------------*/
  267. /*            READ_SEQ_SEC                                         */
  268. /*  Reads a sector sequentially from opened file                   */
  269. /*  Returns 00h if successful else returns non-zero number         */
  270. /*-----------------------------------------------------------------*/
  271.  
  272. char read_seq_sec(FCB)
  273. char FCB[36];
  274. {
  275.     return(bdos(READ_SECT,FCB));
  276. }
  277. /*-----------------------------------------------------------------*/
  278. /*            WRITE_SEQ_SEC                                        */
  279. /*  Writes a sector sequentially to the opened file                */
  280. /*  Returns 00h if successful else returns non-zero number         */
  281. /*-----------------------------------------------------------------*/
  282.  
  283. char write_seq_sec(FCB)
  284. char FCB[36];
  285. {
  286.      return(bdos(WRITE_SECT,FCB));
  287. }
  288. /*-----------------------------------------------------------------*/
  289. /*            CREATE_FILE                                          */
  290. /*  Creates the file named in the FCB  ==> CP/M Function No. 22    */
  291. /*  Returns 255 if directory is full                               */
  292. /*-----------------------------------------------------------------*/
  293.  
  294. char create_file(FCB)
  295. char FCB[36];
  296. {
  297.     return(bdos(CREATE,FCB));
  298. }
  299. /*-----------------------------------------------------------------*/
  300. /*            GET_DEFAULT                                          */
  301. /*  Get the current default disk No.  ==>  CP/M Function No. 25    */
  302. /*  Returns the code, A = 0, B = 1,...and so on.                   */
  303. /*-----------------------------------------------------------------*/
  304.  
  305. char get_default()
  306. {
  307.     return(bdos(DEFAULT,0));
  308. }
  309. /*-----------------------------------------------------------------*/
  310. /*            SETDMA                                               */
  311. /*  Sets the DMA (read/write buffer) address                       */
  312. /*  Doesn't return anything                                        */
  313. /*-----------------------------------------------------------------*/
  314.  
  315. void setdma(DMA_BUFF)
  316. char DMA_BUFF[128];
  317. {
  318.     bdos(26, &DMA_BUFF[0]);
  319. }
  320. /*-----------------------------------------------------------------*/
  321. /*            GET_ALV
  322.     Gets the address (pointer to) the allocation vector for the
  323.     allocation blocks.   Function 27.                              */
  324. /*-----------------------------------------------------------------*/
  325. unsigned get_alv()
  326. {
  327.     return(bdos(ALLOCATION, 0));
  328. }
  329. /*-----------------------------------------------------------------*/
  330. /*            MAKE_RO                                              */
  331. /*  Makes the logical disk selected by "select_dsk" R/O status     */
  332. /*  Doesn't return anything?                                       */
  333. /*-----------------------------------------------------------------*/
  334.  
  335. int make_ro()
  336. {
  337.     bdos(READ_ONLY,0);
  338. }
  339. /*-----------------------------------------------------------------*/
  340. /*            DPB_ADR                                              */
  341. /*  This is Function 31 - get Disk Parameter Block Address.   It   */
  342. /*  returns the address of the 15 byte block where the disk format */
  343. /*  information is stored by the BIOS.                             */
  344. /*-----------------------------------------------------------------*/
  345.  
  346. unsigned dpb_adr()
  347. {
  348.     return(bdos(DPB, 0));
  349. }
  350. /*-----------------------------------------------------------------*/
  351. /*            SET_ATTRIBUTES                                       */
  352. /*  Sets the attributes in the nominated FCB.   Note these must    */
  353. /*  have the high bit set prior to calling this function.          */
  354. /*  Returns 255 if file not found.                                 */
  355. /*-----------------------------------------------------------------*/
  356.  
  357. char set_attributes(FCB)
  358. char FCB[36];
  359. {
  360.     return(bdos(SET_ATTRIBUTES,FCB));
  361. }
  362. /*-----------------------------------------------------------------*/
  363. /*            USER_ID                                              */
  364. /*  Will set the User No., or get the User No., as instructed      */
  365. /*  Code = 255 to get User No.                                     */
  366. /*       = 0 to 15 to set User No.                                 */
  367. /*  Returns current user number if Code = 255                      */
  368. /*-----------------------------------------------------------------*/
  369.  
  370. char user_id(CODE)
  371. char CODE;
  372. {
  373.     return(bdos(USER_ID,CODE));
  374. }
  375. /*-----------------------------------------------------------------*/
  376. /*  Functions from K & R  ==>  in BDS C                            */
  377. /*-----------------------------------------------------------------*/
  378. /*            BITCOUNT                                             */
  379. /*  Counts the number of "1" bits in a byte (page 47)              */
  380. /*-----------------------------------------------------------------*/
  381.  
  382. short bitcount(n)
  383. unsigned n;
  384. {
  385.     short b;
  386.  
  387.     for(b = 0; n != 0; n >> 1)
  388.         if(n & 01)
  389.             b++;
  390.     return(b);
  391. }
  392. /*-----------------------------------------------------------------*/
  393. /*            BINARY                                               */
  394. /*  Finds whether a binary number occurs in a sorted array (p 54)  */
  395. /*-----------------------------------------------------------------*/
  396.  
  397. short binary(x, v, n)
  398. short x, v[], n;
  399. {
  400.     short low, high, mid;
  401.  
  402.     low = 0;
  403.     high = n - 1;
  404.     while(low <= high)
  405.     {
  406.         mid = (low + high)/2;
  407.         if(x < v[mid])
  408.             high = mid - 1;
  409.         else if (x > v[mid])
  410.             low = mid + 1;
  411.         else return(mid);    /* found match */
  412.     }
  413.     return(-1);
  414. }
  415. /*-----------------------------------------------------------------*/
  416. /*            SHELL_SORT                                           */
  417. /*  Sort v[0].....v[n-1] into increasing order  (page 58)          */
  418. /*-----------------------------------------------------------------*/
  419.  
  420. void shell_sort(v, n)
  421. short v[], n;
  422. {
  423.     short gap, i, j, temp;
  424.  
  425.     for(gap = n/2; gap > 0; gap = gap/2)
  426.         for(i = gap; i < n; i++)
  427.             for(j = i-gap; j >= 0 && v[j] > v[j+gap];j -= gap)
  428.             {
  429.                 temp = v[j];
  430.                 v[j] = v[j+gap];
  431.                 v[j+gap] = temp;
  432.             }
  433. }
  434. /*-----------------------------------------------------------------*/
  435. /*            REVERSE                                              */
  436. /*  Reverse a NULL-terminated string in place  (page 59)           */
  437. /*-----------------------------------------------------------------*/
  438.  
  439. void reverse(s)
  440. char s[];
  441. {
  442.     int c, i, j;
  443.  
  444.     for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
  445.     {
  446.         c = s[i];
  447.         s[i] = s[j];
  448.         s[j] = c;
  449.     }
  450. }
  451. /*-----------------------------------------------------------------*/
  452. /*            ITOA                                                 */
  453. /*  Convert integer into a printable ASCII string  (page 60)       */
  454. /*-----------------------------------------------------------------*/
  455.  
  456. void itoa(n,s)
  457. char s[];
  458. int n;
  459. {
  460.     int i, sign;
  461.  
  462.     if(( sign = n) < 0)
  463.         n = -n;        /* make n positive */
  464.     i = 0;
  465.  
  466.     do {
  467.         s[i++] = n % 10 + '0';    /* put digits in reverse */
  468.        }
  469.     while((n /= 10) > 0);
  470.         if(sign < 0)
  471.             s[i++] = '-';
  472.     s[i] = '\0';    /* NULL terminator */
  473.     reverse(s);    /* put into correct order */
  474. }
  475. /*-----------------------------------------------------------------*/
  476. /*            INDEX                                                */
  477. /*  Find index of string t in string s, return -1 if none (p 67)   */
  478. /*-----------------------------------------------------------------*/
  479.  
  480. int index(s, t)
  481. char s[], t[];
  482. {
  483.     int i, j, k;
  484.  
  485.     for( i = 0; s[i] != '\0'; i++)
  486.     {
  487.         for(j = i, k = 0; t[k] != '\0' && s[j] == t[k];j++,k++)
  488.         ;
  489.     if(t[k] == '\0')
  490.         return(i);
  491.     }
  492.     return(-1);
  493. }
  494. /*-----------------------------------------------------------------*/
  495. /*            PRINT_DEC                                            */
  496. /*  Print a decimal number to the console  (page 85)               */
  497. /*-----------------------------------------------------------------*/
  498.  
  499. void print_dec(n)
  500. int n;
  501. {
  502.     char s[10];
  503.     int i;
  504.  
  505.     if( n < 0)
  506.     {
  507.         putchar('-');
  508.         n = -n;        /* make number positive */
  509.     }
  510.     i = 0;
  511.     if((i = n/10) != 0)
  512.         print_dec(i);
  513.     putchar(n % 10 + '0');
  514. }
  515. /*-----------------------------------------------------------------*/
  516. /*            SWAP_POINTERS                                        */
  517. /*  Interchange two pointers  (page 117)                           */
  518. /*-----------------------------------------------------------------*/
  519.  
  520. void swap_pointers(px, py)
  521. char *px[], *py[];
  522. {
  523.     char *temp;
  524.  
  525.     temp = *px;
  526.     *px = *py;
  527.     *py = temp;
  528. }
  529. /*-----------------------------------------------------------------*/
  530. /*  LIBRARY FILE  ==>  isalnum                                     */
  531. /*  Tests whether a character is alpha-numeric                     */
  532. /*  Returns   TRUE/FALSE                                           */
  533. /*-----------------------------------------------------------------*/
  534.  
  535. char isalnum(c)
  536. char c;
  537. {
  538.     if(isalpha(c) || ( c >= '0' && c <= '9'))
  539.         return(1);
  540.     else return(0);
  541. }
  542. /*-----------------------------------------------------------------*/
  543. /*            L_SHIFT                                             */
  544. /*       Multiply a value by 2 raised to the power given.         */
  545. /******************************************************************/
  546. unsigned l_shift(value, number)
  547. unsigned value;
  548. int number;
  549. {
  550.     int i, factor;
  551.     factor = 1;    /* Starting value */
  552.  
  553.     for(i = 0; i < number; i++)
  554.          factor = factor*2;
  555.     value = value*factor;
  556.     return(value);
  557. }
  558. /*-----------------------------------------------------------------*/
  559. /*            R_SHIFT                                              */
  560. /*       Divide a value by 2 raised to the power given.            */
  561. /*******************************************************************/
  562. unsigned r_shift(value, number)
  563. unsigned value;
  564. int number;
  565. {
  566.     int i, factor;
  567.     factor = 1;    /* Starting value */
  568.  
  569.     for(i = 0; i < number; i++)
  570.          factor = factor*2;
  571.     value = value/factor;
  572.     return(value);
  573. }
  574. /*-----------------------------------------------------------------*/
  575. /*  LIBRARY FILE  ==>  PRT_BIN
  576.  
  577.     Will convert an unsigned integer to a printable ASCII string, in
  578.     binary notation.  e.g. the number 0xff will be converted to
  579.  
  580.               11111111
  581.  
  582.     Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  583. /*-----------------------------------------------------------------*/
  584.  
  585. void print_bin(i)
  586. unsigned i;
  587. {
  588.     char str[17];    /* The string to hold the result           */
  589.     int n;        /* Bit counter                             */
  590.  
  591.     str[16] = '\0';    /* String must be null-terminated          */
  592.     if(i & 0x01)
  593.         str[15] = '1';
  594.     else str[15] = '0';    /* Check first bit                 */
  595.     for(n = 0; n < 15; n++)
  596.     {
  597.         i = i >> 1;    /* Shift right by one bit          */
  598.         if(i & 0x01)
  599.             str[14 - n] = '1';
  600.         else str[14 - n] = '0';
  601.     }
  602.     printf("%s", str);    /* Print the binary string         */
  603. }
  604. /*-----------------------------------------------------------------*/
  605. /*  LIBRARY FILE  ==>  BIT_SET
  606.  
  607.     This function will set the nominated bit in an unsigned
  608.     integer.   Note the bits are numbered from 0 to 15 = 16
  609.     bits altogether.   It returns the unsigned integer with
  610.     the nominated bit set.
  611.  
  612.     Usage:    bit_set(u, n);
  613.     -----     Where u = unsigned integer and n = bit number.
  614.  
  615.     Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  616. /*-----------------------------------------------------------------*/
  617.  
  618. unsigned bit_set(u, n)
  619. unsigned u;
  620. int n;
  621. {
  622.     unsigned modifier;
  623.     int i;
  624.  
  625.     if(n == 0)
  626.         modifier = 1;
  627.     else if( n > 0)
  628.     {
  629.         modifier = 1;
  630.         for(i = 1; i <= n; i++)
  631.         {
  632.             modifier = modifier*2;
  633.         }
  634.     }
  635.     return(u | modifier);
  636. }
  637. /*-----------------------------------------------------------------*/
  638. /*  LIBRARY FILE  ==>  BIT_RESET
  639.  
  640.     This function will reset the nominated bit in an unsigned
  641.     integer.   Note the bits are numbered from 0 to 15 = 16
  642.     bits altogether.   It returns the unsigned integer with
  643.     the nominated bit reset to zero.
  644.  
  645.     Usage:    bit_reset(u, n);
  646.     -----     Where u = unsigned integer and n = bit number.
  647.  
  648.     Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  649. /*-----------------------------------------------------------------*/
  650.  
  651. unsigned bit_reset(u, n)
  652. unsigned u;
  653. int n;
  654. {
  655.     unsigned modifier;
  656.     int i;
  657.  
  658.     if(n == 0)
  659.         modifier = 1;
  660.     else if( n > 0)
  661.     {
  662.         modifier = 1;
  663.         for(i = 1; i <= n; i++)
  664.         {
  665.             modifier = modifier*2;
  666.         }
  667.     }
  668.     modifier = modifier | 0xffff;
  669.     return(u & modifier);
  670. }
  671. /*-----------------------------------------------------------------*/
  672. /*  LIBRARY FILE  ==>  ISPRINT
  673.  
  674.     Will return TRUE (+1) if the character being tested is able to
  675.     be printed on the console, else returns FALSE (0).
  676.  
  677.     Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  678. /*-----------------------------------------------------------------*/
  679.  
  680. char isprint(c)
  681. char c;
  682. {
  683.     if(c > 0x1f && c < 0x7f)
  684.         return(1);    /* A printable character           */
  685.     else return(0);
  686. }
  687. /*-----------------------------------------------------------------*/
  688. /*  LIBRARY FILE  ==>  SCOPY_N
  689.  
  690.     This will copy string2 to string1 for "n" characters.    If "n"
  691.     is greater than strlen(string2) then it will only copy until
  692.     all the characters in string2 have been done.
  693.  
  694.     NOTE:     It doesn't terminate string1 with the '\0' character
  695.     ----      when it has copied across the nominated number of
  696.               characters from string2.   This is so you can use
  697.               the routine to overwrite/insert a string within a
  698.               buffer.
  699.  
  700.     Copyright 1986 - Cogar Computer Services Pty.Ltd.              */
  701. /*-----------------------------------------------------------------*/
  702.  
  703. void scopy_n(s1, s2, n)
  704. char *s1, *s2;
  705. int n;
  706. {
  707.     int i, j;
  708.     if(n > strlen(s2))
  709.         i = strlen(s2);
  710.     else i = n;
  711.  
  712.     for(j = 0; j < i; j++)
  713.         s1[j] = s2[j];
  714. }
  715. /*-----------------------------------------------------------------*/
  716. unsigned integer with
  717.     the nominated bit reset to zero.
  718.  
  719.     Usage:    bit_reset(u, n);
  720.     -