
#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>

#define MAXPAT    4L
#define MAXMB     200L
#define MINLEFT   512L
#define FAST      0L
#define CHIP      1L
#define BOTH      2L

#define cls (scr_clear());

struct MemBlks
 {
  UBYTE *adx;
  ULONG cnt;
 };

struct MemBlks MB = { 0 };
struct MemBlks TMB[2][MAXMB] = { 0 };

UBYTE dp[4] = { 255,170,85,0 };

UBYTE *sa;
ULONG i,k,fav,cav,fnu,cnu,bcnt,inpt,bflag;
ULONG fflag,cflag,itcnt,mfst,mchp,sadx;
ULONG tf,doit,fstcnt,chpcnt,trial;
char s[80];
char  cc;

void 
lines(c)
 int c;
 {
  int i;

  for(i=0;i<c;i++)printf("\n");
 }

void
printc(s)
 char *s;
 {
  int l;

  for(l=0;l<((80-strlen(s))/2);l++) printf(" ");
  printf(s);
 }

void
printblocks(type)
 ULONG type;
 {
  ULONG i,av,nu,blkcnt;

  cls;
  lines(1);
  if(!type)
   {
    printc("F A S T   M E M O R Y\n\n");
    blkcnt=fstcnt;
    nu=fnu;
    av=fav;
   }
   else
   {
    printc("C H I P   M E M O R Y\n\n");
    blkcnt=chpcnt;
    nu=cnu;
    av=cav;
   }
  if(blkcnt)
   {
    sprintf(s,"Available %8ld - Allocated %8ld - Free %8ld\n\n",av,av-nu,nu);
    printc(s);
    for(i=0;i<blkcnt;i++)
     {
      printf("\n             ");
      printf("Block # %3ld from %8lx ",i+1,TMB[type][i].adx);
      printf(" to %8lx  total %8ld",TMB[type][i].adx+TMB[type][i].cnt,
       TMB[type][i].cnt);
     }
   }
 }

UBYTE
checkmem(stadx,chkcnt)
 UBYTE *stadx;
 ULONG chkcnt;
  {
   ULONG tt,i,inpvar,prntval;
   UWORD exptd,revd,pass;

   lines(1);
   sprintf(s,"Testing from adrress %8lx to address %8lx   count %8ld\n\n",
    stadx,stadx+chkcnt,chkcnt);
   printc(s);
   for(pass=0;pass<MAXPAT;pass++)
    {
     exptd=dp[pass];
     prntval=dp[pass];
     sprintf(s,"Testing Pattern =%3lx\n",prntval);
     printc(s);
     for(i=0;i<chkcnt;i++)
      {
       stadx[i]=(UBYTE)exptd;
       revd=(UBYTE)stadx[i];
       if(revd!=exptd)
        {
         printf("\n\n  ERROR  at address %8lx   ",(long)i+stadx);
         printf("exptd = %2lx    revd = %2lx\n\n",(long)exptd,(long)revd);
         printc("Enter options     1 = continue  0 = exit ");
         scanf("%ld",&inpvar);
         if(inpvar==0) return FALSE;
        }
      }
    }
   lines(1);
   return TRUE;
  }

closeup(fcnt,ccnt)
 ULONG fcnt,ccnt;
 {
  ULONG i;

  for(i=0;i<fcnt;i++) FreeMem(TMB[FAST][i].adx,TMB[FAST][i].cnt);
  for(i=0;i<ccnt;i++) FreeMem(TMB[CHIP][i].adx,TMB[CHIP][i].cnt);
  cls;
  lines(2);
  printc("MTEST v1.03 completed.     { C.A. Jagow   8/12/89 }\n\n");
  exit();
 }

testblock(blk,typ)
 ULONG blk,typ;
 {
  ULONG rslt;
  
    for(k=1;k<itcnt+1;k++)
     {
      rslt=checkmem(TMB[typ][blk].adx,TMB[typ][blk].cnt);
      if(rslt)
       {
        sprintf(s,"END OF PASS # %4ld,  %4ld TO GO\n",k,itcnt-k);
        printc(s);
       }
      if(!rslt) k=itcnt+2;
     }
    lines(2);
    if(rslt)
     printc("MEMORY TESTS GOOD!\n");
    if(!rslt)
     printc("TEST FAILED!\n");
 }

testall(typ,itc)
 ULONG typ,itc;
 {
  ULONG bbcnt,rslt,ii,it;

  if(typ==CHIP) bbcnt=chpcnt;
  if(typ==FAST) bbcnt=fstcnt;
  for(it=0;it<itc;it++)
   {
    for(ii=0;ii<bbcnt;ii++)
       {
      rslt=checkmem(TMB[typ][ii].adx,TMB[typ][ii].cnt);
      lines(1);
      if(rslt) printc("MEMORY TESTS GOOD!\n");
      if(!rslt) printc("TEST FAILED\n");
     }
    printc("SELECTED BLOCKS TEST GOOD!\n\n");
    sprintf(s,"END OF PASS # %4ld,  %4ld TO GO\n",it+1,itc-(it+1));
    printc(s);
   }
 }

