/*-------------------------------------------------------------------------*
 *                          NTP.c  Source C                                * 
 *                          ~~~~~  ~~~~~~~~                                * 
 *                                                                         *
 *  Auteur     : Xavier Leclercq    pour "Le Petit Amiga illustré"         *
 *                                                                         *
 *  But du jeu : UTILISER LES STRUCTURES DE TYPE "LIST" DE L'exec.library  *
 *                                                                         *
 *  FUNCTION		NTP <Taskname> <New_Priority> [o]                  *
 *                                                                         *
 *  EXAMPLE             NTP AT -110                                        *
 *                                                                         *
 *  NOTES		type NTP ? for help                                *
 *                                                                         *
 *  BUGS                /                                                  *
 *                                                                         *
 *-------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------*
 *    NTP se balade dans la structure "list" des "tasks" du système         *
 *--------------------------------------------------------------------------*/

#include <stdio.h>
#include <strings.h>
#include <exec/execbase.h>
#include <exec/memory.h>

/*--------------------------------------------------------------------------*/

#define  BOLD      "\x9b1;31;40m"
#define  ITALIC    "\x9b3;31;40m"
#define  SOULIGNE  "\x9b4;31;40m"
#define  INVERSE   "\x9b7;31;40m"
#define  NORMAL    "\x9b0;31;40m"
#define  COPYRIGHT "\xa9"
#define  FALSE     0x0L

/*--------------------------------------------------------------------------*/

extern struct ExecBase *SysBase;
struct Task *ptrtask = NULL, *a_task = NULL;
char   *etat[]={"TS_INVALID","TS_ADDED","TS_RUNNING","TS_READY","TS_WAITING",
"TS_EXCEPTION","TS_REMOVED"};
char *type[]={"NT_UNKNOW","NT_TASK","NT_INTERRUPT","NT_DEVICE","NT_MSGPORT",
"NT_MESSAGE","NT_FREEMSG","NT_REPLYMSG","NT_RESOURCE","NT_LIBRARY",
"NT_MEMORY","NT_SOFTINT","NT_FONT","NT_PROCESS","NT_SEMAPHORE","NT_SIGNALSEM",
"NT_BOOTNODE","NT_KICKMEM","NT_GRAPHICS","NT_DEATHMESSAGE","NT_USER",
"NT_EXTENDED"};
long int run,tnodes[100],*Anode=tnodes,wtask,ltask;
void Affiche(struct Task *ptrtask);

/*--------------------------------------------------------------------------*/

void CopyRight()
{
  printf("%sNTP%s",BOLD,NORMAL);
  printf(" v1.1  by %sXavier Leclercq%s\n"\
  "%s12 Vieux Chemin d'Ath B-7548"\
  " Warchin BELGIUM%s\n",BOLD,NORMAL,ITALIC,NORMAL);
  printf("     %sType NTP ? for HELP%s\n",SOULIGNE,NORMAL);
  printf("\n");
}

/*--------------------------------------------------------------------------*/

void Affiche(struct Task *ptrtask)
{
  int i;
  printf("struct Task { \n");
  printf("  struct  Node tc_Node { \n");
  printf("    struct  Node *ln_Succ\n");
  printf("    struct  Node *ln_Pred\n");
  i=ptrtask->tc_Node.ln_Type;
  if (i>253) i-=234;
  printf("    UBYTE   ln_Type      : %s\n",type[i]);
  printf("    BYTE    ln_Pri       : %d\n",ptrtask->tc_Node.ln_Pri);
  printf("    char    *ln_Name     : %s\n",ptrtask->tc_Node.ln_Name);
  printf("    }\n");
  printf("UBYTE   tc_Flags     : %08x\n",ptrtask->tc_Flags);
  i=ptrtask->tc_State;
  if (i>253) i-=234;
  printf("UBYTE   tc_State     : %s\n",etat[i]);
  printf("BYTE    tc_IDNestCnt : %08x\n",ptrtask->tc_IDNestCnt);
  printf("BYTE    tc_TDNestCnt : %08x\n",ptrtask->tc_TDNestCnt);
  printf("ULONG   tc_SigAlloc  : %08x\n",ptrtask->tc_SigAlloc);
  printf("ULONG   tc_SigWait   : %08x\n",ptrtask->tc_SigWait);   
  printf("ULONG   tc_SigRecvd  : %08x\n",ptrtask->tc_SigRecvd);
  printf("ULONG   tc_SigExcept : %08x\n",ptrtask->tc_SigExcept);
  printf("UWORD   tc_TrapAlloc : %08x\n",ptrtask->tc_TrapAlloc);
  printf("UWORD   tc_TrapAble  : %08x\n",ptrtask->tc_TrapAble);
  printf("APTR    tc_ExceptData: %08x\n",ptrtask->tc_ExceptData);
  printf("APTR    tc_ExceptCode: %08x\n",ptrtask->tc_ExceptCode);
  printf("APTR    tc_TrapData  : %08x\n",ptrtask->tc_TrapData);
  printf("APTR    tc_TrapCode  : %08x\n",ptrtask->tc_TrapCode);
  printf("APTR    tc_SPReg     : %08x\n",ptrtask->tc_SPReg);
  printf("APTR    tc_SPLower   : %08x\n",ptrtask->tc_SPLower);
  printf("APTR    tc_SPUpper   : %08x\n",ptrtask->tc_SPUpper);
  printf("VOID  (*tc_Switch)() : %08x\n",ptrtask->tc_Switch);
  printf("VOID  (*tc_Launch)() : %08x\n",ptrtask->tc_Launch);
  printf("struct  List tc_MemEntry \n");	   
  printf("APTR    tc_UserData  : %08x\n",ptrtask->tc_UserData);
  printf("}\n");
}   

