/* This code is in the public domain. It was written by Steve Holland
   (sdh4@cornell.edu) It is placed here without copyright. */


#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/resident.h>
#include <exec/memory.h>
#include <proto/exec.h>


extern struct ExecBase *SysBase;


#define FASTMEM_MIN 0x7c00000
#define FASTMEM_MAX 0x7efffff
#define NEWROM_MIN  0x7f00000
#define NEWROM_MAX  0x7f7ffff
#define ARRAYSIZE 100

#define BASEINCREMENT 0x7000000

struct Resident **BasicArray; /* We start with BasicArray[2] in case we happen 
 to be at the beginning of a memory segment, in which case we will be overwritten
 by the free list on reset. Therefore the beginning of our data is &BasicArray[2] */

struct MemList *MyList;

void main(int argc,char *argv[])
{
  struct Resident **Array;
  int ResCnt;
  int Cnt,ArgCnt;
  int AllocAbsSize;
  APTR AllocAbsPtr;
  APTR KickMemPtr;
  APTR AllocBase;
  struct MemEntry *MEArray;
  
  if (!argc) return;
  
  Array=(struct Resident **)SysBase->ResModules;
  BasicArray=AllocMem(sizeof(struct Resident *)*ARRAYSIZE,MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP);
  if (!BasicArray) exit(1);
  
  for (Cnt=2,ArgCnt=1;argv[ArgCnt] && Cnt < (ARRAYSIZE-1);ArgCnt++) {
    for (ResCnt=0;Array[ResCnt];ResCnt++) {
      if (!strcmp(argv[ArgCnt],Array[ResCnt]->rt_Name)) {
        BasicArray[Cnt]=(struct Resident *)(((ULONG)Array[ResCnt])+((ULONG)BASEINCREMENT));
        Cnt++;
        break;
      }
    }
  }
  BasicArray[Cnt]=NULL;
  AllocAbsSize=sizeof(struct Resident *)*(Cnt);
  AllocAbsPtr=(APTR)&BasicArray;
  
  AllocBase=AllocMem(1000+16+sizeof(struct MemList)+(2*sizeof(struct MemEntry)),MEMF_CLEAR|MEMF_CHIP|MEMF_PUBLIC);
  if (!AllocBase) exit(10);
  
  MyList=(struct MemList *)(((char *)AllocBase)+8);
  MEArray=&MyList->ml_ME[0];
  MEArray[0].me_Un.meu_Addr=BasicArray;
  MEArray[0].me_Length=ARRAYSIZE*sizeof(struct Resident *);
  MEArray[1].me_Un.meu_Addr=AllocBase;
  MEArray[1].me_Length=16+sizeof(struct MemList)+(2*sizeof(struct MemEntry));
  MyList->ml_Node.ln_Succ=NULL;
  MyList->ml_Node.ln_Pred=NULL;
  MyList->ml_NumEntries=2;
  Disable();
  SysBase->KickMemPtr=MyList;
  SysBase->KickTagPtr=&BasicArray[2];
  SysBase->KickCheckSum=SumKickData();
  Enable();
}
