@tabsize 4
@author "Henk Robbers"
@node "A Home Cooked C compiler"
@subject "AHCC V4.a"

	Welcome to Ansi HCC

	AHCC is a Pure C compatible C compiler for Atari ST and its offspring.

	Installation of this distribution

	Changes since first release

	Gem integration:
		Editor
		Quick guide to the main menu
		Quick guide to the window menu
		The KIT
		Project file

	Free standing:
		Disclaimer
		Compiler/Assembler
		Linker
		Shell/Compiler/Assembler/Linker

	Standard library
	Object format

	Important read:
		Introduction to the notion 'area'

	specific AHCC features
	A taste of C99
	How to combine C and Assembly in a .C file.

	Throughout this manual the word Enter applies to Return evenly.

	Henk Robbers.
	december 2011

@endnode

@node "Changes since first"

	march 20 2012
	v4.10
		General:
			Some reorganization of debug code.
			It is now possible to write intermediate code
			(IXC, aka "interchange code") to a .i file alongside
			the object code.
			This option has been disentangled from other debug code.
			The IXC might be of interest to the curious user, but it is
			basically of use to myself when there are problems.
			I dont need to recompile AHCC and compile other peoples
			code. I can ask a user to send me the IXC.
		
		Shell:
			Name of loaded project is now shown in the menu bar.
			always visible. Display menu entry removed.
			Split menu title 'Project'.
			No need for menu entry 'Assemble',
			  'Compile' will do just fine.
			Entry removed.
			Use HIDETREE to disable the debug menu.
			(DISABLED was cleared by Boxkite after a selector action).
			This caused some confusion.

			Accept names without extension in the project file.
			They now default to .c

		Compiler:
			Flag an error on a unclosed comment.
			Detect differences in prototypes regarding qualifiers.
			e.g: p(const char *); vs p(char *){...}
			
			Fixed a subtle bug in the optimizer. (Fixes Marathon)

		Coldfire:
		    Fixed wrong code where a pushed float was used in a call.
		    Fixed wrong code when casting float to unsigned long.

		Assembler:
			accept operands of the form (a,b) and (e,f,g)
			where a is a 16 bit constant and e is a 8 bit constant.
			generate a(b) resp. e(f,g) where possible.

		Library:
			Added function 'delay'.

	januari 24 2012
	v4.9
		Compiler:			
			Fixed a extremely stupid bug where comparisons of the kind
			'constant compared to variable' were reversed wrongly.
			e.g. (0 < i)

			Fixed a terrible bug where under certain circumstances
			a ftst insstruction got lost.
			
			Accept spurious ampersand to a function name to get a
			reference to that function.

			There are FPU instruction that are NOT unary operaters.
			These are: fmod, modf, ldexp and frexp.
			Put these function in ahccstd.lib.
		
			Fixed wrong code with comma expressions within expressions.

		  Coldfire:
			Fix in the Coldfire Floating point code table.

			Do not generate addressing mode 6 (An,Xn) with floating point
			instructions.
			
			Do not generate FScc instructions.
			Repaired wrong divide for pointer difference calculation.

		Library:
			stdio.c: function tmpfile added.
			string.c: function strtoul added.
			stdlib.c: function system added.
			ahccstdf.lib
			Added support for missing FPU instructions on Coldfire.

	november 28 2011
	v4.8
		Compiler:
			Fix a crash that sometimes could occur when a local
				initializer was absent or was wrong.
			Fix a crash when a while expression is wrong or absent.
			Allow {} around any local initializer.

			Deny arrays of void.
			Deny returning of arrays.

			Fixed a regression since 4.7 leading to incorrect code
			in rare situations.

			Fix a error preventing floating constants of the form:
			nE-n from compiling correctly.

			Coldfire:
			Fix incorrect code when a temporary was needed
			from a memory location.
			
		Library:
			Fixed a leftover from Sozobon, where a floating point
			integral part could not exceed |2^31|.
			
			Changed v_pie --> v_pieslice

	november 14 2011
	v4.7
		Compiler:
			Slight reduction of spurious error messages.

			Wrong code was generated when converting a real
			to unsigned long.

			New header file stdbool.h
			small fixes in compiler.h

			Fixed a error when a input name is a filename only,
			     no slashes.

			Fixed a mistake with eliminating the false side of a
			expression of the form:  constant ? x : y
				where the true side is a binary operation.

		  For Coldfire:
			Small fix in the new code tables for Coldfire.
			Affects long mul/div.

			Cleanup of Coldfire code generator.
			Intruduction of code table for assignment.
			Many fixes in the code for Coldfire floating point.

			In rare cases the optimizer must split a move.
			If no registers are available a pusher is generated.
			(Until now a message "no free reg" was displayed in stead.)
			Fixed a bug in a table causing some registers to be
			kept alive indefinately, causing the above split.

		Editor:
			'_' is a alphanumeric character for bold display.

		Kit:
			Replaced checkbox 'word' by 3 radiobuttons:
				whole word
				word begin
				anywhere

			Which makes it possible to find a string that is the
			beginning of a word. (e.g. prefixes).

		Library:
			gemf.lib
			Fix a confusion in gemf.h
				removed #define gl_apid _app
				The 2 names have NOT the same meaning.

			ahccgem.lib, ahccgemf.lib
			Fix in appl_init regarding returning of application
				identifier.

	june 24 2011
	v4.6
		Compiler:
			Cast condition code to int on unary plus/minus to
			comparisons.	(think about it :-)
			Also a fix in condition code casting for Coldfire.
			Fixed a regression since V3.b4 where differences
			between a function prototype and its actual declaration
			were not error flagged anymore.

		Assembler:
			Coldfire instruction set completed. The set is complete,
			but check for specific Coldfire restrictions on already
			existing instructions is not performed yet.
			This will be done in a future release.
			You can run the new Digger V8 on object files for
			checking validity of your Coldfire code.

		Library:
			Created library ahccstfi.lib.
			A standard library for Coldfire but without floating
			point. Affects particularly printf and scanf.
			For coldfire compatible programs not needing floating
			point that one would like to run on a Falcon witout FPU.

			Added function _crystal() and vdi() and struct _VDIParBlk
			for programs that submit extra bindings based on the
			Pure C GEM library.

	june 14 2011
	v4.5
		Compiler:
			Fixed a regression since 4.4 causing a alignment error
			   when a bitfield was followed by a plain char declaration.

			Optimization of table switch such that large gaps
			  between groups of close case values are dealt with
			  efficiently.

			Correction in table switch for Coldfire code.
			Index scaling by shift: long.
			Promote unprototyped pushing of floats and ints.
			Fix l and f postfix with float constants.

		Assembler:
			Digit zero is NOT a octal prefix in assembly files.

			Implemented * operand.
			Implemented 'dcb' statement.
			'repeat' statement can now be nested.
			Macros can have 'repeat' statements.
			Repeat value can be any constant expression.
			Repaired equ and = statements.

		Library:
			Added atan2 to ahccstd.lib

	february 17 2011
	v4.4
		Compiler:
			Fixed a bug in switch statements when a table is generated.
			The problem only occurs in leaf functions (no further calls).
			A argument register was not saved.

			Fixed a regression where redeclarations of variables
			were not anymore rejected.

			Bitfields now also work with option -i (type int is 32 bits).
			The fields are packed into a 32 bit word.

			Code rearrangement such that (a##b##c) is now correctly
			retokenized.

		Assembler:
			Fixed a regression where C style #if* directives were
			handled incorrect resulting in strange error messages.

			Fixed a regression where local labels within a module
			were incorrectly matched to equally named local labels
			in previous modules.

			Implemented scope for dot prefixed labels.
			(local between non dotted labels)

			labels within modules couldnt be exported. Fixed.

		Library:
			Added missing function 'ceil'
			Added SozobonX gemfast replacement 'gemf.lib'
				The lib is a wrapper around ahcc's gemlib.

			New include files unistd.h, sys/stat.h, sys/types.h
				These replace functions in ext.h and hence are
				included by ext.h.

			Fixed a bug in sleep(). The bug prevented sleep()
				from sleeping.

		Linker:
			Removed redundant debug messages about doubly defined
			names that could result in a crash.

	november 28 2010
	v4.3
		Compiler:
			Fixed wrong mode bits in Coldfire 'fmovem.d reglist,(A7)'.
			Fixed typo in "unknown mnemonic" message.
			Skip rest of line after above message.

			Improved code for comparing bitfields to zero
			and assigning constants to bitfields.
			Replaced flagwords operated by |= resp. &=~ by
			bitfield definitions.
			For instance:
			in stead of  'flag |= FLAGNAME resp. flag &= ~FLAGNAME',
			         now 'flag.flagname = 1 resp. flag.flagname = 0'
			without increase of code.

			Repaired warning 'value too big for field',
			which was never issued due to a typo.
			Also made sure the generated code conforms to Pure C
			in this case.

			The include folder can now be used by both Pure C and AHCC
			in all case. The sinclude folder is only needed when
			compiling AHCC* itself.

		Assembler:
			Implemented directives 'ifd' and 'ifnd' as synonyms
			for 'ifdef' and 'ifndef'.

			A expression of the form (label1 - label2) can only be
			resolved when the labels are NOT advance references and
			when the labels are in the same area (or module).

			This might be repaired in the next release. It will
			take some contemplation and time.

	october 30 2010
	v4.2
		Compiler:
			Removed error "bool not allowed".

			Fixed a rare case where logical expressions with && or ||
			including constants were not handled properly.
			pe
			if (VERSION == DEMO_VERSION && c < 0)
			where upercase identifiers are constants and c is a variable.

			Fixed wrong code for comparing a double to a integer constant.

			Fixed assignments of the form a = b = c;
			where a and b are doubles.

			Accept '=' with options -I, -D

		Assembler:
			Fix in preprocessor.
			endif directive was not detected properly resulting
			in "error 1 #endif missing".

			implemented directives:
			.extern, .ifne, .iff, .ifeq, .ifle, .iflt, .ifge, .ifgt

			labels without ':' must begin at position 1 of a line.
			This assures typos in opcode mnemonics are rejected.

			Fixed 'wrong processor type' message.

		Shell:
			If AHCC cant find header files, setting maximum verbosity
			will display in the journal which paths AHCC has tried.
			(Maximum verbosity = all 4 v's in the KIT.)

			Implemented project file option .S
			.S options are passed when compiling assembler files.
			(extension .S)
			When the option is present it is passed to .S files only.
			If absent, the .C options are passed to all source files
			including .S files.

		Editor:
			Fix in detecting changes in files with Unix line endings
			resulting in false positives when closing.
			Undone changes were falsely reported as change.
			Not dangerous but Annoying.

			With option 'visible tabs' active, AHCC now also shows
			trailing white space. Usefull when comparing files.
			The small triangle is used.

			When 'visible tab' is inactive, compare files (^2) no longer
			takes trailing white space into account.

			So, when 'compare folders' marks files as changed and ^2
			doesnt find a change, you can be sure that its only trailing
			space that is the difference.

	october 5 2010
	v4.1
		Compiler:
			Further fixes for and completion of Coldfire target.

			Fixed a rare crash when compiling nnn.c when AHCC also
			had open in a window a file nnn.s from the same folder.
			It happened to me while I was rewriting nkcc.s into nkcc.c
			:-)

			Cdecl functions returning a pointer do so in
			      both a0 and d0.

		Assembler:
			Accept ENDR after REPEAT.
			Fix a memory leak in the 'ascii' opcode.

		Library:
			Set both variables _envp and __EnvStrPtr in ahcstart.c
			Replaced getenv (gcc version) by getenv from dlibs.
			Repaired enum HOURGLAS,BUSYBEE in sinclude\np_aes.h & aes.h
			Removed a few leftover debugging printf's from AHCM

		Shell:
			Find multiple, Find in project:
			Fixed line number counting for files with unix line endings.

		Editor:
			Window menu 'leave' behaviour changed. The menu is no longer
			popped when left via the bottom of the menu.

	may 27 2010
	v4
		Editor:
			Better placement of windows with tiling.

		Compiler:
			Finished 68020 compatible Coldfire target.
			Long mod (%) done by hardware for 68020+ and Coldfire.
			Fixed a bug in AHCCST concerning assigning a variable
			    to a bit field.
			Forbid duplication of enum identifiers.

		Linker:
			'nm' list: addresses always in hex.

		Library:
			Fixed binding for vsl_ends; Some VDI's acces intout.
			Changed binding for v_gtext; Intin array static.
			Replies and setting of errno same as Pure C lib.

	march 17 2010
	v3.b8
		This page:
			Order of history reversed.

		Compiler:

			Option -7 preliminary Coldfire V4e target.
			=========================================
			See also: Status of Coldfire support.

			Fixed Option -c-
				No nested comments didnt work.
			Fix in option -*i (32 bit int)
			error 'no declarer for extern object'
				changed to warning, default is 'int'.

			New warning: 'no prototype for 'name'.
			warning: 'no args matching' only if there are args to match
			         and only for old style prototypes.

			Removed option -4 (double is float)
			Removed option -*s (scale 32)
				It appeared that Pure C does long scaling the same way
				without being optional.

			A few small fixes for very rare situations.

			Removed a spurious call to a diagnostic print routine.
			    Reduces all binaries by about 7Kb.

			Relaxed a limitation on the number of names in the Pure C
			object output format.

		Linker:
			Improved load map.
				All symbols are printed.
				Local symbols are enclosed by < >.
			Option -n: Write a 'nm' style list of symbels to prog.SYM

			DRI symbol table in executable:
				write symbols first 22 characters in stead of first 8.

		Assembler:
			Allow size .b in Scc instructions.
			Detection of '*' comment in lexer.

			new directives: (from devpac)
			incbin
				include a binary file as is at the current position.

			section
				allowed operands: text, data or bss.

		Library:
			Merged ainclude and sinclude folders.
			ainclude is now obsolete and removed.
			The sinclude folder can be used for both Pure C libraries
			and AHCC libraries.

			All 16 bit integrals in sinclude are declared as short !!!!

			FILE structure of AHCCSTD.LIB compatible with the one
			of Pure C lib. (Needed for fixing AHCCSTD ;-)

			Fixes in AHCCSTD.LIB

			Changed name of folder from AHCCLIB to AHCCSTD

			Update wind_get.	(table of number of replies)

	january 6 2010
	v3.b7

		General:
			Changed the naming scheme of all the incarnations of AHCC.
			The name of the project file is always the same as the
			name of the executable. See 'distribution'.

		Shell:
			Close the project file. (problems saving after ALT+P)
			Fixed a memory leak when compiling from a open window.

		Compiler:
			Create AHCC_ST.
			A 68000 version without floating point support.

			The header cache is always freed between make's.
			It must also be freed between files when caching
			is switched off.

			Cached headers take about 30% less space due to
			redesign of tokenized input format.

			Another dereference of a zero pointer.

		Library:
			Fixes in stricmp, strnicmp & strtol.
			Consistency check in AHCM (memory allocator).

	december 16 2009
	v3.b6

		Compiler:
			Fixed a dereference of a zero pointer.
			Couldnt be detected on the Milan.
			So I will always be needing my TT.

	december 8 2009
	v3.b5

		Shell:
			Very, very usefull:
			New menu entry Project->Edit ALT+P
			Loads the current projectfile in the editor.
			Open->Open .P* removed.

			menu entry 'Find selection in project' now also in the journal.

			KIT:	button for option -*u (default .super in assembly)

		Compiler:
			Improved include file lookup.
			Now Teradesk compiles directly from its own directory.
			The need for setting a include dir in the KIT is almost
			never needed when -I's are in the project file.
			This is also beneficial for AHCC_P.TTP. There the default
			to ainclude is removed.

			Made a lot of error/warning messages a lot more readable.

			Completely forgot about relative long branches in the
			output phase. :-(   Fixed.

			Fixed a regression and a closed loop while generating switch
			tables. (related to allowing long 'case' constants)
			It happened when a case value forms a negative short.

			typechecking of call's:
			p(); or p(void);	/* declaration */
			........
			p();	/* call */
			Is no longer warned. The mixing of old and new args is silently
			accepted when no arguments are involved.

			Same for declarations:
			p() or p(void);
			followed by
			p(void){...} or p(){...}

			Bugfixes for rare cases involving boolean comma expressions
			and pushers.

		Assembler:
			Fixed ordinal in "out of range" message for shifts.

			Fixed a serious regression when combining C and Assembly in a file.
			(message: CE: invalid asm area number)

			Accept include filename between ampersands.
			For the moment the warning persists and can be ignored.

	november 25 2009
	v3.b4

		Assembler:
			Fixed a memory leak;
			C preprocessor activated in .S files
			While doing this, it appeared that AHCC never checked
			if a preprocessor command was the first of a line. :-(
			This is now repaired.

			.global
			.org
			.equ and .set	second form
			.ascii
			.asciil
			.asciiz
			.page

			option -*u		default .super

			repair broken exg An,Dn

			allow mixed register lists of form:
			Dn-An ( ascending register number) --> Dn-D7/A0-An
			An-Dn (descending register number) --> An-A0/D7-Dn

			Option -*w to set default size for Xn (no dot).
			           default (option not set) is word.
			Also fixed a bug in determining the Xn size.

		Compiler:
			Activated and fixed option -x prepend underscore.
			Fixed occasionally incorrect line number in messages.
			#warning
			__func__ identifier and its synonym __FUNCTION__
			case: long constants allowed
			Fixed stupid mistake in constant validation since v3.b3
			Typos in constant folding for <= and >= (wrong way around)
			      Not detected until compiling emutos :-(

			Negative absolute operands handled correctly.
			Removed '#' from #warn, #error messages.
			Less cryptic message for mismatching pointers to function.
			Sometimes the Help opened the wrong file.
			Fixed by restructuring the Help DataBase.

			Allow 'formal' declaration of arrays by specifying
			empty [] pair. e.g. static char forward[];

			It appeared that if flag 'cdecl calling' was set,
			functions returning a pointer returned in D0, wereas the
			callee expected the pointer still in A0.
			Probably a relic of a distant past.
			Pointers are now always returned in A0.
			Fixed another bug in 'cdecl' calling in combination
			with __syscall__. (a2 wasnt preserved)

			Incrementing a void * wasnt warned nor handled sensibly.
			Arithmetic to unscalable pointers is warned and not scaled.

			Fixed wrong handling of absolute Lvalues and references.

			Fix and improvement of rare optimization incidence.

			Fixed a bug in implicit dereferencing of callee expressions.
			e.g. (a ? c : d)(arg);

			Fixed a terrible regression in constant casting.
			Casting int to float was lost somewhere.

			Fixed a bug in long pointer scaling in 68000 mode (-2-)

		Linker:
			Fixed a memory bug for libraries with excessive
			number of names. ( more than 1359 )
			Result of a nested project was not correctly passed
			and the linker was not called. Fixed.
			'Linking' message gives name of project file.
			Object files are linked in the order in which they
			appear in the project file.

			Build a ROM image:
			Option -t=N   N is startaddress of text+data sections.
			                   bss start will be set at 0.
			       -i=N   N is size of image in kilobytes. (zero padding)

			Make sure ALL areas are of even size.

		Shell:
			KIT: button 'inherit options'
			for nested projects, inherit options from parent project.

		Editor:
			Improvement of UNDO behaviour. See Undo.

	march 19 2009
	v3.b3
		Fixed a omission while expanding.
		       (K&R 2nd A12.3 don't replace at rescan.)
		My solution of recursive macro expension yielded
		false positives. So it is removed.
		It might be necessary to completely redesign the
		expansion mechanisms. The current implementation is a
		Sozobon legacy. AHCC should work fine when you remove
		all recursive definitions and usage in your sources.

		A memory bug is killed.
		A few minor bugs fixed.

		The Pure C offsetof macro couldn't work in #if's
		(again, Sozobon legacy).
		Implemented __offsetof__ operator

		If your programs use offsetof in a #if conditional
		and you do not use one stddef.h of AHCC,
		you must copy the implementation of offsetof from stddef.h
		in folder AINCLUDE to your own stddef.h.

		Handling of # (stringify) and ## (token catenation)
		same as Pure C (Not entirely ANSI).
		Oh well, ANSI is completely bonkers in that respect.

	februari 2 2009
	v3.b2:

		Macro expansion now detects recursion. (v3.b1 crashed)
		=====================================

		Bugfixes in relative path handling.
		More flexible use of shel_find result.
		Builtin macro __FILE__ replaces '\' by '\\'.

@endnode

@node "A taste of C99"

	The following C99 features are implemented in AHCC:

	// Comment
	_Bool
	long case constants and switch
	__func__ identifier. (__FUNCTION__ as a synonym)

@endnode

@node "combine C and Assembly"

	Assembly functions can be included into C source files.

	These functions are specified by the AHCC specific
	__asm__ keyword. __asm__ shares its syntactical position
	with the keyword cdecl.

	Example (which you can find in the file ahcstart.c in ahcclib)

	void __asm__ __text(void)
	{
			... M68K standard assembly ...
	}

	C static and global declarations can be directly used in
	operands where they are syntactically appropriate.

	Members of unions and structs can be accessed by the operator '@'
	Because the point was not available, I chose the '@' aka 'at'
	symbol.

	When '@' is used on a data declaration the offset within that
	object is added to the address and the resulting operand is
	a memory reference.

	When '@' is used on a struct or union type definition, the offset
	within the type is produced as a constant.

	This makes it possible to address members of unions and structs
	with the indirect addressing modes.

	The whole construct removes the necessity to repeat struct and
	member definitions in assembler include files.
	In stead you can include the C header files.

@endnode

@node Installation
@alias distribution

	The AHCC distribution
	=====================

	AHCC_HYP.ZIP :: AHCC.HYP
			        AHCC.REF
			        AHCC.STG

	To be unzipped to your favourite st-guide folder.
		So you can read them first.

	Full version for 68020 or higher, 68881/2 and Coldfire V4e
	==========================================================

	AHCC.ZIP ::

		Unzip will give you folder AHCC.BIN somewhere.
		If you haven't got Pure C, just use AHCC from this folder.
		If you have a Pure C Installation, it is best to copy the files
		from AHCC.BIN to appropriate places in your Pure C folder.
		This makes it easy to combine AHCC & Pure C object files freely
		within the same project.
		You must at least copy AHCC_RT.H to your current include folder.

		AHCC.BIN\
			LIB\
				AHCCGEM.LIB ; GEM bindings
				AHCCGEMF.LIB; GEM bindings for Coldfire
				AHCCSTD.LIB ; Standard lib
				AHCCSTDI.LIB; Standard lib for 68000 without floating point
				AHCCSTDF.LIB; Standard lib for Coldfire
				AHCCSTFI.LIB; Standard lib for Coldfire without floating point
				GEMF.LIB    ; Sozobon Gemfast wrapper functions
				AHCSTART.O	; startup code for above Standard libs
			INCLUDE\		; include directory for Pure C and AHCC libs
			SINCLUDE\		; include directory using short exclusively
			                    only needed for compiling AHCC* itself.
			------------
			AHCC.CFG		; config file for AHCC.PRG
			AHCC.PRG		; Gem integrated Editor/Shell/
			                                 Compiler/Assembler/Linker
			AHCC.MAP		;    its load map
			AHCC.BUF		; Last Copy/Cut from editor See Buffer
			AHCC.RSC		; resource
			AHCC_T.TTP		; commandline version of Compiler/Assembler
			AHCC_T.MAP		;    its load map
			AHCC_P.TTP		; Shell/Compiler/Assembler/Linker
			AHCC_P.MAP		;    its load map
			AHCL.TTP		; Commandline Linker
			AHCL.MAP		;    its load map
			AHCL_P.TTP		; Linker using project file
			HELLO.C
			HELLO.PRJ		; Everybody's favourite starter program
			HELLO_PC.PRJ	; Pure C version

	All the above binaries are compiled for 68020+ and 68882
	You need Falcon/TT or higher to run them.

	Version for 68000. No floating point support.
	=============================================

	AHCCST.ZIP ::

		Unzip will give you folder AHCCST.BIN somewhere.
		If you haven't got Pure C, just use AHCCST from this folder.
		If you have a Pure C Installation, it is best to copy the files
		from AHCCST.BIN to appropriate places in your Pure C folder.
		This makes it easy to combine AHCCST & Pure C object files freely
		within the same project.
		You must at least copy AHCC_RT.H to your current include folder.

		AHCCST.BIN\
			LIB\
				AHCCGEM.LIB ; GEM bindings
				AHCCSTDI.LIB; Standard lib without floating point
				GEMF.LIB    ; Sozobon Gemfast wrapper functions
				AHCSTART.O	; startup code for above Standard lib
			INCLUDE\		; include directory for Pure C and AHCC libs
			SINCLUDE\		; include directory using short exclusively
			                    only needed for compiling AHCC* itself.
			------------
			AHCCST.CFG		; config file for AHCCST.PRG
			AHCCST.PRG		; Gem integrated Editor/Shell/
			                                 Compiler/Assembler/Linker
			AHCCST.MAP		;    its load map
			AHCCST.BUF		; Last Copy/Cut from editor See Buffer
			AHCC.RSC		; resource
			AHCCST_T.TTP	; commandline version of Compiler/Assembler
			AHCCST_T.MAP	;    its load map
			AHCCST_P.TTP	; Shell/Compiler/Assembler/Linker
			AHCCST_P.MAP	;    its load map
			AHCL.TTP		; Commandline Linker
			AHCL.MAP		;    its load map
			AHCL_P.TTP		; Linker using project file
			HELLO.C
			HELLO_ST.PRJ		; Everybody's favourite starter program

	All the above binaries are compiled for 68000
	They can be run on any Atari or clone.

	Version for Coldfire V4e
	==========================================================

	AHCCCF.ZIP ::

		Unzip will give you folder AHCCCF.BIN somewhere.

		AHCCCF.BIN\
			LIB\
				AHCCGEM.LIB ; GEM bindings
				AHCCGEMF.LIB; GEM bindings for Coldfire
				AHCCSTD.LIB ; Standard lib
				AHCCSTDI.LIB; Standard lib for 68000 without floating point
				AHCCSTDF.LIB; Standard lib for Coldfire
				AHCCSTFI.LIB; Standard lib for Coldfire without floating point
				GEMF.LIB    ; Sozobon Gemfast wrapper functions
				AHCSTART.O	; startup code for above Standard libs
			INCLUDE\		; include directory for Pure C and AHCC libs
			SINCLUDE\		; include directory using short exclusively
			                    only needed for compiling AHCC* itself.
			------------
			AHCCCF.CFG		; config file for AHCCCF.PRG
			AHCCCF.PRG		; Gem integrated Editor/Shell/
			                                 Compiler/Assembler/Linker
			AHCCCF.MAP		;    its load map
			AHCCCF.BUF		; Last Copy/Cut from editor See Buffer
			AHCC.RSC		; resource
			AHCCCF_T.TTP	; commandline version of Compiler/Assembler
			AHCCCF_T.MAP	;    its load map
			AHCCCF_P.TTP	; Shell/Compiler/Assembler/Linker
			AHCCCF_P.MAP	;    its load map
			AHCLCF.TTP		; Commandline Linker
			AHCLCF.MAP		;    its load map
			AHCLCF_P.TTP	; Linker using project file
			AHCLCF_P.MAP	;    its load map
			HELLO.C
			HELLO_CF.PRJ	; Everybody's favourite starter program

	All the above binaries are compiled for 68020+ and Coldfire
	You need Falcon/TT or higher to run them.
	The programs run on Coldfire without emulation.


	Source distribution
	============================================================
	AHCC_SRC.ZIP ::
		AHCC.SRC\
						subsystem folders:
			AHCC\		; sources of the Compiler/Assembler/Linker
			AHCCGEM\	; sources of the GEM bindings
			AHCCLIB\	; sources of the Standard lib
			CALC\		; Example GEM program (No documentation)
			COMMON\		; sources of routines used by all subsystems
						  subject to diverse build environments
						  (Hence not presented in form of a library)
			DIGGER\		; sources of TT-Digger (Yes, finaly open :-)
			SHELL\		; sources of the Shell of AHCC
			TEXT\		; sources of the text functions of all subsystems

						root:
			AAAA.C		; Main of all subsystems. Build is governed by
						  the contents of the project files
						  and the resource files.
						  The resource files sit in their respective
						  subsystem folders.
			AAAA.H		; Main header file
			AA_INTRO.H
			WI_TYPES.H  ; Header files that must be present in the root

			AHCC.PRJ	; Project file of complete GEM integrated AHCC
			AHCC_P.PRJ	;    "     Shell/Compiler/Assembler/Linker
			AHCC_T.PRJ	;    "     commandline /Compiler/Assembler

			AHCCST.PRJ	; Project file of complete GEM integrated AHCCST
			AHCCST_P.PRJ;    "     Shell/Compiler/Assembler/Linker
			AHCCST_T.PRJ;    "     commandline /Compiler/Assembler

			AHCCCF.PRJ	; Project file of complete GEM integrated AHCCCF
			AHCCCF_P.PRJ;    "     Shell/Compiler/Assembler/Linker
			AHCCCF_T.PRJ;    "     commandline /Compiler/Assembler

			AHCL.PRJ	; Project file of commandline Linker
			AHCL_P.PRJ	;    "     Linker using Project file

			AHCLCF.PRJ	; Project file of commandline Linker for Coldfire
			AHCLCF_P.PRJ;    "     Linker for Coldfire using Project file

			AHCX.PRJ	;    "     Editor only.
			CALC.PRJ	;    "     Example program
			CALC_PC.PRJ	;    "     Example program original Pure C
			DIGGER.PRJ	;    "     TT-Digger


	Unzip will give you folder AHCC.SRC somewhere, from which
	you can build everything.

	All programs need the SINCLUDE folder.

	CALC.PRJ, AHCX.PRJ and DIGGER.PRJ will build in their respective
	folders CALC, TEXT  and DIGGER.

	AHCC*.* suite will build into SHELL folder.
	From there you can copy the new binaries into the bin folder
	of your choice.

@endnode

@node include

	The AHCC distribution comes with 3 include directories.

	This is why:

	INCLUDE
		Basically the original Pure C folder. It has some major
		changes in it to make it usable by AHCC.
		It can of course be used together with the Pure C libraries.
		It makes it possible to port a app to AHCC by compiling
		and linking files 1 by 1.
		Most important aspect of this folder is that it uses 'int'
		type for 16 bit integral types.

	SINCLUDE
		The most important property of these header files is that
		ALL ocurrences of int have been replaced by short.
		This makes it possible to use these header files for programs
		for which you must define int as 32 bit.
		These programs can keep using the standard 16 bit libraries
		of ancient ST.

		All AHCC subsystems use SINCLUDE.

		SINCLUDE also contains my personal version of the AES
		and VDI headers.
		Soon after I started writing GEM programs in 1988,
		I got extremely annoyed by the ridiculous, annoying and
		spurious prefixes. So I removed the lot.
		All AHCC subsystems rely on these personal headers.

@endnode

@node "Eextension for Operating Systems"

	unary operators:

		__bswp__   byteswap   input size: byte, word, long
		                     output size:       word, long

		byte:	the operand is (sign)extended to word then rotated 8 bits
		word:	the operand is rotated 8 bits
		long:	the low word is rotated 8 bits,
				the high word is rotated 8 bits and
				then the high and low words are swapped.

		__ldsr__		get SR
		__stsr__		set SR
		__getsetsr__	get SR and then set SR

	identifiers just providing code:

		__save__		Save    d0-d7/a0-a6 on the stack
		__rest__		Restore d0-d7/a0-a6 from the stack
		__nop__			No operation (pipeline flushing)

@endnode

@node "specific AHCC features"
@alias __syscall__
@alias __offsetof__
@alias "32 bits"

	AHCC extensions
	===============

	Eextension for Operating Systems

	Other extensions:
	Hint! Use these exclusively in header files.

	__syscall__ operator

		This operator makes a TOS binding library obsolete.

		syntax:

		__syscall__(a, b)
		__syscall__(a)

		a: trap number
		b: optional first item to push on the stack (cdecl)
		   or put in D0

		See the most comprehensive example of its usage in TOS.H :-)

		The operator takes the same syntactical position as cdecl and thus
		forms part of a complete prototype that is ANSI for the rest of it.

		AHCC will directly generate trap instruction sequences.

	__offsetof__ unary operator

		Works almost exactly as sizeof operator.
		1: The left term must be a expression denoting the member of a
		   struct or union object.
		   e.g. a: pobject->member
		        b: (*pobject).member
		        c: object.member
		2: The left term is a union or structure type followed
		   by a dot and a member name.
		   e.g. struct node.left

		the result is a constant of type size_t representing the
		offset of the member within its union or structure type.

		In stddef.h you can find the following ANSI macro:
		#define offsetof(type, member) __offsetof__ type.member

		The macro can be used for examples 1b, 1c and 2
		Note that examples 1a and 1b are equivalent.

	16 or 32 bits

		AHCC can be presented with a default int size.
			See compiler_options.

		When AHCC is configured to 16 bit int, it will consider
		int and short as completely synonymous.

		When AHCC is configured to 32 bit int, it will consider
		int and long as completely synonymous.

		This to avoid useless warnings about pointers.

	combine C and Assembly

		AHCC accepts assembly on the function level in .C files.

@endnode

@node "Project file"

	The project file is a ascii file that can be produced by
	AHCC's integrated editor.

	<project>			::=
						[  <output_file> | ¯*®  ]
						[  ¯.L® ¯[® <linker_options> ¯]®  ]
						[  ¯.C® ¯[® <compiler_options> ¯]®  ]
						[  ¯.S® ®[® <assembler_options> ¯]®  ]
						¯=®
						{  <module>  ¯(® <dependency_list> ¯)® }

	<module>			::=
						¯*®
						|  <project_file>
						|  <assembler_module>
						|  <C_module>
						|  <object_file>
						|  <library_file>

	<assembler_module>	::=
						<assembler_file> [  ¯[® <assembler_options> ¯]®  ]

	<C_module>			::=
						<C_file> [  ¯[® <compiler_options> ¯]®  ]

	<project_file>		::=
						another Project file.

	<object_file>		::=
						A linkable object file of the implemented format
						with extension '.o'

	<library_file>		::=
						A library file of the implemented format
						with extension '.a' | '.l' | '.lib'

	<assembler_file>	::=
						A ascii file with extension '.s'

	<C_file>			::=
						A ascii file with extension '.c'

	<dependency_list>	::=
						<dependency_list> | ¯,® <file>


@endnode

@node "Quick guide to the main menu"

	File
		Open ...
		Open C*
		Open H*
		Open S*
		Open PR*
		Open 'some extension'

		Quit

	Options
		Window ...

		Tile
		Overlap
		cycle

		Function keys ...
		Open buffer

		Find multiple ...
		Compare folders ...
		Define braces ...

		At rtn reset_undo
		autosave config
		Find in hypertext

	Project
		Select ...
	
	<name of project file>
		Edit
		Reload

		Config ...
		Clear help stack
		Find in project ...
		Show dependencies

		Compile
		Compile ...
		Assemble ...

		Make
		Make all
		Link

@endnode

@node File
@alias Open Quit

	This menu title only contains Open and Quit entries.
	All the other file operations are held in the window menu
	for that file once the file is opened.

	Open ...

		The first entry implicitly supplies the fileselector with the
		wildcard *.*

	Open <some wildcard>

		The other entries supply *. followed by the extension wildcard as
		given in the menu entry itself.

		You can use a resource editor for adapting the wildcards to your
		own liking. Make sure the editor does NOT change object indices.

	Quit
		Leave the program.

		If any changes in open files are not saved, the program asks you
		whether this should be done or not.

		If 'Autosave config' is set, AHCC will write its configuration
		to AHCC.CFG and the contents of the copy/paste buffer
		to AHCCBUF.TXT. Both files are loaded when AHCC is started again.

		When the project help is activated, the project database will
		be written back without asking and only if the database content
		has become different.

	See 'Editor' for more details about the functions of the editor.

@endnode

@node Options
@alias Window Tile Overlap cycle

	Window ...
		The KIT is opened with at least the options block visible.
		See KIT for more details.

	Tile
		The open editor text windows are tiled on the screen.
		Only the first 9 windows are affected.
		It is particularly useful with 2 windows on a big screen.

	Overlap
		All open editor text windows are displayed overlapping.

	Cycle
		Top the next open window.

@endnode

@node "Function keys"
@alias "Open buffer"

	Function keys ...
		AHCC has 20 built in fixed texts very often needed
		in C and assigned to function keys F1 to F20.
		This menu entry displays the texts in the journal.
		A % in the text indicates where the cursur will be placed
		after insertion of the text.

	Open buffer
		The Copy/paste buffer will be opened in a window.
		You can edit in this window, but NOT cut, copy or paste :-)
		You can also select a portion of the buffer contents.
		See also Paste.

@endnode

@node "Find multiple"
@alias "Compare folders" "Define braces"

	See general information about the KIT.

	Find multiple ...
		The KIT is opened having at least the 'Find' block visible.
		See general information about browsing.

	Compare folders ...
		The KIT is opened having at least the 'Compare Folders' block
		visible. There you can specify 2 folders for comparison.

	Define braces ...
		The KIT is opened having at least the 'Define braces' block
		visible. In this block you can define braces that are words.
		A single '*' at the end of a word serves as a wildcard.
		It is mostly used for preprocessor nests : '#if* ... #endif'.

@endnode

@node "At rtn reset_undo"
@alias "autosave config" "Find in hypertext"

	At rtn reset_undo
		This options affects the lifetime of the undo buffer.
		By default the undo buffer is emptied at each mouse click.
		When set, the undo buffer is also emptied when a new line
		is created by pressing Enter.

		Note that there exists a undo buffer for each text window.

	Autosave config
		The configuration and the copy/paste buffer are saved to disc
		when AHCC is quitted.

	Find in hypertext
		A selected text is sought for in this hypertext.
		The text must be a node or alias.
@endnode

@node "Project manager"
@alias Shell Project Select Edit Reload Config Compile Assemble Make
@alias "Show dependencies" "Make all" "Find in project" Link
@alias "Clear help stack"

	Project management is based on the syntax of the Pure C
		project manager.

	The manager comprises the menu title 'Project'.

	The first menu entry does not invoke a function.
	It just displays the name of the project for a quick check.

	Menu entries are:

	Clear help stack
		For if you lost track of the number of HELP's active.

	Select
		Load a new project.
		Via the file selector a new project can be loaded.
		When affirmed by OK, the old project is erased and the
		selected project will be loaded.

	Edit
		The current project file is opened in a window for editing.

	Reload
		Currently changes in the project file are not recognized
		by AHCC. This will be repaired in the future.
		For now, you can force the use of a changed project by
		selecting this menu entry.

	Config
		The options blok of the KIT will be displayed.
		A description of options can be found in section KIT.

	Find in project
		Same as 'Find multiple' but the string is sought for
		in the files belonging to the current project.
		See also 'KIT'.

	Show dependencies
		A list of files and dependencies as expressed in the
		project file will be produced in the journal.
		If option 'auto dependencies' is active, a very exhaustive
		list of ALL input files and ALL header files per input file
		will be produced. Auto dependencies are passed by the compiler
		to the project manager. The list will only be complete once
		a 'make all' has been successfully completed.

	nnnn identifiers
		This entry does not invoke a function.
		When the option 'project help' is active, this entry displays
		the number of different identifiers in the project.
		The information is only of interest to people with insatiable
		curiosity. (like me :-)

	Compile
		Compile the file in the top window when it has either
		extension .C or .S

		In contrast to Pure C, AHCC considers the file part of the
		current project. So the file is compiled within the context
		of the project. All options from the project file and the KIT
		are passed to the compiler.

		So it is not necessary anymore to do a dummy edit and then
		select 'Make'.

	Compile ...
		Same as compile, but the file is selected through the
		file selector. Extension .C is preset.

	Assemble
		Same as compile.

	Assemble ...
		Same as compile, but the file is selected through the
		file selector. Extension .S is preset.

	Make
		Compile all files of the project whose source files are newer
		than the corresponding object files.
		The process takes in consideration header files mentioned
		as dependencies in the project file line between parenthesis.

		If the option 'Auto dependencies' is set in the kit,
		the process needs a valid project database (.ADB).
		The use of 'Auto dependencies' is only useful after a
		'Make All' has been successfully performed.
		In case of 'Auto dependencies', dependencies in the project
		file are ignored.

	Make all
		Compile all files of the project.
		When a 'Make All' does not finish due to user interrupt or
		errors, a simple Make will suffice for further attempts to
		produce the program or library.

	Link
		Link the current project and produce a executable binary
		or a library.

@endnode

@node "Quick guide to the window menu"

	The window menu:

	File(window)
		Save
		Save as ...
		Print
		Print selection
		Close
		Abandon

	Edit
		Undo
		CrLf
		Reveal changes
		Shift left
		Shift right
		Fix tabs
		To upper case
		To lower case
		Replace ...
		Replace same

	Buffer
		Cut
		Cut&append
		Copy
		Append
		Paste

	Search
		Find ...
		Find same
		Find same other direction
		Find selection
		Find sel. multiple
		Find sel. in proj.
		Select all
		Compare		See filecompare.
		Reveal cursor
		Reveal end selection
		Go to line
		Check braces
		Find declaration

@endnode

@node "File(window)"
@alias Save Print Close Abandon
@alias "Save as" "Print selection"

	Save
		Write edited file back to disc if modified.
		AHCC keeps track of edited lines.
			If a line has been modified back and forth not resulting
			in a real change, the line is not marked as modified.
			Particularly of interest when a file is closed.

	Save as ...
		Write the file to disc under a different name.
		The file selector is invoked for specifying the new name.

	Print
	Print selection
		Write the whole file, or a selection to PRN:

	Close
		Close file and remove its window from the screen.
		If the file is not really modified, the file is closed
		silently, otherwise a alert is invoked for a choice
		between cancel, discard changes or save.

	Abandon.
		All changes are abondoned and the contents of the file
		after last 'save' are displayed.

@endnode

@node Edit
@alias 	Undo CrLf "Reveal changes" "Shift left" "Shift right"
@alias "Fix tabs" "To upper case" "To lower case" Replace "Replace same"

	Undo
		1:	Undo all changes since the last mouse click, or last
			Enter depending on 'At rtn reset_undo' setting.

		2:	After use of HELP for finding declarations,
			UNDO returns to the place of the HELP action.
			All such HELP actions are maintained in a help_stack.
			Each HELP steps the stack up.
			Each UNDO steps the stack down.
			Unless some editing has been done in between.
			In that case the help stack has been canceled and
			the edit will be undone.

		Whether a edit UNDO or a HELP UNDO will be performed can
		be seen in the menu title "Project". When a help stack
		is active the title reads "Project (Help)".

		If you lost track and you don't want to take the risk of
		pressing a UNDO too many, you can clear the stack by
		pressing shift + UNDO.

	CrLf
		This menu entry is checked when the first line of a text is
		ending with Carriage return AND Line feed characters.
		Selecting the menu entry will flip the setting.

		When the file is saved, the setting will be used for
		line ending in the whole file.

	Reveal changes
		When AHCC complains to you that a file is changed and not
		saved, use this menu entry to find the changed lines.
		Especially useful when you forgot what you did and didn't
		really have the intention to change the file.
		Each invocation of 'Reveal changes' will search further
		after the last line of the current display.

	Shift left
		Remove as much white space from the beginning of all
		selected lines such that a left shift according to the
		current tab size setting is achieved.

	Shift right
		Insert a physical TAB at the beginning of each selected line.

	Fix tabs
		Experimental function.
		The function acts on a selection and uses 3 parameters that
		can be set in the KIT in 'Retabulation block' and 'Tab size'.

	To upper case
		Convert selected text to upper case.

	To lower case
		Convert selected text to lower case.

		Both functions are restricted to the first line of a selection.

	Replace ...
		The KIT will be opened with at least the 'Find' block visible.
		See KIT for more details.

	Replace same
		Replace next or all occurrences of the 'Find' string by the
		'Replace' string.

	When beginning or end of the file is reached during Find or Replace
	operations, the operation will stop and the direction of operation
	will be reversed.
@endnode

@node Buffer
@alias Cut "Cut&append" Copy Append Paste

	Operations to and from the copy/paste byffer.

	Cut
		Remove selection from current window and copy to buffer
	Cut&append
		Remove selection from current window and append to buffer
	Copy
		Copy selection from current window to buffer
	Append
		Append selection from current window to buffer
	Paste
		Insert from buffer at current cursor position.
		If a selection is on:
			Replace selection with content of buffer.
		If part of the buffer content is selected, this selected
		part is pasted in stead of the whole buffer.
		see also 'Open buffer'.
@endnode

@node Search
@alias "Find ..." "Find same" "Find same other direction" "Find selection"
@alias "Find sel. multiple" "Find sel. in proj." "Select all" "Compare"
@alias "Reveal cursor" "Reveal end selection" "Go to line" "Check braces"
@alias "Find declaration"

	Find ...
		The KIT is opened having at least the Find&replace block
		visible.

	Find same
		Search for next current find string further in top window.

	Find same in opposite direction
		Viz.

	Find selection
		Copy selection to Find block and search for it in top window.

	Find selection multiple
		Copy selection to Find block and search for it in currently
		defined directory for multiple find.

	Find selection in project
		Copy selection to Find block and search for it in current
		project.

	Select all
		Select all text in top window.

	Compare
		Compare 2 files. See filecompare.

	Reveal cursor
		Slide window such that the text cursor becomes visible.

	Reveal end selection
		Slide window such that the end of the current selection
		 becomes visible.

	Go to line.
		The KIT is opened having at least the Window parameters
		 block visible.

	Check braces
		Match the following braces recursively: {} [] ().
		Matching starts at cursor position and proceeds until
		the end of the file.

	Reveal declaration
		Inspect the project database to see if the selected word
		is a declaration. If found, open the file in which the
		declaration is made at the declaration's position.
		Only file level declarations are considered.
@endnode

@node KIT

	The KIT is AHCC's toolbox.

	It is a large dialogue held in a scrollable window.
	All items are applied immediately when activated:
		Buttons by just left clicking, editable text fields by
		pressing Enter. To make a text field active, place the text
		cursor in the field by a left click.

	The KIT can be kept permanently on the screen.

	The KIT is divided into blocks.
	Some blocks are revealed automatically through appropriate menu items.

	The info line of the KIT tells you on which file any KIT action
	will be performed.

	Find & replace block
	Compare folders block
	Window parameters block
	Retabulation block
	Define braces block
	Options for the Shell block
	Options for the Compiler block
	Options for the Linker block

@endnode

@node "Find & replace block"

	Column of strings headed by Find:
		Search strings are their own exit buttons.
		Type a string in one of the fields and press Enter.
		If a string is found, it will made visible and selected
		in its window.

	Column of radiobuttons headed by R:
		The selected button tells which find string is used by the
		Find&replace operation. It ensures that find and replace
		strings are kept related independant of the current
		find operation. It prevents inadvertantly replacing a unrelated
		string by the replace string.

	 Replace by:
		If the cursur is placed in this field and Enter is pressed,
		the string marked by one of the radiobuttons will be sought
		for and if found replaced by the content of this field.

	Radio buttons:
		Top window
			Search will take place in the window mentioned in the
			KIT's info line.
		Project
			Search will take place in the current project.
		Multiple:
			Search will take place in the directory mentioned in the
			field below the 'Multiple' button.

		See browse for more information.

	Check buttons:
		Word
			checked:
				Searches are performed on whole words only.
			unchecked:
				Any character sequence matching the string is found.
		Case
			checked:
				Strings are searched for case sensative.
			unchecked:
				Strings are searched for independant of case.
		space
			checked:
				Selection of a found string will be including
				surrounding white space.
			unchecked:
				The exact string will be selected.

	Buttons  & :
		Indicate the direction of the current search.

	String below 'multiple' button:
		Here you specify the directory to which the multiple search
		will be applied.

		Right clicking on the field opens the fileselector for a
		easy way of choosing.

		In a multitasking environment you can also drag&drop a
		directory from a desktop window onto the field.

		See browse for more information, especially for wildcard
		usage.

	Check buttons: These are used in 'multiple' and 'project' searches.
	See browse for more information.
		deep
			checked:
				Scan subdirectories.
			unchecked:
				Scan only stated directory.
		1 per file
			checked:
				Stop searching a file as soon as a string is found.
			unchecked:
				Report all occurrences of a string.

		Verbose: See browse.


@endnode

@node "Compare folders block"
@alias foldercompare

	It is basically simple.
	You specify 2 folders in the KIT. Same sort of wildcards apply as for browse.

	This can be done by typing, by right clicking which opens the file selector
	or by dropping a path object on the field.

	Press GO and all files in the folders are compared.
	If you have checked the 'deep' button, all nested folders will be compared
	recursively.

	A report is put in the journal.
	Mismatch filename1 :: filename2.	Unequal files found.
	Lone filename.                      A file is in one of the directories only.

	Right click on these words and the files will be opened in windows
	in a convenient way.

	In case of Mismatch, the 2 files will be opened and tiled vertically
	and ready for applying filecompare by pressing Ctrl + 2.

@endnode

@node "Window parameters block"

	Split lines on last space before nth ch:
		Some texts, mostly originating from wordprocessors, only have hard
		newlines per paragraph.

		Because AHCC is not a word processor but a simple editor, no dynamic
		formatting takes place.
		You can specify a splitting position here.
		The default is 248.
		The splitting is done at load time and is permanent during the session.
		If you save, the splitting will be permanent over all sessions. ;-)

		For good reasons a split is not considered a change in the file content.
		So if you want to keep the lines split, you must use Save as...,
		or make a small change in the text and save.

		Note: the split parameter is not used when editing.
		The feature is added to accomodate texts that are apparently designed
		with dynamic formatting in mind. In other words: the extreme length is
		not intended to be a extreme long line. If you really want long lines
		you can still make them.

	Tab size:
		Separation of tab positions. Physical TAB character '\9' expands
		to next higher tab position by inserting spaces.

	Visible tab:
		A 2 character field.
		first character:  the one that replaces the TAB chaeacter.
		second character: the one that replaces generated spaces.
		If the first character is space, the second chracter is ignored.

	Remove trailing space:
		When a file is saved, any trailing white space in a line
		will be removed.

	autoindent:
		Enter used for creating a new line will start this new line with
		the heading white space taken from the line preceding the new line.

	Small font:
		If there is a font that is half the size of the current font,
		the former will be switched to.

	Boldtags:
		Reserved word (as defined by AHCC's compiler implementation) will
		be displayed in bold face.

	Scroll information bars, for vertical and for horizontal scrolling.
		Each bar has 3 fields and 1 check button.
		Following the arrows:
			Number of lines resp. ch. positions to
			scroll when an arrow is activated.
		The other elements affect paging.
		Check button:
			The whole page minus 1 line resp. character is scrolled.
		2 numbers forming a fraction:
			If the check button is not checked:
			The part of the screen to be scrolled out of sight when
			a page element is activated.

	Go to line:
		type the new line linenumber in the editable field and press ENTER.

@endnode

@node "Retabulation block"

	This block holds the parameters for the 'Fix tabs' operation.

	Brain dead Unix editors often make variable tab settings
	impossible by mixing real spaces with physical TABs in a single
	line. Mostly the physical TAB is a standard 8. Very annoying.

	For this reason you can set 3 different tab sizes in the KIT.
	'Apparent tab size':
		Set this to what you might think is intended when you have set
	'Tab size' to what looks like the correct value.
	                       Just experiment a little.
		Now you must set
	'physical tab size' to 'Tab size' and 'Tab size' to what you
		want it to be.

	Fix tabs will: replace TABs by 'physical tab size' spaces,
	         then: replace every 'Apparent tab size' spaces
	               by a single TAB,
	         then: redisplay using 'Tab size'.

	Set the field 'Visible tab' to non space for good understanding.
	'/ÿ' is a very convenient value.

	The button 'leading only' restricts the operation to
	leading white space.

	It is recommended to not clear this button, because the Fix tab
	function is not perfect yet for intermediate tabs.
@endnode

@node "Define braces block"

	Word:
		Braces that are made of words.
		10 pairs can be defined by the user.
		A single '*' at the end of a word serves as a wildcard.
		It is mostly used for preprocessor nests : '#if* ... #endif'.

	A selection is created by:
		ALT + left click,
		double left click,
		a single right click.

	All braces are recognised by a selection operation.
	If a left brace is selected,  everything between and including braces
	will be selected.
	If a right brace is selected, only in between braces will be selected.

	A selection can also be made by holding left button and dragging
	and by SHIFT + left click.
	These types of selection do not invoke brace matching.

@endnode

@node "Options for the Shell"

	Verbosity:
		The more buttons checked, the more info is produced in the
		journal. Try it out.
	Project help:
	Auto dependencies:
	Cache headers:
	Inherit options:
	     for nested projects, inherit options from
	     parent project.

	Extra wildcard for make:
		If checked, the following wildcard will be applied when
		selecting files for inclusion in a make operation.

@endnode

@node "Options for the Compiler"

	These are some of the most likely needed options.
	For a complete overview see Compiler/Assembler.
	These and more options can be specified in the project file
	as .C[options]

	5 -d
		Here you can predefine 5 macros
		Only those of which the button is checked are passed
		to the compiler.

	5 -i
		Here you can specify 5 include directories
		Only those of which the button is checked are used
		by the compiler.

@endnode

@node "Options for the Linker"

	These are some of the most likely needed options.
	For a complete overview see Linker.
	These and more options can be specified in the project file
	as .L[options]

@endnode

@node "Standard library"

	Replacement standard library functions for Atari ST with Alcyon C v4.14
	      Version 1.20.0, by Dale Schumacher, last modified 10/19/1988.

	Translated to ANSI 89 for use with AHCC or Pure C:
	      Version 2.0,    by Henk Robbers.

	Important notice		Read this!!

		header files
		process control
		memory allocator (AHCM)
		memory management	(extra)
		file handling
		input/output functions
		coercion
		string manipulation
		character functions
		date/time functions
		searching and sorting
		error handling functions
		variable argument lists
		miscellaneous functions
		extra functions

		revision record
@endnode

@node "Important notice"

	AHCCLIB uses exclusively types short and long.
	NOT int.

	This is because AHCC can be configured to use a 2-byte int size
	or a 4-byte int size.

	AHCCLIB is not meant to be portable.
	The use of integer types is hence made unambiguously suitable
	for the TOS platform.

	As a compensation AHCC will treat short & int as synonymous
	when set to 2_byte int, and long & int as synonymous when set
	to 4-byte int.

	AHCCLIB is runtime compatible to Pure C libraries.
	AHCCLIB can be used with Pure C header files.

	If AHCCLIB replaces Pure C libraries, make sure that you also
	replace the startup code.

	Last:
	Due to dependency on properties mentioned in
	'Introduction to the notion area',
	AHHCLIB itself should always be compiled with AHCC.
@endnode

@node "Introduction to the notion"
@alias area

	Throughout this manual the notion "area" is often used.

	In AHCC & AHCL a area is the unit of linkage.
	It can be either TEXT, DATA or BSS.

	In other contexts the notion just means:
	'a certain amount of consecutive memory locations'.
	This description of course suites very well the special meaning
	in this paragraphe.

	Separate areas are produced for each function.

	DATA & BSS are put into separate areas per file according
	to storage class.

	Storage classes are:

	global data
	static data
	global bss
	static bss
	string literals
	double precision floating point literals

	The granularity of areas can be increased by interspersing
	data declarations with function body definitions.

	At the closure of a function body definition all current
	data areas are also closed, and new are started.

	By having a function's data close to its usage, a lot of
	unnecessary linking in of data not referenced by the function
	is avoided.

	Practical implication of this approach is that you can have
	most of a library's functions in a single file, which
	dramatically reduces compilation time. The many header files
	need to be parsed only once for a multitude of library functions.

	In particular:
	The whole AHCCLIB compiles on a TT + fastram in just over
	1 minute.
	The AHCCLIB consists of 1 C file per standard header.

	The nature of areas implies that they should not, and can not
	be split further.
	This allows the compiler and the linker to remove fixup data
	for relative references within an area.

@endnode

@node "header files"

assert.h
	This header defines the assert() run-time condition checking macro.

basepage.h
	The BASEPAGE struct and the _base variable, which is initialized
	to point to the current process basepage, are defined in this file.

ctype.h
	The isxxxx() macros and toxxxx() macros are defined in this file.

errno.h
	This file defines the error code constants, the errno variable
	and related error handling functions.

limits.h
	Various maximum and minimum values are defined by this file.
	Among these are PATHSIZE and MAXINT.

tos.h
	System calls to bios, xbios and gemdos calls are defined
	in this file.

setjmp.h
	This file defines the buffer needed to save your context when
	using setjmp() or longjmp().

stat.h
	The struct stat and the file mode flag constants are defined
	in this file.

stdarg.h
	This header defines the type and macros needed for variable
	argument list processing.

stddef.h
	This is the root header file which should be included in all
	programs.  It defines dLibs, NULL, size_t, ptrdiff_t and the
	offsetof() macro.

stdio.h
	This header file should be present in nearly all C programs.
	It contains defines the FILE struct, EOF and contains extern
	declarations for standard i/o and other commonly used functions.
	For convenience, the constants TRUE, FALSE and ERROR are also
	defined in this file, although this is somewhat non-standard.

stdlib.h
	This files defines some standard functions, including
	AHCCLIBS's memory allocator AHCM

string.h
	This file defines aliases for string function names (since some
	string functions have various names on different systems) and
	extern declarations for all string functions.

time.h
	This file defines time related constants and structures, and
	extern declarations for the time functions.

ext.h
	Miscellaneous function ported from Pure C

stdbool.h
	AHCC implements natively ANSI 99 _Bool type,
	hence this header file which defines bool, true and false

@endnode

@node "process control"

	You should include <process.h> in your program if you use functions
	in this section.

	_StkSize, etext, edata, ebss, __text, __data, __bss
	_initargs
	main, exit, abort
	shell, system		/* not yet in AHCCLIB */
@endnode

@node "memory management"

	You should include <stdlib.h> in your program if you use functions
	in this section.

	alloca
	sbrk
	brk

@endnode

@node "file handling"

	You should include <stdio.h> in your program if you use functions
	in this section.

	Functions on Gemdos handles:

	mkdir
	rmdir
	creat
	open
	close
	dup
	dup2
	remove
	rename
	lseek
	tell

	Path manipulation:

	fullpath
	findfile
	pfindfile
	wildcard
	_splitpath
	_makepath
	tmpnam
	tempnam

	FILE *stream functions:

	fopen
	freopen
	fdopen
	fopenp
	fclose
	fseek
	rewind
	ftell
	fgetpos
	fsetpos
	fileno
	feof
	ferror
	clearerr
	setbuf
	setvbuf

	prelude & postlude handled by startup code:

	Init_iob
	Exit_iob
@endnode

@node "input/output functions"

	You should include <stdio.h> in your program if you use functions
	in this section.

	Often implemented as macros, not really in AHCCLIB:

	getc
	ungetc
	putc
	getchar
	ungetchar
	putchar

	Functions on Gemdos handles:

	read
	write
	getw
	putw
	getl
	putl
	getln
	gets
	puts
	cputs

	_printf
	printf
	sprintf
	cprintf
	vfprintf
	vprintf
	vsprintf

	_scanf
	scanf
	sscanf
	vscanf
	vsscanf
	vfscanf
	_tttty

	FILE *stream functions:

	fread
	fwrite
	fgets
	fgetc
	fungetc
	fputs
	fputc
	fflush
	fprintf
	fscanf
@endnode

@node coercion
	You should include <stdlib.h> in your program if you use functions
	in this section.

	ltoa
	ultoa
	itoa
	ftoa		*
	atol
	atoi
	atof		*
	strtod
	strtol
	strtoul

	see also _printf _scanf et al
@endnode

@node "string manipulation"
	You should include <string.h> in your program if you use functions
	in this section.

	memmove
	memcpy
	memset
	memcmp
	memicmp
	memccpy
	memchr
	bzero
	strlen
	strcpy
	strncpy
	strpcpy
	strdup
	strset
	strnset
	substr
	subnstr
	strcat
	strncat
	strupr
	strlwr
	strrev
	strcmp
	strncmp
	stricmp
	strnicmp
	strstr
	stristr
	strchr
	strrchr
	strpos
	strrpos
	strspn
	strcspn
	strpbrk
	strrpbrk
	strtok
	strtrim
	stradj
	strrpl
	strirpl
@endnode

@node "character functions"

	To use the functions in this section, you must include <ctype.h>
	in your source file.  Please note that the isxxxx() functions,
	except isascii(), only have defined results if isascii() is true.
	(ie. they only work properly on values 0x00 through 0x7F)

	toupper
	tolower
	toascii

	isalnum,isalpha,isascii,iscntrl,isdigit,isgraph,
	islower,isprint,ispunct,isspace,isupper,isxdigit isblank
@endnode

@node "date/time functions"

	To use the functions in this section, you must include <time.h>
	in your source file.

	time
	ctime
	localtime
	gmtime timezone
	asctime
	mktime
	stime
	utime
	clock
	strftime
	difftime
	start_timer
	time_since
@endnode

@node "searching and sorting"

	To use the functions in this section, you must include <stdlib.h>
	in your source file.

	StdCompare
	qsort
	hsort
	bsearch
	lsearch
	lfind
@endnode

@node "error handling functions"

	To use the functions in this section, you must include <errno.h>
	in your source file.

	errno
	perror
	perrorf
	strerror

@endnode

@node "miscellaneous functions"

	To use the functions in this section, you must include <stdlib.h>
	in your source file.

	atexit
	getopt
	rand
	srand
	swab
	abs
	labs
	max
	min
	swap
	assert
	ctlcnv
	getenv
	putenv
@endnode

@node "extra functions"

	To use the functions in this section, you must include <ext.h>
	in your source file.

	getcurdir
	chdir
	chmod
	getcwd
	getch
	getche
	putch
	kbhit
	getpid
	stat
	access
	fsize
	isatty
	sleep
	usleep

@endnode

@node FILE
@alias stream

typedef	struct
{
	short		     _cnt;		/* # of bytes in buffer */
	unsigned char	*_ptr;		/* current buffer pointer */
	unsigned char	*_base;		/* base of file buffer */
	unsigned int	_flag;		/* file status flags */
	short		    _file;		/* file handle */
	size_t		    _bsiz;		/* buffer size */
	unsigned char	_ch;		/* tiny buffer, for "unbuffered" i/o */
}
FILE;
@endnode

@node getcurdir

short getcurdir(short drive, char *path)

	Call Dgetpath,
	return -1 when the path doesn't exist;

@endnode

@node _StkSize
@alias etext edata ebss __text __data __bss

long _StkSize = 4096;

	This variable defines the amount of run-time stack space to be
	reserved.  The default value is 4K, which is enough
	for small applications.  Since dynamic memory is NOT allocated
	from the stack, this value need only be large enough to handle
	local variables and deep recursion.

	The stack area is created by the linker at the end of the BSS.

char *etext;
char *edata;
char *ebss;

	These variables point to the first byte beyond the end of the
	text, data and BSS segments respectively.  They are provided
	for compatibility.

__text
__data
__bss

	These are the linkable names of the first byte of the
	respective segments.
@endnode

@node _initargs

void _initargs(char *cmdline, int cmdlen)

	Process the command arguments, either parsing the command line
	or copying XARG arguments, and retrieve the environment string.
	This function is called from the startup module very early on.
	Values to be passed to the user's main() function are stored in
	the global variables "_argc" and "_argv".  The startup module
	initiallizes these variables to indicate that no arguments are
	available, and sets "_envp" from the value in the basepage.  If
	a program doesn't use arguments, this function can be replaced
	by one like the one in <sys\minimum.h> to make the program smaller.
@endnode

@node Init_iob
@alias Exit_iob

void (*init_streams)(void) = Init_iob;

	This function defines the standard streams, check to see which
	of them are devices.
	The startup module calls this function prior to starting
	the C program.
	The following standard streams are initialized by Init_iob():
		stdin		Standard input, may be redirected
		stdout		Standard output, may be redirected
		stderr		Usually the system console
		stdprn		The standard printer (output only)
		stdaux		The communication port (input/output)

void (*end_streams)(void) = Exit_iob;
	Flushes and closes all open streams.
	Called by exit()
@endnode

@node atexit

typedef void VpV(void);
short atexit(VpV *func)

	Define routines that must be executed when a program ends,
	either by calling exit(n) or by returning from main.

	A maximum of 32 atexit functions can be stacked.

	-1 is returned when the stack is full.
@endnode

@node main
@alias exit abort

short main(short argc, char *argv[], char *envp)

	This function is not actually in the standard libraries, but
	must be present somewhere in the user's code.  The parameters
	passed to it by the startup code are the number of arguments in the
	command line, a pointer to a list of pointers to arguments, and
	a pointer to the initial environment string.  The return value
	from main() to exit().  Therefore, you
	should always return from main(), or call exit() directly.

void exit(short status)

	Returns <status> value to the operating system.
	The exit function is held in the startup code.

void abort(void)

	Prints the message "Abnormal program termination" to stderr and
	calls exit() with a status code of 3.
@endnode

@node getpid(void)

int getpid(void)

	Return an integer value unique for this process.
@endnode
@node getenv

char *getenv(const char *var)

	Search for <var> in the environment.  If <var> is found, a pointer
	to it's value is returned.  NULL is returned if <var> is not found.
	WARNING:  The returned pointer points into the environment and
	must not be modified!
@endnode

@node putenv

short putenv(const char *entry)

	Add <entry> to the environment.
	<entry> can be any of the following forms:

		<VARIABLE>
		<VARIABLE>=
		<VARIABLE>=<value>

	The first form removes <VARIABLE> from the environment.  getenv()
	will return NULL if looking for this variable.  The second form adds
	<VARIABLE> to the environment, with a null value.  getenv() will
	return a pointer to a '\0' character if looking for this variable.
	Many environment handlers don't support such "tag variables", so
	their use is not recommended.  The final form is the most common,
	and safest to use.  <VARIABLE> is installed (or replaced) with the
	value <value>.  It should be noted that the putenv() function itself
	is not supported in many systems and therefore may not be portable.
	In addition, care should be taken to prevent overflowing the space
	allocated for the environment.  Returns TRUE for success or FALSE
	for failure.  NO OVERFLOW CHECKING IS DONE.
@endnode

@node shell
void shell()

Not yet implemented in AHCCLIB

@alias system
	Invoke a command line interface shell.  If the "SHELL" environment
	variable is not defined, a prompt showing the current working
	directory will be given.  Each line entered will then be passed
	to the system() function for execution until the command "exit"
	is entered to terminate the shell.  If "SHELL" is defined, and
	the "_shell_p" variable is valid, the value of "SHELL" will be
	passed to the program pointed to by "_shell_p" in order to allow
	the shell to invoke a command line interaction of its own.  If
	the "_shell_p" variable is not valid, the program defined by
	"SHELL" will be searched for along the "PATH", and executed with
	no arguments.  If the "SHELL" can't be found, the internal command
	line described above will be used.

int system(char *command)
	Attempts to pass <command> to the shell program pointed to by
	the system variable "_shell_p".  If a valid shell can't be found
	there, the "SHELL" environment variable is searched for.  If it
	exists and is not empty, it will be the name of the shell program
	to execute the given command.  If "SHELL" is not valid, the
	"PATH" variable is used as a list of directories to search for
	the program name which is the first token of the command.  The
	extensions tried (if none is specified) are ".TTP", ".TOS",
	".PRG" and ".APP".
@endnode

@node fork
@alias forklp forkle forklpe forkv forkvp forkve forkvpe wait
int forkl(char *program[, *arg0, *arg1, ..., *argN], NULL)
	Create a child process.  Since it is not possible to do a true
	Unix-style fork(), the functionality of the fork()/exec() pair
	is provided by these fork*() functions.  A process is created,
	running concurrently if possible, which executes <program> with
	the arguments given.  A process id number is returned, which can
	be compared against the return value from wait().  Note that by
	convention <arg0> should be the name of the program that is
	being called, and is often ignored.  The fork*() functions all
	return ERROR if they for failure, or the child pid for success.

int forklp(char *program[, *arg0, *arg1, ..., *argN], NULL)
	Use the environment variable "PATH" to find <program>. (cf: forkl)

int forkle(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp)
	Pass the environment <envp> to the child process. (cf: forkl)

int forklpe(char *program[, *arg0, *arg1, ..., *argN], NULL, *envp)
	Use the environment variable "PATH" to find <program> and
	pass the environment <envp> to the child process. (cf: forkl)

int forkv(char *program, **argv)
	Like forkl() except <argv> points to a NULL terminated list of
	pointers to arguments.  This is particularly useful if the number
	of arguments is not known at compile time.

int forkvp(char *program, **argv)
	Use the environment variable "PATH" to find <program>. (cf: forkv)

int forkve(char *program, **argv, *envp)
	Pass the environment <envp> to the child process. (cf: forkv)

int forkvpe(char *program, **argv, *envp)
	Use the environment variable "PATH" to find <program> and
	pass the environment <envp> to the child process. (cf: forkv)

int wait(int *rvp)
	Wait for a child process to terminate.  Return -1 if there are
	no children.  Normal return is the process id number of the
	terminated child.  <rvp> is an pointer to the place to store
	the return value and exit status.  The high byte of the word
	pointed to be <rvp> will contain the value returned from the
	child through exit().  The low byte will contain 0 if the process
	terminated normally, or an error code if abnormally.
@endnode

@node gemdos
@alias bios xbios bdos

long gemdos(int func, ...)
	Call operating system trap #1 (GEMDOS) function number <func> with
	the arguments given.  Return value returned by the trap call.

long bios(int func, ...)
	Call operating system trap #13 (BIOS) function number <func> with
	the arguments given.  Return value returned by the trap call.

long xbios(int func, ...)
	Call operating system trap #14 (XBIOS) function number <func> with
	the arguments given.  Return value returned by the trap call.

int bdos(int func, long parameter)
	Call operating system trap #2 (BDOS) function number <func> with
	passing the specified <parameter>.  Note that <parameter> must
	always be a long value, even if only a 16-bit value is required
	by the specified BDOS function.
@endnode

@node setjmp

int setjmp(jmp_buf context)
	Save <context> for longjmp(). You MUST include <setjmp.h> to use.
	Calling this function saves the current program context in the
	context buffer provided and returns zero.  A later call to the
	longjmp() function will cause the context to be restored and
	your program will continue as if it just returned from setjmp(),
	but this time with the (non-zero) return value specified in the
	longjmp() call.  THE SAVED CONTEXT WILL NOT BE VALID IF YOU
	EXIT THE FUNCTION THAT CALLED setjmp().

void longjmp(jmp_buf context, int rv)
	Return <rv> to the <context> saved by setjmp(). (cf: setjmp)
	You MUST include <setjmp.h> to use.

catch & throw are not ported to AHCCLIB

int catch(jmp_buf context, int (*func)())
	Execute <func> with <context> saved for throw().  You MUST include
	<setjmp.h> to use.  Return the value returned by <func>.  The main
	advantage of these functions over catch/throw is the ability to
	return zero from the function executed, and the logically "cleaner"
	encapsulation of the non-local jump operation.  These functions
	are patterned after similar functions in LISP.  (cf: setjmp/longjmp)

void throw(jump_buf context, int rv)
	Return <rv> to <context> saved by catch().  You MUST include
	<setjmp.h> to use.
@endnode

@node "memory allocator"
@alias AHCM

                          Welcome to AHCM
                A Home Cooked Memory allocation system.

                                Why?

   ù             Thread safe by using multiple heaps.
   ù      Internal structures available to the user so you can
               perform sanity checks and detect leaking.
   ù A key field which can be used for identifying individual allocations
   ù     A type field which can be used for grouping allocations
   ù         Both fields can be used for controlled freeing
   ù  Reduction of OS heap fragmentation by putting the larger units
             in blocks a multiple of a given roundup width.


                         1: Introduction to AHCM
                         2: Function reference
                         3: AHCM examples


                   AHCM will make your life easy.

  The base functions are used in XaAES for almost 3 years without problems.

                      Greetings, Henk Robbers.


Amsterdam
feb 2005
@endnode

@node "Introduction to AHCM"

The current memory allocation system of standard C is just too simple
and primitive.
The lack of block structuring and hence the danger of
memory leakage are a constant source of misbehaviour.

Another point is that the standard system is totalitarian.
There is only 1 heap.
AHCM can have any number of heaps, each having different access
permissions and different chunk and round sizes.

AHCM uses the same 2 level approach as other Atari malloc systems
which reduces considerably the number of Gemdos calls.

A single application level memory allocation is called a 'unit'.
A Gemdos level allocation is called a 'block'.

Both entities use next and prior pointers.
Additionally each unit is provided with 2 identification fields.
These fields make it possible to abandon the pointer driven freeing
completely. In stead freeing can be done by catagorizing units.
There is no longer the need of the often tedious remembering of the
addresses of ALL allocated units and calling free() for each unit in turn.


Handling of large units (larger then fits in the heaps chunksize):
   A Gemdos block of size equal to the nearest higher multiple
   of the heaps round size is allocated.
   The large unit is placed at end of the block.
   The excess at the beginning of the block is put in a free list.
   No space is wasted.
   When the large unit is freed, the block is shrunken to the
   heaps chunk size. The resulting smaller unit is put in the free list.
   Of course, if nothing has been allocated at the beginning, the whole
   block is returned to the OS.

   When a large unit is shrunken by realloc, any part that becomes free
   and is larger than the chunksize is also given back to the OS in
   multiples of chunksize.

There is now a function that can free a whole bunch of units in a single
streak by using one or both of those 2 identification fields.

Because TOS and Mint do not provide virtual memory as yet, use of
the stack for allocating dynamic memory may cause stack capacity
problems.

To compensate for this, AHCM provides 3 functions (XA_up, XA_new & XA_down)
for use in a stack like manner. Or in a block structured manner if you wish.
The system doesn't work automatically; you have to call these functions
explicitly. But at least it provides a way of block structured dynamic
memory that is easy to do it correctly.

The principle is that keeping track of memory is block structured,
yet the memory itself is allocated from the heap.

For efficiency and organizational reasons, the block structured functions
use their own default base structure.

If your version of C supports a 'new' function natively, you don't
need this option. :-)
@endnode

@node "Function reference"

ù   AHCM's structures and definitions:

	ø   XA_memory         The base structure describing the heap;
	                          required  by ALL calls to AHCM
	ø   XA_block          The OS level block administration
	ø   XA_unit           The user level unit administration
	ø   XA_key            Type of the 'key' and 'type' fields

ù   AHCM's functions:

	ø   XA_set_base       Fill out a base structure.
	ø   XA_alloc          Allocate                   (replaces malloc)
	ø   XA_calloc         Allocate and zeroize       (replaces calloc)
	ø   XA_realloc        Reallocate with different size  (replaces realloc)
	ø   XA_free           Free                       (replaces free)
	ø   XA_free_all       Completely or selectively freeing in a heap.
	ø   XA_up             Increment the stack value in the base
	ø   XA_new            Allocate using stack value in the base for 'type'
	ø   XA_down           Free everything with a type higher than
	                      or equal to the stack value in the base,
	                      then decrement the stack value in the base
	ø   XA_leaked         Go through all allocated units in a heap
	ø   XA_sanity         Do some sanity checks on a heap
	ø   XA_report         User hook function type for processing results	                      of XA_leaked and XA_sanity
@endnode

@node XA_set_base

	Description:
		Fill out a base structure.

	Declaration:
		void    XA_set_base (XA_memory *base, size_t chunk,
		                     short round, short flags);

	Parameters:
		base:            Address of the base of the heap to be filled out.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is filled out.
		chunk:           The Gemdos chunk size to be used by this heap.
		                 The value can be changed anytime.
		round:           A number representing the power of 2 to which
		                 chunk will be rounded up.
		flags:           If zero AHCM will use Malloc(chunk) for allocating
		                 memory chunks.
		                 Otherwise Mxalloc(chunk, flags) will be used.
		                 The flags tell AHCM what kind of memory must be
		                 allocated for this heap.

		Examples of these flags:
		                MX_STRAM        0
		                MX_TTRAM        1
		                MX_PREFSTRAM    2
		                MX_PREFTTRAM    3
		                MX_HEADER      (1 << 3)
		                MX_PRIVATE    ((1 << 3) | (1 << 4))
		                MX_GLOBAL     ((1 << 3) | (2 << 4))
		                MX_SUPERVISOR ((1 << 3) | (3 << 4))
		                MX_READABLE   ((1 << 3) | (4 << 4))
@endnode

@node XA_alloc

	Description:
		Allocate a amount of memory.

	Declaration:
		void *  XA_alloc (XA_memory *base, size_t amount,
		                  XA_key key, XA_key type);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		amount:          The amount of memory in bytes that has to be
		                 allocated.
		key:             A number defined by the user.
		type:            Another number defined bu the user.

		The key should identify each allocation uniquely.
		The type can be used to group a number of allocations together.
		It is reported back by the XA_leaked and XA_sanity functions.
		It can also be used by the XA_free_all function for selective
		freeing.

	Return:
		The address of the user part of the allocated memory.
		Zero if the memory couldn't be allocated
		or if some error occurred or was detected.
@endnode

@node XA_calloc

	Description:
	    Allocate a zeroized amount of memory.

	Declaration:
		void *  XA_calloc (XA_memory *base, size_t items, size_t chunk,
		                   XA_key key, XA_key type);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		chunk:           A amount of memory in bytes.
		items:           The number of 'chunk's that has to be allocated.
		                 Note that a single unit is allocated of size
		                 items*chunk.
		key:             A number defined by the user.
		type:            Another number defined bu the user.

		The user part of the allocated memory is zeroized.

		The key should identify each allocation uniquely.
		The type can be used to group a number of allocations together.
		It is reported back by the XA_leaked and XA_sanity functions.
		It can also be used by the XA_free_all function for selective
		freeing.

	Return:
		The address of the user part of the allocated memory.
		Zero if the memory couldn't be allocated
		or if some error occurred or was detected.
@endnode

@node XA_realloc

	Description:
		Reallocate a previously allocated amount of memory with a
		             different size.

	Declaration:
		void *  XA_realloc (XA_memory *base, void *old, size_t new_amount,
		                    XA_key key, XA_key type);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		old:             Adress of allocation whose size has to be changed.
		                 If old is zero, XA_realloc behaves exactly like
		                 XA_alloc.
		                 If the address is not of a existing unit the
		                 behaviour is undefined.
		new_amount:      The new amount of memory in bytes that has to be
		                 allocated.
		key:             A number defined by the user.
		type:            Another number defined bu the user.

		The key should identify each allocation uniquely.
		The type can be used to group a number of allocations together.
		It is reported back by the XA_leaked and XA_sanity functions.
		It can also be used by the XA_free_all function for selective
		freeing.

		The contents of the new allocation will be the same as the old
		up and including the lesser of the new and the old size.
		Any excess storage in the larger of the 2 will have
		undeterminate contents.
		key and type replace existing key and type.

	Return:
		The address of the user part of the allocated memory.
		The address may or may not be different from the old address.
		Zero if the memory couldn't be allocated
		or if some error occurred or was detected.
		If the old allocation wasnt previously allocated,
		no action is taken and 0L is returned.
@endnode

@node XA_up

	Description:
		Increment the current stack level in the base.

	Declaration:
		void   XA_up (XA_memory *base);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		                 In any case the base must be different from
		                 any base used by XA_(c,re)alloc.
		                 If you always provide a zero base, this will
		                 automatically be the case.
@endnode

@node XA_new

	Description:
		Allocate using stack value set by XA_up

	Declaration:
		void *XA_new(XA_memory *base, size_t amount, XA_key key);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		                 In any case the base must be different from
		                 any base used by XA_alloc and XA_calloc.
		                 If you always provide a zero base, this will
		                 automatically be the case.
		amount:          The amount of memory in bytes that has to be
		                 allocated.
		key:             A number defined by the user for unique
		                 identification of allocation.
		                 Note: The stack value in the base is used as type.
@endnode

@node XA_down

	Description:
		Free everything with a type higher than
	    or equal to the current stack value in the base,
	    then decrement the stack value in the base

	Declaration:
		void    XA_down (XA_memory *base);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		                 In any case the base must be different from
		                 any base used by XA_(c,re)alloc.
		                 If you always provide a zero base, this will
		                 automatically be the case.
@endnode

@node XA_free

	Description:
		Free a unit.

	Declaration:
		void    XA_free (XA_memory *base, void *area);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		area:            Address of an area as returned by any of the
		                 allocation functions.
@endnode

@node XA_free_all

	Description:
		All or selective freeing in a heap.

	Declaration:
		void    XA_free_all (XA_memory *base, XA_key key, XA_key type);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.

		key:             All units with specified key must be freed.
		type:            All units with specified type must be freed.

		                 If both key and type are passed -1, the whole
		                 heap is freed in the fasted way possible.

		                 If -1 is specified for key or type, no check is
		                 made for that field. Which means that all units
		                 of that key cq type are considered.

		                 The relation between key and type is 'and'

		                 Example:
		                 XA_free_all(0, -1, handle)
		                 All units having handle as type are freed.
@endnode

@node XA_report

	Description:
		Type of a report function that is called by XA_leaked and
		    XA_sanity when something reportable occurs.

		A fuction of the type must be written by the user.
		You may find a example of such a function in AHCM examples.

	Declaration:
		typedef void XA_report (XA_memory *base,
		                        XA_block *blk, XA_unit *unit, char *txt);

	Parameters:
		base:        Address of base of the heap to be used.
		             Zero if only 1 heap is to be used by the program,
		             in which case the standard base is used.

		blk:         Block that is subject of the report. (if applicable)
		unit:        Unit that is subject of the report.  (if applicable)
		txt:         A character string provided by XA_leaked and XA_sanity
		             so you know where the call to the report function
		             comes from.
@endnode

@node XA_leaked

	Description:
		Report every unit that is still allocated at the point this
		   function is called.
		Normally one should call this function right before exit().

	Declaration:
		bool    XA_leaked (XA_memory *base,
		                   XA_key key, XA_key type, XA_report *report);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		report:          Address of the report function to be called for
		                 each allocated unit.
		key and type:    Usage is same as for XA_free_all.
		                 With the exception that units are not freed,
		                 but reported in stead. ;-)
@endnode

@node XA_sanity

	Description:
		Do a sanity check on a heap.

		A function of this type can be written by the user.

		The XA_sanity in AHCM does some very basic checks and
		can be considered a example.

		For each block in the heap:
		  First all sizes of units in the block are added up
		    to see if units fill the block completely.
		    This MUST be the case.
		  Then the used list links are followed up and down (next, prior)
		    If this process reaches the unit at which it started, the links
		    are sane. Same is done for the free list.


	Declaration:
		void    XA_sanity (XA_memory *base, XA_report *report);

	Parameters:
		base:            Address of base of the heap to be used.
		                 Zero if only 1 heap is to be used by the program,
		                 in which case the standard base is used.
		report:          Address of the report function to be called for
		                 each unit causing a error.
@endnode

@node structures
@alias definitions types XA_memory XA_block XA_unit XA_key size_t

ù   size_t should be defined as long (32 bits) in its usual standard way.

@index XA_memory
ù   The base structure describing the heap required by all calls to AHCM:

@index XA_memory
typedef struct xa_memory
{
	XA_block *first, *last, *cur;
	long chunk;
	short round,
	      mode,
	      stack;
} XA_memory;



ù   any list of units, generalizing used and free lists

typedef struct xa_list
{
	struct xa_unit *first, *cur, *last;
} XA_list;

@index XA_block
ù   Administration of OS level blocks (also called 'chunks')

typedef struct xa_block
{
	long size;
	struct xa_block *next, *prior;
	XA_list used, free;
	short mode;
	XA_unit area[0];
} XA_block;

@index XA_key
ù   The type of the key and type field in the AHCM units has been
	parameterized. This makes changing the type
	an easy and safe operation.

	Currently defined as:
typedef short XA_key;

@index XA_unit
ù  Administration of user level blocks (also called 'units')

typedef struct xa_unit
{
	long size;
	struct xa_unit *next,*prior;
	XA_key key, type;
	char area[0];
} XA_unit;
@endnode

@node "AHCM examples"

The package contains as a bridge to the functions
malloc, calloc, realloc, free & _FreeAll
as follows:

void *malloc(size_t size)
{
	return XA_alloc(0, size, 0, 0);
}

void *calloc(size_t items, size_t chunk)
{
	return XA_calloc(0, items, chunk, 0, 0);
}

void *realloc(void *old, size_t new_size)
{
	return XA_realloc(0, old, new_size, 0, 0);
}

void free(void *addr)
{
	XA_free(0, addr);
}

void _FreeAll(void)
{
	XA_free_all(0, -1, -1);
}

And also as a quick way of using leak detection and identification of
individual allocations:

void *xmalloc(size_t size, XA_key key)
{
	return XA_alloc(nil, size, key, 0);
}

void *xcalloc(size_t items, size_t chunk, XA_key key)
{
	return XA_calloc(nil, items, chunk, key, 0);
}

void *xrealloc(void *old, size_t size, XA_key key)
{
	return XA_realloc(nil, old, size, key, 0);
}


========================================================================

Very often the allocated units all are needed at the same time all this
time. (Lines or records in file as long as the file is open)
This means that no individual freeing is needed.
The absence of the need of individual freeing can make the allocation
many times more efficient.

AHCM makes such an approach possible and not too difficult.
The multiple heaps originated from the need for use in asynchronous threads.
They appeared to be very useful in single threaded code as well.

The advantage of the approach below is that it remains to be dynamic
as a whole.

The functions in the example are real. I use them in the Pure linker
replacement for all symbol tables.

#include "ahcm.h"

typedef struct membase
{
	XA_memory base;
	char *memory;
	size_t memorynow;
	size_t chunk;
	char *name;              /* For debugging */
} MEMBASE;

/* NB!
   blockprefix and unitprefix are from "ahcm.h"
   and are important.
*/

void init_membase(MEMBASE *mb, long chunk, char *name)
{
	mb->chunk = chunk - blockprefix - 2*unitprefix;
	mb->memorynow = 2*mb->chunk;
	mb->memory = 0;
	mb->name = name;
	XA_set_base(&mb->base, chunk, 0, 0);
}

void * alloc(MEMBASE *mb, size_t new, char *remark)
{
	char *ret;
	new = (new + 3) & ~3;             /* 4 byte align */

	if (mb->memorynow + new > mb->chunk)
	{
		mb->memory = XA_alloc(&mb->base, mb->chunk, -1, -1);

		if (mb->memory == 0)
		{
			mem_alert(remark);        /* some warning function */
			return 0;
		}

		mb->memorynow = 0;
	}

	ret = mb->memory;
	mb->memory += new;                /* Simply put the units one after
	mb->memorynow += new;                each other without any red tape */
	return ret;
}

void free_membase(MEMBASE *mb)
{
	XA_free_all(&mb->base, -1, -1);
	mb->memorynow = 2*mb->chunk;      /* useful high value for initial */
	mb->memory = 0;
}


void some_function(void)
{
	/* Define a memory base for local use */
	MEMBASE mlocal;
	init_membase(&mlocal, 8192, "efficient local base");

	.....................

	while (not_ready)
	{
		any_pointer *new = alloc(&mlocal, anysize, some_remark);

		/* Do anything you like with any number of 'new's
		until you're done */

		............................................................

	}

	.....................

	free_membase(&mlocal);         /* Free the whole local base in a swoop */
}

==========================================================================

Example of a report function:

#if __PUREC__
XA_report punit
#else
void punit (XA_memory *base, XA_block *blk, XA_unit *unit, char *txt)
#endif
{
	printf("**** %s: ", txt);
	if (!unit)
		printf("nil\n");
	else
	{
		XA_unit *prior = unit->prior,
		        *next = unit->next;
		printf(" -%d- %ld :: %ld, p:%ld :: %ld, n:%ld :: %ld, block %ld :: %ld\n",
			unit->key,
			unit,
			unit->size,
			prior,
			prior?prior->size:-1,
			next,
			next?next->size:-1,
			blk,
			blk->size);
	}
}

========================================================================
@endnode

@node alloca

char *cdecl alloca(size_t size)

	Allocate at least <size> bytes of memory from the stack.  This
	is "automatic" variable space and will be freed when the function
	which called alloca() exits.  DO NOT use the other dynamic memory
	functions like free() and realloc() on the block returned
	by this function.  A pointer to the requested block is returned,
	or NULL if there is not enough stack space available.
@endnode

@node sbrk

void *sbrk(size_t amount)

	Move the "break" by <amount>.  The break is the line between the
	top of the heap and the bottom of the stack.  The size of the
	stack/heap area is defined by _StkSize.  Initially, the heap uses
	zero bytes.  Since malloc() doesn't use the heap, often the heap
	will stay that way.  This function moves the location of the break
	by <amount> bytes, positive or negative, and returns the old value
	of the break.  If this causes a collision with the stack, or a
	negative value reduces the heap below zero bytes, NULL is returned
	and the break is not moved.  Note that the heap pointer is moved by
	EXACTLY the <amount> specified.  If you want to ensure that sbrk()
	will return word-aligned memory segments, you must make sure that
	<amount> is always even, since the heap is initially aligned properly.
@endnode

@node brk

short brk(void *address)

	Set the "break" to <address>.  Return 0 for success.  If <address>
	is not a valid break value, return -1 and don't move the break.
@endnode

@node chdir

short chdir(const char *pathname)

	Changes the current working directory to <pathname>.  If a
	drive letter is specified in <pathname>, the current working
	directory for that drive is set.  Returns 0 for success, or
	a negative error code.
@endnode

@node mkdir

short mkdir(const char *pathname)

	Creates a new directory called <pathname>.  A drive letter may
	be specified.  Returns 0 for success, or a negative error code.
@endnode

@node rmdir

short rmdir(const char *pathname)

	Removes an existing directory called <pathname>.  A drive letter may
	be specified.  Returns 0 for success, or a negative error code.
@endnode

@node fullpath

char *fullpath(char *full, const char *part)

	<part> is a (possibly) ambiguous file/path specification.  A
	non-ambiguous file/path spec is created which includes a drive
	letter and all intermediate sub-directories.  If the partial
	specification is not valid, NULL is returned, otherwise a
	pointer to <full> is returned.  If NULL is specified for <full>,
	an internal buffer is used and a pointer to it is returned.

@endnode

@node getcwd

char *getcwd(char *buffer, short size)

	Get the full pathname of the current working directory.  This
	value will ALWAYS end with a '\\' character.  <pathbuf> is a
	pointer to a buffer of <size> bytes that will be used to store
	the current working directory.  If <buffer> is NULL, a buffer
	of <size> bytes will be malloc()ed.  The function returns a
	pointer to the buffer for success, or NULL for failure, either
	because malloc() failed, or the value is larger than <size>.
	This function uses fullpath() to get the pathname, therefore
	the buffer internal to fullpath() is overwritten.
@endnode

@node access

short access(const char *name, short amode)

	Return non-zero if a file with the given <name> can be accessed
	in the given <amode>.  Possible <amode> values are:
		0x00		file exists
		0x02		file can be written
		0x04		file can be read
		0x06		file can be read and written
@endnode

@node findfile

char *findfile(const char *afn, const char *ext)

	Return full file spec for <afn> if found. If <afn> has no extension,
	extensions from <ext> are tried until a match is found, or the list
	ends.  <ext> is a list of extensions separated by '\0' characters
	and ending with an additional '\0', ie. ".ttp\0.tos\0.prg\0" (note
	that the final null is added by the compiler to any string constant.
	If <afn> already has an extension, <ext> is not used.  If no matching
	files are found, NULL is returned.  The pointer returned when a match
	is found points to a buffer which is internal to fullpath().  If you
	want to save the value returned, you must make a copy before the
	buffer is overwritten by subsequent calls.  Note: several dLibs
	functions call filefind(), so don't make too many assumptions about
	how long the internal buffer is going to stay valid.
@endnode

@node pfindfile

char *pfindfile(const char *path, const char *afn, const char *ext)

	Like findfile() but search all directories (separated by ',' or ';')
	in <path>.  If <path> is NULL, the "PATH" environment variable is
	used instead.  If <afn> specifies a drive or directory, <path> is
	not used.  The internal buffer for findfile() is used by pfindfile().
@endnode

@node wildcard

char *wildcard(const char *pathname)

	Return matches for a wildcard filename.  If <pathname> is not
	NULL, the first file which matches <pathname> will be returned.
	The <pathname> may contain wildcards only in the filename portion,
	not in any sub-directories.  Subsequent calls to wildcard() with
	a NULL argument return the next matching filename.  NULL is
	returned when no more files match.  Note: the pointer returned
	points to an internal buffer which is overwritten with each
	call.  It should not be modified, and should be copied into a
	safe place if you want to save the value.
@endnode

@node _splitpath

char *_splitpath
(
	const char *src,
	char *drive,
	char *path,
	char *file,
	char *ext
)

	Parse the <src> filename into component parts. Returns <src>.
	If any of the component pointers is NULL, that component will
	be parsed, but not saved.  If a given component does not exists
	int the <src> string, the component will be empty, (ie.: "").
	The <drive> component will be a drive letter followed by a colon,
	(ie.: "a:").  The <path> component will be the subdirectory names
	leading up to the filename, but will not include a trailing '\'
	unless the path the simply the root path "\", and there will only
	be a leading '\' if the path is fully qualified, or "rooted", ie.:
	"\this\is\a\path\name".  The <file> component is the base filename
	without any extension, ie.: "filename".  The <ext> component is
	the file extention with no leading '.', ie.: "txt".  Recommended
	sizes for the components is Drive[4], Path[128], File[10], Ext[4].
@endnode

@node _makepath

char *_makepath
(
	char *dst,
	const char *drive,
	const char *path,
	const char *file,
	const char *ext
);

	Build the <dst> filename from component parts. Returns <dst>.
	This function is basically in inverse of _splitpath(), and will
	accept the components parsed by _splitpath() as input.  It will
	also allow a little more flexibility in that it will treat any
	component which is a NULL pointer as an empty field, and the
	<path> component may optionally have a trailing '\'.
@endnode

@node tmpnam

char *tmpnam(char *s)

	Generate a unique filename to be used for a temporary file.
	The filename will have the form "TEMP$nnn.TMP" where "nnn" is a
	sequence of numeric digits.  The name will unique in the current
	working directory.  If <s> is NULL, space will be obtained from
	malloc() to store the filename and thus must be free()'d by the
	caller.  If <s> is not NULL, the filename will be copied into the
	buffer provided.  This function returns NULL for failure, or a
	pointer to the filename for success.
@endnode

@node tempnam

char *tempnam(const char *dir, char *pfx)

	This function is similar to tmpnam(), but is somewhat more flexible.
	<dir> specifies the directory part of the filename.  If <dir> is
	NULL, the TMPDIR environment variable will be used.  If TMPDIR is
	not found, the current directory is used.  <pfx> specifies the
	filename prefix (up to 5 characters).  The form of the filename
	will be "dir\pfxnnn.TMP", similar to tmpnam().  The storage for
	the filename is always obtained from malloc(), so the caller must
	free() it after use.  This function returns NULL for failure, or a
	pointer to the fully expanded filename for success.
@endnode

@node stat

short stat(const char *name, struct stat *statbuf)

	Search for file <name> and load <statbuf> with information
	about that file, if it is found.  Return 0 if found, or
	ERROR (-1) if no file/directory matched <name>.  Volume
	labels are not included in the search.  The file <ext.h>
	must be included if you use this functions, since it defines
	struct stat.
@endnode

@node fsize

long fsize(const char *name)

	Return the size of the file <name> in bytes.  Note that this
	is a long value.  Return -1L if the file is not found.
@endnode

@node isatty

short isatty(short handle)

	Return non-zero if <handle> refers to a character device.
	Negative handles always refer to character devices.
@endnode

@node creat

int creat(char *filename)

	Create a new file with the given <filename>.  If a file with
	the name already exists, it will be truncated to zero bytes.
	Since the OS doesn't do this properly, the file is actually
	deleted and then re-created.
@endnode

@node chmod

short chmod(const char *filename, short pmode)

	Change the mode attribute of <filename> to <pmode>.  Values for
	<pmode> are the same as for the creat() function.  Returns 0 for
	success, or a negative error code.
	The function calls Fattrib.
@endnode

@node open

short open(const char *filename, short iomode, ...)

	The ellipsis is for optional pmode constants.
	Attempt to open <filename> with the given <iomode>.  A file handle
	is returned if the open succeeds.  A negative error code is returned
	for errors.  Valid <iomode> values are:
		O_RDONLY	read mode
		O_WRONLY	write mode
		O_RDWR		read/write mode
	In addition to the (mutually exclusive) modes above, one or more
	of the following options may be |-ed with <iomode>:
		O_APPEND	start file pointer at end of file
		O_TRUNC		if file exists, truncate to 0 length
		O_CREAT		creat() file if none exists (uses <pmode>)
		O_EXCL		return EEXIST if file exists and
				O_CREAT is specified (exclusive mode).
	Note: It is possible to open the character devices "con:", "aux:",
	and "prn:" with this call, and negative handles (-1..-3) will be
	returned.  Error returns are always < -3.  The <stdio.h> file
	contains iomode constants.  The <stat.h> file contains pmode
	constants.
@endnode

@node close

short close(short handle)

	Close file referenced by the file handle <h>.  Return 0 for
	success, or a negative error code.
@endnode

@node dup

short dup(short handle)

	Return a second file handle which refers to the same file as
	the given <handle>. (cf: dup2)
@endnode

@node dup2

short dup2(short handle1, short handle2)

	Force <handle2> to refer to the same file as <handle1>.  Return
	0 for success, or a negative error code.  Both dup() and dup2()
	are direct calls to Fdup() and Fforce() GEMDOS calls.  Refer to
	your GEMDOS documentation for further information.
@endnode

@node remove

short remove(const char *filename)

	Delete <filename>, if it exists.  Return 0 for success, or a
	negative error code.
@endnode

@node rename

short rename(const char *oldname, const char *newname)

	Change the name of file <oldname> to <newname>.  You may use this
	function to move files from one directory (pathname) to another,
	but not from one drive to another.  Return 0 for success, or a
	negative error code.
@endnode

@node lseek

size_t lseek(short h, size_t offset, short origin)

	Move file pointer for file <h> to specified location.  <origin>
	specifies the starting point for the <offset> distance.  Valid
	<origin> values are:
		SEEK_SET	from beginning of file	(0)
		SEEK_CUR	from current location	(1)
		SEEK_END	from end of file	(2)
	The <offset> value is the distance in bytes from the origin.
	The final file position, or a negative error code, is returned.
@endnode

@node tell

size_t tell(short h)

	Return the current file position for the file <h>.
@endnode

@node fopen

FILE *fopen(const char *filename, const char *mode)

	Open <filename> as a stream file.  This is the normal open way
	to open a file.  The <mode> is a string specifying the mode(s)
	that are relevent to the file open.  Valid <mode> characters are:
		r		read mode
		w		write mode
		a		append mode
		b		binary mode
		t		text (translated) mode
	At least one of "r", "w" or "a" must be specified.  "t" is assumed
	and indicates that <nl> is translated to <cr><lf> on output and
	vica-versa on input.  If the stream is a character device, the
	translation is slightly different.  The output translation is the
	same, but on input <cr> and <lf> both become <nl> in all cases.
	The "b", for binary mode, overides "t" and indicated that characters
	are not translated during i/o operations.  "a" represents append
	mode and means that the file pointer will initially be placed at
	the end of the file.  "w" mode will create a file if it doesn't
	exists, or zero an existing file.  If "r" is the only mode specified,
	the file must already exist.  A (FILE *) is returned if the open
	succeeds, or NULL if it fails.
@endnode

@node freopen

FILE *freopen(const char *filename, const char *mode, FILE *fp)

	Closes the file associated with <fp> and opens the new file as with
	fopen(), except that a new FILE structure is not created.  The
	existing FILE structure pointed to by <fp> is re-initialized with
	the new file information.  This is typically used to redirect i/o
	to standard streams stdin, stdout, stderr, stdprn, stdaux.  <fp>
	is returned for success, or NULL for failure.
@endnode

@node fdopen

FILE *fdopen(short h, const char *mode)

	Associates a stream with the already open file <h>.  The <mode>
	values are the same as for fopen(), but MUST be compatible with
	the mode in which <h> was open()ed.  This functions allows a file
	opened with the low level open()/creat() calls to be used as a
	buffered/translated stream.  A pointer to a FILE struct is returned,
	or NULL for errors.
@endnode

@node fopenp

FILE *fopenp(const char *filename, const char *mode)

	Find <filename> somewhere on the PATH and open it with <mode>.
	Refer to the fopen() function for valid <mode> values.  If you
	want to use a search path other than the PATH environment
	variable, use the pfindfile() function to locate the file, and
	pass that filename to fopen().  (cf: pfindfile, fopen)
@endnode

@node fclose

short fclose(FILE *fp)

	Close the stream <fp>, flushing the buffer.  Returns 0 on success.
@endnode

@node setbuf

void setbuf(FILE *fp, void *buf)

	If <buf> is NULL, make <fp> unbuffered; else <buf> points to a buffer
	of BUFSIZ characters to be used as the stream buffer for <fp>.
@endnode

@node setvbuf

short setvbuf(FILE *fp, void *buf, short bmode, size_t size)

	If <buf> is NULL or <bmode> is _IONBF, make <fp> unbuffered;
	otherwise <buf> points to a buffer of <size> characters to be
	used as the stream buffer for <fp>.  The <bmode> variable
	indicates the type of buffering desired, as follows:
		_IONBF		No buffering
		_IOFBF		Full buffering (normal)
		_IOLBF		Line buffering (not supported, same as _IOFBF)
@endnode

@node fseek

short fseek(FILE *fp, long offset, short origin)

	Operates like lseek(), except it works on streams.  Note that
	stream file positions may be misleading due to translation of
	<nl> characters during i/o.  ftell() may be used reliably with
	fseek() to reposition a file to a prior location.  WARNING:
	fseek() returns 0 for success, non-zero for failure, according
	to the ANSI standard.  Some implementations use 0 for failure.
	This function is maintained for compatibility with old programs.
	fsetpos() should be used in new code.  (cf: fsetpos)
@endnode

@node rewind

void rewind(FILE *fp)

	Operates like fseek(fp, 0L, SEEK_SET), except it also clears the
	end-of-file and error flags for <fp>.  There is no return value.
@endnode

@node ftell

long ftell(FILE *fp)

	Operates like tell(), except it works on streams.  Note that
	stream file positions may be misleading due to translation of
	<nl> characters during i/o.  This function is maintained for
	compatibility with old programs.  fsetpos() should be used in
	new code.  (cf: fsetpos)
@endnode

@node fgetpos

short fgetpos(FILE *fp, fpos_t *pos)

	Get the position of the stream <fp> and store it at the location
	pointed to be <pos>.  This is the new X3J11 function to replace
	ftell().  Returns 0 for success and ERROR for failure.
@endnode

@node fsetpos

short fsetpos(FILE *fp, const fpos_t *pos)

	Set the position of the stream <fp> to the valued stored at the
	location pointed to be <pos>.  Note that this function is only
	required to work properly for a <pos> value which was previously
	obtained by fgetpos() on the same stream.  This is the new X3J11
	function to replace fseek().  Returns 0 for success and ERROR for
	failure.
@endnode

@node fileno

short fileno(FILE *fp)

	Return the file handle associated with the stream <fp>.
@endnode

@node feof

short feof(FILE *fp)

	Return non-zero if <fp>	is at end of file.
@endnode

@node ferror

short ferror(FILE *fp)

	Return non-zero if and error has occurred on <fp>.
@endnode

@node clearerr

void clearerr(FILE *fp)

	Clear the error flag on <fp>.
@endnode

@node read

size_t read(short h, void *data, size_t length)

	Read <length> bytes from the file reference by file handle <h>.
	Data is stored in the buffer pointed to by <data>.  The number
	of bytes actually read is returned, 0 for end of file, or a
	negative error code.  Note that the maximum number of bytes
	that can be read by this function is MAXINT.
@endnode

@node write

size_t write(short h, void *data, size_t length)

	Write <length> bytes to the file reference by file handle <h>.
	Data is written from the buffer pointed to by <data>.  The number
	of bytes actually written is returned, or a negative error code.
	Note that the maximum number of bytes that can be written by
	this function is MAXINT.
@endnode

@node fread

size_t fread(void *data, size_t size, size_t count, FILE *fp)

	Read <count> items of <size> characters each from stream <fp>.
	Data is stored in the buffer pointed to by <data>.  The number of
	full items actually read is returned, or a negative error code.
	This call DOES NOT translate characters, even if the stream is
	opened in translate mode.
@endnode

@node fwrite

size_t fwrite(const void *data, size_t size, size_t count, FILE *fp)

	Write <count> items of <size> characters each to stream <fp>.
	Data is read from the buffer pointed to by <data>.  The number of
	full items actually written is returned, or a negative error code.
	This call DOES NOT translate characters, even if the stream is
	opened in translate mode.
@endnode

@node fgetc

short fgetc(FILE *fp)

	Get a character from <fp>.  Returns the character or EOF.
@endnode

@node fungetc

short fungetc(short c, FILE *fp)

	Push the character <c> back to be gotten by the next fgetc()
	call on <fp>.  Only 1 character may be ungotten at a time on
	each stream.  Subsequent calls to fungetc() will write over
	the currently saved character.
@endnode

@node fputc

short fputc(short c, FILE *fp)

	Put the character <c> to the stream <fp>.
@endnode

@node fflush

short fflush(FILE *fp)

	Flush the file i/o buffer of the stream <fp>.  The buffer is
	automatically flushed when it is full, the stream is closed,
	or the program terminates through exit().  This function has
	no effect if the stream in unbuffered.  Call this function
	before switching between reading and writing on a stream which
	is opened for both.
@endnode

@node getc

#define getc( c )     fgetc( c )

	for compatability
@endnode

@node ungetc

#define ungetc( c)	  fungetc( c )

	for compatability
@endnode

@node putc

#define putc( c, s )  fputc( c, s )

	for compatability
@endnode

@node getw

short getw(FILE *fp)

	Get a 2-byte value from the stream <fp>.  The high-order byte is
	read first.  Use feof() to test for end-of-file.
@endnode

@node putw

short putw(short n, FILE *fp)

	Put the 2-byte value <n> to the stream <fp>.  The high-order byte
	is written first.
@endnode

@node getl

long getl(FILE *fp)

	Get a 4-byte value from the stream <fp>.  The high-order byte is
	read first.  Use feof() to test for end-of-file.
@endnode

@node putl

long putl(long n, FILE *fp)

	Put the 4-byte value <n> to the stream <fp>.  The high-order byte
	is written first.
@endnode

@node getchar

#define getchar()     fgetc( stdin )

	for compatability
@endnode

@node ungetchar

#define ungetchar( c) fungetc(c, stdin)

	for compatability
@endnode

@node putchar

#define putchar( c )  fputc( c, stdout )

	for compatability
@endnode

@node getch

short getch(void)

	Machine dependent console input function.  This function normally
	gets a character from the keyboard by calling the GEMDOS "Cnecin"
	function.
@endnode

@node getche

short getche(void)

	Same as getch() but calls Cconin() directly.
@endnode

@node putch

short putch(short c)

	Machine dependent (typically quite fast) console output function.
	This function normally puts a character to the console by calling
	the GEMDOS "Cconout" function.
	The return value of this function is simply the character sent.

/*	not yet in AHCCLIB:
	If cfg_ch() is given the _CIOB
	option, output is sent to the BIOS "Bconout" function instead.
	The BIOS level functions don't process ^C, ^S or ^Q, while the
	GEMDOS functions do.  At the BIOS level, the _CIOVT option to
	cfg_ch() allows VT-52 escape code processing on output.  The
	GEMDOS function always does VT-52 emulation.  The BIOS function
	defaults to skipping this overhead, but if VT-52 emulation is
	desired, it can still be used through the faster BIOS level
	routine	by using the _CIOVT option.  Control codes, like '\b'
	and '\r', are supported even without VT-52 emulation.
*/
@endnode

@node kbhit

short kbhit(void)

	Machine dependent function to detect if input is waiting for the
	getch() function.  Returns non-zero if the console has data ready.
	The function just calls GEMDOS Cconis.
@endnode

@node getln

typedef short InFunc(void *ip);
typedef short OutFunc(char c, void *op);

char *getln(void *ip, InFunc *get, OutFunc *put, char *buffer, size_t limit)

	Get a line of input from the user.  Allow simple editing of the line
	with BS/DEL, ESC, and CR/LF to terminate input.  Characters are
	retreived by a get(ip) and echoed with put(c,op).  A pointer to
	<buffer> is returned in any case.  This function is no longer
	needed to handle editable i/o from stdin, since the pseduo-tty
	driver code built into fgetc() now handles line editing, but this
	function is still useful if you want to supply your own get/put
	functions (like curses?).
@endnode

@node fgets

char *fgets(char *data, short limit, FILE *fp)

	Get data from <fp> and puts it in the <data> buffer.  At most,
	<limit>-1 characters will be read.  Input will also be terminated
	when a newline is read.  <data> will be '\0' terminated and the
	newline, if read, will be included.  A pointer to the start of
	<data> is returned, or NULL for EOF.
@endnode

@node fputs

short fputs(const char *data, FILE *fp)

	Write the characters in <data> to the stream <fp>.  A newline
	WILL NOT be added.
@endnode

@node gets

char *gets(char *data)

	Get data from stdin and puts it in the <data> buffer.  Input is
	terminated when a newline is read.  The	newline will be replaced
	by a '\0' to terminate the string.  A backspace character will
	remove the preceeding character from the buffer, but will not
	backspace past the start of the buffer.  A pointer to the start
	of <data> is returned, or NULL for EOF.
@endnode

@node puts

short puts(const char *data)

	Write the characters in <data> to stdout.  A newline WILL be
	written after the data.

	The number of characters actually put is returned.
@endnode

@node cputs

void cputs(char *data)

	Write the characters in <data> directly to the console using the
	system dependent putch() function.  A newline WILL NOT be written
	after the data.
@endnode

@node fprintf

short fprintf(FILE *fp, const char *fmt, ...)

	Formatted output to the stream <fp>.  See the _printf() function
	for a description of the <fmt> formatting string.
@endnode

@node printf

short printf(const char *fmt, ...)

	Formatted output to the stdout stream.  See the _printf() function
	for a description of the <fmt> formatting string.
@endnode

@node sprintf

short sprintf(char *buf, const char *fmt, ...)

	Formatted output to the string <buf>.  See the _printf() function
	for a description of the <fmt> formatting string.
@endnode

@node cprintf

short cprintf(const char *fmt, ...)

	Formatted output directly to the console.  This functions uses the
	system dependent putch() for output.  See the _printf() function
	for a description of the <fmt> formatting string.
@endnode

@node vfprintf

short vfprintf(FILE *fp, const char *fmt, va_list args)

	Formatted output to the stream <fp> with a variable argument list.
	See _printf() for formatting and va_start() for stdarg explaination.
@endnode

@node vprintf

short vprintf(const char *fmt, va_list args)

	Formatted output to the stdout stream with a variable argument list.
	See _printf() for formatting and va_start() for stdarg explaination.
@endnode

@node vsprintf

short vsprintf(char *buf, const char *fmt, va_list args)

	Formatted outout to the string <buf> with a variable argument list.
	See _printf() for formatting and va_start() for stdarg explaination.
@endnode

@node fscanf

short fscanf(FILE *fp, const char *fmt, ...)

	Formatted input from the stream <fp>.  See the _scanf() function
	for a description of the <fmt> formatting string.
@endnode

@node scanf

short scanf(const char *fmt, ...)

	Formatted input from the stdin stream.  See the _scanf() function
	for a description of the <fmt> formatting string.
@endnode

@node sscanf

short sscanf(const char *buf, const char *fmt, ...)

	Formatted input from the string <s>.  See the _scanf() function
	for a description of the <fmt> formatting string.
@endnode

@node vscanf

short vscanf(const char *fmt, va_list args)

	Formatted input from the stdin stream with a variable argument list.
	See the _scanf() function for a description of the
	<fmt> formatting string and va_start() for stdarg explaination.
@endnode

@node vsscanf

short vsscanf(char *buf, const char *fmt, va_list args)

	Formatted input from the string <s> with a variable argument list.
	See the _scanf() function for a description of the
	<fmt> formatting string and va_start() for stdarg explaination.
@endnode

@node vfscanf

short vfscanf(FILE *fp, const char *fmt, va_list args)

	Formatted input from the stream <fp> with a variable argument list.
	See the _scanf() function for a description of the
	<fmt> formatting string and va_start() for stdarg explaination.
@endnode

@node _tttty

short _tttty(FILE *fp)

	"Teeny Tiny TTY" driver function.  This function is internal to
	dLibs, but it's name is documented to allow you to replace it with
	a tty driver of your own.  It's operation can be best understood
	by reading and UNDERSTANDING the code in the routine provided.  In
	brief, this function is supposed to read from <fp>, up to a newline
	character, putting the character in the FILE buffer, and return the
	number of characters read (similar to _fillbuf() in some systems).
	If the stream is in binary mode, a full buffer is to be read, with
	no translation.  If the stream is unbuffered, characters are also
	untranslated, but ^C on input is checked for, however, the code
	which calls this function will translate carriage return characters
	into newlines and ^Z will cause EOF.  Effectively, this means that
	line editing is not allowed if the stream is unbuffered, but most
	translation is done.  Note that this mode of operation is the least
	likely to produce unix-like results, particularly in the way some
	control characters are echoed.  It is recommended that either binary
	mode, or buffered and translated mode be used.
@endnode

@node _printf

size_t _printf(void *op, OutFunc *put, const char *fmt, va_list args)

	This function does all the work for printf(), et al.  Many systems
	don't provide direct access to this function (or it's equivalent),
	but it is useful for writing your own printf()-like functions.
	Since this is a non-standard interface, and v[sf]print() is now
	available, you should probably use the stdarg functions instead.
	<fmt> points to a format control string.  <args> pointers to a
	list of arguments.  The format string is used to create and output
	stream with the arguments.  The <put> function is used to output
	each character.  The <op> parameter is given to the <put> function
	to specify the output stream.  Calls to <put> are of the form:
	"(*put)(c, op);" where <c> is the character to output.  The format
	string is composed of characters and format specifications.  The
	'%' character introduces a format specifier.  The general form of
	a format specifier is:
	  %[-][ |+][0][<width>|*][.[<precision>|*]][l]{d|i|u|o|x|p|b|c|s}
	The '-' specifies left justification.  The ' ' or '+' specifies
	the character which preceeds positive numeric values.  The '0'
	specifies that numeric fields will be padded with '0' rather than
	' '.  The <width> field is a numeric value specifying a minimum
	field width.  The <precision> field is a numeric value specifying
	the maximum number of data characters to display.  If '*' is
	specified for the width or the precision, an "int" value is taken
	from the argument list and used for that value.  If no width is
	specified, the field width varies according to the data width.  If
	no precision is specified, all data characters are included in the
	data width.  If the data width exceeds the field width, the field
	width will expand to allow all data characters to be printed.
	Including the 'l' or capitalizing the trailing character specifies
	that the associated value is a "long" type.  The trailing character
	specifies the format type, as follows:
		d	Signed decimal integer
		i	same as 'd'
		u	Unsigned decimal integer
		o	Unsigned octal integer
		x	Unsigned hexadecimal integer
		b	Unsigned binary integer
		p	Pointer (displayed in %06.8lX format)
		c	Character
		s	String
	If the character following the '%' is not recognized, it is
	simply passed along to the output stream, thus "%%" is used to
	print a single '%' character.
@endnode

@node ltoa

char *ltoa(long n, char *buf, short radix)

	Convert the long value <n> to a string in <buf> using <radix>
	as the number base.  If <n> is negative, '-' will be the first
	character in <buf>.  A pointer to <buf> is returned.
@endnode

@node ultoa

char *ultoa(unsigned long n, char *buff, short radix)

	Convert the unsigned long value <n> to a string in <buf> using
	<radix>	as the number base.  A pointer to <buf> is returned.
@endnode

@node itoa

char *itoa(short n, char *buf, short radix)

	Convert the integer value <n> to a string in <buf> using <radix>
	as the number base.  If <n> is negative, '-' will be the first
	character in <buf>.  A pointer to <buf> is returned.
@endnode

@node ftoa
@alias ecvt fcvt
short ftoa( double *x, char *resStr, short ndig, short format,
            short *decPnt, short *sign );

	Convert the double precision floating point number <x>
	to a ascii string.
@endnode

@node atol

long atol(const char *number)

	Convert the string <number> to a long value.  Leading whitespace
	is ignored, a leading +/- is optional.  Characters are processed
	until a non-digit is reached.  Return value is undefined in an
	overflow situation.
@endnode

@node atoi

short atoi(const char *number)

	Convert the string <number> to an int value.  Leading whitespace
	is ignored, a leading +/- is optional.  Characters are processed
	until a non-digit is reached.  Return value is undefined in an
	overflow situation.
@endnode

@node atof

double atof(const char *fval)

	Convert the string <number> to a double precisio floating point
	value. The function strtod is directly called.
@endnode

@node strtod

double strtod(const char *s, const char **endptr)

	Convert a character string to a double precision floating point
	valu. Any format for denoting real numbers used throuhgout the
	world is accepted.
	p.e

	1
	1.0
	0.1
	1e5
	-.6 E -00010
	123456.7890123

	etcetera
@endnode

@node strtol

long strtol(const char *number, const char **nptr, short base)

	Convert the string <number> to a long value of base <base>.  Bases
	from 0 to 36 are allowed.  Leading whitespace is ignored, and a
	leading +/- is optional.  If the <base> is 0, a leading '0'
	indicates base 8 and a leading "0x" or "0X" indicates base 16.
	Characters are processed until a character is found which is not in
	the specified base.  If <nptr> is non-NULL, it will be set to point
	to the character which terminated the translation in <number>.
	Return value is undefined in an overflow situation.
@endnode

@node strtoul

unsigned long strtoul(const char *number, const char **nptr, short base)

	Convert the string <number> to an unsigned long value of base
	<base>.  Bases from 0 to 36 are allowed.  Leadinwhitespace is
	ignored.  If the <base> is 0, a leading '0' indicates base 8 and a
	leading "0x" or "0X" indicates base 16.  Characters are processed
	until a character is found which is not in the specified base.  If
	<nptr> is non-NULL, it will be set to point to the character which
	terminated the translation in <number>.  Return value is undefined
	in an overflow situation.
@endnode

@node _scanf

short _scanf(void *ip, InFunc *get, UnFunc *unget, const char *fmt, char **args)

	This function does all the work for scanf(), et al.  Many systems
	don't provide direct access to this function (or it's equivalent),
	but it is useful for writing your own scanf()-like functions.
	<fmt> points to a format control string.  <args> pointers to a
	list of arguments, each of which is the address of a variable in
	which input data may be stored.  The format string is used to
	control reading of characters from the <get> function.  As each
	character is needed <get> is called in the form "c = (*get)(ip);"
	where <c> is the character read (negative for errors) and <ip> is
	the auxiliary pointer specified by the <ip> parameter.  If a
	character needs to be un-gotten, a call to <unget> of the form
	"(*unget)(c, ip);" is made.  The format string is composed of
	characters and format specifications.  Any characters in <fmt>,
	except whitespace characters, which are not part of a format
	specifier are expected to be matched one-to-one by characters in
	the input stream.  Scanning terminates if a mismatch occurs or if
	any call to <get> results in an error.  Whitespace characters
	match 0 or more whitespace characters in the input stream.  The
	'%' character introduces a format specifier.  The general form of
	a format specifier is:
		 %[*][<width>][l|h]{d|u|o|x|b|i|c|s|n}
	The '*' specifies that a field is to be scanned by not stored.
	No variable pointer should be provided for non-stored format
	specs.  The <width> field specifies that maximum number of
	characters to be process to fill the given format type.  Less
	than <width> characters will be processed if the field ends
	before <width> characters have been processed.  A field ends when
	either a whitespace character, or a character which does not fit
	the specified format, is read.  The preceding 'l' (or
	capitalizing the conversion character) specifies that the
	associated variable is a "long" type.  The trailing character
	specifies the format type, as follows:
		d Signed decimal integer
		u Unsigned decimal integer
		o Unsigned octal integer
		x Unsigned hexadecimal integer
		b Unsigned binary integer
		i Unsigned decimal/octal/hexadecimal/binary integer
		c Character
		s String
		n the current position in the input stream
	If a <width> is specified with the 'c' format, exactly <width>
	characters (including whitespace) are read from the input stream,
	and written to a string.  No '\0' character is added If the
	character following the '%' is not recognized, it is expected to
	match the input stream as a non-format character, thus "%%" is
	used to match a single '%' character.
	One additional conversion is the brace-format.  Shown as "%[...]",
	the '...' represent a list of characters.  If the first character
	in the list is a '^', the field contains any characters -not- in
	the list (starting with the 1st character after the '^').  If the
	first character of the list is not a '^', then the field will
	only contain those characters found in the list.  A right brace
	character (']') can be included as one of the list of characters
	by placing it as the first character in the list.  If the '^'
	negation character is the first character, the included brace
	should be the next character after the '^'.  For maximum
	portability, a range should be explicitly given (a good example
	would be "%[0123456789]"), but to allow for porting from
	systems with smarter scanf functions, this version of scanf
	also supports ranges represented using a <first>-<last>
	form (eg: "%[0-9]").  To use the first-last form, the
	character <first> must be lexically less than or equal to
	the character <last>.  If this rule is violated, or if the
	hyphen is the first or last character of the list, the
	hyphen will be assumed to be just another character in the
	list and no range expansion will be done.  The resulting
	string containing the characters in (or not in) the list
	will be null terminated.  It should be noted that, unlike
	most of the other formats, this conversion does allow the
	programmer to specify that whitespace characters will be
	included in the resulting string.
