[comp.sources.amiga] v90i222: SetCPU 1.60 - identify and adjust parameters based on cpu type, Part02/04

amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (08/15/90)

Submitted-by: daveh@cbmvax.commodore.com (Dave Haynie)
Posting-number: Volume 90, Issue 222
Archive-name: util/setcpu-1.60/part02

#!/bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 4)."
# Contents:  SetCPU.h coolhand.c memory.c mmu.c
# Wrapped by tadguy@abcfd20 on Tue Aug 14 17:35:35 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'SetCPU.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'SetCPU.h'\"
else
echo shar: Extracting \"'SetCPU.h'\" \(10417 characters\)
sed "s/^X//" >'SetCPU.h' <<'END_OF_FILE'
X/*
X	SetCPU V1.60
X	by Dave Haynie, April 13, 1990
X	Released to the Public Domain
X
X	HEADER FILE
X*/
X
X
X#define PROGRAM_VERSION	160
X
X#include <exec/types.h>
X#include <exec/execbase.h>
X#include <exec/nodes.h>
X#include <exec/lists.h>
X#include <exec/memory.h>
X#include <exec/io.h>
X#include <devices/trackdisk.h>
X#include <libraries/expansionbase.h>
X#include <libraries/configregs.h>
X#include <libraries/configvars.h>
X#include <graphics/gfxbase.h>
X#include <graphics/gfxmacros.h>
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X#include <libraries/dosextens.h>
X#include <libraries/filehandler.h>
X#include <functions.h>
X#include <stdio.h>
X#include <ctype.h>
X
X/* ====================================================================== */
X
X/* Define all bit components used for manipulation of the Cache Control
X   Register. */
X
X#define CACR_INST	((ULONG)(1L<<0))
X#define CACR_DATA	((ULONG)(1L<<8))
X#define CACR_FIXED	((ULONG)(CACR_DATA<<CACR_WALLOC))
X
X#define CACR_WALLOC	5
X#define CACR_BURST	4
X#define CACR_CLEAR	3
X#define CACR_ENTRY	2
X#define CACR_FREEZE	1
X#define CACR_ENABLE	0
X
X#define CACR_ENABLE40	15
X#define CACR_DATA40	16
X
X/* ====================================================================== */
X
X/* Define important bits used in various MMU registers. */
X
X/* Here are the CRP definitions.  The CRP register is 64 bits long, but
X   only the first 32 bits are control bits, the next 32 bits provide the
X   base address of the table. */
X
X#define	CRP_UPPER	(1L<<31)		/* Upper/lower limit mode */
X#define CRP_LIMIT(x)	((ULONG)((x)&0x7fff)<<16)/* Upper/lower limit value */
X#define CRP_SG		(1L<<9)			/* Indicates shared space */
X#define CRP_DT_INVALID	0x00			/* Invalid root descriptor */
X#define	CRP_DT_PAGE	0x01			/* Fixed offset, auto-genned */
X#define CRP_DT_V4BYTE	0x02			/* Short root descriptor */
X#define	CRP_DT_V8BYTE	0x03			/* Long root descriptor */
X
X/* Here are the TC definitions.  The TC register is 32 bits long. */
X
X#define	TC_ENB		(1L<<31)		/* Enable the MMU */
X#define	TC_SRE		(1L<<25)		/* For separate Supervisor */
X#define	TC_FCL		(1L<<24)		/* Use function codes? */
X#define	TC_PS(x)	((ULONG)((x)&0x0f)<<20)	/* Page size */
X#define TC_IS(x)	((ULONG)((x)&0x0f)<<16)	/* Logical shift */
X#define	TC_TIA(x)	((ULONG)((x)&0x0f)<<12)	/* Table indices */
X#define	TC_TIB(x)	((ULONG)((x)&0x0f)<<8)
X#define TC_TIC(x)	((ULONG)((x)&0x0f)<<4)
X#define	TC_TID(x)	((ULONG)((x)&0x0f)<<0)
X
X/* Here are the page descriptor definitions, for short desctriptors only,
X   since that's all I'm using at this point. */
X   
X#define	PD_ADDR(x)	((ULONG)(x)&~0x0fL)	/* Translated Address */
X#define IV_ADDR(x)	((ULONG)(x)&~0x03L)	/* Invalid unused field */	
X#define	PD_WP		(1L<<2)			/* Write protect it! */
X#define PD_CI		(1L<<6)			/* Cache inhibit */
X#define PD_DT_TYPE	0x03			/* Page descriptor type */
X#define PD_DT_INVALID	0x00			/* Invalid root descriptor */
X#define	PD_DT_PAGE	0x01			/* Fixed offset, auto-genned */
X#define PD_DT_V4BYTE	0x02			/* Short root descriptor */
X#define	PD_DT_V8BYTE	0x03			/* Long root descriptor */
X
X/* This is needed for identification of bogus systems that test positive
X   for MMUs. */
X
X#define BOGUSMMU	0xffffffffL
X
X/* Here's the MMU support stuff. */
X
X#define ROMROUND	0x00020000L	/* ROM/Main level at 128K grain */
X#define SMALLROMSIZE	0x00040000L
X#define BIGROMSIZE	0x00080000L
X#define DEVROUND	0x00004000L	/* Device level at 16K grain */
X#define STKROUND	0x00000400L	/* Stack level at 1K grain */
X#define TABROUND	0x00000400L	/* Table alignment matches page size */
X#define PAGESIZE	0x00020000L
X#define MAINTABSIZE	(128L * sizeof(ULONG))
X#define SUBTABSIZE	(8L * sizeof(ULONG))
X#define STKTABSIZE	(16L * sizeof(ULONG))
X
X/* Magic ROM numbers */
X
X#define MAGIC_256	0x11114ef9
X#define MAGIC_512	0x11144ef9
X   
X/* ====================================================================== */
X
X/* Some external system declarations. */
X
Xextern BPTR Lock(), Open();
X
X/* Checking logic */
X
X#define	CK68000		0
X#define CK68010		1
X#define CK68020		2
X#define CK68030		3
X#define CK68040		4
X#define CK68851		5
X#define CK68881		6
X#define CK68882		7
X#define CKFPU		8
X#define CKMMU		9
X#define CKMMUON		10
X#define CKMMUROM	11
X#define CKMMUALIEN	12
X#define CHECKS		13
X
X#define	WARNING	5
X#define READOK	0L
X
X#define SizeOf(x)	((ULONG)sizeof(x))
X#define min(a,b)	((a<b)?a:b)
X#define max(a,b)	((a>b)?a:b)
X
X/* ====================================================================== */
X
X/* From the CONTROL.A module */
X
Xextern void			SetCACR(),
X		 		GetCRP(),
X				SetCRP(),
X				SetTC();
X
Xextern ULONG			GetCACR(),
X				*GetVBR(),
X 				GetTC();
X
X/* ====================================================================== */
X
X/* From the IDENTS.A module */
X
Xextern ULONG			GetCPUType(),
X				GetMMUType(),
X				GetFPUType();
X
X/* ====================================================================== */
X
X/* From the OTHER.A module */
X
Xextern void			SetMMUTag(),
X				FlushATC(),
X				SetKeyDelay();
X
Xextern ULONG			KeyCode,
X				KeyCodeSize,
X				BerrCode,
X				BerrCodeSize;
X
X/* ====================================================================== */
X
X/* From the REBOOT.A module. */
X
Xextern void	 		ROMBoot(),
X				CleanBoot();
X
Xextern ULONG			BootCode,
X				BootCodeSize,
X				ResetCode,
X				ResetCodeSize;
X
X
X/* ====================================================================== */
X
X/* From the EXPDEV.C module. */
X
X/* This structure is device information used by the memory mapping routine. */
X
Xstruct ExpROMData {
X   struct ExpROMData *next;
X   ULONG ROMbase;
X   ULONG ROMsize;
X   ULONG imagebase;
X   ULONG tablebase;
X   char *name;	
X};
X
Xextern LONG				ReadExpDevs();
Xextern struct ExpROMData		*GetExpROM();
Xextern void				FreeExpROM(),
X					SafeConfigDevs();
X
X/* ====================================================================== */
X
X/* From the MISC.C module. */
X
X/* Patch types */
X
X#define PT_STRING	1
X#define PT_JSR		2
X#define PT_END		3
X#define PT_IGNORE	4
X#define PT_KEYBOARD	5
X
X/* This is a item */
X
Xstruct pitem {
X   UWORD Type;		/* The type of patch to apply */
X   UWORD Pad;		/* Nothing here yet... */
X   ULONG Offset;	/* The offset at which to apply the patch */
X   ULONG Length;	/* The length of the patch item */
X   UWORD *Code;		/* The actual patch item */
X};
X
X/* This is the patch structure. */
X
Xstruct patch {
X   struct patch *next;	/* Next patchlist */
X   struct pitem *list;	/* First item in this patchlist */
X   UWORD Version;	/* Which ROM version */
X   UWORD Revision;	/*   and revision */
X};
X
X/* These are the some patch system variables. */
X
X#define KEYPATCH		0
X
Xextern struct patch 		SystemPatch[];
Xextern struct MemChunk 		*lastpatch;
X
X/* The actual functions. */
X
Xextern LONG			striequ(),
X				strniequ();
X
Xextern void			MotorOff();
Xextern BYTE			ReadBuf();
Xextern LONG			CheckTDDev();
X
Xextern LONG			AddPatch();
X
X/* ====================================================================== */
X
X/* From the MMU.C module. */
X
Xextern void 			Phantom(),
X				SetMMURegs(),
X				FillBasicTable(),
X				FreeMMUTable(),
X				MakeExpTable(),
X				MakeFastStack(),
X				FreeFastStack();
X
X/* ====================================================================== */
X
X/* From the MEMORY.C module. */
X
X/* This section describes the system tag structure, where I stick all the
X   information that I like to keep around.  */
X   
X#define ROM_NOP			0x0000	/* No ROM operation called for */
X#define ROM_FAST		0x0002	/* Normally installed FASTROM image */
X#define ROM_KICK		0x0003	/* Installed as a KICK image */
X#define ROM_FKICK		0x0004	/* A KICK image made into a FAST image */
X 
X/* This was originally the patchtag structure, which looked like a patch.  I 
X   decided that was real kludgy.  I hook the systag onto an invalid page 
X   descriptor which I locate in the physical ROM image, a place that should 
X   always be safe to have an invalid tag structure.  Don't change this without
X   checking in the "030Stuff.a" file -- some of these structure members are
X   used by the reboot code. */
X
Xstruct systag {
X   ULONG 		tagsize;	/* Size of this tag */
X   ULONG 		progver;	/* The program version */
X   ULONG		*maintable;	/* The main ROM table */
X   ULONG		*romhi;		/* The main ROM image */
X   UWORD 		romtype;	/* Type of MMU ROM */
X   UWORD 		patches;	/* The number of other patches applied */
X   struct MemChunk 	*patchlist;	/* List of installed patches */
X   struct ExpROMData	*devs;		/* Translated device ROMs */
X   ULONG		TC;		/* Precomputed TC used for KICK. */
X   ULONG		CRP[2];		/* Precomputed CRP used for KICK. */
X   UWORD		config;		/* Configuration status. */
X   ULONG		BerrSize;	/* Size of bus error handler. */
X   char			*OldBerr;	/* The old BERR routine. */
X   char			*BerrHandler;	/* My BERR routine. */
X   short		wrapup;		/* Upper address wrap bound. */
X   short		wrapdown;	/* Lower address wrap bound. */
X   ULONG		tablesize;	/* Main table size. */
X   char			*ResetCode;	/* Actual reset routine */
X   ULONG		romsize;	/* Size of ROM image */
X   ULONG		romloc;		/* Where does the fool thing go? */
X   ULONG		romstart;	/* And where do we start it up? */
X   ULONG		*romlo;		/* Secondary ROM image, if needed */
X   char			*sysstack;	/* Physical system stack image */
X   ULONG		sysstksize;	/* System Stack allocated size. */
X   ULONG		ResetSize;	/* Size of the reset code. */
X   char			*OldReset;	/* Old Reset Code */
X};
X
X/* The actual functions */
X
Xextern void 			MemCopy(),
X				SetMMURegs(),
X				*AllocAligned(),
X				SnoopSpecial(),
X				FillBasicTable(),
X				FreeSAFEImage();
XULONG *				SizeROM();
Xextern struct systag		*AllocROMImage(),
X				*AllocDISKImage(),
X				*AllocSAFEImage(),
X				*GetSysTag();
Xextern LONG			SmartlyGetRange();
X
X/* ====================================================================== */
X
X/* From the DISKIO.C module. */
X
Xextern struct systag 	*AllocKSImage(),
X			*AllocFILEImage(),
X			*AllocDISKImage();
X
X/* ====================================================================== */
X
X/* From the COOLHAND.C module. */
X
Xstruct Window *CoolHand();
X
X/* ====================================================================== */
X
X/* Intermodule globals */
X
Xstruct CfgBlock {
X   ULONG Addr, Size;
X};
X
X#ifdef MAIN_MODULE
Xstruct ExpansionBase *ExpansionBase = NULL;	/* The expansion library */
Xunsigned short LoadErr = 16;
Xstruct CfgBlock Bridge = { 0L, 0L }, A26x0 = { 0L, 0L };
X#else
Xextern struct ExpansionBase *ExpansionBase;
Xextern unsigned short LoadErr, forcewrap;
Xextern struct CfgBlock Bridge, A26x0;
Xextern BOOL allochead,aliens;
Xextern ULONG cpu;
X#endif
X
END_OF_FILE
if test 10417 -ne `wc -c <'SetCPU.h'`; then
    echo shar: \"'SetCPU.h'\" unpacked with wrong size!
