/******************************************************************************/
/* DOSCALLS.ASM, DOSCALLS.H						      */
/* Written by John W. Ratcliff, December 1991.				      */
/******************************************************************************/
/* DOSCALLS is a linkable object module that provides many of the functions   */
/* available through the standard C libraries.	There are number of reasons to*/
/* use DOSCALLS.OBJ rather than C library function calls.		      */
/*									      */
/*	 1. Portability: These functions work the same regardless of what     */
/*			 C compiler you are using.			      */
/*									      */
/*	 2. Size:	 These functions are extremely small compared to      */
/*			 equivalent C library functions. The C library	      */
/*			 functions are general while the DOSCALLS	      */
/*			 function calls are very specific.  Accessing C       */
/*			 library function calls causes large amounts of       */
/*			 library code to get drug in that you probably	      */
/*			 don't want.                                          */
/*									      */
/*	 3. TSR capability: If you program TSR's you will find that           */
/*			 dragging in C library functions will kill you	      */
/*			 for a whole number of reasons.  Using		      */
/*			 DOSCALLS.OBJ you have no DGROUP dependencies and     */
/*			 you can easily write single segment TSR's and        */
/*			 even write both COM modules and DOS device	      */
/*			 drivers.					      */
/*									      */
/*	 4. Assembly language:	If you don't program in C and need basic      */
/*			 DOS support functions, you can just use DOSCALLS     */
/*			 for this purpose.				      */
/*									      */
/*	 5. Simplicity:  DOSCALLS don't ignore the fact that you are programming*/
/*			 on an MS-DOS machine.	They in fact simply provide   */
/*			 C callable access to INT 21h calls.  Because of this */
/*			 they are all easy to use.			      */
/******************************************************************************/
#define NEW_FILE 0 // MFOPEN file types, 0 open as a new file for read/write
#define OLD_FILE 1 // file type 1, open as an old file for read/write access
#define FILE_NOT_FOUND 0 // file handle of zero, is file not found.

int  far mfopen(char far *filename,long int far *size,int type);
int  far mpfopen(char far *filename,long int far *size,int type);
/******************************************************************************/
/* mfopen -> Does a DOS file open.  Returns a DOS file handle, which is simply*/
/*	     an integer.  You can open a file as a new file or as an old file */
/*	     by specifying the file type.  A return code of zero means that   */
/*	     the file couldn't be opened.  You pass the address of a long int */
/*	     who's contents will be filled with the total length of the file. */
/*	     If you pass a null address then the size will not be reported.   */
/*	     After a file open, the file pointer will always be sitting at    */
/*	     byte position zero.					      */
/******************************************************************************/

int  far mfclose(int fhand);
int  far mpfclose(int fhand);
/******************************************************************************/
/* mfclose -> Close a file that was opened with mfopen. 		      */
/******************************************************************************/

long int  far mfpos(int fhand);
/******************************************************************************/
/* mfpos -> report current file position of this file.			      */
/******************************************************************************/

long int far mfseek(int fhand,long int fpos);
/******************************************************************************/
/* mfseek -> seek file to this position passed.  Return code is actual file   */
/*	     seek position achieved. (In case request went past end of file.) */
/******************************************************************************/

int  far mfread(void far *address,long int size,int fhand);
/******************************************************************************/
/* mfread -> read from file, into address, for length of size, from fhand.    */
/*	     return code of 1, successful file read, return code of zero,     */
/*	     file read failed.						      */
/******************************************************************************/

int  far mfwrite(void far *address,long int size,int fhand);
/******************************************************************************/
/* mfwrite -> write data to file, from address, for length of size, to fhand. */
/*	      return code of 1, success, return code of zero, write failed.   */
/******************************************************************************/

char far * far fload(char far *name,long int far *siz);
char far * far fpload(char far *name,long int far *siz);
/******************************************************************************/
/* fload -> allocate memory, and read entire file in.  Uses name as filename  */
/*	    and returns the length read in, in siz.  If siz is null then siz  */
/*	    not set.  If return code is NULL then was unable to load file.    */
/*	    Either the file wasn't found, or there wasn't enough memory to    */
/*	    read it in.  Otherwise return code is the address of the file     */
/*	    read in at.  Uses MEMALLOC (provided by application program) to   */
/*	    allocate memory, and caller must do MEMFREE when finished with    */
/*	    this memory.						      */
/******************************************************************************/

char far * far floadpara(char far *name,long int far *siz,int far *segment);
/******************************************************************************/
/* floadpara -> a special version of fload, that reads in the file into       */
/*		allocated memory, but forces it at a paragraph boundary.      */
/*		The return code is still the address of allocated memory for  */
/*		the file read, but the variable segment is loaded with the    */
/*		actual segment boundary that the file was read in at.  This   */
/*		is used by digplay's LoadDriver call, which loads a binary    */
/*		image into memory, that must fall on a paragraph boundary.    */
/******************************************************************************/

int  far keystat(void);
/******************************************************************************/
/* keystat-> report DOS key status.  Zero, no key pending, 1, key pending.    */
/******************************************************************************/

