/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/****************************************************************************
 * 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 __kernel_h
#include "kernel.h"
#endif

#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 _kernel_oserror 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
 *
 */
#define os_swi(swicode, regs) \
        (((swicode) & (1 << 17)) ? \
                (void)os_swix((swicode) & ~(1 << 17), regs) : \
                os_swi(swicode, regs))
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.
 *
 */
#define os_swi0(swicode) \
        (((swicode) & (1 << 17)) ? \
                os_swix0((swicode) & ~(1 << 17)) : \
                os_swi0(swicode))
os_error *(os_swi0)(int swicode); /* zero arguments and results */
#define os_swi1(swicode, a) \
        (((swicode) & (1 << 17)) ? \
                os_swix1((swicode) & ~(1 << 17), a) : \
                os_swi1(swicode, a))
os_error *(os_swi1)(int swicode, ...);
#define os_swi2(swicode, a, b) \
        (((swicode) & (1 << 17)) ? \
                os_swix2((swicode) & ~(1 << 17), a, b) : \
                os_swi2(swicode, a, b))
os_error *(os_swi2)(int swicode, ...);
#define os_swi3(swicode, a, b, c) \
        (((swicode) & (1 << 17)) ? \
                os_swix3((swicode) & ~(1 << 17), a, b, c) : \
                os_swi3(swicode, a, b, c))
os_error *(os_swi3)(int swicode, ...);
#define os_swi4(swicode, a, b, c, d) \
        (((swicode) & (1 << 17)) ? \
                os_swix4((swicode) & ~(1 << 17), a, b, c, d) : \
                os_swi4(swicode, a, b, c, d))
os_error *(os_swi4)(int swicode, ...);
#define os_swi5(swicode, a, b, c, d, e) \
        (((swicode) & (1 << 17)) ? \
                os_swix5((swicode) & ~(1 << 17), a, b, c, d, e) : \
                os_swi5(swicode, a, b, c, d, e))
os_error *(os_swi5)(int swicode, ...);
#define os_swi6(swicode, a, b, c, d, e, f) \
        (((swicode) & (1 << 17)) ? \
                os_swix6((swicode) & ~(1 << 17), a, b, c, d, e, f) : \
                os_swi6(swicode, a, b, c, d, e, f))
os_error *(os_swi6)(int swicode, ...);

#define os_swi1r(swicode, a, b) \
        (((swicode) & (1 << 17)) ? \
                os_swix1r((swicode) & ~(1 << 17), a, b) : \
                os_swi1r(swicode, a, b))
os_error *(os_swi1r)(int swicode, ...);
#define os_swi2r(swicode, a, b, c, d) \
        (((swicode) & (1 << 17)) ? \
                os_swix2r((swicode) & ~(1 << 17), a, b, c, d) : \
                os_swi2r(swicode, a, b, c, d))
os_error *(os_swi2r)(int swicode, ...);
#define os_swi3r(swicode, a, b, c, d, e, f) \
        (((swicode) & (1 << 17)) ? \
                os_swix3r((swicode) & ~(1 << 17), a, b, c, d, e, f) : \
                os_swi3r(swicode, a, b, c, d, e, f))
os_error *(os_swi3r)(int swicode, ...);
#define os_swi4r(swicode, a, b, c, d, e, f, g, h) \
        (((swicode) & (1 << 17)) ? \
                os_swix4r((swicode) & ~(1 << 17), a, b, c, d, e, f, g, h) : \
                os_swi4r(swicode, a, b, c, d, e, f, g, h))
os_error *(os_swi4r)(int swicode, ...);
#define os_swi5r(swicode, a, b, c, d, e, f, g, h, i, j) \
        (((swicode) & (1 << 17)) ? \
                os_swix5r((swicode) & ~(1 << 17), a,b,c,d,e,f,g,h,i,j) : \
                os_swi5r(swicode, a,b,c,d,e,f,g,h,i,j))
os_error *(os_swi5r)(int swicode, ...);
#define os_swi6r(swicode, a, b, c, d, e, f, g, h, i, j, k, l) \
        (((swicode) & (1 << 17)) ? \
                os_swix6r((swicode) & ~(1 << 17),a,b,c,d,e,f,g,h,i,j,k,l) : \
                os_swi6r(swicode, a,b,c,d,e,f,g,h,i,j,k,l))
os_error *(os_swi6r)(int swicode, ...);

os_error *os_swix0(int swicode); /* zero arguments and results */
os_error *os_swix1(int swicode, ...);
os_error *os_swix2(int swicode, ...);
os_error *os_swix3(int swicode, ...);
os_error *os_swix4(int swicode, ...);
os_error *os_swix5(int swicode, ...);
os_error *os_swix6(int swicode, ...);

os_error *os_swix1r(int swicode, ...);
os_error *os_swix2r(int swicode, ...);
os_error *os_swix3r(int swicode, ...);
os_error *os_swix4r(int swicode, ...);
os_error *os_swix5r(int swicode, ...);
os_error *os_swix6r(int swicode, ...);

/* ------------------------------- 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);


# endif

/* end of os.h */