ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.8
Committed: 2001-01-25T22:24:36Z (23 years, 4 months ago) by cebix
Branch: MAIN
Changes since 1.7: +26 -0 lines
Log Message:
- AmigaOS: implemented XPRAM watchdog thread
- AmigaOS: disabled 68060 Super Bypass mode because of CPU bug triggered
  by MacOS 8
- minor documentation updates

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