ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.1
Committed: 1999-10-03T14:16:25Z (24 years, 8 months ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

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