/*--------------------------------------------------------------------------*
 *
 * fonction principale : main()
*/

main(int argc,char *argv[])
{
  char StructCmp[80],StructCmp2[80],*ptr,rep[80],keyb[80];
  int i,j,n,siarg;
  signed int pri,PriOld;	
  do {
  for (j=0;j<80;StructCmp[j]=0,StructCmp2[j]=0,keyb[j]=0,j++);
/*
 * Pas d'argument ?
*/
  if (argc < 2) {
    printf("\f");
    CopyRight();
    printf("\nAmiga Task name ? "),gets(keyb);
    for (ptr=keyb,j=0;*ptr;StructCmp[j]=*ptr,ptr++,j++);
    for (ptr=keyb,j=0;*ptr;StructCmp2[j]=tolower(*ptr),ptr++,j++);
    ptr=keyb;
  }
  else {
    if (argc <= 3) {
      CopyRight();
    }
    ptr=argv[1];
  } 
/*
 * Si l'argument est un "?" on affiche l'aide....
*/
    if (*ptr=='?') {
      printf("\t\t\tNTP means Name Task Priority...\n"\
"       Type    : NTP <Amiga_task_Name> <new_priority> [O]\n\n"\
"                 Examples: \n"\
"                 ========= \n\n"\
"          NTP  AT  -110              ;Set ©Atonce_Task to -110...\n"\
"          NTP  ALL                   ;Show all tasknames available\n"\
"          NTP                        ;enter Arguments with your keyboard\n"\
"          NTP  trackdisk.device 5    ;is a  good  input  \n"\
"          NTP  TRackDISk.DEVICE 5    ;is an input error !\n"\
"          NTP  DF1 10                ;The new priority of DF1 is now = 10\n"\
"          NTP  DF0 8 O               ;OutPut OFF (=~ NTP DF0 8 >NIL:)\n"\
"          NTP  input.device 15 >prt: ;OutPut to printer\n"\
      "\n");
      exit(0);  
    }
   
/*
 * Recherche le premier argument
*/
  for(ptr=argv[1],j=0;*ptr;keyb[j]=*ptr,ptr++,j++);
  for(keyb[j]=0,ptr=argv[1],j=0;*ptr;StructCmp[j]=*ptr,ptr++,j++);
  for(keyb[j]=0,ptr=argv[1],j=0;*ptr;StructCmp2[j]=tolower(*ptr),ptr++,j++);
/*
 * Option ALL : afficher toutes les tâches...
*/
  n=strncmp(StructCmp2,"all",3); 
  if (n==0) {
    if (argc == 2) siarg=1;
    Anode=tnodes; 
    run=(long int)SysBase->ThisTask;
    Disable();
    for(a_task=(struct Task*)SysBase->TaskReady.lh_Head;
      a_task->tc_Node.ln_Succ;
      *Anode=(long int)a_task,Anode++,
      a_task=a_task->tc_Node.ln_Succ);
    wtask=Anode;
    for(a_task=(struct Task*)SysBase->TaskWait.lh_Head;
      a_task->tc_Node.ln_Succ;
      *Anode=(long int)a_task,Anode++,
      a_task=a_task->tc_Node.ln_Succ);
    ltask=Anode;
    Enable();
    ptrtask=(struct Task *)run;
    Affiche(ptrtask);
    for(Anode=(long int*)tnodes;Anode!=(long int*)wtask;
        Affiche((struct Task*)*Anode),Anode++);
    for(;Anode!=(long int*)ltask;
        Affiche((struct Task*)*Anode),Anode++);
  }
  else {
    if (argc < 3) {
    printf("New Priority    ? "),scanf("%d",&pri),gets(rep);
    siarg=0;
    }
    else {
      pri=atoi(argv[2]);
      siarg=1;
    }
    ptrtask=(struct Task *)FindTask(StructCmp);
    if (ptrtask==0) {
      if (argc <=3) printf("%sTask unknow!%s\n",INVERSE,NORMAL);    
    }
    else {
      if (argc <= 3 || siarg==0) {
        Affiche(ptrtask);  
      } 
     PriOld=SetTaskPri(ptrtask,pri);
     if (PriOld > 127 ) PriOld-=256;
     if (argc <= 3) 
       printf("Old priority = %d        New priority = %d\n",PriOld,pri);
     }
  }
  if (siarg==1) exit(0);
  printf("\nQuit ? (Y/N) "),gets(rep),argc=0;
  } while(rep[0]=='N'||rep[0]=='n'); 
  exit(0);
}
