[comp.sources.amiga] v89i068: amf - add memory forever

page@swan.ulowell.edu (Bob Page) (03/16/89)

Submitted-by: U211344@HNYKUN11.BITNET (Olaf 'Rhialto' Seibert)
Posting-number: Volume 89, Issue 68
Archive-name: kernel/amf.1

This is an AddMem that installs a ResModule in order to initialize the
extra memory as early in the system bootstrap as possible.

[uuencoded executables included.  ..Bob]

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:    Shell Archiver
#	Run the following text with /bin/sh to create:
#	Amf.c
#	amf.uu
#	Clobber.c
#	clobber.uu
#	makefile
# This archive created: Thu Mar 16 10:50:31 1989
cat << \SHAR_EOF > Amf.c
/*
 *  AddMemForever - Copyright (C) 1989 by Olaf Seibert
 *
 *  This is an AddMem that installs a ResModule in order to initialize
 *  the extra memory as early in the system bootstrap as possible.
 *
 *  Sigh, many kludges for the Manx assembler...
 *
 *  This is free software. There is no warranty whatsoever. If this
 *  program proves defective, you assume all costs ... etc bla bla bla.
 *  In short: For distribution refer to the GNU General Public Licence.
 *
 */

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

#ifndef TAG_PRIORITY
#define TAG_PRIORITY    115
#endif

#define INDIRECT        0x80000000

extern void *AllocMem();
extern struct Resident *FindResident();
extern long TypeOfMem();

/* Whose dumb idea was it to type ExecBase.KickCheckSum an APTR ? */
extern APTR SumKickData();

/* 'cuz they are in the code segment out of the compiler's control... */
extern void BeginLabel(), EndLabel(), Init(), Base(), Size();

extern char Name[], IdString[];
extern struct Resident Resident;
extern struct MemList MemList;
extern long ResModules[], KickTagPtr[];

#asm

.begin:
        move.l  a0,-(sp)
        move.l  d0,-(sp)
        bsr.s   __main
        lea     8(sp),sp
        rts

#endasm

struct ExecBase *SysBase;

long _main(d0, a0)
long d0;
char *a0;
{
    register char *CopyOfModule;
    register long ModuleSize;
    register long Relocation;

    SysBase = *(struct ExecBase **)4;

    if (TypeOfMem(*(long *)Base + sizeof(struct MemHeader)) == 0)
        Init();                 /* Add the memory now */

    if (FindResident(Name))
        return 0;               /* Already resident */

    ModuleSize = (char *)EndLabel - (char *)BeginLabel;
    CopyOfModule = AllocMem(ModuleSize, MEMF_CHIP|MEMF_PUBLIC);

    if (CopyOfModule == NULL)
        return 20;              /* This would be very weird */

    Relocation = CopyOfModule - (char *)BeginLabel;

    Resident.rt_MatchTag = (struct Resident *)CopyOfModule;
    Resident.rt_EndSkip = (APTR)(CopyOfModule + ModuleSize);
    Resident.rt_Name += Relocation;         /* char * */
    Resident.rt_IdString += Relocation;     /* char * */
    Resident.rt_Init = (APTR)((char *) Resident.rt_Init + Relocation);

    MemList.ml_Node.ln_Succ = (struct Node *)SysBase->KickMemPtr;
    MemList.ml_Node.ln_Name += Relocation;  /* char * */
    MemList.ml_ME[0].me_Addr = (APTR)CopyOfModule;
    MemList.ml_ME[0].me_Length = ModuleSize;

    Disable();

    /* Set up link for Resident list */
    ResModules[0] = (long) CopyOfModule;
    if (ResModules[1] = (long) SysBase->ResModules)
        ResModules[1] |= INDIRECT;

    /* Set up link for KickTagPtr list */
    KickTagPtr[0] = (long) CopyOfModule;
    if (KickTagPtr[1] = (long) SysBase->KickTagPtr)
        KickTagPtr[1] |= INDIRECT;

    CopyMem((char *)BeginLabel, CopyOfModule, ModuleSize);

    SysBase->ResModules = (APTR)((char *)&ResModules[0] + Relocation);
    SysBase->KickTagPtr = (APTR)((char *)&KickTagPtr[0] + Relocation);
    SysBase->KickMemPtr = (APTR)((char *)&MemList + Relocation);
    SysBase->KickCheckSum = SumKickData();

    Enable();

    return 0;
}

