Subject: port-mac/2113: Add resource management for ADB support on P550
To: None <gnats-bugs@NetBSD.ORG>
From: Walter Ruetten <walter@ghpc8.ihf.rwth-aachen.de>
List: netbsd-bugs
Date: 02/22/1996 21:25:16
>Number:         2113
>Category:       port-mac
>Synopsis:       Add resource management for ADB support on P550
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 22 16:05:05 1996
>Last-Modified:
>Originator:     Walter Ruetten
>Organization:

>Release:        1.1
>Environment:
Mac Performa P550, NetBSD/mac68k, 
System: NetBSD islington.ihf.rwth-aachen.de 1.1A NetBSD 1.1A (ISLINGTON) #278: Tue Feb 20 19:39:14 MET 1996 walter@islington.ihf.rwth-aachen.de:/usr/src/sys/arch/mac68k.vi/compile/ISLINGTON mac68k


>Description:
- Performa P550 needs the 'CountResources', 'GetIndResource',
    'FixDiv' and 'FixMul' toolbox traps.
- OStrap 'Delay' is also needed.

-  NewPtr trap doesn't clear memory! This harms ADB on the P550.

-  PB180 needs Vertical Blanking Queue (VBLQueue, 60Hz retrace interrupts).



>How-To-Repeat:

>Fix:

File: macrom.c:
- Add ExpandMem and assorted memory.
- Add variables for resource management.
- Add mrg_Delay() which handles the OStrap 'Delay'
- Add C functions for resource management:
    is_resource()
    count_all_resources()
    w_build_resource_list()
    w_count_resources()
    w_get_ind_resource()
- Add mrg_VBLQueue() to handle the Vertical Blanking Queue
  (still preliminary).
- Zero out memory allocated by OStrap 'Newptr sys,clear'.
- Add mrg_StripAddress() to handle 'StripAddress' trap. 
- Update mrg_OStrap[] and mrg_ToolBoxtraps[]
- Add mrg_SetOSTrapAddress() to handle 'SetOSTrapAddress' trap.
- make mrg_aline_super() tell from where it got called,
    what parameters it got, and which ones it is going to return
    when MRG_DEBUG is defined.
- fill in addresses for 'FixDiv' and 'FixMul' traps from the
    ROM vector table.
- in mrg_init(): build up resourcelist before any of the
                 ADB stuff starts running.
- in mrg_init(): initialize VBLQueue.
- in mrg_init(): initialize ExpandMem et al. with magic numbers
                 and pointers to each other.
- make setup_egret() more verbose concerning interrupt vectors
    and the results of SetOSTrapAddress.
- allow setup_egret() to run for two different values of 
    HwCfgFlag3.
- in mrg_fixupROMBase(): relocate ToolBoxtraps too.


File: macromasm.s:
- variables for ExpandMem and VBLQueue.
- assembler stubs for mrg_CountResources() and mrg_GetIndResource().

File: locore.s:
- Divert 60Hz timer tick to mrg_VBLQueue().

File: autoconf.c:
- rt clock must be running before adb_init for PowerBooks,
    as they use the VBLqueue.


diffs follow:


diff -c mac68k/mac68k/macrom.c mac68k.vi/mac68k/macrom.c
*** mac68k/mac68k/macrom.c	Sat Oct 14 03:09:10 1995
--- mac68k.vi/mac68k/macrom.c	Tue Feb 20 21:27:52 1996
***************
*** 69,74 ****
--- 69,77 ----
  u_char mrg_adbstore[512];
  u_char mrg_adbstore2[512];
  u_char mrg_adbstore3[512];
+ u_char mrg_ExpandMem[512];			/* 0x1ea Bytes minimum */
+ u_char mrg_adbstore4[32];			/* 0x16 bytes was the largest I found yet */
+ u_char mrg_adbstore5[80];			/* 0x46 bytes minimum */
  
  caddr_t	mrg_romadbintr = (caddr_t)0x40807002;	/* ROM ADB interrupt */
  caddr_t	mrg_rompmintr = 0;			/* ROM PM (?) interrupt */
