/*
|
/*
|
** bootstrap.h -- This file is a part of the Amiga bootloader.
|
** bootstrap.h -- This file is a part of the Amiga bootloader.
|
**
|
**
|
** Copyright 1993, 1994 by Hamish Macdonald
|
** Copyright 1993, 1994 by Hamish Macdonald
|
**
|
**
|
** Some minor additions by Michael Rausch 1-11-94
|
** Some minor additions by Michael Rausch 1-11-94
|
** Modified 11-May-94 by Geert Uytterhoeven
|
** Modified 11-May-94 by Geert Uytterhoeven
|
** (Geert.Uytterhoeven@cs.kuleuven.ac.be)
|
** (Geert.Uytterhoeven@cs.kuleuven.ac.be)
|
** - inline Supervisor() call
|
** - inline Supervisor() call
|
**
|
**
|
** This file is subject to the terms and conditions of the GNU General Public
|
** This file is subject to the terms and conditions of the GNU General Public
|
** License. See the file COPYING in the main directory of this archive
|
** License. See the file COPYING in the main directory of this archive
|
** for more details.
|
** for more details.
|
**
|
**
|
*/
|
*/
|
|
|
#ifndef BOOTSTRAP_H
|
#ifndef BOOTSTRAP_H
|
#define BOOTSTRAP_H
|
#define BOOTSTRAP_H
|
|
|
#include <asm/amigatypes.h>
|
#include <asm/amigatypes.h>
|
#include <asm/amigahw.h>
|
#include <asm/amigahw.h>
|
|
|
struct List {
|
struct List {
|
struct Node *l_head;
|
struct Node *l_head;
|
struct Node *l_tail;
|
struct Node *l_tail;
|
struct Node *l_tailpred;
|
struct Node *l_tailpred;
|
u_char l_type;
|
u_char l_type;
|
u_char l_pad;
|
u_char l_pad;
|
};
|
};
|
|
|
struct MemChunk {
|
struct MemChunk {
|
struct MemChunk *mc_Next; /* pointer to next chunk */
|
struct MemChunk *mc_Next; /* pointer to next chunk */
|
u_long mc_Bytes; /* chunk byte size */
|
u_long mc_Bytes; /* chunk byte size */
|
};
|
};
|
|
|
#define MEMF_CHIP (1<<1)
|
#define MEMF_CHIP (1<<1)
|
#define MEMF_FAST (1<<2)
|
#define MEMF_FAST (1<<2)
|
#define MEMF_LOCAL (1<<8)
|
#define MEMF_LOCAL (1<<8)
|
#define MEMF_CLEAR (1<<16)
|
#define MEMF_CLEAR (1<<16)
|
|
|
struct MemHeader {
|
struct MemHeader {
|
struct Node mh_Node;
|
struct Node mh_Node;
|
u_short mh_Attributes; /* characteristics of this region */
|
u_short mh_Attributes; /* characteristics of this region */
|
struct MemChunk *mh_First; /* first free region */
|
struct MemChunk *mh_First; /* first free region */
|
void *mh_Lower; /* lower memory bound */
|
void *mh_Lower; /* lower memory bound */
|
void *mh_Upper; /* upper memory bound+1 */
|
void *mh_Upper; /* upper memory bound+1 */
|
u_long mh_Free; /* total number of free bytes */
|
u_long mh_Free; /* total number of free bytes */
|
};
|
};
|
|
|
struct ExecBase {
|
struct ExecBase {
|
u_char fill1[296];
|
u_char fill1[296];
|
u_short AttnFlags;
|
u_short AttnFlags;
|
u_char fill2[24];
|
u_char fill2[24];
|
struct List MemList;
|
struct List MemList;
|
u_char fill3[194];
|
u_char fill3[194];
|
u_char VBlankFrequency;
|
u_char VBlankFrequency;
|
u_char PowerSupplyFrequency;
|
u_char PowerSupplyFrequency;
|
u_char fill4[36];
|
u_char fill4[36];
|
u_long EClockFrequency;
|
u_long EClockFrequency;
|
};
|
};
|
|
|
#ifndef AFF_68020
|
#ifndef AFF_68020
|
#define AFB_68020 1
|
#define AFB_68020 1
|
#define AFF_68020 (1<<AFB_68020)
|
#define AFF_68020 (1<<AFB_68020)
|
#endif
|
#endif
|
|
|
#ifndef AFF_68030
|
#ifndef AFF_68030
|
#define AFB_68030 2
|
#define AFB_68030 2
|
#define AFF_68030 (1<<AFB_68030)
|
#define AFF_68030 (1<<AFB_68030)
|
#endif
|
#endif
|
|
|
#ifndef AFF_68040
|
#ifndef AFF_68040
|
#define AFB_68040 3
|
#define AFB_68040 3
|
#define AFF_68040 (1<<AFB_68040)
|
#define AFF_68040 (1<<AFB_68040)
|
#endif
|
#endif
|
|
|
#ifndef AFF_68881
|
#ifndef AFF_68881
|
#define AFB_68881 4
|
#define AFB_68881 4
|
#define AFF_68881 (1<<AFB_68881)
|
#define AFF_68881 (1<<AFB_68881)
|
#endif
|
#endif
|
|
|
#ifndef AFF_68882
|
#ifndef AFF_68882
|
#define AFB_68882 5
|
#define AFB_68882 5
|
#define AFF_68882 (1<<AFB_68882)
|
#define AFF_68882 (1<<AFB_68882)
|
#endif
|
#endif
|
|
|
#ifndef AFF_FPU40
|
#ifndef AFF_FPU40
|
#define AFB_FPU40 6
|
#define AFB_FPU40 6
|
#define AFF_FPU40 (1<<AFB_FPU40)
|
#define AFF_FPU40 (1<<AFB_FPU40)
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* GfxBase is now used to determine if AGA or ECS is present
|
* GfxBase is now used to determine if AGA or ECS is present
|
*/
|
*/
|
|
|
struct GfxBase {
|
struct GfxBase {
|
u_char unused1[0xec];
|
u_char unused1[0xec];
|
u_char ChipRevBits0;
|
u_char ChipRevBits0;
|
u_char unused2[5];
|
u_char unused2[5];
|
u_short monitor_id;
|
u_short monitor_id;
|
};
|
};
|
|
|
#ifndef GFXB_HR_AGNUS
|
#ifndef GFXB_HR_AGNUS
|
#define GFXB_HR_AGNUS 0
|
#define GFXB_HR_AGNUS 0
|
#define GFXF_HR_AGNUS (1<<GFXB_HR_AGNUS)
|
#define GFXF_HR_AGNUS (1<<GFXB_HR_AGNUS)
|
#endif
|
#endif
|
|
|
#ifndef GFXB_HR_DENISE
|
#ifndef GFXB_HR_DENISE
|
#define GFXB_HR_DENISE 1
|
#define GFXB_HR_DENISE 1
|
#define GFXF_HR_DENISE (1<<GFXB_HR_DENISE)
|
#define GFXF_HR_DENISE (1<<GFXB_HR_DENISE)
|
#endif
|
#endif
|
|
|
#ifndef GFXB_AA_ALICE
|
#ifndef GFXB_AA_ALICE
|
#define GFXB_AA_ALICE 2
|
#define GFXB_AA_ALICE 2
|
#define GFXF_AA_ALICE (1<<GFXB_AA_ALICE)
|
#define GFXF_AA_ALICE (1<<GFXB_AA_ALICE)
|
#endif
|
#endif
|
|
|
#ifndef GFXB_AA_LISA
|
#ifndef GFXB_AA_LISA
|
#define GFXB_AA_LISA 3
|
#define GFXB_AA_LISA 3
|
#define GFXF_AA_LISA (1<<GFXB_AA_LISA)
|
#define GFXF_AA_LISA (1<<GFXB_AA_LISA)
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* HiRes(=Big) Agnus present; i.e.
|
* HiRes(=Big) Agnus present; i.e.
|
* 1MB chipmem, big blits (none of interest so far) and programmable sync
|
* 1MB chipmem, big blits (none of interest so far) and programmable sync
|
*/
|
*/
|
#define GFXG_OCS (GFXF_HR_AGNUS)
|
#define GFXG_OCS (GFXF_HR_AGNUS)
|
/*
|
/*
|
* HiRes Agnus/Denise present; we are running on ECS
|
* HiRes Agnus/Denise present; we are running on ECS
|
*/
|
*/
|
#define GFXG_ECS (GFXF_HR_AGNUS|GFXF_HR_DENISE)
|
#define GFXG_ECS (GFXF_HR_AGNUS|GFXF_HR_DENISE)
|
/*
|
/*
|
* Alice and Lisa present; we are running on AGA
|
* Alice and Lisa present; we are running on AGA
|
*/
|
*/
|
#define GFXG_AGA (GFXF_AA_ALICE|GFXF_AA_LISA)
|
#define GFXG_AGA (GFXF_AA_ALICE|GFXF_AA_LISA)
|
|
|
struct Library;
|
struct Library;
|
|
|
extern struct ExecBase *SysBase;
|
extern struct ExecBase *SysBase;
|
|
|
static __inline void *
|
static __inline void *
|
AllocMem (unsigned long byteSize,unsigned long requirements)
|
AllocMem (unsigned long byteSize,unsigned long requirements)
|
{
|
{
|
register void *_res __asm("d0");
|
register void *_res __asm("d0");
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register unsigned long d0 __asm("d0") = byteSize;
|
register unsigned long d0 __asm("d0") = byteSize;
|
register unsigned long d1 __asm("d1") = requirements;
|
register unsigned long d1 __asm("d1") = requirements;
|
__asm __volatile ("jsr a6@(-0xc6)"
|
__asm __volatile ("jsr a6@(-0xc6)"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6), "r" (d0), "r" (d1)
|
: "r" (a6), "r" (d0), "r" (d1)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
return _res;
|
return _res;
|
}
|
}
|
static __inline void
|
static __inline void
|
CloseLibrary (struct Library *library)
|
CloseLibrary (struct Library *library)
|
{
|
{
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct Library *a1 __asm("a1") = library;
|
register struct Library *a1 __asm("a1") = library;
|
__asm __volatile ("jsr a6@(-0x19e)"
|
__asm __volatile ("jsr a6@(-0x19e)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6), "r" (a1)
|
: "r" (a6), "r" (a1)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
static __inline void
|
static __inline void
|
Disable (void)
|
Disable (void)
|
{
|
{
|
extern struct ExecBase *SysBase;
|
extern struct ExecBase *SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
__asm __volatile ("jsr a6@(-0x78)"
|
__asm __volatile ("jsr a6@(-0x78)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6)
|
: "r" (a6)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
static __inline void
|
static __inline void
|
Enable (void)
|
Enable (void)
|
{
|
{
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
__asm __volatile ("jsr a6@(-0x7e)"
|
__asm __volatile ("jsr a6@(-0x7e)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6)
|
: "r" (a6)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
static __inline void
|
static __inline void
|
FreeMem (void * memoryBlock,unsigned long byteSize)
|
FreeMem (void * memoryBlock,unsigned long byteSize)
|
{
|
{
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register void *a1 __asm("a1") = memoryBlock;
|
register void *a1 __asm("a1") = memoryBlock;
|
register unsigned long d0 __asm("d0") = byteSize;
|
register unsigned long d0 __asm("d0") = byteSize;
|
__asm __volatile ("jsr a6@(-0xd2)"
|
__asm __volatile ("jsr a6@(-0xd2)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6), "r" (a1), "r" (d0)
|
: "r" (a6), "r" (a1), "r" (d0)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
static __inline struct Library *
|
static __inline struct Library *
|
OpenLibrary (char *libName,unsigned long version)
|
OpenLibrary (char *libName,unsigned long version)
|
{
|
{
|
register struct Library * _res __asm("d0");
|
register struct Library * _res __asm("d0");
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register u_char *a1 __asm("a1") = libName;
|
register u_char *a1 __asm("a1") = libName;
|
register unsigned long d0 __asm("d0") = version;
|
register unsigned long d0 __asm("d0") = version;
|
__asm __volatile ("jsr a6@(-0x228)"
|
__asm __volatile ("jsr a6@(-0x228)"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6), "r" (a1), "r" (d0)
|
: "r" (a6), "r" (a1), "r" (d0)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
return _res;
|
return _res;
|
}
|
}
|
static __inline void *
|
static __inline void *
|
SuperState (void)
|
SuperState (void)
|
{
|
{
|
register void *_res __asm("d0");
|
register void *_res __asm("d0");
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
__asm __volatile ("jsr a6@(-0x96)"
|
__asm __volatile ("jsr a6@(-0x96)"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6)
|
: "r" (a6)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
return _res;
|
return _res;
|
}
|
}
|
static __inline void
|
static __inline void
|
CacheClearU (void)
|
CacheClearU (void)
|
{
|
{
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
__asm __volatile ("jsr a6@(-0x27c)"
|
__asm __volatile ("jsr a6@(-0x27c)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6)
|
: "r" (a6)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
static __inline unsigned long
|
static __inline unsigned long
|
CacheControl (unsigned long cacheBits,unsigned long cacheMask)
|
CacheControl (unsigned long cacheBits,unsigned long cacheMask)
|
{
|
{
|
register unsigned long _res __asm("d0");
|
register unsigned long _res __asm("d0");
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register unsigned long d0 __asm("d0") = cacheBits;
|
register unsigned long d0 __asm("d0") = cacheBits;
|
register unsigned long d1 __asm("d1") = cacheMask;
|
register unsigned long d1 __asm("d1") = cacheMask;
|
__asm __volatile ("jsr a6@(-0x288)"
|
__asm __volatile ("jsr a6@(-0x288)"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6), "r" (d0), "r" (d1)
|
: "r" (a6), "r" (d0), "r" (d1)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
return _res;
|
return _res;
|
}
|
}
|
static __inline unsigned long
|
static __inline unsigned long
|
Supervisor (unsigned long (*userfunc)())
|
Supervisor (unsigned long (*userfunc)())
|
{
|
{
|
register unsigned long _res __asm("d0");
|
register unsigned long _res __asm("d0");
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register struct ExecBase *a6 __asm("a6") = SysBase;
|
register unsigned long (*a0)() __asm("a0") = userfunc;
|
register unsigned long (*a0)() __asm("a0") = userfunc;
|
/* gcc doesn't seem to like asm parameters in a5 */
|
/* gcc doesn't seem to like asm parameters in a5 */
|
__asm __volatile ("movel a5,sp@-;movel a0,a5;jsr a6@(-0x1e);movel sp@+,a5"
|
__asm __volatile ("movel a5,sp@-;movel a0,a5;jsr a6@(-0x1e);movel sp@+,a5"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6), "r" (a0)
|
: "r" (a6), "r" (a0)
|
: "a0","a1","d0","d1","memory");
|
: "a0","a1","d0","d1","memory");
|
return _res;
|
return _res;
|
}
|
}
|
|
|
|
|
struct ExpansionBase;
|
struct ExpansionBase;
|
extern struct ExpansionBase *ExpansionBase;
|
extern struct ExpansionBase *ExpansionBase;
|
|
|
static __inline struct ConfigDev *
|
static __inline struct ConfigDev *
|
FindConfigDev (struct ConfigDev *oldConfigDev,long manufacturer,long product)
|
FindConfigDev (struct ConfigDev *oldConfigDev,long manufacturer,long product)
|
{
|
{
|
register struct ConfigDev * _res __asm("d0");
|
register struct ConfigDev * _res __asm("d0");
|
register struct ExpansionBase* a6 __asm("a6") = ExpansionBase;
|
register struct ExpansionBase* a6 __asm("a6") = ExpansionBase;
|
register struct ConfigDev *a0 __asm("a0") = oldConfigDev;
|
register struct ConfigDev *a0 __asm("a0") = oldConfigDev;
|
register long d0 __asm("d0") = manufacturer;
|
register long d0 __asm("d0") = manufacturer;
|
register long d1 __asm("d1") = product;
|
register long d1 __asm("d1") = product;
|
__asm __volatile ("jsr a6@(-0x48)"
|
__asm __volatile ("jsr a6@(-0x48)"
|
: "=r" (_res)
|
: "=r" (_res)
|
: "r" (a6), "r" (a0), "r" (d0), "r" (d1)
|
: "r" (a6), "r" (a0), "r" (d0), "r" (d1)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
return _res;
|
return _res;
|
}
|
}
|
|
|
struct GfxBase;
|
struct GfxBase;
|
extern struct GfxBase *GfxBase;
|
extern struct GfxBase *GfxBase;
|
struct View;
|
struct View;
|
static __inline void
|
static __inline void
|
LoadView (struct View *view)
|
LoadView (struct View *view)
|
{
|
{
|
register struct GfxBase* a6 __asm("a6") = GfxBase;
|
register struct GfxBase* a6 __asm("a6") = GfxBase;
|
register struct View *a1 __asm("a1") = view;
|
register struct View *a1 __asm("a1") = view;
|
__asm __volatile ("jsr a6@(-0xde)"
|
__asm __volatile ("jsr a6@(-0xde)"
|
: /* no output */
|
: /* no output */
|
: "r" (a6), "r" (a1)
|
: "r" (a6), "r" (a1)
|
: "a0","a1","d0","d1", "memory");
|
: "a0","a1","d0","d1", "memory");
|
}
|
}
|
|
|
static __inline void change_stack (char *stackp)
|
static __inline void change_stack (char *stackp)
|
{
|
{
|
__asm__ volatile ("movel %0,sp\n\t" :: "g" (stackp) : "sp");
|
__asm__ volatile ("movel %0,sp\n\t" :: "g" (stackp) : "sp");
|
}
|
}
|
|
|
static __inline void disable_cache (void)
|
static __inline void disable_cache (void)
|
{
|
{
|
__asm__ volatile ("movec %0,cacr" :: "d" (0));
|
__asm__ volatile ("movec %0,cacr" :: "d" (0));
|
}
|
}
|
|
|
static __inline void disable_mmu (void)
|
static __inline void disable_mmu (void)
|
{
|
{
|
if (SysBase->AttnFlags & AFF_68040)
|
if (SysBase->AttnFlags & AFF_68040)
|
__asm__ volatile ("moveq #0,d0;"
|
__asm__ volatile ("moveq #0,d0;"
|
".long 0x4e7b0003;" /* movec d0,tc */
|
".long 0x4e7b0003;" /* movec d0,tc */
|
".long 0x4e7b0004;" /* movec d0,itt0 */
|
".long 0x4e7b0004;" /* movec d0,itt0 */
|
".long 0x4e7b0005;" /* movec d0,itt1 */
|
".long 0x4e7b0005;" /* movec d0,itt1 */
|
".long 0x4e7b0006;" /* movec d0,dtt0 */
|
".long 0x4e7b0006;" /* movec d0,dtt0 */
|
".long 0x4e7b0007" /* movec d0,dtt1 */
|
".long 0x4e7b0007" /* movec d0,dtt1 */
|
: /* no outputs */
|
: /* no outputs */
|
: /* no inputs */
|
: /* no inputs */
|
: "d0");
|
: "d0");
|
else {
|
else {
|
__asm__ volatile ("subl #4,sp;"
|
__asm__ volatile ("subl #4,sp;"
|
"pmove tc,sp@;"
|
"pmove tc,sp@;"
|
"bclr #7,sp@;"
|
"bclr #7,sp@;"
|
"pmove sp@,tc;"
|
"pmove sp@,tc;"
|
"addl #4,sp");
|
"addl #4,sp");
|
if (SysBase->AttnFlags & AFF_68030)
|
if (SysBase->AttnFlags & AFF_68030)
|
__asm__ volatile ("clrl sp@-;"
|
__asm__ volatile ("clrl sp@-;"
|
".long 0xf0170800;" /* pmove sp@,tt0 */
|
".long 0xf0170800;" /* pmove sp@,tt0 */
|
".long 0xf0170c00;" /* pmove sp@,tt1 */
|
".long 0xf0170c00;" /* pmove sp@,tt1 */
|
"addql #4,sp");
|
"addql #4,sp");
|
}
|
}
|
}
|
}
|
|
|
static __inline void jump_to (unsigned long addr)
|
static __inline void jump_to (unsigned long addr)
|
{
|
{
|
__asm__ volatile ("jmp %0@" :: "a" (addr));
|
__asm__ volatile ("jmp %0@" :: "a" (addr));
|
/* NOTREACHED */
|
/* NOTREACHED */
|
}
|
}
|
|
|
#endif /* BOOTSTRAP_H */
|
#endif /* BOOTSTRAP_H */
|
|
|