@endnode

@node ctlcnv

char *ctlcnv(char *string)

	Convert \<char> notation in <string> to actual characters.  This
	is useful for reading strings from a stream when you want to allow
	insertion of control character or other characters that may have
	special meaning otherwise, or may not otherwise be allowed.  The
	following formats are supported:
		\n		newline or linefeed
		\r		carriage return
		\0		null character (value 0)
		\b		backspace
		\t		horizontal tab
		\v		vertical tab
		\f		form feed
		\a		alarm (bell)
		\\		backslash
		\'		single quote
		\"		double quote
		\NNN		octal constant
		\xNN		hexadecimal constant
		\<nl>		"folded" line (both characters removed)
	A pointer to the modified <string> is returned.
@endnode

@node memmove

void *memmove( void *dest, const void *source, size_t len )

	Copies the <source> block to the <dest>.  <len> bytes are
	always copied.  No terminator is added to <dest>.  A pointer
	to <dest> is returned.  Overlap checking IS done.
@endnode

@node memcpy

void *	memcpy( void *dest, const void *source, size_t len )

	Copies the <source> block to the <dest>.  <len> bytes are
	always copied.  No terminator is added to <dest>.  A pointer
	to <dest> is returned.  Overlap checking IS NOT done.
@endnode

@node memset