fi
# end of 'SetCPU.h'
fi
if test -f 'coolhand.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'coolhand.c'\"
else
echo shar: Extracting \"'coolhand.c'\" \(7518 characters\)
sed "s/^X//" >'coolhand.c' <<'END_OF_FILE'
X/*
X	SetCPU V1.60
X	by Dave Haynie, April 13, 1990
X	Released to the Public Domain
X
X	COOLHAND MODULE
X
X	This module contains the code used to display a cool looking 
X	KickStart prompt hand on the screen.
X*/
X
X#include "setcpu.h"
X
X/* ====================================================================== */
X
X/* This is the KickStart hand design as in the A1000.  Only, Intuition makes
X   it considerably easier to build than they way the Kernel ROM does it. */
X   
X/* Define the vectors.  The hand is a drawing composed of a series of line
X   vectors.  Intuition provides a handy structure, called a boarder, that'll
X   render this whole mess with a single function call. */
X
Xstatic WORD vect1[] = {  0,  0, 23,  0, 23, 22, 78, 22, 78,  0, 90,  0,101, 11,
X                       101, 83, 92, 83, 92, 45, 29, 45, 27, 43, 18, 43, 17, 45,
X                        10, 45, 10, 54,  0, 61,  0,  0 };
Xstatic WORD vect2[] = {  0,  0,  0,-62, 93,-62,105,-50,105, 23, 53, 23, 53, 28,
X                        49, 36, 45, 41, 41, 44, 35, 53, 27, 57, 27, 68,-23, 68,
X                       -23, 37,-24, 37,-24,  9,-20,  3,-13, -3,-12, -7, -8,-14,
X                        -3,-17,  0,-18,  0,-18, -3,-16, -7,-14,-11, -7,-12, -3,
X                       -19,  3,-23,  9,-23, 36,-22, 37,-22, 67,  7, 67,  7, 46,
X                        15, 46, 19, 44, 19, 23, 17, 20, 17, 10, 32, -3, 32,-15,
X                        29,-17, 26,-17, 29,-14, 29, -7, 28, -6, 21, -6, 18, -9,
X                         9, -2, -3,  4,-15, 13,-15, 12, -3,  3, -7,  2,-10, -1,
X                        -7,  1, -3,  2,  0,  0 };
Xstatic WORD vect3[] = {  0,  0,  2, -7, 10, -6, 11, -3, 11,  4,  4,  4,  0,  0 };
Xstatic WORD vect4[] = {  0,  0,  0,-10, 15,-23, 15,-35, 74,-35, 74,  2,  1,  2,
X                         0, -2 };
Xstatic WORD vect5[] = {  0,  0, 51,  0, 51, 21,  0, 21,  0,  0 };
Xstatic WORD vect6[] = {  0,  0, 11,  0, 11, 14,  0, 14,  0,  0 };
Xstatic WORD vect7[] = {  0,  0,  7,  0,  7, 12,  0, 12,  0,  0 };
Xstatic WORD vect8[] = {  0,  0,  3,  0,  3,  2,  0,  6,  0,  0 };
Xstatic WORD vect9[] = {  0,  0,  0,-20,  7,-20, 12,-25, 12,-34, 16,-32, 24,-32,
X                        24,-30, 28,-25, 32,-25, 32,-23, 26,-14, 18,-11, 18,  0,
X                         0,  0 };
Xstatic WORD vect10[] = { 0,  0,  0,  5,  5,  2,  0,  0 };
Xstatic WORD vect11[] = { 0,  0, -4,  2, -4, -3, 17, -3,  7,  7,  6,  7,  8,  5,
X                         3,  0,  0,  0 };
X
Xstatic WORD vect12[] = { 0,  0,  7,  0,  7,  5,  3, 13,  0, 17, -5, 18, -8, 18,
X                       -11, 14,-11, 11,  0,  0 };
X
Xstatic WORD vect13[] = { 0,  0,  0,  3,  2,  6,  2,  6,  8,  5,  9,  2,  5, -1,
X                         0,  0 };
Xstatic WORD vect14[] = { 0,  0,  8,  2, 10, -1,  6, -5,  3, -5,  0, -3,  0,  0 };
Xstatic WORD vect15[] = { 0,  0, 11, 11, 11, 83 };
X
Xstatic struct Border HandLines[] = {
X   { 105, 51,1,0,JAM1,18, &vect1[0], &HandLines[1] },
X   { 103,112,1,0,JAM1,59, &vect2[0], &HandLines[2] },
X   { 120,101,1,0,JAM1, 7, &vect3[0], &HandLines[3] },
X   { 121,132,1,0,JAM1, 8, &vect4[0], &HandLines[4] },
X   { 130, 51,1,0,JAM1, 5, &vect5[0], &HandLines[5] },
X   { 166, 54,1,0,JAM1, 5, &vect6[0], &HandLines[6] },
X   { 168, 55,1,0,JAM1, 5, &vect7[0], &HandLines[7] },
X   { 117, 97,1,0,JAM1, 5, &vect8[0], &HandLines[8] },
X   { 111,179,1,0,JAM1,15, &vect9[0], &HandLines[9] },
X   { 123,135,1,0,JAM1, 4,&vect10[0],&HandLines[10] },
X   { 127,138,1,0,JAM1, 9,&vect11[0],&HandLines[11] },
X   { 148,135,1,0,JAM1,10,&vect12[0],&HandLines[12] },
X   { 138,146,1,0,JAM1, 8,&vect13[0],&HandLines[13] },
X   { 124,144,1,0,JAM1, 7,&vect14[0],&HandLines[14] },   
X   { 196, 51,1,0,JAM1, 3,&vect15[0],NULL },
X};
X
X/* This is a list of area fills to perform; the first number is the "A" pen
X   to set, the next two numbers are the screen position to start filling
X   from. */
X
Xstatic WORD FillList[][3] = {
X   { 2, 107,109 }, { 3, 132, 71 }, { 2, 169, 66 }, { 1, 104, 51 },
X   { 1, 129, 51 }, { 1, 167, 55 }, { 1, 176, 67 }, { 1, 182, 55 },
X   { 1, 196,134 }, { 1, 145,136 }, { 1, 116, 97 }
X};
X
X#define FILLCNT	11
X
X/* Finally, I've got a few images to render, which I do using the standard
X   Intuition Image structures. */
X
XUWORD image0[] = {	/* AMIGA */
X   0x1f9f,0xfe3f,0xff77,0xfe7c, 0x070c,0xef8f,0x1e71,0xdc30,
X   0x07f8,0xe7ce,0x1cf3,0x1fe0, 0x0731,0xf3ce,0x1df6,0x1cc0,
X   0x0760,0x03dc,0x3ffc,0x1d80, 0x07c0,0x879c,0x3f78,0x1f00,
X   0x0780,0xcf78,0x7e78,0x1e00, 0x0700,0xfeff,0xfc7c,0x1c00,
X   0x1001,0x8220,0x4050,0x0004, 0x0404,0x8889,0x1210,0x5010,
X   0x0408,0x2448,0x1090,0x1020, 0x0410,0x1042,0x0510,0x1040,
X   0x0420,0x0050,0x2690,0x1080, 0x0440,0x0484,0x0900,0x1100,
X   0x0480,0x4960,0x4208,0x1200, 0x0500,0x0683,0x8404,0x1400,
X};
X
XUWORD image1[] = {	/* Kick */
X   0xc71f,0x1e63,0x8000, 0x6631,0x8c63,0x0000, 0x3e01,0x8c33,0x0000, 
X   0x6631,0x8c1f,0x0000, 0xc61f,0x0e33,0x0000, 0x0600,0x0063,0x0000,
X   0x0700,0x0c63,0x8000
X};
X
XUWORD image2[] = {	/* Start */
X   0x703c,0xdc38,0x3e00, 0x9818,0x664c,0x6000, 0x1998,0x780c,0x3c00,
X   0x19b8,0x600c,0x0600, 0x7cdc,0x3c3e,0x7c00, 0x1800,0x000c,0x0000,
X   0x1000,0x0008,0x0000
X};
X
Xstruct Image NameImage[] = {
X   { 126,122,64,8,2,&image0[0],3,0,&NameImage[1] },
X   { 144,112,48,7,1,&image1[0],2,0,&NameImage[2] },
X   { 140,102,48,7,1,&image2[0],2,0,NULL }   
X};
X
X/* Here's the color scheme. */
X
Xstatic WORD coolColor[] = { 0x0fff,0x0000,0x077c,0x0bbb };
X
X/* ====================================================================== */
X
X/* This section contains data for the mechanics of the CoolHand. */
X
Xstatic struct NewScreen newScreen = {
X   0,0,320,200,2,0,1,0,CUSTOMSCREEN,NULL,NULL,NULL,NULL
X};
X
Xstatic struct NewWindow newWindow = {
X   0,0,320,200,2,0,0,BORDERLESS|ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,
X   CUSTOMSCREEN
X};
X
Xstatic struct Screen	*coolScreen;
Xstatic struct Window	*coolWindow, *coolShade;
X
Xstruct GfxBase		*GfxBase;
Xstruct IntuitionBase	*IntuitionBase;
X
X/* ====================================================================== */
X
X/* This is the main section.  Since I consider the CoolHand prompt the end
X   of this life and the beginning of the next, I'm not going to worry about
X   freeing stuff up. */
X   
Xstruct Window *CoolHand() {
X   struct RastPort *rp;
X   struct ViewPort *vp;
X   struct Image *image;
X   LONG size;
X   UWORD i,*bits,*pointer;
X   BOOL ok = TRUE;
X
X   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L);
X   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
X   if (!GfxBase || !IntuitionBase) return;
X   if (!(coolScreen = OpenScreen(&newScreen))) return;
X   ShowTitle(coolScreen,0L);
X   LoadRGB4(vp = &coolScreen->ViewPort,&coolColor[0],4L);
X   newWindow.Screen = coolScreen;
X   pointer = (UWORD *)AllocMem(64L,MEMF_CHIP|MEMF_CLEAR);
X   if (!(coolShade = OpenWindow(&newWindow))) return;
X   if (!(coolWindow = OpenWindow(&newWindow))) return;
X   WindowToFront(coolShade);
X   SetPointer(coolWindow,pointer,2L,2L,0L,0L);
X   Delay(25L);
X   DrawBorder(rp = coolWindow->RPort,&HandLines[0],0L,0L);
X
X   SetOPen(rp,1L);
X   for (i = 0; i < FILLCNT; ++i) {
X      SetAPen(rp,(long)FillList[i][0]);
X      Flood(rp,0L,(long)FillList[i][1],(long)FillList[i][2]);
X   }
X   for (image = &NameImage[0]; image; image = image->NextImage) {
X      size = (LONG) (((image->Width+15)/16)*image->Height)*2*image->Depth;
X      movmem((char *)image->ImageData,
X             (char *)(bits = (UWORD *)AllocMem(size,MEMF_CHIP)),
X             (int)size);
X      image->ImageData = bits;
X   }
X   DrawImage(rp,&NameImage[0],0L,0L);
X   CloseWindow(coolShade);
X   return coolWindow;
X}
END_OF_FILE
if test 7518 -ne `wc -c <'coolhand.c'`; then
    echo shar: \"'coolhand.c'\" unpacked with wrong size!
