/* MergeMem.c v2 - by Carolyn Scheppner CBM 02/87 * modified: 07/87 to move printf's outside of Forbid * (printf eventually Waits which breaks a Forbid) * Now responsive from WB, linkage with TWstartup.obj * * Attempts to merge the memlists of sequentially configged ram boards * which have the same Attributes (for contiguous expansion ram) * * Note: This program has been tested with an Alegra plugged into * a Microbotics Starboard' pass-thru, and with an A2000 * with multiple 2-meg ram boards. This program makes * the assumption that sequentially configged ram boards * have sequential entries in the MemHeader list. * If ram boards are not installed largest to smallest, * this may not be true and this program will not be able * to merge them. * * Alink with TWStartup.obj ... Amiga.lib, LC.lib * */ #include "exec/types.h" #include "exec/exec.h" #include "exec/execbase.h" extern struct ExecBase *SysBase; extern LONG stdin; char TWspec[] = {"CON:100/50/440/100/ MergeMem v2 "}; char auth[] = {"cas/cbm"}; main(argc,argv) int argc; char **argv; { struct MemChunk *chunk; struct MemHeader *mem, *firstmem, *prevmem = 0; struct ExecBase *eb = SysBase; ULONG memsize; ULONG mems[32], ends[32], atts[32], prev[32], mrgs[32]; ULONG k, memCnt = 0, mrgCnt = 0; BOOL FromWb; /* Temps */ struct MemChunk *oldFirst; APTR oldLower, oldUpper; ULONG oldFree; FromWb = (argc==0) ? TRUE : FALSE; if((argc==2)&&(argv[1][0]=='?')) { printf("MergeMem v2 --- Carolyn Scheppner CBM 07/87\n"); printf("Usage: MergeMem\n"); printf("Attempts to merge sequentially config'd ram boards\n"); exit(0); } Forbid(); firstmem = (struct MemHeader *)eb->MemList.lh_Head; /* Go to end of MemHeader list */ for (mem = firstmem; mem->mh_Node.ln_Succ; mem = (struct MemHeader *)mem->mh_Node.ln_Succ) { mems[memCnt] = (ULONG)mem; ends[memCnt] = (ULONG)mem->mh_Upper; atts[memCnt] = (ULONG)mem->mh_Attributes; memCnt++; } /* Back up from terminal node to point at last MemHeader */ mem = (struct MemHeader *)mem->mh_Node.ln_Pred; /* Backwards, for each except first */ for ( ; (ULONG)mem != (ULONG)firstmem; mem = prevmem) { prevmem = (struct MemHeader *)mem->mh_Node.ln_Pred; /* If prev MemHeader describes neighboring ram of same Attributes */ if(((ULONG)prevmem->mh_Upper == (ULONG)mem->mh_Lower - 32)&& (prevmem->mh_Attributes == mem->mh_Attributes)) { prev[mrgCnt] = (ULONG)prevmem; mrgs[mrgCnt] = (ULONG)mem; mrgCnt++; /* Save needed stuff from MemHeader before Remove()ing it */ oldFirst = mem->mh_First; oldLower = mem->mh_Lower; oldUpper = mem->mh_Upper; oldFree = mem->mh_Free; Remove(mem); /* Adjust Upper and Free in prev MemHeader to include this mem */ memsize = (ULONG)oldUpper - (ULONG)oldLower +32L; prevmem->mh_Upper = (APTR)((ULONG)prevmem->mh_Upper + memsize); prevmem->mh_Free += oldFree; /* Link last free chunk of prevmem to first free of mem */ for (chunk = prevmem->mh_First; chunk->mc_Next; chunk = chunk->mc_Next); chunk->mc_Next = oldFirst; /* Now FreeMem() the old MemHeader as a 32 byte chunk */ FreeMem(mem,32); } } Permit(); if(stdin > 0) { printf("RAM configuration:\n"); for(k=0; k