/*
 *   dos.h -- extra-ANSI 
 *
 *   DOS-related functions and services.
 *
 *           Copyright (c) 1990-1992, MetaWare Incorporated
 */

#ifndef _DOS_H
#define _DOS_H
#pragma push_align_members(64);

#ifdef __CPLUSPLUS__
extern "C" {
#endif

#ifndef _CRTIMP
    #if _MSNT && _DLL
	#define _CRTIMP __declspec(dllimport)
    #else
	#define _CRTIMP
    #endif
#endif


#define _A_NORMAL 	0
#define _A_RDONLY 	1
#define _A_HIDDEN 	2
#define _A_SYSTEM 	4
#define _A_VOLID 	8
#define _A_SUBDIR 	16
#define _A_ARCH 	32

#define _FP_SEG(farptr) (*(unsigned short *)((unsigned *)&(farptr) + 1))
#define _FP_OFF(farptr) (*((unsigned *)&(farptr)))

extern unsigned _dos_close(int __handle);
extern unsigned _dos_creat(const char * __path,unsigned __attribute,
	int * __handle);
extern unsigned _dos_creatnew(const char * __path,unsigned __attribute,
	int *__handle);
extern void _dos_getdrive(unsigned * __drive);
#if _MSNT
    #ifndef _UNICHAR_DEFINED
        typedef unsigned short _unichar;
        #define _UNICHAR _unichar
        #define _UNICHAR_DEFINED
    #endif

    extern unsigned _udos_getfileattr(const _unichar * __path,
        unsigned * __attributes);
#endif
extern unsigned _dos_getfileattr(const char * __path,unsigned * __attributes);
extern unsigned _dos_getftime(int __handle,unsigned * __date,unsigned * __time);
extern unsigned _dos_open(const char * __path,unsigned __mode,int * __handle);
extern void _dos_setdrive(unsigned __newdrive,unsigned * __drives);
extern unsigned _dos_setfileattr(const char * __path,unsigned __attributes);
extern unsigned _dos_setftime(int __handle,unsigned __date,unsigned __time);
extern unsigned _dos_read(int __handle, _Far void * __buffer,
	unsigned __length, unsigned * __bytes);
extern unsigned _dos_write(int __handle, const _Far void * __buffer,
	unsigned __length, unsigned * __bytes);
extern unsigned _dos_commit(int __handle);

#ifndef _FIND_T_DEFINED
#define _FIND_T_DEFINED

#pragma Off(Align_members)
#if _MSNT || _OS2
    struct _find_t {
	long reserved;
	unsigned long attrib;
	unsigned short int wr_time;
	unsigned short int wr_date;
	long int size;
	char name[256];
	};
#else
    struct _find_t {
	char reserved[21];
	char attrib;
	unsigned short int wr_time;
	unsigned short int wr_date;
	long int size;
	char name[13];
	};
#endif
#pragma Pop(Align_members)

#endif /* _FIND_T_DEFINED */

#ifndef _DATETIME_T_DEFINED
#define _DATETIME_T_DEFINED

#pragma Off(Align_members)
struct _dosdate_t {
    unsigned char day;
    unsigned char month;
    unsigned short int year;
    unsigned char dayofweek;
    };
#pragma Pop(Align_members)

#pragma Off(Align_members)
struct _dostime_t {
    unsigned char hour;
    unsigned char minute;
    unsigned char second;
    unsigned char hsecond;
    };
#pragma Pop(Align_members)

#endif /* _DATETIME_T_DEFINED */

#ifndef _DISKFREE_T_DEFINED
#define _DISKFREE_T_DEFINED

#pragma Off(Align_members)
#if _MSNT || _OS2
struct _diskfree_t {
    unsigned total_clusters;
    unsigned avail_clusters;
    unsigned sectors_per_cluster;
    unsigned bytes_per_sector;
    };
#else  /* _MSDOS */
struct _diskfree_t {
    unsigned short total_clusters;
    unsigned short avail_clusters;
    unsigned short sectors_per_cluster;
    unsigned short bytes_per_sector;
    };
#endif
#pragma Pop(Align_members)

#endif /* _DISKFREE_T_DEFINED */ 

#ifdef _REENTRANT
    #if _MSNT
	extern int * __doserrno(void);
	#define _doserrno   (*__doserrno())
    #elif !defined(_STATIC_H)
	#include <static.h>
    #endif
#else
    _CRTIMP extern int  _doserrno;
#endif

extern unsigned _dos_findfirst(const char * __path,unsigned __attributes,
	struct _find_t * __buffer);
extern unsigned _dos_findnext(struct _find_t * __buffer);
extern unsigned _dos_findclose(struct _find_t * __buffer);
extern void _dos_getdate(struct _dosdate_t * __date);
extern unsigned _dos_getdiskfree(unsigned __drive,
	struct _diskfree_t * __diskinfo);
extern void _dos_gettime(struct _dostime_t * __time);
extern unsigned _dos_setdate(struct _dosdate_t * __date);
extern unsigned _dos_settime(struct _dostime_t * __time);

#if __HIGHC__
#define FP_SEG(farptr) _FP_SEG(farptr)
#define FP_OFF(farptr) _FP_OFF(farptr)
#define dosdate_t _dosdate_t
#define dostime_t _dostime_t
#define diskfree_t _diskfree_t
#define find_t _find_t

extern unsigned _dos_findfirst(const char * __path,unsigned __attributes,
	struct find_t * __buffer);
extern unsigned _dos_findnext(struct find_t * __buffer);
extern void _dos_getdate(struct dosdate_t * __date);
extern unsigned _dos_getdiskfree(unsigned __drive,
	struct diskfree_t * __diskinfo);
extern void _dos_gettime(struct dostime_t * __time);
extern unsigned _dos_setdate(struct dosdate_t * __date);
extern unsigned _dos_settime(struct dostime_t * __time);
#endif


#if _MSNT
    _CRTIMP extern unsigned int _osversion;  /* not recommended for use!! */
#endif

/*------------------------------------------------------------------
    The rest of this file contains functionality supported only on
    DOS.
*/

#if _MSDOS

extern unsigned int _osversion;

extern int _bdos(int __fnumber, unsigned int __dxreg, unsigned int __alreg);
extern unsigned _dos_allocmem(unsigned __size,unsigned * __segment);
extern unsigned _dos_freemem(unsigned __segment);
extern void _dos_keep(unsigned __retcode,unsigned __memsize);
extern unsigned _dos_setblock(unsigned __size,unsigned __segment,unsigned * __maxsize);
extern void _disable(void );
extern void _enable(void );


#ifdef _I386
/*  
 * Functions to get and set interrupt handlers under
 * the Phar Lap and Ergo runtime environments.
 * See the Library Reference Manual for details on the use of these functions.
 */

	/* Define an interrupt handler type */
#ifndef _INTERRPT
#define _INTERRPT _CC (_INTERRUPT|_CALLING_CONVENTION)
#endif

	/* The real mode handler is a 32-bit seg:off address */
typedef long int _real_int_handler_t;

	/* Get current protected mode interrupt handler. */
	/* A function that returns a pointer to a function returning void. */
extern _Far _INTERRPT void (* _getpvect (int intno)) ();

	/* Get current real mode interrupt handler */
extern  _real_int_handler_t _getrvect (int intno);

	/* Set protected-mode interrupt handler */
extern int _setpvect (int intno, _Far _INTERRPT void (*handler) ());

	/* Set real-mode interrupt handler */
extern int _setrvect (int intno, _real_int_handler_t rmhandler);

	/* Set current real mode and protected mode interrupt handlers. */
	/* Both will point to a protected-mode handler. */
extern int _setrpvectp (int intno, _Far _INTERRPT void (*pmhandler) ());

#else
extern _Far void (* _dos_getvect(unsigned __intnumber))();
extern void _dos_setvect(unsigned __intnumber,_Far void (*v)());
#endif

#ifndef _REGS_DEFINED
#define _REGS_DEFINED
/*
 * WORDREGS and DWORDREGS have the same size arguments.  The WORDREGS struct 
 * is provided for compatibility with previous source code.
 */
#pragma Off(Align_members)
struct _DWORDREGS {
    unsigned int eax;
    unsigned int ebx;
    unsigned int ecx;
    unsigned int edx;
    unsigned int esi;
    unsigned int edi;
    unsigned int cflag;
    };
#pragma Pop(Align_members)

#pragma Off(Align_members)
struct _WORDREGS {
    unsigned int ax;
    unsigned int bx;
    unsigned int cx;
    unsigned int dx;
    unsigned int si;
    unsigned int di;
    unsigned int cflag;
    };
#pragma Pop(Align_members)

#pragma Off(Align_members)
struct _BYTEREGS {
    unsigned char al, ah, xax[sizeof(int)-2];
    unsigned char bl, bh, xbx[sizeof(int)-2];
    unsigned char cl, ch, xcx[sizeof(int)-2];
    unsigned char dl, dh, xdx[sizeof(int)-2];
    };
#pragma Pop(Align_members)

union _REGS {
    struct _DWORDREGS w;
    struct _WORDREGS  x;
    struct _BYTEREGS  h;
    struct _BYTEREGS  l;
    };

#pragma Off(Align_members)
struct _SREGS {
    unsigned short int es;
    unsigned short int cs;
    unsigned short int ss;
    unsigned short int ds;
    };
#pragma Pop(Align_members)

#endif /* _REGS_DEFINED */

#ifndef _DOSERROR_DEFINED
#define _DOSERROR_DEFINED

#pragma Off(Align_members)
struct _DOSERROR {
    short int exterror;
#ifdef __CPLUSPLUS__
    // Can't have a field named "class" in C++
    char Class;
#else
    char class;
#endif
    char action;
    char locus;
    };
#pragma Pop(Align_members)

#endif /* _DOSERROR_DEFINED */

extern int _dosexterr(struct _DOSERROR * __buffer);
extern int _intdos(union _REGS * __before, union _REGS * __after);
extern int _intdosx(union _REGS * __before, union _REGS * __after,
	struct _SREGS * __segregs);
extern int _int86(int __number,union _REGS * __before, union _REGS * __after);
extern int _int86x(int __number,union _REGS * __before, union _REGS * __after,
	struct _SREGS * __segregs);
extern void _segread(struct _SREGS * __segregs);

#ifdef __HIGHC__

#define REGS _REGS
#define SREGS _SREGS
#define DWORDREGS _DWORDREGS
#define WORDREGS _WORDREGS
#define BYTEREGS _BYTEREGS
#define DOSERROR _DOSERROR

#include <_na.h>
#if _NA_NAMES
    _NA(bdos)
    _NA(dosexterr)
    _NA(intdos)
    _NA(intdosx)
    _NA(int86)
    _NA(int86x)
    _NA(segread)
#elif _MSDOS
    extern int bdos(int __fnumber, unsigned int __dxreg, unsigned int __alreg);
    extern int dosexterr(struct DOSERROR * __buffer);
    extern int intdos(union REGS * __before, union REGS * __after);
    extern int intdosx(union REGS * __before, union REGS * __after,
	    struct SREGS * __segregs);
    extern int int86(int __number,union REGS * __before, union REGS * __after);
    extern int int86x(int __number,union REGS * __before, union REGS * __after,
	    struct SREGS * __segregs);
    extern void segread(struct SREGS * __segregs);
#endif /*_NA_NAMES*/

#endif /*__HIGHC__*/

#endif /* _MSDOS */

#ifdef __CPLUSPLUS__
}
#endif

#pragma pop_align_members();

#endif /* _DOS_H */
