/**************************************************
UZI (Unix Z80 Implementation) Kernel:  unix.h
***************************************************/

#include <sys/types.h>


#define UFTSIZE     32	/* Number of user files */
#define OFTSIZE     64	/* Open file table size */
#define ITABSIZE    64	/* Inode table size */
#define PTABSIZE    24	/* Process table size */

#define NSIGS       16	/* Number of signals <= 16 */

#define ROOTINODE    1	/* Inode # of /  for all mounted filesystems. */

#define TICKSPERSEC 50	/* Ticks per second */
#define MAXTICKS    10	/* Max ticks before swapping out (time slice) */

#define ARGBLK       0	/* Block number on SWAPDEV for arguments */

/* Offsets (in longs) into block zero of /dev/mem */
#define OFF_UDATA	0
#define OFF_PTAB	1
#define OFF_USERS	2
#define OFF_YOU		3


#define MAXEXEC      0	/* Max no of blks of executable file */

#define EMAGIC	(0xc3)		/* Header of executable (64KB static) */
#define EMAGIC1	(0x12345678)	/* Executable (MAPUX 32-bit reloc) */
#define CMAGIC   24721	/* Random number for cinode c_magic */
#define SMOUNTED 12742	/* Magic number to specify mounted filesystem */
#define NULL         0


/* These macros are simply to trick the compiler into generating
   more compact code. */
/* Actually, with hcc this is actually worse, but after top makes
   little difference as fair as I can see - mcy */

#define ifnull(e) if(e){}else
#define ifnot(e) if(e){}else
#define ifzero(e) if(e){}else

 /*
 |  Header on an executable file
*/
typedef struct ehead
{
	int	magic;
	int	text_size,
		data_size,
		bss_size,
		stk_size,
		brk_req;
	int	ext_offset;
	int	unused;
} ehead;
	

 /*
 |  This structure is bigger than the Z80 one
*/
typedef struct s_queue
{
    char *q_base;	/* Pointer to data */
    char *q_head;	/* Pointer to addr of next char to read. */
    char *q_tail;	/* Pointer to where next char to insert goes. */
    int  q_size;	/* Max size of queue */
    int  q_count;	/* How many characters presently in queue */
    int  q_wakeup;	/* Threshold for waking up processes waiting on queue*/
} queue_t;


 /*
 |  This could be done as a single int now, but it isn't
*/
typedef struct time_s
{
	uint16 t_time;
	uint16 t_date;
} time__t;


 /*
 |  User's structure for times() system call
*/
struct tms
{
	time__t  tms_utime;
	time__t  tms_stime;
	time__t  tms_cutime;
	time__t  tms_cstime;
	time__t  tms_etime;      /* Elapsed real time */
};


/* Flags for setftime() */
#define A_TIME  1
#define M_TIME  2
#define C_TIME  4


 /*
 |  Looks like a stucture describing a character read
 |  from a bufer
*/
typedef struct off_t
{
	uint16  o_blkno;	/* Block number */
	int16	o_offset;	/* Offset within block 0-511 */
} off_t;


typedef uint16 blkno_t;  /* Can have 65536 512-byte blocks in filesystem */
#define NULLBLK ((blkno_t)-1)


 /*
 |  This is the buffer that devio mucks about with.  This is the
 |  same size as the Z80 version.
*/
typedef struct blkbuf
{
    char        bf_data[512];    /* This MUST be first ! */
    int16       bf_dev;
    blkno_t     bf_blk;
    char        bf_dirty;
    char        bf_busy;
    uint16      bf_time;        /* LRU time stamp */
/*    struct blkbuf *bf_next;    /* LRU free list pointer */
} blkbuf, *bufptr;


 /*
 |  i-node as stored on disc
 |  This is still 64 bytes with Amiga - no pointers involved
*/
typedef struct dinode
{
    uint16   i_mode;
    uint16   i_nlink;
    uint16   i_uid;
    uint16   i_gid;
    off_t    i_size;
    time__t  i_atime;
    time__t  i_mtime;
    time__t  i_ctime;
    blkno_t  i_addr[20];
} dinode;               /* Exactly 64 bytes long! */


 /*
 |  Really only used by users
 |  Status of an open file ??  Dunno.
*/
struct stat
{
	int16    st_dev;
	uint16   st_ino;
	uint16   st_mode;
	uint16   st_nlink;
	uint16   st_uid;
	uint16   st_gid;
	uint16   st_rdev;
	off_t    st_size;
	time__t  st_atime;
	time__t  st_mtime;
	time__t  st_ctime;
};


