2000
Invoking BDS C using C.SUB
Overview of the BDS C Language System
Overview -- C Compiler, Pass 1
Overview -- C Compiler, Pass 2
Overview -- C Linker
Overview -- C Librarian
Overview -- C Skeleton File
Variable Types
Braces
Variable Accessing
ARIES-1 C Library
Special I/O using CIO
:Invoking BDS C using C.SUB

     BDS  C  may  be invoking either by the conventional means  or  by 
using  the  SUBMIT file C.SUB.   If the SUBMIT file  is  used,  it  is 
engaged as follows --

          SUBMIT C filename

where  'filename'  is the name of 'filename.C',  the file to  compile.  
Note that the user is NOT to to type filename.C,  but is just to  type 
filename.

     As  execution  of the two passes of the compiler and  the  linker 
proceeds,  the  user  will be given the chance to abort processing  at 
various  critical  points  in  the process by  the  execution  of  the 
ABORTSUB  program.   If  an  error has occurred  during  the  previous 
processing, ABORT when this program is executed.


:Overview of the BDS C Language System

	The main components of C are: 4 executable programs,
a standard library file, and one skeleton run-time subroutine
file.

A description of each follows:
:Overview -- C Compiler, Pass 1

CC1:	Because C loads the entire source file into memory
	in one shot, the compilation is broken up into two
	phases (not "passes", strictly; The two phases end
	up taking about 8 passes to actually implement),
	maximizing the amount of memory available for the
	source file.
	CC1, the first half of the compiler, accepts a C
	source file with any filename and extension (say,
	"foo.c") and writes out a temporary file (with the
	same filename and extension ".CCI") containg a symbol
	table and an encoded form of the source code.

	The file extension ".C" is NOT assumed for the
	input file, so saying "FOO" for "FOO.C" would not
	work.


	If the source file name is preceded by a disk
	designation, then the input is taken from the specified
	disk and the ouput is also written to that disk.

	If any errors are detected during CC1, the output
	file will not be written.

	In addition to the name of the source file, a few
	options may also be specified on the command line
	by preceding the option list with a dash (-):

	s 	causes undeclared identifiers to be implicitly
	        declared as integer variables, wherever possible.

	hex digit (4-f)  sets symbol table size to the 
			 specified value (in K bytes);
			 default is 8 (5 for versions x.xT.)
	

	For example,
		A>cc1 foobar.c -s6
	supresses errors for undefined variables and sets 
	symbol table size to 6K bytes;
		A>cc1 zot.c -e
	sets symbol table size to 14K bytes.
	Note that the option list must contain no blanks.
		A>cc1 b:td.c
	takes the source file from disk B and writes the .CCI
	file to disk B (regardless of what the currently logged
	disk is.)

	On an 8080, speed is about 12 lines source/sec.

:Overview -- C Compiler, Pass 2

CC2:	This is the second half of the compiler. CC2 accepts
	a ".CCI" file as input, and writes out a ".CRL" file
	if no errors are detected. (CRL is mnemonic for
	'C ReLocatable')

	If all goes well, writing out of the CRL file is
	followed by deletion of the "CCI" file, and 
	compilation is complete.

	As for CC1, if a disk is specified explicitly as in
		A>cc2 c:yahoo
	then the .CCI file is loaded from the specified disk
	and the .CRL file is written to that same disk.

	On an 8080, execution time =  about 35 lines/sec.

:Overview -- C Linker

