ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.10
Committed: 2001-06-30T12:58:07Z (23 years, 4 months ago) by cebix
Branch: MAIN
Changes since 1.9: +13 -76 lines
Log Message:
- fixed compilation problems under AmigaOS
- fsave/frestore on AmigaOS and NetBSD/m68k always use a 68882/68040-style
  FPU frame, eliminating the need for 68060 FPU patches

File Contents

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