void *memset( void *dest, short data, size_t len )

    Set <len> bytes of <dest> to <data>.  A pointer to <dest>
	is returned.
@endnode

@node memcmp

short memcmp( const void *blk1, const void *blk2, size_t len )

	Lexicographically compare the two blocks.  Return a value
	indicating the relationship between the blocks.  Possible
	return values are:
		negative blk1 <  blk2
		0		 blk1 == blk2
		positive blk1 >  blk2
	<len> bytes are always compared.
@endnode

@node memicmp

short memicmp( const char *blk1, const char *blk2, size_t len )

	Compare blocks as with memcmp(), but ignore the case of any
	alphabetic characters.
@endnode

@node memccpy

void *memccpy( char *dst, const char *src, const char c, short cnt )

	Copy bytes from <src> to <dst> until either <cnt> bytes have been
	copied, or the character <c> has been copied.  If <c> is found,
	a pointer to the character following <c> in <dst> is returned, or
	NULL is <cnt> reaches 0 before <c> is found.
@endnode

@node memchr

void *memchr( const void *buf, short c, size_t cnt )

	Search the first <cnt> bytes of <buf> for <c>.  Returns a pointer to
	the matching character, or NULL if not found.
@endnode

@node bzero

void *bzero(void *buf, size_t cnt)

	Zero <cnt> characters in <buf>.  Returns <buf>.