/* Bit masks for i_mode and st_mode */

#define OTH_EX  0001
#define OTH_WR  0002
#define OTH_RD  0004
#define GRP_EX  0010
#define GRP_WR  0020
#define GRP_RD  0040
#define OWN_EX  0100
#define OWN_WR  0200
#define OWN_RD  0400

#define SAV_TXT 01000
#define SET_GID 02000
#define SET_UID 04000

#define MODE_MASK 07777

#define F_REG  0100000
#define F_DIR   040000
#define F_PIPE  010000
#define F_BDEV  060000
#define F_CDEV  020000

#define F_MASK  0170000


 /*
 |  i-node as stores in memory.  Note that it includes
 |  a dinode structure
*/
typedef struct cinode
{
	uint16    c_magic;	/* Used to check for corruption. */
	int16     c_dev;	/* Inode's device */
	uint16    c_num;	/* Inode # */
	dinode    c_node;
	char      c_refs;	/* In-core reference count */
	char      c_dirty;	/* Modified flag. */
} cinode, *inoptr;


#define NULLINODE ((inoptr)NULL)
#define NULLINOPTR ((inoptr*)NULL)


 /*
 |  Directory
*/
typedef struct direct
{
	uint16	d_ino;
	char	d_name[14];
} direct;


 /*
 |  Crikey.  A whole filesystem
*/
typedef struct filesys
{
	int16     s_mounted;
	uint16    s_isize;
	uint16    s_fsize;
	int16     s_nfree;
	blkno_t   s_free[50];
	int16     s_ninode;
	uint16    s_inode[50];
	int16     s_fmod;
	time__t   s_time;
	blkno_t   s_tfree;
	uint16    s_tinode;
	inoptr    s_mntpt;	/* Mount point */
} filesys, *fsptr;


 /*
 |  An open file
*/
typedef struct oft
{
	off_t	o_ptr;	/* File position point16er */
	inoptr	o_inode;	/* Pointer into in-core inode table */
	char	o_access;	/* O_RDONLY, O_WRONLY, or O_RDWR */
	char	o_refs;	/* Reference count: depends on # of active children */
} oft;


/* Process table p_status values */

#define P_EMPTY         0    /* Unused slot */
#define P_RUNNING       1    /* Currently running process */
#define P_READY         2    /* Runnable   */
#define P_SLEEP         3    /* Sleeping; can be awakened by signal */
#define P_XSLEEP        4    /* Sleeping, don't wake up for signal */
#define P_PAUSE         5    /* Sleeping for pause(); can wakeup for signal */
#define P_FORKING       6    /* In process of forking; do not mess with */
#define P_WAIT          7    /* Executed a wait() */
#define P_ZOMBIE        8    /* Exited. */


#define SIGHUP  1       
#define SIGINT  2      
#define SIGQUIT 3     
#define SIGILL  4    
#define SIGTRAP 5   
#define SIGADD  6  
#define SIGINTE 7 
#define SIGFPE  8 
#define SIGKILL 9
#define SIGBUS  10
#define SIGSEGV 11
#define SIGSYS  12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15

#define SIG_DFL         (int (*)())0
#define SIG_IGN         (int (*)())1

#define sigmask(sig)    (1<<(sig))

#include <sys/memman.h>

 /*
 |  Process table entry
*/
typedef struct p_tab
{
	char		p_status;	/* Process status */
	int		p_pid;		/* Process ID */
	int		p_uid;
	struct p_tab	*p_pptr;	/* Process parent's table entry */
	memblk		p_memlst;	/* List of memory blocks */
	char		*p_isp;		/* Private interrupt stack */
	unsigned	p_alarm;	/* Seconds until alarm goes off */
	unsigned	p_exitval;	/* Exit value */
	/* Everything below here is overlaid by time info at exit */
	char		*p_wait;	/* Address of thing waited for */
	int		p_priority;	/* Process priority */
	uint16		p_pending;	/* Pending signals */
	uint16		p_ignored;	/* Ignored signals */
} p_tab, *ptptr;


