home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 193_01 / deff3.c < prev    next >
Text File  |  1985-11-14  |  18KB  |  504 lines

  1. /*-----------------------------------------------------------------*/
  2. /*  LIBRARY FUNCTIONS  ==>  written by Phil Cogar                  */
  3. /*  For BDS C under CP/M 2.2 using the "BDOS" Function             */
  4. /*                                                                 */
  5. /*  This file contains the following functions -                   */
  6. /*                                                                 */
  7. /*       CGET                CPUT           DIRECTC                */
  8. /*       CLRSCREEN           LISTC          GET_IOBYTE             */
  9. /*       SET_IOBYTE          PRT_STR        READ_STR               */
  10. /*       CON_STAT            GET_CPM        RESET_DSK              */
  11. /*       SELECT_DSK          OPEN_FILE      CLOSE_FILE             */
  12. /*       SEARCH_FIRST        SEARCH_NEXT    CREATE_FILE            */
  13. /*       ERASE_FILE          READ_SEQ_SEC   WRITE_SEQ_SEC          */
  14. /*       GET_DEFAULT         SET_DMA        MAKE_RO                */
  15. /*       SET_ATTRIBUTES      USER_ID        BITCOUNT               */
  16. /*       BINARY              SHELL_SORT     REVERSE                */
  17. /*       ITOA                INDEX          PRINT_DEC              */
  18. /*       SWAP_POINTERS       ISALNUM                               */
  19. /*                                                                 */
  20. /*  all of which are described in DEFF3.TXT and are                */
  21. /*  contained in the linking file  ==>  DEFF3.CRL                  */
  22. /*  Copyright 1986 - Cogar Computer Services Pty. Ltd.             */
  23. /*-----------------------------------------------------------------*/
  24. #include "pec.h"    /* definitions required                    */
  25. /*=================================================================*/
  26. /*            CGET                                                 */
  27. /*  Read Console Byte  ==>  CP/M Function No. 1                    */
  28. /*  Note will read any BYTE value from the console                 */
  29.  
  30. cget()
  31. {
  32.     bdos(READ,0);
  33. }
  34. /*-----------------------------------------------------------------*/
  35. /*            CPUT                                                 */
  36. /*  Write Console Byte  ==> CP/M Function No. 2                    */
  37. /*  Note will send any BYTE value to the console                   */
  38.  
  39. cput(c)
  40. int c;
  41. {
  42.     bdos(WRITE,c);
  43. }
  44. /*-----------------------------------------------------------------*/
  45. /*            CLRSCREEN                                            */
  46. /*  Clear screen function for Hazeltine Esprit terminal            */
  47.  
  48. clrscreen()
  49. {
  50.     cput(126);
  51.     cput(28);
  52. }
  53. /*-----------------------------------------------------------------*/
  54. /*            LISTC                                                */
  55. /*  List byte to line printer                                      */
  56.  
  57. listc(c)
  58. int c;
  59. {
  60.  
  61.     bdos(LIST, c);
  62. }
  63. /*-----------------------------------------------------------------*/
  64. /*            DIRECTC                                              */
  65. /*  Use direct console IN/OUT  ==>  CP/M function No. 6            */
  66. /*  Note:     DUTY = IN = 0FFH                                     */
  67. /*                 = OUT = character to be printed to screen       */
  68. /*  Returns either the input character or Reg. A = 0               */
  69. /*-----------------------------------------------------------------*/
  70.  
  71. #define    IN 255    /* Character in function */
  72.  
  73. directc(DUTY)
  74. int DUTY;
  75. {
  76.     bdos(DCIO,DUTY);
  77. }
  78. /*-----------------------------------------------------------------*/
  79. /*            GET_IOBYTE                                           */
  80. /*  Get IOBYTE setting                                             */
  81. /*  Returns the current IOBYTE setting                             */
  82. /*-----------------------------------------------------------------*/
  83.  
  84. get_iobyte()
  85. {
  86.     bdos(IOBYTE,0);
  87. }
  88. /*-----------------------------------------------------------------*/
  89. /*            SET_IOBYTE                                           */
  90. /*  Sets the IOBYTE                                                */
  91. /*  Doesn't return anything                                        */
  92. /*-----------------------------------------------------------------*/
  93.  
  94. set_iobyte(IOB)
  95. short IOB;    /* new IOBYTE setting */
  96. {
  97.     bdos(SET_IOBYTE,IOB);
  98. }
  99. /*-----------------------------------------------------------------*/
  100. /*            PRT_STR                                              */
  101. /*  Print a "$" terminated string to the console                   */
  102. /*  Doesn't return anything                                        */
  103. /*-----------------------------------------------------------------*/
  104.  
  105. prt_str(BUFF)
  106. char *BUFF;    /* pointer to string buffer */
  107. {
  108.     bdos(PRT_STRING,BUFF);
  109. }
  110. /*-----------------------------------------------------------------*/
  111. /*            READ_STR                                             */
  112. /*  Read a "RETURN" terminated string from the console             */
  113. /*  Note:     The CR doesn't form part of the string.   As written */
  114. /*  ----      this function terminates the string with a null.     */
  115. /*-----------------------------------------------------------------*/
  116.  
  117. #define BUFF_LEN    134    /* maximum number of characters */
  118.  
  119. read_str(BUFF)
  120. short *BUFF;
  121. {
  122.     short n;
  123.     for(n = 0; n <= BUFF_LEN; n++)
  124.     {
  125.         BUFF[n] = '\0';    /* Initialise string with NULL's */
  126.     }
  127.     
  128.     BUFF[0] = BUFF_LEN;    /* must tell CP/M buffer size */
  129.  
  130.     bdos(READ_STRING,BUFF);
  131. }
  132. /*-----------------------------------------------------------------*/
  133. /*            CON_STAT                                             */
  134. /*  Read the console status  ==>  CP/M Function No. 11             */
  135. /*  Returns NULL if no character waiting, else returns 0FFH        */
  136. /*-----------------------------------------------------------------*/
  137.  
  138. con_stat()
  139. {
  140.     bdos(CON_STATUS,0);
  141. }
  142. /*-----------------------------------------------------------------*/
  143. /*            GET_CPM                                              */
  144. /*  Get CP/M Version Number                                        */
  145. /*  Number is returned in HL with the details -                    */
  146. /*                                                                 */
  147. /*     H = 00H for CP/M  or H = 01H for MP/M                       */
  148. /*     L = 00H for all releases prior to 2.0                       */
  149. /*     L = 20H for release 2.0, 21H for release 2.1, 22H for       */
  150. /*         release 2.2, and so on.                                 */
  151. /*-----------------------------------------------------------------*/
  152.  
  153. get_cpm()
  154. {
  155.     bdos(CPM_NUM,0);
  156. }
  157. /*-----------------------------------------------------------------*/
  158. /*            RESET_DSK                                            */
  159. /*  Reset the disk system                                          */
  160. /*  Typically used after a disk is changed                         */
  161. /*  Does not return anything                                       */
  162. /*-----------------------------------------------------------------*/
  163.  
  164. reset_dsk()
  165. {
  166.     bdos(RESET,0);
  167. }
  168. /*-----------------------------------------------------------------*/
  169. /*            SELECT_DSK                                           */
  170. /*  Select logical disk  ==>  CP/M Function No. 14                 */
  171. /*  This makes the nominated disk the default disk                 */
  172. /*  Note:     Drive A = 00H                                        */
  173. /*  ----      Drive B = 01H, and so on                             */
  174. /*-----------------------------------------------------------------*/
  175.  
  176. select_dsk(DISK)
  177. short DISK;
  178. {
  179.     toupper(DISK);    /* make this upper case */
  180.     DISK = DISK - 66; /* convert to A = 0, B = 1, etc */
  181.  
  182.     bdos(LOGICAL,DISK);
  183. }
  184. /*-----------------------------------------------------------------*/
  185. /*            OPEN_FILE                                            */
  186. /*  Open a file  ==>  CP/M Function No. 15                         */
  187. /*  To use this you must have previously formulated a File         */
  188. /*  Control Block (FCB) using setfcb(fcbaddr, filename)            */
  189. /*  Returns the Directory code in Register A, or 0FFH if it failed */
  190. /*  Note particularly the nominated FCB must be declared for use   */
  191. /*  GLOBALLY so that it can be known by other functions.           */
  192. /*-----------------------------------------------------------------*/
  193.  
  194. open_file(FCB)
  195. char FCB[36];
  196. {
  197.     bdos(OPEN_FILE,FCB);
  198. }
  199. /*-----------------------------------------------------------------*/
  200. /*            CLOSE_FILE                                           */
  201. /*  Close a file  ==>  CP/M Function No. 16                        */
  202. /*  Will close the file named in the FCB                           */
  203. /*  Same exit parameters as for "open_file"                        */
  204.  
  205. close_file(FCB)
  206. char FCB[36];
  207. {
  208.     bdos(CLOSE_FILE,FCB);
  209. }
  210. /*-----------------------------------------------------------------*/
  211. /*            SEARCH_FIRST                                         */
  212. /*  Search for first match of file name  ==>  CP/M Function No. 17 */
  213. /*  Returns 255 if file name not found in directory                */
  214. /*  Else returns pointer to location of file name.                 */
  215. /*-----------------------------------------------------------------*/
  216.  
  217. search_first(FCB)
  218. char FCB[36];
  219. {
  220.     bdos(SEARCH_FIRST,FCB);
  221. }
  222. /*-----------------------------------------------------------------*/
  223. /*            SEARCH_NEXT                                          */
  224. /*  Search for next match  ==>  CP/M Function No. 18               */
  225. /*  Can ONLY be used after a successful "search_first".            */
  226. /*  Same return paramaters as for search_first.                    */
  227. /*-----------------------------------------------------------------*/
  228.  
  229. search_next()
  230. {
  231.     bdos(SEARCH_NEXT,0);
  232. }
  233. /*-----------------------------------------------------------------*/
  234. /*            ERASE_FILE                                           */
  235. /*  Erase (delete) the named file from directory                   */
  236. /*  Returns 255 if file not found.                                 */
  237. /*-----------------------------------------------------------------*/
  238.  
  239. erase_file(FCB)
  240. char FCB[36];
  241. {
  242.     bdos(ERASE,FCB);
  243. }
  244. /*-----------------------------------------------------------------*/
  245. /*            READ_SEQ_SEC                                         */
  246. /*  Reads a sector sequentially from opened file                   */
  247. /*  Returns 00h if successful else returns non-zero number         */
  248. /*-----------------------------------------------------------------*/
  249.  
  250. read_seq_sec(FCB)
  251. char FCB[36];
  252. {
  253.     bdos(READ_SECT,FCB);
  254. }
  255. /*-----------------------------------------------------------------*/
  256. /*            WRITE_SEQ_SEC                                        */
  257. /*  Writes a sector sequentially to the opened file                */
  258. /*  Returns 00h if successful else returns non-zero number         */
  259. /*-----------------------------------------------------------------*/
  260.  
  261. write_seq_sec(FCB)
  262. char FCB[36];
  263. {
  264.      bdos(WRITE_SECT,FCB);
  265. }
  266. /*-----------------------------------------------------------------*/
  267. /*            CREATE_FILE                                          */
  268. /*  Creates the file named in the FCB  ==> CP/M Function No. 22    */
  269. /*  Returns 255 if directory is full                               */
  270. /*-----------------------------------------------------------------*/
  271.  
  272. create_file(FCB)
  273. char FCB[36];
  274. {
  275.     bdos(CREATE,FCB);
  276. }
  277. /*-----------------------------------------------------------------*/
  278. /*            GET_DEFAULT                                          */
  279. /*  Get the current default disk No.  ==>  CP/M Function No. 25    */
  280. /*  Returns the code, A = 0, B = 1,...and so on.                   */
  281. /*-----------------------------------------------------------------*/
  282.  
  283. get_default()
  284. {
  285.     bdos(DEFAULT,0);
  286. }
  287. /*-----------------------------------------------------------------*/
  288. /*            SET_DMA                                              */
  289. /*  Sets the DMA (read/write buffer) address                       */
  290. /*  Doesn't return anything                                        */
  291. /*-----------------------------------------------------------------*/
  292.  
  293. set_dma(DMA_BUFF)
  294. short DMA_BUFF[128];
  295. {
  296.     bdos(SETDMA,DMA_BUFF);
  297. }
  298. /*-----------------------------------------------------------------*/
  299. /*            MAKE_RO                                             */
  300. /*  Makes the logical disk selected by "select_dsk" R/O status     */
  301. /*  Doesn't return anything?                                       */
  302. /*-----------------------------------------------------------------*/
  303.  
  304. make_ro()
  305. {
  306.     bdos(READ_ONLY,0);
  307. }
  308. /*-----------------------------------------------------------------*/
  309. /*            SET_ATTRIBUTES                                       */
  310. /*  Sets the attributes in the nominated FCB.   Note these must    */
  311. /*  have the high bit set prior to calling this function.          */
  312. /*  Returns 255 if file not found.                                 */
  313. /*-----------------------------------------------------------------*/
  314.  
  315. set_attributes(FCB)
  316. char FCB[36];
  317. {
  318.     bdos(SET_ATTRIBUTES,FCB);
  319. }
  320. /*-----------------------------------------------------------------*/
  321. /*            USER_ID                                              */
  322. /*  Will set the User No., or get the User No., as instructed      */
  323. /*  Code = 255 to get User No.                                     */
  324. /*       = 0 to 15 to set User No.                                 */
  325. /*  Returns current user number if Code = 255                      */
  326. /*-----------------------------------------------------------------*/
  327.  
  328. user_id(CODE)
  329. short CODE;
  330. {
  331.     bdos(USER_ID,CODE);
  332. }
  333. /*-----------------------------------------------------------------*/
  334. /*  Functions from K & R  ==>  in BDS C                            */
  335. /*-----------------------------------------------------------------*/
  336. /*            BITCOUNT                                             */
  337. /*  Counts the number of "1" bits in a byte (page 47)              */
  338. /*-----------------------------------------------------------------*/
  339.  
  340. bitcount(n)
  341. unsigned n;
  342. {
  343.     short b;
  344.  
  345.     for(b = 0; n != 0; n >>= 1)
  346.         if(n & 01)
  347.             b++;
  348.     return(b);
  349. }
  350. /*-----------------------------------------------------------------*/
  351. /*            BINARY                                               */
  352. /*  Finds whether a binary number occurs in a sorted array (p 54)  */
  353. /*-----------------------------------------------------------------*/
  354.  
  355. binary(x, v, n)
  356. short x, v[], n;
  357. {
  358.     short low, high, mid;
  359.  
  360.     low = 0;
  361.     high = n - 1;
  362.     while(low <= high)
  363.     {
  364.         mid = (low + high)/2;
  365.         if(x < v[mid])
  366.             high = mid - 1;
  367.         else if (x > v[mid])
  368.             low = mid + 1;
  369.         else return(mid);    /* found match */
  370.     }
  371.     return(-1);
  372. }
  373. /*-----------------------------------------------------------------*/
  374. /*            SHELL_SORT                                           */
  375. /*  Sort v[0].....v[n-1] into increasing order  (page 58)          */
  376. /*-----------------------------------------------------------------*/
  377.  
  378. shell_sort(v, n)
  379. short v[], n;
  380. {
  381.     short gap, i, j, temp;
  382.  
  383.     for(gap = n/2; gap > 0; gap = gap/2)
  384.         for(i = gap; i < n; i++)
  385.             for(j = i-gap; j >= 0 && v[j] > v[j+gap];j -= gap)
  386.             {
  387.                 temp = v[j];
  388.                 v[j] = v[j+gap];
  389.                 v[j+gap] = temp;
  390.             }
  391. }
  392. /*-----------------------------------------------------------------*/
  393. /*            REVERSE                                              */
  394. /*  Reverse a NULL-terminated string in place  (page 59)           */
  395. /*-----------------------------------------------------------------*/
  396.  
  397. reverse(s)
  398. char s[];
  399. {
  400.     int c, i, j;
  401.  
  402.     for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
  403.     {
  404.         c = s[i];
  405.         s[i] = s[j];
  406.         s[j] = c;
  407.     }
  408. }
  409. /*-----------------------------------------------------------------*/
  410. /*            ITOA                                                 */
  411. /*  Convert integer into a printable ASCII string  (page 60)       */
  412. /*-----------------------------------------------------------------*/
  413.  
  414. itoa(n,s)
  415. char s[];
  416. short n;
  417. {
  418.     short i, sign;
  419.  
  420.     if(( sign = n) < 0)
  421.         n = -n;        /* make n positive */
  422.     i = 0;
  423.  
  424.     do {
  425.         s[i++] = n % 10 + '0';    /* put digits in reverse */
  426.        }
  427.     while((n /= 10) > 0);
  428.         if(sign < 0)
  429.             s[i++] = '-';
  430.     s[i] = '\0';    /* NULL terminator */
  431.     reverse(s);    /* put into correct order */
  432. }
  433. /*-----------------------------------------------------------------*/
  434. /*            INDEX                                                */
  435. /*  Find index of string t in string s, return -1 if none (p 67)   */
  436. /*-----------------------------------------------------------------*/
  437.  
  438. index(s, t)
  439. char s[], t[];
  440. {
  441.     short i, j, k;
  442.  
  443.     for( i = 0; s[i] != '\0'; i++)
  444.     {
  445.         for(j = i, k = 0; t[k] != '\0' && s[j] == t[k];j++,k++)
  446.         ;
  447.     if(t[k] == '\0')
  448.         return(i);
  449.     }
  450.     return(-1);
  451. }
  452. /*-----------------------------------------------------------------*/
  453. /*            PRINT_DEC                                            */
  454. /*  Print a decimal number to the console  (page 85)               */
  455. /*-----------------------------------------------------------------*/
  456.  
  457. print_dec(n)
  458. short n;
  459. {
  460.     char s[10];
  461.     short i;
  462.  
  463.     if( n < 0)
  464.     {
  465.         putchar('-');
  466.         n = -n;        /* make number positive */
  467.     }
  468.     i = 0;
  469.     if((i = n/10) != 0)
  470.         print_dec(i);
  471.     putchar(n % 10 + '0');
  472. }
  473. /*-----------------------------------------------------------------*/
  474. /*            SWAP_POINTERS                                        */
  475. /*  Interchange two pointers  (page 117)                           */
  476. /*-----------------------------------------------------------------*/
  477.  
  478. swap_pointers(px, py)
  479. char *px[], *py[];
  480. {
  481.     char *temp;
  482.  
  483.     temp = *px;
  484.     *px = *py;
  485.     *py = temp;
  486. }
  487. /*-----------------------------------------------------------------*/
  488. /*  LIBRARY FILE  ==>  isalnum                                     */
  489. /*  Tests whether a character is alpha-numeric                     */
  490. /*  Returns   TRUE/FALSE                                           */
  491. /*-----------------------------------------------------------------*/
  492.  
  493. isalnum(c)
  494. char c;
  495. {
  496.     if(isalpha(c) || ( c >= '0' && c <= '9'))
  497.         return(1);
  498.     else return(0);
  499. }
  500. /*-----------------------------------------------------------------*/
  501. hile((n /= 10) > 0);
  502.         if(sign < 0)
  503.             s[i++] = '-';
  504.     s[i] = '\0';