@endnode

@node strlen

size_t strlen( const char *string )

	Returns the number of characters in a string, not including the
	terminating '\0'.
@endnode

@node strcpy

char *strcpy(char *dest, const char *source)

	Copies the <source> string to the <dest> including the '\0'.  A
	pointer to the start of <dest> is returned.
@endnode

@node strncpy

char *strncpy(char *dest, const char *source, size_t limit)

	Copies the <source> string to the <dest>.  At most, <limit>
	characters are copied.  If <source> ends before <limit> characters
	have been copied, the '\0' is copied, otherwise <dest> is not
	terminated by the copy.
@endnode

@node strpcpy

char *strpcpy(char *dest, char *start, char *stop)

	Copies characters from <start> up to <stop> into <dest>.  The
	character pointed to by <stop> is not copied, and MUST be in the
	same string as <start>.  The <dest> pointer is returned.
@endnode

@node strdup

char *strdup(const char *string)

	Create a copy of <string> and return a pointer to the copy.
	Storage for the copy is obtained from malloc().
@endnode

@node strset

char *strset(char *string, char c)

	Fill <string> with <c> up the the terminating '\0' of <string>.
@endnode

@node strnset

char *strnset(char *string, char c, int n)

	Fill at most <n> characters of <string> with <c>, up to the the
	terminating '\0' of <string>.
