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