/*->c.os */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>


#include "h.kernel"


#include "h.os"
#include "h.swis"


#ifndef XOS_Bit
  #define XOS_Bit          0x020000
#endif





os_error *os_swix(int swicode, os_regset *r)
{
   return ((os_error *)_kernel_swi(swicode, (_kernel_swi_regs *)r, (_kernel_swi_regs *)r));
}

void os_swi(int swicode, os_regset *r)
{
   _kernel_swi(swicode+0x80000000, (_kernel_swi_regs *)r, (_kernel_swi_regs *)r);
}




os_error *os_swi4r(int swicode,
  int r0, int r1, int r2, int r3,
  int *r0out, int *r1out, int *r2out, int *r3out)
{
  os_regset r;
  os_error *e;

  r.r[0] = r0;
  r.r[1] = r1;
  r.r[2] = r2;
  r.r[3] = r3;
  if ((os_X & swicode) == 0) {
    os_swi(swicode, &r);
    e = 0;
  } else {
    e = os_swix(swicode, &r);
  };
  if (r0out) *r0out = r.r[0];
  if (r1out) *r1out = r.r[1];
  if (r2out) *r2out = r.r[2];
  if (r3out) *r3out = r.r[3];
  return e;
}




os_error *os_swi4(int swicode, int r0, int r1, int r2, int r3) {
  os_regset r;
  r.r[0] = r0;
  r.r[1] = r1;
  r.r[2] = r2;
  r.r[3] = r3;
  if ((os_X & swicode) == 0) {
    os_swi(swicode, &r);
    return 0;
  } else {
    return os_swix(swicode, &r);
  };
}



os_error *os_swi1(int swicode, int r0) {
  return os_swi4(swicode, r0, 0, 0, 0);
}

os_error *os_swi2(int swicode, int r0, int r1) {
  return os_swi4(swicode, r0, r1, 0, 0);
}

os_error *os_swi3(int swicode, int r0, int r1, int r2) {
  return os_swi4(swicode, r0, r1, r2, 0);
}



os_error *os_swi3r(int swicode,
  int r0, int r1, int r2, int *r0out, int *r1out, int *r2out)
{
  return os_swi4r(swicode, r0, r1, r2, 0, r0out, r1out, r2out, 0);
}




os_error * os_byte(int a, int *x, int *y)
{
  return os_swi3r(os_X | OS_Byte, a, *x, *y, 0, x, y);
}


os_error * os_word(int wordcode, void *p)
{
  os_regset r;

  r.r[0] = wordcode;
  r.r[1] = (int) p;

  return os_swix(OS_Word, &r);
}


os_error * os_gbpb(os_gbpbstr *p)
{
  return os_swix(OS_GBPB, (os_regset *) p);
}

os_error * os_file(os_filestr *p)
{
  return os_swix(OS_File, (os_regset *) p);
}


os_error * os_find(os_regset *p)
{
  return os_swix(OS_Find, (os_regset *) p);
}


os_error * os_cli(char * command)
{
  os_regset r;

  r.r[0] = (int) command;

  return os_swix(OS_CLI, &r);
}



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

int os_read_var_size (char *var)
{
  os_error  * err;
  os_regset   reg;

  reg.r[0] = (int) var;
  reg.r[1] = 0;
  reg.r[2] = -1;		/* top bit set to find existence/length of
				 * variable */
  reg.r[3] = 0;			/* context ptr */
  reg.r[4] = 0;
  err = os_swix (OS_ReadVarVal, &reg);

  /* PRM (1-309) says ignore any returned error */
  /* on exit r2==0 if var does NOT exist */
  /* if var exists, r2 is NOT length */
  return ((reg.r[2] == 0)?0:~reg.r[2]);
}




