ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.6
Committed: 2000-10-11T17:55:05Z (23 years, 8 months ago) by cebix
Branch: MAIN
Changes since 1.5: +24 -24 lines
Log Message:
- added a few more emulated privileged instructions to NetBSD/m68k
- tried to make VOSF run under NetBSD/m68k, little success (shows stripes and
  sometimes crashes)

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