ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.7
Committed: 2000-10-17T12:24:58Z (24 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.6: +21 -43 lines
Log Message:
- FPU is now available under NetBSD/m68k
- main_unix.cpp: added more emulated privileged instructions

File Contents

# User Rev Content
1 cebix 1.1 *
2     * asm_support.asm - AmigaOS utility functions in assembly language
3     *
4     * Basilisk II (C) 1997-1999 Christian Bauer
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     *
20    
21     INCLUDE "exec/types.i"
22     INCLUDE "exec/macros.i"
23     INCLUDE "exec/memory.i"
24     INCLUDE "exec/tasks.i"
25     INCLUDE "dos/dos.i"
26     INCLUDE "devices/timer.i"
27    
28     XDEF _AtomicAnd
29     XDEF _AtomicOr
30     XDEF _MoveVBR
31     XDEF _Execute68k
32     XDEF _Execute68kTrap
33     XDEF _TrapHandlerAsm
34     XDEF _ExceptionHandlerAsm
35     XDEF _Scod060Patch1
36     XDEF _Scod060Patch2
37     XDEF _ThInitFPUPatch
38 jlachmann 1.5 XDEF _AsmTriggerNMI
39 cebix 1.1
40     XREF _OldTrapHandler
41     XREF _OldExceptionHandler
42     XREF _IllInstrHandler
43     XREF _PrivViolHandler
44     XREF _EmulatedSR
45     XREF _IRQSigMask
46     XREF _InterruptFlags
47     XREF _MainTask
48     XREF _SysBase
49 cebix 1.2 XREF _quit_emulator
50 cebix 1.1
51     SECTION text,CODE
52    
53     *
54     * Atomic bit operations (don't trust the compiler)
55     *
56    
57     _AtomicAnd move.l 4(sp),a0
58     move.l 8(sp),d0
59     and.l d0,(a0)
60     rts
61    
62     _AtomicOr move.l 4(sp),a0
63     move.l 8(sp),d0
64     or.l d0,(a0)
65     rts
66    
67     *
68     * Move VBR away from 0 if neccessary
69     *
70    
71     _MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp)
72     move.l _SysBase,a6
73    
74     lea getvbr,a5 ;VBR at 0?
75     JSRLIB Supervisor
76     tst.l d0
77     bne.s 1$
78    
79     move.l #$400,d0 ;Yes, allocate memory for new table
80     move.l #MEMF_PUBLIC,d1
81     JSRLIB AllocMem
82     tst.l d0
83     beq.s 1$
84    
85     JSRLIB Disable
86    
87     move.l d0,a5 ;Copy old table
88     move.l d0,a1
89     sub.l a0,a0
90     move.l #$400,d0
91     JSRLIB CopyMem
92     JSRLIB CacheClearU
93    
94     move.l a5,d0 ;Set VBR
95     lea setvbr,a5
96     JSRLIB Supervisor
97    
98     JSRLIB Enable
99    
100     1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6
101     rts
102    
103     getvbr movec vbr,d0
104     rte
105    
106     setvbr movec d0,vbr
107     rte
108    
109     *
110     * Execute 68k subroutine (must be ended with rts)
111     * r->a[7] and r->sr are unused!
112     *
113    
114     ; void Execute68k(uint32 addr, M68kRegisters *r);
115     _Execute68k
116     move.l 4(sp),d0 ;Get arguments
117     move.l 8(sp),a0
118    
119     movem.l d2-d7/a2-a6,-(sp) ;Save registers
120    
121     move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
122     pea 1$ ;Push return address on stack
123     move.l d0,-(sp) ;Push pointer to 68k routine on stack
124     movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
125    
126     rts ;Jump into 68k routine
127    
128     1$ move.l a6,-(sp) ;Save a6
129     move.l 4(sp),a6 ;Get pointer to M68kRegisters
130     movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
131     move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
132     addq.l #4,sp ;Remove pointer from stack
133    
134     movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
135     rts
136    
137     *
138     * Execute MacOS 68k trap
139     * r->a[7] and r->sr are unused!
140     *
141    
142     ; void Execute68kTrap(uint16 trap, M68kRegisters *r);
143     _Execute68kTrap
144     move.l 4(sp),d0 ;Get arguments
145     move.l 8(sp),a0
146    
147     movem.l d2-d7/a2-a6,-(sp) ;Save registers
148    
149     move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
150     move.w d0,-(sp) ;Push trap word on stack
151     subq.l #8,sp ;Create fake A-Line exception frame
152     movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
153    
154     move.l a2,-(sp) ;Save a2 and d2
155     move.l d2,-(sp)
156     lea 1$,a2 ;a2 points to return address
157     move.w 16(sp),d2 ;Load trap word into d2
158    
159     jmp ([$28.w],10) ;Jump into MacOS A-Line handler
160    
161     1$ move.l a6,-(sp) ;Save a6
162     move.l 6(sp),a6 ;Get pointer to M68kRegisters
163     movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
164     move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
165     addq.l #6,sp ;Remove pointer and trap word from stack
166    
167     movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
168     rts
169    
170     *
171     * Exception handler of main task (for 60Hz interrupts)
172     *
173    
174     _ExceptionHandlerAsm
175     move.l d0,-(sp) ;Save d0
176    
177     and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C?
178     bne.s 2$
179    
180     move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR?
181     and.w #$0700,d0
182     bne 1$
183     move.w #$0064,-(sp) ;Yes, fake interrupt stack frame
184     pea 1$
185     move.w _EmulatedSR,d0
186     move.w d0,-(sp)
187 cebix 1.6 or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode
188 cebix 1.1 move.w d0,_EmulatedSR
189 jlachmann 1.5 move.l $64.w,-(sp) ;Jump to MacOS interrupt handler
190     rts
191 cebix 1.1
192     1$ move.l (sp)+,d0 ;Restore d0
193     rts
194    
195     2$ JSRLIB Forbid ;Waiting for Dos signal?
196     sub.l a1,a1
197     JSRLIB FindTask
198     move.l d0,a0
199     move.l TC_SIGWAIT(a0),d0
200     move.l TC_SIGRECVD(a0),d1
201     JSRLIB Permit
202     btst #SIGB_DOS,d0
203     beq 3$
204     btst #SIGB_DOS,d1
205     bne 4$
206    
207     3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets
208     JSRLIB GetMsg
209    
210     move.w _EmulatedSR,d0
211     or.w #$0700,d0 ;Disable all interrupts
212     move.w d0,_EmulatedSR
213     moveq #0,d0 ;Disable all exception signals
214     moveq #-1,d1
215     JSRLIB SetExcept
216 cebix 1.2 jsr _quit_emulator ;CTRL-C, quit emulator
217 cebix 1.1 4$ move.l (sp)+,d0
218     rts
219    
220     *
221     * Process Manager 68060 FPU patches
222     *
223    
224     _Scod060Patch1 fsave -(sp) ;Save FPU state
225     tst.b 2(sp) ;Null?
226     beq.s 1$
227     fmovem.x fp0-fp7,-(sp) ;No, save FPU registers
228     fmove.l fpiar,-(sp)
229     fmove.l fpsr,-(sp)
230     fmove.l fpcr,-(sp)
231     pea -1 ;Push "FPU state saved" flag
232     1$ move.l d1,-(sp)
233     move.l d0,-(sp)
234     bsr.s 3$ ;Switch integer registers and stack
235     addq.l #8,sp
236     tst.b 2(sp) ;New FPU state null or "FPU state saved" flag set?
237     beq.s 2$
238     addq.l #4,sp ;Flag set, skip it
239     fmove.l (sp)+,fpcr ;Restore FPU registers and state
240     fmove.l (sp)+,fpsr
241     fmove.l (sp)+,fpiar
242     fmovem.x (sp)+,fp0-fp7
243     2$ frestore (sp)+
244     movem.l (sp)+,d0-d1
245     rts
246    
247     3$ move.l 4(sp),a0 ;Switch integer registers and stack
248     move sr,-(sp)
249     movem.l d2-d7/a2-a6,-(sp)
250     cmp.w #0,a0
251     beq.s 4$
252     move.l sp,(a0)
253     4$ move.l $36(sp),a0
254     movem.l (a0)+,d2-d7/a2-a6
255     move (a0)+,sr
256     move.l a0,sp
257     rts
258    
259     _Scod060Patch2 move.l d0,-(sp) ;Create 68060 null frame on stack
260     move.l d0,-(sp)
261     move.l d0,-(sp)
262     frestore (sp)+ ;and load it
263     rts
264    
265     *
266     * Thread Manager 68060 FPU patches
267     *
268    
269     _ThInitFPUPatch tst.b $40(a4)
270     bne.s 1$
271     moveq #0,d0 ;Create 68060 null frame on stack
272     move.l d0,-(a3)
273     move.l d0,-(a3)
274     move.l d0,-(a3)
275     1$ rts
276    
277     *
278     * Trap handler of main task
279     *
280    
281 jlachmann 1.5 _TrapHandlerAsm:
282     cmp.l #4,(sp) ;Illegal instruction?
283 cebix 1.1 beq.s doillinstr
284     cmp.l #10,(sp) ;A-Line exception?
285     beq.s doaline
286     cmp.l #8,(sp) ;Privilege violation?
287     beq.s doprivviol
288 jlachmann 1.5 cmp.l #9,(sp) ;Trace?
289     beq dotrace
290     cmp.l #3,(sp) ;Illegal Address?
291     beq.s doilladdr
292    
293     cmp.l #32,(sp)
294     blt 1$
295     cmp.l #47,(sp)
296     ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors
297    
298 cebix 1.7 1$ move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler
299 jlachmann 1.5 rts
300    
301     *
302     * TRAP #0 - 15 Instruction Vectors
303     *
304    
305 cebix 1.7 doTrapXX move.l a0,(sp) ;Save a0
306 jlachmann 1.5 move.l usp,a0 ;Get user stack pointer
307     move.l 2*4(sp),-(a0) ;Copy 4-word stack frame to user stack
308     move.l 1*4(sp),-(a0)
309     move.l a0,usp ;Update USP
310     move.l (sp)+,a0 ;Restore a0
311    
312     addq.l #4*2,sp ;Remove exception frame from supervisor stack
313     andi #$d8ff,sr ;Switch to user mode, enable interrupts
314 cebix 1.1
315 jlachmann 1.5 move.l $2d*4.w,-(sp) ;Jump to MacOS exception handler
316 cebix 1.1 rts
317    
318 jlachmann 1.5
319     *
320     * trace Vector
321     *
322    
323 cebix 1.7 dotrace move.l a0,(sp) ;Save a0
324 jlachmann 1.5
325     move.l usp,a0 ;Get user stack pointer
326     move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack
327     move.l 2*4(sp),-(a0)
328     move.l 1*4(sp),-(a0)
329     move.l a0,usp ;Update USP
330     move.l (sp)+,a0 ;Restore a0
331    
332     lea 6*2(sp),sp ;Remove exception frame from supervisor stack
333     andi #$18ff,sr ;Switch to user mode, enable interrupts, disable trace
334    
335     move.l $24.w,-(sp) ;Jump to MacOS exception handler
336     rts
337    
338    
339 cebix 1.1 *
340     * A-Line handler: call MacOS A-Line handler
341     *
342    
343     doaline move.l a0,(sp) ;Save a0
344     move.l usp,a0 ;Get user stack pointer
345     move.l 8(sp),-(a0) ;Copy stack frame to user stack
346     move.l 4(sp),-(a0)
347     move.l a0,usp ;Update USP
348     move.l (sp)+,a0 ;Restore a0
349    
350     addq.l #8,sp ;Remove exception frame from supervisor stack
351     andi #$d8ff,sr ;Switch to user mode, enable interrupts
352    
353     move.l $28.w,-(sp) ;Jump to MacOS exception handler
354     rts
355    
356 jlachmann 1.5 *
357     * Illegal address handler
358     *
359    
360 cebix 1.7 doilladdr move.l a0,(sp) ;Save a0
361 jlachmann 1.5
362     move.l usp,a0 ;Get user stack pointer
363     move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack
364     move.l 2*4(sp),-(a0)
365     move.l 1*4(sp),-(a0)
366     move.l a0,usp ;Update USP
367     move.l (sp)+,a0 ;Restore a0
368    
369     lea 6*2(sp),sp ;Remove exception frame from supervisor stack
370     andi #$d8ff,sr ;Switch to user mode, enable interrupts
371    
372     move.l $0c.w,-(sp) ;Jump to MacOS exception handler
373     rts
374    
375    
376 cebix 1.1 *
377     * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
378     * to execute extended opcodes (see emul_op.h)
379     *
380    
381 cebix 1.7 doillinstr movem.l a0/d0,-(sp)
382 jlachmann 1.5 move.w ([6+2*4,sp]),d0
383     and.w #$ff00,d0
384     cmp.w #$7100,d0
385     movem.l (sp)+,a0/d0
386     beq 1$
387    
388     move.l a0,(sp) ;Save a0
389     move.l usp,a0 ;Get user stack pointer
390     move.l 8(sp),-(a0) ;Copy stack frame to user stack
391     move.l 4(sp),-(a0)
392     move.l a0,usp ;Update USP
393     move.l (sp)+,a0 ;Restore a0
394    
395     add.w #3*4,sp ;Remove exception frame from supervisor stack
396     andi #$d8ff,sr ;Switch to user mode, enable interrupts
397    
398     move.l $10.w,-(sp) ;Jump to MacOS exception handler
399     rts
400    
401 cebix 1.7 1$ move.l a6,(sp) ;Save a6
402 cebix 1.1 move.l usp,a6 ;Get user stack pointer
403    
404     move.l a6,-10(a6) ;Push USP (a7)
405     move.l 6(sp),-(a6) ;Push PC
406     move.w 4(sp),-(a6) ;Push SR
407     subq.l #4,a6 ;Skip saved USP
408     move.l (sp),-(a6) ;Push old a6
409     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
410     move.l a6,usp ;Update USP
411    
412     add.w #12,sp ;Remove exception frame from supervisor stack
413     andi #$d8ff,sr ;Switch to user mode, enable interrupts
414    
415     move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp
416     jsr _IllInstrHandler
417     addq.l #4,sp
418    
419     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
420     addq.l #4,sp ;Skip saved USP (!!)
421     rtr ;Return from exception
422    
423     *
424     * Privilege violation handler: MacOS runs in supervisor mode,
425     * so we have to emulate certain privileged instructions
426     *
427    
428     doprivviol move.l d0,(sp) ;Save d0
429     move.w ([6,sp]),d0 ;Get instruction word
430    
431     cmp.w #$40e7,d0 ;move sr,-(sp)?
432     beq pushsr
433     cmp.w #$46df,d0 ;move (sp)+,sr?
434     beq popsr
435    
436     cmp.w #$007c,d0 ;ori #xxxx,sr?
437     beq orisr
438     cmp.w #$027c,d0 ;andi #xxxx,sr?
439     beq andisr
440    
441     cmp.w #$46fc,d0 ;move #xxxx,sr?
442     beq movetosrimm
443    
444     cmp.w #$46ef,d0 ;move (xxxx,sp),sr?
445     beq movetosrsprel
446     cmp.w #$46d8,d0 ;move (a0)+,sr?
447     beq movetosra0p
448     cmp.w #$46d9,d0 ;move (a1)+,sr?
449     beq movetosra1p
450    
451     cmp.w #$40f8,d0 ;move sr,xxxx.w?
452     beq movefromsrabs
453     cmp.w #$40d0,d0 ;move sr,(a0)?
454     beq movefromsra0
455     cmp.w #$40d7,d0 ;move sr,(sp)?
456 cebix 1.6 beq movefromsrsp
457 cebix 1.1
458     cmp.w #$f327,d0 ;fsave -(sp)?
459     beq fsavepush
460     cmp.w #$f35f,d0 ;frestore (sp)+?
461     beq frestorepop
462 jlachmann 1.5 cmp.w #$f32d,d0 ;fsave xxx(a5) ?
463     beq fsavea5
464     cmp.w #$f36d,d0 ;frestore xxx(a5) ?
465     beq frestorea5
466 cebix 1.1
467     cmp.w #$4e73,d0 ;rte?
468     beq pvrte
469    
470     cmp.w #$40c0,d0 ;move sr,d0?
471     beq movefromsrd0
472     cmp.w #$40c1,d0 ;move sr,d1?
473     beq movefromsrd1
474     cmp.w #$40c2,d0 ;move sr,d2?
475     beq movefromsrd2
476     cmp.w #$40c3,d0 ;move sr,d3?
477     beq movefromsrd3
478     cmp.w #$40c4,d0 ;move sr,d4?
479     beq movefromsrd4
480     cmp.w #$40c5,d0 ;move sr,d5?
481     beq movefromsrd5
482     cmp.w #$40c6,d0 ;move sr,d6?
483     beq movefromsrd6
484     cmp.w #$40c7,d0 ;move sr,d7?
485     beq movefromsrd7
486    
487     cmp.w #$46c0,d0 ;move d0,sr?
488     beq movetosrd0
489     cmp.w #$46c1,d0 ;move d1,sr?
490     beq movetosrd1
491     cmp.w #$46c2,d0 ;move d2,sr?
492     beq movetosrd2
493     cmp.w #$46c3,d0 ;move d3,sr?
494     beq movetosrd3
495     cmp.w #$46c4,d0 ;move d4,sr?
496     beq movetosrd4
497     cmp.w #$46c5,d0 ;move d5,sr?
498     beq movetosrd5
499     cmp.w #$46c6,d0 ;move d6,sr?
500     beq movetosrd6
501     cmp.w #$46c7,d0 ;move d7,sr?
502     beq movetosrd7
503    
504     cmp.w #$4e7a,d0 ;movec cr,x?
505     beq movecfromcr
506     cmp.w #$4e7b,d0 ;movec x,cr?
507     beq movectocr
508    
509     cmp.w #$f478,d0 ;cpusha dc?
510     beq cpushadc
511     cmp.w #$f4f8,d0 ;cpusha dc/ic?
512     beq cpushadcic
513    
514 jlachmann 1.5 cmp.w #$4e69,d0 ;move usp,a1
515     beq moveuspa1
516     cmp.w #$4e68,d0 ;move usp,a0
517     beq moveuspa0
518    
519     cmp.w #$4e61,d0 ;move a1,usp
520     beq moved1usp
521    
522 cebix 1.1 pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp
523     move.l a6,(sp) ;Save a6
524     move.l usp,a6 ;Get user stack pointer
525    
526     move.l a6,-10(a6) ;Push USP (a7)
527     move.l 6(sp),-(a6) ;Push PC
528     move.w 4(sp),-(a6) ;Push SR
529     subq.l #4,a6 ;Skip saved USP
530     move.l (sp),-(a6) ;Push old a6
531     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
532     move.l a6,usp ;Update USP
533    
534     add.w #12,sp ;Remove exception frame from supervisor stack
535     andi #$d8ff,sr ;Switch to user mode, enable interrupts
536    
537     move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp
538     jsr _PrivViolHandler
539     addq.l #4,sp
540    
541     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
542     addq.l #4,sp ;Skip saved USP
543     rtr ;Return from exception
544    
545     ; move sr,-(sp)
546     pushsr move.l a0,-(sp) ;Save a0
547     move.l usp,a0 ;Get user stack pointer
548     move.w 8(sp),d0 ;Get CCR from exception stack frame
549     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
550     move.w d0,-(a0) ;Store SR on user stack
551     move.l a0,usp ;Update USP
552     move.l (sp)+,a0 ;Restore a0
553     move.l (sp)+,d0 ;Restore d0
554     addq.l #2,2(sp) ;Skip instruction
555     rte
556    
557     ; move (sp)+,sr
558     popsr move.l a0,-(sp) ;Save a0
559     move.l usp,a0 ;Get user stack pointer
560     move.w (a0)+,d0 ;Get SR from user stack
561     move.w d0,8(sp) ;Store into CCR on exception stack frame
562     and.w #$00ff,8(sp)
563 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
564 cebix 1.1 move.w d0,_EmulatedSR ;And save them
565    
566     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
567     bne 1$
568     tst.l _InterruptFlags
569     beq 1$
570     movem.l d0-d1/a0-a1/a6,-(sp)
571     move.l _SysBase,a6
572     move.l _MainTask,a1
573     move.l _IRQSigMask,d0
574     JSRLIB Signal
575     movem.l (sp)+,d0-d1/a0-a1/a6
576     1$
577     move.l a0,usp ;Update USP
578     move.l (sp)+,a0 ;Restore a0
579     move.l (sp)+,d0 ;Restore d0
580     addq.l #2,2(sp) ;Skip instruction
581     rte
582    
583     ; ori #xxxx,sr
584     orisr move.w 4(sp),d0 ;Get CCR from stack
585     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
586     or.w ([6,sp],2),d0 ;Or with immediate value
587     move.w d0,4(sp) ;Store into CCR on stack
588     and.w #$00ff,4(sp)
589 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
590 cebix 1.1 move.w d0,_EmulatedSR ;And save them
591     move.l (sp)+,d0 ;Restore d0
592     addq.l #4,2(sp) ;Skip instruction
593     rte
594    
595     ; andi #xxxx,sr
596     andisr move.w 4(sp),d0 ;Get CCR from stack
597     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
598     and.w ([6,sp],2),d0 ;And with immediate value
599     storesr4 move.w d0,4(sp) ;Store into CCR on stack
600     and.w #$00ff,4(sp)
601 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
602 cebix 1.1 move.w d0,_EmulatedSR ;And save them
603    
604     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
605     bne.s 1$
606     tst.l _InterruptFlags
607     beq.s 1$
608     movem.l d0-d1/a0-a1/a6,-(sp)
609     move.l _SysBase,a6
610     move.l _MainTask,a1
611     move.l _IRQSigMask,d0
612     JSRLIB Signal
613     movem.l (sp)+,d0-d1/a0-a1/a6
614     1$ move.l (sp)+,d0 ;Restore d0
615     addq.l #4,2(sp) ;Skip instruction
616     rte
617    
618     ; move #xxxx,sr
619     movetosrimm move.w ([6,sp],2),d0 ;Get immediate value
620     bra.s storesr4
621    
622     ; move (xxxx,sp),sr
623     movetosrsprel move.l a0,-(sp) ;Save a0
624     move.l usp,a0 ;Get user stack pointer
625     move.w ([10,sp],2),d0 ;Get offset
626     move.w (a0,d0.w),d0 ;Read word
627     move.l (sp)+,a0 ;Restore a0
628     bra.s storesr4
629    
630     ; move (a0)+,sr
631     movetosra0p move.w (a0)+,d0 ;Read word
632     bra storesr2
633    
634     ; move (a1)+,sr
635     movetosra1p move.w (a1)+,d0 ;Read word
636     bra storesr2
637    
638     ; move sr,xxxx.w
639     movefromsrabs move.l a0,-(sp) ;Save a0
640     move.w ([10,sp],2),a0 ;Get address
641     move.w 8(sp),d0 ;Get CCR
642     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
643     move.w d0,(a0) ;Store SR
644     move.l (sp)+,a0 ;Restore a0
645     move.l (sp)+,d0 ;Restore d0
646     addq.l #4,2(sp) ;Skip instruction
647     rte
648    
649     ; move sr,(a0)
650     movefromsra0 move.w 4(sp),d0 ;Get CCR
651     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
652     move.w d0,(a0) ;Store SR
653     move.l (sp)+,d0 ;Restore d0
654     addq.l #2,2(sp) ;Skip instruction
655     rte
656    
657     ; move sr,(sp)
658     movefromsrsp move.l a0,-(sp) ;Save a0
659     move.l usp,a0 ;Get user stack pointer
660     move.w 8(sp),d0 ;Get CCR
661     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
662     move.w d0,(a0) ;Store SR
663     move.l (sp)+,a0 ;Restore a0
664     move.l (sp)+,d0 ;Restore d0
665     addq.l #2,2(sp) ;Skip instruction
666     rte
667    
668     ; fsave -(sp)
669     fsavepush move.l (sp),d0 ;Restore d0
670     move.l a0,(sp) ;Save a0
671     move.l usp,a0 ;Get user stack pointer
672     fsave -(a0) ;Push FP state
673     move.l a0,usp ;Update USP
674     move.l (sp)+,a0 ;Restore a0
675     addq.l #2,2(sp) ;Skip instruction
676     rte
677    
678     ; frestore (sp)+
679     frestorepop move.l (sp),d0 ;Restore d0
680     move.l a0,(sp) ;Save a0
681     move.l usp,a0 ;Get user stack pointer
682     frestore (a0)+ ;Restore FP state
683     move.l a0,usp ;Update USP
684     move.l (sp)+,a0 ;Restore a0
685     addq.l #2,2(sp) ;Skip instruction
686     rte
687    
688 jlachmann 1.5 ; frestore xxx(a5) +jl+
689     frestorea5 move.l (sp),d0 ;Restore d0
690     move.l a0,(sp) ;Save a0
691     move.l a5,a0 ;Get base register
692     add.w ([6,sp],2),a0 ;Add offset to base register
693     frestore (a0) ;Restore FP state from (a0)
694     move.l (sp)+,a0 ;Restore a0
695     addq.l #4,2(sp) ;Skip instruction
696     rte
697    
698     ; fsave xxx(a5) +jl+
699 cebix 1.7 fsavea5 move.l (sp),d0 ;Restore d0
700 jlachmann 1.5 move.l a0,(sp) ;Save a0
701     move.l a5,a0 ;Get base register
702     add.w ([6,sp],2),a0 ;Add offset to base register
703     fsave (a0) ;Push FP state to (a0)
704     move.l (sp)+,a0 ;Restore a0
705     addq.l #4,2(sp) ;Skip instruction
706     rte
707    
708     ; rte
709     pvrte movem.l a0/a1,-(sp) ;Save a0 and a1
710 cebix 1.1 move.l usp,a0 ;Get user stack pointer
711 jlachmann 1.5
712 cebix 1.1 move.w (a0)+,d0 ;Get SR from user stack
713 jlachmann 1.5 move.w d0,8+4(sp) ;Store into CCR on exception stack frame
714     and.w #$c0ff,8+4(sp)
715     and.w #$e700,d0 ;Extract supervisor bits
716 cebix 1.1 move.w d0,_EmulatedSR ;And save them
717 jlachmann 1.5 move.l (a0)+,10+4(sp) ;Store return address in exception stack frame
718    
719     move.w (a0)+,d0 ;get format word
720     lsr.w #7,d0 ;get stack frame Id
721     lsr.w #4,d0
722     and.w #$001e,d0
723     move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length
724     subq.w #4,d0 ; count only extra words
725     lea 16+4(sp),a1 ; destination address (in supervisor stack)
726     bra 1$
727    
728 cebix 1.7 2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack
729     1$ dbf d0,2$
730 jlachmann 1.5
731 cebix 1.1 move.l a0,usp ;Update USP
732 jlachmann 1.5 movem.l (sp)+,a0/a1 ;Restore a0 and a1
733 cebix 1.1 move.l (sp)+,d0 ;Restore d0
734     rte
735    
736 jlachmann 1.5 ; sizes of exceptions stack frames
737     StackFormatTable:
738     dc.w 4 ; Four-word stack frame, format $0
739     dc.w 4 ; Throwaway four-word stack frame, format $1
740     dc.w 6 ; Six-word stack frame, format $2
741     dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3
742     dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4
743     dc.w 4 ; Format $5
744     dc.w 4 ; Format $6
745     dc.w 30 ; MC68040 access error stack frame, Format $7
746     dc.w 29 ; MC68010 bus and address error stack frame, format $8
747     dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9
748     dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a
749     dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b
750     dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c
751     dc.w 4 ; Format $d
752     dc.w 4 ; Format $e
753     dc.w 4 ; Format $f
754    
755 cebix 1.1 ; move sr,dx
756     movefromsrd0 addq.l #4,sp ;Skip saved d0
757     moveq #0,d0
758     move.w (sp),d0 ;Get CCR
759     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
760     addq.l #2,2(sp) ;Skip instruction
761     rte
762    
763     movefromsrd1 move.l (sp)+,d0
764     moveq #0,d1
765     move.w (sp),d1
766     or.w _EmulatedSR,d1
767     addq.l #2,2(sp)
768     rte
769    
770     movefromsrd2 move.l (sp)+,d0
771     moveq #0,d2
772     move.w (sp),d2
773     or.w _EmulatedSR,d2
774     addq.l #2,2(sp)
775     rte
776    
777     movefromsrd3 move.l (sp)+,d0
778     moveq #0,d3
779     move.w (sp),d3
780     or.w _EmulatedSR,d3
781     addq.l #2,2(sp)
782     rte
783    
784     movefromsrd4 move.l (sp)+,d0
785     moveq #0,d4
786     move.w (sp),d4
787     or.w _EmulatedSR,d4
788     addq.l #2,2(sp)
789     rte
790    
791     movefromsrd5 move.l (sp)+,d0
792     moveq #0,d5
793     move.w (sp),d5
794     or.w _EmulatedSR,d5
795     addq.l #2,2(sp)
796     rte
797    
798     movefromsrd6 move.l (sp)+,d0
799     moveq #0,d6
800     move.w (sp),d6
801     or.w _EmulatedSR,d6
802     addq.l #2,2(sp)
803     rte
804    
805     movefromsrd7 move.l (sp)+,d0
806     moveq #0,d7
807     move.w (sp),d7
808     or.w _EmulatedSR,d7
809     addq.l #2,2(sp)
810     rte
811    
812     ; move dx,sr
813     movetosrd0 move.l (sp),d0
814     storesr2 move.w d0,4(sp)
815     and.w #$00ff,4(sp)
816 jlachmann 1.5 and.w #$e700,d0
817 cebix 1.1 move.w d0,_EmulatedSR
818    
819     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
820     bne.s 1$
821     tst.l _InterruptFlags
822     beq.s 1$
823     movem.l d0-d1/a0-a1/a6,-(sp)
824     move.l _SysBase,a6
825     move.l _MainTask,a1
826     move.l _IRQSigMask,d0
827     JSRLIB Signal
828     movem.l (sp)+,d0-d1/a0-a1/a6
829     1$ move.l (sp)+,d0
830     addq.l #2,2(sp)
831     rte
832    
833     movetosrd1 move.l d1,d0
834     bra.s storesr2
835    
836     movetosrd2 move.l d2,d0
837     bra.s storesr2
838    
839     movetosrd3 move.l d3,d0
840     bra.s storesr2
841    
842     movetosrd4 move.l d4,d0
843     bra.s storesr2
844    
845     movetosrd5 move.l d5,d0
846     bra.s storesr2
847    
848     movetosrd6 move.l d6,d0
849     bra.s storesr2
850    
851     movetosrd7 move.l d7,d0
852     bra.s storesr2
853    
854     ; movec cr,x
855     movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word
856    
857     cmp.w #$8801,d0 ;movec vbr,a0?
858     beq.s movecvbra0
859     cmp.w #$9801,d0 ;movec vbr,a1?
860     beq.s movecvbra1
861 jlachmann 1.5 cmp.w #$1801,d0 ;movec vbr,d1?
862     beq movecvbrd1
863 cebix 1.1 cmp.w #$0002,d0 ;movec cacr,d0?
864     beq.s moveccacrd0
865     cmp.w #$1002,d0 ;movec cacr,d1?
866     beq.s moveccacrd1
867     cmp.w #$0003,d0 ;movec tc,d0?
868     beq.s movectcd0
869     cmp.w #$1003,d0 ;movec tc,d1?
870     beq.s movectcd1
871 cebix 1.6 cmp.w #$1000,d0 ;movec sfc,d1?
872 jlachmann 1.5 beq movecsfcd1
873 cebix 1.6 cmp.w #$1001,d0 ;movec dfc,d1?
874 jlachmann 1.5 beq movecdfcd1
875 cebix 1.6 cmp.w #$0806,d0 ;movec urp,d0?
876 jlachmann 1.5 beq movecurpd0
877 cebix 1.6 cmp.w #$0807,d0 ;movec srp,d0?
878 jlachmann 1.5 beq.s movecsrpd0
879 cebix 1.6 cmp.w #$0004,d0 ;movec itt0,d0
880 jlachmann 1.5 beq.s movecitt0d0
881 cebix 1.6 cmp.w #$0005,d0 ;movec itt1,d0
882 jlachmann 1.5 beq.s movecitt1d0
883 cebix 1.6 cmp.w #$0006,d0 ;movec dtt0,d0
884 jlachmann 1.5 beq.s movecdtt0d0
885 cebix 1.6 cmp.w #$0007,d0 ;movec dtt1,d0
886 jlachmann 1.5 beq.s movecdtt1d0
887 cebix 1.1
888     bra pv_unhandled
889    
890     ; movec cacr,d0
891     moveccacrd0 move.l (sp)+,d0
892     move.l #$3111,d0 ;All caches and bursts on
893     addq.l #4,2(sp)
894     rte
895    
896     ; movec cacr,d1
897     moveccacrd1 move.l (sp)+,d0
898     move.l #$3111,d1 ;All caches and bursts on
899     addq.l #4,2(sp)
900     rte
901    
902     ; movec vbr,a0
903     movecvbra0 move.l (sp)+,d0
904     sub.l a0,a0 ;VBR always appears to be at 0
905     addq.l #4,2(sp)
906     rte
907    
908     ; movec vbr,a1
909     movecvbra1 move.l (sp)+,d0
910     sub.l a1,a1 ;VBR always appears to be at 0
911     addq.l #4,2(sp)
912     rte
913    
914 jlachmann 1.5 ; movec vbr,d1
915     movecvbrd1 move.l (sp)+,d0
916     moveq.l #0,d1 ;VBR always appears to be at 0
917     addq.l #4,2(sp)
918     rte
919    
920 cebix 1.1 ; movec tc,d0
921     movectcd0 addq.l #4,sp
922     moveq #0,d0 ;MMU is always off
923     addq.l #4,2(sp)
924     rte
925    
926 jlachmann 1.5 ; movec tc,d1 +jl+
927     movectcd1 move.l (sp)+,d0 ;Restore d0
928     moveq #0,d1 ;MMU is always off
929     addq.l #4,2(sp)
930     rte
931    
932 cebix 1.6 ; movec sfc,d1 +jl+
933 cebix 1.7 movecsfcd1 move.l (sp)+,d0 ;Restore d0
934 cebix 1.6 moveq #0,d1
935 jlachmann 1.5 addq.l #4,2(sp)
936     rte
937    
938 cebix 1.6 ; movec dfc,d1 +jl+
939 cebix 1.7 movecdfcd1 move.l (sp)+,d0 ;Restore d0
940 cebix 1.6 moveq #0,d1
941 cebix 1.1 addq.l #4,2(sp)
942     rte
943    
944 cebix 1.7 movecurpd0 ; movec urp,d0 +jl+
945     movecsrpd0 ; movec srp,d0
946     movecitt0d0 ; movec itt0,d0
947     movecitt1d0 ; movec itt1,d0
948     movecdtt0d0 ; movec dtt0,d0
949     movecdtt1d0 ; movec dtt1,d0
950 jlachmann 1.5 addq.l #4,sp
951     moveq.l #0,d0 ;MMU is always off
952     addq.l #4,2(sp) ;skip instruction
953     rte
954    
955 cebix 1.1 ; movec x,cr
956     movectocr move.w ([6,sp],2),d0 ;Get next instruction word
957    
958     cmp.w #$0801,d0 ;movec d0,vbr?
959     beq.s movectovbr
960 jlachmann 1.5 cmp.w #$1801,d0 ;movec d1,vbr?
961     beq.s movectovbr
962 cebix 1.1 cmp.w #$0002,d0 ;movec d0,cacr?
963     beq.s movectocacr
964     cmp.w #$1002,d0 ;movec d1,cacr?
965     beq.s movectocacr
966 cebix 1.6 cmp.w #$1000,d0 ;movec d1,sfc?
967 jlachmann 1.5 beq.s movectoxfc
968 cebix 1.6 cmp.w #$1001,d0 ;movec d1,dfc?
969 jlachmann 1.5 beq.s movectoxfc
970 cebix 1.1
971     bra pv_unhandled
972    
973     ; movec x,vbr
974     movectovbr move.l (sp)+,d0 ;Ignore moves to VBR
975     addq.l #4,2(sp)
976     rte
977    
978     ; movec dx,cacr
979     movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches
980     move.l _SysBase,a6
981     JSRLIB CacheClearU
982     movem.l (sp)+,d1/a0-a1/a6
983     move.l (sp)+,d0
984     addq.l #4,2(sp)
985     rte
986    
987 cebix 1.6 ; movec x,sfc
988     ; movec x,dfc
989 jlachmann 1.5 movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC
990     addq.l #4,2(sp)
991     rte
992    
993 cebix 1.1 ; cpusha
994     cpushadc
995     cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches
996     move.l _SysBase,a6
997     JSRLIB CacheClearU
998     movem.l (sp)+,d1/a0-a1/a6
999     move.l (sp)+,d0
1000     addq.l #2,2(sp)
1001     rte
1002 jlachmann 1.5
1003     ; move usp,a1 +jl+
1004 cebix 1.7 moveuspa1 move.l (sp)+,d0
1005 jlachmann 1.5 move usp,a1
1006     addq.l #2,2(sp)
1007     rte
1008    
1009     ; move usp,a0 +jl+
1010 cebix 1.7 moveuspa0 move.l (sp)+,d0
1011 jlachmann 1.5 move usp,a0
1012     addq.l #2,2(sp)
1013     rte
1014    
1015     ; move a1,usp +jl+
1016 cebix 1.7 moved1usp move.l (sp)+,d0
1017 jlachmann 1.5 move a1,usp
1018     addq.l #2,2(sp)
1019     rte
1020    
1021     ;
1022     ; Trigger NMI (Pop up debugger)
1023     ;
1024    
1025 cebix 1.7 _AsmTriggerNMI move.l d0,-(sp) ;Save d0
1026 jlachmann 1.5 move.w #$007c,-(sp) ;Yes, fake NMI stack frame
1027     pea 1$
1028     move.w _EmulatedSR,d0
1029     and.w #$f8ff,d0 ;Set interrupt level in SR
1030     move.w d0,-(sp)
1031     move.w d0,_EmulatedSR
1032    
1033     move.l $7c.w,-(sp) ;Jump to MacOS NMI handler
1034     rts
1035    
1036     1$ move.l (sp)+,d0 ;Restore d0
1037     rts
1038    
1039 cebix 1.1
1040     END