***************
*** 77,88 ****
--- 80,331 ----
  caddr_t mrg_InitEgret = 0;
  caddr_t	mrg_ADBIntrPtr = (caddr_t)0x0;	/* ADB interrupt taken from MacOS vector table*/
  
+ caddr_t *rsrc_handle;				/* Variables for ROM resource map */
+ caddr_t *rsrc_header;
+ u_int32_t nr_of_rsrcs;
+ 
+ 
  /*
   * Last straw functions; we didn't set them up, so freak out!
   * When someone sees these called, we can finally go back and
   * bother to implement them.
   */
  
+ 
+ int
+ mrg_Delay()
+ {
+ #define TICK_DURATION 16625
+ 
+ 	int result = noErr;
+ 	u_int32_t ticks;
+ 
+ 	asm("	movl	a0, %0"		/* get arguments */
+ 		:
+ 		: "g" (ticks));
+ 
+ #if defined(MRG_DEBUG)
+ 	printf("mrg: mrg_Delay(%d) = %d ms\n", ticks, ticks * 60);
+ #endif
+ 	delay(ticks * TICK_DURATION);
+ 	return(ticks);	/* The number of ticks since startup should be
+ 			 * returned here. Until someone finds a need for
+ 			 * this, we just return the requested number
+ 			 *  of ticks */
+ }
+ 
+ 
+ int
+ is_resource(caddr_t rp)
+ {
+ 	/*  Heuristic to locate resources in the ROM.
+ 	 *  rp+8 builds a linked list, but where does it start?
+ 	 */
+ 	if (    (0x00000000 == ( *((u_int32_t *)  rp   ) & 0x00ffffff))	/* magic numbers */
+ 	     && (0x00000000 ==   *((u_int32_t *) (rp+0x04)) )		/* magic numbers */
+ 	     && ( 0 == ( *((u_int32_t *) (rp+0x08)) & 0x0f ) )		/* on paragraph boundary */
+ 	     && ( 0 == ( *((u_int32_t *) (rp+0x0c)) & 0x0f ) )		/* on paragraph boundary */
+ 	     && ( 0 == (  ((u_int32_t) rp) & 0x0f )      )		/* on paragraph boundary */
+ 	     && (256 > ( *((u_int32_t *) (rp+0x0c)) - ((u_int32_t)rp & 0x0fffff)  ))
+ 									/* point to someplace near rp */
+ 	   )
+ 	      return 1;
+ 	 else return 0;
+ }
+ 
+ int
+ count_all_resources(caddr_t rombase, u_int32_t romlen)
+ {
+ 	caddr_t romptr;
+ 	u_int32_t nr_of_rsrcs = 0; 
+ 
+ 	for (romptr = rombase + romlen; romptr >= rombase; romptr -= 0x10)
+ 	{
+ 	    if (is_resource(romptr))
+ 	    nr_of_rsrcs++;  
+ 	}
+ 	return nr_of_rsrcs;
+ }
+ 
+ void
+ w_build_resource_list(caddr_t rombase, u_int32_t romlen)
+ {
+ 	caddr_t romptr;
+ 	u_int32_t rsrc_no = 0;
+ #ifdef MRG_DEBUG
+ 	char rsrc_name[5];
+ 
+ 	printf("mrg: Resources found:\n");
+ #endif
+ 	nr_of_rsrcs = count_all_resources(rombase, romlen);
+ 	if(0 == (rsrc_header = (caddr_t *) malloc(nr_of_rsrcs * sizeof(caddr_t), M_TEMP, M_NOWAIT)))
+ 	    panic("mrg: Can't malloc memory for rsrc_header list\n");
+ 	if(0 == (rsrc_handle = (caddr_t *) malloc(nr_of_rsrcs * sizeof(caddr_t), M_TEMP, M_NOWAIT)))
+ 	    panic("mrg: Can't malloc memory for rsrc_handle list\n");
+ 
+ 	for (romptr = rombase + romlen; romptr >= rombase; romptr -= 0x10)
+ 	{
+ 	    if (is_resource(romptr))
+ 		if (rsrc_no < nr_of_rsrcs)
+ 		{
+ 		    rsrc_header[rsrc_no] = romptr;
+ 		    rsrc_handle[rsrc_no] = (caddr_t) (ROMBase + *((u_int32_t *)(romptr + 0x0c)));
+ 		    rsrc_no++;
+ #ifdef MRG_DEBUG
+ 		    strncpy(rsrc_name, (char *) (romptr + 0x10), 4);
+ 		    rsrc_name[4] = '\0';
+ 		    printf("%4s 0x%2x   ", rsrc_name, *((u_int16_t *) (romptr + 0x14)) );
+ #endif
+ 		}  
+ 	}
+ #ifdef MRG_DEBUG  
+ 	printf("\n");
+ #endif
+ }
+ 
+ int
+ w_count_resources(u_int32_t rsrc_type)
+ {
+ 	u_int32_t rsrc_no = 0;
+ 	u_int32_t rsrc_count = 0;
+   
+ #ifdef MRG_DEBUG
+ 	char rsrc_name[5];
+ 
+ 	strncpy(rsrc_name, (char *) (&rsrc_type), 4);
+ 	rsrc_name[4] = '\0';
+ 	printf("mrg: w_count_resources called for resource %4s :  ", rsrc_name);
+ #endif
+ 	while (rsrc_no < nr_of_rsrcs)
+ 	{
+ 	    if (rsrc_type == *((u_int32_t *) (rsrc_header[rsrc_no] + 0x10)) )
+ 	    rsrc_count++;
+ 	    rsrc_no++;
+ 	}
+ #ifdef MRG_DEBUG
+ 	printf("found %d resources of requested type!\n", rsrc_count);
+ #endif
+ 	return rsrc_count;
+ }
+ 
+ caddr_t *
+ w_get_ind_resource(u_int32_t rsrc_type, u_int16_t rsrc_ind)
+ {
+ 	u_int32_t rsrc_no = 0;
+ 
+ #ifdef MRG_DEBUG
+ 	char rsrc_name[5];
+ 
+ 	strncpy(rsrc_name, (char *) (&rsrc_type), 4);
+ 	rsrc_name[4] = '\0';
+ 	printf("mrg: w_get_int_resource called for resource %4s, no. %d :  ", rsrc_name, rsrc_ind);
+ #endif
+ 
+ 	while (rsrc_ind > 0)
+ 	{
+ 	    while (    (rsrc_no < nr_of_rsrcs)
+ 		    && (rsrc_type != *((u_int32_t *) (rsrc_header[rsrc_no] + 0x10)) )
+ 		  )
+ 	    {
+ 		rsrc_no++;
+ 	    }
+ 	    rsrc_ind--;
+ 	    rsrc_no++;
+ 	}
+ 	rsrc_no--;
+ 	if (rsrc_no == nr_of_rsrcs)
+ 	{ /* Error */
+ #ifdef MRG_DEBUG
+ 	    printf("not found!\n");
+ #endif
+ 	    return (caddr_t *) 0;
+ 	}
+ 	else
+ 	{
+ #ifdef MRG_DEBUG
+ 	    printf("found at addr 0x%x -> 0x%x\n", &rsrc_handle[rsrc_no], rsrc_handle[rsrc_no]);
+ #endif
+ 	    return (caddr_t *) &rsrc_handle[rsrc_no];
+ 	}
+ }
+ 
+ 
+ void
+ mrg_VBLQueue()
+ {
+ #define qLink 0
+ #define qType 4
+ #define vblAddr 6
+ #define vblCount 10
+ #define vblPhase 12
+ 
+ 	caddr_t vbltask;
+ 	caddr_t last_vbltask;
+ 	
+ 	last_vbltask = (caddr_t) &VBLQueue_head;
+ 	vbltask = VBLQueue_head;
+ 	while (0 != vbltask)
+ 	{
+ 	    if ( 0 != *((u_int16_t *)(vbltask + vblPhase)) )
+ 	    {
+ 		*((u_int16_t *)(vbltask + vblPhase)) -= 1;
+ 	    } else
+ 	    {
+ 		if ( 0 != *((u_int16_t *)(vbltask + vblCount)) )
+ 		{
+ 		    *((u_int16_t *)(vbltask + vblCount)) -= 1;
+ 		} else
+ 		{
+ #if defined(MRG_DEBUG)
+ 		    printf("mrg: mrg_VBLQueue: calling VBL task at 0x%x with VBLTask block at 0x%x\n",
+ 			   *((u_int32_t *)(vbltask + vblAddr)), vbltask);
+ #endif	      
+ 		    asm("   movml	#0xfffe, sp@-   /* better save all registers! */
+ 			    movl	%0, a0
+ 			    movl	%1, a1
+ 			    jbsr	a1@
+ 			    movml	sp@+, #0x7fff"	/* better restore all registers! */
+ 			    :
+ 			    : "g" (vbltask), "g" (*((caddr_t)(vbltask + vblAddr))));
+ #if defined(MRG_DEBUG)
+ 		    printf("mrg: mrg_VBLQueue: back from VBL task\n");
+ #endif	      
+ 		    if ( 0 == *((u_int16_t *)(vbltask + vblCount)) )
+ 		    {
+ #if defined(MRG_DEBUG)
+ 			printf("mrg: mrg_VBLQueue: removing VBLTask block at 0x%x\n",
+ 			       vbltask);
+ #endif	      
+ 			*((u_int32_t *)(last_vbltask + qLink)) = *((u_int32_t *)(vbltask + qLink));
+ 			    /* can't free memory from VBLTask block as
+ 		             * we don't know where it came from */
+ 			if (vbltask == VBLQueue_tail)
+ 			{ /* last task of do{}while */
+ 			    VBLQueue_tail = last_vbltask;
+ 			}
+ 		    }
+ 		}
+ 	    }
+ 	    last_vbltask = vbltask;
+ 	    vbltask = (caddr_t) *((u_int32_t *)(vbltask + qLink));
+ 	} /* while */
+ }
+ 
+ 
+ void
+ mrg_init_stub_1()
+ {
+   	asm("movml #0xffff, sp@-");
+ 	printf("mrg: hit mrg_init_stub_1\n");
+   	asm("movml sp@+, #0xffff");
+ }
+ 
+ void
+ mrg_init_stub_2()
+ {
+ 	panic("mrg: hit mrg_init_stub_2\n");
+ }
+ 
  void
  mrg_1sec_timer_tick()
  {	
***************
*** 229,234 ****
--- 472,478 ----
  #endif
  		*(u_int32_t *)ptr = numbytes;
  		ptr += 4;
+ 		bzero(ptr, numbytes); /* NewPtr, Clear ! */
  	}
  
  	asm("	movl	%0, a0" :  : "g" (ptr));