@endnode

@node substr

char *substr(char *dest, char *source, size_t start, size_t end)

	Copy characters from <source> to <dest> starting with character
	<start> and ending with <end>.  A pointer to <dest>, which will
	be '\0' terminated, is returned.
@endnode

@node subnstr

char *subnstr(char *dest, char *source, size_t start, size_t length)

	Copy <length> characters from <source> to <dest> starting with
	character <start>.  A pointer to <dest>, which will be '\0'
	terminated, is returned.
@endnode

@node strcat

char *strcat(char *dest, const char *source)

	Concatenate <source> on the end of <dest>.  The terminator of
	<dest> will be overwritten by the first character of <source>.
	The termintor from <source> will be copied.  A pointer to
	the modified <dest> is returned.
@endnode

@node strncat

char *strncat(char *dest, char *source, size_t limit)

	Concatenate <limit> characters from <source> onto <dest>.  If
	<source> contains less than <limit> characters, the length of
	source is used for <limit>.  The terminating '\0' is always
	added.  A pointer to <dest> is returned.
@endnode

@node strupr

char *strupr(char *string)

	Convert all alphabetic characters in <string> to upper case.
@endnode

@node strlwr

char *strlwr(char *string)

	Convert all alphabetic characters in <string> to lower case.
@endnode