main()
 {
  ULONG mtype,mblk,ok;

  fflag=FALSE;
  cflag=FALSE;
  bflag=FALSE;
  doit=FALSE;
  cflag=TRUE;
  tf=FALSE;
  fstcnt=0;
  chpcnt=0;
  ok=TRUE;
  inpt=4;
  while(inpt>3)
   {
    cls;
    lines(1);
    printc("MTest  v1.03  8/12/89\n\n");
    printc("Written by  C. A. Jagow\n\n");
    printc("ALL ADDRESS COUNTS ARE DECIMAL\n\n");
    printc("ALL OTHER VALUES ARE HEXIDECIMAL\n\n");
    lines(1);    
    printc("Memory allocation selections are:     \n\n");
    printc("3 = QUIT\n");
    printc("2 = BOTH\n");
    printc("1 = CHIP\n");
    printc("0 = FAST\n");
    lines(1);
    printc("Please enter memory allocation selection? ");
    scanf("%ld",&i);
    inpt=i;
   }
  if(inpt==3) closeup(0,0);
  if(inpt==0) fflag=TRUE;
   else fflag=FALSE;
  if(inpt==1) cflag=TRUE;
   else cflag=FALSE;
  if(inpt==2)
   {
    bflag=TRUE;
    cflag=TRUE;
    fflag=TRUE;
   }
   else bflag=FALSE;
  if(fflag)
   {
    bcnt=0;
    mfst=AvailMem(MEMF_FAST);
    fav=mfst;
    while(mfst)
     {
      trial=AvailMem(MEMF_FAST|MEMF_LARGEST);
      if(trial>=MINLEFT)
       {
        sadx=AllocMem(trial,MEMF_FAST);
        if(sadx)
         {
          TMB[FAST][fstcnt].adx=sadx;
          TMB[FAST][fstcnt].cnt=trial;
          mfst-=trial;
          bcnt+=trial;
          fstcnt++;
         }
       }
       else mfst=FALSE;
      fnu=fav-bcnt;
     }
   }
  if(cflag)
   {
    bcnt=0;
    mchp=AvailMem(MEMF_CHIP);
    cav=mchp;
    while(mchp)
     {
      trial=AvailMem(MEMF_CHIP|MEMF_LARGEST);
      if(trial>=MINLEFT)
       {
        sadx=AllocMem(trial,MEMF_CHIP);
        if(sadx)
         {
          TMB[CHIP][chpcnt].adx=sadx;
          TMB[CHIP][chpcnt].cnt=trial;
          mchp-=trial;
          bcnt+=trial;
          chpcnt++;
         }
       }
      else mchp=FALSE;
      cnu=cav-bcnt;
     }
   }
  while(ok)
   {
    inpt=4;
    while(inpt>3)
     {
      cls;
      lines(1);
      printc("MTest  v1.03  8/12/89\n\n");
      lines(3);
      printc("Memory testing selections are:     \n\n");
      printc("3 = QUIT\n");
      printc("2 = BOTH\n");
      printc("1 = CHIP\n");
      printc("0 = FAST\n");
      lines(1);
      printc("Please enter memory testing selection? ");
      scanf("%ld",&inpt);
      if(!bflag)
       {
        if(inpt==2) inpt=4;
        if((inpt==0)&(!fflag)) inpt=4; 
        if((inpt==1)&(!cflag)) inpt=4;
       }
     }
    if(inpt==3) closeup(fstcnt,chpcnt);
    if(inpt==0) mtype=FAST;
    if(inpt==1) mtype=CHIP;
    if((inpt==2)&&(bflag)) doit=TRUE;
      else doit=FALSE;
    mblk=1;
    if(!doit)
     {
      printblocks(mtype);
      lines(2);
      printc("Enter block number to test? { 0 = all blocks } ");
      scanf("%ld",&mblk);
      if(mtype==FAST)
       if(mblk>fstcnt) mblk=fstcnt;
      if(mtype==CHIP)
       if(mblk>chpcnt) mblk=chpcnt;
     }
    lines(2);
    printc("Enter number of iterations? ");
    scanf("%ld",&itcnt);
    tf=FALSE;
    cls;    
    lines(2);
    if(!mblk) tf=TRUE;
    if(tf) testall(mtype,itcnt);
    if(doit)
     {
      lines(2);
      printc("TESTING ALL AVAILABLE MEMORY\n\n");
      printc("FAST TEST\n\n");
      testall(FAST,itcnt);
      lines(2);
      printc("CHIP TEST\n\n");
      testall(CHIP,itcnt);
      tf=FALSE;
     }
    if((!tf)&&(!doit))
     {
      mblk--;
      testblock(mblk,mtype);
     }
    lines(2);
    printc("TEST COMPLETE!\n\n");
    printc("Continue testing?  { 0 = exit program   1 = continue } ");
    scanf("%ld",&ok);
   }
  closeup(fstcnt,chpcnt);
 }
