home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / programs / monitors / perfmeter / perfmeter.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  20KB  |  728 lines

  1. ;/*    PerfMeter by Digital Design, Inc.
  2.  
  3. lc -j73 -v -y -ba perfmeter.c
  4. blink lib:cback.o+perfmeter.o to perfmeter lib lib:lc.lib+lib:amiga.lib
  5. quit
  6.  
  7.     Author:        Juha 'Comm' Tuominen / Digital Design
  8.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  9.     Released:    15-Jul-91    v1.10
  10.     Revised:    07-Sep-91    v1.11
  11.     Revised:    08-Sep-91    v1.12
  12.     Revised:    18-Sep-91    v1.2    (needs KS2.0 now)
  13.     Revised:    19-Oct-91    v1.21    (uptime bug fixed)
  14.     Revised:    04-Nov-91    v2.0    (major bug fixing)
  15.     Revised:    25-Nov-92    v2.1    (small bug fix)
  16.     Revices:    03-Dec-92    v2.2    (extented font support)
  17.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  18.     Compiler:    SAS/C v5.10->
  19.     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  20. */
  21.  
  22. #include <exec/types.h>
  23. #include <exec/memory.h>
  24. #include <exec/execbase.h>
  25. #include <exec/tasks.h>
  26. #include <libraries/dos.h>
  27. #include <devices/timer.h>
  28. #include <intuition/intuitionbase.h>
  29. #include <libraries/diskfont.h>
  30. #include <graphics/rastport.h>
  31. #include <graphics/gfx.h>
  32. #include <graphics/gfxbase.h>
  33. #include <graphics/gfxmacros.h>
  34. #include <graphics/text.h>
  35. #include <proto/all.h>
  36. #include <string.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39.  
  40. #define STACK_SIZE 1000L    /* Arska's stack size */
  41.  
  42. #define NAME         "Perfmeter"
  43. #define VERSION        2
  44. #define REVISION    2
  45. #define DATE        "02.12.92"
  46. #define VERS        "Perfmeter 2.2"
  47. #define VSTRING        "PerfMeter 2.2 (03.12.92)\n\0"
  48. #define VERSTAG        "\0$VER: Perfmeter 2.2 (03.12.92)\0"
  49.  
  50. #define FONTSIZE 8
  51. #define FONTNAME "blob.font"
  52.  
  53. #define WINDOWWIDTH        172
  54. #define WINDOWHEIGTH    130
  55.  
  56. long _stack=16384;
  57. char *_procname=VSTRING;
  58. long _priority=5;
  59. long _BackGroundIO=FALSE;
  60.  
  61. void MemCleanup() {}
  62.  
  63. UBYTE    versiontag[]=VERSTAG;    /* for version command */
  64.  
  65. BOOL    task_added=FALSE,zipped=FALSE,oldzipped=FALSE,timeropen=FALSE,timeropen2=FALSE,
  66.         keepgoing=TRUE,time_requested=FALSE,time_requested2=FALSE;
  67. ULONG    maxchip, maxfast, freechip=0, freefast=0,maxpub,freepub,cputime=NULL,
  68.         cputemp=NULL,prevcpu=68,count=0,chipscale=0, fastscale=0, publicscale=0,
  69.         jakaja=0,cputemp2=0,tag1;
  70. char    processor[10]="68000",*taskname="Arska Väijy",itemname[10]="  Idle";
  71. int        cpuload=0,mode=0,oldmode=1,buffer[7][151],load=0,switchcount=0,upsecs=0,
  72.         upmins=0,uphours=0,updays=0,oldi=0,offset;
  73. UBYTE    xc[]={5,5,5,5,5,5,6,6,6,7,7,7,8,8,9,9,10,11,11,12,13,13,14,15,16,17,18,19,20,20,21,23,24,25,26,27,28,29,30,31,33,34,35,36,38,39,40,41,42,44,45,46,48,49,50,51,52,54,55,56,57,59,60,61,62,63,64,65,66,67,69,70,70,71,72,73,74,75,76,77,77,78,79,79,80,81,81,82,82,83,83,83,84,84,84,85,85,85,85,85,85},
  74.         yc[]={45,46,48,49,50,51,52,54,55,56,57,59,60,61,62,63,64,65,66,67,69,70,70,71,72,73,74,75,76,77,77,78,79,79,80,81,81,82,82,83,83,83,84,84,84,85,85,85,85,85,85,85,85,85,85,85,84,84,84,83,83,83,82,82,81,81,80,79,79,78,77,77,76,75,74,73,72,71,70,70,69,67,66,65,64,63,62,61,60,59,57,56,55,54,52,51,50,49,48,46,45},
  75.         xx[]={15,15,15,15,15,15,15,15,15,16,16,16,16,17,17,17,18,18,18,19,19,20,20,21,21,22,22,23,24,24,25,26,26,27,28,29,29,30,31,32,33,33,34,35,36,37,38,39,40,40,41,42,43,44,45,46,47,48,49,49,50,51,52,53,54,55,56,56,57,58,59,60,60,61,62,63,63,64,65,66,66,67,67,68,69,69,70,70,71,71,72,72,72,73,73,73,74,74,74,74,74,75,75,75,75,75,75,75,75,75},
  76.         yy[]={43,44,45,46,47,48,49,49,50,51,52,53,54,55,56,56,57,58,59,60,60,61,62,63,63,64,65,66,66,67,67,68,69,69,70,70,71,71,72,72,72,73,73,73,74,74,74,74,74,75,75,75,75,75,75,75,75,75,75,75,75,74,74,74,74,73,73,73,72,72,72,71,71,70,70,69,69,68,68,67,66,66,65,64,64,63,62,61,61,60,59,58,57,57,56,55,54,53,52,51,50,50,49,48,47,46,45,44,43,43};
  77. APTR    stack=NULL;
  78. WORD    cordinates[]={0,0,100,65};    /* zipped window cordinates and size */
  79.  
  80.                                                                                
  81. extern    struct ExecBase    *SysBase;
  82. struct    IntuitionBase *IntuitionBase=NULL;
  83. struct    Library *DiskfontBase=NULL;
  84. struct    Window *window=NULL;
  85. struct    IntuiText abouttext[];
  86. struct    IntuiText proceed;
  87. struct    GfxBase *GfxBase=NULL;
  88. struct    MsgPort *timerport=NULL;
  89. struct    timerequest *timermsg=NULL;
  90. struct    MsgPort *timerport2=NULL;
  91. struct    timerequest *timermsg2=NULL;
  92. struct    Task *task=NULL;
  93. struct    TextFont *textfont;
  94.  
  95. struct    NewWindow mywindow =
  96. {    420,
  97.     14,
  98.     WINDOWWIDTH,
  99.     WINDOWHEIGTH,
  100.     0,1,
  101.     CLOSEWINDOW | MENUPICK | NEWSIZE,
  102.     SMART_REFRESH | WINDOWDRAG | WINDOWCLOSE | WINDOWDEPTH,
  103.     NULL,
  104.     NULL,
  105.     "Perfmeter",
  106.     NULL,
  107.     NULL,
  108.     140,
  109.     90,
  110.     NULL,
  111.     NULL,
  112.     WBENCHSCREEN
  113.  
  114. };
  115.  
  116. struct TagItem tagitems[2]={
  117.     {WA_Zoom,&cordinates},
  118.     {0,}
  119. };
  120.  
  121.  
  122. struct TextAttr TOPAZ80 = {(STRPTR)"topaz.font",TOPAZ_EIGHTY,0,0};
  123.  
  124. struct IntuiText abouttext[9] =
  125. {
  126.     {2,1,JAM1,8, 4,(struct TextAttr *)&TOPAZ80,(UBYTE *)VERS,(struct IntuiText *)&abouttext[1]},
  127.     {2,1,JAM1,8,14,(struct TextAttr *)&TOPAZ80,(UBYTE *)"by Juha Tuominen",(struct IntuiText *)&abouttext[2]},
  128.     {2,1,JAM1,8,22,(struct TextAttr *)&TOPAZ80,(UBYTE *)"Copyright © 1992",(struct IntuiText *)&abouttext[3]},
  129.     {2,1,JAM1,8,30,(struct TextAttr *)&TOPAZ80,(UBYTE *)"Digital Design, Inc.",(struct IntuiText *)&abouttext[4]},
  130.     {2,1,JAM1,8,38,(struct TextAttr *)&TOPAZ80,(UBYTE *)" ",(struct IntuiText *)&abouttext[5]},
  131.     {2,1,JAM1,8,46,(struct TextAttr *)&TOPAZ80,(UBYTE *)"Average 88100 load: 0   %",(struct IntuiText *)&abouttext[6]},
  132.     {2,1,JAM1,8,54,(struct TextAttr *)&TOPAZ80,(UBYTE *)" ",(struct IntuiText *)&abouttext[7]},
  133.     {2,1,JAM1,8,62,(struct TextAttr *)&TOPAZ80,(UBYTE *)"Arska Väijy has found",(struct IntuiText *)&abouttext[8]},
  134.     {2,1,JAM1,8,70,(struct TextAttr *)&TOPAZ80,(UBYTE *)"0 perfect numbers.",(struct IntuiText *)NULL}
  135. };
  136.  
  137. struct IntuiText proceed=
  138. {
  139.     2,1,JAM1,5,3,(struct TextAttr *)&TOPAZ80,(UBYTE *)"Continue",(struct IntuiText *)NULL
  140. };
  141.  
  142. /* This menu isn't visually beatufull but do just fine for this program */
  143.  
  144. struct IntuiText IText1={0,1,JAM1,0,0,&TOPAZ80,"Quit",NULL};
  145. struct MenuItem MenuItem9={NULL,0,64,58,8,ITEMTEXT+ITEMENABLED+HIGHBOX,0,(APTR)&IText1,NULL,NULL,NULL,MENUNULL};
  146. struct IntuiText IText2={0,1,JAM1,0,0,&TOPAZ80,"Switch",NULL};
  147. struct MenuItem MenuItem8={&MenuItem9,0,56,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText2,NULL,NULL,NULL,MENUNULL};
  148. struct IntuiText IText3={0,1,JAM1,0,0,&TOPAZ80,"Public",NULL};
  149. struct MenuItem MenuItem7={&MenuItem8,0,48,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText3,NULL,NULL,NULL,MENUNULL};
  150. struct IntuiText IText4={0,1,JAM1,0,0,&TOPAZ80,"Fast",NULL};
  151. struct MenuItem MenuItem6={&MenuItem7,0,40,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText4,NULL,NULL,NULL,MENUNULL};
  152. struct IntuiText IText5={0,1,JAM1,0,0,&TOPAZ80,"Chip",NULL};
  153. struct MenuItem MenuItem5={&MenuItem6,0,32,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText5,NULL,NULL,NULL,MENUNULL};
  154. struct IntuiText IText6={0,1,JAM1,0,0,&TOPAZ80,"Load",NULL};
  155. struct MenuItem MenuItem4={&MenuItem5,0,24,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText6,NULL,NULL,NULL,MENUNULL};
  156. struct IntuiText IText7={0,1,JAM1,0,0,&TOPAZ80,"CPU",NULL};
  157. struct MenuItem MenuItem3={&MenuItem4,0,16,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText7,NULL,NULL,NULL,MENUNULL};
  158. struct IntuiText IText8={0,1,JAM1,0,0,&TOPAZ80,"Idle",NULL};
  159. struct MenuItem MenuItem2={&MenuItem3,0,8,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText8,NULL,NULL,NULL,MENUNULL};
  160. struct IntuiText IText9={0,1,JAM1,0,0,&TOPAZ80,"About",NULL};
  161. struct MenuItem MenuItem1={&MenuItem2,0,0,58,8,ITEMTEXT+ITEMENABLED+HIGHCOMP,0,(APTR)&IText9,NULL,NULL,NULL,MENUNULL};
  162.  
  163. struct Menu Menu1={NULL,0,0,62,0,    MENUENABLED,"Project",&MenuItem1};
  164.  
  165.  
  166.  
  167. void cleanexit(int error);
  168. void openthings(void);
  169. void addtimerequest(long secs, long micros);
  170. void changefont(void);
  171. void addtimerequest2(long secs, long micros);
  172. void uptime(void);
  173. ULONG maxmemsize(long memtype);
  174. void updatewindow(void);
  175. void oddstuff(void);
  176. void idletask(void);
  177. void __saveds switchroutine(void);
  178. void updatezipped(int i);
  179.  
  180.  
  181. void CXBRK(void) 
  182.     cleanexit(0);
  183. }
  184.  
  185. void cleanexit(int error)
  186. {
  187.     if(task_added) RemTask(task);
  188.     if(task) FreeMem(task,sizeof(struct Task));
  189.     if(stack) FreeMem(stack,STACK_SIZE);
  190.     if(timeropen2)
  191.     {    if(time_requested2)
  192.         {
  193.             AbortIO((struct IORequest *)timermsg2);
  194.             WaitIO((struct IORequest *)timermsg2);
  195.         }
  196.         CloseDevice((struct IORequest *)timermsg2);
  197.     }
  198.     if(timermsg2) DeleteExtIO((struct IORequest *)timermsg2);
  199.     if(timerport2) DeletePort(timerport2);
  200.  
  201.     if(timeropen)
  202.     {    if(time_requested)
  203.         {
  204.             AbortIO((struct IORequest *)timermsg);
  205.             WaitIO((struct IORequest *)timermsg);
  206.         }
  207.         CloseDevice((struct IORequest *)timermsg);
  208.     }
  209.     if(timermsg) DeleteExtIO((struct IORequest *)timermsg);
  210.     if(timerport) DeletePort(timerport);
  211.     if(window->MenuStrip) ClearMenuStrip(window);
  212.     if(window) CloseWindow(window);
  213.     if(DiskfontBase) CloseLibrary(DiskfontBase);
  214.     if(GfxBase) CloseLibrary((struct Library *)GfxBase);
  215.     if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  216.     XCEXIT(error);
  217. }
  218.  
  219.  
  220. void openthings(void)
  221. {
  222.     int i,j;
  223.  
  224.     if (SysBase->LibNode.lib_Version<36)
  225.         cleanexit(99);
  226.     if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",36L)))
  227.         cleanexit(30);
  228.     if (!(IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",36L)))
  229.         cleanexit(30);
  230.     if (!(DiskfontBase=(struct Library*)OpenLibrary("diskfont.library", 36L)))
  231.         cleanexit(30);
  232.     if(!(timerport=CreatePort(0,0)))
  233.         cleanexit(22);
  234.     if(!(timermsg=(struct timerequest *) CreateExtIO(timerport, sizeof(struct timerequest))))
  235.         cleanexit(22);
  236.     if(OpenDevice("timer.device", UNIT_VBLANK, ((struct IORequest *) timermsg), 0))
  237.         cleanexit(22);
  238.  
  239.     timeropen=TRUE;
  240.  
  241.     if(!(timerport2=CreatePort(0,0)))
  242.         cleanexit(22);
  243.     if(!(timermsg2=(struct timerequest *) CreateExtIO(timerport2, sizeof(struct timerequest))))
  244.         cleanexit(22);
  245.     if(OpenDevice("timer.device", UNIT_VBLANK, ((struct IORequest *) timermsg2), 0))
  246.         cleanexit(22);
  247.  
  248.     timeropen2=TRUE;
  249.  
  250.     if(!(window=OpenWindowTagList(&mywindow,(struct TagItem *)&tagitems)))
  251.         cleanexit(27);
  252.     SetMenuStrip(window,&Menu1);
  253.  
  254.     if(!(stack=AllocMem(STACK_SIZE, MEMF_CLEAR)))
  255.         cleanexit(10);
  256.     if(!(task=(struct Task*)AllocMem(sizeof(struct Task),MEMF_CLEAR|MEMF_PUBLIC)))
  257.         cleanexit(10);
  258.  
  259.     maxchip=maxmemsize(MEMF_CHIP);
  260.     maxfast=maxmemsize(MEMF_FAST);
  261.     maxpub=maxchip+maxfast;
  262.  
  263.     if(SysBase->AttnFlags & AFF_68010)    strcpy(processor,"68010");
  264.     if(SysBase->AttnFlags & AFF_68020)    strcpy(processor,"68020");
  265.     if(SysBase->AttnFlags & AFF_68030)    strcpy(processor,"68030");
  266.     if(SysBase->AttnFlags & AFF_68040)    strcpy(processor,"68040");
  267.  
  268.     /*    Because we run this part only once we just have to assume that user 
  269.         does not add memory cartiges or change the main processor while
  270.         this program is running :-)
  271.         Yeah really. All non-autoconfigurable boards should be added in the
  272.         memory before running Perfmeter. Some strange things might happen
  273.         if you don't do so.
  274.     */
  275.  
  276.     chipscale=maxchip/100;
  277.     fastscale=maxfast/100;
  278.     publicscale=maxpub/100;
  279.  
  280.     if(offset=window->WScreen->BarHeight-8)
  281.         SizeWindow(window,0,offset);
  282.  
  283.     /* init buffer */
  284.     for(i=0;i<6;i++)
  285.     {
  286.         for(j=0;j<150;j++)
  287.             buffer[i][j]=0;
  288.     }
  289.  
  290. }
  291.  
  292.  
  293. void changefont(void)
  294. {
  295.     struct    TextAttr    textattr;
  296.     struct    TextFont    *textfont;
  297.  
  298.     textattr.ta_Name=FONTNAME;;
  299.     textattr.ta_YSize=FONTSIZE;
  300.     textattr.ta_Style=FS_NORMAL;
  301.     textattr.ta_Flags=FPF_ROMFONT | FPF_DISKFONT;
  302.  
  303.     if(textfont=(struct TextFont *)OpenDiskFont(&textattr))
  304.     {    SetFont(window->RPort,textfont);
  305.         if(!window->RPort->TxHeight==8)
  306.         {    cleanexit(10);
  307.         }
  308.     }
  309.     else
  310.     {    cleanexit(10);
  311.     }
  312. }
  313.  
  314. void addtimerequest(long secs, long micros)
  315. {
  316.     time_requested=TRUE;
  317.     timermsg->tr_node.io_Command=TR_ADDREQUEST;
  318.     timermsg->tr_time.tv_secs=secs;
  319.     timermsg->tr_time.tv_micro=micros;
  320.     SendIO((struct IORequest *)timermsg);
  321. }
  322.  
  323. void addtimerequest2(long secs, long micros)
  324. {
  325.     time_requested2=TRUE;
  326.     timermsg2->tr_node.io_Command=TR_ADDREQUEST;
  327.     timermsg2->tr_time.tv_secs=secs;
  328.     timermsg2->tr_time.tv_micro=micros;
  329.     SendIO((struct IORequest *)timermsg2);
  330. }
  331.  
  332. void uptime(void)
  333. {    char temp[30];
  334.  
  335.     if(++upsecs>59)
  336.     {    upsecs=0;
  337.         if(++upmins>59)
  338.         {    upmins=0;
  339.             if(++uphours>23)
  340.             {    uphours=0;
  341.                 updays++;
  342.             }
  343.         }
  344.     }
  345.     if(!zipped)
  346.     {    SetDrMd(window->RPort,JAM2);
  347.         SetBPen(window->RPort,0);
  348.         SetAPen(window->RPort,1);
  349.         Move(window->RPort,10,123+offset);
  350.         sprintf(temp,"Uptime: %02d days  %02d:%02d:%02d",updays,uphours,upmins,upsecs);
  351.         Text(window->RPort,temp,25);
  352.     }
  353. }
  354.  
  355. ULONG maxmemsize(long memtype)
  356. {
  357.     ULONG blocksize=0;
  358.     struct MemHeader *MemHeader;
  359.  
  360.     Forbid();
  361.         for(MemHeader=(struct MemHeader *)SysBase->MemList.lh_Head;MemHeader->mh_Node.ln_Succ;MemHeader=(struct MemHeader *)MemHeader->mh_Node.ln_Succ)
  362.         {
  363.             if(MemHeader->mh_Attributes&memtype)
  364.                 blocksize+=((ULONG)MemHeader->mh_Upper-(ULONG)MemHeader->mh_Lower);
  365.         }
  366.     Permit();
  367.  
  368.     return(blocksize);
  369.  
  370.     /* MaxMemSize() by Louis A. Mamakos. */
  371. }
  372.  
  373.  
  374.  
  375. void updatezipped(int i)
  376. {
  377.     UBYTE    offset1=0,offset2=0;
  378.     char    temp[10];
  379.  
  380.     if(oldi<30)
  381.     {    offset1=1;
  382.         offset2=6;
  383.     }
  384.     else
  385.     {    offset1=3;
  386.         offset2=8;
  387.     }
  388.     SetAPen(window->RPort,0);
  389.     Move(window->RPort,53,58+offset);
  390.     Draw(window->RPort,6+xx[oldi+offset1],103-yy[oldi+offset1]+offset);
  391.     Draw(window->RPort,6+xc[oldi],103-yc[oldi]+offset);
  392.     Draw(window->RPort,6+xx[oldi+offset2],103-yy[oldi+offset2]+offset);
  393.     Draw(window->RPort,53,58+offset);
  394.     Move(window->RPort,14,60+offset);
  395.     sprintf(temp,"%d%%    ",oldi);
  396.     Text(window->RPort,temp,4);
  397.     if(i<30) {offset1=1;offset2=6;} else {offset1=3;offset2=8;}
  398.     SetAPen(window->RPort,1);
  399.     Move(window->RPort,53,58+offset);
  400.     Draw(window->RPort,6+xx[i+offset1],103-yy[i+offset1]+offset);
  401.     Draw(window->RPort,6+xc[i],103-yc[i]+offset);
  402.     Draw(window->RPort,6+xx[i+offset2],103-yy[i+offset2]+offset);
  403.     Draw(window->RPort,53,58+offset);
  404.     Move(window->RPort,14,60+offset);
  405.     sprintf(temp,"%d%%    ",i);
  406.     Text(window->RPort,temp,4);
  407.     for(i=0;i<101;i+=10)
  408.     {    Move(window->RPort,3+xc[i],103-yc[i]+offset);
  409.         Text(window->RPort,"+",1);
  410.     }
  411.     Move(window->RPort,56,60+offset);
  412.     Text(window->RPort,itemname,6);
  413. }
  414.  
  415. void updatewindow(void)
  416. {
  417.     int i,j;
  418.     ULONG    curchip, curfast, curpub;
  419.     struct    RastPort *rp=window->RPort;
  420.     char    temp[10],temp2[10];    /* two temps for double buffering */
  421.  
  422.     if(mode!=oldmode || oldzipped!=zipped)    /* User has decided to look some other item or window zip gadget is pressed*/
  423.     {    if(!zipped)
  424.         {    sprintf(temp,"%s",itemname);
  425.             strcpy(window->Title,temp);
  426.             RefreshWindowFrame(window);
  427.             SetAPen(rp,0);
  428.             RectFill(rp,8,12+offset,164,115+offset);
  429.  
  430.             /* 3D border */
  431.             SetAPen(rp,1);
  432.             Move(rp,10,111+offset);
  433.             Draw(rp,10,16+offset);
  434.             Draw(rp,161,16+offset);
  435.             SetAPen(rp,2);
  436.             Draw(rp,161,111+offset);
  437.             Draw(rp,11,111+offset);
  438.  
  439.             /* Scaling lines */
  440.             SetAPen(rp,3);
  441.             Move(rp,11,38+offset);
  442.             Draw(rp,160,38+offset);
  443.             Move(rp,11,64+offset);
  444.             Draw(rp,160,64+offset);
  445.             Move(rp,11,90+offset);
  446.             Draw(rp,160,90+offset);
  447.  
  448.             /* Draw existing GFX from buffer */
  449.             Move(rp,10,110-buffer[mode][0]+offset);
  450.             SetAPen(rp,1);
  451.             for(j=1;j<=150;j++)
  452.                 Draw(rp,j+10,110-buffer[mode][j]+offset);
  453.         }
  454.         else
  455.         {    SetAPen(window->RPort,0);
  456.             RectFill(window->RPort,10,15+offset,95,62+offset);
  457.             oldi=-1;
  458.             strcpy(window->Title,"");
  459.             RefreshWindowFrame(window);
  460.         }
  461.         oldmode=mode;
  462.         oldzipped=zipped;
  463.     }
  464.  
  465.     /* let's scroll a bit, OK? */
  466.     for(i=0;i<7;i++)
  467.     {
  468.         for(j=0;j<150;j++)
  469.             buffer[i][j]=buffer[i][j+1];
  470.     }
  471.     curchip=AvailMem(MEMF_CHIP);
  472.     curfast=AvailMem(MEMF_FAST);
  473.     curpub=AvailMem(MEMF_PUBLIC);
  474.  
  475.     buffer[0][150]=(UBYTE)(100*cputemp/60);
  476.     buffer[1][150]=load;
  477.     buffer[2][150]=(UBYTE)(curchip/chipscale);
  478.     if(fastscale)
  479.         buffer[3][150]=(UBYTE)(curfast/fastscale);
  480.     buffer[4][150]=(UBYTE)(curpub/publicscale);
  481.     buffer[5][150]=switchcount;
  482.     buffer[6][150]=(UBYTE)(83-(100*cputemp/60));
  483.     if(buffer[6][150]<0) buffer[6][150]=0;
  484.  
  485.  
  486.     for(i=0;i<7;i++)
  487.     {    if(buffer[i][150]>93)
  488.         {    buffer[i][150]=93;
  489.         }
  490.     }
  491.  
  492.     if(!zipped)
  493.     {    SetDrMd(rp,JAM1);
  494.         SetAPen(rp,0);
  495.         sprintf(temp,"%d%%  ",buffer[mode][149]);
  496.         sprintf(temp2,"%d%%  ",buffer[mode][150]);
  497.         Move(rp,140,24+offset);
  498.         Text(rp,temp,4);
  499.         ScrollRaster(rp,1,0,11,17+offset,160,110+offset);
  500.         SetAPen(rp,1);
  501.         Move(rp,140,24+offset);
  502.         Text(rp,temp2,4);
  503.         SetAPen(rp,3);
  504.         WritePixel(rp,160,38+offset);
  505.         WritePixel(rp,160,64+offset);
  506.         WritePixel(rp,160,90+offset);
  507.         SetAPen(rp,1);
  508.         Move(rp,159,110-buffer[mode][149]+offset);
  509.         Draw(rp,160,110-buffer[mode][150]+offset);
  510.     }
  511.     else
  512.     {    if(oldi!=buffer[mode][150])
  513.         {    updatezipped(buffer[mode][150]);
  514.             oldi=buffer[mode][150];
  515.         }
  516.     }
  517. }
  518.  
  519.  
  520.  
  521.  
  522. void idletask(void)    /*    This is Arska Väijy */
  523. {
  524.     ULONG suurinluku=1,taydellinenluku,luku;
  525.  
  526.     Disable();
  527.         task->tc_Switch=switchroutine;
  528.         task->tc_Flags|=TF_SWITCH;
  529.     Enable();
  530.  
  531.     while(1)
  532.     {    taydellinenluku=0;
  533.         for(luku=suurinluku;luku>1;luku--)
  534.         {
  535.             if(!(suurinluku%luku))
  536.                 taydellinenluku+=luku;
  537.         }
  538.         if(taydellinenluku==suurinluku)
  539.             count++;
  540.         suurinluku++;
  541.     }
  542.  
  543.     /* As you know, there may not be busy looped parts in multitasking
  544.        programs :-) */
  545. }
  546.  
  547. void __saveds switchroutine(void)
  548. {
  549.     /*    Thanks to Juhani Vehviläinen for sweatting with me because of
  550.         this idle counting routine */
  551.  
  552.     cputime+=SysBase->Quantum-SysBase->Elapsed;
  553.     switchcount++;
  554. }
  555.  
  556.  
  557. void _main(char *arguments)
  558. {
  559.     ULONG    timersignal, 
  560.             timersignal2,
  561.             idcmpsignal, 
  562.             signals, 
  563.             class;
  564.     UWORD    code, 
  565.             qualifier;
  566.     struct    IntuiMessage *msg=NULL;
  567.     char    temp1[80],temp2[80];
  568.     struct    Node *mynode;
  569.     ULONG    sum1=0;
  570.     int        pos1=0,pos=0,last[61],length=0,i,j=0,argumentcount=0;
  571.     
  572.  
  573.     /* handle arguments */
  574.     for(i=0;i<strlen(arguments);i++)
  575.     {    if(arguments[i]==32 || arguments[i]==13 || arguments[i]==10)
  576.         {    if(!strncmp(temp1,"-x",2))
  577.                 mywindow.LeftEdge=atoi(temp1+2);
  578.             if(!strncmp(temp1,"-y",2))
  579.                 mywindow.TopEdge=atoi(temp1+2);
  580.             argumentcount++;
  581.             j=0;
  582.         }
  583.         else
  584.         {    temp1[j++]=arguments[i];
  585.             temp1[j]=0;
  586.         }
  587.     }
  588.  
  589.     openthings();
  590.     changefont();
  591.  
  592.     for(i=0;i<60;i++)
  593.         last[i]=0;
  594.  
  595.     timersignal = 1L << timerport->mp_SigBit;
  596.     timersignal2= 1L << timerport2->mp_SigBit;
  597.     idcmpsignal = 1L << window->UserPort->mp_SigBit;
  598.  
  599.     addtimerequest(1,0);
  600.     addtimerequest2(0,10);
  601.  
  602.     task->tc_Node.ln_Type=NT_TASK;
  603.     task->tc_Node.ln_Name=taskname;
  604.     task->tc_Node.ln_Pri=-128;
  605.     task->tc_SPLower=(APTR)stack;
  606.     task->tc_SPUpper=(APTR)(STACK_SIZE+(ULONG)stack);
  607.     task->tc_SPReg=task->tc_SPUpper;
  608.  
  609.     AddTask(task,idletask,0L);
  610.     task_added=TRUE;
  611.  
  612.     while(keepgoing)
  613.     {    signals = Wait(timersignal | timersignal2 | idcmpsignal | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D);
  614.  
  615.         if(signals & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
  616.             cleanexit(0);
  617.  
  618.         if(signals & idcmpsignal)
  619.         {
  620.             while(msg=(struct IntuiMessage *)GetMsg(window->UserPort))
  621.             {
  622.                 class=msg->Class;
  623.                 code=msg->Code;
  624.                 qualifier=msg->Qualifier;
  625.                 ReplyMsg((struct Message *) msg);
  626.  
  627.                 switch(class)
  628.                 {
  629.                     case CLOSEWINDOW:
  630.                         keepgoing=FALSE;
  631.                         break;
  632.                     case NEWSIZE:
  633.                         if(window->Width==WINDOWWIDTH && window->Height==WINDOWHEIGTH+offset)
  634.                             zipped=FALSE;
  635.                         else if(!zipped)
  636.                         {    zipped=TRUE;
  637.                             if(window->Height<65+offset)
  638.                                 SizeWindow(window,0,offset);
  639.                             SetAPen(window->RPort,0);
  640.                             RectFill(window->RPort,10,15+offset,95,62);
  641.                         }
  642.                         break;
  643.                     case MENUPICK:
  644.                         switch(ITEMNUM(code))
  645.                         {
  646.                             case 0:
  647.                                 cputime=100-cpuload;
  648.                                 if(cputime<1 || cputime>100)
  649.                                     cputime=20;
  650.                                 sprintf(temp1,"Average %s load: %d %% ",processor,cputime);
  651.                                 cputime=0;
  652.                                 abouttext[5].IText=(UBYTE *)temp1;
  653.                                 sprintf(temp2,"%d perfect numbers.",count);
  654.                                 abouttext[8].IText=(UBYTE *)temp2;
  655.                                 AutoRequest(NULL,&abouttext[0],NULL,&proceed,NULL,NULL,272,128);
  656.                                 break;
  657.                             case 1:
  658.                                 mode=0;
  659.                                 strcpy(itemname,"  Idle");
  660.                                 break;
  661.                             case 2:
  662.                                 mode=6;
  663.                                 strcpy(itemname,"   CPU");
  664.                                 break;
  665.                             case 3:
  666.                                 mode=1;
  667.                                 strcpy(itemname,"  Load");
  668.                                 break;
  669.                             case 4:
  670.                                 mode=2;
  671.                                 strcpy(itemname,"  Chip");
  672.                                 break;
  673.                             case 5:
  674.                                 mode=3;
  675.                                 strcpy(itemname,"  Fast");
  676.                                 break;
  677.                             case 6:
  678.                                 mode=4;
  679.                                 strcpy(itemname,"Public");
  680.                                 break;
  681.                             case 7:
  682.                                 mode=5;
  683.                                 strcpy(itemname,"Switch");
  684.                                 break;
  685.                             case 8:
  686.                                 cleanexit(0);
  687.                         }
  688.                         break;
  689.                 }
  690.             }
  691.         }
  692.  
  693.         if(signals & timersignal)
  694.         {
  695.             GetMsg(timerport);
  696.             addtimerequest(1,0);
  697.             uptime();
  698.             if(100*cputime/60<100)
  699.                 cputemp=cputime;
  700.             cputemp2+=100*cputime/60;
  701.             cputime=0;
  702.             cpuload=cputemp2/++jakaja;
  703.             length = 0;
  704.             Disable();
  705.                 for(mynode=(SysBase->TaskReady).lh_Head;mynode=mynode->ln_Succ;length++)
  706.                     ;
  707.             Enable();
  708.             sum1+=(length-last[pos1]);
  709.             last[pos]=length;
  710.             if(++pos1==60)    pos1=0;
  711.             if(++pos==60)    pos=0;
  712.             load=(sum1*100+50)/480;
  713.             if(load>100)
  714.  
  715.                 load=100;
  716.             updatewindow();
  717.             switchcount=0;
  718.         }
  719.         if(signals & timersignal2)
  720.         {
  721.             GetMsg(timerport2);
  722.             addtimerequest2(0,8);
  723.         }
  724.     }
  725.     cleanexit(0);
  726. }
  727.