@node strrev

char *strrev(char *string)

	Reverse the order of the characters in <string> in place.
@endnode

@node strcmp

short strcmp(const char *str1, const char *str2)

	Lexicographically compare the two strings.  Return a value
	indicating the relationship between the strings.  Possible
	return values are:
		negative str1 <  str2
		0		 str1 == str2
		positive str1 >  str2
@endnode

@node strncmp

short strncmp( const char *str1, const char *str2, size_t limit )

	Compare strings as with strcmp(), but limit comparison to the
	<limit> characters.
@endnode

@node stricmp

short stricmp(const char *str1, const char *str2)

	Compare strings as with strcmp(), but ignore the case of any
	alphabetic characters.
@endnode

@node strnicmp

short strnicmp( const char *str1, const char *str2, size_t limit )

	Compare strings as with strncmp(), but ignore the case of any
	alphabetic characters.
@endnode

@node strstr

char *strstr ( const char *string, const char *pattern )

	Return a pointer to the first occurance of <pattern> in <string>.
	NULL is returned if <pattern> is not found.
@endnode

@node stristr

char *stristr(char *string, char *pattern)
	Same as strstr(), but ignore the case of any alphabetic characters.
@endnode

@node strchr

char *strchr(char *string, short symbol)

	Return a pointer to the first occurance of <symbol> in <string>.
	NULL is returned if <symbol> is not found.  '\0' is included in
	the search.
