/****************************************************************************
*
* (C) 2000 by BECK IPC GmbH
*
*  BECK IPC GmbH
*  Garbenheimerstr. 38
*  D-35578 Wetzlar
*
*  Phone : (49)-6441-905-240
*  Fax   : (49)-6441-905-245
*
* ---------------------------------------------------------------------------
* Module      : rtos.c
*
* Function    :   IPC@Chip SC12: RTOS api functions
*                 (see html documentation of the RTOS API)
*                 Use memory model large at your program, if you use this C file.
*                 See html documentation of the RTOS API for details.
*                 Use model Large at your application project, because not all pointer
*                 parameters are declarded as far pointers
* Author        : bartat
* Date          : 19.01.00
* ---------------------------------------------------------------------------

$Header: RTOS.C, 12, 14.02.2002 10:47:27, Christoph Stoidner$

$Log:
 12   IPC@CHIP  1.11        14.02.2002 10:47:27  Christoph Stoidner add Find
      Semaphore Function
 11   IPC@CHIP  1.10        16.01.2002 11:45:06  Christoph Stoidner add starteam
      directives
 10   IPC@CHIP  1.9         14.01.2002 13:18:37  Christoph Stoidner add new
      functions
 9    IPC@CHIP  1.8         02.07.2001 13:29:06  Markus Bartat   delete the send
      message/taskstart functions
 8    IPC@CHIP  1.7         19.06.2001 13:40:10  Markus Bartat   edit
 7    IPC@CHIP  1.6         19.06.2001 13:35:07  Markus Bartat   start: Added
      comments to the c functions
 6    IPC@CHIP  1.5         01.06.2001 12:20:26  Markus Bartat   added new
      functions
 5    IPC@CHIP  1.4         31.05.2001 16:18:25  Christoph Stoidner
 4    IPC@CHIP  1.3         31.05.2001 14:27:45  Christoph Stoidner
 3    IPC@CHIP  1.2         29.05.2001 16:11:08  Markus Bartat   modify comment
 2    IPC@CHIP  1.1         29.05.2001 16:03:57  Markus Bartat   added API call
      0x11 Create a task without starting it
 1    IPC@CHIP  1.0         14.02.2001 16:09:47  Christoph Stoidner
$

* History       :
*
*  Vx.yy                   Author  Changes
*
*             19.01.00       mb    Create
*             22.07.00       mb    add timer procedure calls (see html documentation)
*             20.08.00       mb    add task state API calls
*             24.08.00       mb    add API calls suspend and resume tasks
*             23.10.00       mb    add event group calls
*             26.10.00       mb    add message exchange calls
*             29.05.01       mb    add task create call without running the task
*             01.06.01       mb    add get task state call without using taskmonitoring
*****************************************************************************/
#include <DOS.H>
#include "clib/rtxapi.h"
#include "clib/rtos.h"
/*************************************************************************/
/**********************************************************************************************/
//Task control functions
/***********************************************************************************************/
//create/start a task
/************************************************************************************************/
int RTX_Create_Task(int far * taskID, TaskDefBlock  far * taskdefblock)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;


  inregs.h.ah   = RTX_TASK_CREATE;
  inregs.x.bx   = FP_SEG(taskID);
  inregs.x.si   = FP_OFF(taskID);
  segregs.es    = FP_SEG(taskdefblock);
  inregs.x.di   = FP_OFF(taskdefblock);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);

  //return errorcode
  return outregs.x.ax;

}

int RTX_Create_Task_Without_Run(int far * taskID, TaskDefBlock  far * taskdefblock)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;


  inregs.h.ah   = RTX_TASK_CREATE_WITHOUT_RUN;
  inregs.x.bx   = FP_SEG(taskID);
  inregs.x.si   = FP_OFF(taskID);
  segregs.es    = FP_SEG(taskdefblock);
  inregs.x.di   = FP_OFF(taskdefblock);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);

  //return errorcode
  return outregs.x.ax;

}


