/*
   TSK.H - TCtask - Type definitions and global routine prototypes.

   V1.1   T.Wagner
   V1.2   TECON Ltd.
*/
/*
          - options switching parameter was added for snapshot().
          - tsk_dis_preempt(), tsk_ena_preempt() were added.
          - some bugs were corrected.
*/

#include "tcconf.h"
#include <stdio.h>
#include <dos.h>
#include <conio.h>


#define _Near near
#define local static      /* Comment out the "static" for debugging */

//************************* Œ®¥ **************************

#pragma aux MS_C "_*"                                  \
                 parm caller []                        \
                 value struct float struct routine [ax];\
//                 modify [ax bx cx dx es];

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

typedef unsigned char byte;
typedef unsigned short int word;
typedef short int word_s;
typedef unsigned long dword;
typedef void (*funcptr)();
typedef void far *farptr;
typedef void *nearptr;
typedef byte *byteptr;
typedef char *charptr;
typedef word *wordptr;

#define TTIMEOUT ((nearptr) -1L)
#define TWAKE    ((nearptr) -2L)

/* Task states */

#define  ST_KILLED   0
#define  ST_STOPPED  1
#define  ST_DELAYED  2
#define  ST_WAITING  3
#define  ST_ELIGIBLE 4
#define  ST_RUNNING  5

/* Task flags */

#define  F_TEMP   0x80     /* Task is temporary, free on kill */
#define  F_STTEMP 0x40     /* Task stack is temporary, free on kill */
#define  F_CRIT   0x01     /* Task is critical, may not be preempted */

#define  FL_SYSM  0xf0     /* Mask for system flags */
#define  FL_USRM  0x0f     /* Mask for user flags */

/* Timer queue element states */

#define  TSTAT_REMOVE      -1    /* Remove element from queue */
#define  TSTAT_IDLE        0     /* Not in queue */
#define  TSTAT_COUNTDOWN   1     /* Count down timeout, then remove */
#define  TSTAT_REPEAT      2     /* Count down, reload when done */

/* Timer queue element control structure pointer kinds */

#define  TKIND_TASK        1     /* tcbptr, Wakeup associated task */
#define  TKIND_WAKE        2     /* tcbptr, but not same task */
#define  TKIND_PROC        3     /* call function */
#define  TKIND_FLAG        4     /* flagptr, set flag */
#define  TKIND_COUNTER     5     /* counterptr, increment counter */

#define  TKIND_TEMP        0x80  /* Hi bit set means temporary element */

/* Name link structure types */

#define  TYP_TCB        1
#define  TYP_FLAG       2
#define  TYP_RESOURCE   3
#define  TYP_COUNTER    4
#define  TYP_MAILBOX    5
#define  TYP_PIPE       6
#define  TYP_WPIPE      7
#define  TYP_BUFFER     8

#define  NAMELENGTH     9  /* For structure names: 8 bytes + zero */

typedef struct name_rec *nameptr;

struct name_rec {
                nameptr    follow;        /* Next name in list */
                nameptr    prev;          /* Previous name in list */
                nearptr     strucp;        /* Top of structure pointer */
                byte       nkind;         /* Kind of structure */
                char       name [NAMELENGTH];
                };

typedef struct name_rec namerec;

typedef struct tcb_rec *tcbptr;
typedef tcbptr *tqueptr;

typedef struct tlink_rec *tlinkptr;

struct tlink_rec {
                  tlinkptr next;
                  dword    timeout;    /* Timeout counter */
                  dword    reload;     /* Timeout counter reload value */
                  nearptr   strucp;     /* Pointer to control structure */
                  byte     tstate;     /* Element state */
                  byte     tkind;      /* Kind of control structure */
                 };

typedef struct tlink_rec tlink;

struct tcb_rec {
                                   tcbptr   next;       /* Next in queue */
                                   tqueptr  queue;         /* Queue head pointer */
                                   charptr  stack;      /* Task stack */
                                   charptr  stkbot;     /* Task stack bottom */
                                   word     prior;      /* Task priority */
                                   word     initprior;  /* Initial Task priority */
               byte     state;      /* Task state */
               byte     flags;      /* Task flags */
               tlink    timerq;     /* Timer queue link */
               nearptr   retptr;     /* Event return pointer */
               word_s   retsize;    /* Return buffer size for pipes */
#if (TSK_NAMED)
               namerec  name;
#endif
                              };

