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 >
Wrap
Text File
|
1985-11-14
|
18KB
|
504 lines
/*-----------------------------------------------------------------*/
/* LIBRARY FUNCTIONS ==> written by Phil Cogar */
/* For BDS C under CP/M 2.2 using the "BDOS" Function */
/* */
/* This file contains the following functions - */
/* */
/* CGET CPUT DIRECTC */
/* CLRSCREEN LISTC GET_IOBYTE */
/* SET_IOBYTE PRT_STR READ_STR */
/* CON_STAT GET_CPM RESET_DSK */
/* SELECT_DSK OPEN_FILE CLOSE_FILE */
/* SEARCH_FIRST SEARCH_NEXT CREATE_FILE */
/* ERASE_FILE READ_SEQ_SEC WRITE_SEQ_SEC */
/* GET_DEFAULT SET_DMA MAKE_RO */
/* SET_ATTRIBUTES USER_ID BITCOUNT */
/* BINARY SHELL_SORT REVERSE */
/* ITOA INDEX PRINT_DEC */
/* SWAP_POINTERS ISALNUM */
/* */
/* all of which are described in DEFF3.TXT and are */
/* contained in the linking file ==> DEFF3.CRL */
/* Copyright 1986 - Cogar Computer Services Pty. Ltd. */
/*-----------------------------------------------------------------*/
#include "pec.h" /* definitions required */
/*=================================================================*/
/* CGET */
/* Read Console Byte ==> CP/M Function No. 1 */
/* Note will read any BYTE value from the console */
cget()
{
bdos(READ,0);
}
/*-----------------------------------------------------------------*/
/* CPUT */
/* Write Console Byte ==> CP/M Function No. 2 */
/* Note will send any BYTE value to the console */
cput(c)
int c;
{
bdos(WRITE,c);
}
/*-----------------------------------------------------------------*/
/* CLRSCREEN */
/* Clear screen function for Hazeltine Esprit terminal */
clrscreen()
{
cput(126);
cput(28);
}
/*-----------------------------------------------------------------*/
/* LISTC */
/* List byte to line printer */
listc(c)
int c;
{
bdos(LIST, c);
}
/*-----------------------------------------------------------------*/
/* DIRECTC */
/* Use direct console IN/OUT ==> CP/M function No. 6 */
/* Note: DUTY = IN = 0FFH */
/* = OUT = character to be printed to screen */
/* Returns either the input character or Reg. A = 0 */
/*-----------------------------------------------------------------*/
#define IN 255 /* Character in function */
directc(DUTY)
int DUTY;
{
bdos(DCIO,DUTY);
}
/*-----------------------------------------------------------------*/
/* GET_IOBYTE */
/* Get IOBYTE setting */
/* Returns the current IOBYTE setting */
/*-----------------------------------------------------------------*/
get_iobyte()
{
bdos(IOBYTE,0);
}
/*-----------------------------------------------------------------*/
/* SET_IOBYTE */
/* Sets the IOBYTE */
/* Doesn't return anything */
/*-----------------------------------------------------------------*/
set_iobyte(IOB)
short IOB; /* new IOBYTE setting */
{
bdos(SET_IOBYTE,IOB);
}
/*-----------------------------------------------------------------*/
/* PRT_STR */
/* Print a "$" terminated string to the console */
/* Doesn't return anything */
/*-----------------------------------------------------------------*/
prt_str(BUFF)
char *BUFF; /* pointer to string buffer */
{
bdos(PRT_STRING,BUFF);
}
/*-----------------------------------------------------------------*/
/* READ_STR */
/* Read a "RETURN" terminated string from the console */
/* Note: The CR doesn't form part of the string. As written */
/* ---- this function terminates the string with a null. */
/*-----------------------------------------------------------------*/
#define BUFF_LEN 134 /* maximum number of characters */
read_str(BUFF)
short *BUFF;
{
short n;
for(n = 0; n <= BUFF_LEN; n++)
{
BUFF[n] = '\0'; /* Initialise string with NULL's */
}
BUFF[0] = BUFF_LEN; /* must tell CP/M buffer size */
bdos(READ_STRING,BUFF);
}
/*-----------------------------------------------------------------*/
/* CON_STAT */
/* Read the console status ==> CP/M Function No. 11 */
/* Returns NULL if no character waiting, else returns 0FFH */
/*-----------------------------------------------------------------*/
con_stat()
{
bdos(CON_STATUS,0);
}
/*-----------------------------------------------------------------*/
/* GET_CPM */
/* Get CP/M Version Number */
/* Number is returned in HL with the details - */
/* */
/* H = 00H for CP/M or H = 01H for MP/M */
/* L = 00H for all releases prior to 2.0 */
/* L = 20H for release 2.0, 21H for release 2.1, 22H for */
/* release 2.2, and so on. */
/*-----------------------------------------------------------------*/
get_cpm()
{
bdos(CPM_NUM,0);
}
/*-----------------------------------------------------------------*/
/* RESET_DSK */
/* Reset the disk system */
/* Typically used after a disk is changed */
/* Does not return anything */
/*-----------------------------------------------------------------*/
reset_dsk()
{
bdos(RESET,0);
}
/*-----------------------------------------------------------------*/
/* SELECT_DSK */
/* Select logical disk ==> CP/M Function No. 14 */
/* This makes the nominated disk the default disk */
/* Note: Drive A = 00H */
/* ---- Drive B = 01H, and so on */
/*-----------------------------------------------------------------*/
select_dsk(DISK)
short DISK;
{
toupper(DISK); /* make this upper case */
DISK = DISK - 66; /* convert to A = 0, B = 1, etc */
bdos(LOGICAL,DISK);
}
/*-----------------------------------------------------------------*/
/* OPEN_FILE */
/* Open a file ==> CP/M Function No. 15 */
/* To use this you must have previously formulated a File */
/* Control Block (FCB) using setfcb(fcbaddr, filename) */
/* Returns the Directory code in Register A, or 0FFH if it failed */
/* Note particularly the nominated FCB must be declared for use */
/* GLOBALLY so that it can be known by other functions. */
/*-----------------------------------------------------------------*/
open_file(FCB)
char FCB[36];
{
bdos(OPEN_FILE,FCB);
}
/*-----------------------------------------------------------------*/
/* CLOSE_FILE */
/* Close a file ==> CP/M Function No. 16 */
/* Will close the file named in the FCB */
/* Same exit parameters as for "open_file" */
close_file(FCB)
char FCB[36];
{
bdos(CLOSE_FILE,FCB);
}
/*-----------------------------------------------------------------*/
/* SEARCH_FIRST */
/* Search for first match of file name ==> CP/M Function No. 17 */
/* Returns 255 if file name not found in directory */
/* Else returns pointer to location of file name. */
/*-----------------------------------------------------------------*/
search_first(FCB)
char FCB[36];
{
bdos(SEARCH_FIRST,FCB);
}
/*-----------------------------------------------------------------*/
/* SEARCH_NEXT */
/* Search for next match ==> CP/M Function No. 18 */
/* Can ONLY be used after a successful "search_first". */
/* Same return paramaters as for search_first. */
/*-----------------------------------------------------------------*/
search_next()
{
bdos(SEARCH_NEXT,0);
}
/*-----------------------------------------------------------------*/
/* ERASE_FILE */
/* Erase (delete) the named file from directory */
/* Returns 255 if file not found. */
/*-----------------------------------------------------------------*/
erase_file(FCB)
char FCB[36];
{
bdos(ERASE,FCB);
}
/*-----------------------------------------------------------------*/
/* READ_SEQ_SEC */
/* Reads a sector sequentially from opened file */
/* Returns 00h if successful else returns non-zero number */
/*-----------------------------------------------------------------*/
read_seq_sec(FCB)
char FCB[36];
{
bdos(READ_SECT,FCB);
}
/*-----------------------------------------------------------------*/
/* WRITE_SEQ_SEC */
/* Writes a sector sequentially to the opened file */
/* Returns 00h if successful else returns non-zero number */
/*-----------------------------------------------------------------*/
write_seq_sec(FCB)
char FCB[36];
{
bdos(WRITE_SECT,FCB);
}
/*-----------------------------------------------------------------*/
/* CREATE_FILE */
/* Creates the file named in the FCB ==> CP/M Function No. 22 */
/* Returns 255 if directory is full */
/*-----------------------------------------------------------------*/
create_file(FCB)
char FCB[36];
{
bdos(CREATE,FCB);
}
/*-----------------------------------------------------------------*/
/* GET_DEFAULT */
/* Get the current default disk No. ==> CP/M Function No. 25 */
/* Returns the code, A = 0, B = 1,...and so on. */
/*-----------------------------------------------------------------*/
get_default()
{
bdos(DEFAULT,0);
}
/*-----------------------------------------------------------------*/
/* SET_DMA */
/* Sets the DMA (read/write buffer) address */
/* Doesn't return anything */
/*-----------------------------------------------------------------*/
set_dma(DMA_BUFF)
short DMA_BUFF[128];
{
bdos(SETDMA,DMA_BUFF);
}
/*-----------------------------------------------------------------*/
/* MAKE_RO */
/* Makes the logical disk selected by "select_dsk" R/O status */
/* Doesn't return anything? */
/*-----------------------------------------------------------------*/
make_ro()
{
bdos(READ_ONLY,0);
}
/*-----------------------------------------------------------------*/
/* SET_ATTRIBUTES */
/* Sets the attributes in the nominated FCB. Note these must */
/* have the high bit set prior to calling this function. */
/* Returns 255 if file not found. */
/*-----------------------------------------------------------------*/
set_attributes(FCB)
char FCB[36];
{
bdos(SET_ATTRIBUTES,FCB);
}
/*-----------------------------------------------------------------*/
/* USER_ID */
/* Will set the User No., or get the User No., as instructed */
/* Code = 255 to get User No. */
/* = 0 to 15 to set User No. */
/* Returns current user number if Code = 255 */
/*-----------------------------------------------------------------*/
user_id(CODE)
short CODE;
{
bdos(USER_ID,CODE);
}
/*-----------------------------------------------------------------*/
/* Functions from K & R ==> in BDS C */
/*-----------------------------------------------------------------*/
/* BITCOUNT */
/* Counts the number of "1" bits in a byte (page 47) */
/*-----------------------------------------------------------------*/
bitcount(n)
unsigned n;
{
short b;
for(b = 0; n != 0; n >>= 1)
if(n & 01)
b++;
return(b);
}
/*-----------------------------------------------------------------*/
/* BINARY */
/* Finds whether a binary number occurs in a sorted array (p 54) */
/*-----------------------------------------------------------------*/
binary(x, v, n)
short x, v[], n;
{
short low, high, mid;
low = 0;
high = n - 1;
while(low <= high)
{
mid = (low + high)/2;
if(x < v[mid])
high = mid - 1;
else if (x > v[mid])
low = mid + 1;
else return(mid); /* found match */
}
return(-1);
}
/*-----------------------------------------------------------------*/
/* SHELL_SORT */
/* Sort v[0].....v[n-1] into increasing order (page 58) */
/*-----------------------------------------------------------------*/
shell_sort(v, n)
short v[], n;
{
short gap, i, j, temp;
for(gap = n/2; gap > 0; gap = gap/2)
for(i = gap; i < n; i++)
for(j = i-gap; j >= 0 && v[j] > v[j+gap];j -= gap)
{
temp = v[j];
v[j] = v[j+gap];
v[j+gap] = temp;
}
}
/*-----------------------------------------------------------------*/
/* REVERSE */
/* Reverse a NULL-terminated string in place (page 59) */
/*-----------------------------------------------------------------*/
reverse(s)
char s[];
{
int c, i, j;
for(i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
/*-----------------------------------------------------------------*/
/* ITOA */
/* Convert integer into a printable ASCII string (page 60) */
/*-----------------------------------------------------------------*/
itoa(n,s)
char s[];
short n;
{
short i, sign;
if(( sign = n) < 0)
n = -n; /* make n positive */
i = 0;
do {
s[i++] = n % 10 + '0'; /* put digits in reverse */
}
while((n /= 10) > 0);
if(sign < 0)
s[i++] = '-';
s[i] = '\0'; /* NULL terminator */
reverse(s); /* put into correct order */
}
/*-----------------------------------------------------------------*/
/* INDEX */
/* Find index of string t in string s, return -1 if none (p 67) */
/*-----------------------------------------------------------------*/
index(s, t)
char s[], t[];
{
short i, j, k;
for( i = 0; s[i] != '\0'; i++)
{
for(j = i, k = 0; t[k] != '\0' && s[j] == t[k];j++,k++)
;
if(t[k] == '\0')
return(i);
}
return(-1);
}
/*-----------------------------------------------------------------*/
/* PRINT_DEC */
/* Print a decimal number to the console (page 85) */
/*-----------------------------------------------------------------*/
print_dec(n)
short n;
{
char s[10];
short i;
if( n < 0)
{
putchar('-');
n = -n; /* make number positive */
}
i = 0;
if((i = n/10) != 0)
print_dec(i);
putchar(n % 10 + '0');
}
/*-----------------------------------------------------------------*/
/* SWAP_POINTERS */
/* Interchange two pointers (page 117) */
/*-----------------------------------------------------------------*/
swap_pointers(px, py)
char *px[], *py[];
{
char *temp;
temp = *px;
*px = *py;
*py = temp;
}
/*-----------------------------------------------------------------*/
/* LIBRARY FILE ==> isalnum */
/* Tests whether a character is alpha-numeric */
/* Returns TRUE/FALSE */
/*-----------------------------------------------------------------*/
isalnum(c)
char c;
{
if(isalpha(c) || ( c >= '0' && c <= '9'))
return(1);
else return(0);
}
/*-----------------------------------------------------------------*/
hile((n /= 10) > 0);
if(sign < 0)
s[i++] = '-';
s[i] = '\0';