/*************************************************************************/
//Delete a task
/*************************************************************************/
int RTX_Delete_Task(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_TASK_DELETE;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Stop and kill a task
/*************************************************************************/
int RTX_Kill_Task(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_TASK_KILL;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Go to sleep for a defined time
/*************************************************************************/
int RTX_Sleep_Time(unsigned int time_ms)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_SLEEP_TIME;
  inregs.x.bx   = time_ms;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Go to sleep, until  wakerequest
/*************************************************************************/
int RTX_Sleep_Request(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_SLEEP_REQ;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Wakeup a sleeping task
/*************************************************************************/
int RTX_Wakeup(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_WAKEUP_TASK;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//End execution of task by itself, this functions never returns
/*************************************************************************/
int RTX_End_Execution(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_END_EXEC;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode, avoid compiler warning
  return outregs.x.ax;
}




/*************************************************************************/
//Change taskprio
/*************************************************************************/
int RTX_Change_TaskPrio(int taskID, int prio, int  far *error)
{
  union  REGS  inregs;
  union  REGS  outregs;

  *error = 0;
  inregs.h.ah   = RTX_CHANGE_PRIO;
  inregs.x.bx   = taskID;
  inregs.x.cx   = prio;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  if(outregs.x.dx!=0)
  {
	 *error =outregs.x.ax;
	 return outregs.x.dx;
  }
  return outregs.x.ax;
}


/*************************************************************************/
//Get the ID of the current running task
/*************************************************************************/
int RTX_Get_TaskID(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_GET_TASKID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}



/*************************************************************************/
//access filesystem
/*************************************************************************/
int RTX_Access_Filesystem(void)
{
  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_ACCESS_FILESYSTEM;
  int86(RTOSVECT,&inregs,&outregs);
//  if((int)outregs.x.dx==-3)  //fileaccess ok, but reserving dta entry
                               //for findfirst/next failed
  return outregs.x.dx;
}




/*************************************************************************/
//Get state of a task, using the taskmonitoring mode
/*************************************************************************/
int RTX_Get_Task_State(char * taskname, Task_StateData * taskdata, int * error)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  *error=0;

  inregs.h.ah   = RTX_GET_TASK_STATE;
  segregs.es    = FP_SEG(taskname);
  inregs.x.di   = FP_OFF(taskname);
  segregs.ds    = FP_SEG(taskdata);
  inregs.x.si   = FP_OFF(taskdata);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  if(outregs.x.dx!=0)
  {
    *error=outregs.x.ax;
    return outregs.x.dx;
  }
  //return taskid
  return outregs.x.ax;
}

/*************************************************************************/
//Get state of a task, without using taskmonitoring mode
/*************************************************************************/
int RTX_Get_Task_State_Ext(char * taskname, unsigned int * taskstate, int * error)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  *error=0;
  *taskstate=0;
  inregs.h.ah   = RTX_GET_TASK_STATE_EXT;
  segregs.es    = FP_SEG(taskname);
  inregs.x.di   = FP_OFF(taskname);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  if(outregs.x.dx!=0)
  {
    *error=outregs.x.ax;
    return outregs.x.dx;
  }
  *taskstate=outregs.x.bx;
  //return taskid
  return outregs.x.ax;
}


/*************************************************************************/
//Get task  list
/*************************************************************************/
int RTX_Get_Task_List(TaskList *tasklist, int length)
{
   union  REGS  inregs;
   union  REGS  outregs;
   struct SREGS segregs;

   inregs.h.ah   = RTX_GET_TASK_LIST;
   segregs.es    = FP_SEG(tasklist);
   inregs.x.di   = FP_OFF(tasklist);
   inregs.x.cx   = length;

   int86x(RTOSVECT,&inregs,&outregs,&segregs);
   //return list length
   return outregs.x.bx;
}

/*************************************************************************/
//Start taskmonitoring
/*************************************************************************/
void RTX_Start_Task_Monitor(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_START_TASK_MONITOR;
  int86(RTOSVECT,&inregs,&outregs);
}


/*************************************************************************/
//Start taskmonitoring
/*************************************************************************/
void RTX_Stop_Task_Monitor(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_STOP_TASK_MONITOR;
  int86(RTOSVECT,&inregs,&outregs);
}


/*************************************************************************/
//Suspend a  task
/*************************************************************************/
int RTX_Suspend_Task(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_SUSPEND_TASK;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Resume a  task
/*************************************************************************/
int RTX_Resume_Task(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_RESUME_TASK;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Restart a  task, killed with call 0x02
/*************************************************************************/
int RTX_Restart_Task(int taskID)
{
  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_RESTART_TASK;
  inregs.x.bx   = taskID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}




/*************************************************************************/
/*************************************************************************/
//Semaphore functions
/*************************************************************************/
/*************************************************************************/

/*************************************************************************/
//Create a semaphore
/*************************************************************************/
int RTX_Create_Sem(int far * semID, char  far * name, int initvalue)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;


  inregs.h.ah   = RTX_CREATE_SEM;
  inregs.x.bx   = FP_SEG(semID);
  inregs.x.si   = FP_OFF(semID);

  inregs.x.cx   = initvalue;

  segregs.es    = FP_SEG(name);
  inregs.x.di   = FP_OFF(name);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Delete a  semaphore
/*************************************************************************/
int RTX_Delete_Sem(int semID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_DELETE_SEM;
  inregs.x.bx   = semID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Free a  resource semaphore
/*************************************************************************/
int RTX_Free_Sem(int semID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_FREE_RES;
  inregs.x.bx   = semID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Get a  counting semaphore
/*************************************************************************/
int RTX_Get_Sem(int semID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_GET_SEM;
  inregs.x.bx   = semID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Release a  resoure semaphore
/*************************************************************************/
int RTX_Release_Sem(int semID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_RELEASE_SEM;
  inregs.x.bx   = semID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Reserve a  resoure semaphore (optional timeout)
/*************************************************************************/
int RTX_Reserve_Sem(int semID, long  far  * time_ms)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;
  inregs.h.ah   = RTX_RESERVE_RES;
  inregs.x.bx   = semID;
  segregs.es    = FP_SEG(time_ms);
  inregs.x.di   = FP_OFF(time_ms);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Signal a  counting semaphore
/*************************************************************************/
int RTX_Signal_Sem(int semID)
{
  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_SIGNAL_SEM;
  inregs.x.bx   = semID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}




/*************************************************************************/
//Wait on a  counting semaphore (optional timeout)
/*************************************************************************/
int RTX_Wait_Sem(int semID, long  far  * time_ms)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  inregs.h.ah   = RTX_WAIT_SEM;
  inregs.x.bx   = semID;
  segregs.es    = FP_SEG(time_ms);
  inregs.x.di   = FP_OFF(time_ms);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Find an semaphore, specified by 4 char name tag
/*************************************************************************/
int RTX_Find_Sem(int * ID, char * name)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  *ID=0;
  inregs.h.ah   = RTX_FIND_SEM;
  segregs.es    = FP_SEG(name);
  inregs.x.di   = FP_OFF(name);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  if(outregs.x.dx==0)
  {
    *ID = outregs.x.ax;
    return 0;
  }
  return outregs.x.ax;
}




/*************************************************************************/
/*************************************************************************/
//Time/Date functions
/*************************************************************************/
/*************************************************************************/

/*************************************************************************/
//Get system time and date
/*************************************************************************/
int RTX_Get_TimeDate(TimeDate_Structure  far * td)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_GET_TIMEDATE;
  inregs.x.bx   = FP_SEG(td);
  inregs.x.si   = FP_OFF(td);
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return 0;
}


/*************************************************************************/
//Set system time and date
/*************************************************************************/
int RTX_Set_TimeDate(TimeDate_Structure  far * td)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_SET_TIMEDATE;
  inregs.x.bx   = FP_SEG(td);
  inregs.x.si   = FP_OFF(td);
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return 0;
}

/*************************************************************************/
//Get tick count of system clock
/*************************************************************************/
void RTX_Get_System_Ticks(unsigned long far * ticks)
{

  union  REGS  inregs;
  union  REGS  outregs;
  inregs.h.ah   = RTX_GET_TICKS;
  inregs.x.bx   = FP_SEG(ticks);
  inregs.x.si   = FP_OFF(ticks);
  int86(RTOSVECT,&inregs,&outregs);
}


/*************************************************************************/
//Install timer procedure
/*************************************************************************/
int RTX_Install_Timer(TimerProc_Structure far * TProcPtr)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  inregs.h.ah   = RTX_INSTALL_TIMER;
  segregs.es    = FP_SEG(TProcPtr);
  inregs.x.di   = FP_OFF(TProcPtr);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Remove timer procedure
/*************************************************************************/
int RTX_Remove_Timer(unsigned int timerID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_REMOVE_TIMER;
  inregs.x.bx   = timerID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Start periodic execution of timer procedure
/*************************************************************************/
int RTX_Start_Timer(unsigned int timerID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_START_TIMER;
  inregs.x.bx   = timerID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Stop periodic execution of timer procedure
/*************************************************************************/
int RTX_Stop_Timer(unsigned int timerID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_STOP_TIMER;
  inregs.x.bx   = timerID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Create event group
/*************************************************************************/
int RTX_Create_EventGroup(unsigned int * ID, char * name, int init_value)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  inregs.h.ah   = RTX_CREATE_EVENTGROUP;

  inregs.x.bx   = init_value;
  segregs.es    = FP_SEG(ID);
  inregs.x.di   = FP_OFF(ID);
  segregs.ds    = FP_SEG(name);
  inregs.x.si   = FP_OFF(name);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);

  return outregs.x.ax;
}

/*************************************************************************/
//Delete an event group
/*************************************************************************/
int RTX_Delete_EventGroup(unsigned int ID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_DELETE_EVENTGROUP;
  inregs.x.bx   = ID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}

/*************************************************************************/
//Signal events group
/*************************************************************************/
int RTX_Signal_Events(unsigned int ID, unsigned int event_mask, unsigned event_value)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_SIGNAL_EVENTS;
  inregs.x.bx   = ID;
  inregs.x.cx   = event_mask;
  inregs.x.dx   = event_value;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}


/*************************************************************************/
//Wait for events
/*************************************************************************/
int RTX_Wait_For_Event(unsigned int ID, RTX_Wait_Event * event_ptr)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  inregs.h.ah   = RTX_WAIT_EVENTS;
  inregs.x.bx   = ID;
  segregs.es    = FP_SEG(event_ptr);
  inregs.x.di   = FP_OFF(event_ptr);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}


/*************************************************************************/
//Read current events on a group
/*************************************************************************/
int RTX_Get_EventGroup_State(unsigned int ID, unsigned int * Event)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  inregs.h.ah   = RTX_GET_EVENTGROUP_STATE;
  inregs.x.bx   = ID;
  segregs.es    = FP_SEG(Event);
  inregs.x.di   = FP_OFF(Event);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}

/*************************************************************************/
//Get the saved event flags/bits
/*************************************************************************/
int RTX_Get_Saved_Events(unsigned int * Event)
{
  union  REGS  inregs;
  union  REGS  outregs;

  *Event=0;
  inregs.h.ah   = RTX_GET_EVENT_FLAGS;
  int86(RTOSVECT,&inregs,&outregs);
  if(outregs.x.dx==0)
  {
    *Event = outregs.x.ax;
    return 0;
  }
  return outregs.x.ax;
}

/*************************************************************************/
//Find an event group, specified by 4 char name tag
/*************************************************************************/
int RTX_Find_EventGroup(unsigned int * ID, char * name)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  *ID=0;
  inregs.h.ah   = RTX_FIND_EVENTGROUP;
  segregs.es    = FP_SEG(name);
  inregs.x.di   = FP_OFF(name);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  if(outregs.x.dx==0)
  {
    *ID = outregs.x.ax;
    return 0;
  }
  return outregs.x.ax;
}


/*************************************************************************/
//Create message exchange
/*************************************************************************/
int RTX_Create_Msg(RTX_Msg * msg_ptr)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;
  inregs.h.ah   = RTX_CREATE_MSG;
  segregs.es    = FP_SEG(msg_ptr);
  inregs.x.di   = FP_OFF(msg_ptr);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}

/*************************************************************************/
//Delete a message exchange
/*************************************************************************/
int RTX_Delete_Msg(unsigned int ID)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_DELETE_MSG;
  inregs.x.bx   = ID;
  int86(RTOSVECT,&inregs,&outregs);
  //return errorcode
  return outregs.x.ax;
}