CLINK:	This program links a "main" function from some
	CRL file together with C.CCC (for common system
	subroutines) and any subordinate functions which
	"main" may require (from perhaps many CRL files).

	A successful linkage causes a ".COM" file to be
	generated. At this point, the 8080 absolute
	machine code file is ready to be executed (for
	better or worse) as a transient command by CP/M.

	The first argument on the command line must be the
	name of a CRL file containing a "main" function. If
	the name is specified with an extension, then that
	extension is interpreted specially as indicating
	which disks are to be involved in the operation (this
	is akin to the mechanism ASM uses to determine source
	and destination disks.)

	For example, if the first argument to CLINK were
	given as:
		A>clink foo.bc
	then CLINK would interpret the "b" in ".bc" as 
	specifying the disk on which "DEFF.CRL" and "C.CCC" are
	to be found, and the "c" in ".bc" as specifying which
	disk the .COM file is to be written to. Both of these
	values, if omitted, default to the currently logged in
	disk.
	The first argument may also be preceded by a disk
	designation, to specify where all .CRL files are to be
	searched for (by default). For example, the command
		A>clink b:zot.ac
	tells CLINK to get C.CCC and DEFF.CRL from disk A; to
	write the ouput file to disk C; and to find ZOT.CRL on
	disk B.


	Any other CRL files to search may also be specified
	on the command line (WITHOUT their .CRL suffixes),
	causing those to be searched in the order specified.
	The default disk to search will be the same disk from
	which the original CRL file was taken; this default
	can be overridden by specifying an explicit disk
	designation for any appropriate CRL file name needing
	it. For example,
		A>clink c:foo.bb bar a:zot fraz
	causes disk C to be searched for the files FOO.CRL,
	BAR.CRL and FRAZ.CRL, while disk A would be searched
	to find ZOT.CRL. Disk B is where CLINK would expect
	DEFF.CRL and C.CCC to reside, and the output would go
	to disk B also.


	When all given CRL files have been searched, CLINK
	will automatically search DEFF.CRL.

	If there are still some unresolved references, then
	CLINK will ask for input from the keyboard to try
	resolving them.

	There are also several options which may be
	specified on the command line. Each option must
	be preceded by a dash (-); the space between
	options and their argument (if needed) is optional.
	The presently supported options are:

	-s		Prints out load statistics;
	-t nnnn		Reserves location nnnn (hex) and
			above for user; default is to 
			reserve no space. What this really
			does is to cause the first op in
			the object file to be
				lxi sp,nnnn
			instead of
				lxi sp,bdos.
	-o name		Causes the .COM file generated to
			have the given name. Default is 
			the name of the first .CRL file
			given (the one with the "main"
			function.)

	-e xxxx		Sets start of data area to address
			xxxx, to maintain consistency between
			several separate .COM files when
			chaining (via the library function
			"exec") is used.
	-c		Specifies that the .COM file is to
			be chained to from another .COM file.
			If the resultant .COM file is invoked
			directly from CP/M instead of via the
			"exec" function, then ARGC & ARGV
			processing is suspended, since upon
			being chained to you wouldn't want
			ARGC & ARGV processing to take place.
				Note that if you use this
			option, you should also use the -e
			option to set the data area address
			equal to that of the chaining .COM
			file.
	


	Examples:
		A>clink foo bar
	gets "main" from the file FOO.CRL, searches for
	needed functions first in FOO.CRL and then, if needed,
	in BAR.CRL and DEFF.CRL. All files are assumed to 
	reside on the currently logged in disk.

		A>clink b:ihtfp belle -s
	searches for IHTFP.CRL and BELLE.CRL on disk B; prints
	a statistics summary when linkage is complete. The 
	files DEFF.CRL and C.CCC are assumed to reside on the
	currently logged in disk; output also goes to the
	currently logged in disk.

		A>clink b:ihtfp.aa -s belle -o zot
	is the same as the last example except: the output
	file is called ZOT.COM, DEFF.CRL and C.CCC are assumed
	to reside on A, and output goes to A.


		A>clink stoned -t7000 -s
	sets top of memory to 7000h and prints out load
	statistics. Current disk used for everything.

	Note that if the load statistics tell you that
	the "LAST ADDRESS" is greate
2000
r than the "TOP OF
	MEMORY", the program hasn't got the chance of a
	snowball in hell of running correctly.

:Oveview -- C Librarian

