mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
2517 lines
56 KiB
Plaintext
2517 lines
56 KiB
Plaintext
.tab stops 8,16,24,32,40,48,56,64,72,80
|
||
.rm 65
|
||
.nofill
|
||
.title ^^C Language Under CP/M
|
||
.da Revision 01.07
|
||
.dat Revision 01.07
|
||
.swap toc
|
||
|
||
|
||
.bl 5
|
||
.c
|
||
C Language Under CP/M
|
||
.c
|
||
---------------------
|
||
.bl 2
|
||
.c
|
||
Revision 01.07
|
||
.c
|
||
--------------
|
||
.bl 2
|
||
.c
|
||
September 23, 1982
|
||
.c
|
||
------------------
|
||
.bl 15
|
||
.c
|
||
Digital Research, Inc.
|
||
.c
|
||
P.O. Box 579
|
||
.c
|
||
Pacific Grove, CA 93950
|
||
.c
|
||
(408) 649-3896
|
||
.c
|
||
TWX 910 360 5001
|
||
.bl 4
|
||
.c
|
||
************************
|
||
.c
|
||
* Company Confidential *
|
||
.c
|
||
************************
|
||
.bl 5
|
||
.fill
|
||
Note: This document contains Digital Research proprietary information, and
|
||
must not be copied or distributed for any purpose whatsoever, without
|
||
prior written permission of Digital Research, Inc.
|
||
.bl 1
|
||
Address Comments to: Steve Williams, x6082
|
||
.break
|
||
.swap doc
|
||
.title ^^C Language Under CP/M
|
||
.chapter Introduction
|
||
.title ^^C Language Under CP/M
|
||
.subtitle Introduction
|
||
.page
|
||
.hl 1 Audience
|
||
.i 5
|
||
This document describes the C language implementation available with
|
||
CP/M-68K.
|
||
The intent is to provide both an implementation guide, and a preliminary
|
||
manual for early users. The reader should be familiar with the C language
|
||
as described by Kernighan and Ritchie in "The C Programming Language".
|
||
.bl 1
|
||
.subtitle Philosophy
|
||
.hl 1 Philosophy
|
||
.i 5
|
||
The implementation philosophy is to provide a system which can run
|
||
applications written in C on other operating systems. This usually
|
||
means programs written to run under UNIX. Programs which use the UNIX
|
||
fork/exec multi-tasking primitives or which rely upon reading UNIX file
|
||
structures directly (e.g., directories) obviously cannot be made to run
|
||
under CP/M. The vast majority of UNIX software, however, does not use
|
||
fork/exec except for chaining, and does not read file structure data. It is
|
||
this large body of software with which CP/M C seeks compatibility.
|
||
.subtitle Differences from PCC
|
||
.bl 1
|
||
.hl 1 Differences from PCC
|
||
.i 5
|
||
The most commonly accepted standard for the C language is the Portable C
|
||
Compiler (pcc) written by Stephen C. Johnson, as implemented on UNIX operating
|
||
system (Version 7). This compiler is also used in the Zilog, ONYX, XENIX,
|
||
Berkeley UNIX, and UNIQ systems. The language accepted by pcc is thus
|
||
a defacto standard among UNIX systems.
|
||
.bl 1
|
||
.i 5
|
||
The CP/M C compiler differs from pcc in the following areas:
|
||
.bl 1
|
||
.ls
|
||
.leb;The C "int" (default) data type is 16 bits long. Pointers are 32 bits
|
||
long. Care is required to ensure that all function definitions and function
|
||
calls which use long (32 bit ints) and pointer parameters use the proper
|
||
declarations.
|
||
.leb;"long", "int", and "char" register variables are assigned to "D"
|
||
registers. Five such registers are available in each procedure.
|
||
.leb;Any register variable used as a pointer is assigned to an "A" register.
|
||
There are 3 such registers available per procedure.
|
||
.leb;Floating point is not implemented.
|
||
.leb;Structure assignment, structure arguments, and structures returned from
|
||
procedures are not implemented.
|
||
.leb;All local declarations (within a function body) must precede the first
|
||
executable statement of the function.
|
||
.leb;Initialization of automatic variables is not supported.
|
||
.leb;Enumeration types are not supported.
|
||
.leb;Structure initialization is handled as if the structure were an array of
|
||
short integers, as in UNIX version 6.
|
||
.leb;Variable and function names must be unique in 8 characters. External
|
||
names must be unique in 7 characters.
|
||
.els
|
||
.subtitle Operating Instructions
|
||
.bl 1
|
||
.hl 1 Operating Instructions
|
||
.i 5
|
||
To compile a C program under CP/M, one uses the "c" and "clink" command files.
|
||
Separate compilations are handled easily using this method.
|
||
.bl 1
|
||
The compiler command line is:
|
||
.bl 1
|
||
.i 5
|
||
A>submit c file
|
||
.bl 1
|
||
where "file.c" is the filename. The compiler produces "file.o" as the
|
||
object. The Linker is invoked as follows:
|
||
.bl 1
|
||
.i 5
|
||
A>submit clink file
|
||
.bl 1
|
||
All libraries and header files are included automatically by the command
|
||
file. Multiple files may be specified if desired. For example, to compile
|
||
and link files "a.c", "b.c", and "c.c", the following commands would be
|
||
used:
|
||
.bl 1
|
||
.i 5
|
||
A>submit c a
|
||
.i 5
|
||
A>submit c b
|
||
.i 5
|
||
A>submit c c
|
||
.i 5
|
||
A>submit clink a b c
|
||
.bl 1
|
||
The resulting output would be placed in file "a.68k".
|
||
.subtitle Memory Layout
|
||
.test page 30
|
||
.hl 1 Memory Layout
|
||
.i 5
|
||
C programs under CP/M have a memory layout similar to UNIX C programs. The
|
||
program is divided up into three segments: "text" (instructions), "data"
|
||
(initialized data), and "bss" (uninitialized data). Automatic variables are
|
||
allocated on the stack. These sections are arranged in memory as follows:
|
||
.bl 1
|
||
.nofill
|
||
.lm 8
|
||
+----------------------------------+ TPA Low
|
||
! Text Segment !
|
||
+----------------------------------+ "etext"
|
||
! Data Segment !
|
||
+----------------------------------+ "edata"
|
||
! Bss Segment !
|
||
+----------------------------------+ "end"
|
||
! Heap (grows to higher addresses) !
|
||
+----------------------------------+ "break"
|
||
.
|
||
.
|
||
.
|
||
+----------------------------------+
|
||
! Stack (grows to lower addresses) !
|
||
+----------------------------------+ TPA High
|
||
.bl 1
|
||
.lm 0
|
||
.fill
|
||
There are two dynamic memory areas: the stack and the heap. The stack is
|
||
used for procedure calls and automatic variables. The heap is managed by the
|
||
"brk", "sbrk", "malloc", and "free" procedures described later. This area
|
||
is used for dynamically growing data structures, such as symbol tables.
|
||
.bl 1
|
||
.i 5
|
||
The locations "etext", "edata", and "end" are defined by the linkage
|
||
editor, and may be used to determine the ending addresses of the ".text",
|
||
".data", and ".bss" segments. The "break" location is the first free location
|
||
following the heap area.
|
||
.subtitle Calling Conventions
|
||
.hl 1 Calling Conventions
|
||
.i 5
|
||
Procedures are called in C via the jsr (Jump to Subroutine) instruction. A6
|
||
is used as the frame pointer (for referencing local storage). Arguments are
|
||
pushed (in reverse order) onto the A7 stack. Word and character arguments
|
||
to functions occupy 16 bits on the stack. Long and pointer arguments occupy
|
||
32 bits. D0 is used as the function value return register in all cases.
|
||
Functions which declare no return value will return garbage.
|
||
.bl 1
|
||
.test page 25
|
||
.i 5
|
||
The sequence:
|
||
.nofill
|
||
.bl 1
|
||
xyz() _{
|
||
long a;
|
||
int b;
|
||
char x;
|
||
register y;
|
||
.
|
||
.
|
||
.
|
||
b = blivot(x,a);
|
||
_}
|
||
.bl 1
|
||
Generates:
|
||
.bl 1
|
||
__xyz:
|
||
link a6,_#-8 * space for a,b,x
|
||
movem.l d6-d7,-(a7) * d7 used for "y"
|
||
. * d6 reserves space
|
||
.
|
||
.
|
||
move.l -4(a6),(a7) * Load Parameter "a"
|
||
move.b -8(a6),d0 * Load Parameter "x"
|
||
ext.w d0 * Extend to word size
|
||
move.w d0,-(a7) * Push it
|
||
jsr __blivot * Call subroutine
|
||
add.l _#2,a7 * Pop argument list
|
||
move.w d0,-6(a6) * Store return parameter
|
||
tst.l (a7)+ * Purge longword
|
||
movem.l (a7)+,d7 * Unsave register(s)
|
||
unlk a6 * Restore frame pointer
|
||
rts * Return to caller
|
||
.bl 1
|
||
.fill
|
||
Note that due to the varying length of arguments on the stack, older C code
|
||
which relied on the fact that all arguments were the same length may not work
|
||
without modification.
|
||
.bl 1
|
||
The compiler prepends an underscore ('__') character to the beginning of
|
||
each external variable or function name. This means that all external names
|
||
in C must be unique in 7 characters.
|
||
.bl 1
|
||
The compiler generated code maintains a long word at the top of the stack
|
||
for use in subroutine calls. This shortens the stack popping code
|
||
required on return from a procedure call. The "movem.l" instruction used
|
||
to save the registers contains an extra register to allocate this space.
|
||
.bl 1
|
||
Registers D3-D7 and A3-A5 are used by the compiler for register variables.
|
||
These registers must be saved and restored (if used) by a procedure called
|
||
from a C program. The compiler generated code saves only those registers
|
||
used, as illustrated above.
|
||
Registers D0-D2 and A0-A2 are scratch registers and may
|
||
be modified by the called procedure.
|
||
.subtitle Stack Frame
|
||
.test page 25
|
||
.hl 1 Stack Frame
|
||
The standard C stack frame has the following appearance:
|
||
.bl 1
|
||
.nofill
|
||
.lm 8
|
||
A7 -> +---------------------------------+
|
||
! Longword for procedure calls !
|
||
+---------------------------------+
|
||
! Saved Registers !
|
||
+---------------------------------+
|
||
! Local variable area !
|
||
+---------------------------------+
|
||
A6 -> ! Previous value of A6 !
|
||
+---------------------------------+
|
||
! Return address !
|
||
+---------------------------------+
|
||
! Argument 1 !
|
||
+---------------------------------+
|
||
! Argument 2 !
|
||
+---------------------------------+
|
||
.
|
||
.
|
||
.
|
||
.bl 1
|
||
.fill
|
||
.lm 0
|
||
Arguments are either 2 or 4 bytes, depending on argument type.
|
||
A6 is used by the compiler-generated code to reference all variables on the
|
||
stack.
|
||
.subtitle Command Line Interface
|
||
.hl 1 Command Line Interface
|
||
.i 5
|
||
The standard C "argc/argv" interface for arguments typed on the command line
|
||
also works under CP/M. For instance, the command:
|
||
.bl 1
|
||
.lm 8
|
||
command arg1 arg2 arg3 ... argn
|
||
.bl 1
|
||
.lm 0
|
||
causes the following setup:
|
||
.bl 1
|
||
.lm 8
|
||
.nofill
|
||
argc = n+1
|
||
argv[0] -> "C Runtime"
|
||
argv[1] -> "arg1"
|
||
argv[2] -> "arg2
|
||
.
|
||
.
|
||
.
|
||
argv[n] -> "argn"
|
||
.bl 1
|
||
.lm 0
|
||
.fill
|
||
Note that the command name cannot be obtained under CP/M. The argv[0]
|
||
argument will therefore always be incorrect.
|
||
.subtitle I/O Conventions
|
||
.hl 1 I/O Conventions
|
||
.i 5
|
||
UNIX C programs use two types of file and device I/O: regular files and
|
||
stream files. Regular files are identified by a unique number called a
|
||
"file descriptor". In CP/M, this number is in the range (0-15). Stream
|
||
files are identified by the address of a mysterious control block hidden
|
||
deep in the bowels of the run-time system. (This is a USER control block,
|
||
the file system does not rely on it).
|
||
.bl 1
|
||
.i 5
|
||
Stream files differ from regular files in that some form of intermediate
|
||
buffering is used, making single-byte I/O much more efficient.
|
||
.bl 1
|
||
.i 5
|
||
Under UNIX, printers, terminals, etc. may be referenced as "files", using
|
||
the special names "/dev/tty", "/dev/lp", etc. Under CP/M, these names will
|
||
be "CON:" for the console device, "LST:" for the listing device.
|
||
.bl 1
|
||
.i 5
|
||
ASCII files under CP/M are stored with a carriage return / line feed pair
|
||
following each line. End of file is indicated by a control-Z (0x1a)
|
||
character. C programs typically terminate lines with only a line
|
||
feed. This means that CP/M C library read and write operations to ASCII
|
||
files must insert and delete carriage return characters where appropriate.
|
||
The control-Z must be deleted on read and inserted on close for such files.
|
||
These operations are not desirable for binary files. An extra
|
||
entry point has been added to all file open and creation calls to distinguish
|
||
between ASCII and binary files.
|
||
.subtitle Standard Files
|
||
.hl 1 Standard Files
|
||
.i 5
|
||
C programs begin execution with three files already open. These files are
|
||
known as the standard input, standard output and standard error files, and can
|
||
be accessed as either stream or regular files within the C program. The
|
||
following definitions are available from the <stdio.h> file:
|
||
.bl 1
|
||
.nofill
|
||
.lm 8
|
||
File File Descriptor Stream Name
|
||
---- --------------- -----------
|
||
standard input STDIN stdin
|
||
standard output STDOUT stdout
|
||
standard error STDERR stderr
|
||
.bl 1
|
||
.fill
|
||
.lm 0
|
||
Standard files may be closed and reopened using the usual library routines.
|
||
In addition, I/O redirection is available from the command line.
|
||
.subtitle I/O Redirection
|
||
.hl 1 I/O Redirection
|
||
.i 5
|
||
The C program standard input and standard output may be redirected by using
|
||
the "<" and ">" characters. No space is allowed between the "<" or ">" and
|
||
the filename. The standard error file may not be redirected.
|
||
.bl 1
|
||
.i 5
|
||
For example, the command:
|
||
.bl 1
|
||
.i 8
|
||
test <a >lst: c d e f
|
||
.bl 1
|
||
executes the file "test.68k" with the standard input coming from disk file
|
||
"a" and the standard output going to the listing device. The argument list
|
||
is "c d e f".
|
||
|
||
.chapter Library Routines
|
||
.page
|
||
.c
|
||
Library Routines
|
||
.c
|
||
----------------
|
||
.bl 1
|
||
.i 5
|
||
The CP/M C library is a collection of routines dealing with I/O,
|
||
dynamic memory allocation, system traps, and data conversion.
|
||
Specific routines are provided for running on the 68000 or 8086/88
|
||
processors, as well as for accessing CP/M in a portable fashion.
|
||
.bl 1
|
||
.i 5
|
||
The C Style Guide (Chapter 3) provides important information on writing
|
||
C code in a portable manner. The reader is urged to pay careful attention
|
||
to the material found there.
|
||
.subtitle Differences from UNIX V7
|
||
.hl 1 Differences from UNIX V7
|
||
.i 5
|
||
Much emphasis has been placed on keeping the C library compatible with UNIX
|
||
V7, to allow programs to be easily moved from UNIX to CP/M.
|
||
Many UNIX operating system calls and features have been simulated.
|
||
Certain C functions available under UNIX simply cannot be implemented under
|
||
CP/M:
|
||
.ls
|
||
.leb;The UNIX fork / exec, kill, lock, nice, pause, ptrace, sync, and wait
|
||
primitives require a multi-tasking system, and
|
||
cannot be implemented under CP/M without unreasonable effort and poor
|
||
performance.
|
||
.leb;The UNIX acct system call is not implemented under CP/M.
|
||
.leb;The UNIX alarm function (timer), "stime" (set time), "time", "ftime" and
|
||
"times" system calls
|
||
are meaningless in CP/M, since CP/M
|
||
does not require a clock.
|
||
|
||
.leb;The UNIX "chdir" (Change Directory) system call is not implemented.
|
||
.leb;The UNIX "dup" and "dup2" (duplicate file descriptor) functions are
|
||
not implemented.
|
||
.leb;The UNIX "getuid", "getgid", "geteuid", "getegid", "setuid" and "setgid"
|
||
functions for
|
||
obtaining and setting the group and user IDs of a process are not implemented.
|
||
.leb;The UNIX "indir" (indirect system call) is not available from C under
|
||
UNIX, and is not implemented.
|
||
.leb;The UNIX "ioctl", "stty", and "gtty" system calls for manipulating
|
||
I/O devices are not implemented.
|
||
.leb;The UNIX "link" call to connect one file to another is
|
||
not implemented.
|
||
.leb;The UNIX "chdir", "chroot",
|
||
"mknod", "mount", "umount", "mpx", "pipe", "pkon", "pkoff",
|
||
"profil", "sync",
|
||
"stat", "fstat", "umask" and "utime" system calls
|
||
are UNIX file system specific, and
|
||
are not implemented.
|
||
.leb;The UNIX "phys" system call is not implemented.
|
||
.leb;The following UNIX library functions are not available under CP/M:
|
||
.ls
|
||
.leb;Assert -- program verification routines
|
||
.leb;Crypt -- DES Encryption routines
|
||
.leb;dbm -- Data base management routines
|
||
.leb;Getenv -- environment variable support
|
||
.leb;Getgrent, getlogin, getpw, and getpwent functions for reading the
|
||
login file
|
||
.leb;l3tol, ltol3 -- 3-byte to long conversion routines
|
||
.leb;monitor -- Execution profiling routines
|
||
.leb;itom, madd, msub, mult, mdiv, min, mout, pow, gcd, and rpow multi-word
|
||
integer math routines
|
||
.leb;nlist -- fetch name list values from a UNIX load module
|
||
.leb;pkopen, pkclose, pkread, pkwrite, and pkfail -- UNIX communications
|
||
driver simulation subroutines.
|
||
.leb;plot -- graphics interface
|
||
.leb;popen, pclose -- piping routines
|
||
.leb;sleep
|
||
.leb;system -- Execute UNIX command
|
||
.leb;ttyslot -- Return slot number in UNIX "ttys" file of controlling
|
||
terminal.
|
||
.els
|
||
.els
|
||
The present version of the library does not contain the floating
|
||
point routines available under UNIX.
|
||
.bl 1
|
||
.i 5
|
||
In addition to the above omissions, it was necessary to add entry points
|
||
to file OPEN and CREATE calls to distinguish between ASCII and binary files.
|
||
Byte level End of File is also not available for binary files. ASCII files,
|
||
however, are compatible with UNIX, and with the CP/M text editors and
|
||
other CP/M utilities which use ASCII files.
|
||
.bl 1
|
||
.i 5
|
||
Another incompatibility is that this documentation does not split up the
|
||
UNIX system calls and library functions, since all calls are library
|
||
functions under CP/M.
|
||
|
||
.subtitle abort Function
|
||
.page
|
||
.hl 1 abort Function
|
||
Description:
|
||
.bl 1
|
||
The abort function causes the current program to terminate with a severe
|
||
error. The exact error is system dependent. For the 68000, an Illegal
|
||
Instruction Trap is used. This invokes DDT-68K if the debugger is loaded
|
||
with the object program.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD code;
|
||
.bl 1
|
||
abort(code);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
code Is loaded into register D0 before abort
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.bl 1
|
||
.lm 8
|
||
The abort function never returns.
|
||
.lm 0
|
||
Bugs:
|
||
.bl 1
|
||
.lm 8
|
||
.lm 0
|
||
.fill
|
||
|
||
.subtitle abs Function
|
||
.page
|
||
.hl 1 abs Function
|
||
Description:
|
||
The abs function takes the absolute value of a single argument. This function
|
||
is implemented as a macro (in <stdio.h>), so arguments with side effects
|
||
will not work as expected. In particular, the call:
|
||
.bl 1
|
||
.i 8
|
||
a = abs(*x++);
|
||
.bl 1
|
||
will increment "x" twice.
|
||
.bl 1
|
||
.nofill
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD val;
|
||
WORD ret;
|
||
.bl 1
|
||
ret = abs(val);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
val is the input value
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret is the absolute value of "val"
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle access Function
|
||
.page
|
||
.hl 1 access Function
|
||
Description:
|
||
.bl 1
|
||
The access function checks to see whether a file may be legally accessed
|
||
by the invoking program. Under CP/M, the file may be accessed if it
|
||
exists.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *name;
|
||
WORD mode;
|
||
WORD ret;
|
||
.bl 1
|
||
ret = access(name,mode);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name points to the null-terminate filename
|
||
.bl 1
|
||
mode is 4 to check read access
|
||
2 to check write access
|
||
1 to check exec access
|
||
0 to check directory path access
|
||
(this argument is ignored by CP/M)
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.bl 1
|
||
.lm 8
|
||
0 If access is allowed
|
||
-1 If access is not permitted
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
The only real check made here is to see if the file exists.
|
||
|
||
.subtitle atoi, atol Functions
|
||
.page
|
||
.hl 1 atoi, atol Functions
|
||
Description:
|
||
.bl 1
|
||
The "atoi" and "atol" functions convert an ASCII string to a
|
||
integer, or long (respectively) binary number. Strings converted
|
||
by atoi and atol have the following format:
|
||
.i 8
|
||
.bl 1
|
||
[ ...][-][+]dddddd ....
|
||
.bl 1
|
||
Leading spaces are ignored, and one leading sign is permitted.
|
||
.bl 1
|
||
.nofill
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *string;
|
||
WORD ival;
|
||
LONG lval,atol();
|
||
.bl 1
|
||
ival = atoi(string);
|
||
lval = atol(string);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
.fill
|
||
String is a null-terminated string containing the number to be converted.
|
||
Conversion proceeds until digits are exhausted.
|
||
Zero is returned if no digits are present.
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
Converted value as "ival" (int), or "lval" (long).
|
||
.lm 0
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
There is no provision for overflow detection or reporting.
|
||
It is not possible to limit the number of contiguous digits processed, or to
|
||
determine the number of digits actually processed.
|
||
|
||
.subtitle brk, sbrk Functions
|
||
.page
|
||
.hl 1 brk, sbrk Functions
|
||
Description:
|
||
.bl 1
|
||
The "brk" and "sbrk" functions
|
||
are used to extend the "heap" portion of the user program.
|
||
The "brk" function sets the upper bound of the program (the "break" in
|
||
UNIX terminology) to an absolute address. The "sbrk" function extends the
|
||
program by an incremental amount.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD brk();
|
||
BYTE *addr,*sbrk();
|
||
WORD incr;
|
||
WORD ret;
|
||
BYTE *start;
|
||
.bl 1
|
||
ret = brk(addr);
|
||
start = sbrk(incr)
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
addr Is the desired new break address
|
||
incr Is the incremental number of bytes desired
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
0 Is returned for success (brk)
|
||
-1 Is returned for failure (brk)
|
||
.bl 1
|
||
start Is the beginning of the allocated area (sbrk)
|
||
0 is returned for failure (sbrk)
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle calloc, malloc, realloc, free Functions
|
||
.page
|
||
.hl 1 calloc, malloc, realloc, free Functions
|
||
Description:
|
||
.bl 1
|
||
The "calloc", "malloc", "realloc" and "free" library functions manage the
|
||
dynamic area between the ".bss" region and the stack.
|
||
.bl 1
|
||
"malloc" allocates an area of contiguous bytes (aligned on a word boundary),
|
||
and returns the address of this area. "sbrk" is called to allocate additional
|
||
heap space if needed.
|
||
.bl 1
|
||
"calloc" allocates space for an array of elements, the size of which are
|
||
given in bytes.
|
||
.bl 1
|
||
"realloc" changes the size of a block. The address of the (possibly moved)
|
||
block is returned.
|
||
.bl 1
|
||
"free" is used to release a block previously allocated by "malloc".
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD size,number;
|
||
BYTE *addr,*malloc(),*calloc(),*realloc();
|
||
.bl 1
|
||
addr = malloc(size);
|
||
addr = calloc(number,size);
|
||
addr = realloc(addr,size);
|
||
free(addr);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
size Is the number of bytes desired
|
||
number Is the number of elements desired
|
||
"addr" Points to the allocated region
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
address of the allocated region if successful
|
||
0 if unsuccessful
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Freeing a bogus address can have disastrous consequences.
|
||
|
||
.subtitle chmod, chown Functions
|
||
.page
|
||
.hl 1 chmod, chown Functions
|
||
Description:
|
||
.bl 1
|
||
The "chmod" and "chown" UNIX system calls allow a user under UNIX to change
|
||
the protection and owner ID of an existing file. These calls are treated
|
||
as NO-OPs by CP/M (if the file exists).
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *name;
|
||
WORD mode,owner,group,ret;
|
||
.bl 1
|
||
ret = chmod(name,mode);
|
||
ret = chown(name,owner,group);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name Is the affected filename (null-terminated)
|
||
mode Is the new mode for the file
|
||
owner Is the new owner of the file
|
||
group Is the new group number
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret 0 (success) if file exists
|
||
-1 if file does not exist
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle close Function
|
||
.page
|
||
.hl 1 close Function
|
||
Description:
|
||
.bl 1
|
||
The close function is used to terminate access to a file or device. This
|
||
routine is used on files opened via the "open" or "creat" functions.
|
||
A file descriptor (not a stream) is specified for the operation. Stream files
|
||
are closed via the "fclose" function.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD fd,ret;
|
||
.bl 1
|
||
ret = close(fd);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is the file descriptor to be closed
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
0 For a successful close
|
||
-1 For an unknown file descriptor
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle creat, creata, creatb Functions
|
||
.page
|
||
.hl 1 creat, creata, creatb Functions
|
||
Description:
|
||
.bl 1
|
||
The creat function adds a new file to a disk directory. The file is then
|
||
opened for reference by file descriptor (not a stream file).
|
||
The creat and creata functions create an ASCII file. "Creatb" creates a
|
||
binary file.
|
||
.bl 1
|
||
.nofill
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *name;
|
||
WORD mode,fd;
|
||
.bl 1
|
||
fd = creat(name,mode);
|
||
fd = creata(name,mode);
|
||
fd = creatb(name,mode);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name Is the filename string (null-terminated)
|
||
mode Is the UNIX file mode (ignored by CP/M)
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 16
|
||
.fill
|
||
.bl 1
|
||
.i -8
|
||
fd Is the file descriptor for the opened file. A file descriptor is
|
||
an "int" quantity used to denote an open file in a read, write, or lseek
|
||
call.
|
||
.bl 1
|
||
.i -8
|
||
-1 Is returned if there are any errors.
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
UNIX programs which use binary files will compile successfully, but will not
|
||
execute properly.
|
||
|
||
.subtitle ctype Functions
|
||
.page
|
||
.hl 1 ctype Functions
|
||
Description:
|
||
.bl 1
|
||
The file "<ctype.h>" defines a number of functions used to classify
|
||
ASCII characters. These functions indicate whether a character belongs to
|
||
a certain character class, returning non-zero for true and zero for false.
|
||
.bl 1
|
||
The functions are:
|
||
.bl 1
|
||
.nofill
|
||
isalpha(c) c is a letter
|
||
isupper(c) c is upper case
|
||
islower(c) c is lower case
|
||
isdigit(c) c is a digit
|
||
isalnum(c) c is alphanumeric
|
||
isspace(c) c is a whitespace character
|
||
ispunct(c) c is a punctuation character
|
||
isprint(c) c is a printable character
|
||
iscntrl(c) c is a control character
|
||
isascii(c) c is an ascii character (< 0x80)
|
||
.bl 1
|
||
.fill
|
||
Whitespace characters are defined as the space (0x20), tab (0x09), carriage
|
||
return (0x0d), line feed (0x0a) and form feed (0x0c) characters. Punctuation
|
||
characters are those characters which are not control characters and
|
||
not alphanumeric. Printing characters are defined as space (0x20) through
|
||
tilde (0x7e). A control character is less than space (0x20).
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
_#include <ctype.h>
|
||
.bl 1
|
||
WORD ret;
|
||
BYTE c; /* or WORD c; */
|
||
.bl 1
|
||
ret = isalpha(c);
|
||
ret = isupper(c);
|
||
ret = islower(c);
|
||
ret = isdigit(c);
|
||
ret = isalnum(c);
|
||
ret = isspace(c);
|
||
ret = ispunct(c);
|
||
ret = isprint(c);
|
||
ret = iscntrl(c);
|
||
ret = isascii(c);
|
||
.lm 0
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
c Is the character to be classified
|
||
.bl 1
|
||
.lm 0
|
||
.test page 5
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret = 0 for False
|
||
ret <>0 for True
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
These functions are implemented as macros, so arguments with side effects
|
||
(e.g., "*p++") will not function correctly in all cases.
|
||
.bl 1
|
||
Bogus values are returned if arguments are not ASCII characters (i.e.,
|
||
> 0x7f).
|
||
|
||
.subtitle end, etext, edata Locations
|
||
.page
|
||
.hl 1 end, etext, edata Locations
|
||
Description:
|
||
.bl 1
|
||
The labels "end", "etext", and "edata" are defined by the linkage editor
|
||
to be the first location past the ".bss", ".text", and ".data" regions
|
||
respectively. The program break location (last used location) is initially
|
||
set to "end". This location is altered by many library functions, however.
|
||
The "break" may be retrieved by 'sbrk(0)'.
|
||
|
||
.subtitle exit, __exit Functions
|
||
.page
|
||
.hl 1 exit, __exit Functions
|
||
Description:
|
||
.bl 1
|
||
The "exit" function is used to pass control back to CP/M. An optional
|
||
completion code may be returned. (This is presently ignored by CP/M).
|
||
.bl 1
|
||
All memory is deallocated, and any open files are closed. Buffer flushing
|
||
is also performed for stream output files.
|
||
.bl 1
|
||
"__exit" is used to return control immediately to CP/M without flushing or
|
||
closing open files.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD code;
|
||
.bl 1
|
||
exit(code);
|
||
__exit(code);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
code is the optional return code
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
(none)
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle fclose, fflush Functions
|
||
.page
|
||
.hl 1 fclose, fflush Functions
|
||
Description:
|
||
.bl 1
|
||
fclose and fflush are used to close and flush a stream file, respectively.
|
||
The stream address is used to identify which stream is to be operated on.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
FILE *stream;
|
||
.bl 1
|
||
ret = fclose(stream);
|
||
ret = fflush(stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
stream Is the stream address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
0 If successful
|
||
-1 If bad stream address or write failure
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle feof, ferror, clearerr, fileno Functions
|
||
.page
|
||
.hl 1 feof, ferror, clearerr, fileno Functions
|
||
Description:
|
||
.bl 1
|
||
These functions deal with manipulating file streams in a system-independent
|
||
manner.
|
||
.bl 1
|
||
The "feof" function returns non-zero if a specified stream is at end of
|
||
file, and zero otherwise.
|
||
.bl 1
|
||
"ferror" returns non-zero when an error has occurred on a specified stream.
|
||
"clearerr" clears this error condition. This is useful for functions such
|
||
as "putw" where no error indication is returned for output failures.
|
||
.bl 1
|
||
"fileno" returns the file descriptor associated with an open stream.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
FILE *stream;
|
||
WORD fd;
|
||
.bl 1
|
||
ret = feof(stream);
|
||
ret = ferror(stream);
|
||
clearerr(stream);
|
||
fd = fileno(stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
stream Is the stream address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is a zero or non-zero indicator
|
||
fd Is the returned file descriptor
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle fopen, freopen, fdopen Functions
|
||
.page
|
||
.hl 1 fopen, freopen, fdopen Functions
|
||
Description:
|
||
.bl 1
|
||
The "fopen", "freopen", and "fdopen" functions are used to associate an I/O
|
||
stream with a file or device.
|
||
.bl 1
|
||
"fopen" and "fopena" open an existing ASCII file for I/O as a stream.
|
||
"fopenb" opens an existing binary file for I/O as a stream.
|
||
.bl 1
|
||
"freopen" and "freopa" substitute a new ASCII file in place of an open stream.
|
||
"freopb" substitutes a new binary file in place of an open stream.
|
||
.bl 1
|
||
"fdopen" associates a file which was opened by file descriptor (using
|
||
"open" or "creat") with a stream.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
FILE *fopen(),*fopena(),*fopenb();
|
||
FILE *freopen(),*freopa(),*freopb();
|
||
FILE *fdopen;
|
||
FILE *stream;
|
||
BYTE *name,*access;
|
||
WORD fd;
|
||
.bl 1
|
||
stream = fopen(name,access);
|
||
stream = fopena(name,access);
|
||
stream = fopenb(name,access);
|
||
stream = freopen(name,access,stream);
|
||
stream = freopa(name,access,stream);
|
||
stream = freopb(name,access,stream);
|
||
stream = fdopen(fd,access);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name Is the null-terminated filename string
|
||
.bl 1
|
||
access Is the access string:
|
||
"r" For reading the file
|
||
"w" For writing the file
|
||
"a" For appending to a file
|
||
.bl 1
|
||
stream Is the stream address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
stream Stream address if open was successful
|
||
0 If unsuccessful
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
.test page 10
|
||
Bugs:
|
||
.bl 1
|
||
UNIX programs which use "fopen" on binary files will compile and link
|
||
correctly, but fail to execute properly.
|
||
|
||
.subtitle fread, fwrite Functions
|
||
.page
|
||
.hl 1 fread, fwrite Functions
|
||
Description:
|
||
.bl 1
|
||
"fread" and "fwrite" are used to transfer a stream of bytes between a
|
||
stream file and primary memory.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD nitems;
|
||
BYTE *buff;
|
||
WORD size;
|
||
FILE *stream;
|
||
.bl 1
|
||
nitems = fread(buff,size,nitems,stream);
|
||
nitems = fwrite(buff,size,nitems,stream);
|
||
.lm 0
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
buff Is the primary memory buffer address
|
||
size Is the number of bytes in each item
|
||
nitems Is the number of items to transfer
|
||
stream Is an open stream file
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
nitems The number of items actually read / written
|
||
0 If an error occurred (including EOF)
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle fseek, ftell, rewind Functions
|
||
.page
|
||
.hl 1 fseek, ftell, rewind Functions
|
||
Description:
|
||
.bl 1
|
||
The "fseek", "ftell", and "rewind" functions are used in positioning a stream
|
||
file.
|
||
.bl 1
|
||
"fseek" sets the read / write pointer to an arbitrary offset in the stream.
|
||
"rewind" sets the read / write pointer to the beginning of the stream.
|
||
These calls have no effect on the console device or the listing device.
|
||
.bl 1
|
||
The "ftell" function returns the present value of the read / write pointer
|
||
within the stream. This call returns a meaningless value for non-file
|
||
devices.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
FILE *stream;
|
||
LONG offset,ftell();
|
||
WORD ptrname;
|
||
.bl 1
|
||
ret = fseek(stream,offset,ptrname);
|
||
ret = rewind(stream);
|
||
offset = ftell(stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
stream Is the stream address
|
||
offset Is a signed offset measured in bytes
|
||
ptrname Is the sense of offset:
|
||
.bl 1
|
||
0 => from beginning of file
|
||
1 => from current position
|
||
2 => from end of file
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret 0 for success; -1 for failure
|
||
offset present offset in stream
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
ASCII file seek and tell operations do not account for carriage returns
|
||
which will eventually be deleted. Control-Z characters at the end of the
|
||
file are handled correctly.
|
||
|
||
.subtitle getc, getchar, fgetc, getw, getl Functions
|
||
.page
|
||
.hl 1 getc, getchar, fgetc, getw, getl Functions
|
||
Description:
|
||
.bl 1
|
||
The "getc", "getchar", "fgetc", "getw", and "getl"
|
||
functions are used to perform
|
||
input from a stream.
|
||
.bl 1
|
||
"getc" reads a single character from an input stream. This function is
|
||
implemented as a macro in <stdio.h>, and arguments should not have
|
||
side effects.
|
||
.bl 1
|
||
"getchar" reads a single character from the standard input. It is identical
|
||
to "getc(stdin)" in all respects.
|
||
.bl 1
|
||
"fgetc" is a function implementation of "getc", used to reduce object code
|
||
size.
|
||
.bl 1
|
||
"getw" reads a word (16 bits)
|
||
from the stream, high byte first (compatible with "read"
|
||
function call). No special alignment is required.
|
||
.bl 1
|
||
"getl" reads a long (32 bits) from the stream, in 68000 byte order. No
|
||
special alignment is required.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ichar;
|
||
FILE *stream;
|
||
WORD iword;
|
||
LONG ilong,getl();
|
||
.bl 1
|
||
ichar = getc(stream);
|
||
ichar = getchar();
|
||
ichar = fgetc(stream);
|
||
iword = getw(stream);
|
||
ilong = getl(stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
stream Is the stream address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ichar Character read from stream
|
||
iword Word read from stream
|
||
ilong Long word read from stream
|
||
-1 On read failures
|
||
.lm 0
|
||
.fill
|
||
.test page 6
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Error return from getchar is incompatible with UNIX version 6 and previous.
|
||
.bl 1
|
||
Error return from getl or
|
||
getw is a valid value which might occur in the
|
||
file normally. Use feof or ferror to detect end of file or read error.
|
||
|
||
.subtitle getpass Function
|
||
.page
|
||
.hl 1 getpass Function
|
||
Description:
|
||
.bl 1
|
||
The "getpass" function reads a password from the console device. A prompt
|
||
is output, and the input read without echoing. A pointer is returned to
|
||
a 0-8 character null-terminated string.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *prompt;
|
||
BYTE *getpass;
|
||
BYTE *pass;
|
||
.bl 1
|
||
pass = getpass(prompt);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
prompt Is a null-terminated prompt string
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
pass points to the password read
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
The return value points to static data whose content is overwritten by
|
||
each call.
|
||
|
||
.subtitle getpid Function
|
||
.page
|
||
.hl 1 getpid Function
|
||
Description:
|
||
.bl 1
|
||
The getpid function is a bogus routine which returns a phony "process id".
|
||
This routine is strictly for UNIX compatibility, and serves no useful purpose
|
||
under CP/M. The return value is unpredictable in some implementations.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD pid;
|
||
.bl 1
|
||
pid = getpid();
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
(none)
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
pid Phony "process id"
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle gets, fgets Functions
|
||
.page
|
||
.hl 1 gets, fgets Functions
|
||
Description:
|
||
.bl 1
|
||
"gets" and "fgets" are used to read strings from stream files. "fgets" reads
|
||
a string including a newline (line feed) character. "gets" deletes the
|
||
newline, and reads only from the standard input. Both terminate the strings
|
||
with a null character.
|
||
.bl 1
|
||
A maximum count is specified with fgets, but not with gets. This maximum
|
||
count includes the terminating null character.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *addr;
|
||
BYTE *s;
|
||
BYTE *gets(),*fgets();
|
||
WORD n;
|
||
FILE *stream;
|
||
.bl 1
|
||
addr = gets(s);
|
||
addr = fgets(s,n,stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s Is the string buffer area address
|
||
n Is the maximum character count
|
||
stream Is the input stream
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
addr Is the string buffer address
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle index, rindex Functions
|
||
.page
|
||
.hl 1 index, rindex Functions
|
||
Description:
|
||
.bl 1
|
||
The index and rindex functions are used to locate a given character in a
|
||
string. "index" returns a pointer to the first occurrence of the character,
|
||
while "rindex" returns a pointer to the last occurrence.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE c;
|
||
BYTE *s;
|
||
BYTE *ptr;
|
||
BYTE *index(),*rindex();
|
||
.bl 1
|
||
ptr = index(s,c);
|
||
ptr = rindex(s,c);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s Is a null-terminated string pointer
|
||
c Is the character to look for
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ptr The desired character address
|
||
0 If character not in the string
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle isatty Function
|
||
.page
|
||
.hl 1 isatty Function
|
||
Description:
|
||
.bl 1
|
||
The "isatty" function can be used by a CP/M C program to determine if a
|
||
file descriptor is attached to the CP/M console device ("CON:").
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD fd;
|
||
WORD ret;
|
||
.bl 1
|
||
ret = isatty(fd);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is an open file descriptor
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
1 If fd attached to CON:
|
||
0 Otherwise
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle lseek, tell Functions
|
||
.page
|
||
.hl 1 lseek, tell Functions
|
||
Description:
|
||
.bl 1
|
||
"lseek" is used to position a file
|
||
referenced by file descriptor to an
|
||
arbitrary offset. This function should not be used with stream files, due
|
||
to the possibility of stale data in the stream buffer.
|
||
The "fseek" function should be used instead.
|
||
.bl 1
|
||
"tell" is used to determine the file offset of an open file descriptor.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD fd;
|
||
WORD ptrname;
|
||
LONG offset,lseek(),tell(),ret;
|
||
.bl 1
|
||
ret = lseek(fd,offset,ptrname);
|
||
ret = tell (fd);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is the open file descriptor
|
||
offset Is a signed byte offset in the file
|
||
ptrname Is the interpretation of "offset":
|
||
.bl 1
|
||
0 => from the beginning of the file
|
||
1 => from the current file position
|
||
2 => from the end of the file
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret resulting absolute file offset
|
||
-1 If an error occurs
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Incompatible with versions 1-6 of UNIX
|
||
|
||
.subtitle mktemp Function
|
||
.page
|
||
.hl 1 mktemp Function
|
||
Description:
|
||
.bl 1
|
||
The "mktemp" function is used to create a temporary filename. The calling
|
||
argument is a character string ending in 6 "X" characters. These characters
|
||
are overwritten with the temporary filename.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *string;
|
||
BYTE *mktemp();
|
||
.bl 1
|
||
string = mktemp(string)
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
string Is the address of the template string
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
string Is the original address argument
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle open, opena, openb Functions
|
||
.page
|
||
.hl 1 open, opena, openb Functions
|
||
Description:
|
||
.bl 1
|
||
The open and opena functions open an existing ASCII
|
||
file by file descriptor. The openb function opens an existing binary file.
|
||
The file may
|
||
be opened for reading, writing, or updating.
|
||
.bl 1
|
||
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *name;
|
||
WORD mode;
|
||
WORD fd;
|
||
.bl 1
|
||
fd = open(name,mode);
|
||
fd = opena(name,mode);
|
||
fd = openb(name,mode);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name Is the null-terminated filename string
|
||
.bl 1
|
||
mode Is the access desired:
|
||
0 => read only
|
||
1 => write only
|
||
2 => read/write (update)
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
fd Is the file descriptor for accessing the file
|
||
-1 Indicates open failure
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
UNIX programs which use binary files will compile correctly, but will not
|
||
execute properly.
|
||
|
||
.subtitle perror Function
|
||
.page
|
||
.hl 1 perror Function
|
||
Description:
|
||
.bl 1
|
||
The "perror" function produces a short message on the standard error file
|
||
which gives a description of the last system error encountered. An argument
|
||
string is printed first, then a colon, followed by the message.
|
||
.bl 1
|
||
The UNIX notion of an external variable, "errno", which contains the last
|
||
error returned from the operating system is simulated.
|
||
A list of the possible values of "errno" and of the messages printed by
|
||
"perror" is given in Appendix A.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *s;
|
||
.bl 1
|
||
perror(s);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.i 8
|
||
s Is the prefix string to be printed
|
||
.bl 1
|
||
Returns:
|
||
.bl 1
|
||
.i 8
|
||
(none)
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
.lm 8
|
||
.fill
|
||
Many messages are "Error undefined on CP/M".
|
||
.lm 0
|
||
|
||
.subtitle printf, fprintf, sprintf Functions
|
||
.page
|
||
.hl 1 printf, fprintf, sprintf Functions
|
||
Description:
|
||
.bl 1
|
||
The printf family of functions is used to format data for output. "printf"
|
||
outputs to the standard output stream. "fprintf" outputs to an arbitrary
|
||
stream file. "sprintf" outputs to a string (memory).
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
BYTE *fmt;
|
||
FILE *stream;
|
||
BYTE *string;
|
||
BYTE *sprintf(),rs;
|
||
/* Args can be any type */
|
||
.bl 1
|
||
ret = printf (fmt,arg1,arg2 ...);
|
||
ret = fprintf(stream,fmt,arg1,arg2 ...);
|
||
rs = sprintf(string,fmt,arg1,arg2 ...);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fmt Is a format string with conversion specifiers
|
||
argn Are data arguments to be converted
|
||
stream Is an output stream file
|
||
string Is a buffer address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Number of characters output
|
||
-1 if error
|
||
rs Buffer string address
|
||
Null (zero) if error
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Conversion Operators
|
||
.bl 1
|
||
The occurrence of a "%" character in the format string indicates the start of
|
||
a conversion operator. Values to be converted are obtained from the argument
|
||
list in order. Valid Conversion operators are:
|
||
.bl 1
|
||
.ls
|
||
.lec 'd' Convert a binary number to decimal ASCII and insert in output stream.
|
||
.lec 'o' Convert a binary number to octal ASCII and insert in output stream.
|
||
.lec 'x' Convert a binary number to hexadecimal ASCII and insert in output
|
||
stream.
|
||
.lec 'c' Use the argument as a single ASCII character.
|
||
.lec 's' Use the argument as a pointer to a null-terminated ASCII string, and
|
||
insert the string into the output stream.
|
||
.lec 'u' Convert a binary number to decimal ASCII (unsigned) and insert in
|
||
output stream.
|
||
.lec '%' Print a '%' character.
|
||
.els
|
||
Between the '%' character and the conversion operator, the following optional
|
||
information may be present:
|
||
.ls
|
||
.leb;An optional minus sign which specifies that the converted output be
|
||
left-adjusted rather than the default right adjustment.
|
||
.leb;An optional digit string specifying a field width. This value gives the
|
||
minimum width of the field. If the digit string begins with a '0' character,
|
||
then zero padding will be done instead of blank padding.
|
||
If an asterisk ("*") is used, the value of the width field will be taken as
|
||
the next argument in the argument list.
|
||
.leb;A '.' character which separates the field width from the precision
|
||
string.
|
||
.leb;A digit string which specifies the precision for floating point
|
||
conversion. (i.e., the number of digits following the decimal point).
|
||
If an asterisk ("*") is used, the value of the precision field will be taken
|
||
from the next argument in the argument list.
|
||
.leb;The character "l" or "L" which specifies that a long value (32 bits)
|
||
is to be converted. A capitalized conversion code will accomplish the
|
||
same thing.
|
||
.els
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle putc, putchar, fputc, putw, putl Functions
|
||
.page
|
||
.hl 1 putc, putchar, fputc, putw, putl Functions
|
||
Description:
|
||
.bl 1
|
||
The "putc", "putchar", "fputc", and "putw" functions are used to output
|
||
characters and words (16-bits) to stream files.
|
||
.bl 1
|
||
The "putc" function outputs a single 8-bit character to a stream file. This
|
||
function is implemented as a macro in <stdio.h>, so arguments with side
|
||
effects should not be used. "fputc" provides the equivalent function as
|
||
a real function.
|
||
.bl 1
|
||
The putchar function outputs a character to the standard output stream file.
|
||
This function is also implemented as a macro in <stdio.h>. Side effects
|
||
should be avoided with putchar.
|
||
.bl 1
|
||
The "putw" function outputs a 16-bit word to the specified stream file. The
|
||
word is output high byte first, compatible with the write function call.
|
||
.bl 1
|
||
The "putl" function outputs a 32-bit longword to the stream file. The bytes
|
||
are output in 68000 order, as with the "write" function call.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE c;
|
||
FILE *stream;
|
||
WORD w,ret;
|
||
LONG lret,putl(),l;
|
||
.bl 1
|
||
ret = putc(c,stream);
|
||
ret = fputc(c,stream);
|
||
ret = putchar(c);
|
||
ret = putw(w,stream);
|
||
lret = putl(l,stream);
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
c Is the character to be output
|
||
stream Is the output stream address
|
||
w Is the word to be output
|
||
l Is the long to be output
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is the word or character output
|
||
lret Is the long output with putl
|
||
-1 Indicates an output error
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
A -1 return from "putw" or "putl" is a perfectly valid integer or long
|
||
value. "ferror" should
|
||
be used to detect write errors.
|
||
|
||
.subtitle puts, fputs Functions
|
||
.page
|
||
.hl 1 puts, fputs Functions
|
||
Description:
|
||
.bl 1
|
||
"puts" and "fputs" are used to output a null-terminated string to an output
|
||
stream.
|
||
.bl 1
|
||
"puts" outputs the string to the standard output, and appends a newline
|
||
character.
|
||
.bl 1
|
||
"fputs" outputs the string to a named output stream. No newline character
|
||
is appended.
|
||
.bl 1
|
||
Neither routine copies the trailing null to the output stream.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
BYTE *s;
|
||
FILE *stream;
|
||
.bl 1
|
||
ret = puts(s);
|
||
ret = fputs(s,stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s Is the string to be output
|
||
stream Is the output stream
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is the last character output
|
||
-1 Indicates an error
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
The newline incompatibility is not very elegant, but is required to be
|
||
compatible with UNIX.
|
||
|
||
.subtitle qsort Function
|
||
.page
|
||
.hl 1 qsort Function
|
||
Description:
|
||
.bl 1
|
||
"qsort" is a quicksort routine. The user supplies a vector of elements
|
||
and a function to compare two elements. The vector is returned in sorted
|
||
order.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
BYTE *base;
|
||
WORD number;
|
||
WORD size;
|
||
WORD compare();
|
||
.bl 1
|
||
ret = qsort(base,number,size,compare);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
base Is the base address of the element vector
|
||
number Is the number of elements to sort
|
||
size Is the size of each element in bytes
|
||
compare Is the address of the comparison function
|
||
.bl 1
|
||
This function is called by:
|
||
.bl 1
|
||
ret = compare(a,b);
|
||
.bl 1
|
||
The return is:
|
||
.bl 1
|
||
< 0 if a < b
|
||
= 0 if a = b
|
||
> 0 if a > b
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
0 always
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle rand, srand Functions
|
||
.page
|
||
.hl 1 rand, srand Functions
|
||
Description:
|
||
.bl 1
|
||
"rand" and "srand" constitute the C language random number generator. The
|
||
generator is initialized by calling "srand" with the seed, and random numbers
|
||
are retrieved by calls to "rand". The random numbers are C "int" quantities.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD seed;
|
||
WORD rnum;
|
||
.bl 1
|
||
rnum = srand(seed);
|
||
rnum = rand();
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
seed Is an "int" random number seed
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
rnum Desired random number
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle read Function
|
||
.page
|
||
.hl 1 read Function
|
||
Description:
|
||
.bl 1
|
||
The "read" function is used to read data from a file opened by file descriptor
|
||
(using "open" or "creat"). Any arbitrary number of bytes may be read,
|
||
starting at the current file pointer.
|
||
.bl 1
|
||
Under CP/M, the most efficient reads begin and end on 128-byte boundaries.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
WORD fd;
|
||
BYTE *buffer;
|
||
WORD bytes;
|
||
.bl 1
|
||
ret = read(fd,buffer,bytes);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is a file descriptor open for read
|
||
buffer Is the buffer address
|
||
bytes Is the number of bytes to be read
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Number of bytes actually read
|
||
-1 Indicates error
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle scanf, sscanf, fscanf Functions
|
||
.page
|
||
.hl 1 scanf, sscanf, fscanf Functions
|
||
Description:
|
||
.bl 1
|
||
The scanf family of functions is used to do input format conversions. "scanf"
|
||
reads from the standard input, "fscanf" reads from an open stream file, and
|
||
"sscanf" reads from a null-terminated string.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *format,*string;
|
||
WORD nitems;
|
||
FILE *stream;
|
||
/* Args can be any type */
|
||
.bl 1
|
||
nitems = scanf(format,arg1,arg2 ...);
|
||
nitems = fscanf(stream,format,arg1,arg2 ...);
|
||
nitems = sscanf(string,format,arg1,arg2 ...);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
format Is the control string
|
||
argn Are pointers to converted data locations
|
||
stream Is an open input stream file
|
||
string Is a null-terminated input string
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
nitems The number of items converted
|
||
-1 If an I/O error occurred
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Control String Format
|
||
.bl 1
|
||
The control string consists of:
|
||
.ls
|
||
.leb;Blanks, tabs, or newlines (line feeds) which match optional white
|
||
space in the input.
|
||
.leb;An ASCII character (not '%') which must match the next character of the
|
||
input stream.
|
||
.leb;Conversion specifications, which consist of a leading '%', an optional
|
||
'*' (which suppresses assignment), and a conversion character. The next
|
||
input field is converted and assigned to the next argument, up to the
|
||
next inappropriate character in the input, or until the field width is
|
||
exhausted.
|
||
.els
|
||
Conversion characters indicate the interpretation of the next input field.
|
||
Valid conversion characters are:
|
||
.ls
|
||
.lec '%###'A single '%' is matched in the input at this point; no conversion
|
||
is performed.
|
||
.lec 'd###'A decimal ASCII integer is converted and stored where the next
|
||
argument points.
|
||
.lec 'o###'An octal ASCII integer is converted.
|
||
.lec 'x###'A hexadecimal ASCII integer is converted.
|
||
.lec 's###'A space-terminated character string is input. The argument pointer
|
||
is assumed to point to a character array big enough to contain the string
|
||
and a trailing null character (which will be added).
|
||
.lec 'c###'A single ASCII character will be stored. Spaces are not skipped.
|
||
To find the next non-blank character, "%1s" should be used.
|
||
.lec '_[##'#A string not terminated by spaces is stored. The left bracket is
|
||
followed by a string of characters and a right bracket. If the first
|
||
character following the bracket is not "_^", the input will be read up
|
||
until the first character not between the brackets. If the first character
|
||
following the left bracket is "_^", then the input will be read until the
|
||
first character which is between the brackets.
|
||
.els
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
The success of literal matches and suppressed assignments cannot be
|
||
determined.
|
||
|
||
.subtitle setjmp, longjmp Functions
|
||
.page
|
||
.hl 1 setjmp, longjmp Functions
|
||
Description:
|
||
.bl 1
|
||
Setjmp and longjmp are used to execute a "non-local goto". The setjmp
|
||
function is called initially to specify a return location. Longjmp may then
|
||
be called from the procedure which invoked setjmp or any procedure which is
|
||
called subsequently. Longjmp causes a simulated return from setjmp in the
|
||
procedure which originally invoked setjmp. A setjmp
|
||
return value is passed from the
|
||
longjmp call.
|
||
The procedure invoking setjmp must not return before
|
||
longjmp is called.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
_#include <setjmp.h>
|
||
WORD xret,ret;
|
||
jmp__buf env;
|
||
.
|
||
.
|
||
.
|
||
xret = setjmp(env);
|
||
.
|
||
.
|
||
.
|
||
longjmp(env,ret);
|
||
.lm 0
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
env Contains the saved environment
|
||
ret Is the desired return value from setjmp
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
xret 0 when setjmp invoked initially
|
||
Copied from "ret" when longjmp called
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Definitely kludgy.
|
||
|
||
.subtitle signal Function
|
||
.page
|
||
.hl 1 signal Function
|
||
Description:
|
||
.bl 1
|
||
The signal function connects a C function with a 68000 exception condition.
|
||
Each possible exception condition is indicated by a number. The following
|
||
exceptions are recognized:
|
||
.ls
|
||
.lec '4' Illegal Instruction Trap (Includes illegal instructions, privilege
|
||
violation, and Line A and Line F traps).
|
||
.lec '5' Trace Trap
|
||
.lec '6' Trap Instruction other than 2 or 3 (used by BDOS and BIOS).
|
||
.lec '8' Arithmetic traps (Zero Divide, CHK instruction, and TRAPV
|
||
instruction).
|
||
.lec '10' BUSERR (non-existant memory) or addressing (boundary) error trap.
|
||
.els
|
||
All other values are ignored, to be compatible with UNIX.
|
||
.bl 1
|
||
Return from the procedure activated by the signal causes
|
||
resumption of normal processing. Registers and condition codes are
|
||
preserved by the library routines.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret,sig;
|
||
WORD func();
|
||
.bl 1
|
||
ret = signal(sig,func);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
sig Is the signal number given above
|
||
func Is the address of a C function
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret 0 if no error, -1 if sig out of range
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle strcat, strncat Functions
|
||
.page
|
||
.hl 1 strcat, strncat Functions
|
||
Description:
|
||
.bl 1
|
||
Functions "strcat" and "strncat" are used for string concatenation. "strcat"
|
||
concatenates two null-terminated strings. "strncat" copies at most a
|
||
specified number of characters.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *s1,*s2,*ret;
|
||
BYTE *strcat(),*strncat();
|
||
WORD n;
|
||
.bl 1
|
||
ret = strcat(s1,s2);
|
||
ret = strncat(s1,s2,n);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s1 Is the first string.
|
||
s2 Is the second string, appended to s1.
|
||
n Is the maximum number of characters in s1.
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is a pointer to s1
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
"strcat(s1,s1)" never terminates, and usually destroys the operating system
|
||
in the process.
|
||
|
||
.subtitle strcmp, strncmp Functions
|
||
.page
|
||
.hl 1 strcmp, strncmp Functions
|
||
Description:
|
||
.bl 1
|
||
The "strcmp" and "strncmp" functions are used for string comparison. "strcmp"
|
||
uses null termination, and "strncmp" limits the comparison to a specified
|
||
number of characters.
|
||
.bl 1
|
||
.nofill
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *s1,*s2;
|
||
WORD val,n;
|
||
.bl 1
|
||
val = strcmp(s1,s2);
|
||
val = strncmp(s1,s2,n);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s1 Is a null-terminated string address
|
||
s2 Is a null-terminated string address
|
||
n Is the maximum number of characters to compare
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
val Is the comparison result:
|
||
.bl 1
|
||
< 0 => s1 < s2
|
||
= 0 => s1 = s2
|
||
> 0 => s1 > s2
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Different machines (and compilers)
|
||
interpret the characters as signed or unsigned.
|
||
|
||
.subtitle strcpy, strncpy Functions
|
||
.page
|
||
.hl 1 strcpy, strncpy Functions
|
||
Description:
|
||
.bl 1
|
||
"strcpy" and "strncpy" are used to copy one null-terminated string to
|
||
another. "strcpy" uses null-termination, while "strncpy" imposes a maximum
|
||
count on the copied string.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *s1,*s2,*ret;
|
||
BYTE *strcpy(),*strncpy();
|
||
WORD n;
|
||
.bl 1
|
||
ret = strcpy(s1,s2);
|
||
ret = strncpy(s1,s2,n);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s1 Is the destination string
|
||
s2 Is the source string
|
||
n Is the maximum character count
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is the address of s1
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
If the count is exceeded in strncpy, the destination string is not
|
||
null-terminated.
|
||
|
||
.subtitle strlen Function
|
||
.page
|
||
.hl 1 strlen Function
|
||
Description:
|
||
.bl 1
|
||
"strlen" returns the length of a null-terminated string.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *s;
|
||
WORD len;
|
||
.bl 1
|
||
len = strlen(s);
|
||
.lm 0
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
s Is the string address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
len Is the string length
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle swab Function
|
||
.page
|
||
.hl 1 swab Function
|
||
Description:
|
||
.bl 1
|
||
The "swab" function is used to copy an area of memory to another area
|
||
of memory. The high and low bytes in the destination copy are reversed.
|
||
This function may be used to copy binary data from a PDP-11 or VAX to the
|
||
68000. The number of bytes to swap must be even.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
BYTE *from,*to;
|
||
WORD nbytes;
|
||
.bl 1
|
||
ret = swab(from,to,nbytes);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
from Is the address of the source buffer
|
||
to Is the address of the destination
|
||
nbytes Is the number of bytes to copy
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Always 0
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle ttyname Function
|
||
.page
|
||
.hl 1 ttyname Function
|
||
Description:
|
||
.bl 1
|
||
"ttyname" returns a pointer to the null-terminated filename of the terminal
|
||
device associated with an open file descriptor.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE *name,*ttyname();
|
||
WORD fd;
|
||
.bl 1
|
||
name = ttyname(fd);
|
||
.lm 0
|
||
.bl 1
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is an open file descriptor
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.fill
|
||
.bl 1
|
||
A pointer to the null-terminated string "CON:" if the file descriptor is
|
||
open and attached to the CP/M console device. Zero (NULL) is returned
|
||
otherwise.
|
||
.lm 0
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle ungetc Function
|
||
.page
|
||
.hl 1 ungetc Function
|
||
Description:
|
||
.bl 1
|
||
"ungetc" pushes a character back onto an input stream. The next "getc",
|
||
"getw", or "getchar" operation will incorporate the character. One character
|
||
of buffering is guaranteed, provided something has been read from the stream.
|
||
The "fseek" function erases any pushed back
|
||
characters.
|
||
Attempts to "ungetc" EOF (-1) are rejected.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
BYTE c;
|
||
FILE *stream;
|
||
WORD ret;
|
||
.bl 1
|
||
ret = ungetc(c,stream);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
c Is the character to push back
|
||
stream Is the stream address
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret c if the character successfully pushed back
|
||
-1 for errors
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle unlink Function
|
||
.page
|
||
.hl 1 unlink Function
|
||
Description:
|
||
.bl 1
|
||
The unlink function deletes a named file from the file system. The removal
|
||
operation fails if the file is presently open, or if the file does not
|
||
exist.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD ret;
|
||
BYTE *name;
|
||
.bl 1
|
||
ret = unlink(name);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
name Is the null-terminated filename
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
0 If unlink operation successful
|
||
-1 If unlink operation failed
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
|
||
.subtitle write Function
|
||
.page
|
||
.hl 1 write Function
|
||
Description:
|
||
.bl 1
|
||
The "write" function transfers data to a file open by file descriptor.
|
||
Transfer begins at the present file pointer, as set by previous transfers or
|
||
by the "lseek" function. Any arbitrary number of bytes may be written to the
|
||
file. The number of bytes actually written is returned. It is an error
|
||
condition when the number of bytes written does not match the number
|
||
requested.
|
||
.bl 1
|
||
Under CP/M, the most efficient writes begin and end on 128-byte boundaries.
|
||
.nofill
|
||
.bl 1
|
||
Calling Sequence:
|
||
.bl 1
|
||
.lm 8
|
||
WORD fd;
|
||
BYTE *buffer;
|
||
WORD bytes;
|
||
WORD ret;
|
||
.bl 1
|
||
ret = write(fd,buffer,bytes);
|
||
.bl 1
|
||
.lm 0
|
||
Arguments:
|
||
.bl 1
|
||
.lm 8
|
||
fd Is the open file descriptor
|
||
buffer Is the starting buffer address
|
||
bytes Is the number of bytes to write
|
||
.bl 1
|
||
.lm 0
|
||
Returns:
|
||
.lm 8
|
||
.bl 1
|
||
ret Is the number of bytes actually written
|
||
-1 For errors
|
||
.lm 0
|
||
.fill
|
||
.bl 1
|
||
Bugs:
|
||
.bl 1
|
||
Due to the buffering scheme used, all data is not written to the file until
|
||
the file is closed.
|