/* kerinfo - kernel interface table
 * --------------------------------
 * 
 * All functions should be called using the GCC calling conventions:
 * 
 * (1) parameters are passed on the stack, aligned on 16 bit boundaries
 * (2) registers d0-d1 and a0-a1 are scratch registers and may be modified
 *     by the called functions
 * (3) if the function returns a value, it will be returned in register
 *     d0
 * 
 * data types:
 * -----------
 * int   is 16bit
 * 
 * short is 16bit
 * long  is 32bit
 * 
 * ushort, ulong - unsigned version of short, long
 * 
 */

struct kerinfo
{
	short	maj_version;	/* kernel version number */
	short	min_version;	/* minor kernel version number */
	ushort	default_perm;	/* default file permissions */
	ushort	version;	/* version number */
	
	
	/* OS functions
	 * ------------
	 * NOTE: these tables are definitely READ ONLY!!!!
	 */
	Func	*bios_tab;	/* pointer to the BIOS entry points */
	Func	*dos_tab;	/* pointer to the GEMDOS entry points */
	
	
	/* media change vector
	 * -------------------
	 * call this if a device driver detects a disk
	 * change during a read or write operation. The parameter is the BIOS
	 * device number of the disk that changed.
	 */
	void	_cdecl (*drvchng)(ushort);
	