/*************************************************************************/
//Send a message to a message exchange
/*************************************************************************/
int RTX_Send_Msg(unsigned int ID, int prio, char * msg)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;
  inregs.h.ah   = RTX_SEND_MSG;
  inregs.x.bx   = ID;
  inregs.x.cx   = prio;
  segregs.es    = FP_SEG(msg);
  inregs.x.di   = FP_OFF(msg);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}




/*************************************************************************/
//Get a message from a message exchange, no wait
/*************************************************************************/
int RTX_Get_Msg(unsigned int ID, char * msg)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;
  inregs.h.ah   = RTX_GET_MSG;
  inregs.x.bx   = ID;
  segregs.es    = FP_SEG(msg);
  inregs.x.di   = FP_OFF(msg);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}



/*************************************************************************/
//Wait for a message, optional timeout
/*************************************************************************/
int RTX_Wait_For_Msg(RTX_Wait_Msg * msg_ptr)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;
  inregs.h.ah   = RTX_WAIT_MSG;
  segregs.es    = FP_SEG(msg_ptr);
  inregs.x.di   = FP_OFF(msg_ptr);
  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  return outregs.x.ax;
}


/*************************************************************************/
//Find an message exchange, specified by 4 char name tag
/*************************************************************************/
int RTX_Find_Msg(unsigned int * ID, char * name)
{
  union  REGS  inregs;
  union  REGS  outregs;
  struct SREGS segregs;

  *ID=0;
  inregs.h.ah   = RTX_FIND_MSG;
  segregs.es    = FP_SEG(name);
  inregs.x.di   = FP_OFF(name);

  int86x(RTOSVECT,&inregs,&outregs,&segregs);
  if(outregs.x.dx==0)
  {
    *ID = outregs.x.ax;
    return 0;
  }
  return outregs.x.ax;
}



/*************************************************************************/
//Disable Task Sheduling
/*************************************************************************/
void RTX_Disable_Task_Scheduling(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_DISABLE_TASK_SCHEDULING;
  int86(RTOSVECT,&inregs,&outregs);
  return;
}


/*************************************************************************/
//Enable Task Sheduling
/*************************************************************************/
void RTX_Enable_Task_Scheduling(void)
{
  union  REGS  inregs;
  union  REGS  outregs;

  inregs.h.ah   = RTX_ENABLE_TASK_SCHEDULING;
  int86(RTOSVECT,&inregs,&outregs);
  return;
}

/*************************************************************************/
//end rtos.c
/*************************************************************************/