CLIB:	This program maintains .CRL files, allows transfer
	of functions from one CRL file to another, etc. To
	invoke CLIB, just type 
			A>clib
	Clib will print a line such as
		FUNCTION BUFFER SIZE = nnnnn
	specifying the largest function size that can be
	handled. Attempting to "transfer" or "extract" a 
	function larger than this size could be destructive.

	Next CLIB will prompt with a "*". Typing "h" at 
	this point will give you a command summary.

	Basically, you work CLIB by opening one to six
	CRL files (which then become associated with	
	"file numbers"), diddling the files to your hearts
	content, closing all files which you altered, and
	typing control-C.


	The old version of any CRL file you change with CLIB
	is renamed to name.BRL (for Backup ReLative).

	A sample session of CLIB to, say, transfer the 
	functions named "FOO", "BAR", and "ZOT" from
	a .CRL file named "DSSR" to one named "RTS" would
	go as follows:


	A>clib

	BD SOFTWARE C LIBRARIAN VERSION x.x
	FUNCTION BUFFER SIZE = xxxx BYTES

	* open 0 dssr
	* open 1 rts
	* t 0 1 foo
	* t 0 1 bar
	* t 0 1 zot
	* c 1
	* ^C

	A> ...


	The "open" commands prepare to do work on a .CRL file,
	and associate each .CRL file opened with a digit (0-5).
	The "transfer" commands tell CLIB to transfer the
	named function from the first file (named by file #)
	to the second file (also named by number).
	The "close" command need only be given for files
	which have been altered; since DSSR wasn't written
	to in the above example, it didn't need to be closed,
	but RTS did need to be closed.


DEFF.CRL:  This file contains the standard function library...
	   all 60+ functions worth. See the BDS C User's Guide
	   for documentation on these functions.
:Overview -- C Skeleton File

C.CCC:	The run-time skeleton file, containing code for
	processing the command line (generating argc and
	argv, for you UNIX lovers), room for file I/O
	buffers, some math subroutines, etc.



	Note on the BDS C compiler:

	THIS IS NOT AN INTERPRETER.

	Some hacks, such as BASIC-E, are billed as compilers
	but actually just do some preprocessing and then
	interpret the program. BDS C is a true compiler,
	generating not-too-optimal but nevertheless quick
	8080 code.

	For the gory details on the BDS C implementation, see
	my notes to APPENDIX A of the EXCELLENT book  
		"The C Programming Language."

:Variable Types

	Variable types supported:
	int 	char	unsigned	struct	union
	arrays (of one or two dimensions)
	pointers
	simple combinations of the above

	For example,
			char *foo[10][15];
	declares foo to be a two dimensional array of
	pointers to characters;

			char (*foo)();
	declares foo to be a pointer to a function returning
	a character;

			char *foo, bar, zot[10];
	declares foo to be a pointer to characters, bar to
	be a single char variable, ant zot to be an array
	of 10 characters.

:Braces

	If your keyboard doesn't support the '{' and '}'
	characters (open and close brace, for those of
	you whose printer doesn't know about ascii 7B and
	7D), the symbols 'begin' and 'end' may be 
	substituted. Don't unless you have to; '{' and '}'
	take up less memory.
	The CONVERT program will perform this conversion,
	if necessary.

:Variable Accessing

	Since all functions in C may be used recursively, all
	variable accessing is done relative to a base-of-
	stack-frame pointer, kept in the BC register pair
	during execution. Note that it takes 8 bytes of code
	to transfer a simple local variable whose address is
		(Base of stack pointer) + foo
	to the HL register pair; The code appears as:

		lxi h,foo
		dad b
		mov a,m
		inx h
		mov h,m
		mov m,a .
	To get an array element or structure element is even
	more hairy. Facts like this are enough to make me 
	REALLY wish Intel had bothered to implement a double
	byte indirect load instruction. Oh well.

:ARIES-1 C Library

     The  following  are the names of the routines available in the  C 
Library DEFF.CRL.   They are listed here as a memory convenience,  and 
refer to the manual for further details.

1.  General Purpose Functions

     csw()          exit()         bdos(c,de)          peek(n)
     poke(n,b)      inp(n)         outp(n,b)           pause()
     sleep(n)       call(adr,h,a,b,d)                  abs(n)
     srand(n)       rand()         setmem(adr,count,byte)
     movmem(source,dest,count)     qsort(base,nel,width,compar)
       char *source, *dest;          char *base; int(*compar)();
     exec(name)
       char *name;

2.  Character Input/Output

     getchar()      ungetch(c)     kbhit()             putchar(c)
     puts(str)      char *gets(str)
       char *str;     char *str;
     printf(format,arg1,arg2,...)  scanf(format,arg1,arg2,...)
       char *format;                 char *format;

3.  String and Character Processing

     isalpha(c)     isupper(c)     islower(c)     isdigit(c)
       char c;        char c;        char c;        char c;
     touppper(c)    tolower(c)     isspace(c)     strcat(s1,s2)
       char c;        char c;        char c;        char *s1, *s2;
     strcmp(s1,s2)  strcpy(s1,s2)  strlen(str)    atoi(str)
      char *s1,*s2;  char *s1,*s2;  char *str;     char *str;
     initw(array,string)           initb(array,string)
       int *array; char *string;     char *array, *string;
     getval(strptr)
       char **strptr;

4.  File I/O

     creat(filename)               unlink(filename)
       char *filename;               char *filename;
     open(filename,mode)           close(fd)
       char *filename;
       {mode=0 - input, mode=1 - output, mode=2 - input and output}
     read(fd,buf,nbl)              write(fd,buf,nbl)
       char *buf;                    char *buf;
     seek(fd,offset,code)          tell(fd)
     fopen(filename,iobuf)         fcreat(filename,iobuf)
       char *filename;               char *filename;
       struct buf *iobuf;            struct buf *iobuf;
     getc(iobuf)                   putc(c,iobuf)
       struct buf *iobuf;            char c; struct buf *iobuf;
     getw(iobuf)                   putw(w,iobuf)
       struct buf *iobuf;            struct buf *iobuf;
     fflush(iobuf)
       struct buf *iobuf;

5.  Plotting Functions (for Memory-Mapped Video Boards)

     setplot(base,xsize,ysize)
     clrplot()
     plot(x,y,chr)
       char chr;
     txtplot(string,x,y,ropt)
       char *string;
     line(c,x1,y1,x2,y2)

6.  Plotting Functions for Hazeltine 1500

     clear()
     cplot(x,y,chr)
       char chr;
     ctxtplot(x,y,string)
       char *string;

7.  Special I/O -- CIO

     cio(fn) or cio(fn,arg)

          CIO indexes directly into the BIOS Jump Table.   'fn' is the 
index offset,  and 'arg' is an argument passed (up to 16  bits).   The 
offsets and functions permitted are --

     Offset    Function

       0       CONST -- Console status;  Returned value = 0 if no char 
                 ready, 255 if char ready
       1       CONIN -- Console input; Returned value = char typed
       2       CONOUT -- Console output; Input value = char to output
       3       LIST -- List output; Input value = char to output
       4       PUNCH -- Punch output; Input value = char to output
       5       READER -- Reader input; Returned value = char input
:Special I/O using CIO

     CIO is called by --

               cio(fn) or cio(fn,arg)

     CIO indexes directly into the BIOS Jump Table.  'fn' is the index 
offset,  and 'arg' is an argument passed (up to 16 bits).  The offsets 
and functions permitted are --

     Offset    Function

       0       CONST -- Console status;  Returned value = 0 if no char 
                 ready, 255 if char ready
       1       CONIN -- Console input; Returned value = char typed
       2       CONOUT -- Console output; Input value = char to output
       3       L
100
IST -- List output; Input value = char to output
       4       PUNCH -- Punch output; Input value = char to output
       5       READER -- Reader input; Returned value = char input

0

