ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.11
Committed: 2001-10-14T18:00:44Z (23 years, 1 month ago) by jlachmann
Branch: MAIN
Changes since 1.10: +2 -0 lines
Log Message:
AmigaOS: added Video depth/resolution switching

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 jlachmann 1.11 and.w #$d8ff,_EmulatedSR ;enable interrupts in EmulatedSR
320    
321 cebix 1.1 move.l $28.w,-(sp) ;Jump to MacOS exception handler
322     rts
323    
324 jlachmann 1.5 *
325     * Illegal address handler
326     *
327    
328 cebix 1.7 doilladdr move.l a0,(sp) ;Save a0
329 jlachmann 1.5
330     move.l usp,a0 ;Get user stack pointer
331     move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack
332     move.l 2*4(sp),-(a0)
333     move.l 1*4(sp),-(a0)
334     move.l a0,usp ;Update USP
335     move.l (sp)+,a0 ;Restore a0
336    
337     lea 6*2(sp),sp ;Remove exception frame from supervisor stack
338     andi #$d8ff,sr ;Switch to user mode, enable interrupts
339    
340     move.l $0c.w,-(sp) ;Jump to MacOS exception handler
341     rts
342    
343    
344 cebix 1.1 *
345     * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
346     * to execute extended opcodes (see emul_op.h)
347     *
348    
349 cebix 1.7 doillinstr movem.l a0/d0,-(sp)
350 jlachmann 1.5 move.w ([6+2*4,sp]),d0
351     and.w #$ff00,d0
352     cmp.w #$7100,d0
353     movem.l (sp)+,a0/d0
354     beq 1$
355    
356     move.l a0,(sp) ;Save a0
357     move.l usp,a0 ;Get user stack pointer
358     move.l 8(sp),-(a0) ;Copy stack frame to user stack
359     move.l 4(sp),-(a0)
360     move.l a0,usp ;Update USP
361     move.l (sp)+,a0 ;Restore a0
362    
363     add.w #3*4,sp ;Remove exception frame from supervisor stack
364     andi #$d8ff,sr ;Switch to user mode, enable interrupts
365    
366     move.l $10.w,-(sp) ;Jump to MacOS exception handler
367     rts
368    
369 cebix 1.7 1$ move.l a6,(sp) ;Save a6
370 cebix 1.1 move.l usp,a6 ;Get user stack pointer
371    
372     move.l a6,-10(a6) ;Push USP (a7)
373     move.l 6(sp),-(a6) ;Push PC
374     move.w 4(sp),-(a6) ;Push SR
375     subq.l #4,a6 ;Skip saved USP
376     move.l (sp),-(a6) ;Push old a6
377     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
378     move.l a6,usp ;Update USP
379    
380     add.w #12,sp ;Remove exception frame from supervisor stack
381     andi #$d8ff,sr ;Switch to user mode, enable interrupts
382    
383     move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp
384     jsr _IllInstrHandler
385     addq.l #4,sp
386    
387     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
388     addq.l #4,sp ;Skip saved USP (!!)
389     rtr ;Return from exception
390    
391     *
392     * Privilege violation handler: MacOS runs in supervisor mode,
393     * so we have to emulate certain privileged instructions
394     *
395    
396     doprivviol move.l d0,(sp) ;Save d0
397     move.w ([6,sp]),d0 ;Get instruction word
398    
399     cmp.w #$40e7,d0 ;move sr,-(sp)?
400     beq pushsr
401     cmp.w #$46df,d0 ;move (sp)+,sr?
402     beq popsr
403    
404     cmp.w #$007c,d0 ;ori #xxxx,sr?
405     beq orisr
406     cmp.w #$027c,d0 ;andi #xxxx,sr?
407     beq andisr
408    
409     cmp.w #$46fc,d0 ;move #xxxx,sr?
410     beq movetosrimm
411    
412     cmp.w #$46ef,d0 ;move (xxxx,sp),sr?
413     beq movetosrsprel
414     cmp.w #$46d8,d0 ;move (a0)+,sr?
415     beq movetosra0p
416     cmp.w #$46d9,d0 ;move (a1)+,sr?
417     beq movetosra1p
418    
419     cmp.w #$40f8,d0 ;move sr,xxxx.w?
420     beq movefromsrabs
421     cmp.w #$40d0,d0 ;move sr,(a0)?
422     beq movefromsra0
423     cmp.w #$40d7,d0 ;move sr,(sp)?
424 cebix 1.6 beq movefromsrsp
425 cebix 1.1
426     cmp.w #$f327,d0 ;fsave -(sp)?
427     beq fsavepush
428     cmp.w #$f35f,d0 ;frestore (sp)+?
429     beq frestorepop
430 jlachmann 1.5 cmp.w #$f32d,d0 ;fsave xxx(a5) ?
431     beq fsavea5
432     cmp.w #$f36d,d0 ;frestore xxx(a5) ?
433     beq frestorea5
434 cebix 1.1
435     cmp.w #$4e73,d0 ;rte?
436     beq pvrte
437    
438     cmp.w #$40c0,d0 ;move sr,d0?
439     beq movefromsrd0
440     cmp.w #$40c1,d0 ;move sr,d1?
441     beq movefromsrd1
442     cmp.w #$40c2,d0 ;move sr,d2?
443     beq movefromsrd2
444     cmp.w #$40c3,d0 ;move sr,d3?
445     beq movefromsrd3
446     cmp.w #$40c4,d0 ;move sr,d4?
447     beq movefromsrd4
448     cmp.w #$40c5,d0 ;move sr,d5?
449     beq movefromsrd5
450     cmp.w #$40c6,d0 ;move sr,d6?
451     beq movefromsrd6
452     cmp.w #$40c7,d0 ;move sr,d7?
453     beq movefromsrd7
454    
455     cmp.w #$46c0,d0 ;move d0,sr?
456     beq movetosrd0
457     cmp.w #$46c1,d0 ;move d1,sr?
458     beq movetosrd1
459     cmp.w #$46c2,d0 ;move d2,sr?
460     beq movetosrd2
461     cmp.w #$46c3,d0 ;move d3,sr?
462     beq movetosrd3
463     cmp.w #$46c4,d0 ;move d4,sr?
464     beq movetosrd4
465     cmp.w #$46c5,d0 ;move d5,sr?
466     beq movetosrd5
467     cmp.w #$46c6,d0 ;move d6,sr?
468     beq movetosrd6
469     cmp.w #$46c7,d0 ;move d7,sr?
470     beq movetosrd7
471    
472     cmp.w #$4e7a,d0 ;movec cr,x?
473     beq movecfromcr
474     cmp.w #$4e7b,d0 ;movec x,cr?
475     beq movectocr
476    
477     cmp.w #$f478,d0 ;cpusha dc?
478     beq cpushadc
479     cmp.w #$f4f8,d0 ;cpusha dc/ic?
480     beq cpushadcic
481    
482 jlachmann 1.5 cmp.w #$4e69,d0 ;move usp,a1
483     beq moveuspa1
484     cmp.w #$4e68,d0 ;move usp,a0
485     beq moveuspa0
486    
487     cmp.w #$4e61,d0 ;move a1,usp
488     beq moved1usp
489    
490 cebix 1.1 pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp
491     move.l a6,(sp) ;Save a6
492     move.l usp,a6 ;Get user stack pointer
493    
494     move.l a6,-10(a6) ;Push USP (a7)
495     move.l 6(sp),-(a6) ;Push PC
496     move.w 4(sp),-(a6) ;Push SR
497     subq.l #4,a6 ;Skip saved USP
498     move.l (sp),-(a6) ;Push old a6
499     movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
500     move.l a6,usp ;Update USP
501    
502     add.w #12,sp ;Remove exception frame from supervisor stack
503     andi #$d8ff,sr ;Switch to user mode, enable interrupts
504    
505     move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp
506     jsr _PrivViolHandler
507     addq.l #4,sp
508    
509     movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
510     addq.l #4,sp ;Skip saved USP
511     rtr ;Return from exception
512    
513     ; move sr,-(sp)
514     pushsr move.l a0,-(sp) ;Save a0
515     move.l usp,a0 ;Get user stack pointer
516     move.w 8(sp),d0 ;Get CCR from exception stack frame
517     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
518     move.w d0,-(a0) ;Store SR on user stack
519     move.l a0,usp ;Update USP
520     move.l (sp)+,a0 ;Restore a0
521     move.l (sp)+,d0 ;Restore d0
522     addq.l #2,2(sp) ;Skip instruction
523     rte
524    
525     ; move (sp)+,sr
526     popsr move.l a0,-(sp) ;Save a0
527     move.l usp,a0 ;Get user stack pointer
528     move.w (a0)+,d0 ;Get SR from user stack
529     move.w d0,8(sp) ;Store into CCR on exception stack frame
530     and.w #$00ff,8(sp)
531 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
532 cebix 1.1 move.w d0,_EmulatedSR ;And save them
533    
534     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
535     bne 1$
536     tst.l _InterruptFlags
537     beq 1$
538     movem.l d0-d1/a0-a1/a6,-(sp)
539     move.l _SysBase,a6
540     move.l _MainTask,a1
541     move.l _IRQSigMask,d0
542     JSRLIB Signal
543     movem.l (sp)+,d0-d1/a0-a1/a6
544     1$
545     move.l a0,usp ;Update USP
546     move.l (sp)+,a0 ;Restore a0
547     move.l (sp)+,d0 ;Restore d0
548     addq.l #2,2(sp) ;Skip instruction
549     rte
550    
551     ; ori #xxxx,sr
552     orisr move.w 4(sp),d0 ;Get CCR from stack
553     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
554     or.w ([6,sp],2),d0 ;Or with immediate value
555     move.w d0,4(sp) ;Store into CCR on stack
556     and.w #$00ff,4(sp)
557 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
558 cebix 1.1 move.w d0,_EmulatedSR ;And save them
559     move.l (sp)+,d0 ;Restore d0
560     addq.l #4,2(sp) ;Skip instruction
561     rte
562    
563     ; andi #xxxx,sr
564     andisr move.w 4(sp),d0 ;Get CCR from stack
565     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
566     and.w ([6,sp],2),d0 ;And with immediate value
567     storesr4 move.w d0,4(sp) ;Store into CCR on stack
568     and.w #$00ff,4(sp)
569 jlachmann 1.5 and.w #$e700,d0 ;Extract supervisor bits
570 cebix 1.1 move.w d0,_EmulatedSR ;And save them
571    
572     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
573     bne.s 1$
574     tst.l _InterruptFlags
575     beq.s 1$
576     movem.l d0-d1/a0-a1/a6,-(sp)
577     move.l _SysBase,a6
578     move.l _MainTask,a1
579     move.l _IRQSigMask,d0
580     JSRLIB Signal
581     movem.l (sp)+,d0-d1/a0-a1/a6
582     1$ move.l (sp)+,d0 ;Restore d0
583     addq.l #4,2(sp) ;Skip instruction
584     rte
585    
586     ; move #xxxx,sr
587     movetosrimm move.w ([6,sp],2),d0 ;Get immediate value
588     bra.s storesr4
589    
590     ; move (xxxx,sp),sr
591     movetosrsprel move.l a0,-(sp) ;Save a0
592     move.l usp,a0 ;Get user stack pointer
593     move.w ([10,sp],2),d0 ;Get offset
594     move.w (a0,d0.w),d0 ;Read word
595     move.l (sp)+,a0 ;Restore a0
596     bra.s storesr4
597    
598     ; move (a0)+,sr
599     movetosra0p move.w (a0)+,d0 ;Read word
600     bra storesr2
601    
602     ; move (a1)+,sr
603     movetosra1p move.w (a1)+,d0 ;Read word
604     bra storesr2
605    
606     ; move sr,xxxx.w
607     movefromsrabs move.l a0,-(sp) ;Save a0
608     move.w ([10,sp],2),a0 ;Get address
609     move.w 8(sp),d0 ;Get CCR
610     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
611     move.w d0,(a0) ;Store SR
612     move.l (sp)+,a0 ;Restore a0
613     move.l (sp)+,d0 ;Restore d0
614     addq.l #4,2(sp) ;Skip instruction
615     rte
616    
617     ; move sr,(a0)
618     movefromsra0 move.w 4(sp),d0 ;Get CCR
619     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
620     move.w d0,(a0) ;Store SR
621     move.l (sp)+,d0 ;Restore d0
622     addq.l #2,2(sp) ;Skip instruction
623     rte
624    
625     ; move sr,(sp)
626     movefromsrsp move.l a0,-(sp) ;Save a0
627     move.l usp,a0 ;Get user stack pointer
628     move.w 8(sp),d0 ;Get CCR
629     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
630     move.w d0,(a0) ;Store SR
631     move.l (sp)+,a0 ;Restore a0
632     move.l (sp)+,d0 ;Restore d0
633     addq.l #2,2(sp) ;Skip instruction
634     rte
635    
636     ; fsave -(sp)
637     fsavepush move.l (sp),d0 ;Restore d0
638     move.l a0,(sp) ;Save a0
639     move.l usp,a0 ;Get user stack pointer
640 cebix 1.10 move.l #$41000000,-(a0) ;Push idle frame
641 cebix 1.1 move.l a0,usp ;Update USP
642     move.l (sp)+,a0 ;Restore a0
643     addq.l #2,2(sp) ;Skip instruction
644     rte
645    
646 cebix 1.10 ; fsave xxx(a5)
647     fsavea5 move.l (sp),d0 ;Restore d0
648     move.l a0,(sp) ;Save a0
649     move.l a5,a0 ;Get base register
650     add.w ([6,sp],2),a0 ;Add offset to base register
651     move.l #$41000000,(a0) ;Push idle frame
652     move.l (sp)+,a0 ;Restore a0
653     addq.l #4,2(sp) ;Skip instruction
654     rte
655    
656 cebix 1.1 ; frestore (sp)+
657     frestorepop move.l (sp),d0 ;Restore d0
658     move.l a0,(sp) ;Save a0
659     move.l usp,a0 ;Get user stack pointer
660 cebix 1.10 addq.l #4,a0 ;Nothing to do...
661 cebix 1.1 move.l a0,usp ;Update USP
662     move.l (sp)+,a0 ;Restore a0
663     addq.l #2,2(sp) ;Skip instruction
664     rte
665    
666 cebix 1.10 ; frestore xxx(a5)
667 jlachmann 1.5 frestorea5 move.l (sp),d0 ;Restore d0
668     move.l a0,(sp) ;Save a0
669     move.l (sp)+,a0 ;Restore a0
670     addq.l #4,2(sp) ;Skip instruction
671     rte
672    
673     ; rte
674     pvrte movem.l a0/a1,-(sp) ;Save a0 and a1
675 cebix 1.1 move.l usp,a0 ;Get user stack pointer
676 jlachmann 1.5
677 cebix 1.1 move.w (a0)+,d0 ;Get SR from user stack
678 jlachmann 1.5 move.w d0,8+4(sp) ;Store into CCR on exception stack frame
679     and.w #$c0ff,8+4(sp)
680     and.w #$e700,d0 ;Extract supervisor bits
681 cebix 1.1 move.w d0,_EmulatedSR ;And save them
682 jlachmann 1.5 move.l (a0)+,10+4(sp) ;Store return address in exception stack frame
683    
684     move.w (a0)+,d0 ;get format word
685     lsr.w #7,d0 ;get stack frame Id
686     lsr.w #4,d0
687     and.w #$001e,d0
688     move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length
689     subq.w #4,d0 ; count only extra words
690     lea 16+4(sp),a1 ; destination address (in supervisor stack)
691     bra 1$
692    
693 cebix 1.7 2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack
694     1$ dbf d0,2$
695 jlachmann 1.5
696 cebix 1.1 move.l a0,usp ;Update USP
697 jlachmann 1.5 movem.l (sp)+,a0/a1 ;Restore a0 and a1
698 cebix 1.1 move.l (sp)+,d0 ;Restore d0
699     rte
700    
701 jlachmann 1.5 ; sizes of exceptions stack frames
702     StackFormatTable:
703     dc.w 4 ; Four-word stack frame, format $0
704     dc.w 4 ; Throwaway four-word stack frame, format $1
705     dc.w 6 ; Six-word stack frame, format $2
706     dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3
707     dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4
708     dc.w 4 ; Format $5
709     dc.w 4 ; Format $6
710     dc.w 30 ; MC68040 access error stack frame, Format $7
711     dc.w 29 ; MC68010 bus and address error stack frame, format $8
712     dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9
713     dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a
714     dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b
715     dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c
716     dc.w 4 ; Format $d
717     dc.w 4 ; Format $e
718     dc.w 4 ; Format $f
719    
720 cebix 1.1 ; move sr,dx
721     movefromsrd0 addq.l #4,sp ;Skip saved d0
722     moveq #0,d0
723     move.w (sp),d0 ;Get CCR
724     or.w _EmulatedSR,d0 ;Add emulated supervisor bits
725     addq.l #2,2(sp) ;Skip instruction
726     rte
727    
728     movefromsrd1 move.l (sp)+,d0
729     moveq #0,d1
730     move.w (sp),d1
731     or.w _EmulatedSR,d1
732     addq.l #2,2(sp)
733     rte
734    
735     movefromsrd2 move.l (sp)+,d0
736     moveq #0,d2
737     move.w (sp),d2
738     or.w _EmulatedSR,d2
739     addq.l #2,2(sp)
740     rte
741    
742     movefromsrd3 move.l (sp)+,d0
743     moveq #0,d3
744     move.w (sp),d3
745     or.w _EmulatedSR,d3
746     addq.l #2,2(sp)
747     rte
748    
749     movefromsrd4 move.l (sp)+,d0
750     moveq #0,d4
751     move.w (sp),d4
752     or.w _EmulatedSR,d4
753     addq.l #2,2(sp)
754     rte
755    
756     movefromsrd5 move.l (sp)+,d0
757     moveq #0,d5
758     move.w (sp),d5
759     or.w _EmulatedSR,d5
760     addq.l #2,2(sp)
761     rte
762    
763     movefromsrd6 move.l (sp)+,d0
764     moveq #0,d6
765     move.w (sp),d6
766     or.w _EmulatedSR,d6
767     addq.l #2,2(sp)
768     rte
769    
770     movefromsrd7 move.l (sp)+,d0
771     moveq #0,d7
772     move.w (sp),d7
773     or.w _EmulatedSR,d7
774     addq.l #2,2(sp)
775     rte
776    
777     ; move dx,sr
778     movetosrd0 move.l (sp),d0
779     storesr2 move.w d0,4(sp)
780     and.w #$00ff,4(sp)
781 jlachmann 1.5 and.w #$e700,d0
782 cebix 1.1 move.w d0,_EmulatedSR
783    
784     and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
785     bne.s 1$
786     tst.l _InterruptFlags
787     beq.s 1$
788     movem.l d0-d1/a0-a1/a6,-(sp)
789     move.l _SysBase,a6
790     move.l _MainTask,a1
791     move.l _IRQSigMask,d0
792     JSRLIB Signal
793     movem.l (sp)+,d0-d1/a0-a1/a6
794     1$ move.l (sp)+,d0
795     addq.l #2,2(sp)
796     rte
797    
798     movetosrd1 move.l d1,d0
799     bra.s storesr2
800    
801     movetosrd2 move.l d2,d0
802     bra.s storesr2
803    
804     movetosrd3 move.l d3,d0
805     bra.s storesr2
806    
807     movetosrd4 move.l d4,d0
808     bra.s storesr2
809    
810     movetosrd5 move.l d5,d0
811     bra.s storesr2
812    
813     movetosrd6 move.l d6,d0
814     bra.s storesr2
815    
816     movetosrd7 move.l d7,d0
817     bra.s storesr2
818    
819     ; movec cr,x
820     movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word
821    
822     cmp.w #$8801,d0 ;movec vbr,a0?
823     beq.s movecvbra0
824     cmp.w #$9801,d0 ;movec vbr,a1?
825     beq.s movecvbra1
826 jlachmann 1.5 cmp.w #$1801,d0 ;movec vbr,d1?
827     beq movecvbrd1
828 cebix 1.1 cmp.w #$0002,d0 ;movec cacr,d0?
829     beq.s moveccacrd0
830     cmp.w #$1002,d0 ;movec cacr,d1?
831     beq.s moveccacrd1
832     cmp.w #$0003,d0 ;movec tc,d0?
833     beq.s movectcd0
834     cmp.w #$1003,d0 ;movec tc,d1?
835     beq.s movectcd1
836 cebix 1.6 cmp.w #$1000,d0 ;movec sfc,d1?
837 jlachmann 1.5 beq movecsfcd1
838 cebix 1.6 cmp.w #$1001,d0 ;movec dfc,d1?
839 jlachmann 1.5 beq movecdfcd1
840 cebix 1.6 cmp.w #$0806,d0 ;movec urp,d0?
841 jlachmann 1.5 beq movecurpd0
842 cebix 1.6 cmp.w #$0807,d0 ;movec srp,d0?
843 jlachmann 1.5 beq.s movecsrpd0
844 cebix 1.6 cmp.w #$0004,d0 ;movec itt0,d0
845 jlachmann 1.5 beq.s movecitt0d0
846 cebix 1.6 cmp.w #$0005,d0 ;movec itt1,d0
847 jlachmann 1.5 beq.s movecitt1d0
848 cebix 1.6 cmp.w #$0006,d0 ;movec dtt0,d0
849 jlachmann 1.5 beq.s movecdtt0d0
850 cebix 1.6 cmp.w #$0007,d0 ;movec dtt1,d0
851 jlachmann 1.5 beq.s movecdtt1d0
852 cebix 1.1
853     bra pv_unhandled
854    
855     ; movec cacr,d0
856     moveccacrd0 move.l (sp)+,d0
857     move.l #$3111,d0 ;All caches and bursts on
858     addq.l #4,2(sp)
859     rte
860    
861     ; movec cacr,d1
862     moveccacrd1 move.l (sp)+,d0
863     move.l #$3111,d1 ;All caches and bursts on
864     addq.l #4,2(sp)
865     rte
866    
867     ; movec vbr,a0
868     movecvbra0 move.l (sp)+,d0
869     sub.l a0,a0 ;VBR always appears to be at 0
870     addq.l #4,2(sp)
871     rte
872    
873     ; movec vbr,a1
874     movecvbra1 move.l (sp)+,d0
875     sub.l a1,a1 ;VBR always appears to be at 0
876     addq.l #4,2(sp)
877     rte
878    
879 jlachmann 1.5 ; movec vbr,d1
880     movecvbrd1 move.l (sp)+,d0
881     moveq.l #0,d1 ;VBR always appears to be at 0
882     addq.l #4,2(sp)
883     rte
884    
885 cebix 1.1 ; movec tc,d0
886     movectcd0 addq.l #4,sp
887     moveq #0,d0 ;MMU is always off
888     addq.l #4,2(sp)
889     rte
890    
891 jlachmann 1.5 ; movec tc,d1 +jl+
892     movectcd1 move.l (sp)+,d0 ;Restore d0
893     moveq #0,d1 ;MMU is always off
894     addq.l #4,2(sp)
895     rte
896    
897 cebix 1.6 ; movec sfc,d1 +jl+
898 cebix 1.7 movecsfcd1 move.l (sp)+,d0 ;Restore d0
899 cebix 1.6 moveq #0,d1
900 jlachmann 1.5 addq.l #4,2(sp)
901     rte
902    
903 cebix 1.6 ; movec dfc,d1 +jl+
904 cebix 1.7 movecdfcd1 move.l (sp)+,d0 ;Restore d0
905 cebix 1.6 moveq #0,d1
906 cebix 1.1 addq.l #4,2(sp)
907     rte
908    
909 cebix 1.7 movecurpd0 ; movec urp,d0 +jl+
910     movecsrpd0 ; movec srp,d0
911     movecitt0d0 ; movec itt0,d0
912     movecitt1d0 ; movec itt1,d0
913     movecdtt0d0 ; movec dtt0,d0
914     movecdtt1d0 ; movec dtt1,d0
915 jlachmann 1.5 addq.l #4,sp
916     moveq.l #0,d0 ;MMU is always off
917     addq.l #4,2(sp) ;skip instruction
918     rte
919    
920 cebix 1.1 ; movec x,cr
921     movectocr move.w ([6,sp],2),d0 ;Get next instruction word
922    
923     cmp.w #$0801,d0 ;movec d0,vbr?
924     beq.s movectovbr
925 jlachmann 1.5 cmp.w #$1801,d0 ;movec d1,vbr?
926     beq.s movectovbr
927 cebix 1.1 cmp.w #$0002,d0 ;movec d0,cacr?
928     beq.s movectocacr
929     cmp.w #$1002,d0 ;movec d1,cacr?
930     beq.s movectocacr
931 cebix 1.6 cmp.w #$1000,d0 ;movec d1,sfc?
932 jlachmann 1.5 beq.s movectoxfc
933 cebix 1.6 cmp.w #$1001,d0 ;movec d1,dfc?
934 jlachmann 1.5 beq.s movectoxfc
935 cebix 1.1
936     bra pv_unhandled
937    
938     ; movec x,vbr
939     movectovbr move.l (sp)+,d0 ;Ignore moves to VBR
940     addq.l #4,2(sp)
941     rte
942    
943     ; movec dx,cacr
944     movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches
945     move.l _SysBase,a6
946     JSRLIB CacheClearU
947     movem.l (sp)+,d1/a0-a1/a6
948     move.l (sp)+,d0
949     addq.l #4,2(sp)
950     rte
951    
952 cebix 1.6 ; movec x,sfc
953     ; movec x,dfc
954 jlachmann 1.5 movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC
955     addq.l #4,2(sp)
956     rte
957    
958 cebix 1.1 ; cpusha
959     cpushadc
960     cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches
961     move.l _SysBase,a6
962     JSRLIB CacheClearU
963     movem.l (sp)+,d1/a0-a1/a6
964     move.l (sp)+,d0
965     addq.l #2,2(sp)
966     rte
967 jlachmann 1.5
968     ; move usp,a1 +jl+
969 cebix 1.7 moveuspa1 move.l (sp)+,d0
970 jlachmann 1.5 move usp,a1
971     addq.l #2,2(sp)
972     rte
973    
974     ; move usp,a0 +jl+
975 cebix 1.7 moveuspa0 move.l (sp)+,d0
976 jlachmann 1.5 move usp,a0
977     addq.l #2,2(sp)
978     rte
979    
980     ; move a1,usp +jl+
981 cebix 1.7 moved1usp move.l (sp)+,d0
982 jlachmann 1.5 move a1,usp
983     addq.l #2,2(sp)
984     rte
985    
986     ;
987     ; Trigger NMI (Pop up debugger)
988     ;
989    
990 cebix 1.7 _AsmTriggerNMI move.l d0,-(sp) ;Save d0
991 jlachmann 1.5 move.w #$007c,-(sp) ;Yes, fake NMI stack frame
992     pea 1$
993     move.w _EmulatedSR,d0
994     and.w #$f8ff,d0 ;Set interrupt level in SR
995     move.w d0,-(sp)
996     move.w d0,_EmulatedSR
997    
998     move.l $7c.w,-(sp) ;Jump to MacOS NMI handler
999     rts
1000    
1001     1$ move.l (sp)+,d0 ;Restore d0
1002     rts
1003    
1004 cebix 1.1
1005     END