ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.10
Committed: 2001-06-30T12:58:07Z (23 years, 5 months ago) by cebix
Branch: MAIN
Changes since 1.9: +13 -76 lines
Log Message:
- fixed compilation problems under AmigaOS
- fsave/frestore on AmigaOS and NetBSD/m68k always use a 68882/68040-style
  FPU frame, eliminating the need for 68060 FPU patches

File Contents

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