/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the RISCOS library for writing applications in C for RISC OS. It may be  *
 * used freely in the creation of programs for Archimedes. It should be     *
 * used with Acorn's C Compiler Release 3 or later.                         *
 *                                                                          *
 ***************************************************************************/

/*
 * Title  : os.h
 * Purpose: provides general access to low-level RISC OS routines
 *
 */

/*
 * This file is provided as an alternative to kernel.h
 * It provides low-level access to RISC OS.
 *
 */

# ifndef __os_h
# define __os_h

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif

typedef struct {
        int r[10];               /* only r0 - r9 matter for SWIs */
} os_regset;

typedef struct {
        int errnum;             /* error number */
        char errmess[252];      /* error message (zero terminated) */
} os_error;

/*
 * os_error * functions return a pointer to an error if it has occurred,
 * otherwise return NULL (0)
 */

/* -------------------------------- os_swi ---------------------------------
 * Perform the given SWI instruction, with the given registers loaded.
 * An error results in a RISC OS error being raised.
 * A NULL regset pointer means that no inout parameters are used
 *
 */

void os_swi(int swicode, os_regset *regs);


#define os_X (0x00020000)

/* ------------------------------- os_swix ---------------------------------
 * Perform the given SWI instruction, with the given registers loaded.
 * Calls returning os_error* use the X form of the relevant SWI. If an error
 * is returned then the os_error should be copied before further system calls
 * are made. If no error occurs then NULL is returned.
 *
 */

os_error *os_swix(int swicode, os_regset *regs);




/* Important note: if swicode does not have the X bit set, then os_swi is
 * called
 * and these functions return NULL (regardless of whether an error was
 * raised); please try to use X bit set swicodes to save confusion.
 *
 */


/*
 * SWIs with varying numbers of arguments and results. NULL result pointers
 * mean that the result from that register is not required. The swi codes can
 * be of the X form if required, as specified by swicode.
 *
 */

os_error *os_swi0(int swicode); /* zero arguments and results */
os_error *os_swi1(int swicode, int r0);
os_error *os_swi2(int swicode, int r0, int r1);
os_error *os_swi3(int swicode, int r0, int r1, int r2);
os_error *os_swi4(int swicode, int r0, int r1, int r2, int r3);
os_error *os_swi6(int swicode, int r0, int r1, int r2, int r3, int r4, int r5);

os_error *os_swi1r(int swicode, int r0in, int *r0out);
os_error *os_swi2r(int swicode, int r0in, int r1in, int *r0out, int *r1out);
os_error *os_swi3r(int swicode, int, int, int, int*, int*, int*);
os_error *os_swi4r(int swicode, int, int, int, int, int*, int*, int*, int*);
os_error *os_swi6r(int swicode,
  int r0, int r1, int r2, int r3, int r4, int r5,
  int *r0out, int *r1out, int *r2out, int *r3out, int *r4out, int *r5out);


/* ------------------------------- os_byte ---------------------------------
 * Perform an OS_Byte SWIx, with x and y passed in register r1 and r2
 * respectively.
 *
 */

os_error *os_byte(int a, int *x /*inout*/, int *y /*inout*/);


/* ------------------------------- os_word ---------------------------------
 * Perform an OS_Word SWIx, with operation number given in "wordcode" and
 * "p" pointing at necessary parameters to be passed in r1
 *
 */

os_error *os_word(int wordcode, void *p);

typedef struct {
        int action;             /* specifies action of osgbpb */
        int file_handle;        /* file handle, but may be used as a char *
                                 * pointing to wildcarded dir-name */
        void *data_addr;        /* memory address of data */
        int number, seq_point, buf_len;
        char *wild_fld;         /* points to wildcarded filename to match */
        int reserved[3];        /* space to allow treatment as reg_block */
} os_gbpbstr;


/* -------------------------------- os_gbpb --------------------------------
 * Perform an OS_GBPB SWI. os_gbpbstr should be used like an os_regset.
 *
 */

os_error *os_gbpb(os_gbpbstr*);

typedef struct {
        int action;             /* action or object type if output data */
        char * name;            /* pointer to filename or pathname */
        int loadaddr, execaddr; /* load, exec addresses */
        int start, end;         /* start address/length, end add./attributes */
        int reserved[4];        /* space to allow treatment as reg_block */
} os_filestr;


/* -------------------------------- os_file --------------------------------
 * Perform an OS_FILE SWI.
 *
 */

os_error *os_file(os_filestr*);


/* ------------------------------- os_args ---------------------------------
 * Perform an OS_Args SWI.
 *
 */

os_error *os_args(os_regset*);


/* ------------------------------ os_find ----------------------------------
 * Perform an OS_Find SWI.
 *
 */

os_error *os_find(os_regset*);


/* ------------------------------ os_cli -----------------------------------
 * Perform an OS_CLI SWI.
 *
 */

os_error *os_cli(char *cmd);


/* ------------------------------ os_read_var_val --------------------------
 * reads a named environment variable into a given buffer (of size "bufsize")
 * If variable doesn't exist then buf points at a null string.
 */

void os_read_var_val(char *name, char *buf /*out*/, int bufsize);



/* Added by cafj --------------- os_read_var_size -------------
 * Function to check for the existence of a system variable
 * On entry var is a pointer to the variable name
 * Returns 0 if variable does not exist (or if SWI errors)
 * Returns length of variable if variable is found but does
 * not read the value */

extern int os_read_var_size (char *var);


# endif

/* end of os.h */
