Home | History | Annotate | Line # | Download | only in mac68k
      1 /*	$NetBSD: macrom.c,v 1.74 2024/02/05 21:46:05 andvar Exp $	*/
      2 
      3 /*-
      4  * Copyright (C) 1994	Bradley A. Grantham
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 /*
     29  * Mac ROM Glue
     30  *
     31  * This allows MacBSD to access (in a limited fashion) routines included
     32  * in the Mac ROMs, like ADBReInit.
     33  *
     34  * As a (fascinating) side effect, this glue allows ROM code (or any other
     35  * MacOS code) to call MacBSD kernel routines, like NewPtr.
     36  *
     37  * Uncleaned-up weirdness,
     38  *	This doesn't work on a lot of machines.  Perhaps the IIsi stuff
     39  * can be generalized somewhat for others.  It looks like most machines
     40  * are similar to the IIsi ("Universal ROMs"?).
     41  */
     42 
     43 #include <sys/cdefs.h>
     44 __KERNEL_RCSID(0, "$NetBSD: macrom.c,v 1.74 2024/02/05 21:46:05 andvar Exp $");
     45 
     46 #include "opt_adb.h"
     47 #include "opt_ddb.h"
     48 
     49 #include <sys/param.h>
     50 #include <sys/systm.h>
     51 #include <sys/malloc.h>
     52 #include <sys/queue.h>
     53 #include <sys/cpu.h>
     54 #include <sys/intr.h>
     55 
     56 #include <uvm/uvm_extern.h>
     57 
     58 #include <machine/frame.h>
     59 #include <machine/viareg.h>
     60 
     61 #include <mac68k/mac68k/macrom.h>
     62 #include <mac68k/dev/adbvar.h>
     63 
     64 	/* trap modifiers (put it macrom.h) */
     65 #define TRAP_TOOLBOX(a)	((a) & 0x800)
     66 #define TRAP_PASSA0(a)	((a) & 0x100)
     67 #define TRAP_NUM(a)	(TRAP_TOOLBOX(a) ? (a) & 0x3ff : (a) & 0xff)
     68 #define TRAP_SYS(a)	((a) & 0x400)
     69 #define TRAP_CLEAR(a)	((a) & 0x200)
     70 
     71 
     72 	/* Mac Rom Glue global variables */
     73 /*
     74  * ADB Storage.  Is 512 bytes enough?  Too much?
     75  */
     76 u_char mrg_adbstore[512];
     77 u_char mrg_adbstore2[512];
     78 u_char mrg_adbstore3[512];
     79 u_char mrg_ExpandMem[512];			/* 0x1ea Bytes minimum */
     80 u_char mrg_adbstore4[32];			/* 0x16 bytes was the largest I found yet */
     81 u_char mrg_adbstore5[80];			/* 0x46 bytes minimum */
     82 
     83 /*
     84  * InitEgret in the AV ROMs requires a low memory global at 0x2010 to be
     85  * pointed at this jump table, which can be found at 0x40803280. It's
     86  * included here so we can do mrg_fixupROMBase on it.
     87  */
     88 
     89 u_int32_t mrg_AVInitEgretJT[] = {
     90 	0x408055D0, 0x4083985A, 0x40839AB6, 0x4080F180,
     91 	0x4080C0B6, 0x4080C30A, 0x4080C380, 0x4080C482,
     92 	0x4080C496, 0x4080C82E, 0x4080C9FE, 0x4080CA16,
     93 	0x4081D1D6, 0x4085CDDE, 0x4080DF28, 0x4080DFC6,
     94 	0x4080E292, 0x4080E2C0, 0x4080E348, 0x4080E600,
     95 	0x4080E632, 0x4080E6B8, 0x4080E6E4, 0x4080E750,
     96 	0x4080E776, 0x4080E7B4, 0x408B90E0, 0x40852490,
     97 	0x40852280, 0x40852410, 0x4080E8F0, 0x4080E940,
     98 	0x4080E960, 0x4080E9B0, 0x4080E9E0, 0x4080EA50,
     99 	0x4080EA70, 0x4080EB14, 0x4080EBC0, 0x4081D1D6,
    100 	0x40810AB0, 0x40810BDA, 0x40810CCA, 0x40810FF2,
    101 	0x4080FF8C, 0x40810292, 0x40812CE2, 0x40813AAE,
    102 	0x40813AE0, 0x408113DE, 0x40811EB0, 0x40811FA0,
    103 	0x40811DD0, 0x4083B720, 0x408412E0, 0x40841300,
    104 	0x40841380, 0x4083A390, 0x408411F0
    105 };
    106 
    107 void *	mrg_romadbintr = (void *)0;	/* ROM ADB interrupt */
    108 void *	mrg_rompmintr = 0;		/* ROM PM (?) interrupt */
    109 const char *mrg_romident = NULL;		/* ident string for ROMs */
    110 void *	mrg_ADBAlternateInit = 0;
    111 void *	mrg_InitEgret = 0;
    112 void *	mrg_ADBIntrPtr = (void *)0x0;	/* ADB interrupt taken from MacOS vector table*/
    113 void *	ROMResourceMap = 0;
    114 extern romvec_t *mrg_MacOSROMVectors;
    115 #if defined(MRG_TEST) || defined(MRG_DEBUG)
    116 void *	ResHndls[] = {
    117 	0, 0, 0, 0, 0, 0, 0, 0,
    118 	0, 0, 0, 0, 0, 0, 0, 0,
    119 	0, 0, 0, 0, 0, 0, 0, 0,
    120 	0, 0, 0, 0, 0, 0, 0, 0,
    121 	0, 0, 0, 0, 0, 0
    122 };
    123 #else
    124 void *	ResHndls[] = {
    125 	0, 0, 0, 0, 0, 0, 0, 0,
    126 	0, 0, 0, 0, 0, 0, 0, 0,
    127 	0, 0, 0, 0
    128 };
    129 #endif
    130 
    131 void *dtmgr_softintr_cookie;
    132 
    133 /*
    134  * Last straw functions; we didn't set them up, so freak out!
    135  * When someone sees these called, we can finally go back and
    136  * bother to implement them.
    137  */
    138 
    139 int
    140 mrg_Delay(void)
    141 {
    142 #define TICK_DURATION 16625
    143 	u_int32_t ticks;
    144 
    145 	__asm volatile ("movl	%%a0,%0"	/* get arguments */
    146 		: "=g" (ticks)
    147 		:
    148 		: "a0");
    149 
    150 #if defined(MRG_DEBUG)
    151 	printf("mrg: mrg_Delay(%d) = %d ms\n", ticks, ticks * 60);
    152 #endif
    153 	delay(ticks * TICK_DURATION);
    154 
    155 	/*
    156 	 * The number of ticks since startup should be
    157 	 * returned here. Until someone finds a need for
    158 	 * this, we just return the requested number
    159 	 * of ticks
    160 	 */
    161 	return (ticks);
    162 }
    163 
    164 /*
    165  * Handle the Deferred Task manager here
    166  *
    167  */
    168 static void *	mrg_DTList = NULL;
    169 
    170 void
    171 mrg_DTInstall(void)
    172 {
    173 	void *ptr, *prev;
    174 	void **cptr, **cprev;
    175 
    176 	__asm volatile ("movl %%a0,%0" : "=g" (ptr));
    177 
    178 	prev = (void *)&mrg_DTList;
    179 	while (*(void **)prev != NULL)
    180 		prev = *(void **)prev;
    181 	cptr = (void **)ptr;
    182 	cprev = (void **)prev;
    183 	*cptr = NULL;
    184 	*cprev = ptr;
    185 	softint_schedule(dtmgr_softintr_cookie);
    186 
    187 	__asm volatile ("clrl %%d0" : : : "d0");
    188 }
    189 
    190 void
    191 mrg_execute_deferred(void)
    192 {
    193 	void *ptr;
    194 	int s;
    195 
    196 	while (mrg_DTList != NULL) {
    197 		s = splhigh();
    198 		ptr = *(void **)mrg_DTList;
    199 		mrg_DTList = *(void **)ptr;
    200 		splx(s);
    201 
    202 		__asm volatile (
    203 		"	moveml %%a0-%%a6/%%d1-%%d7,%%sp@-	\n"
    204 		"	movl %0,%%a0		\n"
    205 		"	movl %%a0@(8),%%a2	\n"
    206 		"	movl %%a0@(12),%%a1	\n"
    207 		"	jsr %%a2@		\n"
    208 		"	moveml %%sp@+,%%a0-%%a6/%%d1-%%d7" : : "g" (ptr));
    209 	}
    210 }
    211 
    212 void
    213 mrg_VBLQueue(void)
    214 {
    215 #define qLink 0
    216 #define qType 4
    217 #define vblAddr 6
    218 #define vblCount 10
    219 #define vblPhase 12
    220 	char *vbltask;
    221 	char *last_vbltask;
    222 
    223 	last_vbltask = (char *)&VBLQueue_head;
    224 	vbltask = VBLQueue_head;
    225 	while (0 != vbltask) {
    226 		if (0 != *((u_int16_t *)(vbltask + vblPhase)))
    227 			*((u_int16_t *)(vbltask + vblPhase)) -= 1;
    228 		else if (0 != *((u_int16_t *)(vbltask + vblCount)))
    229 			*((u_int16_t *)(vbltask + vblCount)) -= 1;
    230 		else {
    231 #if defined(MRG_DEBUG)
    232 			printf("mrg: mrg_VBLQueue: calling VBL task at 0x%x with VBLTask block at %p\n",
    233 			    *((u_int32_t *)(vbltask + vblAddr)), vbltask);
    234 #endif
    235 			__asm volatile(
    236 			"	movml	#0xfffe,%%sp@-	\n"
    237 			"	movl	%0,%%a0		\n"
    238 			"	movl	%1,%%a1		\n"
    239 			"	jbsr	%%a1@		\n"
    240 			"	movml	%%sp@+,#0x7fff"
    241 				: : "g" (vbltask),
    242 				    "g" (*((char *)(vbltask + vblAddr)))
    243 				: "a0","a1");
    244 #if defined(MRG_DEBUG)
    245 			printf("mrg: mrg_VBLQueue: back from VBL task\n");
    246 #endif
    247 			if (0 == *((u_int16_t *)(vbltask + vblCount))) {
    248 #if defined(MRG_DEBUG)
    249 				printf("mrg: mrg_VBLQueue: removing VBLTask block at %p\n",
    250 				    vbltask);
    251 #endif
    252 				*((u_int32_t *)(last_vbltask + qLink)) =
    253 				    *((u_int32_t *)(vbltask + qLink));
    254 				/*
    255 				 * can't free memory from VBLTask block as
    256 				 * we don't know where it came from
    257 				 */
    258 				if (vbltask == VBLQueue_tail)
    259 					VBLQueue_tail = last_vbltask;
    260 			}
    261 		}
    262 		last_vbltask = vbltask;
    263 		vbltask = (void *) *((u_int32_t *)(vbltask + qLink));
    264 	}
    265 }
    266 
    267 void
    268 mrg_init_stub_1(void)
    269 {
    270 	__asm volatile ("movml #0xffff,%sp@-");
    271 	printf("mrg: hit mrg_init_stub_1\n");
    272   	__asm volatile ("movml %sp@+, #0xffff");
    273 }
    274 
    275 void
    276 mrg_init_stub_2(void)
    277 {
    278 	panic("mrg: hit mrg_init_stub_2");
    279 }
    280 
    281 short
    282 Count_Resources(u_int32_t rsrc_type)
    283 {
    284 	rsrc_t *rsrc = (rsrc_t *)ROMResourceMap;
    285 	short count = 0;
    286 
    287 #if defined(MRG_DEBUG)
    288 	printf("Count_Resources looking for 0x%08lx at 0x%08lx\n",
    289 	    (long)rsrc_type, (long)rsrc);
    290 #endif
    291 	/*
    292 	 * Return a Count of all the ROM Resources of the requested type.
    293 	 */
    294 	if (ROMResourceMap == 0)
    295 		panic("Oops! Need ROM Resource Map ListHead address!");
    296 
    297 	while (rsrc != 0) {
    298 #if defined(MRG_DEBUG)
    299 		if (rsrc_type == 0)
    300 			printf("0x%08lx: %04x %04x %04x %04x %08x %08x %08x %04x\n",
    301 			    (long)rsrc, rsrc->unknown[0], rsrc->unknown[1],
    302 			    rsrc->unknown[2], rsrc->unknown[3], rsrc->next,
    303 			    rsrc->body, rsrc->name, rsrc->index);
    304 #endif
    305 		if (rsrc_type == 0 || (rsrc_type == rsrc->name))
    306 			count++;
    307 		rsrc = rsrc->next == 0 ? 0 : (rsrc_t *)(rsrc->next + (char *)ROMBase);
    308 	}
    309 
    310 #if defined(MRG_DEBUG)
    311 	printf("Count_Resources found %d\n", count);
    312 #endif
    313 	return count;
    314 }
    315 
    316 void **
    317 Get_Ind_Resource(u_int32_t rsrc_type, u_int16_t rsrc_ind)
    318 {
    319 	rsrc_t *rsrc = (rsrc_t *)ROMResourceMap;
    320 	short i = 0;
    321 
    322 	/*
    323 	 * This routine return the "Handle" to a ROM Resource.  Since few
    324 	 * ROM Resources are called for in NetBSD we keep a small table
    325 	 * for the Handles we return. (Can't reuse the Handle without
    326 	 * defeating the purpose for a Handle in the first place!)  If
    327 	 * we get more requests than we have space for, we panic.
    328 	 */
    329 	if (ROMResourceMap == 0)
    330 		panic("Oops! Need ROM Resource Map ListHead address!");
    331 
    332 	while (rsrc != 0) {
    333 		if (rsrc_type == rsrc->name) {
    334 			rsrc_ind--;
    335 			if (rsrc_ind == 0) {
    336 				for (i = 0;
    337 				    i < sizeof(ResHndls) / sizeof(void *); i++)
    338 					if ((ResHndls[i] == 0) ||
    339 					    (ResHndls[i] == (void *)(rsrc->next + (char *)ROMBase))) {
    340 						ResHndls[i] = (void *)(rsrc->body + (char *)ROMBase);
    341 						return (void **)&ResHndls[i];
    342 					}
    343 				panic("ResHndls table too small!");
    344 			}
    345 		}
    346 		rsrc = rsrc->next == 0 ? 0 : (rsrc_t *)(rsrc->next + (char *)ROMBase);
    347 	}
    348 	return (void **)0;
    349 }
    350 
    351 void
    352 mrg_FixDiv(void)
    353 {
    354 	panic("Oops! Need ROM address of _FixDiv for this system!");
    355 }
    356 
    357 void
    358 mrg_FixMul(void)
    359 {
    360 	panic("Oops! Need ROM address of _FixMul for this system!");
    361 }
    362 
    363 void
    364 mrg_1sec_timer_tick(void)
    365 {
    366 	/* The timer tick from the Egret chip triggers this routine via
    367 	 * Lvl1DT[0] (addr 0x192) once every second.
    368 	 */
    369 }
    370 
    371 void
    372 mrg_lvl1dtpanic(void)		/* Lvl1DT stopper */
    373 {
    374 	printf("Agh!  I was called from Lvl1DT!!!\n");
    375 #ifdef DDB
    376 	Debugger();
    377 #endif
    378 }
    379 
    380 void
    381 mrg_lvl2dtpanic(void)		/* Lvl2DT stopper */
    382 {
    383 	panic("Agh!  I was called from Lvl2DT!!!");
    384 }
    385 
    386 void
    387 mrg_jadbprocpanic(void)	/* JADBProc stopper */
    388 {
    389 	panic("Agh!  Called JADBProc!");
    390 }
    391 
    392 void
    393 mrg_jswapmmupanic(void)	/* jSwapMMU stopper */
    394 {
    395 	panic("Agh!  Called jSwapMMU!");
    396 }
    397 
    398 void
    399 mrg_jkybdtaskpanic(void)	/* JKybdTask stopper */
    400 {
    401 	panic("Agh!  Called JKybdTask!");
    402 }
    403 
    404 #ifdef MRG_ADB
    405 /*
    406  * mrg_adbintr() and mrg_pmintr() are defined in adb_direct.c if we
    407  * not using the MRG method of accessing the ADB/PRAM/RTC.
    408  */
    409 
    410 long
    411 mrg_adbintr(void)	/* Call ROM ADB Interrupt */
    412 {
    413 	if (mrg_romadbintr != NULL) {
    414 #if defined(MRG_TRACE)
    415 		tron();
    416 #endif
    417 
    418 		/* Gotta load a1 with VIA address. */
    419 		/* ADB int expects it from Mac intr routine. */
    420 		__asm volatile (
    421 		"	movml	#0xffff,%%sp@-	\n"
    422 		"	movl	%0,%%a0		\n"
    423 		"	movl	" ___STRING(_C_LABEL(VIA)) ",%%a1 \n"
    424 		"	jbsr	%%a0@		\n"
    425 		"	movml	%%sp@+,#0xffff"
    426 			:
    427 			: "g" (mrg_romadbintr)
    428 			: "a0","a1");
    429 
    430 #if defined(MRG_TRACE)
    431 		troff();
    432 #endif
    433 
    434 	}
    435 	return (1);
    436 }
    437 
    438 long
    439 mrg_pmintr(void)	/* Call ROM PM Interrupt */
    440 {
    441 	if (mrg_rompmintr != NULL) {
    442 #if defined(MRG_TRACE)
    443 		tron();
    444 #endif
    445 
    446 		/* Gotta load a1 with VIA address. */
    447 		/* ADB int expects it from Mac intr routine. */
    448 		__asm volatile (
    449 		"	movml	#0xffff,%%sp@-	\n"
    450 		"	movl	%0,%%a0		\n"
    451 		"	movl	" ___STRING(_C_LABEL(VIA)) ",%%a1 \n"
    452 		"	jbsr	%%a0@		\n"
    453 		"	movml	%%sp@+,#0xffff"
    454 			:
    455 			: "g" (mrg_rompmintr)
    456 			: "a0","a1");
    457 
    458 #if defined(MRG_TRACE)
    459 		troff();
    460 #endif
    461 	}
    462 	return (1);
    463 }
    464 #endif	/* MRG_ADB */
    465 
    466 
    467 void
    468 mrg_notrap(void)
    469 {
    470 	printf("Aigh!\n");
    471 	panic("mrg_notrap: We're doomed!");
    472 }
    473 
    474 int
    475 myowntrap(void)
    476 {
    477 	printf("Oooo!  My Own Trap Routine!\n");
    478 	return (50);
    479 }
    480 
    481 int
    482 mrg_NewPtr(void)
    483 {
    484 	int result = noErr;
    485 	u_int numbytes;
    486 /*	u_int32_t trapword; */
    487 	char *ptr;
    488 
    489 	__asm volatile ("movl	%%d0,%0" : "=g" (numbytes) : : "d0");
    490 
    491 #if defined(MRG_SHOWTRAPS)
    492 	printf("mrg: NewPtr(%d bytes, ? clear, ? sys)", numbytes);
    493 #endif
    494 
    495 		/* plus 4 for size */
    496 	ptr = malloc(numbytes + 4 , M_DEVBUF, M_NOWAIT); /* ?? */
    497 		/* We ignore "Sys;" where else would it come from? */
    498 		/* plus, (I think), malloc clears block for us */
    499 
    500 	if (ptr == NULL) {
    501 		result = memFullErr;
    502 #if defined(MRG_SHOWTRAPS)
    503 		printf(" failed.\n");
    504 #endif
    505 	}else{
    506 #if defined(MRG_SHOWTRAPS)
    507 		printf(" succeded = %p.\n", ptr);
    508 #endif
    509 		*(u_int32_t *)ptr = numbytes;
    510 		ptr += 4;
    511 		memset(ptr, 0, numbytes); /* NewPtr, 0, Clear ! */
    512 	}
    513 
    514 	__asm volatile("movl	%0,%%a0" :  : "g" (ptr) : "a0");
    515 	return (result);
    516 }
    517 
    518 int
    519 mrg_DisposPtr(void)
    520 {
    521 	int result = noErr;
    522 	char *ptr;
    523 
    524 	__asm volatile("movl	%%a0,%0" : "=g" (ptr) : : "a0");
    525 
    526 #if defined(MRG_SHOWTRAPS)
    527 	printf("mrg: DisposPtr(%p)\n", ptr);
    528 #endif
    529 
    530 	if (ptr == 0)
    531 		result = memWZErr;
    532 	else
    533 		free(ptr - 4, M_DEVBUF);
    534 
    535 	return (result);
    536 }
    537 
    538 int
    539 mrg_GetPtrSize(void)
    540 {
    541 	char *ptr;
    542 
    543 	__asm volatile("movl	%%a0,%0" : "=g" (ptr) : : "a0");
    544 
    545 #if defined(MRG_SHOWTRAPS)
    546 	printf("mrg: GetPtrSize(%p)\n", ptr);
    547 #endif
    548 
    549 	if (ptr == 0)
    550 		return (memWZErr);
    551 	else
    552 		return (*(int *)(ptr - 4));
    553 }
    554 
    555 int
    556 mrg_SetPtrSize(void)
    557 {
    558 	void *ptr;
    559 	int newbytes;
    560 
    561 	__asm volatile(
    562 	"	movl	%%a0,%0	\n"
    563 	"	movl	%%d0,%1"
    564 		: "=g" (ptr), "=g" (newbytes) : : "d0","a0");
    565 
    566 #if defined(MRG_SHOWTRAPS)
    567 	printf("mrg: SetPtrSize(%p, %d) failed\n", ptr, newbytes);
    568 #endif
    569 
    570 	return (memFullErr);	/* How would I handle this, anyway? */
    571 }
    572 
    573 int
    574 mrg_PostEvent(void)
    575 {
    576 	return 0;
    577 }
    578 
    579 void
    580 mrg_StripAddress(void)
    581 {
    582 }
    583 
    584 int
    585 mrg_SetTrapAddress(void)
    586 {
    587 	extern void *mrg_OStraps[];
    588 	void *ptr;
    589 	int trap_num;
    590 
    591 	__asm volatile(
    592 	"	movl %%a0,%0	\n"
    593 	"	movl %%d0,%1"
    594 		: "=g" (ptr), "=g" (trap_num) : : "d0","a0");
    595 
    596 #if defined(MRG_DEBUG)
    597 	printf("mrg: trap 0x%x set to 0x%lx\n", trap_num, (long)ptr);
    598 #endif
    599 	mrg_OStraps[trap_num] = ptr;
    600 /*
    601  * If the Trap for Egret was changed, we'd better remember it!
    602  */
    603 	if (trap_num == 0x92) {
    604 #if defined(MRG_DEBUG)
    605 		printf("mrg: reconfigured Egret address from 0x%lx to 0x%lx\n",
    606 		    (long)jEgret, (long)ptr);
    607 #endif
    608 		jEgret = (void (*))ptr;
    609 	}
    610 	return 0;
    611 }
    612 
    613 /*
    614  * trap jump address tables (different per machine?)
    615  * Can I just use the tables stored in the ROMs?
    616  * *Is* there a table stored in the ROMs?
    617  * We only initialize the A-Traps for the routines we have
    618  *  provided ourselves.  The routines we will be trying to
    619  *  use out of the MacROMs will be initialized at run-time.
    620  * I did this to make the code easier to follow and to keep
    621  *  from taking an unexpected side trip into the MacROMs on
    622  *  those systems we don't have fully decoded.
    623  */
    624 void *mrg_OStraps[256] = {
    625 #ifdef __GNUC__
    626 		/* God, I love gcc.  see GCC2 manual, section 2.17, */
    627 		/* "labeled elements in initializers." */
    628 	[0x1e]	(void *)mrg_NewPtr,
    629 		(void *)mrg_DisposPtr,
    630 		(void *)mrg_SetPtrSize,
    631 		(void *)mrg_GetPtrSize,
    632 	[0x2f]	(void *)__UNCONST(mrg_PostEvent),	/* XXXGCC ? */
    633 	[0x3b]	(void *)mrg_Delay,
    634 	[0x47]	(void *)mrg_SetTrapAddress,
    635 	[0x55]	(void *)__UNCONST(mrg_StripAddress),	/* XXXGCC ? */
    636 	[0x82]	(void *)mrg_DTInstall,
    637 #else
    638 #error "Using a GNU C extension."
    639 #endif
    640 };
    641 
    642 void *mrg_ToolBoxtraps[1024] = {
    643 	[0x19c] (void *)mrg_CountResources,
    644 	[0x19d] (void *)mrg_GetIndResource,
    645 	[0x1a0] (void *)mrg_GetResource,
    646 	[0x1af] (void *)mrg_ResError,
    647 };
    648 
    649 /*
    650  * Handle a supervisor mode A-line trap.
    651  */
    652 void
    653 mrg_aline_super(struct frame *frame)
    654 {
    655 	void *trapaddr;
    656 	u_short trapword;
    657 	int isOStrap;
    658 	int trapnum;
    659 	int a0passback;
    660 	u_int32_t a0bucket, d0bucket;
    661 	int danprint=0; /* This shouldn't be necessary, but seems to be.  */
    662 
    663 #if defined(MRG_DEBUG)
    664 	printf("mrg: a super");
    665 #endif
    666 
    667 	trapword = *(u_short *)frame->f_pc;
    668 
    669 	if (trapword == 0xa71e)
    670 		danprint = 1;
    671 
    672 #if defined(MRG_DEBUG)
    673 	printf(" wd 0x%lx", (long)trapword);
    674 #endif
    675 	isOStrap = ! TRAP_TOOLBOX(trapword);
    676 	trapnum = TRAP_NUM(trapword);
    677 
    678 	if (danprint) {
    679 		/*
    680 		 * Without these print statements, ADBReInit fails on IIsi
    681 		 * It is unclear why--perhaps a compiler bug?  delay()s do not
    682 		 * work, nor does some assembly similar to the  printf calls.
    683 		 * A printf(""); is sufficient, but gcc -Wall is noisy about
    684 		 * it, so I figured backspace is harmless enough...
    685 		 */
    686 		printf(" "); printf("\010");
    687 	}
    688 
    689 #if defined(MRG_DEBUG)
    690 	printf(" %s # 0x%x", isOStrap? "OS" :
    691 		"ToolBox", trapnum);
    692 #endif
    693 
    694 	/*
    695 	 * Only OS Traps come to us; alinetrap() takes care of ToolBox
    696 	 * traps, which are a horrible Frankenstein-esque abomination.
    697 	 */
    698 
    699 	trapaddr = mrg_OStraps[trapnum];
    700 #if defined(MRG_DEBUG)
    701 	printf(" addr 0x%lx\n", (long)trapaddr);
    702  	printf("    got:    d0 = 0x%8x,  a0 = 0x%8x, called from: 0x%8x\n",
    703 		frame->f_regs[0], frame->f_regs[8], frame->f_pc	);
    704 #endif
    705 	if (trapaddr == NULL) {
    706 		printf("unknown %s trap 0x%x, no trap address available\n",
    707 			isOStrap ? "OS" : "ToolBox", trapword);
    708 		panic("mrg_aline_super()");
    709 	}
    710 	a0passback = TRAP_PASSA0(trapword);
    711 
    712 #if defined(MRG_TRACE)
    713 	tron();
    714 #endif
    715 
    716 /* 	put a0 in a0 */
    717 /* 	put a1 in a1 */
    718 /* 	put d0 in d0 */
    719 /* 	put d1 in d1 */
    720 /*	put trapaddr in a2 */
    721 /* save a6 */
    722 /* 	call the damn routine */
    723 /* restore a6 */
    724 /* 	store d0 in d0bucket */
    725 /* 	store a0 in d0bucket */
    726 /* This will change a2,a1,d1,d0,a0 and possibly a6 */
    727 
    728 	__asm volatile (
    729 	"	movl	%2@,%%d0	\n"
    730 	"	movl	%2@(4),%%d1	\n"
    731 	"	movl	%2@(32),%%a0	\n"
    732 	"	movl	%2@(36),%%a1	\n"
    733 	"	movl	%3,%%a2		\n"
    734 	"	jbsr	%%a2@		\n"
    735 	"	movl	%%a0,%0		\n"
    736 	"	movl	%%d0,%1"
    737 
    738 		: "=g" (a0bucket), "=g" (d0bucket)
    739 
    740 		: "a" (&frame->f_regs), "g" (trapaddr)
    741 
    742 		: "d0","d1","a0","a1","a2"
    743 );
    744 
    745 #if defined(MRG_TRACE)
    746 	troff();
    747 #endif
    748 #if defined(MRG_DEBUG)
    749 	printf("    result: d0 = 0x%8x,  a0 = 0x%8x\n",
    750 		d0bucket, a0bucket );
    751  	printf(" bk");
    752 #endif
    753 
    754 	frame->f_regs[0] = d0bucket;
    755 	if (a0passback)
    756 		frame->f_regs[8] = a0bucket;
    757 
    758 	frame->f_pc += 2;	/* skip offending instruction */
    759 
    760 #if defined(MRG_DEBUG)
    761 	printf(" exit\n");
    762 #endif
    763 }
    764 
    765 extern u_int32_t traceloopstart[];
    766 extern u_int32_t traceloopend;
    767 extern u_int32_t *traceloopptr;
    768 
    769 void
    770 dumptrace(void)
    771 {
    772 #if defined(MRG_TRACE)
    773 	u_int32_t *traceindex;
    774 
    775 	printf("instruction trace:\n");
    776 	traceindex = traceloopptr + 1;
    777 	while (traceindex != traceloopptr) {
    778 		printf("    %08x\n", *traceindex++);
    779 		if (traceindex == &traceloopend)
    780 			traceindex = &traceloopstart[0];
    781 	}
    782 #else
    783 	printf("mrg: no trace functionality enabled\n");
    784 #endif
    785 }
    786 
    787 	/* To find out if we're okay calling ROM vectors */
    788 int
    789 mrg_romready(void)
    790 {
    791 	return (mrg_romident != NULL);
    792 }
    793 
    794 extern unsigned long	IOBase;
    795 extern volatile u_char	*sccA;
    796 
    797 	/* initialize Mac ROM Glue */
    798 void
    799 mrg_init(void)
    800 {
    801 	const char *findername = "MacBSD FakeFinder";
    802 	int i;
    803 #if defined(MRG_TEST)
    804 	void *ptr;
    805 	short rcnt;
    806 	int sizeptr;
    807 	extern short mrg_ResErr;
    808 	void **handle;
    809 #endif
    810 
    811 	/*
    812 	 * Clear the VBLQueue.
    813 	 */
    814 	VBLQueue = (u_int16_t) 0;
    815 	VBLQueue_head = (void *) 0;
    816 	VBLQueue_tail = (void *) 0;
    817 
    818 #if defined(MRG_TEST)
    819 	if (ROMResourceMap) {
    820 		printf("mrg: testing CountResources\n");
    821 		__asm volatile (
    822 		"	clrl    %%sp@-	\n"
    823 		"	clrl    %%sp@-	\n"
    824 		"	.word   0xa99c	\n"
    825 		"	movw    %%sp@+,%0"
    826 			: "=g" (rcnt));
    827 		printf("mrg: found %d resources in ROM\n", rcnt);
    828 		__asm volatile (
    829 		"	clrl    %%sp@-	\n"
    830 		"	movl    #0x44525652,%%sp@-	\n"
    831 		"	.word   0xa99c	\n"
    832 		"	movw    %%sp@+,%0"
    833 			: "=g" (rcnt));
    834 		printf("mrg: %d are DRVR resources\n", rcnt);
    835 		if (rcnt == 0)
    836 			panic("Oops! No DRVR Resources found in ROM");
    837 	}
    838 #endif
    839 #if defined(MRG_TEST)
    840 	if (ROMResourceMap) {
    841 		printf("mrg: testing GetIndResource\n");
    842 		__asm volatile (
    843 		"	clrl    %%sp@-		\n"
    844 		"	movl    #0x44525652,%%sp@-	\n"
    845 		"	movw    #0x01,%%sp@-	\n"
    846 		"	.word   0xa99d		\n"
    847 		"	movl    %%sp@+,%0"
    848 			: "=g" (handle));
    849 		printf("Handle to first DRVR resource is %p\n", handle);
    850 		printf("DRVR: 0x%08lx -> 0x%08lx -> 0x%08lx\n",
    851 		    (long)Get_Ind_Resource(0x44525652, 1),
    852 		    (long)*Get_Ind_Resource(0x44525652, 1),
    853 		    (long)*((u_int32_t *)*Get_Ind_Resource(0x44525652, 1)));
    854 		__asm volatile (
    855 		"	clrl    %%sp@-		\n"
    856 		"	movl    #0x44525652,%%sp@-	\n"
    857 		"	movw    #0x02,%%sp@-	\n"
    858 		"	.word   0xa99d		\n"
    859 		"	movl    %%sp@+,%0"
    860 			: "=g" (handle));
    861 		printf("Handle to second DRVR resource is %p\n", handle);
    862 		printf("DRVR: 0x%08lx -> 0x%08lx -> 0x%08lx\n",
    863 		    (long)Get_Ind_Resource(0x44525652, 2),
    864 		    (long)*Get_Ind_Resource(0x44525652, 2),
    865 		    (long)*((u_int32_t *)*Get_Ind_Resource(0x44525652, 2)));
    866 	}
    867 #endif
    868 	if (mrg_romready()) {
    869 		printf("mrg: '%s' ROM glue", mrg_romident);
    870 
    871 #if defined(MRG_TRACE)
    872 #if defined(MRG_FOLLOW)
    873 		printf(", tracing on (verbose)");
    874 #else /* ! defined (MRG_FOLLOW) */
    875 		printf(", tracing on (silent)");
    876 #endif /* defined(MRG_FOLLOW) */
    877 #else /* !defined(MRG_TRACE) */
    878 		printf(", tracing off");
    879 #endif	/* defined(MRG_TRACE) */
    880 
    881 #if defined(MRG_DEBUG)
    882 		printf(", debug on");
    883 #else /* !defined(MRG_DEBUG) */
    884 		printf(", debug off");
    885 #endif /* defined(MRG_DEBUG) */
    886 
    887 #if defined(MRG_SHOWTRAPS)
    888 		printf(", verbose traps");
    889 #else /* !defined(MRG_SHOWTRAPS) */
    890 		printf(", silent traps");
    891 #endif /* defined(MRG_SHOWTRAPS) */
    892 	}else{
    893 		printf("mrg: kernel has no ROM vectors for this machine!\n");
    894 		return;
    895 	}
    896 
    897 	printf("\n");
    898 
    899 #if defined(MRG_DEBUG)
    900 	printf("mrg: start init\n");
    901 #endif
    902 		/* expected globals */
    903 	ExpandMem = &mrg_ExpandMem[0];
    904 	*((u_int16_t *)(mrg_ExpandMem + 0x00) ) = 0x0123;	/* magic (word) */
    905 	*((u_int32_t *)(mrg_ExpandMem + 0x02) ) = 0x000001ea;	/* Length of table (long) */
    906 	*((u_int32_t *)(mrg_ExpandMem + 0x1e0)) = (u_int32_t) &mrg_adbstore4[0];
    907 
    908 	*((u_int32_t *)(mrg_adbstore4 + 0x8)) = (u_int32_t) mrg_init_stub_1;
    909 	*((u_int32_t *)(mrg_adbstore4 + 0xc)) = (u_int32_t) mrg_init_stub_2;
    910 	*((u_int32_t *)(mrg_adbstore4 + 0x4)) = (u_int32_t) &mrg_adbstore5[0];
    911 
    912 	*((u_int32_t *)(mrg_adbstore5 + 0x08)) = (u_int32_t) 0x00100000;
    913 	*((u_int32_t *)(mrg_adbstore5 + 0x0c)) = (u_int32_t) 0x00100000;
    914 	*((u_int32_t *)(mrg_adbstore5 + 0x16)) = (u_int32_t) 0x00480000;
    915 
    916 	ADBBase = &mrg_adbstore[0];
    917 	ADBState = &mrg_adbstore2[0];
    918 	ADBYMM = &mrg_adbstore3[0];
    919 	MinusOne = 0xffffffff;
    920 	Lo3Bytes = 0x00ffffff;
    921 	VIA = (void *)__UNVOLATILE(Via1Base);
    922 	MMU32Bit = 1; /* ?means MMU is in 32 bit mode? */
    923   	if (TimeDBRA == 0)
    924 		TimeDBRA = 0xa3b;		/* BARF default is Mac II */
    925   	if (ROMBase == 0)
    926 		panic("ROMBase not set in mrg_init()!");
    927 
    928 	strcpy(&FinderName[1], findername);
    929 	FinderName[0] = (u_char) strlen(findername);
    930 #if defined(MRG_DEBUG)
    931 	printf("After setting globals\n");
    932 #endif
    933 
    934 		/* Fake jump points */
    935 	for (i = 0; i < 8; i++) /* Set up fake Lvl1DT */
    936 		Lvl1DT[i] = mrg_lvl1dtpanic;
    937 	for (i = 0; i < 8; i++) /* Set up fake Lvl2DT */
    938 		Lvl2DT[i] = mrg_lvl2dtpanic;
    939 	Lvl1DT[0] = (void (*)(void))mrg_1sec_timer_tick;
    940 	Lvl1DT[2] = (void (*)(void))mrg_romadbintr;
    941 	Lvl1DT[4] = (void (*)(void))mrg_rompmintr;
    942 	JADBProc = mrg_jadbprocpanic;	/* Fake JADBProc for the time being */
    943 	jSwapMMU = mrg_jswapmmupanic;	/* Fake jSwapMMU for the time being */
    944 	JKybdTask = mrg_jkybdtaskpanic;	/* Fake JKybdTask for the time being */
    945 
    946 	/* probably very dangerous */
    947 	jADBOp = (void (*)(void))mrg_OStraps[0x7c];
    948 
    949 	mrg_VIA2 = (void *)((char *)__UNVOLATILE(Via1Base) +
    950 	    VIA2 * 0x2000);	/* see via.h */
    951 	SCCRd = (void *)__UNVOLATILE(sccA);/* ser.c ; we run before serinit */
    952 
    953 	jDTInstall = (void *)mrg_DTInstall;
    954 	dtmgr_softintr_cookie = softint_establish(SOFTINT_SERIAL,
    955 	    (void (*)(void *))mrg_execute_deferred, NULL);
    956 
    957 	/* AV ROMs want this low memory vector to point to a jump table */
    958 	InitEgretJTVec = (u_int32_t **)(void *)&mrg_AVInitEgretJT;
    959 
    960 	switch (mach_cputype()) {
    961 		case MACH_68020:	CPUFlag = 2;	break;
    962 		case MACH_68030:	CPUFlag = 3;	break;
    963 		case MACH_68040:	CPUFlag = 4;	break;
    964 		default:
    965 			printf("mrg: unknown CPU type; cannot set CPUFlag\n");
    966 			break;
    967 	}
    968 
    969 #if defined(MRG_TEST)
    970 	printf("Allocating a pointer...\n");
    971 	ptr = (void *)NewPtr(1024);
    972 	printf("Result is 0x%lx.\n", (long)ptr);
    973 	sizeptr = GetPtrSize((Ptr)ptr);
    974 	printf("Pointer size is %d\n", sizeptr);
    975 	printf("Freeing the pointer...\n");
    976 	DisposPtr((Ptr)ptr);
    977 	printf("Free'd.\n");
    978 
    979 	for (i = 0; i < 500000; i++)
    980 		if ((i % 100000) == 0)printf(".");
    981 	printf("\n");
    982 
    983 	mrg_ResErr = 0xdead;	/* set an error we know */
    984 	printf("Getting error code...\n");
    985 	i = ResError();
    986 	printf("Result code (0xdeadbaaf): %x\n", i);
    987 	printf("Getting an ADBS Resource...\n");
    988 	handle = GetResource(0x41244253, 2);
    989 	printf("Handle result from GetResource: 0x%lx\n", (long)handle);
    990 	printf("Getting error code...\n");
    991 	i = ResError();
    992 	printf("Result code (-192?) : %d\n", i);
    993 
    994 	for (i = 0; i < 500000; i++)
    995 		if ((i % 100000) == 0)printf(".");
    996 	printf("\n");
    997 
    998 #if defined(MRG_TRACE)
    999 	printf("Turning on a trace\n");
   1000 	tron();
   1001 	printf("We are now tracing\n");
   1002 	troff();
   1003 	printf("Turning off trace\n");
   1004 	dumptrace();
   1005 #endif /* MRG_TRACE */
   1006 
   1007 	for (i = 0; i < 500000; i++)
   1008 		if ((i % 100000) == 0)
   1009 			printf(".");
   1010 	printf("\n");
   1011 #endif /* MRG_TEST */
   1012 
   1013 #if defined(MRG_DEBUG)
   1014 	printf("after setting jump points\n");
   1015 	printf("mrg: end init\n");
   1016 #endif
   1017 
   1018 	if (1) {
   1019 		/*
   1020 		 * For the bloody Mac II ROMs, we have to map this space
   1021 		 * so that the PRam functions will work.
   1022 		 * Gee, Apple, is that a hard-coded hardware address in
   1023 		 * your code?  I think so! (_ReadXPRam + 0x0062 on the
   1024 		 * II)  We map the VIAs in here.  The C610 apparently
   1025 		 * needs it, too, which means that a bunch of 040s do, too.
   1026 		 * Once again, I regret the mapping changes I made...  -akb
   1027 		 */
   1028 #ifdef DIAGNOSTIC
   1029 		printf("mrg: I/O map kludge for ROMs that use hardware %s",
   1030 			"addresses directly.\n");
   1031 #endif
   1032 		pmap_map(0x50f00000, 0x50f00000, 0x50f00000 + 0x4000,
   1033 			 VM_PROT_READ|VM_PROT_WRITE);
   1034 	}
   1035 }
   1036 
   1037 #ifdef MRG_ADB
   1038 static void	setup_egret(void);
   1039 
   1040 static void
   1041 setup_egret(void)
   1042 {
   1043 	if (0 != mrg_InitEgret) {
   1044 
   1045 	/* This initializes ADBState (mrg_ADBStore2) and
   1046 	   enables interrupts */
   1047 		__asm volatile (
   1048 		"	movml	%%a0-%%a2,%%sp@-	\n"
   1049 		"	movl	%1,%%a0	\n"	/* ADBState, mrg_adbstore2 */
   1050 		"	movl	%0,%%a1	\n"
   1051 		"	jbsr	%%a1@	\n"
   1052 		"	movml	%%sp@+,%%a0-%%a2 "
   1053 			:
   1054 			: "g" (mrg_InitEgret), "g" (ADBState)
   1055 			: "a0","a1");
   1056 		jEgret = (void (*)) mrg_OStraps[0x92]; /* may have been set in asm() */
   1057 	}
   1058 	else printf("Help ...  No vector for InitEgret!!\n");
   1059 
   1060 #if defined(MRG_DEBUG)
   1061 	printf("mrg: ADBIntrVector: 0x%8lx,  mrg_ADBIntrVector: 0x%8lx\n",
   1062 			(long) mrg_romadbintr,
   1063 			*((long *) 0x19a));
   1064 	printf("mrg: EgretOSTrap: 0x%8lx\n",
   1065 			(long) mrg_OStraps[0x92]);
   1066 #endif
   1067 }
   1068 #endif
   1069 
   1070 void
   1071 mrg_initadbintr(void)
   1072 {
   1073 	if (mac68k_machine.do_graybars)
   1074 		printf("Got following HwCfgFlags: 0x%4x, 0x%8x, 0x%8x, 0x%8x\n",
   1075 				HwCfgFlags, HwCfgFlags2, HwCfgFlags3, ADBReInit_JTBL);
   1076 
   1077 	if ((HwCfgFlags == 0) && (HwCfgFlags2 == 0) && (HwCfgFlags3 == 0)) {
   1078 		printf("Caution: No HwCfgFlags from Booter, please "
   1079 			"use at least booter version 1.8.\n");
   1080 
   1081 		if (current_mac_model->class == MACH_CLASSIIsi) {
   1082 			printf("     ...  Using defaults for IIsi.\n");
   1083 
   1084 			/* Egret and ADBReInit look into these HwCfgFlags */
   1085 			HwCfgFlags = 0xfc00;
   1086 			HwCfgFlags2 = 0x0000773F;
   1087 			HwCfgFlags3 = 0x000001a6;
   1088 		}
   1089 
   1090 		printf("Using HwCfgFlags: 0x%4x, 0x%8x, 0x%8x\n",
   1091 			HwCfgFlags, HwCfgFlags2, HwCfgFlags3);
   1092 	}
   1093 
   1094 #ifdef MRG_ADB
   1095 	/*
   1096 	 * If we think there is an Egret in the machine, attempt to
   1097 	 * set it up.  If not, just enable the interrupts (only on
   1098 	 * some machines, others are already on from ADBReInit?).
   1099 	 */
   1100 	if (   ((HwCfgFlags3 & 0x0e) == 0x06 )
   1101 	    || ((HwCfgFlags3 & 0x70) == 0x20 )) {
   1102 		if (mac68k_machine.do_graybars)
   1103 			printf("mrg: setup_egret:\n");
   1104 
   1105 		setup_egret();
   1106 
   1107 		if (mac68k_machine.do_graybars)
   1108 			printf("mrg: setup_egret: done.\n");
   1109 
   1110 	} else {
   1111 
   1112 		if (mac68k_machine.do_graybars)
   1113 			printf("mrg: Not setting up egret.\n");
   1114 
   1115 		via_reg(VIA1, vIFR) = 0x4;
   1116 		via_reg(VIA1, vIER) = 0x84;
   1117 
   1118 		if (mac68k_machine.do_graybars)
   1119 			printf("mrg: ADB interrupts enabled.\n");
   1120 	}
   1121 #else
   1122 	/* Extra Egret setup required only for MRG ADB functions. */
   1123 	printf("mrg: skipping egret setup\n");
   1124 #endif /* MRG_ADB */
   1125 }
   1126 
   1127 /*
   1128  * NOTE:  By eliminating the setvectors routine and moving its function
   1129  *        to here we only have to deal with re-locating MacOS Addresses
   1130  *        once and all in one place.
   1131  */
   1132 void
   1133 mrg_fixupROMBase(void *obase, void *nbase)
   1134 {
   1135 	u_int32_t oldbase, newbase;
   1136 	romvec_t *rom;
   1137 	int i;
   1138 
   1139 	oldbase = (u_int32_t) obase;
   1140 	newbase = (u_int32_t) nbase;
   1141 
   1142 	/*
   1143 	 * Grab the pointer to the Mac ROM Glue Vector table
   1144 	 */
   1145 	rom = mrg_MacOSROMVectors;
   1146 
   1147 	if (rom == NULL)
   1148 		return;		/* whoops!  ROM vectors not defined! */
   1149 
   1150 	mrg_romident = rom->romident;
   1151 
   1152 	if (0 != mrg_ADBIntrPtr) {
   1153 		mrg_romadbintr = mrg_ADBIntrPtr;
   1154 		printf("mrg_fixup: using ADBIntrPtr from booter: 0x%08lx\n",
   1155 		    (long)mrg_ADBIntrPtr);
   1156 	} else
   1157 		mrg_romadbintr = rom->adbintr == 0 ?
   1158 		    0 : (char *)rom->adbintr - oldbase + newbase;
   1159 
   1160 	mrg_rompmintr = rom->pmintr == 0 ?
   1161 	    0 : (char *)rom->pmintr - oldbase + newbase;
   1162 	mrg_ADBAlternateInit = rom->ADBAlternateInit == 0 ?
   1163 	    0 : (char *)rom->ADBAlternateInit - oldbase + newbase;
   1164 
   1165 	/*
   1166 	 * mrg_adbstore becomes ADBBase
   1167 	 */
   1168 	*((u_int32_t *)(mrg_adbstore + 0x130)) = rom->adb130intr == 0 ?
   1169 	    0 : (u_int32_t) rom->adb130intr - oldbase + newbase;
   1170 
   1171 	mrg_OStraps[0x77] = rom->CountADBs == 0 ?
   1172 	    0 : (char *)rom->CountADBs - oldbase + newbase;
   1173 	mrg_OStraps[0x78] = rom->GetIndADB == 0 ?
   1174 	    0 : (char *)rom->GetIndADB - oldbase + newbase;
   1175 	mrg_OStraps[0x79] = rom-> GetADBInfo == 0 ?
   1176 	    0 : (char *)rom->GetADBInfo - oldbase + newbase;
   1177 	mrg_OStraps[0x7a] = rom->SetADBInfo == 0 ?
   1178 	    0 : (char *)rom->SetADBInfo - oldbase + newbase;
   1179 	mrg_OStraps[0x7b] = rom->ADBReInit == 0 ?
   1180 	    0 : (char *)rom->ADBReInit - oldbase + newbase;
   1181 	mrg_OStraps[0x7c] = rom->ADBOp == 0 ?
   1182 	    0 : (char *)rom->ADBOp - oldbase + newbase;
   1183 	mrg_OStraps[0x85] = rom->PMgrOp == 0 ?
   1184 	    0 : (char *)rom->PMgrOp - oldbase + newbase;
   1185 	mrg_OStraps[0x51] = rom->ReadXPRam == 0 ?
   1186 	    0 : (char *)rom->ReadXPRam - oldbase + newbase;
   1187 	mrg_OStraps[0x38] = rom->WriteParam == 0 ?
   1188 	    0 : (char *)rom->WriteParam - oldbase + newbase;/* WriteParam*/
   1189 	mrg_OStraps[0x3a] = rom->SetDateTime == 0 ?
   1190 	    0 : (char *)rom->SetDateTime - oldbase + newbase;/*SetDateTime*/
   1191 	mrg_OStraps[0x3f] = rom->InitUtil == 0 ?
   1192 	    0 : (char *)rom->InitUtil - oldbase + newbase;  /* InitUtil */
   1193 	mrg_OStraps[0x51] = rom->ReadXPRam == 0 ?
   1194 	    0 : (char *)rom->ReadXPRam - oldbase + newbase; /* ReadXPRam */
   1195 	mrg_OStraps[0x52] = rom->WriteXPRam == 0 ?
   1196 	    0 : (char *)rom->WriteXPRam - oldbase + newbase;/* WriteXPRam */
   1197 
   1198 	if (rom->Egret == 0) {
   1199 		jEgret = 0;
   1200 		mrg_OStraps[0x92] = 0;
   1201 	} else {
   1202 		jEgret = (void (*))((char *)rom->Egret - oldbase + newbase);
   1203 		mrg_OStraps[0x92] = (char *)rom->Egret - oldbase + newbase;
   1204 	}
   1205 	mrg_InitEgret = rom->InitEgret == 0 ?
   1206 	    0 : (char *)rom->InitEgret - oldbase + newbase;
   1207 
   1208 	if (rom->jClkNoMem == 0) {
   1209 		printf("WARNING: don't have a value for jClkNoMem, ");
   1210 		printf("please contact:  walter (at) ghpc8.ihf.rwth-aachen.de\n");
   1211 		printf("Can't read RTC without it. Using MacOS boot time.\n");
   1212 		jClkNoMem = 0;
   1213 	} else
   1214 		jClkNoMem = (void (*))((char *)rom->jClkNoMem - oldbase + newbase);
   1215 	/*
   1216 	 * Get the ToolBox Routines we may need.  These are
   1217 	 * used in the ADB Initialization of some systems.
   1218 	 * If we don't have the ROM addresses for these routines
   1219 	 * we'll setup to catch the calls in our own dummy
   1220 	 * routines. That way we can politely tell the user
   1221 	 * what we'll need to complete initialization on the system.
   1222 	 */
   1223 	mrg_ToolBoxtraps[0x04d] = rom->FixDiv == 0 ?
   1224 	    (void *)mrg_FixDiv : (char *)rom->FixDiv - oldbase + newbase;
   1225 	mrg_ToolBoxtraps[0x068] = rom->FixMul == 0 ?
   1226 	    (void *)mrg_FixMul : (char *)rom->FixMul - oldbase + newbase;
   1227 
   1228 	/*
   1229 	 * Some systems also require this to be setup for use in
   1230 	 * ADB Initialization.  Use whatever address was provided
   1231 	 * to us in the romvec table for this system. This may
   1232 	 * cause a problem on some systems, and may need a better
   1233 	 * Trap handler in the future.
   1234 	 */
   1235 	ADBReInit_JTBL = rom->ADBReInit_JTBL == 0 ?
   1236 	   0 : (u_int32_t)rom->ADBReInit_JTBL - oldbase + newbase;
   1237 
   1238 	/*
   1239 	 * Setup to trap unexpected access to ADBProc which is used in
   1240 	 * ADB Initialization on some systems. If the correct entry
   1241 	 * point in the ADBInit code is selected, this address is
   1242 	 * re-configured by the ROM during initialization. This feature
   1243 	 * is not currently used by NetBSD.
   1244 	 */
   1245 	JADBProc = mrg_jadbprocpanic;
   1246 
   1247 	/*
   1248 	 * Get the address of the first (top) Resource in the ROM.
   1249 	 * This will be the head of a linked list of all Resources
   1250 	 * in the ROM which will be mapped in mrg_InitResources.
   1251 	 */
   1252 	ROMResourceMap = rom->ROMResourceMap == 0 ?
   1253 	    0 : (void (*))((char *)rom->ROMResourceMap - oldbase + newbase);
   1254 
   1255 	for (i = 0; i < sizeof(mrg_AVInitEgretJT) / sizeof(mrg_AVInitEgretJT[0]); i++)
   1256 		mrg_AVInitEgretJT[i] = mrg_AVInitEgretJT[i] == 0 ?
   1257 		    0 : mrg_AVInitEgretJT[i] - oldbase + newbase;
   1258 
   1259 #if defined(MRG_DEBUG)
   1260 	printf("mrg: ROM adbintr 0x%08lx -> 0x%08lx\n",
   1261 	    (long)rom->adbintr, (long)mrg_romadbintr);
   1262 	printf("mrg: ROM pmintr 0x%08lx -> 0x%08lx\n",
   1263 	    (long)rom->pmintr, (long)mrg_rompmintr);
   1264 	printf("mrg: OS trap 0x77 (CountADBs) = 0x%08lx -> 0x%08lx\n",
   1265 	    (long)rom->CountADBs, (long)mrg_OStraps[0x77]);
   1266 	printf("mrg: OS trap 0x78 (GetIndADB) = 0x%08lx -> 0x%08lx\n",
   1267 	    (long)rom->GetIndADB, (long)mrg_OStraps[0x78]);
   1268 	printf("mrg: OS trap 0x79 (GetADBInfo) = 0x%08lx -> 0x%08lx\n",
   1269 	    (long)rom->GetADBInfo, (long)mrg_OStraps[0x79]);
   1270 	printf("mrg: OS trap 0x7a (SetADBInfo) = 0x%08lx -> 0x%08lx\n",
   1271 	    (long)rom->SetADBInfo, (long)mrg_OStraps[0x7a]);
   1272 	printf("mrg: OS trap 0x7b (ADBReInit) = 0x%08lx -> 0x%08lx\n",
   1273 	    (long)rom->ADBReInit, (long)mrg_OStraps[0x7b]);
   1274 	printf("mrg: OS trap 0x7c (ADBOp) = 0x%08lx -> 0x%08lx\n",
   1275 	    (long)rom->ADBOp, (long)mrg_OStraps[0x7c]);
   1276 	printf("mrg: OS trap 0x85 (PMgrOp) = 0x%08lx -> 0x%08lx\n",
   1277 	    (long)rom->PMgrOp, (long)mrg_OStraps[0x85]);
   1278 	printf("mrg: OS trap 0x92 (Egret) = 0x%08lx -> 0x%08lx\n",
   1279 	    (long)rom->Egret, (long)mrg_OStraps[0x92]);
   1280 	printf("mrg: ROM ADBAltInit 0x%08lx -> 0x%08lx\n",
   1281 	    (long)rom->ADBAlternateInit, (long)mrg_ADBAlternateInit);
   1282 	printf("mrg: ROM ADBReInit_JTBL 0x%08lx -> 0x%08lx\n",
   1283 	    (long)rom->ADBReInit_JTBL, (long)ADBReInit_JTBL);
   1284 	printf("mrg: ROM InitEgret  0x%08lx -> 0x%08lx\n",
   1285 	    (long)rom->InitEgret, (long)mrg_InitEgret);
   1286 	printf("mrg: ROM Resource list-head 0x%08lx -> 0x%08lx\n",
   1287 	    (long)rom->ROMResourceMap, (long)ROMResourceMap);
   1288 #endif
   1289 }
   1290 
   1291 #ifdef MRG_ADB
   1292 void
   1293 ADBAlternateInit(void)
   1294 {
   1295 	if (0 == mrg_ADBAlternateInit) {
   1296 		ADBReInit();
   1297 	} else {
   1298  		__asm volatile (
   1299 		"	movml	%%a0-%%a6/%%d0-%%d7,%%sp@-	\n"
   1300 		"	movl	%0,%%a1		\n"
   1301 		"	movl	%1,%%a3		\n"
   1302 		"	jbsr	%%a1@		\n"
   1303 		"	movml	%%sp@+,%%a0-%%a6/%%d0-%%d7"
   1304 			:
   1305 			: "g" (mrg_ADBAlternateInit), "g" (ADBBase)
   1306 			: "a1","a3");
   1307 	}
   1308 }
   1309 #endif /* MRG_ADB */
   1310