	/* Debugging stuff
	 * ---------------
	 * 
	 * trace - informational messages
	 * debug - error messages
	 * alert - really serious errors
	 * fatal - fatal errors
	 */
	void	_cdecl (*trace)(const char *, ...);
	void	_cdecl (*debug)(const char *, ...);
	void	_cdecl (*alert)(const char *, ...);
	EXITING _cdecl (*fatal)(const char *, ...) NORETURN;
	
	
	/* memory allocation functions
	 * ---------------------------
	 * 
	 * kmalloc(size) / kfree (ptr)
	 * 
	 * kmalloc and kfree should be used for most purposes, and act like
	 * malloc and free respectively; kmalloc'ed memory is *exclusive*
	 * kernel memory, supervisor proteced
	 * 
	 * umalloc(size) / ufree (ptr)
	 * 
	 * umalloc and ufree may be used to allocate/free memory that is
	 * attached to the current process, and which is freed automatically
	 * when the process exits; this is generally not of much use to a file
	 * system driver
	 */
	void *	_cdecl (*kmalloc)(ulong);
	void	_cdecl (*kfree)(void *);
	void *	_cdecl (*umalloc)(ulong);
	void	_cdecl (*ufree)(void *);
	
	
	/* utility functions for string manipulation
	 * -----------------------------------------
	 * 
	 * like the normal library functions
	 * 
	 * sprintf:
	 * --------
	 * kernel sprintf, like library sprintf but not so heavy; floating
	 * point formats are not supported!
	 * Also this sprintf will put at most SPRINTF_MAX characters into
	 * the output string.
	 */
	int	_cdecl (*strnicmp)(const char *, const char *, int);
	int	_cdecl (*stricmp)(const char *, const char *);
	char *	_cdecl (*strlwr)(char *);
	char *	_cdecl (*strupr)(char *);
	int	_cdecl (*sprintf)(char *, const char *, ...);
	
	
	/* utility functions for manipulating time
	 * ---------------------------------------
	 * 
	 * millis_time(ms, timeptr)
	 * 
	 * convert "ms" milliseconds into a DOS time (in td[0]) and date
	 * (in td[1]) convert a DOS style time and date into a Unix style
	 * time; returns the Unix time
	 * 
	 * unixtime(time, date)
	 * 
	 * convert a DOS style time and date into a Unix style time; returns
	 * the Unix time
	 * 
	 * dostime(time)
	 * 
	 * convert a Unix time into a DOS time (in the high word of the
	 * returned value) and date (in the low word)
	 */
	void	_cdecl (*millis_time)(ulong, short *);
	long	_cdecl (*unixtime)(ushort, ushort);
	long	_cdecl (*dostime)(long);
	
	
	/* utility functions for dealing with pauses and sleep
	 * ---------------------------------------------------
	 * 
	 * nap(n)
	 * 
	 * go to sleep temporarily for about "n" milliseconds
	 * (the exact time slept may vary)
	 * 
	 * sleep(que, cond)
	 * 
	 * wait on system queue "que" until a condition occurs
	 * 
	 * wake(que, cond)
	 * 
	 * wake all processes on queue "que" that are waiting for
	 * condition "cond"
	 * 
	 * wakeselect(p)
	 * 
	 * wake a process that is doing a select(); "param" should be the
	 * process code passed to select()
	 */
	void	_cdecl (*nap)(unsigned);
	int	_cdecl (*sleep)(int que, long cond);
	void	_cdecl (*wake)(int que, long cond);
	void	_cdecl (*wakeselect)(long param);
	
	
	/* file system utility functions
	 * -----------------------------
	 * 
	 * denyshare(list, f)
	 * 
	 * "list" is a list of open files, "f" is a new file that is being
	 * opened.
	 * If the file sharing mode of f conflicts with any of the FILEPTRs
	 * in the list, then this returns 1, otherwise 0.
	 * 
	 * denylock(list, newlock)
	 * 
	 * checks a list of locks to see if the new lock conflicts with any
	 * one in the list. If so, the first conflicting lock is returned;
	 * otherwise, a NULL is returned.
	 * This function is only available if maj_version > 0 or
	 * min_version >= 94. Otherwise, it will be a null pointer.
	 */
	int	_cdecl (*denyshare)(FILEPTR *, FILEPTR *);
	LOCK *	_cdecl (*denylock)(LOCK *, LOCK *);
	
	
	/* functions for adding/cancelling timeouts
	 * ----------------------------------------
	 * 
	 * addtimeout(delta, func)
	 * 
	 * schedules a callback to occur at some future time "delta" is the
	 * number of milliseconds before the timeout is to occur, and func is
	 * a pointer to the function which should be called at that time. Note
	 * that the kernel's timeout facility does not actually have a
	 * millisecond resolution, so the function will most likely be called
	 * some time after specified time has elapsed (i.e. don't rely on this
	 * for really accurate timing). Also note that the timeout may occur
	 * in the context of a different process than the one which scheduled
	 * the timeout, i.e. the given function should not make assumptions
	 * involving the process context, including memory space.
	 * addtimeout() returns a long "magic cookie" which may be passed to
	 * the canceltimeout() function to cancel the pending time out.
	 * This function is only available in MiNT versions 1.06 and later;
	 * otherwise the pointer will be NULL.
	 * 
	 * canceltimeout(which)
	 * 
	 * cancels a pending timeout. The parameter is the "magic cookie"
	 * returned from addtimeout(). If the timeout has already occured,
	 * canceltimeout does nothing, otherwise it removes the timeout from the
	 * kernel's schedule.
	 * 
	 * addroottimeout(delta, func, flags)
	 * 
	 * same as addtimeout() but the timeout is attached to the root
	 * process (MiNT) and is never implicitly (programm termination)
	 * canceled
	 * flags - bitvektor, only bit 1 defined at the moment
	 *         if bit 1 is set, addroottimeout is called from an interrupt
	 *         handler and use a static list for new timeouts
	 *         Useful for Softinterrupts!
	 *       - all other bits must be set to 0
	 * 
	 * cancelroottimeout(which)
	 * 
	 * same as canceltimeout() but for root timeouts
	 */
	TIMEOUT * _cdecl (*addtimeout)(long, void _cdecl (*)());
	void	_cdecl (*canceltimeout)(TIMEOUT *);
	TIMEOUT * _cdecl (*addroottimeout)(long, void _cdecl (*)(), ushort);
	void	_cdecl (*cancelroottimeout)(TIMEOUT *);
	
	
	/* miscellaneous other things
	 * --------------------------
	 * 
	 * interrupt safe kill and wake
	 * 
	 * ikill(p, sig)
	 * iwake(que, cond, pid)
	 */
	long	_cdecl (*ikill)(int, int);
	void	_cdecl (*iwake)(int que, long cond, short pid);
	
	/* 1.15 extensions */
	BIO	*bio;	/* buffered block I/O, see block_IO.doc */
	
	/* version 1 extension */
	TIMEVAL	*xtime;	/* pointer to current kernel time - UTC */
	
	long	res;	/* reserved */
	
	/* version 2 extension
	 * pointers are valid if != NULL
	 */
	
	long	_cdecl (*add_rsvfentry)(char *name, char portflags, char bdev);
	long	_cdecl (*del_rsvfentry)(char *name);
	long	_cdecl (*killgroup)(int pgrp, int sig, int priv);
	
	/* easy to use DMA interface, see dma.txt for more details */
	DMA	*dma;
	
	/* for udelay timing loop */
	ulong	*loops_per_sec;
	
	/* lookup cookies in original TOS cookiejar */
	long	_cdecl (*get_toscookie)(ulong tag, ulong *val);
	
	/* reserved, set to 0 */
	long	res2 [16];
};
