/*
   TCLOCAL.H - TCtask - Internal definitions and prototypes.

   V1.1   T.Wagner
   V1.2   TECON Ltd.
*/
/*
   - poolrec structure was added for dynamic memory allocation.
*/
/*
   struct task_stack describes the contents of a tasks stack after creation.
   The first 10 words are the registers to be restored by the scheduler.
   Only the segment registers are significant initially.
   The next three words contain the function address plus the CPU flags
   setup as if an interrupt had occurred at the function's entry address.

   This setup is the same as the stack of an interrupted task after
   scheduling.

   The following two words contain a dummy return address, which points
   to the routine "killretn()". Thus, if the task main function should ever
   return, the task is automatically killed. The last doubleword is
   used for the optional argument to the task.
*/

struct task_stack {
                  word     r_es;
                  word     r_ds;
                  word     r_gs;
                  word     r_fs;
                  dword    r_edi;
                  dword    r_esi;
                  dword    r_ebp;
                  dword    r_ebx;
                  dword    r_edx;
                  dword    r_ecx;
                  dword    r_eax;
                  funcptr  r_eip;
                  dword    r__cs;         //[ ]CS
//                  funcptr  retn;
                  dword    r_eflags;
                  funcptr  dummyret;
//                  nearptr   arg;
                  };

extern tcbptr     _Near tsk_eligible;
extern tcbptr     _Near tsk_current;
extern tlinkptr   _Near tsk_timer;
extern byte       _Near tsk_preempt;
extern byte       _Near tsk_pretick;

#if (CLOCK_MSEC)
extern dword tsk_timeout (dword tout);
extern double tick_factor;
#else
#define tsk_timeout(tout)  tout
#endif

extern void tsk_enqueue (tcbptr task, tqueptr que);
extern void tsk_unqueue (tcbptr task);
extern void tsk_enqtimer (tcbptr task, dword tout);

extern void tsk_kill (tcbptr task);
extern void tsk_kill_queue (tqueptr que);

extern void tsk_install_timer (word divisor, word sys_ticks);
extern void tsk_remove_timer (void);
extern void tsk_install_dos (void);
extern void tsk_remove_dos (void);
extern void tsk_install_kbd (void);
extern void tsk_remove_kbd (void);
//#pragma aux (MS_C) tsk_chain_timer;
//extern void tsk_chain_timer (void);

//#pragma aux (MS_C) tsk_install_bios;
//extern void tsk_install_bios (void);
//#pragma aux (MS_C) tsk_remove_bios;
//extern void tsk_remove_bios (void);

extern word tsk_dseg (void);
extern word tsk_cseg (void);
extern dword tsk_flags (void);

extern tcbptr tsk_runable (tcbptr task);
extern void tsk_wakeup (tcbptr task);
extern void tsk_wait (tqueptr que, dword timeout);


/*
   tsk_unqtimer
      Marks a task for removal from the timer queue.
*/

#define tsk_unqtimer(task) { if (task->timerq.tstate != TSTAT_IDLE) \
                                task->timerq.tstate = (byte) TSTAT_REMOVE; }

#if (TSK_NAMED)
extern namerec tsk_name_list;
extern void tsk_add_name (nameptr elem, charptr name, byte kind, nearptr strucp);
extern void tsk_del_name (nameptr elem);
#endif

#if (TSK_DYNAMIC)                                    /***/
typedef struct pool_rec *poolptr;
struct pool_rec
{
        dword size;      /* including sizeof(poolrec)  and flag FREE */
        poolptr next;
        poolptr prev;
};
typedef struct pool_rec poolrec;
#endif