typedef struct tcb_rec tcb;

typedef struct {
               tcbptr  wait_set;
               tcbptr  wait_clear;
               word_s  state;
#if (TSK_DYNAMIC)
               byte    flags;
#endif
#if (TSK_NAMED)
               namerec name;
#endif
               } flag;

typedef flag *flagptr;

typedef struct {
               tcbptr  wait_set;
               tcbptr  wait_clear;
               dword   state;
#if (TSK_DYNAMIC)
               byte    flags;
#endif
#if (TSK_NAMED)
               namerec name;
#endif
               } counter;

typedef counter *counterptr;

typedef struct {
               tcbptr   waiting;
               tcbptr   owner;
               word_s   state;
#if (TSK_DYNAMIC)
               byte     flags;
#endif
#if (TSK_NAMED)
               namerec  name;
#endif
               } resource;

typedef resource *resourceptr;

struct msg_header {
                  struct msg_header *next;
                  };

typedef struct msg_header *msgptr;

typedef struct {
               tcbptr  waiting;
               msgptr  mail_first;
               msgptr  mail_last;
#if (TSK_DYNAMIC)
               byte    flags;
#endif
#if (TSK_NAMED)
               namerec name;
#endif
               } mailbox;

typedef mailbox *mailboxptr;

typedef struct {
               tcbptr   wait_read;
               tcbptr   wait_write;
               tcbptr   wait_clear;
               word     bufsize;
               word     filled;
               word     inptr;
               word     outptr;
               byteptr  contents;
#if (TSK_DYNAMIC)
               byte     flags;
#endif
#if (TSK_NAMED)
               namerec  name;
#endif
               } pipe;

typedef pipe *pipeptr;

typedef struct {
               tcbptr   wait_read;
               tcbptr   wait_write;
               tcbptr   wait_clear;
               word     bufsize;
               word     filled;
               word     inptr;
               word     outptr;
               wordptr  wcontents;
#if (TSK_DYNAMIC)
               byte     flags;
#endif
#if (TSK_NAMED)
               namerec  name;
#endif
               } wpipe;

typedef wpipe *wpipeptr;

typedef struct {
               resource    buf_write;
               resource    buf_read;
               wpipe       pip;
               word        msgcnt;
#if (TSK_DYNAMIC)
               byte    flags;
#endif
#if (TSK_NAMED)
               namerec     name;
#endif
               } buffer;

typedef buffer *bufferptr;

extern void install_tasker (byte varpri, int speedup);
extern void remove_tasker (void);
extern void preempt_on (void);
extern void preempt_off (void);
extern void tsk_dis_preempt (void);        /***/
extern void tsk_ena_preempt (void);        /***/