// Extended key codes returned by getkey
#define TAB 9
#define ENTER 13
#define ESCAPE 27
#define SPACE 32
#define BACKSPACE 8

#define STAB 271
#define LEFT 331
#define RIGHT 333
#define UP 328
#define DOWN 336

#define HOME 71+256
#define PGUP 73+256
#define END 79+256
#define PGDN 81+256

#define F1 315
#define F2 316
#define F3 317
#define F4 318
#define F5 319
#define F6 320
#define F7 321
#define F8 322
#define F9 323
#define F10 324
#define F11 325


int  far getkey(void);
/******************************************************************************/
/* getkey -> DOS getkey function. Returns keypress pending.  Automatically    */
/*	     handles extended key codes, by adding 256 to them. 	      */
/******************************************************************************/

void far farcop(char far *dest,char far *source);
/******************************************************************************/
/* farcop -> string copy routine, but uses far pointers.		      */
/******************************************************************************/

void far farcat(char far *dest,char far *source);
/******************************************************************************/
/* farcat -> string concatenate routine, but with far pointers. 	      */
/******************************************************************************/

int far farlen(char far *string); // Return length of string.

int far farcompare(char far *source,char far *dest); // String compare.

void far ucase(char far *string); // Upper case a string.

char far * far fmalloc(long int size);
/******************************************************************************/
/* fmalloc -> DOS memory allocation.  Works fine by itself but conflicts with */
/*	      C compiler's far memory allocation.  DOS likes memory to be     */
/*	      de-allocated in the order that it was originally allocated, in  */
/*	      order for it to cleanly defragment memory pools.	These function*/
/*	      calls are valid if you are writing a TSR or must do DOS memory  */
/*	      allocation exclusively.					      */
/******************************************************************************/

void far ffree(char far *tmp);
/******************************************************************************/
/* ffree -> free dos allocated memory.					      */
/******************************************************************************/

void far writeln(char far *string);
/******************************************************************************/
/* writeln -> echo a string to the console.  Avoids dragging all of the printf*/
/*	      library code, which is HUGE!				      */
/******************************************************************************/

void far * far GetTimerInterruptVector(void);
/******************************************************************************/
/* GetTimerInterruptVector -> reports the current far address of the timer    */
/*	    interrupt vector.  This function call is used to report the       */
/*	    original address of the timer interrupt vector, should your       */
/*	    application choose to change it.  These services are provided     */
/*	    because some of the sound drivers use the Timer interrupt to play */
/*	    back sound.  (Use AudioCapabilities to find out which ones.)  Even*/
/*	    though the sound drivers all still service the original 18.2 timer*/
/*	    interrupt, some application software may have already modified    */
/*	    the timer for it's own purposes.  In these cases you will         */
/*	    want to disable that timer while digitized sound playback is      */
/*	    occuring, and then put it back when sound playback has completed. */
/*	    If your application doesn't reprogram the timer interrupt vector  */
/*	    rate, you needn't worry about any of this stuff.                  */
/******************************************************************************/

void far SetTimerInterruptVector(void far *address,unsigned int divisor);
/******************************************************************************/
/* SetTimerInterruptVector -> set the timer interupt vector to a new address  */
/*	     and specify a new interupt rate.				      */
/******************************************************************************/

int far mdelete(char far *fname); // Delete a file by filename.
int far ifexists(char far *fname);	// Does this file exist? 1 yes, 0 no.


#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define GRAY 7
#define GREY 7
#define DARK_GREY 8
#define DARK_GRAY 8
#define LIGHT_BLUE 9
#define LIGHT_GREEN 10
#define LIGHT_CYAN 11
#define LIGHT_RED 12
#define LIGHT_MAGENTA 13
#define YELLOW 14
#define WHITE 15

#define BEHIND << 4 |

void far tprint(int x,int y,int len,char far *string,int color);
void far tcolor(int x,int y,int len,int color);  // Change text background color.
void far TextCursor(int xloc,int yloc);

void far farmov(char far *dest,char far *source,int length);

int  far CurrentPath(char far *dest); // Load string with full current path
				      // including drive letter.
int  far LoadPath(char far *dest); // Find drive and directory we loaded from.
	// Fully qualified, includes drive letter.

// Find a file by a spec.  Spec could be "*.COM" or some other specified.
// If the address in spec is non-zero, it is assumed to be pointing at a
// valid ascii string to perform a file match against.	It will do a find
// first.  If it is non-zero then it does a find next, which is a sequential
// search on the criterion specified.  The file name found is copied into
// the far pointer dest.  A return code of 1 means file found, 0 no files
// left that match.
int  far FindFile(char far *spec,char far *dest);

// Change directory to this drive and path name.  Accepts drive letter.
// Return code of 1, Success, 0 fail.
int  far ChangeDirectory(char far *dirname);

int far mrename(char far *old,char far *new);

void far MemStosb(char far *dest,int value,int length);

int far scale(int a,int b,int c);

void far * far MakeFP(int offset,int segment);
int far MakeSeg(char far *address);

void far DBUG(long int value,int xloc,int yloc);
