#include "custom.h"

/* ////////////////////////////////////////////////////////////////////
   Common defines

///////////////////////////////////////////////////////////////////// */


/* ///////////// no time slice if not defined ////////////////////// */

#ifndef TIME_SLICE
#define TIME_SLICE               9
#endif

#ifndef MAX_TIMERS
#define MAX_TIMERS               9
#endif

/* ///////////// System Events ///////////////////////////////////// */

/** removed **
#ifndef LAST_EVENT
#define LAST_EVENT               64
#endif
**/

#define BITS_PER_INT             (8 * sizeof(int ))
#define TOTAL_USER_EVENT_ALLOC   ((LAST_EVENT + BITS_PER_INT - 1)/BITS_PER_INT)
#define FIRST_SYS_EVENT          (BITS_PER_INT * TOTAL_USER_EVENT_ALLOC)


enum {
   KEYBOARD_WAIT = FIRST_SYS_EVENT,     /* -- keep this entry alone -- */
   COM1_RCV_WAIT,
   COM2_RCV_WAIT,
   LAST_SYSTEM_EVENT
   }; //systemEvents;

#define TOTAL_SYS_EVENT_ALLOC    ((LAST_SYSTEM_EVENT - FIRST_SYS_EVENT + BITS_PER_INT - 1)/BITS_PER_INT)
#define MAX_EVENT_ALLOC          ((TOTAL_USER_EVENT_ALLOC + TOTAL_SYS_EVENT_ALLOC))
#define TOTAL_EVENTS             ((BITS_PER_INT * MAX_EVENT_ALLOC))


/* ///////////// Other Defines ///////////////////////////////////// */

#define NULL                     0L
#define FALSE                    0
#define TRUE                     1

#define PERIODIC                 1
#define ONE_SHOT		 0

#define Q_EVENT                  1

#define CURR_TASK                0L             /* indicates current task */
#define CURRENT_TASK             CURR_TASK      /* indicates current task */
#define CURRENTTASK              CURR_TASK      /* indicates current task */

#define NO_ARGUMENT              NULL

#define event                    unsigned int   /* event flags stored in unsigned ints */
#define far_address(s, p)     (void far *)((unsigned long)(((unsigned long)(s) << 16)) + (unsigned long)(p))
extern unsigned long far * far SystemClock;


/* ///////////// Ticks ///////////////////////////////////////////// */

#define TICKS_PER_SECOND         291   //18
#define TICKS_PER_MINUTE         1092
#define TICKS_PER_HOUR          (unsigned)(1092 * 60 )
#define ONE_SECOND               18L               /* one second */
#define TEN_SECOND		 180L


/* ////////////////////////////////////////////////////////////////////
   Error Codes

///////////////////////////////////////////////////////////////////// */

#define SUCCESS                  0
#define FAILURE                  SUCCESS - 1
#define ERR_TASKALLOC_FULL       SUCCESS - 1
#define ERR_TIMERID_NOTFOUND     SUCCESS - 2
#define ERR_INVALID_ADDRESS      SUCCESS - 3
#define ERR_INVALID_EVENTID      SUCCESS - 4

/* ////////////////////////////////////////////////////////////////////
   Generalized related Queue Structures

//////////////////////////////////////////////////////////////////// */
#define MAX_Qs   32  //mamimum number of unprocessed queue items
#define NO_Qs   255  //flags that no queue item was available or allocated

typedef struct QueuePtr {
    struct QueuePtr * next;
    } QueuePtr;

typedef struct Queue {
   void far *head;
   void far *tail;
   } Queue;

typedef struct Q_Item {
   QueuePtr far *next;
   char far *text;
   } Q_Item;


/* ////////////////////////////////////////////////////////////////////
   Task Structure
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   This control structure defines a task.  When a task is suspended,
   all of the registers including instruction address, flags, etc...
   are stored in the task's stack and the suspended bit is set.  The
   suspended bit indicates that the stack contains registers to pop
   before starting the task.

///////////////////////////////////////////////////////////////////// */

typedef struct Task {
      unsigned         suspended:1;
      unsigned         free:1;

      unsigned long    sleep;
      unsigned long    time_slice;
      unsigned long    time_slice_interval;
      event            events[ MAX_EVENT_ALLOC ];
      event            startup_event;

      void far *       init_stack_addr;
      void far *       curr_stack_addr;
      void far *       queue_event;
      Queue            list;
      int              stack_size;
      int              priority;
      char             task_name [ MAX_TASK_NAME ];
      } Task;