@endnode

@node strrchr

char *strrchr(char *string, short symbol)

	Return a pointer to the last occurance of <symbol> in <string>.
	NULL is returned if <symbol> is not found.  '\0' is included in
	the search.
@endnode

@node strpos

ptrdiff_t strpos(char *string, char symbol)

	Return the index of the first occurance of <symbol> in <string>.
	-1 is returned if <symbol> is not found.
@endnode

@node strrpos

ptrdiff_t strrpos(char *string, char symbol)

	Return the index of the last occurance of <symbol> in <string>.
	-1 is returned if <symbol> is notound.
@endnode

@node strspn

size_t strspn ( const char *string, const char *set )

	Return the length of the sub-string of <string> that consists
	entirely of characters found in <set>.  The terminating '\0'
	in <set> is not considered part of the match set.  If the first
	character if <string> is not in <set>, 0 is returned.
@endnode

@node strcspn

size_t strcspn( const char *string, const char *set )

	Return the length of the sub-string of <string> that consists
	entirely of characters not found in <set>.  The terminating '\0'
	in <set> is not considered part of the match set.  If the first
	character if <string> is in <set>, 0 is returned.
@endnode

@node strpbrk

char *strpbrk( const char *string, const char *set )

	Return a pointer to the first occurance in <string> of any
	character in <set>.
@endnode

@node strrpbrk

char *strrpbrk(const char *string, const char *set)

	Return a pointer to the last occurance in <string> of any
	character in <set>.
@endnode

@node strtok

char *strtok( char *string, const char *delim )

	Return a token from <string>.  If <string> is not NULL, it is
	the beginning of a string from which tokens are to be extracted.
	Characters found in <delim> are skipped over to find the start
	of a token, characters are then accumulated until a character in
	<delim> is found, or the terminator of <string> is reached.
	A pointer to the '\0' terminated token is then returned.  Note
	that this function modifies <string> (by inserting '\0's) in
	the process.  Subsequent calls to strtok() may specify NULL as
	the <string> argument, in which case subsequent tokens are
	returned, or NULL if there are no more tokens.
@endnode

@node strtrim

char *strtrim(char *string, char *junk)

	Remove leading and trailing characters found in <junk>
	from <string>.  Return a pointer to the modified <string>.
@endnode

@node stradj

char *stradj(char *string, short dir)

	Adjust <string> by adding space if <dir> is positive, or removing
	space if <dir> is negative.  The magnitude of <dir> is the number
	of character positions to add or remove.  Characters are added or
	removed at the beginning of <string>.  A pointer to the modified
	<string> is returned.
@endnode

@node strrpl

short strrpl(char *string, const char *ptrn, const char *rpl, short n)

	Replace at most <n> occurances of <ptrn> in <string> with <rpl>.
	If <n> is -1, replace all.  Return the number of replacments.
@endnode

@node strirpl

short strirpl(char *string, const char *ptrn, const char *rpl, short n)

	Same as strrpl() except ignore the case of alphabetic characters.
@endnode

@node toupper

short toupper(short c)

	Convert <c> to upper case, if alphabetic.
@endnode

@node tolower

short tolower(short c)

	Convert <c> to lower case, if alphabetic.
@endnode

@node toascii

short toascii(short c)
	Convert <c> to 7-bit ascii, putting it into the range 0x00..0x7F.
@endnode

@node "is...."
@alias isalnum isalpha isascii iscntrl isdigit isgraph
@alias islower isprint ispunct isspace isupper isxdigit isblank

short isalnum(short c)
	Return non-zero if <c> is '0'..'9','A'..'Z','a'..'z'.

short isalpha(short c)
	Return non-zero if <c> is 'A'..'Z','a'..'z'.

short isascii(short c)
	Return non-zero if <c> is 0x00..0x7F.

short iscntrl(short c)
	Return non-zero if <c> is 0x00..0x1F,0x7F.

short isdigit(short c)
	Return non-zero if <c> is '0'..'9'.

short isgraph(short c)
	Return non-zero if <c> is 0x21..0x7E.

short islower(short c)
	Return non-zero if <c> is 'a'..'z'.

short isprint(short c)
	Return non-zero if <c> is 0x20..0x7E.

short ispunct(short c)
	Return non-zero if <c> is not iscntrl(), isalnum() or isspace().

short isspace(short c)
	Return non-zero if <c> is 0x09..0x0D,0x20.

short isupper(short c)
	Return non-zero if <c> is 'A'..'Z'.

short isxdigit(short c)
	Return non-zero if <c> is '0'..'9','A'..'F','a'..'f'.

short isblank (short c)
	Return non_zero if <c> is ' ' or '\t'.
@endnode

@node time

time_t time(time_t *rawtime)

	Get the current system clock date/time value.  Altough the value
	of this function is compatible with the ANSI proposed standard,
	on some systems (notably System V), this function returns the
	number of seconds elapsed since 00:00:00 GMT on Jan 1, 1970.
	This implementation returns an encoded date/time value instead.
	Therefore any programs which depend on this value being a number
	of seconds will not work properly.  However, other functions in
	this section which make use of the raw time value returned by
	time() are implemented to be compatible with this encoding, and
	will work properly.  In addition to returning the raw time value,
	if the <rawtime> pointer is not NULL, the value is stored in
	the time_t variable <rawtime> points to.
@endnode

@node ctime

char *ctime(const time_t *rawtime)

	Convert <rawtime> to a string.  A 26 character fixed field string
	is created from the raw time value.  The following is an example
	of what this string might look like:
		"Wed Jul 08 18:43:07 1987\n\0"
	A 24-hour clock is used, and due to a limitation in the ST system
	clock value, only a resolution of 2 seconds is possible.  A pointer
	to the formatted string, which is held in an internal buffer, is
	returned.
@endnode

@node localtime

struct tm *localtime(const time_t *rawtime)

	Convert <rawtime> to fill time structure fields.  A pointer to an
	internal structure is returned.  Refer to <time.h> for the values
	of the various structure fields.
@endnode

@node gmtime
@alias timezone

long timezone;
struct tm *gmtime(time_t *rawtime)

	Convert <rawtime> to fill struct tm fields.
	The value held in a variable timezone is subtracted
	before converted. timezone holds the difference between
	localtime and Greenwich mean time in seconds.

	A pointer to an internal structure is returned.
	Refer to <time.h> for the values of the various structure fields.
@endnode

@node asctime

char *asctime(const struct tm *time)

	Convert <time> structure value to a string.  The same format, and
	the same internal buffer, as for ctime() is used for this function.
@endnode

@node mktime

time_t mktime(struct tm *time)

	Convert <time> structure value to raw time format.
@endnode

@node stime

void stime(time_t *rawtime)

	Set the system clock to <rawtime>.
	The keyboard clock is also set;
@endnode

@node utime

short utime(char *pathname, time_t *rawtime)

	Set the modification date of <pathname> to <rawtime>.  Returns zero
	for success, or a negative error code.
@endnode

@node clock

clock_t clock(void)

	Returns the current value of the system clock.  The difference
	of two clock() times, divded by CLK_TCK, will give you elapsed
	seconds.
@endnode

@node strftime

size_t strftime( char *s, size_t max_size, const char *format,
                       const struct tm *timeptr );


	Write a maximum of max_size characters to string <s>
	String <format> serves as formatting string like in _printf.
	The following formatting options are recognized:

	%a abbreviated weekday
	%A full weekday
	%b abbreviated name of month
	%B full name of month
	%c date and time
	%d day im month (1-31)
	%H hour (0-23)
	%I hour (0-12)
	%j day im year (1-366)
	%m month (1-12)
	%M minute (00-59)
	%p AM/PM
	%S second (00-59)
	%w weekday (0-6)
	%W week im year (0-52)
	%x local date
	%X local time
	%y year without century (0-99)
	%Y year with century
	%Z name of time xone (z.B. CET)
	%% the '%' character

@endnode

@node difftime

double difftime( time_t time2, time_t time1 );

	Time difference:
	Returns the difference between 2 time
@endnode

@node start_timer

clock_t start_timer(clock_t *t)

	Start a 200Hz timer.  This timer value can later be checked with
	time_since() to determine elapsed time.  These functions provide
	a very low-overhead way of timing events.
@endnode

@node time_since

clock_t time_since(clock_t *t)

	Returns the number of 200Hz ticks since start_timer() was called
	for timer <t>.
@endnode

@node sleep

void sleep(unsigned short dt)

	Suspend operation for <dt> seconds.  This is implemented as a
	start_timer()/time_since() tight loop waiting for the specified
	amount of time to pass.  In a multi-tasking environment, this
	function should be replaced by a call which will de-activate
	this task for a period of time, allowing other tasks to run.
@endnode

@node usleep

void usleep(unsigned short dt)

	Suspend operation for <dt> microseconds.  Works like sleep().
@endnode

@node StdCompare

typedef short StdCompare(const void * item1, const void *item2);

	The type of the compare function used by
	searching and sorting routines.

	Pointers to two items are passed to the function, which must
	return a number representing their relationship as follows:
		negative	item1 <  item2
		0			item1 == item2
		positive	item1 >  item2
@endnode

@node qsort

void qsort (void *base, size_t num, size_t size, StdCompare *cmp)

	Perform a recursive quick-sort on an array starting at <base>
	containing <num> elements of <size> bytes each.  The function
	of type StdCompare pointed to by <cmp> is used to compare elements.
	The qsort() function requires the use of a temporary data area
	that is large enough to hold <size> bytes.  The default space
	provided is 128 bytes large.  If your record size is larger than
	128 bytes, YOU MUST provide an alternative storage area.  The
	global variable "_qbuf" points to the storage qsort() will use.
	Setting "_qbuf" to NULL restores use of the internal buffer.
	This routine is optimized to avoid N*N sort times for ordered data.
	In fact, performance on sorted or reverse-sorted data is actually
	"best case" with this algorithm, rather than "worst case" as with
	most qsort() implementations.
@endnode

@node hsort

void hsort(void *base, size_t num, size_t size, StdCompare *cmp)

	Perform an N*log(N) heap-sort on an array starting at <base>
	containing <num> elements of <size> bytes each.  The function
	of type StdCompare pointed to by <cmp> is used to compare elements.
	The hsort() function requires no extra storage, is not recursive,
	and has an almost constant N*log(N) sort time.  In the average
	case, it is about half as fast as qsort() on random data.  If
	portability is a concern, it should be noted that qsort() is
	almost always available, but hsort() is not.
@endnode

@node bsearch

void *	bsearch( const void *key, const void *base,
          size_t num, size_t size,
          StdCompare *cmp);

	Perform a binary search for <key> on the sorted data at <base>.
	<num>, <size> and <cmp> are like the corresponding parameters
	to qsort().  A pointer to the matching element is returned for
	success, or NULL for failure.  The global variable "_bsearch"
	will contain the index of either the matching element, or the
	index of the element that the <key> value should be inserted
	after.  The use of "_bsearch" is not supported by most
	implementations of bsearch().
@endnode

@node lsearch

void *	lsearch(void *key, void *base,
		  size_t *num, size_t size,
		  StdCompare *cmp)

	Perform a linear search for <key> on the data at <base>. The
	<num>, <size> and <cmp> parameters are like the corresponding
	parameters to qsort().  A pointer to the first matching element
	is returned for success, or NULL for failure.  If <key> is not
	found, it will be added to the end of the array and <num> will
	be incremented.  Note that, unlike bsearch() and qsort(), the
	<num> parameter is a POINTER to a location which holds the
	number of elements to sort.
@endnode

@node lfind

void *	lfind(void *key, void *base,
		  size_t *num, size_t size,
		  StdCompare *cmp)

	Like lsearch(), but do not add elements which are not found.
	Note that <num> is a POINTER, even though it is not modified.
@endnode

@node errno

short errno;

	This variable is set to zero when the program is loaded.  It is
	not zeroed by any library functions, but may be set to a non-zero
	error number by many of them (particularly the standard i/o and
	system service functions).  The meaning of this error number may
	be found in the symbolic #defines in <errno.h>
@endnode

@node perror

void perror(char *msg)
	Write, to stderr, <msg> (if non-null and non-empty), followed by
	": " and a system error messaged derived from the value of errno.
@endnode

@node perrorf

void perrorf(char *fmt, ...)

	Write, to stderr, the name of the program, followed by ": ",
	followed by a message formatted as by printf() from <fmt> and
	the optional arguments, followed by ": " and a system error
	message derived from the value of errno.  This is a non-standard
	extended version of perror().  (cf: printf, perror)
@endnode

@node strerror

char *strerror(short errnum)

	Return the system error message for error <errnum>.  If <errnum>
	is outside the range of valid error numbers, NULL is returned.
@endnode

@node "variable argument lists"
@alias va_list va_start va_arg va_end

	The macros in this section are defined in the <stdarg.h> header file.

typedef char * va_list;

	This is the type for a variable argument list traversal variable.

#define va_start(list, param) ((ap) = (char *)...)

	This macro initializes the va_list variable <list> to begin
	traversing variable argument lists.  <param> is the last parameter
	in the function call before the variable arguments begin.  This
	parameter MUST NOT be a register variable.
	HR: The use of AHCC/PureC specific ... in the macro makes
	the use of <param> obsolete. It is kept for comapatability.

	Note:
	The ... parameter at the end of a parametr list defines a
	AHCC specific local parameter name: '__ELLIPSIS__'.
	This name is refered to by the va_start macro.
	If you use va_start in a function without ellipsis,
	the absence is reported by the  message: 'undefined __ELLIPSIS__'.

MACRO va_arg(list, type)

	This macro retrieves a variable argument of type <type>, updates
	the va_list variable <list>, and returns the value of the retrieved
	argument.  The <type> should not be parenthesised.

MACRO va_end(list)

	This macro must be called after all desired variable arguments have
	been retrieved, to reset the context of the va_list variable <list>.
@endnode

@node getopt

short getopt(short argc, char **argv, char *optstring)

	This function eases the processing of the command line.  Each call
	returns a character from <optstring>, with optarg set to a parameter
	if one is required; or a '?' indicating that an invalid option was
	found; or EOF indicating that all options have been processed.  The
	<argc> and <argv> parameters are (of course) the argc and argv values
	passed to main().  The <opstring> is a string of option characters.
	If an option takes a parameter, it is followed by a ':' in <optstring>,
	and the char *optarg variable (global) will be set to point to the
	parameter string from the command line.  For example, "bno:v" defines
	the valid option characters as 'b', 'n', 'o' and 'v', and 'o' takes
	a parameter.  All options must be preceeded (in the command line) by
	a '-' character.  A single '-' character is taken to indicate stdin
	as a file, and terminates the argument processing.  A "--" string
	indicated the end of options, and is skipped over.  When option
	processing is successfully completed, the global variable optind will
	contain the index into argv[] of the next argument to be processed.
	Subsequent arguments should be processed with a loop like this:
		while(optind < argc)
			process(argv[optind++]);
	If an error occurs during argument process, an error message is
	written to stderr and '?' is returned by getopt().  Your program
	should then give a usage message and abort.  If the global variable
	opterr is set to zero, no error message will be given, but '?' will
	still be returned.  Note that command lines accepted by getopt() are
	quite flexible.  The command lines "-b -v -o filename -- - file",
	"-vbofilename - file",  and "-ofilename -bv - file" all will return
	the 'b', 'v', and 'o' options with the parameter to 'o' set to
	"filename" and leave the arguments "-" and "file2" for further
	processing.  Please examine the sample program "echo.c" for an
	example of getopt() usage.
@endnode

@node rand

short rand(void)

	Return a pseudorandom number in the range 0..32767.  This
	function uses the system random number generator, but grabs
	it's value out of the middle to avoid the exactly 50%
	behavior of the lowest order bit.  Source code is also provided,
	though commented out, showing how to generate your own
	random number sequence if the system random numbers aren't
	sufficient or for porting these routines to another machine.
@endnode

@node srand

void srand(unsigned short seed)

	Seed the random number generator.
@endnode

@node swab

void swab(char *src, char *dst, size_t n)

	Swap adjacent bytes while copying <n> bytes from <src> to <dst>.
	This allows bulk translation to/from Intel byte ordering.  Please
	note the backward order of the <src> and <dst> parameters.  Don't
	blame me... this is how Microsoft specifies it.
@endnode

@node swap
@alias max min abs

short abs(short  v);
long labs(long   v);

	Return the absolute value of <x>.

MACRO max(x,y)
	Return the larger of <x> and <y>.  This macro evaluates the
	larger argument twice and the smaller argument once.

MACRO min(x,y)
	Return the smaller of <x> and <y>.  This macro evaluates the
	smaller argument twice and the larger argument once.

MACRO swap(a,b)
	Exchange <a> and <b> by chained XORs.  The macro evaluates
	each argument several times.
@endnode

@node assert

MACRO assert(condition)

	If <condition> is not true at run-time, this macro causes an
	assert failure message to be written to stderr, displaying the
	line number and source file name, and aborts the program.  If
	the symbol NDEBUG is #defined (usually with a -D option to cc),
	all assert() calls are disabled.
@endnode

@node "revision record"

This is an attempt to record changes to dLibs from past versions.
I make no promises about it's completeness.

	v2.0
	v1.2
	v1.1
	v1.0
@endnode

@node "v2.0"
	May 2008

	This release belongs to the AHCC C89 compiler for ST/TT family.
	The main effort of this release comprises work on the strong
	typing offered by ANSI C 1989.

	This release is in no way compatible to the previous releases
	and can not be used by Sozobon or Alcyon.

	For this reason the name of the library is changed to "AHCCLIB"

	AHCCLIB is mainly provided to be a simple and uncluttered
	library for beginners.

	AHCC produces object files that are binary compatible to those
	produced by Pure C.
	As a consequence, this library can be used as a replacement
	for the proprietary standard libraries of the Pure C distribution.

	Henk Robbers.
@endnode

@node "v1.2"
	October 1988.

	This release corresponds to the release of the Sozobon C
	compiler for the ST, and includes quite a bit of general code
	cleanup as dictated by the stricter (and more correct)
	requirements of the Sozobon compiler.  This code IS still
	compatible with Alcyon C, but now it is also compatible
	with Sozobon C.

	This release fixes many bugs, most minor, some major.  Some
	of the functions that were improved are:  mktime(), stime(),
	strtrim(), ctlcnv(), realloc(), fullpath(), findfile(),
	lsearch(), tell(), putenv(), exec(), _initargs(), main(),
	qsort(), memccpy() and swab().

	The header files were somewhat restuctrured, and <stddef.h> and
	<stdarg.h> were added, for more ANSI X3J11 compatibility.  Also
	<sys\minimum.h> was added as a non-portable hack to make very
	small programs when no standard i/o or argv/argc is needed.

	The blkXXX() functions have now all been renamed to their X3J11
	memXXX() names and some were recoded in assembly language.

	The stream i/o functions were overhauled, resulting in changes
	to the FILE structure and nearly all associated functions.  The
	new functions handle interactive i/o with the console much more
	nicely, emulating (partly) a tty driver which gives essentially
	line-oriented operation for standard input on a character device.
	You can now backspace to edit, ^U to retype a line, and ^C to
	interrupt a program (sorry, only during input) and none of these
	characters will appear in the input read by the program.  Since
	there is never agreement about how such a driver should work, all
	the code is encapsulated in the _tttty() function, which is in
	a separate object module.

	The pfindfile() function now has a path parameter, but the PATH
	environment variable will still be used if NULL is specified.
	The wildcard() function has also changed slightly in that is
	no longer expands the filenames with fullpath().

	Some new functions in this release are: mktime(), usleep(),
	alloca(), _splitpath(), _makepath(), bzero(), memcpy(),
	strpcpy(), strtol(), strtoul(), perror(), perrorf(), strerror(),
	fgetpos(), fsetpos(), vprintf(), vfprintf(), vsprintf() and getopt().