fi
# end of 'coolhand.c'
fi
if test -f 'memory.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'memory.c'\"
else
echo shar: Extracting \"'memory.c'\" \(11245 characters\)
sed "s/^X//" >'memory.c' <<'END_OF_FILE'
X/*
X	SetCPU V1.60
X	by Dave Haynie, April 13, 1990
X	Released to the Public Domain
X
X	MEMORY.C MODULE
X
X	This module is responsible for ROM image allocation, MMU table
X	allocation and creation, and other functions based on memory.
X*/
X
X#include "setcpu.h"
X
X/* ====================================================================== */
X
X/* Local data types */
X
Xstruct range {
X   ULONG first;
X   ULONG last;
X};
X
X/* ====================================================================== */
X
X/* This function copies from the source to the destination, by longword, with
X   BYTE length "length". */
X
Xvoid MemCopy(src,des,len)
XULONG *src, *des;
XULONG len;
X{
X   len = (len + 3)>>2;
X   while (len--) *des++ = *src++;
X}
X
X/* ====================================================================== */
X
X/* This section contains the memory allocation code.  There are two
X   problems here.  First of all, we'd like to use 32 bit FAST memory if 
X   at all possible.  Next, block translation and page tables must be on at
X   least a page sized boundary, if not a block boundary.  */
X   
X/* This routine finds the memory block for me to use in AllocAligned().
X   It takes into account either A2620 or A2630 systems, where I can snoop 
X   out the memory for that particular board, knowing it's the fastest.  I
X   can adjust for 1.4's automatic memory merging in this case too, to be
X   sure I have 32 bit RAM.  If I don't have one of my boards, I'll return 
X   a pointer to the first non-$C00000 memory list marked as FAST. */
X
Xstatic struct range SRange = { 0L, 0L };
Xstatic ULONG MaxMem = 0;
X
XLONG SmartlyGetRange() {
X   struct ExecBase *eb = *((struct ExecBase **)4L);
X   register struct MemHeader *mem;
X
X   /* First try for either A2620 or A2630 */
X   
X   if (A26x0.Addr && A26x0.Size) {
X      SRange.first = A26x0.Addr;
X      SRange.last = A26x0.Size + SRange.first;
X   } 
X
X   /* For another critters, but we go here to find MaxMem, even
X      if we know it's an A26x0. */
X
X   for (mem = (struct MemHeader *)eb->MemList.lh_Head; mem->mh_Node.ln_Succ;
X        mem = (struct MemHeader *)mem->mh_Node.ln_Succ) {
X      if ((ULONG)(mem->mh_Upper) > MaxMem) MaxMem = (ULONG)mem->mh_Upper;
X      if (mem->mh_Attributes & MEMF_CHIP) continue;
X      if (((ULONG)mem >= 0xc00000 && (ULONG)mem <= 0xc80000)) continue;
X      if (!SRange.first) {
X         SRange.first = (ULONG)mem->mh_Lower;
X         SRange.last = (ULONG)mem->mh_Upper;
X      }
X   }
X   if (SRange.first) 
X      return TRUE;
X   return FALSE;
X}
X
X/* This routine allocates such an aligned block of memory from a specified 
X   memory list. */
X   
Xvoid *AllocAligned(size,bound)
Xregister ULONG size;
Xregister ULONG bound;
X{
X   register ULONG target;
X   void *mem = NULL;
X
X   Forbid();
X   if (!allochead) {
X      target = (SRange.last-size) & ~(bound-1);
X      while (target > SRange.first && !(mem = AllocAbs(size,target)))
X         target -= bound;
X      SRange.last = (ULONG)mem;
X   } else {
X      target = (SRange.first+size+bound-1) & ~(bound-1);
X      while (target < SRange.last && !(mem = AllocAbs(size,target)))
X         target += bound;
X      SRange.first = (ULONG)mem+size;
X   }
X   Permit();
X   return mem;
X}
X
X/* This routine finds the memory wrap and appropriate MMU table size for
X   the given configuration. It requires the value of MaxMem to have been
X   already calculated. */
X   
Xvoid FindWrap(tag)
Xstruct systag *tag;
X{
X   ULONG test;
X     
X   if (forcewrap == -1) {
X      tag->wrapdown = 0;
X      for (test = MaxMem; !(test & 0x80000000) && tag->wrapdown < 8; test <<= 1)
X         tag->wrapdown++;
X   } else
X      tag->wrapdown = forcewrap;
X   tag->tablesize = (128 << (8 - tag->wrapdown)) * sizeof(ULONG);
X}
X
X/* This routine computes the ROM size from the magic tag values. */
X
XULONG CalcROMSize(tagval)
XULONG tagval;
X{
X   if (tagval == MAGIC_256) return SMALLROMSIZE;
X   if (tagval == MAGIC_512) return BIGROMSIZE;
X   return 0L;
X}
X
X/* This function sizes the ROM based on its base value and correctly splits 
X a base address between possible ROM halves. This routine uses the Commodore
X   ROM file format, which is like this:
X
X	0:	00000000
X	4:	size
X	8:	start of ROM
X
X   The ROM, in any case, begins with either "$11114ef9", for 256L ROMs, or
X   "$11144ef9", for 512K ROMs.  The next longword can be used to figure out
X   where the ROM actually goes, in memory. */
X
XULONG *SizeROM(tag,base,getram)
Xstruct systag *tag;
XULONG *base, getram;
X{
X   ULONG *rom = NULL;
X
X   if (!(tag->romsize = CalcROMSize(base[0]))) return NULL;
X
X   if (getram) 
X      if (!(rom = (ULONG *)AllocAligned(tag->romsize,ROMROUND))) return NULL;
X
X   if (tag->romsize == SMALLROMSIZE) {
X      tag->romstart = base[1];
X      tag->romloc = base[1] & 0xfffc0000;
X      tag->romlo = 0L;
X      tag->romhi = rom;
X   } else {
X      tag->romstart = base[1];
X      tag->romloc = base[1] & 0xfff80000;
X      tag->romlo = rom;
X      tag->romhi = (ULONG *)((ULONG)rom + SMALLROMSIZE);
X   }
X   return rom;
X}
X
X/* ====================================================================== */
X
X/* This section contains routines that manage different ROM image types. */
X
X/* This function gets an aligned ROM image copied from system ROM. */
X
Xstruct systag *AllocROMImage(type)
XUWORD type;
X{
X   struct systag *tag = NULL, *oldtag = NULL;
X   ULONG *rom = NULL, *table = NULL, *base;
X   
X  /* Let's make the allocations.  I allocate the ROM first, then the table,
X     then the tag; since we're coming from the end of memory, this should
X     result in the least fragging. */
X
X   SmartlyGetRange();
X   if (!(tag = AllocAligned(SizeOf(struct systag),8L))) goto fail;
X   if (oldtag = GetSysTag())
X      base = (ULONG *)oldtag->romloc;
X   else {
X      if (*(base = (ULONG *)0x00f80000) != MAGIC_512)
X         base = (ULONG *)0x00fc0000;
X   }
X   rom = SizeROM(tag,base,TRUE);
X   FindWrap(tag);
X   if (!(table = AllocAligned(tag->tablesize+4,TABROUND))) goto fail;
X   tag->maintable = table;
X   tag->romtype = type;
X   MemCopy(tag->romloc,rom,tag->romsize);
X   FillBasicTable(tag,FALSE);
X   return tag;
X
Xfail:
X   if (rom)   FreeMem(rom,tag->romsize);
X   if (table) FreeMem(table,tag->tablesize+4);
X   if (tag)   FreeMem(tag,SizeOf(struct systag));
X   return NULL;
X}
X
X/* This function gets an aligned, reset-safe image in either $00C00000 or 
X   CHIP memory, copies the ROM code from the passed temporary image, and 
X   then sets up it's MMU table such that the memory used for the safe image
X   will be missed by the Amiga's memory-sizing logic on reboot. */
X
Xstruct systag *AllocSAFEImage(temp)
Xstruct systag *temp;
X{
X   struct ExecBase *eb = *((struct ExecBase **)4L);
X   struct MemHeader *safe, *safeC000 = NULL, *safeCHIP = NULL, *tmem;
X   struct systag *tag;
X   ULONG upper, base, *table;
X
X   for (safe = (struct MemHeader *)eb->MemList.lh_Head; safe->mh_Node.ln_Succ; 
X        safe = (struct MemHeader *)safe->mh_Node.ln_Succ) {
X      tmem = (struct MemHeader *)safe;
X      if ((ULONG)(tmem->mh_Upper) > MaxMem) MaxMem = (ULONG)tmem->mh_Upper;      
X      if (tmem->mh_Attributes & MEMF_CHIP) {
X         if (!safeCHIP || safeCHIP->mh_Upper < tmem->mh_Upper)
X            safeCHIP = tmem;
X      } else if ((ULONG)safe >= 0xc00000 && (ULONG)safe <= 0xc80000) {
X         if (!safeC000 || safeC000->mh_Upper < tmem->mh_Upper)
X            safeC000 = tmem;
X      }
X   }
X
X  /* Will it fit?  You need at least 1 meg of memory. */
X
X   if (!safeC000 && safeCHIP->mh_Upper < 0x080000L) return NULL;
X
X  /* Now, where should it go. */
X
X   if (safeC000)
X      upper = ((ULONG)safeC000->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
X   else if (safeCHIP)
X      upper = ((ULONG)safeCHIP->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
X
X   FindWrap(temp);
X   table = (ULONG *)(base = upper-ROMROUND);
X   tag = (struct systag *)(base = (base + temp->tablesize + 36L) & ~7L);
X   *tag = *temp;
X   tag->maintable = table;
X   
X   if (temp->romlo) {
X      tag->romlo = (ULONG *)(upper - SMALLROMSIZE - ROMROUND);
X      if (safeC000) {
X         upper = ((ULONG)safeCHIP->mh_Upper+ROMROUND-1L) & ~(ROMROUND-1L);
X         tag->romhi = (ULONG *)(upper - SMALLROMSIZE);
X      } else
X         tag->romhi = (ULONG *)(upper - SMALLROMSIZE*2 - ROMROUND);
X   } else {
X      tag->romhi = (ULONG *)(upper - temp->romsize - ROMROUND);
X      tag->romlo = 0L;
X   }
X
X  /* Other tag initializations. */
X
X   tag->romtype = ROM_KICK;
X   FillBasicTable(tag,TRUE);
X
X   base = (base + SizeOf(struct systag) + 32L) & ~7L;
X
X   tag->BerrHandler = (char *)(base = (base + SizeOf(struct systag)+32L) & ~7L);
X   tag->BerrSize = (BerrCodeSize + 4) & ~3L;
X
X   if (tag->romlo) MemCopy(temp->romlo,tag->romlo,SMALLROMSIZE);
X   MemCopy(temp->romhi,tag->romhi,SMALLROMSIZE);
X
X   tag->ResetCode = (char *)(base = (base + BerrCodeSize + 32L) & ~7L);
X   tag->ResetSize = BerrCodeSize;
X   MemCopy(BootCode,tag->ResetCode,BootCodeSize);
X
X   return tag;
X}
X
X/* This function returns memory to the system, automatically setting the
X   appropriate memory flags. */
X
Xvoid ReturnMem(size,mem)
XULONG size;
XULONG mem;
X{
X   if (mem < 0x00200000)
X      AddMemList(size,MEMF_CHIP|MEMF_PUBLIC,-15L,(char *)mem,NULL);
X   else if (mem >= 0x00c00000 && mem < 0x00c80000)
X      AddMemList(size,MEMF_FAST|MEMF_PUBLIC,-15L,(char *)mem,NULL);
X   else
X      AddMemList(size,MEMF_FAST|MEMF_PUBLIC,0L,(char *)mem,NULL);
X}
X
X/* This function can be used after rebooting to remove the specially allocated
X   SAFE image.  This is normally used after copying the safe image into a 
X   standard FASTROM image and adjusting the MMU accordingly.  The SAFE RAM
X   at this point isn't in any memory list, so we aren't really freeing it,
X   just linking it into a list. */
X
Xvoid FreeSAFEImage(kick)
Xstruct systag *kick;
X{
X   if (kick->romlo == 0 || (ULONG)kick->romhi+SMALLROMSIZE == (ULONG)kick->romlo)
X      ReturnMem(ROMROUND+kick->romsize,kick->romhi);
X   else {
X      ReturnMem(ROMROUND+SMALLROMSIZE,kick->romlo);
X      ReturnMem(SMALLROMSIZE,kick->romhi);
X   }
X}
X
X/* ====================================================================== */
X
X/* This routine gets the system tag from the patched system, if it's
X   there.  This tag is stored in an invalid table entry that's within the
X   physical ROM image.  If the MMU isn't on, there's no system tag, by
X   definition.  This has been enhanced to perform a sanity check on the
X   tag encountered -- the systag contains a pointer to the table, this
X   can be checked. */
X   
Xstruct systag *GetSysTag() {
X   struct systag *maybetag;
X   ULONG i, myCRP[2], *table = NULL,size;
X   APTR oldTrap;
X   struct Task *task;
X
X   if (cpu == 68040 || !(GetTC() & TC_ENB) || aliens) return NULL;
X
X   GetCRP(myCRP);
X   table = (ULONG *)myCRP[1];
X
X  /* In case the MMU is alien and has some of this memory read protected... */
X   task = FindTask(0L);
X   oldTrap = task->tc_TrapCode;
X   task->tc_TrapCode = (APTR)BerrCode;
X
X  /* The tag is now in an easier-to-locate place. This isn't SetCPU V1.5
X     compatible; SetCPU V1.5 FASTROM will appear alien to SetCPU V1.6. But
X     this is much better for modern systems and modern software. */
X   size = (myCRP[0]>>16)+1;
X   maybetag = (struct systag *)IV_ADDR(table[size]);
X   if (!maybetag || maybetag->maintable != table || maybetag->tablesize != size<<2) 
X      maybetag = NULL;
X
X  /* Restore the trap vector */
X   task->tc_TrapCode = oldTrap;
X   return maybetag;
X}
X
END_OF_FILE
if test 11245 -ne `wc -c <'memory.c'`; then
    echo shar: \"'memory.c'\" unpacked with wrong size!
fi
# end of 'memory.c'
fi
if test -f 'mmu.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mmu.c'\"
else
echo shar: Extracting \"'mmu.c'\" \(8963 characters\)
sed "s/^X//" >'mmu.c' <<'END_OF_FILE'
X/*
X	SetCPU V1.60
X	by Dave Haynie, April 13, 1990
X	Released to the Public Domain
X
X	MMU.C MODULE
X
X	This module is responsible for some of the MMU table creation
X        functions.
X*/
X
X#include "setcpu.h"
X
X
X/* ====================================================================== */
X
X/* This function maps the phantom area for a given memory location. */
X
Xvoid Phantom(tag,loc)
Xstruct systag *tag;
XULONG loc;
X{
X   ULONG xindex = loc/ROMROUND;
X
X   if (xindex < 60)
X      tag->maintable[xindex] = PD_ADDR(0x00800000)|PD_DT_PAGE;
X   else
X      tag->maintable[xindex] = PD_ADDR(0x00ce0000)|PD_DT_PAGE;
X}
X
X
X/* This table contains a list of the blocks of memory that should be 
X   cache-inhibited. */
X
Xstatic ULONG InTable[] = { 0x00000000,0x00200000,0x00b00000,0x00f00000,0L,0L };
X   
X
X/* This function fills the basic MMU table and other standard tag itemd from 
X   an allocated image.  Some tables may need additional information in the 
X   table.  The basic table consists of one table level and uses direct page 
X   translation on a grain of 128K per entry.  Everything's directly mapped 
X   except for the last two entries, which are for the $FC0000-$FFFFFF area. */
X
Xvoid FillBasicTable(tag,phantoms)
Xstruct systag *tag;
XLONG phantoms;
X{
X   register ULONG i, image, j;
X   ULONG page,size,loc;
X	
X   tag->tagsize = SizeOf(struct systag);
X   tag->progver = PROGRAM_VERSION;
X   tag->patches = 0;
X   tag->patchlist = tag->devs = NULL;
X   tag->config = 1;
X   tag->BerrSize = 0L;
X   tag->OldBerr = tag->BerrHandler = NULL;
X   tag->sysstack = NULL;
X   tag->sysstksize = 0;
X   tag->OldReset = tag->ResetCode = NULL;
X   tag->ResetSize = 0;
X
X  /* Here I make a table that maps everything straight through. */
X   for (i = 0; i < tag->tablesize/sizeof(ULONG); i++) 
X      tag->maintable[i] = PD_ADDR(i<<17)|PD_DT_PAGE;
X   tag->maintable[i] = IV_ADDR(tag)|PD_DT_INVALID;
X
X  /* Mark the inhibited pages. */
X   for (i = 0; InTable[i+1]; i += 2)
X      for (j = InTable[i]/PAGESIZE; j < InTable[i+1]/PAGESIZE; ++j)
X         tag->maintable[j] |= PD_CI;
X
X  /* Here I map the ROM image to the ROM location. */
X   image = (ULONG)tag->romlo;
X   loc = tag->romloc/PAGESIZE;
X   if (image) {
X      if (phantoms) Phantom(tag,image);
X      tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
X      if (phantoms) Phantom(tag,image+PAGESIZE);
X      tag->maintable[loc++] = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
X   }
X   image = (ULONG)tag->romhi;
X   if (phantoms) Phantom(tag,image);
X   tag->maintable[loc++] = PD_ADDR(image)|PD_WP|PD_DT_PAGE;
X   if (phantoms) Phantom(tag,image+PAGESIZE);
X   tag->maintable[loc]   = PD_ADDR(image+PAGESIZE)|PD_WP|PD_DT_PAGE;
X
X  /* Here I look for Bridge Cards, which are known to have problems with
X     the data cache enabled, so I always disable it, reguardless of 
X     whether caching is actually enabled in the CACR. */
X
X   if (Bridge.Addr && Bridge.Size) {
X      page = Bridge.Addr/PAGESIZE;
X      size = max((ULONG)Bridge.Size/PAGESIZE,1);
X      while (size-- && page < tag->tablesize)
X         if ((tag->maintable[page] & PD_DT_TYPE) == PD_DT_PAGE)
X            tag->maintable[page++] |= PD_CI;
X   } 	
X}
X
X/* This routine sets up the MMU registers (shadowed in tag fields) in the
X   standard SetCPU fashion.  The CPU Root Pointer tells the MMU about the 
X   table I've set up, and all that's left to do is bang the Translation
X   Control Register to turn the thing on.  Note that the first half of the 
X   CRP is control data, the second the address of my table.  */
X   
Xvoid SetMMURegs(tag)
Xstruct systag *tag;
X{
X   tag->CRP[0] = CRP_LIMIT(tag->tablesize/sizeof(ULONG)-1)|CRP_SG|CRP_DT_V4BYTE;
X   tag->CRP[1] = (ULONG)(tag->maintable);
X
X   tag->TC = TC_PS(0x0a)|TC_IS(tag->wrapup)|
X             TC_TIA(0x0f-tag->wrapup)|TC_TIB(0x03)|TC_TIC(0x04)|TC_TID(0);
X}
X
X/* ====================================================================== */
X
X/* This function frees all MMU tables. */
X
Xvoid FreeMMUTable(tag)
Xstruct systag *tag;
X{
X   ULONG i,j, *subtab;
X
X   for (i = 0; i < 128; ++i)
X      if ((tag->maintable[i] & PD_DT_TYPE) == PD_DT_V4BYTE) {
X         for (subtab = (ULONG *)PD_ADDR(tag->maintable[i]), j = 0; j < 8; ++j)
X            if ((subtab[j] & PD_DT_TYPE) == PD_DT_V4BYTE)
X               FreeMem((char *)PD_ADDR(subtab[j]),STKTABSIZE);
X         FreeMem((char *)subtab,SUBTABSIZE);
X      }
X   FreeMem((char *)tag->maintable,tag->tablesize);
X}
X
X/* ====================================================================== */
X
X/* This function makes subtables for CardROMFile I/O devices. */
X
Xvoid MakeExpTable(tag)
Xstruct systag *tag;
X{
X   ULONG i, *SUBTable, iospace;
X   struct ExpROMData *er;
X
X   while (er = GetExpROM()) {
X      er->next = tag->devs;
X      tag->devs = er;
X
X      iospace = ((ULONG)er->ROMbase)/ROMROUND;
X
X     /* If necessary, modify the table */
X      if (tag->maintable[iospace] == PD_ADDR(iospace<<17)|PD_DT_PAGE) {
X         if (SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) {
X            for (i = 0; i < 8; ++i) 
X               SUBTable[i] = PD_ADDR((iospace<<17)+(i<<14))|PD_CI|PD_DT_PAGE;
X            tag->maintable[iospace] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
X         }
X      } else
X         SUBTable = (ULONG *)PD_ADDR(tag->maintable[iospace]);
X
X      if (SUBTable) {
X         er->imagebase = (ULONG)AllocAligned(er->ROMsize,DEVROUND);
X         er->tablebase = (ULONG)&SUBTable[0];
X
X         MemCopy(er->ROMbase,er->imagebase,er->ROMsize);
X         iospace = (er->ROMbase - (iospace * ROMROUND))/DEVROUND;
X         for (i = 0; i < er->ROMsize/DEVROUND; ++i)
X            SUBTable[iospace+i] = PD_ADDR(er->imagebase+(DEVROUND*i))|PD_CI|PD_DT_PAGE;
X      }
X   }
X}
X
X/* ====================================================================== */
X
X/* This function hunts down the system stack and translates it into a 
X   block of 32 bit memory if it's found to be located in Chip RAM. Note
X   that this routine must only be called when the MMU is turned on.  The
X   current functions used to turn the MMU on make use of the supervisor
X   stack.  This code must be run in user mode to insure that the supervisor
X   stack image and the actual stack are the same during the transfer of
X   control. */
X
Xvoid MakeFastStack(tag)
Xstruct systag *tag;
X{
X   struct ExecBase *eb = *((struct ExecBase **)4L);
X   ULONG i, *SUBTable, *STKTable, tabndx, subndx, stkndx, tmem, base;
X
X   base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
X
X   if (base >= 0x00200000L) return;
X
X   tag->sysstksize = (((ULONG)eb->SysStkUpper - (ULONG)eb->SysStkLower + 1)/STKROUND)*STKROUND;
X   tabndx = base/ROMROUND;
X   tmem = tabndx * ROMROUND;
X
X  /* Make the I/O level subtable (level 2).  Most entries are going to be
X     a straight translation. */
X
X   if (!(SUBTable = AllocAligned(SUBTABSIZE,TABROUND)) ||
X       !(STKTable = AllocAligned(STKTABSIZE,TABROUND))) return;
X
X   for (i = 0; i < 8; ++i) 
X      SUBTable[i] = PD_ADDR(tmem+(i*DEVROUND))|PD_DT_PAGE;
X   tag->maintable[tabndx] = PD_ADDR(SUBTable)|PD_DT_V4BYTE;
X
X  /* Make the Stack level subtable (level 3).  Fill all 16 entries with a
X     straight translation. */
X   
X   subndx = (base - tmem)/DEVROUND;
X   tmem += subndx * DEVROUND;
X
X   for (i = 0; i < 16; ++i)
X      STKTable[i] = PD_ADDR((tmem)+(i*STKROUND))|PD_DT_PAGE;
X   SUBTable[subndx] = PD_ADDR(STKTable)|PD_DT_V4BYTE;
X
X  /* Now take care of the actual stack translation. */
X
X   tag->sysstack = (char *)AllocAligned(tag->sysstksize,STKROUND);
X   MemCopy(base,tag->sysstack,tag->sysstksize);
X
X   stkndx = (base - tmem)/STKROUND;
X   
X   for (i = 0; i < tag->sysstksize/STKROUND && i < 16; ++i)
X      STKTable[i+stkndx] = PD_ADDR(tag->sysstack+(STKROUND*i))|PD_DT_PAGE;
X   FlushATC();
X}
X
X/* This function removes the fast stack translation. Like the fast stack
X   creation routine, this must be called with the MMU turned on, in user
X   mode, so that both stack images can be identical when the switch is
X   made.  This routine doesn't clean up the MMU tables, it just deals
X   with the stack image. */
X
Xvoid FreeFastStack(tag)
Xstruct systag *tag;
X{
X   struct ExecBase *eb = *((struct ExecBase **)4L);
X   ULONG *SUBTable, *STKTable, tabndx, subndx, tmem, base;
X
X   base = (((ULONG)eb->SysStkLower)/STKROUND)*STKROUND;
X
X  /* Find the stack's translation table. */
X
X   tabndx = base/ROMROUND;
X   tmem = tabndx * ROMROUND;
X   SUBTable = (ULONG *)PD_ADDR(tag->maintable[tabndx]);
X
X   subndx = (base - tmem)/DEVROUND;
X
X  /* Set things back the way they were. */
X
X   Disable();
X   STKTable = (ULONG *)PD_ADDR(SUBTable[subndx]);
X   MemCopy(tag->sysstack,base,tag->sysstksize);
X   SUBTable[subndx] = PD_ADDR(tmem+(subndx*DEVROUND))|PD_DT_PAGE;
X   FlushATC();
X   Enable();
X
X  /* Get rid of the fast image stuff. */
X
X   FreeMem((char *)STKTable,STKTABSIZE);
X   FreeMem((char *)tag->sysstack,tag->sysstksize);
X}
X
X/* ====================================================================== */
X
X/* This routine knows the best way to reset the system, in an attempt to
X   avoid MMU-based troubles. */
X
Xvoid CleverReset()
X{
X   geta4();
X   CleanBoot();
X}
END_OF_FILE
if test 8963 -ne `wc -c <'mmu.c'`; then
    echo shar: \"'mmu.c'\" unpacked with wrong size!
fi
# end of 'mmu.c'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
Mail comments to the moderator at <amiga-request@uunet.uu.net>.
Post requests for sources, and general discussion to comp.sys.amiga.