/* ////////////////////////////////////////////////////////////////////
   Watch-Dog Timers
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

   Timers are set by setTimer() and cleared by clearTimer() functions.
   When set, the number of tenths of seconds in the wait_value is
   decremented to zero.  When it does, the timer re-arms itself by
   reloading orig_value to wait_value and calls the action() function.

/////////////////////////////////////////////////////////////////////  */

typedef struct {                    /* timer structure */
      unsigned long    wait_value;
      unsigned long    orig_value;
      int (pascal *action)  ( void far * arg );
      void far       * argument;
      } Timer;


/* ////////////////////////////////////////////////////////////////////
    Time Of Day
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   
   Time of day structure used to insure time of day is represented in a
   common form as this package is moved from processor to processor.

///////////////////////////////////////////////////////////////////// */

typedef struct {
      int              hour;
      int              minute;
      int              second;
      } timeofday;


/* ////////////////////////////////////////////////////////////////////
    Function Prototypes

///////////////////////////////////////////////////////////////////// */

/* -- general prototypes -------------------------------------------- */

void pascal initTaskSystem(void );
void pascal restore_IntTraps(void );

void pascal scheduler(void );
void pascal enableInts(void );
void pascal condenableInts(int );
int pascal disableInts(void );

extern void pascal enableSched(void );
extern void pascal disableSched(void );

extern Timer far Counters[];
extern Task far * far currentTask;
extern Task far Tasks[];
extern event SystemEvents[];

extern int far actual_tasks;
extern int far actual_timers;
extern unsigned long far * far SystemClock;

/* -- serial port related prototypes -------------------------------- */
#ifndef DISABLED
#define DISABLED    0L
#endif

#ifndef ENABLED
#define ENABLED     1L
#endif

enum baudRates {
   b50 = 0,
   b75, b110, b134, b150, b300, b600, b1200,
   b1800, b2000, b2400, b3600, b4800, b7200,
   b9600,  b14400,  b19200,  b28800, b38400,
   b57600, b115200 };  //serial port baud rates

enum  commConsts {
      d5 = 0x00, d6 = 0x01, d7 = 0x02, d8 = 0x03,
      s1 = 0x00, s2 = 0x04,
      pN = 0x00, pO = 0x08, pE = 0x18, pM = 0x28, pS = 0x38 };

int pascal RS232_ini( int Port, int portControl ); //low level

int pascal port_IRQ( int Port, int IRQ_status );   //low level

int enablePortIRQ( int Port );
int diaablePortIRQ( int Port );

int init_SerialPort( int Port,
		       char Baud,
		       char Parity,
		       char DataBits,
		       char StopBits );

int pascal getComBuffer(int Port);
int pascal get_8250(int Port);
int pascal put_8250(int Port,int sendChar);
int pascal crlf_8250(int Port);
void pascal comPutChar(void);


/* -- event related prototypes -------------------------------------- */
int pascal clearSystemEvent( event event_id );
int pascal defineEventFct( event event_id,
		    int (pascal *start_addr) (event event_id, void far * arg ),
		    void far * argument );

event pascal getActiveEvent(Task far * task );
int pascal setSystemEvent( event event_id );
int pascal toggleSystemEvent( event event_id );
int pascal waitEvent(Task far * task, event event_id );


/* -- task related prototypes --------------------------------------- */
Task far * pascal defineTask(int (pascal *start_addr) (void far * arg ),
			     void far * argument,
			     unsigned stack_size,
			     int priority,
			     char far * task_name );

Task far * pascal findTask(char far *name);

int pascal sleepTask(Task far * task, int ticks );
int pascal sleepTill(Task far * task, long time_of_day );
int pascal suspendTask(Task far * task, int cond );
int pascal terminateTask(Task far * task );
int pascal terminateTask_id(int task_id );

int pascal getPriority(Task far * ptr );
int pascal setPriority(Task far * ptr, int prio );


/* -- queue event prototypes ---------------------------------------- */

int pascal queueEvent(Task far * task, void far *ptr );
void far * pascal getnext_queueEvent(Task far * task );
void far * pascal isnext_queueEvent(Task far * task );
int pascal queueMessage(Task far * task, char far *text);


/* -- timer related prototypes -------------------------------------- */

int pascal clearTimer(int timer_id );

int pascal clearTimer_id(int timer_id );

int pascal setTimer_id( int timer_id, unsigned flag,
                 unsigned long init_value,
		 int (pascal *action)(void far * arg ),
		 void far * argument );

int pascal setTimer( unsigned flag,
		 unsigned long init_value,
		 int (pascal *action)(void far * arg ),
		 void far * argument );



