
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/runbar.h>
#include <exec/execbase.h>
#include <exec/memory.h>

void VBRtest(void); /* VBR test procedure */
void VBRMove(void); /* VBR move procedure */

struct Library *RunBarBase; /* Library Base*/

/* CPU Image */
UWORD chip cpuData[39] =
{
	/* Plane 0 */
	0x0000,0x0000,0x2AA0,0x1FE0,0x3FE0,0x1FE0,0x3860,0x1FE0,
	0x3060,0x1FE0,0x3FE0,0x0000,0x0000,
	/* Plane 1 */
	0x0000,0x1540,0x1540,0x6030,0x0800,0x6030,0x0780,0x6030,
	0x0F80,0x6030,0x1540,0x1540,0x0000,
	/* Plane 2 */
	0x0000,0x0000,0x0A80,0x0000,0x2820,0x0000,0x27A0,0x0000,
	0x2FA0,0x0000,0x0A80,0x0000,0x0000
};

struct Image cpu =
{
	0, 0,		/* LeftEdge, TopEdge */
	13, 13, 3,	/* Width, Height, Depth */
	cpuData,	/* ImageData */
	0x0007, 0x0000,	/* PlanePick, PlaneOnOff */
	NULL		/* NextImage */
};


/* Menu Structure */
struct SBItem menu[]=
{
  {0,NULL},         /* 0 - Normal, 1 - Disabled */ 
  {0,NULL},         /* 2 - Bar   ,15 - Menu End */
  {2,NULL},
  {0,"Exit"},
  {15,NULL}     
};

/* Information about Menu */
struct RBInfo info =
{
  RB_VERSION,     /* Always set it to RB_VERSION*/
  "CpuControl",/* Menu name.Please use specific name, because */
                  /* this name will use for unique check. */
  RBF_UNIQUE      /* Will not allow duplicates. */
};

    ULONG  vbp;
static  char   ver[]="$VER: CPU Control by Sergej Kravcenko 1.0 (24.11.96)";
/*--------------------Main Program-------------------------*/
void main()
{ 
    struct Task *prtask;
    char   line1[]="VBR to FAST";
    char   line2[]="VBR to CHIP";
    char   line3[]="Enable Cache";
    char   line4[]="Disable Cache";
    BOOL   my_close,cache,vbr;
    struct MsgPort *port;
    struct RBMessage *my_message;
    UWORD  Flags;
    ULONG  fastmem,cachestate,mask;
    struct ExecBase *SysBase=*(struct ExecBase **)4;
    ULONG  class,code,cputype; /* cputype 0 - 000 or 010,1 - 020,2 - 030 */
                               /* 3 - 040,4 - 060                 */
    
/*---------------Open Library------------------------------*/    
    RunBarBase = (struct Library *)
    OpenLibrary( "RunBar.library",1);
  
    if( RunBarBase == NULL) goto end;
    
/*------------------Get Task Pointer-----------------------*/    
    prtask = FindTask(NULL);
    
/*-------------------Get CPU Type--------------------------*/    
    Flags = SysBase->AttnFlags;
    cputype = 0;
    if ((Flags&0x0002) != 0)
        cputype = 1;
    if ((Flags&0x0004) != 0)
        cputype = 2;
    if ((Flags&0x0008) != 0)
        cputype = 3;
    if ((Flags&0x0080) != 0)
        cputype = 4;
/*------------Check Fast Mem------------------------------*/ 
    Forbid();
    fastmem = AvailMem(MEMF_FAST);
    Permit();
/*---Quit if 68000 CPU and no FAST memory------------*/
    if ((fastmem < 1024) && (cputype == 0)) goto end;

/*----------Get Info about Cache and VBR state---------*/
    cachestate = CacheControl(0x00000000,0x00000000);
    if ((cachestate & 0x00000001) != 0) cache = TRUE;
    else cache = FALSE;
    
    Supervisor((unsigned long (* )())VBRtest);
    if (vbp != 0)  vbr = TRUE;
    else vbr = FALSE;  

    if (cputype > 1) mask = 0x00001111;
    else mask = 0x00000001;
/*------------------Layout Menu-----------------------*/
    if (fastmem < 1024)
    menu[1].sbi_Type = 1;
    else
     if (vbr == TRUE) menu[1].sbi_Name = line2;
        else menu[1].sbi_Name = line1;
        
    if (cputype == 0) menu[0].sbi_Type = 1;
    else
     if (cache == TRUE) menu[0].sbi_Name = line4;
        else menu[0].sbi_Name = line3;             
/*------------------Create RunBar Menu---------------------*/    
    if (RB_AddTask(prtask,menu,&cpu,&info,&port) != 0) goto end;
    
/*------------------Wait Port------------------------------*/    
    my_close = FALSE;
    while( my_close == FALSE )
    {
     WaitPort(port);
     my_message = (struct RBMessage *) GetMsg(port);
     if (my_message)
     {
        class    = my_message->rb_class;
        code     = my_message->rb_code;
        ReplyMsg((struct Message *) my_message );
        
        if(class == IDCMP_RUNBARCMD)
         {
          switch (code)
          {
            case 0:
              if (cache == FALSE)
              {
               cache = TRUE; 
               CacheControl(0x00001111,mask);
              }
              else
              {
               cache = FALSE; 
               CacheControl(0x00000000,mask);
              }
              if (cache == TRUE) menu[0].sbi_Name = line4;
                 else menu[0].sbi_Name = line3;
              RB_Edit(prtask,menu,&cpu);   
            break;
            case 1:
              VBRMove();
              Supervisor((unsigned long (* )())VBRtest);
              if (vbp != 0)  vbr = TRUE;
              else vbr = FALSE;
              if (vbr == TRUE) menu[1].sbi_Name = line2;
              else menu[1].sbi_Name = line1;
              RB_Edit(prtask,menu,&cpu);
            break;
            case 3:
             my_close = TRUE;
            break;  
          }   
         } 
        if (class == IDCMP_RUNBARMSG)
           {
       /*------------Exit--------------------*/     
             if (code == RB_REMOVE) my_close = TRUE;      
           }                          
       
     }
    }
/*------------Remove RunBar Menu---------------------*/
/* If you get non NULL result, you must wait some time, and try */
/* again. */
    
    while (RB_RemoveTask(prtask)) Delay(10);
    
/*-----------Close Library---------------------------*/    
end:if ( RunBarBase ) CloseLibrary ((struct Library *) RunBarBase);   
}