/* Manx seems to be missing a binding for SumKickData() */

#asm

_LVOSumKickData equ -$264

_SumKickData:
        move.l  4,a6
        jmp     _LVOSumKickData(a6)

#endasm

/* From here will be copied to remain resident: */

#asm

_BeginLabel:

#endasm

/*
 *  This struct Resident must be linked on the ResModules and
 *  and KickTagPtr lists. It must be the first thing in the
 *  resident module. (That's what our code assumes, it is
 *  no system requirement.)
 */

struct Resident Resident = {
    RTC_MATCHWORD,      /* rt_MatchWord */
    NULL,               /* rt_MatchTag */       /* <-- Relocate */
    NULL,               /* rt_EndSkip */        /* <-- Relocate */
    RTF_COLDSTART,      /* rt_Flags */
    1,                  /* rt_Version */
    NT_UNKNOWN,         /* rt_Type */
    TAG_PRIORITY,       /* rt_Priority */
    Name,               /* rt_Name */           /* <-- Relocate */
    IdString,           /* rt_IdString */       /* <-- Relocate */
    (APTR)&Init         /* rt_Init */           /* <-- Relocate */
};

/*
 *  This MemEntry structure describes the memory from BeginLabel to
 *  EndLabel, and must be on the KickMemPtr list (not a List).
 */

struct MemList MemList = {
    {                   /* ml_Node */
        NULL,               /* ln_Next, singly linked list */
        NULL,               /* ln_Prev, unused */
        NT_UNKNOWN,         /* ln_Type */
        0,                  /* ln_Pri */
        Name                /* ln_Name */       /* <-- Relocate */
    },
    1,                  /* ml_NumEntries */
    NULL,               /* me_Addr */           /* <-- Relocate */
    0,                  /* me_Size */           /* <-- Set */
};

char Name[]     = "addmem.tag";
char IdString[] = "AddMemForever by Olaf Seibert (5 march 1989)\r\n";

long KickTagPtr[2] = { 0, 0 };
long ResModules[2] = { 0, 0 };

#asm

_LVOAddMemList  equ -$26a
MEMF_PUBLIC     equ 1
MEMF_FAST       equ 4

_Init:
        movem.l  a6/d2,-(sp)

;;;;
;
;   Allow the user NOT to add memory if he presses the left
;   mouse button.

        btst.b  #6,$bfe001
        beq.s   quit

;;;;
;
;   It is a good idea to first test if there really is some
;   memory when it is supposed to be there. We test the first
;   longword, which will be clobbered by AddMemList anyway.

        move.l  _Base(pc),a0    ; Base address
        clr.l   (a0)
        tst.l   (a0)
        bne.s   quit            ; Must be no or bad memory
        move.l  #$55555555,d0
        move.l  d0,(a0)
        cmp.l   (a0),d0
        bne.s   quit            ; Must be no or bad memory
        asl.l   #1,d0
        move.l  d0,(a0)
        cmp.l   (a0),d0
        bne.s   quit            ; Must be no or bad memory

;;;;
;
;   We now believe there is memory.

        move.l  _Size(pc),d0    ; Size
        move.l  #MEMF_FAST+MEMF_PUBLIC,d1
        moveq.l #0,d2           ; Priority 0
        lea     _Name(pc),a1    ; Name
        move.l  4,a6            ; AbsExecBase
        jsr     _LVOAddMemList(a6)

;;;;
;
;   We are done here. I don't know what the return value should be...

quit:
        moveq.l #0,d0
        movem.l (sp)+,a6/d2
        rts


_Base:  dc.l MEM_BASE
_Size:  dc.l MEM_SIZE

_EndLabel:

#endasm
SHAR_EOF
cat << \SHAR_EOF > amf.uu