@endnode

@node "v1.1"

	December 1987.

	Process control functions, spawn(), spawne(), spawnp() and
	spawnpe() removed.  New functions forkl(), forklp(), forkle(),
	forklpe(), forkv(), forkvp(), forkve(), forkvpe() and wait()
	now handle creation of child processes.

	XARG format extended argument passing is supported by all the
	process control functions and _initargs().

	Many functions which were previously #defined in <stdio.h> to
	gemdos() calls are now real functions.  This allows you to pass
	the address of these functions in function pointer.

	Added brk() and sbrk() functions for managing the heap.  This
	is not typically a good way to allocate memory.  The normal
	malloc() functions are much better in most cases.

	printf() and scanf() now process capital format characters.
	This feature is provided to support old programs which use
	capital characters to indicate long values.  It is NOT*
	recommended for use in current code and is not supported
	by the ANSI proposed standard.  The scanf() function has
	been upgraded to support hyphenated ranges and returns what
	we think are correct values for various end-cases like end-
	of-input and early format conflicts.

	findfile() and pfindfile() have been improved and fopenp()
	had been added to support use of the PATH.  The extension
	list given for findfile() and pfindfile() has been changed
	slightly.  You must now include the '.' portion of the
	extension.  This is to allow searching for the empty extension.

	The header files have been changed and extended to conform
	more closely to ANSI and Unix System V.  As a result, some
	of the structures and actual values for certain flags have
	changed.  The stat structure and related functions like
	access(), stat(), creat(), open(), etc. have been significantly
	changed in implementation.  The open() function supports
	many more mode flags like O_CREAT, O_APPEND, O_TRUNC and O_EXCL.

	A few new functions like swab(), tmpnam(), tempnam(), getcwd()
	and wildcard() have been added.  Only wildcard() is non-standard,
	but I think it's useful to have around.
@endnode

@node "v1.0"

	Originnnal release.  October 1987.
@endnode

@node Editor

	Welcome to the AHCC editor pages.
	AHCC uses a unusual editor, but not difficult to grasp.

	It must be extremely user friendly, because I use it myself, and I can
	be a very unfriendly user. ;-)

	All dialogues are in a single scrollable window called the KIT

	Double or right click ALWAYS results in a selection.

	A quick story on the 'find multiple'
	                     'find in project' features: browse
	It is very similar to the Pure C facility.

	A quick story on the 'compare files'  facility: filecompare
	A quick story on the 'compare folder' facility: foldercompare

	A consise summary of Cursor movement.
	                  of Mouse buttons.
	                  of Undo capabilities.
@endnode

@node "carriage returns"

As we all know UNIX people hate carriage returns.
I don't know if they are right or wrong, perhaps they just
hate the noise.

Anyhow, AHCC again makes your life easy.

The criterium of having carriage return is the first line.
If the first line has carriage return and you save,
   all lines will get carriage return + linefeed.
If the first line has linefeed only and you save,
   all lines will have linefeed only.

You can see the state in the window menu edit-->crlf;
the checked status indicates how the file will be saved.
If you want to change the crlf state, click the menu.

For good reasons a change in current crlf mode is not considered a
change in the file content.

So if you only want to remove (or insert) carriage return,
      you must use Save as...
@endnode

@node "Undo capabilities"

Every thing that is changed between mouse clicks can be undone.
The undo button is a flipflop. Press again will REDO.
This is the default action.

There is a menu option that changes this behaviour.

Main menu --> Options --> At rtn reset_undo.
If this is checked, everything between physical pressing the return or enter
key, can be undone.

Both options allow for a complete "find/replace all" to be undone.
@endnode

@node "Cursor movement"

A quick summary of the keyboard&mouse usage of AHCC.PRG and AHCC.PRG.
In standard menu shortcut format as far as possible.
Only the combinations not in the menu ar stated here.

Cursor movement:
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
	If a selection is on, it is deselected.

		no selection						selection ON
		ÿÿÿÿÿÿÿÿÿÿÿÿ						ÿÿÿÿÿÿÿÿÿÿÿÿ
		1 pos left							on start of sel.
		1 pos right							after end of sel.
		same pos prev line					above start of sel.
		same pos next line					below end of sel.
		to start of line...................	left of start of sel.
		to end of line.....................	right of end of sel.
		1 page up
		1 page down

^		to start of next word			    select next disjunct occurrence of
                                            the current selection type
^		to start of prev word			    select previous disjunct occurrence
                                            of the current selection type

^		as 								as 
^		as 								as 
^		as ^								as ^ but go deeper
^		as ^								as ^ but go deeper
DEL		delete ch under the cursor			delete whole sel.
^DEL	delete part of line
				under and right of cursor		as DEL
^DEL	delete part of line left of  cursor		as DEL
HOME	cursor to first line, first pos.
HOME	cursor to last line, last pos.
BS		delete ch left of cursor.				as DEL

control + shift + cursor arrows:  as the window's single arrows.

Miscalaneous:
ÿÿÿÿÿÿÿÿÿÿÿÿÿ
^+		actuate fuller of top window (if there)
^-		idem
@endnode

@node "Mouse buttons"

Mouse buttons:
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
!!-->  right click:		allways same as double clicking left button;

left click:			cursor on ch under the mouse or as close as possible to
					the highest real character left to the click.
double click:		make selection. see 1)
If selecting a left brace all between and including balancing braces is
	selected.
If selecting a right brace only in between balancing braces is selected.

clicking and left dragging as in all editors: select.
	While dragging, the window contents are scrolled whenever appropriate.

right dragging:		continuous selection.

click as in all editors: make or resize selection.

^click: Make line top of window.
^double click: As above + select.
double click: select whole line.
click: an alternative for left click and double click: select.
@endnode

@node  selection

^ and ^ are extremely useful for going through all the comments or
all the #if*  #endif pairs or all the functions or calls of a source
file.

1)  there are some selection types defined:

selected by double click or right button or click.
	braces:		{ } [ ] ( ) /* */ ' ' " ",
	word:		letters and digits but starting with a letter;
				words can be defined as braces via the "Define braces" menu.

	white space:	vz
	lexical other than above and its surrounding space: vz

	html braces. You know them: <tag ...> ... </tag>
	             right click on the leftmost < or the rightmost >

no type, anything selected by shift click, drag, find or replace.

Note: '' and "" cause no directional problem if there is only 1 pair on a line.

2)  with ^ next is selected including braces,
	with ^ prev is selected excluding braces.
@endnode

@node browsing
@alias browse

	Hits are listed in the journal. Select the word 'Found' with the mouse and
	the file containing the occurrence is opened. The line of the occurence is
	shown selected. If a full path is shown, you can also select the drive
	letter to open the file.

	First you have to define a path. This path is in the KIT window below the
	'Multiple' button in the 'Find' group.
	If the KIT isnt already open, open it by choosing Options->find miltiple or
	pressing alt + g.

	When you hate typing, or have problems remembering trivialities like names,
	as I do, right click on the field. This opens the fileselector.

	Who needs a fileselector when you're running a multitasking OS and a desktop
	that supports drag&drop?
	Just drag a directory name into the field.
	(The Acorn Risc OS doesnt have a file selector at all)

	Don't forget to add a filter to the path.
	The simple filter options are a quick borrow from XaAES:

	All pattern matching is case insensitive.

	Valid patterns are:
		?      Any single char
		*      A string of any char or empty
		!X     Any char except for X
		[abcd] One of (any one of a,b,c or d)
	Examples:
		*       All files in dir
		*.*     All files with a dot !!!
		a*      All files begining with 'a'
		*.c*    All files with a extension starting with c
		*.o     All '.o' files
		*.!o    All files not ending in '.o'
		!z*.?   All files not starting with 'z', and having a single character
		                                                             extension
		*.[co]  All '.o' and '.c' files
		*.[CH]* All files with an extension starting with C or H

	When a path is established there are several ways to start a search.
	Via the kit: type a find string and click FIND.
	Check if 'Multiple' is selected.
	In stead of typing you can use control + I in a text window. 1 for selecting
	if nothing is selected, a further one to copy the selection in one of the
	Find strings (this starts a top window search as well).
	The quickest way is: select the find string in a text window and press
	control + shift + I. In this case the whole KIT is bypassed. Very useful
	when you don't have a big screen.

	'deep' button:       go recursive through all subdirectories.
	'1 per file' button: stop search in a file on the first occurrence.

	When the find string is empty, AHCC displays a nice scheme of all the
	files in the path. The button 'verbose' is used.
	verbose selected: display full path's ready for cicking on the drive letter.
	        unselected: display only plain names nicely indented.

	AHCC uses the 'Knuth, Morris, Pratt' method for searching.


@endnode

@node filecompare

Open the files you want to compare.
Use Alt + T to tile the windows vertically.

Place the cursor in each file at the point you want to start comparing.
Press Cntrl + 2  (2 from the upper row of the keyboard).

Unequal lines are made visible and will be selected as 'whole line'

This selection type makes it possible to use Cntrl + cursor left or
cursor right to move up or down the selection a line.

This is the way you cater for deleted or inserted lines in the files.

Once you have reached synchrony again, press Cntrl + 2 again to compare
further.

Note: This method looks a little bit tedious. You may be right.
It is not intended for heavy use. It was enough for me to help me get
an impression of changes between to versions of a project.

It was also very helpful to find out if a mistake I made was already
there in previous versions.

And!!! You are in a editor. You don't need to switch programs if you
want to correct something.

@endnode

@node Disclaimer

	Command line programs.
	=====================

	I have not used a commandline since 1983 and I have no intention
	to use one in the future.
	I have no, nada, nope affinity with UNIX commandline usage.
	I think typing commands is not a proper way of using modern
	computers.

	The commandline versions of the compiler and linker of course
	use exactly the same compiler and linker as the GEM versions,
	but I never have tried them out.

	The GEM version uses a interface routine that exactly mimics
	a commandline though. The routine is derived from a startup
	code out of the real world.

	There might be problems with relative paths in the commandline
	versions. The GEM version ALWAYS passes absolute paths.

@endnode

@node "Shell/Compiler/Assembler/Linker"

	The programs AHCC_P.TTP and AHCCST_P.TTP accept a project
	file as input parameter plus a few options of which some
	cannot be put in the project file.

	Usage:
	AHCC(ST)_P [options] filename.prj

	options:
		-v    verbosity
		-x    make all
		-c    cache headers
		-h    project help database
		-j    auto depend
		-g    warn gotos
		-i    nested projects inherit options
		-n    'nm' type symbol list
		-p    load map

	It is often possible to install AHCC(ST)_P with these
	options preset in a desktop program.

	If you drop a project file on AHCC(ST)_P, the project will be made.
	If you press ALT when dropping, a 'Make All' will be performed.

@endnode

@node "Compiler/Assembler"
@subject "A Home Cooked C compiler"


		                 Welcome to AHCC
		             A Home Cooked C compiler

		              Greetings, Henk Robbers.
		                   January 2011

                       Compiler description
                          Compiler usage

@endnode

@node "Compiler description"

	AHCC is a full ANSI C89 compiler based on the original
	Sozobon v1.2 sources. But that is very long ago.
	Very few lines will be the same, but the overall architecture
	has been unchanged because it was good.
	People acquainted with the Sozobon sources will recognize
	many parts.

	AHCC comes in a variety of incarnations of which the GEM
	integrated version is the most well tested and most important.

	AHCC is binary compatable to Pure C so it is possible
	to freely mix AHCC produced and Pure C produced
	objects and libraries.

	AHCC has a builtin assembler.
	It is allowed to use C preprocessor commands in a assembler file.

	As long as AHCC is beta, it will be compiled by Pure C
	to avoid embarrassing confusions and strange entanglements.

	Nevertheless I have hosted AHCC in 3 stages successfully:

		Pure C makes AHCC/1          AHCC/1 compiles CALC ok.
		 AHCC/1 makes AHCC/2          AHCC/2 compiles CALC ok.
		  AHCC/2 makes AHCC/3          AHCC/3 compiles CALC ok.

		In each appropriate stage I checked equality of the binaries.

	This distibution also contains the programs CALC, AHCX and TT-Digger.
	These programs are compiled by AHCC and seem to work satisfactorily.


@endnode

@node "Compiler usage"
@alias compiler_options assembler_options

	Invocation:

		AHCC.TTP [options] inputfilename ...

	Commandline parameters for AHCC:

	AHCC specific options:
		-*b    no branch reversals
		-*c    cache headers
		-*e    don't include ahcc_rt.h  (runtime AHCC specific definitions)
		-*g    warn goto's
		-*h    project help
		-*i    default int is 32 bits
		-*j    auto dependencies
		-*p    suppress peephole optimizations
		-*s    ptr scale 32 bits (int*int=long)
		-*u    Default assembly for superviser mode
		-6     Coldfire (type double is 64 bits)

		The '*' associates left, so the -* options can be
		combined in a single block like this: -*cghjs

	Pure C compatible options
		implemented by AHCC:
			-c     allow nested comments
			-dX..X define macro; optional followed by =value
			-eN    maximum no of erors
			-fN    maximum no of warnings
			-h     cdecl calling
			-iX..X include directory
			-k     default char is unsigned
			-l     maximum identifier length
			       default is 32. Maximum is 256. This is also the
			       maximum of ALL tokens.
			-oX..X Output file name
			-uX..X undefine macro
			-v     verbosity
			-x     prepend underline to identifiers
			-2     generate for MC68020
			-7     generate for Coldfire V4e
			-8     generate directly for MC68881/2

		accepted by AHCC but not implemented:
			-a     strict ANSI
			-b     DRI object output
			-g     size optimization
			-j     no jump optimization
			-m     merge identical strings
			-p     use absolute calls		(AHCC always)
			-q     Pascal calling
			-s     force frame pointers		(AHCC always)
			-t     stack checking
			-w...  suppress warning ...
			-y     add debug info
			-z     register reloading

@endnode

@node Linker
@subject "A Home Cooked Linker"


		                 Welcome to AHCL
		  A Home Cooked Linker for Pure C, DRI, GFA objects

		              Greetings, Henk Robbers.
		                    july 2006

	                       Description:

	AHCL is the stand alone linker that is otherwise built into AHCC.

	The need for writing AHCL arose when I wanted to test AHCC
	without having to recreate a whole bunch of libraries.

	AHCL and AHCC are currently written using Pure C.
	So producing Pure C compatible objects was a obvious choice.

	It also made it very easy to test AHCC output by comparing
	(and combining) with Pure C compiled objects.

	AHCL.TTP is the genuine commandline program.

	AHCL_PRJ.TTP only accepts a single project filename as parameter.
		(I hate commandlines so much)

	This project file is exactly the same as those used by Pure C
	Such files generally have the .PRJ extension.

	In single TOS, just drop the project file on AHCL_PRJ.TTP
	and the project will be linked.

	                      Linker usage
                          Pure C format
	                      Acknoledgment

@endnode

@node "Linker usage"
@alias linker_options

	Invocation:

		AHCL.TTP [options] inputfilename ...

	Commandline parameters for AHCL:

    -v    Verbose
    -j    Collect (make new Pure C format object)
    -n    Write 'nm' type symbol list to [-o].sym
    -p    Write load map to [-o].map
    -o... Output file name
    -c... Name of text file holding list of input filenames

    Options for executable output:
    -sN   Stack size, where N is a number less than 0xffffff
    -g    Add symbol table with global symbols
    -l    Add local  symbols additional to -g
       Set load flags:
    -m    Mallocs for TT ram
    -f    Fast load
    -r    Load in TT ram

    Followed by:
    list of input filenames additional to -c


A example .PRJ file for AHCC_P.TTP

menu_1.ttp
.L [-vpg]		; linker options (same as commandline version)
=
menu_1.o
gfa3blib.lib
@endnode

@node "Pure C format"
@alias "Object format"

	This description is the result of analysis using TT-Digger.
	It is not something published by any firm or organization involved
	in the release of Pure C.

	There is no difference in format between object files
	and libraries. The only difference is the extension.
	The library extension causes AHCC to look in certain standard
	library directories first.

	The format is described hereafter in an ad hoc dynamic Cish
	language:

	0)	(unsigned char) enum fixup_types
		{
			FIX_0,
			FIX_end,
			FIX_step,
			FIX_text,
			FIX_data,
			FIX_bss,
			FIX_offset,

			FIX_global_area,
			FIX_global_entry,
			FIX_local_area,
			FIX_local_entry,

			FIX_long_abs,
			FIX_word_abs,
			FIX_long_pcrel,
			FIX_word_pcrel
		};

		struct
		{
	1)		struct
			{
				long magic;
				     image_size,
				     fixup_size,
				     string_size,
				     res0,
				     d_dbg,		/* apparently disp to debug info
				                   relative to start of image */
				     res2,
				     unknown;
			} header;

	2)		short image_section[ header.image_size/sizeof(short) ];

	3)		struct fixup
			{
				unsigned char type,		/* enum fixup_types */
				              step;
				signed short string_number;
			} fixup_section[ header.fixup_size/sizeof(struct fixup) ];

	4)		union string_section
			{
				char all_strings[ header.string_size ];
	5)			struct one_string
				{
					unsigned char size;
					char n[ struct one_string.size ];
				} string[ ... as often as completely fills string_section ];
			};
		} object_file;


	Comments:
	=========

	0:
		The various fixup types in 'struct fixup.type'.

			FIX_step:
				Defines a surplus step value in multiples of 256.

			FIX_text:
				Introduction of TEXT areas.
			FIX_data:
				Introduction of DATA areas.
			FIX_bss:
				Introduction of BSS areas.
			FIX_offset:
				Introduction of OFFSET's.
			FIX_end:
				The last fixup.

			FIX_global_area:
				start of a globally linkable area.
			FIX_global_entry:
				globally addressable entry within an area.
			FIX_local_area:
				start of a linkable area local to the objectfile.
			FIX_local_entry:
				Entry within an area that is not visible outside
				the object file.

			Below are the fixups that really fix up something. :-)
			FIX_long_abs:
				Fix up a long operand with the start address of
				the addressed area.
			FIX_word_abs:
				Fix up a short operand with the start address of
				the addressed area.
			FIX_long_pcrel:
				Fix up a long operand with the start address of
				the addressed area and make it relative to the
				program counter.
			FIX_word_pcrel:
				Fix up a short operand with the start address of
				the addressed area and make it relative to the
				program counter.


	1:	The object file header:
			magic = 0x4EFA001C
				looks like a 'jmp 28(PC)'.
				Right over the header to the image.

	2:  Image section: content of all initialized areas: TEXT and DATA.

	3:	Fixup section: all the 'struct fixup' records.
		Description of fixup record and its usage:
			type:
				fixup type.
			step:
				Amount of bytes to be added to the current position
				counter for obtaining the position to which the fixup
				applies.
			string_number:
				Number of the string in the string section.

				Fixup types
				  FIX_text, FIX_data, FIX_bss, FIX_offset and FIX_end
				  all have their string_number set to -1.

		Special fixup type FIX_step:
			This fixup catenates step and string_number fields to a
			24 bit integral field. The field defines a surplus step
			value as a multiple of 256 bytes. It allows area sizes
			and distances within areas to be up to the current 32 bit
			maximum value.

	4:	String section: all the names within the object.

			The string number is really the number of the string,
		    *NOT* a offset into the section.
		    So you have to build a pointer array of the strings
		    by yourself.
		    The string number then is the index into this array.

	5:	The format of a single string in the string section.
			      first byte:  length of the string in bytes.
			                   Can be zero, denoting a empty string.
			subsequent bytes:  value of the string.
			                   Can be empty.

			An empty string still has a number!
			Empty strings make it possible to have anonymous linkable
			references. Anonymous references are distinguished from
			each other by their number.
			The string number is thus used to distinguish from each other
			local names in/of different areas.

	Summary:	(very short)
		Fixup records point to a string by number.
		The string number points back to a entry fixup record in the
		image section having the same value in its string_number field.
		It is imparative that all entries have a unique string_number.
		If such a entry fixup is absent, the string identifies the
		name of a external reference.

@endnode

@node Acknoledgment

Thanks to Lonny Pursell and Ingo Schmidt
for advices on GFA objects.

Lonny Pursell for his excellent GBE (Gfa Basic editor)
@endnode

@node GFA

	The famous basic interpreter and compiler that is
	very popular with Atari ST users.

	The format produced by the GFA compiler is slightly different
	from the widely used DRI format.

	(desriptiom later)
@endnode

@pnode "Pure C"
Discontinued fast C compiler for Atari ST
Copyright 1991 Pure Software GmbH
Copyright 1988/1990 Borland International Inc./
    Borland Germany GmbH
All rights reserved.
@endnode

@pnode "Henk Robbers"
Henk Robbers.
te Amsterdam

mailto:h.robbers@chello.nl
http://members.ams.chello.nl/h.robbers

tlf: 020 4182901
@endnode