***************
*** 298,303 ****
--- 542,552 ----
  	return 0;
  }
  
+ void
+ mrg_StripAddress()
+ {
+ }
+ 
  /*
   * trap jump address tables (different per machine?)
   * Can I just use the tables stored in the ROMs?
***************
*** 313,318 ****
--- 562,570 ----
  		(caddr_t)mrg_SetPtrSize,
  		(caddr_t)mrg_GetPtrSize,
  	[0x2f]	(caddr_t)mrg_PostEvent,
+ 	[0x3b]	(caddr_t)mrg_Delay,	
+ 	[0x47]	(caddr_t)mrg_SetOSTrapAddress,
+ 	[0x55]	(caddr_t)mrg_StripAddress,
  	[0x77]	(caddr_t)0x40807778,	/* CountADBs */
  		(caddr_t)0x40807792,	/* GetIndADB */
  		(caddr_t)0x408077be,	/* GetADBInfo */
***************
*** 327,336 ****
--- 579,613 ----
  };
  
  caddr_t mrg_ToolBoxtraps[1024] = {
+ 	[0x19c] (caddr_t)mrg_CountResources,
+ 	[0x19d] (caddr_t)mrg_GetIndResource,
  	[0x1a0] (caddr_t)mrg_GetResource,
  	[0x1af] (caddr_t)mrg_ResError,
  };
  