extern void schedule (void);
extern tcbptr create_task (tcbptr task, funcptr func, charptr stack,
                               word stksz, word prior, nearptr arg
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void kill_task (tcbptr task);
extern word_s start_task (tcbptr task);
extern word_s wake_task (tcbptr task);
extern word get_priority (tcbptr task);
extern void set_priority (tcbptr task, word prior);

extern word_s t_delay (dword ticks);

extern tlinkptr create_timer (tlinkptr elem, dword tout, nearptr strucp,
                                  byte kind, byte rept);
extern void delete_timer (tlinkptr elem);
extern void change_timer (tlinkptr elem, dword tout, byte rept);

extern resourceptr create_resource (resourceptr rsc
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_resource (resourceptr rsc);
extern void release_resource (resourceptr rsc);
extern word_s request_resource (resourceptr rsc, dword timeout);
extern word_s c_request_resource (resourceptr rsc);
extern word_s check_resource (resourceptr rsc);

extern flagptr create_flag (flagptr flg
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_flag (flagptr flg);
extern void set_flag (flagptr flg);
extern void clear_flag (flagptr flg);
extern word_s clear_flag_wait_set (flagptr flg, dword timeout);
extern word_s wait_flag_set (flagptr flg, dword timeout);
extern word_s wait_flag_clear (flagptr flg, dword timeout);
extern word_s check_flag (flagptr flg);

extern counterptr create_counter (counterptr cnt
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_counter (counterptr cnt);
extern void clear_counter (counterptr cnt);
extern word_s wait_counter_set (counterptr cnt, dword timeout);
extern word_s wait_counter_clear (counterptr cnt, dword timeout);
extern void inc_counter (counterptr cnt);
extern dword check_counter (counterptr cnt);

extern mailboxptr create_mailbox (mailboxptr box
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_mailbox (mailboxptr box);
extern void send_mail (mailboxptr box, nearptr msg);
extern nearptr wait_mail (mailboxptr box, dword timeout);
extern nearptr c_wait_mail (mailboxptr box);
extern word_s check_mailbox (mailboxptr box);

extern pipeptr create_pipe (pipeptr pip, nearptr buf, word bufsize
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_pipe (pipeptr pip);
extern word_s read_pipe (pipeptr pip, dword timeout);
extern word_s c_read_pipe (pipeptr pip);
extern word_s write_pipe (pipeptr pip, byte ch, dword timeout);
extern word_s c_write_pipe (pipeptr pip, byte ch);
extern word_s wait_pipe_empty (pipeptr pip, dword timeout);
extern word_s check_pipe (pipeptr pip);
extern word pipe_free (pipeptr pip);

extern wpipeptr create_wpipe (wpipeptr pip, nearptr buf, word bufsize
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_wpipe (wpipeptr pip);
extern word read_wpipe (wpipeptr pip, dword timeout);
extern word c_read_wpipe (wpipeptr pip);
extern word_s write_wpipe (wpipeptr pip, word ch, dword timeout);
extern word_s c_write_wpipe (wpipeptr pip, word ch);
extern word_s wait_wpipe_empty (wpipeptr pip, dword timeout);
extern word check_wpipe (wpipeptr pip);
extern word wpipe_free (wpipeptr pip);

extern bufferptr create_buffer (bufferptr buf, nearptr pbuf, word bufsize
#if (TSK_NAMED)
                               ,charptr name
#endif
                               );
extern void delete_buffer (bufferptr buf);
extern word_s read_buffer (bufferptr buf, nearptr msg, word_s size, dword timeout);
extern word_s c_read_buffer (bufferptr buf, nearptr msg, word_s size);
extern word_s write_buffer (bufferptr buf, nearptr msg, word_s size, dword timeout);
extern word_s c_write_buffer (bufferptr buf, nearptr msg, word_s size);
extern word check_buffer (bufferptr buf);
extern void tfree (nearptr item);

extern word t_read_key (void);
extern word t_wait_key (dword timeout);
extern word t_keyhit (void);

extern word_s tsk_dis_int (void);
extern void tsk_ena_int (word_s);
extern void tsk_nop (void);

extern void tsk_outp (word port, byte b);        /***/
extern byte tsk_inp (word port);
extern void tsk_cli (void);
extern void tsk_sti (void);
extern void test (void);

//#define setx(x)  {tsk_outp(112,9);if(tsk_inp(113)>x)_asm{int 32}}

#define CRITICAL  word_s crit_intsav
#define C_ENTER   crit_intsav = tsk_dis_int()
#define C_LEAVE   tsk_ena_int (crit_intsav)

#if (TSK_DYNAMIC)
extern void tsk_init_pool (int s_size);          /***/
extern nearptr tsk_alloc (dword size);
extern void tsk_free (nearptr item);
extern resource alloc_resource;
#endif

#if (TSK_NAMED)
#define SN_NO_TASKS  0x01                    /***/
#define SN_NO_EVENTS 0x02                    /***/
#define SN_NO_POOL   0x04                                 /***/
extern nearptr find_name (charptr name, byte kind);
/*extern void snapshot (FILE *f, byte mask);*/            /***/
extern void snapshot ();            /***/
#endif

extern word _Near ticks_per_sec;
extern funcptr v24_remove_func;
extern farptr get_vect_d (byte);
extern void set_vect_d (byte, farptr);