xref: /netbsd/sys/arch/mac68k/mac68k/macromasm.s (revision c4a72b64)
1/*	$NetBSD: macromasm.s,v 1.20 2002/05/30 22:04:55 thorpej 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 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by Bradley A. Grantham.
18 * 4. The name of the author may not be used to endorse or promote products
19 *    derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Mac ROM Glue assembly
35 */
36
37
38#include "opt_adb.h"
39#include "assym.h"
40#include <machine/asm.h>
41#include <machine/trap.h>
42
43
44	/* Define this symbol as global with (v) value */
45#define loglob(g, v)	\
46	.global _C_LABEL(g) ;\
47	.set	_C_LABEL(g), v
48
49	/* Return from a pascal function; pop (pbytes) number of bytes */
50	/*  passed as parameters.  Should have picked up "pascal" extension */
51	/*  to GCC... */
52#ifdef __STDC__
53#define	IMMEDIATE	#
54#define pascalret(pbytes)	\
55	movl	%sp@+,%a1		/* get PC (I hate Pascal) */ ; \
56	addl	IMMEDIATE pbytes,%sp	/* pop params (I hate Pascal) */ ; \
57	jra	%a1@			/* return (I hate Pascal) */
58#else
59#define pascalret(pbytes)	\
60	movl	%sp@+,%a1		/* get PC (I hate Pascal) */ ; \
61	addl	#pbytes,%sp		/* pop params (I hate Pascal) */ ; \
62	jra	%a1@			/* return (I hate Pascal) */
63#endif
64
65
66/*
67 * MacOS low-memory global variables.
68 */
69	loglob(ADBBase, 0xcf8)		/* ptr to ADB driver variables */
70	loglob(ADBYMM, 0xd18)		/* Yet more memory used by ADB/PM */
71	loglob(ADBDelay, 0xcea) 	/* 8s of dbras per ADB delay */
72	loglob(ROMBase, 0x2ae)		/* ptr to ROM Base */
73	loglob(Lvl1DT, 0x192)		/* VIA 1 interrupt table */
74	loglob(Lvl2DT, 0x1b2)		/* VIA 2 interrupt table? */
75	loglob(JADBProc, 0x6b8) 	/* ADBReinit pre/post-processing */
76	loglob(jADBOp, 0x5f0)		/* pointer to ADBOp */
77	loglob(DeviceList, 0x8a8)	/* ptr to first device entry */
78	loglob(KbdLast, 0x218)		/* ptr to first device entry */
79	loglob(KbdType, 0x21E)		/* ptr to first device entry */
80	loglob(JKybdTask, 0x21A)	/* keyboard task jump ptr? */
81	loglob(Lo3Bytes, 0x31a) 	/* contains 0x00ffffff */
82	loglob(MinusOne, 0xa06) 	/* contains 0xffffffff */
83	loglob(MMU32Bit, 0xcb2) 	/* MMU mode (uh-oh) 1 = 32 bit? */
84	loglob(CPUFlag, 0x12f)		/* CPU type */
85	loglob(MacJmp, 0x120)		/* ?? */
86	loglob(Scratch8, 0x9fa) 	/* 8-byte scratch area */
87	loglob(Scratch20, 0x1e4)	/* 20-byte scratch area */
88	loglob(Ticks, 0x16a)		/* ticks since system startup */
89	loglob(Time, 0x20c)		/* Sec since midnight, 1-1-1904 */
90	loglob(TimeDBRA, 0xd00) 	/* dbra's per millisecond (short) */
91	loglob(ToolScratch, 0x9ce)	/* another 8-byte scratch area */
92	loglob(VIA, 0x1d4)		/* VIA1 base address */
93	loglob(mrg_VIA2, 0xcec) 	/* VIA2 base address */
94	loglob(SCCRd, 0x1d8)		/* SCC read base address */
95	loglob(FinderName, 0x2e0)	/* Name of finder */
96	loglob(jSwapMMU, 0xdbc) 	/* ptr to MMU swap routine */
97	loglob(ADBState, 0xde0) 	/* ptr to ADB state information? */
98	loglob(jUnimplTrap, 0x61c)	/* ptr to UnimplTrap routine */
99	loglob(jEgret, 0x648)		/* ptr to Egret trap routine */
100	loglob(HwCfgFlags, 0xb22)	/* 2 bytes, h/w config flags */
101	loglob(HwCfgFlags2, 0xdd0)	/* 4 bytes, more h/w config flags */
102	loglob(HwCfgFlags3, 0xdd4)	/* 4 bytes, more h/w config flags */
103	loglob(ADBReInit_JTBL, 0xdd8)	/* 4 bytes, pointer to patch table */
104	loglob(jClkNoMem, 0x54c)	/* Pointer to ClkNoMem function */
105	loglob(PramTransfer, 0x1e4)	/* Transfer buffer used with PRam */
106	loglob(SysParam, 0x1f8) 	/* Place where PRam data gets stored */
107	loglob(ExpandMem, 0x2b6)	/* pointer to Expanded Memory used by */
108					/*   newer ADB routines */
109	loglob(VBLQueue, 0x160)		/* Vertical blanking Queue, unused ? */
110	loglob(VBLQueue_head, 0x162)	/* Vertical blanking Queue, head */
111	loglob(VBLQueue_tail, 0x166)	/* Vertical blanking Queue, tail */
112	loglob(jDTInstall, 0xd9c)	/* Deferred task mgr trap handler */
113
114	loglob(InitEgretJTVec, 0x2010)	/* pointer to a jump table for */
115					/* InitEgret on AV machines */
116
117#if 0
118	/* I wish I knew what these things were */
119	loglob(MMUFlags, 0xcb0)
120	loglob(MMUFluff, 0xcb3)
121	loglob(MMUTbl, 0xcb4)
122	loglob(MMUTblSize, 0xcb8)
123	loglob(MMUType, 0xcb1)
124#endif
125
126	.text
127	.even
128	.global _C_LABEL(panic)
129	.global _C_LABEL(printf)
130
131#ifdef MRG_ADB
132/*
133 * These functions are defined in adb_direct.c if we are not using
134 * the MRG method of accessing the ADB/PRAM/RTC.
135 */
136/*
137 * Most of the following glue just takes C function calls, converts
138 * the parameters to the MacOS Trap parameters, and then tries to
139 * return the result correctly.  About the only thing our C functions
140 * and MacOS' traps have in common is returning numerical results in
141 * %d0.
142 *
143 * If some code actually pulls down the a-trap line, we jump right
144 * to the ROMs; none of this is called.
145 */
146
147/* Initialize Utils, mainly XPRam */
148	/*
149	 * void
150	 */
151ENTRY(InitUtil)
152	.word 0xa03f
153	rts
154
155
156/* Initialize the ADB ------------------------------------------------------*/
157	/*
158	 * void
159	 */
160ENTRY(ADBReInit)
161	.word	0xa07b
162	rts
163
164
165/* Set the ADB device info for a device; routine handler and so on ---------*/
166	/*
167	 * %sp@(4)	ADBSetInfoBlock *info
168	 * %sp@(8)	int		adbAddr
169	 */
170ENTRY(SetADBInfo)
171	movl	%sp@(4),%a0
172	movl	%sp@(8),%d0
173	.word	0xa07a
174	rts
175
176
177/* Find the number of ADB devices in the device table ----------------------*/
178	/*
179	 * void
180	 */
181ENTRY(CountADBs)
182	.word 0xa077
183	rts
184
185
186/* Get ADB entry from index in table ---------------------------------------*/
187	/*
188	 * sp@(4)	ADBDataBlock	*info
189	 * sp@(8)	u_short 	devTableIndex
190	 */
191ENTRY(GetIndADB)
192	movl	%sp@(4),%a0
193	movl	%sp@(8),%d0
194	.word 0xa078
195	rts
196
197
198/* Get ADB device information ----------------------------------------------*/
199	/*
200	 * sp@(4)	ADBSetInfoBlock *info
201	 * sp@(8)	int		adbAddr
202	 */
203ENTRY(GetADBInfo)
204	movl	%sp@(4),%a0
205	movl	%sp@(8),%d0
206	.word 0xa079
207	rts
208
209
210/* Perform an ADB transaction ----------------------------------------------*/
211	/*
212	 * sp@(4)	Ptr	buffer
213	 * sp@(8)	Ptr	compRout
214	 * sp@(12)	Ptr	data
215	 * sp@(16)	short	commandNum
216	 */
217ENTRY(ADBOp)
218	lea	%sp@(4),%a0
219	movl	%sp@(16),%d0
220	.word 0xa07c
221	rts
222#endif /* MRG_ADB */
223
224
225#if 0
226/* My Own Trap (for testing.  returns 50.) ---------------------------------*/
227	.global _MyOwnTrap
228_MyOwnTrap:
229	.word	0xa000
230	rts
231
232
233/* Known RTS (for testing) -------------------------------------------------*/
234	.global _KnownRTS
235_KnownRTS:
236	.word	0xa001
237	rts
238#endif
239
240
241/* Allocate memory ---------------------------------------------------------*/
242ENTRY(NewPtr)
243	/*
244	 * int size
245	 */
246	movl	%sp@(4),%d0
247	.word	0xa71e		/* clear and sys */
248	rts
249
250
251/* Free memory -------------------------------------------------------------*/
252ENTRY(DisposPtr)
253	/*
254	 * Ptr ptr
255	 */
256	movl	%sp@(4),%a0
257	.word	0xa01f
258	rts
259
260
261/* Get size of allocated memory --------------------------------------------*/
262ENTRY(GetPtrSize)
263	/*
264	 * Ptr ptr
265	 */
266	movl	%sp@(4),%a0
267	.word	0xa021
268	rts
269
270
271/* Extend allocated memory -------------------------------------------------*/
272ENTRY(SetPtrSize)
273	/*
274	 * Ptr ptr
275	 * int bytesdiff
276	 */
277	movl	%sp@(4),%a0
278	movl	%sp@(8),%d0
279	.word	0xa020
280	rts
281
282
283/* Resource manager */
284	.data
285GLOBAL(mrg_ResErr)
286	.word	0
287
288	.text
289/* Return the current Resource Manager Error -------------------------------*/
290ENTRY(ResError)
291	/*
292	 * void
293	 */
294	movl	%d2,%sp@-		| Toolbox trap may alter %d0-%d2,%a0,%a1
295					| but C caller would save %d1,%a0,%a1
296	clrw	%sp@-			| space for return arg (ugh)
297	.word	0xa9af			| ResError
298	movw	%sp@+,%d0
299	movl	%sp@+,%d2		| restore %d2
300	rts
301
302ENTRY(mrg_ResError)
303	/*
304	 * %sp@(4)	:short
305	 */
306#if defined(MRG_SHOWTRAPS)
307		movml	#0xc0c0,%sp@-
308		pea	LRE_enter
309		jbsr	_C_LABEL(printf)
310		addql	#4,%sp
311		movml	%sp@+,#0x0303
312#endif
313	movw	_C_LABEL(mrg_ResErr),%sp@(4)
314	| movw	%d0,%sp@(4)
315	pascalret(0)
316
317LRE_enter:
318	.asciz	"mrg: ResError()\n"
319	.even
320
321/* Find a resource in open resource files ----------------------------------*/
322ENTRY(GetResource)
323	/*
324	 * sp@(4)	u_int theType
325	 * sp@(8)	short theID
326	 */
327	movl	%sp@(8),%a1
328	movl	%sp@(4),%a0
329	movl	%d2,%sp@-		| Toolbox trap may alter %d0-%d2,%a0,%a1
330					| but C caller would save %d1,%a0,%a1
331	clrl	%sp@-			| space for :Handle
332	movl	%a0,%sp@-
333	movw	%a1,%sp@-		| pascal parameters upside down
334	.word	0xa9a0			| GetResource
335	movl	%sp@+,%d0		| return Handle
336	movl	%sp@+,%d2		| restore registers
337	rts
338
339ENTRY(mrg_GetResource)
340	/*
341	 * sp@(10)	:Handle
342	 * sp@(6)	u_int	theType
343	 * sp@(4)	short	theID
344	 */
345	/* For now, we return NIL, because, well, we have no resources. */
346#if defined(MRG_SHOWTRAPS)
347		movml	#0xc0c0,%sp@-
348		movw	%sp@(20),%d0
349		movl	%sp@(22),%d1
350		movl	%d0,%sp@-
351		movl	%d1,%sp@-
352		pea	LGR_enter
353		jbsr	_C_LABEL(printf)
354		addl	#12,%sp
355		movml	%sp@+,#0x0303
356#endif
357	clrl	%d0			| okay to change %d0 ?
358	movl	%d0,%sp@(10)		| return value is NIL
359	movl	#-192,%d0		| resNotFound; that's pretty accurate.
360	movw	%d0,_C_LABEL(mrg_ResErr)| set current ResMan error
361	pascalret(6)			| I hate Pascal.
362
363
364
365ENTRY(mrg_CountResources)
366/* Original from WRU: 960120
367 * sp@(4)	u_int32_t  rsrc_type
368 * sp@(8)	u_int16_t  nr_of_rsrcs
369 */
370	movl 	%sp@(4),%d0
371  	movl	%d0,%sp@-
372	jbsr	_C_LABEL(Count_Resources)
373	addl	#4,%sp			| pop C params
374	movw	%d0,%sp@(8)		| store result
375	pascalret(4)
376
377ENTRY(mrg_GetIndResource)
378/* Original from WRU: 960120
379 * sp@(4)	u_int16_t  rsrc_index
380 * sp@(6)	u_int32_t  rsrc_type
381 * sp@(10)	caddr_t   *rsrc_handle
382 */
383	movl	%sp@(6),%a0
384	clrl	%d0
385	movw	%sp@(4),%d0
386  	movl	%d0,%sp@-
387	movl	%a0,%sp@-
388	jbsr	_C_LABEL(Get_Ind_Resource)
389	addl	#8,%sp		| pop C params
390	movl	%d0,%sp@(10)	| store result
391	pascalret(6)
392
393/*
394 * I'd like to take a moment here to talk about the calling convention
395 * for ToolBox routines.  Inside Mac "Operating System Utilities,"
396 * page 8-16, "About the Trap Manager," states that ToolBox routines
397 * may alter %D0-%D2 and %A0-%A1.  However, a crucial bit of code in
398 * ADBReInit on the Mac II, 0x40807834, does not save its own %D1 or %A1
399 * before calling GetResource.	Therefore, it is imperative that our
400 * MacBSD ToolBox trap handler save at least %D1, %D2, %A0, and %A1.  I
401 * believe that the system uses %D0 in most places to hold the function's
402 * return value, as in "movl	%sp@+,%d0", and so I don't think it's
403 * that necessary to save %d0 unless we find a specific case of ugliness.
404 *
405 * It surprises me during every moment that I deal with the Macintosh
406 * architecture how wonderful and ugly it really is.  I continue to find
407 * pieces of beautiful, elegant code, reduced to crap by another following
408 * piece of code which uses global offsets, doesn't save registers, and
409 * makes assumptions.  If only it was consistent, Mac ROMs would be a
410 * true example to programmers everywhere.  As it stands, it is an example
411 * of a different kind. 	-Brad Grantham, September 5th, 1994
412 */
413
414LGR_enter:
415	.asciz	"GetResource('0x%x', %d)\n"
416	.even
417
418
419/*
420 * 1010 line emulator; A-line trap
421 * (we fake MacOS traps from here)
422 */
423	.global _C_LABEL(mrg_aline_super)
424	.global _C_LABEL(mrg_ToolBoxtraps)
425ENTRY_NOPROFILE(alinetrap)
426	clrl	%sp@-		| pad %SR to longword (I still don't know
427				| why we do this.)
428	moveml	#0xffff,%sp@-	| save registers
429	movl	%sp,%sp@-	| save pointer to frame
430	movw	%sp@(FR_HW + 4),%d0	| retrieve status register
431	andw	#PSL_S,%d0	| supervisor state?
432	bne	Lalnosup	| branch if supervisor
433	addql	#4,%sp		| pop frame ptr
434	movql	#T_ILLINST,%d0	| user-mode fault
435	jra	_ASM_LABEL(fault)
436Lalnosup:
437#define FR_PC (FR_HW+2)
438	movl	%sp@(FR_PC + 4),%a0	| retrieve PC
439	movw	%a0@,%d0 	| retrieve trap word
440	btst	#11,%d0 	| ToolBox trap?
441	bne	Laltoolbox	| branch if ToolBox
442	jbsr	_C_LABEL(mrg_aline_super) | supervisor a-line trap
443Lalrts:
444	addql	#4,%sp		| pop frame ptr
445	movw	%sp@(FR_HW),%sr	| restore status register (I hate MacOS traps)
446	movl	%sp@(FR_PC),%a0	| move PC to correct location
447	movl	%a0,%sp@(FR_PC+2)
448	moveml	%sp@+,#0xffff	| restore registers (some of which may have
449				| been magically changed)
450	addql	#8,%sp		| pop alignment long, make stack look like
451				| ordinary jbsr
452	tstw	%d0		| Gotta do this because call might depend on it
453	rts			| Go home (God, this is ugly.)
454Laltoolbox:
455	addql	#4,%sp		| pop frame ptr
456#if defined(MRG_DEBUG)
457		movml	#0xC0C0,%sp@-	| better save
458		pea	LalP1
459		jbsr	_C_LABEL(printf)
460			| printf ("Toolbox trap\n");
461		lea	%sp@(4),%sp	| pop
462		movml	%sp@+,#0x0303	| restore
463#endif
464	movl	%a0,%a1		| save PC
465	movw	%sp@(FR_HW),%sr	| restore status register
466#if defined(MRG_DEBUG)
467		movml	#0xC0C0,%sp@-	| better save
468		movw	%sr,%sp@-
469		clrw	%sp@-		| coerce to int
470		pea	LalP2
471		jbsr	_C_LABEL(printf)
472			| printf ("Status register 0x%x\n", sr);
473		lea	%sp@(8),%sp	| pop
474		movml	%sp@+,#0x0303	| restore
475#endif
476	btst	#10,%d0 	| auto-pop the jump address?
477	beq	Lalnoauto	| branch if no auto-pop
478	pea	Lalautopanic	| I really don't know how to handle this
479	jbsr	_C_LABEL(panic)
480Lalnoauto:
481	addl	#2,%a1		| add 2 to PC
482#if defined(MRG_DEBUG)
483		movml	#0xC0C0,%sp@-	| better save
484		movl	%a1,%sp@-
485		pea	LalP4
486		jbsr	_C_LABEL(printf)
487			| printf ("return address is 0x%x\n", new pc);
488		lea	%sp@(8),%sp	| pop
489		movml	%sp@+,#0x0303	| restore
490#endif
491	movl	%a1,%sp@(FR_PC+2)	| push new return address
492	movl	%d0,%d1		| just in case of panic
493	andl	#0x3ff,%d0	| %d0 = trap number
494#if defined(MRG_DEBUG)
495		movml	#0xC0C0,%sp@-	| better save
496		movl	%d0,%sp@-
497		pea	LalP5
498		jbsr	_C_LABEL(printf)
499			| printf ("trap number is 0x%x\n", trapnum);
500		lea	%sp@(8),%sp	| pop
501		movml	%sp@+,#0x0303	| restore
502#endif
503	lsll	#2,%d0		| ptr = 4 bytes
504	lea	_C_LABEL(mrg_ToolBoxtraps),%a0
505	addl	%d0,%a0		| get trap address
506	movl	%a0@,%a0
507	bne	Laltbok 	| branch on trap addr non-zero
508	movl	%d1,%sp@+	| trap word
509	pea	Laltbnotrap
510	jbsr	_C_LABEL(printf)
511	pea	Laltbnogo
512	jbsr	_C_LABEL(panic)
513Laltbok:
514#if defined(MRG_DEBUG)
515		movml	#0xC0C0,%sp@-	| better save
516		movl	%a0,%sp@-
517		pea	LalP6
518		jbsr	_C_LABEL(printf)
519			| printf ("trap address is 0x%x\n", trapaddr);
520		lea	%sp@(8),%sp	| pop
521		movml	%sp@+,#0x0303	| restore
522#endif
523	movl	%a0,%sp@(FR_HW)	| we will RTS to trap routine (ick)
524	moveml	%sp@+,#0xffff	| restore registers
525	addql	#4,%sp		| pop alignment long
526	rts			| go for it
527
528Lalautopanic:
529	.asciz	"mrg: A-line ToolBox trap wanted auto-pop; I don't know how"
530Laltbnotrap:
531	.asciz	"mrg: Don't know how to handle this trap: 0x%x\n"
532Laltbnogo:
533	.asciz	"mrg: can't go on"
534LalP1:
535	.asciz	"mrg: TB!"
536LalP2:
537	.asciz	" sr 0x%x"
538LalP4:
539	.asciz	" ret 0x%x"
540LalP5:
541	.asciz	" #%d"
542LalP6:
543	.asciz	" addr 0x%x\n"
544	.even
545
546
547	.data
548
549GLOBAL(traceloopstart)
550	.space	20 * 4		| save last 20 program counters on trace trap
551GLOBAL(traceloopend)
552GLOBAL(traceloopptr)
553	.long	_C_LABEL(traceloopstart)
554
555	.text
556ENTRY_NOPROFILE(mrg_tracetrap)
557	movl	%d0,%sp@-		| save %d0
558	movl	%a0,%sp@-		| save %a0
559	movl	%sp@(0x10),%d0		| address of instruction
560		|%sp@	 old %a0
561		|%sp@(4) old %d0
562		|%sp@(8) old %sr
563		|%sp@(10) old %PC
564		|%sp@(14) exception vector
565		|%sp@(16) address of instruction
566#if defined(MRG_FOLLOW)
567		movml	#0xc0c0,%sp@-
568		movl	%d0,%sp@-
569		pea	Ltraceprint
570		jbsr	_C_LABEL(printf) | printf("PC is %x\n", pc);
571		addql	#8,%sp
572		movml	%sp@+,#0x0303
573		tstl	%d0
574#endif
575	beq	LPCiszero		| if PC goes to zero, freak!
576	movl	_C_LABEL(traceloopptr),%a0	| ptr = traceloopptr;
577	movl	%d0,%a0@+		| *ptr++ = PC;
578	cmpl	#_C_LABEL(traceloopend),%a0	| if(ptr == traceloopend)
579	bne	Lnotpast		|  {
580	movl	#_C_LABEL(traceloopstart),%a0	|   ptr = traceloopstart;
581Lnotpast:				|  }
582	movl	%a0,_C_LABEL(traceloopptr)	| traceloopptr = ptr;
583	movl	%sp@+,%a0		| restore %a0
584	movl	%sp@+,%d0		| restore %d0
585	rte				| everything cool, return.
586LPCiszero:
587	movl	%sp@+,%a0		| restore %a0
588	movl	%sp@+,%d0		| restore %d0
589	movml	#0xc0c0,%sp@-
590	pea	LtracePCzero
591	jbsr	_C_LABEL(panic)		| panic("PC is zero!", pc);
592	addql	#4,%sp
593	movml	%sp@+,#0x0303
594
595Ltraceprint:
596	.asciz	"tracing, pc at 0x%08x\n"
597LtracePCzero:
598	.asciz	"PC went to zero!\n"
599	.even
600