begin 644 AddMemForever
M```#\P`````````#``````````(```"O``````````$```/I````KR\(+P!A-
M!D_O``A.=4Y5``!(YPP@(_@`!``````@>0```EA(:``@3KD```*L6$]*@&8`[
M``A.N0```A!(>0```<1.N0```IY83TJ`9P``#'``3-\$,$Y=3G5!^0```F!#.
M^0```9*1R2@(2'@``R\$3KD```)T4$\D0"`*9@``!G`48,Y!^0```9(B2I/(H
M*@DCR@```90@2M'$(\@```&8V[D```&@V[D```&DV[D```&H('D`````(^@")
M(@```:S;N0```;8CR@```;PCQ````<!.N0```HHCR@```@@@>0`````CZ`$L'
M```"#$JH`2QG```*"/D`!P```@PCR@```@`@>0`````CZ`(F```"!$JH`B9GV
M```*"/D`!P```@0O!"\*2'D```&23KD```)@3^\`#"!Y`````$/Y```"""`%/
MT(DA0`$L('D`````0_D```(`(`70B2%``B8@>0````!#^0```:P@!=")(4`"H
M(DZY```!BB!Y`````"%``BI.N0```I1P`&``_L@L>``$3N[]G$K\````````0
M```!`0!S```!Q````=````(0`````````````````<0``0``````````861D,
M;65M+G1A9P``061D365M1F]R979E<B!B>2!/;&%F(%-E:6)E<G0@*#4@;6%R2
M8V@@,3DX.2D-"@```````````````````````$CG(`((.0`&`+_@`6<R('H`Q
M.$*02I!F*"`\555552"`L)!F'..`(("PD&84(#H`'G(%=`!#^O]^+'@`!$ZN"
M_99P`$S?0`1.=0`@````(```3.\#```$("\`#"QY`````$[N_9!.^0```GI,/
M[P`#``0L>0````!.[O\Z+'D`````3N[_B"QY`````$[N_X(B;P`$+'D`````4
M3N[_H"QY`````")O``1.[OWJ``````/L````)0`````````>````*````#8`(
M```\````0@```%H```!@````<````(0```"0````F@```*````"F````K```(
M`+H```#`````Q@```,P```#2````V````.8```#V````_````0H```$:```!U
M)````2H```$Z```!3@```6(```%P```!@````:````&D```!J````;8```)V,
M````#@````(````8````L@```-X```$"```!-````4@```%<```!=@```FP`[
M``*"```"C````I8```*D```"K@````````/R```#Z@````````/R```#ZP``%
&``$```/RV
``
end
size 996
SHAR_EOF
cat << \SHAR_EOF > Clobber.c
#include <exec/types.h>
#include <exec/execbase.h>

struct ExecBase *SysBase;

_main()
{
    ++SysBase->KickCheckSum;
}



SHAR_EOF
cat << \SHAR_EOF > clobber.uu

begin 644 clobber
M```#\P`````````#``````````(````F````$P````$```/I````)F`03E4`:
M`"!L@`Y8J`(J3EU.=6%\0_D````,1?D````,M<EF#C(\``]K"'0`(L)1R?_\R
M(\\````0+'@`!"/.````#$CG@(`(+@`$`2EG$$OZ``A.KO_B8`9"I_-?3G-#`
M^@`D3J[^:"/`````%&8,+CP``X`'3J[_E&`&3KD````"4$].=61O<RYL:6)R:
M87)Y`$GY``!__DYU```#[`````$`````````?`````8````!````%@```!P`S
M```T````/@```&@```"2`````````_(```/J`````P`4````````````````E
.`_(```/K`````0```_*2K
``
end
size 284
SHAR_EOF
cat << \SHAR_EOF > makefile
#
#   Makefile for AddMemForever
#
#   Compile without startup code, initialized data into code segment,
#   and large code, data and integers.

MEMBASE = $$200000  # hex
MEMSIZE = $$200000

amf:    amf.o
    ln amf.o -lcl -w

AddMemForever: amf.o
    ln amf.o -lcl -o $@

both:    amf AddMemForever

install: AddMemForever
    Copy AddMemForever C:AddMem-2M

amf.o:    amf.asm
    as -n amf.asm -EMEM_BASE=$(MEMBASE) -EMEM_SIZE=$(MEMSIZE)

amf.asm:amf.c
    cc +x2 +blcd -a amf.c
SHAR_EOF
#	End of shell archive
exit 0
-- 
Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
Have five nice days.