ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.2
Committed: 1999-10-19T19:28:13Z (25 years, 1 month ago) by cebix
Branch: MAIN
CVS Tags: snapshot-21101999
Changes since 1.1: +2 -2 lines
Log Message:
- now compiles with GCC under AmigaOS

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 _TimevalTo64
32     XDEF _TimevalToMacTime
33     XDEF _Execute68k
34     XDEF _Execute68kTrap
35     XDEF _TrapHandlerAsm
36     XDEF _ExceptionHandlerAsm
37     XDEF _Scod060Patch1
38     XDEF _Scod060Patch2
39     XDEF _ThInitFPUPatch
40    
41     XREF _OldTrapHandler
42     XREF _OldExceptionHandler
43     XREF _IllInstrHandler
44     XREF _PrivViolHandler
45     XREF _EmulatedSR
46     XREF _IRQSigMask
47     XREF _InterruptFlags
48     XREF _MainTask
49     XREF _SysBase
50 cebix 1.2 XREF _quit_emulator
51 cebix 1.1
52     SECTION text,CODE
53    
54     *
55     * Atomic bit operations (don't trust the compiler)
56     *
57    
58     _AtomicAnd move.l 4(sp),a0
59     move.l 8(sp),d0
60     and.l d0,(a0)
61     rts
62    
63     _AtomicOr move.l 4(sp),a0
64     move.l 8(sp),d0
65     or.l d0,(a0)
66     rts
67    
68     *
69     * Move VBR away from 0 if neccessary
70     *
71    
72     _MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp)
73     move.l _SysBase,a6
74    
75     lea getvbr,a5 ;VBR at 0?
76     JSRLIB Supervisor
77     tst.l d0
78     bne.s 1$
79    
80     move.l #$400,d0 ;Yes, allocate memory for new table
81     move.l #MEMF_PUBLIC,d1
82     JSRLIB AllocMem
83     tst.l d0
84     beq.s 1$
85    
86     JSRLIB Disable
87    
88     move.l d0,a5 ;Copy old table
89     move.l d0,a1
90     sub.l a0,a0
91     move.l #$400,d0
92     JSRLIB CopyMem
93     JSRLIB CacheClearU
94    
95     move.l a5,d0 ;Set VBR
96     lea setvbr,a5
97     JSRLIB Supervisor
98    
99     JSRLIB Enable
100    
101     1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6
102     rts
103    
104     getvbr movec vbr,d0
105     rte
106    
107     setvbr movec d0,vbr
108     rte
109    
110     *
111     * Convert timeval to 64 bit microseconds
112     *
113    
114     _TimevalTo64 move.l 4(sp),a0 ;Pointer to timeval
115     move.l 8(sp),a1 ;Pointer to high longword of result, low longword is returned in d0
116    
117     move.l d2,-(sp)
118    
119     move.l TV_SECS(a0),d0 ;Convert to 64 bit microseconds
120     mulu.l #1000000,d1:d0
121     add.l TV_MICRO(a0),d0
122     moveq #0,d2
123     addx.l d2,d1
124     move.l d1,(a1)
125    
126     move.l (sp)+,d2
127     rts
128    
129     *
130     * Convert timeval to Mac time value (>0: milliseconds, <0: microseconds)
131     *
132    
133     _TimevalToMacTime
134     move.l 4(sp),a0 ;Pointer to timeval
135    
136     move.l d2,-(sp)
137    
138     move.l TV_SECS(a0),d0 ;Convert to 64 bit microseconds
139     mulu.l #1000000,d1:d0
140     add.l TV_MICRO(a0),d0
141     moveq #0,d2
142     addx.l d2,d1
143    
144     tst.l d1 ;Too large for 32 bit microseconds?
145     bne.s 1$
146     cmp.l #$7fffffff,d0
147     bhi.s 1$
148    
149     neg.l d0 ;No, return negative microseconds
150     bra.s 2$
151    
152     1$ divu.l #1000,d1:d0 ;Yes, return milliseconds
153    
154     2$ move.l (sp)+,d2
155     rts
156    
157     *
158     * Execute 68k subroutine (must be ended with rts)
159     * r->a[7] and r->sr are unused!
160     *
161    
162     ; void Execute68k(uint32 addr, M68kRegisters *r);
163     _Execute68k
164     move.l 4(sp),d0 ;Get arguments
165     move.l 8(sp),a0
166    
167     movem.l d2-d7/a2-a6,-(sp) ;Save registers
168    
169     move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
170     pea 1$ ;Push return address on stack
171     move.l d0,-(sp) ;Push pointer to 68k routine on stack
172     movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
173    
174     rts ;Jump into 68k routine
175    
176     1$ move.l a6,-(sp) ;Save a6
177     move.l 4(sp),a6 ;Get pointer to M68kRegisters
178     movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
179     move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
180     addq.l #4,sp ;Remove pointer from stack
181    
182     movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
183     rts
184    
185     *
186     * Execute MacOS 68k trap
187     * r->a[7] and r->sr are unused!
188     *
189    
190     ; void Execute68kTrap(uint16 trap, M68kRegisters *r);
191     _Execute68kTrap
192     move.l 4(sp),d0 ;Get arguments
193     move.l 8(sp),a0
194    
195     movem.l d2-d7/a2-a6,-(sp) ;Save registers
196    
197     move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
198     move.w d0,-(sp) ;Push trap word on stack
199     subq.l #8,sp ;Create fake A-Line exception frame
200     movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
201    
202     move.l a2,-(sp) ;Save a2 and d2
203     move.l d2,-(sp)
204     lea 1$,a2 ;a2 points to return address
205     move.w 16(sp),d2 ;Load trap word into d2
206    
207     jmp ([$28.w],10) ;Jump into MacOS A-Line handler
208    
209     1$ move.l a6,-(sp) ;Save a6
210     move.l 6(sp),a6 ;Get pointer to M68kRegisters
211     movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
212     move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
213     addq.l #6,sp ;Remove pointer and trap word from stack
214    
215     movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
216     rts
217    
218     *
219     * Exception handler of main task (for 60Hz interrupts)
220     *
221    
222     _ExceptionHandlerAsm
223     move.l d0,-(sp) ;Save d0
224    
225     and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C?
226     bne.s 2$
227    
228     move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR?
229     and.w #$0700,d0
230     bne 1$
231     move.w #$0064,-(sp) ;Yes, fake interrupt stack frame
232     pea 1$
233     move.w _EmulatedSR,d0
234     move.w d0,-(sp)
235     or.w #$0100,d0 ;Set interrupt level in SR
236     move.w d0,_EmulatedSR
237     move.l $64.w,a0 ;Jump to MacOS interrupt handler
238     jmp (a0)
239    
240     1$ move.l (sp)+,d0 ;Restore d0
241     rts
242    
243     2$ JSRLIB Forbid ;Waiting for Dos signal?
244     sub.l a1,a1
245     JSRLIB FindTask
246     move.l d0,a0
247     move.l TC_SIGWAIT(a0),d0
248     move.l TC_SIGRECVD(a0),d1
249     JSRLIB Permit
250     btst #SIGB_DOS,d0
251     beq 3$
252     btst #SIGB_DOS,d1
253     bne 4$
254    
255     3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets
256     JSRLIB GetMsg
257    
258     move.w _EmulatedSR,d0
259     or.w #$0700,d0 ;Disable all interrupts
260     move.w d0,_EmulatedSR
261     moveq #0,d0 ;Disable all exception signals
262     moveq #-1,d1
263     JSRLIB SetExcept
264 cebix 1.2 jsr _quit_emulator ;CTRL-C, quit emulator
265 cebix 1.1 4$ move.l (sp)+,d0
266     rts
267    
268     *
269     * Process Manager 68060 FPU patches
270     *
271    
272     _Scod060Patch1 fsave -(sp) ;Save FPU state
273     tst.b 2(sp) ;Null?
274     beq.s 1$
275     fmovem.x fp0-fp7,-(sp) ;No, save FPU registers
276     fmove.l fpiar,-(sp)
277     fmove.l fpsr,-(sp)
278     fmove.l fpcr,-(sp)
279     pea -1 ;Push "FPU state saved" flag
280     1$ move.l d1,-(sp)
281     move.l d0,-(sp)
282     bsr.s 3$ ;Switch integer registers and stack
283     addq.l #8,sp
284     tst.b 2(sp) ;New FPU state null or "FPU state saved" flag set?
285     beq.s 2$
286     addq.l #4,sp ;Flag set, skip it
287     fmove.l (sp)+,fpcr ;Restore FPU registers and state
288     fmove.l (sp)+,fpsr
289     fmove.l (sp)+,fpiar
290     fmovem.x (sp)+,fp0-fp7
291     2$ frestore (sp)+
292     movem.l (sp)+,d0-d1
293     rts
294    
295     3$ move.l 4(sp),a0 ;Switch integer registers and stack
296     move sr,-(sp)
297     movem.l d2-d7/a2-a6,-(sp)
298     cmp.w #0,a0
299     beq.s 4$
300     move.l sp,(a0)
301     4$ move.l $36(sp),a0
302     movem.l (a0)+,d2-d7/a2-a6
303     move (a0)+,sr
304     move.l a0,sp
305     rts
306    
307     _Scod060Patch2 move.l d0,-(sp) ;Create 68060 null frame on stack
308     move.l d0,-(sp)
309     move.l d0,-(sp)
310     frestore (sp)+ ;and load it
311     rts
312    
313     *
314     * Thread Manager 68060 FPU patches
315     *
316    
317     _ThInitFPUPatch tst.b $40(a4)
318     bne.s 1$
319     moveq #0,d0 ;Create 68060 null frame on stack
320     move.l d0,-(a3)
321     move.l d0,-(a3)
322     move.l d0,-(a3)
323     1$ rts
324    
325     *
326     * Trap handler of main task
327     *
328    
329     _TrapHandlerAsm cmp.l #4,(sp) ;Illegal instruction?
330     beq.s doillinstr
331     cmp.l #10,(sp) ;A-Line exception?
332     beq.s doaline
333     cmp.l #8,(sp) ;Privilege violation?
334     beq.s doprivviol
335    
336     move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler
337     rts
338    
339     *
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     *
357     * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
358     * to execute extended opcodes (see emul_op.h)
359     *
360    
361     doillinstr move.l a6,(sp) ;Save a6
362     move.l usp,a6 ;Get user stack pointer
363    
364     move.l a6,-10(a6) ;Push USP (a7)
365     move.l 6(sp),-(a6) ;Push PC
366     move.w 4(sp),-(a6) ;Push SR
367     subq.l #4,a6 ;Skip saved USP
368     move.l (sp),-(a6) ;Push old a6
369     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
370     move.l a6,usp ;Update USP
371    
372     add.w #12,sp ;Remove exception frame from supervisor stack
373     andi #$d8ff,sr ;Switch to user mode, enable interrupts
374    
375     move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp
376     jsr _IllInstrHandler
377     addq.l #4,sp
378    
379     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
380     addq.l #4,sp ;Skip saved USP (!!)
381     rtr ;Return from exception
382    
383     *
384     * Privilege violation handler: MacOS runs in supervisor mode,
385     * so we have to emulate certain privileged instructions
386     *
387    
388     doprivviol move.l d0,(sp) ;Save d0
389     move.w ([6,sp]),d0 ;Get instruction word
390    
391     cmp.w #$40e7,d0 ;move sr,-(sp)?
392     beq pushsr
393     cmp.w #$46df,d0 ;move (sp)+,sr?
394     beq popsr
395    
396     cmp.w #$007c,d0 ;ori #xxxx,sr?
397     beq orisr
398     cmp.w #$027c,d0 ;andi #xxxx,sr?
399     beq andisr
400    
401     cmp.w #$46fc,d0 ;move #xxxx,sr?
402     beq movetosrimm
403    
404     cmp.w #$46ef,d0 ;move (xxxx,sp),sr?
405     beq movetosrsprel
406     cmp.w #$46d8,d0 ;move (a0)+,sr?
407     beq movetosra0p
408     cmp.w #$46d9,d0 ;move (a1)+,sr?
409     beq movetosra1p
410    
411     cmp.w #$40f8,d0 ;move sr,xxxx.w?
412     beq movefromsrabs
413     cmp.w #$40d0,d0 ;move sr,(a0)?
414     beq movefromsra0
415     cmp.w #$40d7,d0 ;move sr,(sp)?
416     beq movefromsra0
417    
418     cmp.w #$f327,d0 ;fsave -(sp)?
419     beq fsavepush
420     cmp.w #$f35f,d0 ;frestore (sp)+?
421     beq frestorepop
422    
423     cmp.w #$4e73,d0 ;rte?
424     beq pvrte
425    
426     cmp.w #$40c0,d0 ;move sr,d0?
427     beq movefromsrd0
428     cmp.w #$40c1,d0 ;move sr,d1?
429     beq movefromsrd1
430     cmp.w #$40c2,d0 ;move sr,d2?
431     beq movefromsrd2
432     cmp.w #$40c3,d0 ;move sr,d3?
433     beq movefromsrd3
434     cmp.w #$40c4,d0 ;move sr,d4?
435     beq movefromsrd4
436     cmp.w #$40c5,d0 ;move sr,d5?
437     beq movefromsrd5
438     cmp.w #$40c6,d0 ;move sr,d6?
439     beq movefromsrd6
440     cmp.w #$40c7,d0 ;move sr,d7?
441     beq movefromsrd7
442    
443     cmp.w #$46c0,d0 ;move d0,sr?
444     beq movetosrd0
445     cmp.w #$46c1,d0 ;move d1,sr?
446     beq movetosrd1
447     cmp.w #$46c2,d0 ;move d2,sr?
448     beq movetosrd2
449     cmp.w #$46c3,d0 ;move d3,sr?
450     beq movetosrd3
451     cmp.w #$46c4,d0 ;move d4,sr?
452     beq movetosrd4
453     cmp.w #$46c5,d0 ;move d5,sr?
454     beq movetosrd5
455     cmp.w #$46c6,d0 ;move d6,sr?
456     beq movetosrd6
457     cmp.w #$46c7,d0 ;move d7,sr?
458     beq movetosrd7
459    
460     cmp.w #$4e7a,d0 ;movec cr,x?
461     beq movecfromcr
462     cmp.w #$4e7b,d0 ;movec x,cr?
463     beq movectocr
464    
465     cmp.w #$f478,d0 ;cpusha dc?
466     beq cpushadc
467     cmp.w #$f4f8,d0 ;cpusha dc/ic?
468     beq cpushadcic
469    
470     pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp
471     move.l a6,(sp) ;Save a6
472     move.l usp,a6 ;Get user stack pointer
473    
474     move.l a6,-10(a6) ;Push USP (a7)
475     move.l 6(sp),-(a6) ;Push PC
476     move.w 4(sp),-(a6) ;Push SR
477     subq.l #4,a6 ;Skip saved USP
478     move.l (sp),-(a6) ;Push old a6
479     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
480     move.l a6,usp ;Update USP
481    
482     add.w #12,sp ;Remove exception frame from supervisor stack
483     andi #$d8ff,sr ;Switch to user mode, enable interrupts
484    
485     move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp
486     jsr _PrivViolHandler
487     addq.l #4,sp
488    
489     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
490     addq.l #4,sp ;Skip saved USP
491     rtr ;Return from exception
492    
493     ; move sr,-(sp)
494     pushsr move.l a0,-(sp) ;Save a0
495     move.l usp,a0 ;Get user stack pointer
496     move.w 8(sp),d0 ;Get CCR from exception stack frame
497     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
498     move.w d0,-(a0) ;Store SR on user stack
499     move.l a0,usp ;Update USP
500     move.l (sp)+,a0 ;Restore a0
501     move.l (sp)+,d0 ;Restore d0
502     addq.l #2,2(sp) ;Skip instruction
503     rte
504    
505     ; move (sp)+,sr
506     popsr move.l a0,-(sp) ;Save a0
507     move.l usp,a0 ;Get user stack pointer
508     move.w (a0)+,d0 ;Get SR from user stack
509     move.w d0,8(sp) ;Store into CCR on exception stack frame
510     and.w #$00ff,8(sp)
511     and.w #$2700,d0 ;Extract supervisor bits
512     move.w d0,_EmulatedSR ;And save them
513    
514     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
515     bne 1$
516     tst.l _InterruptFlags
517     beq 1$
518     movem.l d0-d1/a0-a1/a6,-(sp)
519     move.l _SysBase,a6
520     move.l _MainTask,a1
521     move.l _IRQSigMask,d0
522     JSRLIB Signal
523     movem.l (sp)+,d0-d1/a0-a1/a6
524     1$
525     move.l a0,usp ;Update USP
526     move.l (sp)+,a0 ;Restore a0
527     move.l (sp)+,d0 ;Restore d0
528     addq.l #2,2(sp) ;Skip instruction
529     rte
530    
531     ; ori #xxxx,sr
532     orisr move.w 4(sp),d0 ;Get CCR from stack
533     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
534     or.w ([6,sp],2),d0 ;Or with immediate value
535     move.w d0,4(sp) ;Store into CCR on stack
536     and.w #$00ff,4(sp)
537     and.w #$2700,d0 ;Extract supervisor bits
538     move.w d0,_EmulatedSR ;And save them
539     move.l (sp)+,d0 ;Restore d0
540     addq.l #4,2(sp) ;Skip instruction
541     rte
542    
543     ; andi #xxxx,sr
544     andisr move.w 4(sp),d0 ;Get CCR from stack
545     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
546     and.w ([6,sp],2),d0 ;And with immediate value
547     storesr4 move.w d0,4(sp) ;Store into CCR on stack
548     and.w #$00ff,4(sp)
549     and.w #$2700,d0 ;Extract supervisor bits
550     move.w d0,_EmulatedSR ;And save them
551    
552     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
553     bne.s 1$
554     tst.l _InterruptFlags
555     beq.s 1$
556     movem.l d0-d1/a0-a1/a6,-(sp)
557     move.l _SysBase,a6
558     move.l _MainTask,a1
559     move.l _IRQSigMask,d0
560     JSRLIB Signal
561     movem.l (sp)+,d0-d1/a0-a1/a6
562     1$ move.l (sp)+,d0 ;Restore d0
563     addq.l #4,2(sp) ;Skip instruction
564     rte
565    
566     ; move #xxxx,sr
567     movetosrimm move.w ([6,sp],2),d0 ;Get immediate value
568     bra.s storesr4
569    
570     ; move (xxxx,sp),sr
571     movetosrsprel move.l a0,-(sp) ;Save a0
572     move.l usp,a0 ;Get user stack pointer
573     move.w ([10,sp],2),d0 ;Get offset
574     move.w (a0,d0.w),d0 ;Read word
575     move.l (sp)+,a0 ;Restore a0
576     bra.s storesr4
577    
578     ; move (a0)+,sr
579     movetosra0p move.w (a0)+,d0 ;Read word
580     bra storesr2
581    
582     ; move (a1)+,sr
583     movetosra1p move.w (a1)+,d0 ;Read word
584     bra storesr2
585    
586     ; move sr,xxxx.w
587     movefromsrabs move.l a0,-(sp) ;Save a0
588     move.w ([10,sp],2),a0 ;Get address
589     move.w 8(sp),d0 ;Get CCR
590     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
591     move.w d0,(a0) ;Store SR
592     move.l (sp)+,a0 ;Restore a0
593     move.l (sp)+,d0 ;Restore d0
594     addq.l #4,2(sp) ;Skip instruction
595     rte
596    
597     ; move sr,(a0)
598     movefromsra0 move.w 4(sp),d0 ;Get CCR
599     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
600     move.w d0,(a0) ;Store SR
601     move.l (sp)+,d0 ;Restore d0
602     addq.l #2,2(sp) ;Skip instruction
603     rte
604    
605     ; move sr,(sp)
606     movefromsrsp move.l a0,-(sp) ;Save a0
607     move.l usp,a0 ;Get user stack pointer
608     move.w 8(sp),d0 ;Get CCR
609     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
610     move.w d0,(a0) ;Store SR
611     move.l (sp)+,a0 ;Restore a0
612     move.l (sp)+,d0 ;Restore d0
613     addq.l #2,2(sp) ;Skip instruction
614     rte
615    
616     ; fsave -(sp)
617     fsavepush move.l (sp),d0 ;Restore d0
618     move.l a0,(sp) ;Save a0
619     move.l usp,a0 ;Get user stack pointer
620     fsave -(a0) ;Push FP state
621     move.l a0,usp ;Update USP
622     move.l (sp)+,a0 ;Restore a0
623     addq.l #2,2(sp) ;Skip instruction
624     rte
625    
626     ; frestore (sp)+
627     frestorepop move.l (sp),d0 ;Restore d0
628     move.l a0,(sp) ;Save a0
629     move.l usp,a0 ;Get user stack pointer
630     frestore (a0)+ ;Restore FP state
631     move.l a0,usp ;Update USP
632     move.l (sp)+,a0 ;Restore a0
633     addq.l #2,2(sp) ;Skip instruction
634     rte
635    
636     ; rte (only handles format 0)
637     pvrte move.l a0,-(sp) ;Save a0
638     move.l usp,a0 ;Get user stack pointer
639     move.w (a0)+,d0 ;Get SR from user stack
640     move.w d0,8(sp) ;Store into CCR on exception stack frame
641     and.w #$00ff,8(sp)
642     and.w #$2700,d0 ;Extract supervisor bits
643     move.w d0,_EmulatedSR ;And save them
644     move.l (a0)+,10(sp) ;Store return address in exception stack frame
645     addq.l #2,a0 ;Skip format word
646     move.l a0,usp ;Update USP
647     move.l (sp)+,a0 ;Restore a0
648     move.l (sp)+,d0 ;Restore d0
649     rte
650    
651     ; move sr,dx
652     movefromsrd0 addq.l #4,sp ;Skip saved d0
653     moveq #0,d0
654     move.w (sp),d0 ;Get CCR
655     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
656     addq.l #2,2(sp) ;Skip instruction
657     rte
658    
659     movefromsrd1 move.l (sp)+,d0
660     moveq #0,d1
661     move.w (sp),d1
662     or.w _EmulatedSR,d1
663     addq.l #2,2(sp)
664     rte
665    
666     movefromsrd2 move.l (sp)+,d0
667     moveq #0,d2
668     move.w (sp),d2
669     or.w _EmulatedSR,d2
670     addq.l #2,2(sp)
671     rte
672    
673     movefromsrd3 move.l (sp)+,d0
674     moveq #0,d3
675     move.w (sp),d3
676     or.w _EmulatedSR,d3
677     addq.l #2,2(sp)
678     rte
679    
680     movefromsrd4 move.l (sp)+,d0
681     moveq #0,d4
682     move.w (sp),d4
683     or.w _EmulatedSR,d4
684     addq.l #2,2(sp)
685     rte
686    
687     movefromsrd5 move.l (sp)+,d0
688     moveq #0,d5
689     move.w (sp),d5
690     or.w _EmulatedSR,d5
691     addq.l #2,2(sp)
692     rte
693    
694     movefromsrd6 move.l (sp)+,d0
695     moveq #0,d6
696     move.w (sp),d6
697     or.w _EmulatedSR,d6
698     addq.l #2,2(sp)
699     rte
700    
701     movefromsrd7 move.l (sp)+,d0
702     moveq #0,d7
703     move.w (sp),d7
704     or.w _EmulatedSR,d7
705     addq.l #2,2(sp)
706     rte
707    
708     ; move dx,sr
709     movetosrd0 move.l (sp),d0
710     storesr2 move.w d0,4(sp)
711     and.w #$00ff,4(sp)
712     and.w #$2700,d0
713     move.w d0,_EmulatedSR
714    
715     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
716     bne.s 1$
717     tst.l _InterruptFlags
718     beq.s 1$
719     movem.l d0-d1/a0-a1/a6,-(sp)
720     move.l _SysBase,a6
721     move.l _MainTask,a1
722     move.l _IRQSigMask,d0
723     JSRLIB Signal
724     movem.l (sp)+,d0-d1/a0-a1/a6
725     1$ move.l (sp)+,d0
726     addq.l #2,2(sp)
727     rte
728    
729     movetosrd1 move.l d1,d0
730     bra.s storesr2
731    
732     movetosrd2 move.l d2,d0
733     bra.s storesr2
734    
735     movetosrd3 move.l d3,d0
736     bra.s storesr2
737    
738     movetosrd4 move.l d4,d0
739     bra.s storesr2
740    
741     movetosrd5 move.l d5,d0
742     bra.s storesr2
743    
744     movetosrd6 move.l d6,d0
745     bra.s storesr2
746    
747     movetosrd7 move.l d7,d0
748     bra.s storesr2
749    
750     ; movec cr,x
751     movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word
752    
753     cmp.w #$8801,d0 ;movec vbr,a0?
754     beq.s movecvbra0
755     cmp.w #$9801,d0 ;movec vbr,a1?
756     beq.s movecvbra1
757     cmp.w #$0002,d0 ;movec cacr,d0?
758     beq.s moveccacrd0
759     cmp.w #$1002,d0 ;movec cacr,d1?
760     beq.s moveccacrd1
761     cmp.w #$0003,d0 ;movec tc,d0?
762     beq.s movectcd0
763     cmp.w #$1003,d0 ;movec tc,d1?
764     beq.s movectcd1
765    
766     bra pv_unhandled
767    
768     ; movec cacr,d0
769     moveccacrd0 move.l (sp)+,d0
770     move.l #$3111,d0 ;All caches and bursts on
771     addq.l #4,2(sp)
772     rte
773    
774     ; movec cacr,d1
775     moveccacrd1 move.l (sp)+,d0
776     move.l #$3111,d1 ;All caches and bursts on
777     addq.l #4,2(sp)
778     rte
779    
780     ; movec vbr,a0
781     movecvbra0 move.l (sp)+,d0
782     sub.l a0,a0 ;VBR always appears to be at 0
783     addq.l #4,2(sp)
784     rte
785    
786     ; movec vbr,a1
787     movecvbra1 move.l (sp)+,d0
788     sub.l a1,a1 ;VBR always appears to be at 0
789     addq.l #4,2(sp)
790     rte
791    
792     ; movec tc,d0
793     movectcd0 addq.l #4,sp
794     moveq #0,d0 ;MMU is always off
795     addq.l #4,2(sp)
796     rte
797    
798     ; movec tc,d1
799     movectcd1 addq.l #4,sp
800     moveq #0,d1 ;MMU is always off
801     addq.l #4,2(sp)
802     rte
803    
804     ; movec x,cr
805     movectocr move.w ([6,sp],2),d0 ;Get next instruction word
806    
807     cmp.w #$0801,d0 ;movec d0,vbr?
808     beq.s movectovbr
809     cmp.w #$0002,d0 ;movec d0,cacr?
810     beq.s movectocacr
811     cmp.w #$1002,d0 ;movec d1,cacr?
812     beq.s movectocacr
813    
814     bra pv_unhandled
815    
816     ; movec x,vbr
817     movectovbr move.l (sp)+,d0 ;Ignore moves to VBR
818     addq.l #4,2(sp)
819     rte
820    
821     ; movec dx,cacr
822     movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches
823     move.l _SysBase,a6
824     JSRLIB CacheClearU
825     movem.l (sp)+,d1/a0-a1/a6
826     move.l (sp)+,d0
827     addq.l #4,2(sp)
828     rte
829    
830     ; cpusha
831     cpushadc
832     cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches
833     move.l _SysBase,a6
834     JSRLIB CacheClearU
835     movem.l (sp)+,d1/a0-a1/a6
836     move.l (sp)+,d0
837     addq.l #2,2(sp)
838     rte
839    
840     END