#define SYSCALL	1
#define INTERRUPT 2

 /*
 |  Per-process data (Swapped with process)
*/

/* User process stucture */
typedef struct u_data
{
	struct p_tab	*u_ptab;	/* Process table pointer */
	char		u_insys;	/* True if in kernel */
	char		u_callno;	/* sys call being executed. */
	char		u_swaptype;	/* Int or syscall causing switch? */
	int		u_retval;	/* Return value from sys call */
	int		u_error;	/* Last error number */
	char		*u_sp;		/* Used when a process is swapped. */
	char		*u_cisp;	/* Current isp in psleep()ed sys call */
	int		u_argn;		/* First arg */
	int		u_argn1;	/* second */
	int		u_argn2;	/* etc */
	int		u_argn3;        /* etc */
	int		u_store[4];	/* For information during signal servicing */
	char		*u_base;	/* Source or dest for I/O */
	unsigned	u_count;	/* Amount for I/O */
	off_t		u_offset;	/* Place in file for I/O */
	struct blkbuf	*u_buf;

	int		u_gid;
	int		u_euid;
	int		u_egid;
	int		u_mask;		/* umask: file creation mode mask */
	time__t		u_time;		/* Start time */
	char		u_files[UFTSIZE];	/* Process file table:
				contains indexes into open file table. */
	inoptr		u_cwd;		/* Index into inode table of cwd. */
	char		*u_break;	/* Top of data space */
	char		*u_brkhigh;	/* Upper limit for break */
	char		*u_brklow;	/* Lower limit for break */

	inoptr		u_ino;		/* Used during execve() */
	char		*u_isp;		/* Value of initial sp (argv) */

	int		(*u_sigvec[NSIGS])(); /* Array of signal vectors */
	int		u_cursig;	/* Signal currently being caught */
	char		u_name[8];	/* Name invoked with */
	time__t		u_utime;	/* Elapsed ticks in user mode */
	time__t		u_stime;	/* Ticks in system mode */
	time__t		u_cutime;	/* Total childrens ticks */
	time__t		u_cstime;
} u_data;


 /*
 |  Struct to temporarily hold arguments in execve
 |  With Amiga this will hold fewer arguments in its 512 bytes
*/
struct s_argblk
{
	int	a_argc;
	int	a_arglen;
	int	a_envc;
	char	a_buf[512-3*sizeof(int)];
};


/* The device driver switch table */

typedef struct devsw
{
	int	minor;		/* Minor device number (argument to below) */
	int	(*dev_open)();	/* The routines for reading, etc */
	int	(*dev_close)();	/* format: op(minor,blkno,offset,count,buf); */
	int	(*dev_read)();	/* offset would be ignored for block devices */
	int	(*dev_write)();	/* blkno and offset ignored for tty, etc. */
	int	(*dev_ioctl)();	/* count is rounded to 512 for block devices */
} devsw;



 /*
 |  Open() parameters.
*/
#define O_RDONLY        0
#define O_WRONLY        1
#define O_RDWR          2

 /*
 |  Error codes
*/
#define EPERM           1               
#define ENOENT          2               
#define ESRCH           3               
#define EINTR           4               
#define EIO             5               
#define ENXIO           6               
#define E2BIG           7               
#define ENOEXEC         8               
#define EBADF           9               
#define ECHILD          10              
#define EAGAIN          11              
#define ENOMEM          12              
#define EACCES          13              
#define EFAULT          14              
#define ENOTBLK         15              
#define EBUSY           16              
#define EEXIST          17              
#define EXDEV           18              
#define ENODEV          19              
#define ENOTDIR         20              
#define EISDIR          21              
#define EINVAL          22              
#define ENFILE          23              
#define EMFILE          24              
#define ENOTTY          25              
#define ETXTBSY         26              
#define EFBIG           27              
#define ENOSPC          28              
#define ESPIPE          29              
#define EROFS           30              
#define EMLINK          31              
#define EPIPE           32              
#define ENAMETOOLONG    63              

#include <sys/config.h>