+ int
+ mrg_SetOSTrapAddress()
+ {
+ 	int result = noErr;
+ 	u_int trapnumber;
+ 	u_int trapaddress;
+ 	u_int32_t trapword;
+ 
+ 	asm("	movl	d1, %0
+ 		movl	d0, %1
+ 		movl	a0, %2"
+ 		: "=g" (trapword), "=g" (trapnumber), "=g" (trapaddress));
+ 
+ #if defined(MRG_SHOWTRAPS)
+ 	printf("mrg: SetOSTrapAddress(Trap: 0x%x, Address: 0x%8x)", trapnumber,
+ 		trapaddress);
+ #endif
+ 
+ 	mrg_OStraps[trapnumber] = (caddr_t) trapaddress;	
+ 
+ 	return(result);
+ }
+ 
  /*
   * Handle a supervisor mode A-line trap.
   */
***************
*** 377,382 ****
--- 654,661 ----
  	trapaddr = mrg_OStraps[trapnum];
  #if defined(MRG_DEBUG)
  	printf(" addr 0x%x\n", trapaddr);
+  	printf("    got:    d0 = 0x%8x,  a0 = 0x%8x, called from: 0x%8x\n",
+ 		frame->f_regs[0], frame->f_regs[8], frame->f_pc	);
  #endif
  	if(trapaddr == NULL){
  		printf("unknown %s trap 0x%x, no trap address available\n",
***************
*** 422,427 ****
--- 701,708 ----
  	troff();
  #endif
  #if defined(MRG_DEBUG)
+ 	printf("    result: d0 = 0x%8x,  a0 = 0x%8x\n",
+ 		d0bucket, a0bucket );
   	printf(" bk");
  #endif
  
***************
*** 521,526 ****
--- 802,811 ----
  		printf("Can't read RTC without it. Using MacOS boot time.\n");
  	}
  
+ 	mrg_ToolBoxtraps[0x04d] = rom->FixDiv;
+ 	mrg_ToolBoxtraps[0x068] = rom->FixMul;
+ 
+ 
  #if defined(MRG_DEBUG)
  	printf("mrg: ROM adbintr 0x%08x\n", mrg_romadbintr);
  	printf("mrg: ROM pmintr 0x%08x\n", mrg_rompmintr);
***************
*** 556,562 ****
  	caddr_t *handle;
  	int sizeptr;
  	extern short mrg_ResErr;
! 
  	if(mrg_romready()){
  		printf("mrg: '%s' rom glue", mrg_romident);
  
--- 841,853 ----
  	caddr_t *handle;
  	int sizeptr;
  	extern short mrg_ResErr;
! 	
! 	w_build_resource_list(ROMBase, 0x00100000);	/* search one MB */
! 	
! 	VBLQueue = (u_int16_t) 0;	/* No vertical blanking routines in the queue */
! 	VBLQueue_head = (caddr_t) 0;	/*  Let's hope that this init happens
! 	VBLQueue_tail = (caddr_t) 0;	 *  before the RTC interrupts are enabled */
! 					 
  	if(mrg_romready()){
  		printf("mrg: '%s' rom glue", mrg_romident);
  
***************
*** 592,597 ****
--- 883,901 ----
  	printf("mrg: start init\n");
  #endif
  		/* expected globals */
+ 	ExpandMem = &mrg_ExpandMem[0];
+ 	*((u_int16_t *)(mrg_ExpandMem + 0x00) ) = 0x0123;	/* magic (word) */
+ 	*((u_int32_t *)(mrg_ExpandMem + 0x02) ) = 0x000001ea;	/* Length of table (long) */
+ 	*((u_int32_t *)(mrg_ExpandMem + 0x1e0)) = (u_int32_t) &mrg_adbstore4[0];
+ 
+ 	*((u_int32_t *)(mrg_adbstore4 + 0x8)) = (u_int32_t) mrg_init_stub_1;
+ 	*((u_int32_t *)(mrg_adbstore4 + 0xc)) = (u_int32_t) mrg_init_stub_2;
+ 	*((u_int32_t *)(mrg_adbstore4 + 0x4)) = (u_int32_t) &mrg_adbstore5[0];
+ 
+ 	*((u_int32_t *)(mrg_adbstore5 + 0x08)) = (u_int32_t) 0x00100000;
+ 	*((u_int32_t *)(mrg_adbstore5 + 0x0c)) = (u_int32_t) 0x00100000;
+ 	*((u_int32_t *)(mrg_adbstore5 + 0x16)) = (u_int32_t) 0x00480000;
+ 
  	ADBBase = &mrg_adbstore[0];
  	ADBState = &mrg_adbstore2[0];
  	ADBYMM = &mrg_adbstore3[0];
***************
*** 698,705 ****
  			movml	sp@+, a0-a2 "
  			:
  			: "g" (mrg_InitEgret), "g" (ADBState));
  	}
! 	else printf("Help ...  No vector for InitEgret!!");
  }
  
  void
