Home | History | Annotate | Line # | Download | only in loadbsd
loadbsd.c revision 1.8
      1  1.7  chopps /*
      2  1.8  chopps  *	$Id: loadbsd.c,v 1.8 1994/03/20 10:05:11 chopps Exp $
      3  1.7  chopps  */
      4  1.7  chopps 
      5  1.1      mw #include <sys/types.h>
      6  1.1      mw #include <a.out.h>
      7  1.1      mw #include <stdio.h>
      8  1.8  chopps #include <unistd.h>
      9  1.1      mw 
     10  1.1      mw #include <exec/types.h>
     11  1.1      mw #include <exec/execbase.h>
     12  1.1      mw #include <exec/memory.h>
     13  1.1      mw #include <libraries/configregs.h>
     14  1.1      mw #include <libraries/expansionbase.h>
     15  1.5      mw #include <graphics/gfxbase.h>
     16  1.1      mw 
     17  1.1      mw #include <inline/exec.h>
     18  1.1      mw #include <inline/expansion.h>
     19  1.5      mw #include <inline/graphics.h>
     20  1.1      mw 
     21  1.3      mw /* Get definitions for boothowto */
     22  1.3      mw #include "reboot.h"
     23  1.3      mw 
     24  1.6  chopps static char usage[] =
     25  1.6  chopps "
     26  1.6  chopps NAME
     27  1.6  chopps \t%s - loads NetBSD from amiga dos.
     28  1.6  chopps SYNOPSIS
     29  1.6  chopps \t%s some-vmunix [-a] [-b] [-k] [-m memory] [-p] [-t] [-V]
     30  1.6  chopps OPTIONS
     31  1.6  chopps \t-a  Boot up to multiuser mode.
     32  1.6  chopps \t-b  Ask for which root device.
     33  1.6  chopps \t    Its possible to have multiple roots and choose between them.
     34  1.6  chopps \t-k  Reserve the first 4M of fast mem [Some one else
     35  1.6  chopps \t    is going to have to answer what that it is used for].
     36  1.6  chopps \t-m  Tweak amount of available memory, for finding minimum amount
     37  1.6  chopps \t    of memory required to run. Sets fastmem size to specified
     38  1.6  chopps \t    size in Kbytes.
     39  1.6  chopps \t-p  Use highest priority fastmem segement instead of the largest
     40  1.6  chopps \t    segment. The higher priority segment is usually faster
     41  1.6  chopps \t    (i.e. 32 bit memory), but some people have smaller amounts
     42  1.6  chopps \t    of 32 bit memory.
     43  1.6  chopps \t-t  This is a *test* option.  It prints out the memory
     44  1.6  chopps \t    list information being passed to the kernel and also
     45  1.6  chopps \t    exits without actually starting NetBSD.
     46  1.8  chopps \t-S  Include kernel symbol table.
     47  1.6  chopps \t-V  Version of loadbsd program.
     48  1.6  chopps HISTORY
     49  1.6  chopps       This version supports Kernel version 720 +
     50  1.6  chopps ";
     51  1.6  chopps 
     52  1.1      mw struct ExpansionBase *ExpansionBase;
     53  1.5      mw struct GfxBase *GfxBase;
     54  1.1      mw 
     55  1.1      mw #undef __LDPGSZ
     56  1.1      mw #define __LDPGSZ 8192
     57  1.1      mw 
     58  1.5      mw #define MAX_MEM_SEG	16
     59  1.5      mw 
     60  1.6  chopps /*
     61  1.6  chopps  * Kernel parameter passing version
     62  1.8  chopps  *	1:	first version of loadbsd
     63  1.8  chopps  *	2:	needs esym location passed in a4
     64  1.6  chopps  */
     65  1.8  chopps #define KERNEL_PARAMETER_VERSION	2
     66  1.6  chopps 
     67  1.5      mw struct MEM_LIST {
     68  1.5      mw 	u_long	num_mem;
     69  1.5      mw 	struct MEM_SEG {
     70  1.5      mw 		u_long	mem_start;
     71  1.5      mw 		u_long	mem_size;
     72  1.5      mw 		u_short	mem_attrib;
     73  1.5      mw 		short	mem_prio;
     74  1.5      mw 	} mem_seg[MAX_MEM_SEG];
     75  1.5      mw } mem_list, *kmem_list;
     76  1.5      mw 
     77  1.5      mw int k_opt;
     78  1.5      mw int a_opt;
     79  1.5      mw int b_opt;
     80  1.5      mw int p_opt;
     81  1.5      mw int t_opt;
     82  1.6  chopps int m_opt;
     83  1.8  chopps int S_opt;
     84  1.5      mw 
     85  1.5      mw extern char *optarg;
     86  1.5      mw extern int optind;
     87  1.5      mw 
     88  1.1      mw void get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size);
     89  1.6  chopps void Usage (char *program_name);
     90  1.6  chopps void Version (void);
     91  1.6  chopps 
     92  1.8  chopps static const char _version[] = "$VER: LoadBSD 2.0 (12.3.94)";
     93  1.1      mw 
     94  1.1      mw int
     95  1.1      mw main (int argc, char *argv[])
     96  1.1      mw {
     97  1.1      mw   struct exec e;
     98  1.1      mw   int fd;
     99  1.3      mw   int boothowto = RB_SINGLE;
    100  1.1      mw 
    101  1.1      mw   if (argc >= 2)
    102  1.1      mw     {
    103  1.1      mw       if ((fd = open (argv[1], 0)) >= 0)
    104  1.1      mw         {
    105  1.1      mw           if (read (fd, &e, sizeof (e)) == sizeof (e))
    106  1.1      mw             {
    107  1.1      mw               if (e.a_magic == NMAGIC)
    108  1.1      mw                 {
    109  1.1      mw                   u_char *kernel;
    110  1.8  chopps                   int kernel_size;
    111  1.1      mw 		  int text_size;
    112  1.1      mw 		  struct ConfigDev *cd;
    113  1.1      mw 		  int num_cd;
    114  1.5      mw 		  void *fastmem_start;
    115  1.5      mw 		  u_long fastmem_size, chipmem_size;
    116  1.5      mw 		  int i;
    117  1.6  chopps 		  u_short *kern_vers;
    118  1.8  chopps 		  char *esym;
    119  1.8  chopps 		  int string_size;
    120  1.1      mw 
    121  1.5      mw 		  GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library", 0);
    122  1.5      mw 		  if (! GfxBase)	/* not supposed to fail... */
    123  1.5      mw 		    abort();
    124  1.1      mw 		  ExpansionBase= (struct ExpansionBase *) OpenLibrary ("expansion.library", 0);
    125  1.1      mw 		  if (! ExpansionBase)	/* not supposed to fail... */
    126  1.1      mw 		    abort();
    127  1.5      mw 		  optind = 2;
    128  1.8  chopps 		  while ((i = getopt (argc, argv, "kabptVm:S")) != EOF)
    129  1.5      mw 		    switch (i) {
    130  1.5      mw 		    case 'k':
    131  1.5      mw 		      k_opt = 1;
    132  1.5      mw 		      break;
    133  1.5      mw 		    case 'a':
    134  1.5      mw 		      a_opt = 1;
    135  1.5      mw 		      break;
    136  1.5      mw 		    case 'b':
    137  1.5      mw 		      b_opt = 1;
    138  1.5      mw 		      break;
    139  1.5      mw 		    case 'p':
    140  1.5      mw 		      p_opt = 1;
    141  1.5      mw 		      break;
    142  1.5      mw 		    case 't':
    143  1.5      mw 		      t_opt = 1;
    144  1.5      mw 		      break;
    145  1.6  chopps 		    case 'm':
    146  1.6  chopps 		      m_opt = atoi (optarg) * 1024;
    147  1.6  chopps 		      break;
    148  1.6  chopps                     case 'V':
    149  1.6  chopps                       Version();
    150  1.6  chopps                       break;
    151  1.8  chopps                     case 'S':
    152  1.8  chopps                       S_opt = 1;
    153  1.8  chopps                       break;
    154  1.6  chopps                     default:
    155  1.6  chopps                       Usage(argv[0]);
    156  1.6  chopps                       fprintf(stderr,"Unrecognized option \n");
    157  1.6  chopps                       exit(-1);
    158  1.5      mw 		    }
    159  1.5      mw 
    160  1.1      mw 		  for (cd = 0, num_cd = 0; cd = FindConfigDev (cd, -1, -1); num_cd++) ;
    161  1.5      mw 		  get_mem_config (&fastmem_start, &fastmem_size, &chipmem_size);
    162  1.1      mw 
    163  1.1      mw 		  text_size = (e.a_text + __LDPGSZ - 1) & (-__LDPGSZ);
    164  1.8  chopps 		  esym = NULL;
    165  1.8  chopps 		  kernel_size = text_size + e.a_data + e.a_bss
    166  1.8  chopps 		      + num_cd*sizeof(*cd) + 4
    167  1.8  chopps 		      + mem_list.num_mem*sizeof(struct MEM_SEG) + 4;
    168  1.8  chopps 		  /*
    169  1.8  chopps 		   * get symbol table size & string size
    170  1.8  chopps 		   * (should check kernel version to see if it will handle it)
    171  1.8  chopps 		   */
    172  1.8  chopps 		  if (S_opt && e.a_syms) {
    173  1.8  chopps 		    S_opt = 0;			/* prepare for failure */
    174  1.8  chopps 		    if (lseek(fd, e.a_text + e.a_data + e.a_syms, SEEK_CUR) > 0) {
    175  1.8  chopps 		      if (read (fd, &string_size, 4) == 4) {
    176  1.8  chopps 			if (lseek(fd, sizeof(e), SEEK_SET) < 0) {
    177  1.8  chopps 		      	  printf ("Error repositioning to text\n");
    178  1.8  chopps 		      	  exit(0);		/* Give up! */
    179  1.8  chopps 			}
    180  1.8  chopps 			kernel_size += e.a_syms + 4 + string_size;
    181  1.8  chopps 			S_opt = 1;		/* sucess!  Keep -S option */
    182  1.8  chopps 		      }
    183  1.8  chopps 		    }
    184  1.8  chopps 		  }
    185  1.8  chopps 
    186  1.8  chopps 		  kernel = (u_char *) malloc (kernel_size);
    187  1.5      mw 
    188  1.5      mw 		  if (t_opt)
    189  1.5      mw 		    for (i = 0; i < mem_list.num_mem; ++i) {
    190  1.5      mw 		      printf ("mem segment %d: start=%08lx size=%08lx attribute=%04lx pri=%d\n",
    191  1.5      mw 			i + 1, mem_list.mem_seg[i].mem_start,
    192  1.5      mw 			mem_list.mem_seg[i].mem_size,
    193  1.5      mw 			mem_list.mem_seg[i].mem_attrib,
    194  1.5      mw 			mem_list.mem_seg[i].mem_prio);
    195  1.5      mw 		    }
    196  1.1      mw 
    197  1.1      mw                   if (kernel)
    198  1.1      mw                     {
    199  1.1      mw 		      if (read (fd, kernel, e.a_text) == e.a_text
    200  1.1      mw 			  && read (fd, kernel + text_size, e.a_data) == e.a_data)
    201  1.1      mw 			{
    202  1.1      mw 			  int *knum_cd;
    203  1.1      mw 			  struct ConfigDev *kcd;
    204  1.5      mw 			  int mem_ix;
    205  1.8  chopps 
    206  1.5      mw 			  if (k_opt)
    207  1.1      mw 			    {
    208  1.1      mw 			      fastmem_start += 4*1024*1024;
    209  1.1      mw 			      fastmem_size  -= 4*1024*1024;
    210  1.1      mw 			    }
    211  1.6  chopps 
    212  1.6  chopps 			  if (m_opt && m_opt <= fastmem_size)
    213  1.6  chopps 			    {
    214  1.6  chopps 			      fastmem_size = m_opt;
    215  1.6  chopps 			    }
    216  1.1      mw 
    217  1.5      mw 			  if (a_opt)
    218  1.3      mw 			    {
    219  1.3      mw 			      printf("Autobooting...");
    220  1.3      mw 			      boothowto = RB_AUTOBOOT;
    221  1.3      mw 			    }
    222  1.5      mw 
    223  1.5      mw 			  if (b_opt)
    224  1.5      mw 			    {
    225  1.5      mw 			      printf("Askboot...");
    226  1.5      mw 			      boothowto |= RB_ASKNAME;
    227  1.5      mw 			    }
    228  1.3      mw 
    229  1.1      mw 			  printf ("Using %dM FASTMEM at 0x%x, %dM CHIPMEM\n",
    230  1.1      mw 				  fastmem_size>>20, fastmem_start, chipmem_size>>20);
    231  1.6  chopps 			  kern_vers = (u_short *) (kernel + e.a_entry - 2);
    232  1.6  chopps 			  if (*kern_vers > KERNEL_PARAMETER_VERSION &&
    233  1.6  chopps 			      *kern_vers != 0x4e73)
    234  1.6  chopps 			    {
    235  1.6  chopps 			      printf ("This kernel requires a newer version of loadbsd: %d\n", *kern_vers);
    236  1.6  chopps 			      exit (0);
    237  1.6  chopps 			    }
    238  1.1      mw 			  /* give them a chance to read the information... */
    239  1.1      mw 			  sleep(2);
    240  1.1      mw 
    241  1.1      mw 			  bzero (kernel + text_size + e.a_data, e.a_bss);
    242  1.8  chopps 			  /*
    243  1.8  chopps 			   * If symbols wanted (and kernel can handle them),
    244  1.8  chopps 			   * load symbol table & strings and set esym to end.
    245  1.8  chopps 			   */
    246  1.1      mw 			  knum_cd = (int *) (kernel + text_size + e.a_data + e.a_bss);
    247  1.8  chopps 			  if (*kern_vers != 0x4e73 && *kern_vers > 1 && S_opt && e.a_syms) {
    248  1.8  chopps 			    *knum_cd++ = e.a_syms;
    249  1.8  chopps 			    read(fd, (char *)knum_cd, e.a_syms);
    250  1.8  chopps 			    knum_cd = (int *)((char *)knum_cd + e.a_syms);
    251  1.8  chopps 			    read(fd, (char *)knum_cd, string_size);
    252  1.8  chopps 			    knum_cd = (int*)((char *)knum_cd + string_size);
    253  1.8  chopps 			    esym = (char *) (text_size + e.a_data + e.a_bss
    254  1.8  chopps 			      + e.a_syms + 4 + string_size);
    255  1.8  chopps 			  }
    256  1.1      mw 			  *knum_cd = num_cd;
    257  1.5      mw 			  for (kcd = (struct ConfigDev *) (knum_cd+1);
    258  1.5      mw 			       cd = FindConfigDev (cd, -1, -1);
    259  1.6  chopps 			       *kcd++ = *cd)
    260  1.6  chopps 				;
    261  1.5      mw 			  kmem_list = (struct MEM_LIST *)kcd;
    262  1.5      mw 			  kmem_list->num_mem = mem_list.num_mem;
    263  1.5      mw 			  for (mem_ix = 0; mem_ix < mem_list.num_mem; mem_ix++)
    264  1.5      mw 			  	kmem_list->mem_seg[mem_ix] = mem_list.mem_seg[mem_ix];
    265  1.8  chopps 			  if (t_opt)		/* if test option */
    266  1.8  chopps 			    exit (0);		/*   don't start kernel */
    267  1.8  chopps 			  /* AGA startup - may need more */
    268  1.5      mw 			  LoadView (NULL);
    269  1.8  chopps 			  startit (kernel, kernel_size,
    270  1.1      mw 				   e.a_entry, fastmem_start,
    271  1.3      mw 				   fastmem_size, chipmem_size,
    272  1.8  chopps 				   boothowto, esym );
    273  1.1      mw 			}
    274  1.1      mw 		      else
    275  1.1      mw 			fprintf (stderr, "Executable corrupt!\n");
    276  1.1      mw                     }
    277  1.1      mw                   else
    278  1.1      mw 		    fprintf (stderr, "Out of memory! (%d)\n", text_size + e.a_data + e.a_bss
    279  1.5      mw 				   + num_cd*sizeof(*cd) + 4
    280  1.5      mw 				   + mem_list.num_mem*sizeof(struct MEM_SEG) + 4);
    281  1.1      mw                 }
    282  1.1      mw 	      else
    283  1.1      mw 	        fprintf (stderr, "Unsupported executable: %o\n", e.a_magic);
    284  1.1      mw             }
    285  1.1      mw           else
    286  1.1      mw 	    fprintf (stderr, "Can't read header of %s\n", argv[1]);
    287  1.1      mw 
    288  1.1      mw 	  close (fd);
    289  1.1      mw         }
    290  1.1      mw       else
    291  1.1      mw 	perror ("open");
    292  1.1      mw     }
    293  1.1      mw   else
    294  1.6  chopps     Usage(argv[0]);
    295  1.6  chopps   Version();
    296  1.6  chopps }/* main() */
    297  1.1      mw 
    298  1.1      mw void
    299  1.1      mw get_mem_config (void **fastmem_start, u_long *fastmem_size, u_long *chipmem_size)
    300  1.1      mw {
    301  1.1      mw   extern struct ExecBase *SysBase;
    302  1.1      mw   struct MemHeader *mh, *nmh;
    303  1.5      mw   int num_mem = 0;
    304  1.5      mw   u_int seg_size;
    305  1.5      mw   u_int seg_start;
    306  1.5      mw   u_int seg_end;
    307  1.1      mw 
    308  1.1      mw   *fastmem_size = 0;
    309  1.1      mw   *chipmem_size = 0;
    310  1.1      mw 
    311  1.1      mw   /* walk thru the exec memory list */
    312  1.1      mw   Forbid ();
    313  1.1      mw   for (mh  = (struct MemHeader *) SysBase->MemList.lh_Head;
    314  1.1      mw        nmh = (struct MemHeader *) mh->mh_Node.ln_Succ;
    315  1.5      mw        mh  = nmh, num_mem++)
    316  1.1      mw     {
    317  1.5      mw       mem_list.mem_seg[num_mem].mem_attrib = mh->mh_Attributes;
    318  1.5      mw       mem_list.mem_seg[num_mem].mem_prio = mh->mh_Node.ln_Pri;
    319  1.5      mw       seg_start = (u_int)mh->mh_Lower;
    320  1.5      mw       seg_end = (u_int)mh->mh_Upper;
    321  1.5      mw       seg_size = seg_end - seg_start;
    322  1.5      mw       mem_list.mem_seg[num_mem].mem_size = seg_size;
    323  1.5      mw       mem_list.mem_seg[num_mem].mem_start = seg_start;
    324  1.5      mw 
    325  1.1      mw       if (mh->mh_Attributes & MEMF_CHIP)
    326  1.1      mw         {
    327  1.1      mw 	  /* there should hardly be more than one entry for chip mem, but
    328  1.1      mw 	     handle it the same nevertheless */
    329  1.5      mw 	  /* chipmem always starts at 0, so include vector area */
    330  1.6  chopps 	  mem_list.mem_seg[num_mem].mem_start = seg_start = 0;
    331  1.5      mw 	  /* round to multiple of 512K */
    332  1.5      mw 	  seg_size = (seg_size + 512*1024 - 1) & -(512*1024);
    333  1.5      mw 	  mem_list.mem_seg[num_mem].mem_size = seg_size;
    334  1.5      mw 	  if (seg_size > *chipmem_size)
    335  1.1      mw 	    {
    336  1.5      mw 	      *chipmem_size = seg_size;
    337  1.1      mw 	    }
    338  1.1      mw         }
    339  1.1      mw       else
    340  1.1      mw 	{
    341  1.5      mw 	  /* some heuristics.. */
    342  1.5      mw 	  seg_start &= -__LDPGSZ;
    343  1.5      mw 	  /* get the mem back stolen by incore kickstart on A3000 with
    344  1.5      mw 	     V36 bootrom. */
    345  1.5      mw 	  if (seg_end == 0x07f80000)
    346  1.5      mw 	    seg_end = 0x08000000;
    347  1.5      mw 
    348  1.5      mw 	  /* or by zkick on a A2000.  */
    349  1.5      mw 	  if (seg_start == 0x280000
    350  1.5      mw 	    && strcmp (mh->mh_Node.ln_Name, "zkick memory") == 0)
    351  1.5      mw 	      seg_start = 0x200000;
    352  1.5      mw 
    353  1.5      mw 	  seg_size = seg_end - seg_start;
    354  1.5      mw 	  mem_list.mem_seg[num_mem].mem_start = seg_start;
    355  1.5      mw 	  mem_list.mem_seg[num_mem].mem_size = seg_size;
    356  1.5      mw /* if p_opt is set, select memory by priority instead of size */
    357  1.6  chopps 	  if ((!p_opt && seg_size > *fastmem_size) ||
    358  1.6  chopps             (p_opt && *fastmem_size == 0))
    359  1.1      mw 	    {
    360  1.5      mw 	      *fastmem_size = seg_size;
    361  1.5      mw 	      *fastmem_start = (void *)seg_start;
    362  1.1      mw 	    }
    363  1.1      mw 	}
    364  1.1      mw     }
    365  1.5      mw   mem_list.num_mem = num_mem;
    366  1.1      mw   Permit();
    367  1.1      mw }
    368  1.1      mw 
    369  1.1      mw 
    370  1.1      mw 
    371  1.1      mw 
    372  1.1      mw asm ("
    373  1.1      mw 	.set	ABSEXECBASE,4
    374  1.1      mw 
    375  1.1      mw 	.text
    376  1.1      mw 	.globl	_startit
    377  1.1      mw 
    378  1.1      mw _startit:
    379  1.1      mw 	movel	sp,a3
    380  1.1      mw 	movel	4:w,a6
    381  1.1      mw 	lea	pc@(start_super-.+2),a5
    382  1.1      mw 	jmp	a6@(-0x1e)		| supervisor-call
    383  1.1      mw 
    384  1.1      mw start_super:
    385  1.1      mw 	movew	#0x2700,sr
    386  1.1      mw 
    387  1.1      mw 	| the BSD kernel wants values into the following registers:
    388  1.1      mw 	| a0:  fastmem-start
    389  1.1      mw 	| d0:  fastmem-size
    390  1.1      mw 	| d1:  chipmem-size
    391  1.5      mw 	| d5:  AttnFlags (cpuid)
    392  1.3      mw 	| d7:  boothowto
    393  1.8  chopps 	| a4:  esym location
    394  1.1      mw 
    395  1.1      mw 	movel	a3@(4),a1		| loaded kernel
    396  1.1      mw 	movel	a3@(8),d2		| length of loaded kernel
    397  1.1      mw 	movel	a3@(12),a2		| entry point
    398  1.1      mw 	movel	a3@(16),a0		| fastmem-start
    399  1.1      mw 	movel	a3@(20),d0		| fastmem-size
    400  1.1      mw 	movel	a3@(24),d1		| chipmem-size
    401  1.5      mw 	movel	#0,d5
    402  1.5      mw 	movew	(ABSEXECBASE)@(0x128),d5 | SysBase->AttnFlags
    403  1.3      mw 	movel	a3@(28),d7		| boothowto
    404  1.8  chopps 	movel	a3@(32),a4		| esym
    405  1.8  chopps 	subl	a5,a5			| target, load to 0
    406  1.1      mw 
    407  1.5      mw 	btst	#3,(ABSEXECBASE)@(0x129) | AFB_68040,SysBase->AttnFlags
    408  1.5      mw 	beq	not040
    409  1.5      mw 
    410  1.5      mw | Turn off 68040 MMU
    411  1.5      mw 
    412  1.8  chopps 	.word 0x4e7b,0xd003		| movec a5,tc
    413  1.8  chopps 	.word 0x4e7b,0xd806		| movec a5,urp
    414  1.8  chopps 	.word 0x4e7b,0xd807		| movec a5,srp
    415  1.8  chopps 	.word 0x4e7b,0xd004		| movec a5,itt0
    416  1.8  chopps 	.word 0x4e7b,0xd005		| movec a5,itt1
    417  1.8  chopps 	.word 0x4e7b,0xd006		| movec a5,dtt0
    418  1.8  chopps 	.word 0x4e7b,0xd007		| movec a5,dtt1
    419  1.5      mw 	bra	nott
    420  1.5      mw 
    421  1.5      mw not040:
    422  1.1      mw 	lea	pc@(zero-.+2),a3
    423  1.1      mw 	pmove	a3@,tc			| Turn off MMU
    424  1.1      mw 	lea	pc@(nullrp-.+2),a3
    425  1.1      mw 	pmove	a3@,crp			| Turn off MMU some more
    426  1.1      mw 	pmove	a3@,srp			| Really, really, turn off MMU
    427  1.1      mw 
    428  1.1      mw | Turn off 68030 TT registers
    429  1.1      mw 
    430  1.1      mw 	btst	#2,(ABSEXECBASE)@(0x129) | AFB_68030,SysBase->AttnFlags
    431  1.1      mw 	beq	nott			| Skip TT registers if not 68030
    432  1.1      mw 	lea	pc@(zero-.+2),a3
    433  1.1      mw 	.word 0xf013,0x0800		| pmove a3@,tt0 (gas only knows about 68851 ops..)
    434  1.1      mw 	.word 0xf013,0x0c00		| pmove a3@,tt1 (gas only knows about 68851 ops..)
    435  1.1      mw 
    436  1.1      mw nott:
    437  1.1      mw 
    438  1.1      mw 	movew	#(1<<9),0xdff096	| disable DMA
    439  1.1      mw 
    440  1.1      mw L0:
    441  1.8  chopps 	moveb	a1@+,a5@+
    442  1.1      mw 	subl	#1,d2
    443  1.1      mw 	bcc	L0
    444  1.1      mw 
    445  1.1      mw 
    446  1.1      mw 	jmp	a2@
    447  1.1      mw 
    448  1.1      mw 
    449  1.1      mw | A do-nothing MMU root pointer (includes the following long as well)
    450  1.1      mw 
    451  1.1      mw nullrp:	.long	0x7fff0001
    452  1.1      mw zero:	.long	0
    453  1.1      mw 
    454  1.1      mw 
    455  1.1      mw ");
    456  1.1      mw 
    457  1.6  chopps void Usage(char *program_name)
    458  1.6  chopps {
    459  1.6  chopps    fprintf(stderr,usage,program_name,program_name);
    460  1.6  chopps }
    461  1.6  chopps 
    462  1.6  chopps void Version()
    463  1.6  chopps {
    464  1.6  chopps   fprintf(stderr,"%s\n",_version + 6);
    465  1.6  chopps }
    466