2 copyright © 1995-2010, the aros development team. all rights reserved.
5 desc: m68k-amiga bootstrap to exec.
9 #include <aros/kernel.h>
10 #include <exec/resident.h>
11 #include <exec/execbase.h>
12 #include <exec/memory.h>
14 #include "exec_intern.h"
16 #include "m68k_exception.h"
18 /* Here's how it's all laid out on the Amiga
21 * 1 Reset: Initial PC (NOTE: Really is SysBase!)
24 * 4 Illegal Instruction
28 * 8 Privileged Instruction
30 * 10 Line 1010 Emulator
31 * 11 Line 1111 Emulator
35 * 15 Uninitilaized Interrupt Vector
39 * 24 Spurious Interrupt
40 * 25 Level 1 Interrupt
42 * Paula 1: Disk DMA done
43 * Paula 2: Software Int
44 * 26 Level 2 Interrupt
46 * 27 Level 3 Interrupt
50 * 28 Level 4 Interrupt
55 * 29 Level 5 Interrupt
58 * 30 Level 6 Interrupt
60 * Paula 14: Copper (special)
61 * 31 Level 7 Interrupt
74 /* The stack frame here:
75 * Return PC +(0 + 2 + 4)
77 * Exception struct * +(0)
80 * When we call M68KExceptionAction:
81 * D0-D1/A0-A1/A6 (5 * 4) <= NO TOUCHING!
84 * Exception struct * (4) D0
87 * Drop SysBase, SP, and Exception args
88 * Restore D0-D1/A0-A1/A6
89 * Drop the Exception # word
92 extern void M68KExceptionHelper(void);
95 " .globl M68KExceptionHelper\n"
96 "M68KExceptionHelper:\n"
97 " movem.l %d0-%d1/%a0-%a1/%a6,%sp@-\n" // What we destory
98 " move.l %sp@(5*4),%d0\n" // Exception *
100 " move.w %sp@(5*4+4),%d1\n" // SR
101 " move.l 4, %a6\n" // Global SysBase
102 " move.l %a6, %sp@-\n" // Push SysBase
103 " move.l %d1, %sp@-\n" // Push SR
104 " move.l %d0, %sp@-\n" // Push Exception *
105 " jsr M68KExceptionAction\n"
106 " lea %sp@(12),%sp\n" // Drop all stack args
107 " movem.l %sp@+,%d0-%d1/%a0-%a1/%a6\n" // Restore
108 " addq.l #4, %sp\n" // Remove Exception *
109 " rte\n" // And return
114 void M68KExceptionAction(struct M68KException
*Exception
, UWORD SRReg
, struct ExecBase
*SysBase
)
116 if (Exception
->Handler
== NULL
) {
117 kprintf("-- Exception %d\n", Exception
->Id
);
118 Alert(AN_BogusExcpt
);
122 Exception
->Handler(Exception
->Id
, SRReg
, SysBase
);
125 /* We assume that the caller has already set up
126 * the exceptions to a 'reasonable' default. These
127 * are only the overrides for AROS.
129 void M68KExceptionInit(const struct M68KException
*Table
, struct ExecBase
*SysBase
)
131 IPTR
*exception
= (IPTR
*)0; /* Exception base is at 0 */
136 for (size
= 0; Table
[size
].Id
> 0; size
++);
138 /* A little explanation. jmptab will be
139 * constructed as follows:
140 * move.l &Table[i], %sp@+
141 * 0x2f3c (&Table[i] >> 16) (&Table[i] & 0xffff)
142 * jmp %pc@(((size - 1) - i) * (5 * sizeof(UWORD)) + 2)
143 * 0x4efa (((size - 1) - i) * (5 * sizeof(UWORD)) + 2)
146 * jmp M68KExceptionHelper
147 * 0x4ef9 (M68KExceptionHelper >> 16) (M68KExceptionHelper & 0xffff)
149 * NOTICE: jmptab will never be freed! */
150 jmptab
= AllocMem(size
* (5 * sizeof(UWORD
)) + 3 * sizeof(UWORD
), 0);
152 for (i
= 0; i
< size
; i
++, jmptab
+= 5) {
153 jmptab
[0] = 0x2f3c; // movel #...,%sp@-
154 jmptab
[1] = ((IPTR
)(&Table
[i
]) >> 16) & 0xffff;
155 jmptab
[2] = ((IPTR
)(&Table
[i
]) >> 0) & 0xffff;
156 jmptab
[3] = 0x4efa; // jmp %pc@...
157 jmptab
[4] = ((size
- 1) - i
) * (5 * sizeof(UWORD
)) + 2;
158 exception
[Table
[i
].Id
] = (IPTR
)(&jmptab
[0]);
160 jmptab
[0] = 0x4ef9; // jmp ....
161 jmptab
[1] = ((IPTR
)(M68KExceptionHelper
) >> 16) & 0xffff;
162 jmptab
[2] = ((IPTR
)(M68KExceptionHelper
) >> 0) & 0xffff;
164 /* We're all set up now! */