--- 1002,1017 ----
  			movml	sp@+, a0-a2 "
  			:
  			: "g" (mrg_InitEgret), "g" (ADBState));
+ 		jEgret = (void (*)) mrg_OStraps[0x92]; /* may have been set in asm() */
  	}
! 	else printf("Help ...  No vector for InitEgret!!\n");
! 	
! 	printf("mrg: ADBIntrVector: 0x%8x,  mrg_ADBIntrVector: 0x%8x\n",
! 			(long) mrg_romadbintr,
! 			*((long *) 0x19a));
! 	printf("mrg: EgretOSTrap: 0x%8x\n",
! 			(long) mrg_OStraps[0x92]);
! 
  }
  
  void
***************
*** 734,740 ****
  	 * set it up.  If not, just enable the interrupts (only on
  	 * some machines, others are already on from ADBReInit?).
  	 */
! 	if ( (HwCfgFlags3 & 0x0e) == 0x06 ) {
  		if (mac68k_machine.do_graybars)
  			printf("mrg: setup_egret:\n");
  
--- 1046,1053 ----
  	 * set it up.  If not, just enable the interrupts (only on
  	 * some machines, others are already on from ADBReInit?).
  	 */
! 	if (   ((HwCfgFlags3 & 0x0e) == 0x06 )
! 	    || ((HwCfgFlags3 & 0x70) == 0x20 )) {
  		if (mac68k_machine.do_graybars)
  			printf("mrg: setup_egret:\n");
  
***************
*** 774,779 ****
--- 1087,1098 ----
  			temp = (u_int) mrg_OStraps[i];
  			temp = (temp - oldbase) + newbase;
  			mrg_OStraps[i] = (caddr_t) temp;
+ 		}
+ 	for (i=0 ; i<1024 ; i++)
+ 		if (IS_ROM_ADDR(mrg_ToolBoxtraps[i])) {
+ 			temp = (u_int) mrg_ToolBoxtraps[i];
+ 			temp = (temp - oldbase) + newbase;
+ 			mrg_ToolBoxtraps[i] = (caddr_t) temp;
  		}
  	p = (u_int32_t *) mrg_adbstore;
  	for (i=0 ; i<512/4 ; i++)
diff -c mac68k/mac68k/macromasm.s mac68k.vi/mac68k/macromasm.s
*** mac68k/mac68k/macromasm.s	Fri Feb  2 14:16:55 1996
--- mac68k.vi/mac68k/macromasm.s	Tue Feb 20 13:02:48 1996
***************
*** 98,103 ****
--- 98,108 ----
  	loglob(jClkNoMem, 0x54c)	/* Pointer to ClkNoMem function */
  	loglob(PramTransfer, 0x1e4)	/* Transfer buffer used with PRam */
  	loglob(SysParam, 0x1f8) 	/* Place where PRam data gets stored */
+ 	loglob(ExpandMem, 0x2b6)	/* pointer to Expanded Memory used by */
+ 					/*   newer ADB routines */
+ 	loglob(VBLQueue, 0x160)		/* Vertical blanking Queue, unused ? */
+ 	loglob(VBLQueue_head, 0x162)	/* Vertical blanking Queue, head */
+ 	loglob(VBLQueue_tail, 0x166)	/* Vertical blanking Queue, tail */
  
  
  #if 0
***************
*** 125,130 ****
--- 130,145 ----
   * to the ROMs; none of this is called. 
   */
  
+ /* Initialize Utils, mainly XPRam */
+ 	.global _InitUtil
+ 	/*
+ 	 * void
+ 	 */
+ _InitUtil:
+ 	.word 0xa03f
+ 	rts
+ 
+ 
  /* Initialize the ADB ------------------------------------------------------*/
  	.global _ADBReInit
  	/*
***************
*** 339,344 ****
--- 354,396 ----
  	movl	#-192, d0		| resNotFound; that's pretty accurate.
  	movw	d0, _mrg_ResErr 	| set current ResMan error
  	pascalret(6)			| I hate Pascal.
+ 
+ 
+ 
+ 	function(mrg_CountResources)
+ 	/* WRU: 960120
+ 	 * sp@(4)	u_int32_t  rsrc_type
+ 	 * sp@(8)	u_int16_t  nr_of_rsrcs
+ 	 */
+ 	movl 	sp@(4), d0
+   	movl	d0, sp@-
+ 	jbsr	_w_count_resources
+ 	addl	#4, sp			/* pop C params */
+ 	movw	d0, sp@(8)		/* store result */
+ 	movl	sp@+, a0		/* get PC 	*/
+ 	addl	#4, sp			/* pop params	*/
+ 	jra	a0@			/* return	*/
+ 
+ 
+ 
+ 	function(mrg_GetIndResource)
+ 	/* WRU: 960120
+ 	 * sp@(4)	u_int16_t  rsrc_index
+ 	 * sp@(6)	u_int32_t  rsrc_type
+ 	 * sp@(10)	caddr_t   *rsrc_handle
+ 	 */
+ 	movl	sp@(6), a0
+ 	clrl	d0
+ 	movw	sp@(4), d0
+   	movl	d0, sp@-
+ 	movl	a0, sp@-
+ 	jbsr	_w_get_ind_resource
+ 	addl	#8, sp			/* pop C params */
+ 	movl	d0, sp@(10)		/* store result */
+ 	movl	sp@+, a0		/* get PC 	*/
+ 	addl	#6, sp			/* pop params	*/
+ 	jra	a0@			/* return	*/
+ 
  
  /*
   * I'd like to take a moment here to talk about the calling convention
diff -c mac68k/mac68k/locore.s mac68k.vi/mac68k/locore.s
*** mac68k/mac68k/locore.s	Sun Feb 11 13:23:51 1996
--- mac68k.vi/mac68k/locore.s	Tue Feb 20 21:16:29 1996
***************
*** 553,558 ****
--- 553,559 ----
   */
  /* BARF We must re-configure this. */
  	.globl	_hardclock, _nmihand
+ 	.globl	_mrg_VBLQueue
  
  _spurintr:
  _lev3intr:
***************
*** 612,617 ****
--- 613,619 ----
  	movl	sp, sp@-		| push pointer to ps, pc
  	jbsr	_hardclock		| call generic clock int routine
  	lea	sp@(12), sp		| pop params
+ 	jbsr	_mrg_VBLQueue		| give programs in the VBLqueue a chance
  	addql	#1,_intrcnt+20		| add another system clock interrupt
  
  	addql	#1,_cnt+V_INTR		| chalk up another interrupt
diff -c mac68k/mac68k/autoconf.c mac68k.vi/mac68k/autoconf.c
*** mac68k/mac68k/autoconf.c	Sun Feb  4 14:01:51 1996
--- mac68k.vi/mac68k/autoconf.c	Tue Feb 20 13:13:22 1996
***************
*** 134,142 ****
  
  	mrg_init();		/* Init Mac ROM Glue */
  
  	adb_init();		/* ADB device subsystem & driver */
  
! 	startrtclock();
  
  	if (config_rootfound("mainbus", "mainbus") == 0)
  		panic("No main device!");
--- 134,144 ----
  
  	mrg_init();		/* Init Mac ROM Glue */
  
+ 	startrtclock();		/* swapped with adb_init (WRU) */
+ 	
  	adb_init();		/* ADB device subsystem & driver */
  
!      /*	startrtclock(); 	   swapped with adb_init (WRU) */
  
  	if (config_rootfound("mainbus", "mainbus") == 0)
  		panic("No main device!");
>Audit-Trail:
>Unformatted: