ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.12
Committed: 2002-01-15T14:58:34Z (22 years, 4 months ago) by cebix
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.11: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

File Contents

# Content
1 *
2 * asm_support.asm - AmigaOS utility functions in assembly language
3 *
4 * Basilisk II (C) 1997-2002 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 and.w #$d8ff,_EmulatedSR ;enable interrupts in EmulatedSR
320
321 move.l $28.w,-(sp) ;Jump to MacOS exception handler
322 rts
323
324 *
325 * Illegal address handler
326 *
327
328 doilladdr move.l a0,(sp) ;Save a0
329
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 *
345 * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
346 * to execute extended opcodes (see emul_op.h)
347 *
348
349 doillinstr movem.l a0/d0,-(sp)
350 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 1$ move.l a6,(sp) ;Save a6
370 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 beq movefromsrsp
425
426 cmp.w #$f327,d0 ;fsave -(sp)?
427 beq fsavepush
428 cmp.w #$f35f,d0 ;frestore (sp)+?
429 beq frestorepop
430 cmp.w #$f32d,d0 ;fsave xxx(a5) ?
431 beq fsavea5
432 cmp.w #$f36d,d0 ;frestore xxx(a5) ?
433 beq frestorea5
434
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 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 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 and.w #$e700,d0 ;Extract supervisor bits
532 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 and.w #$e700,d0 ;Extract supervisor bits
558 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 and.w #$e700,d0 ;Extract supervisor bits
570 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 move.l #$41000000,-(a0) ;Push idle frame
641 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 ; 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 ; 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 addq.l #4,a0 ;Nothing to do...
661 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 ; frestore xxx(a5)
667 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 move.l usp,a0 ;Get user stack pointer
676
677 move.w (a0)+,d0 ;Get SR from user stack
678 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 move.w d0,_EmulatedSR ;And save them
682 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 2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack
694 1$ dbf d0,2$
695
696 move.l a0,usp ;Update USP
697 movem.l (sp)+,a0/a1 ;Restore a0 and a1
698 move.l (sp)+,d0 ;Restore d0
699 rte
700
701 ; 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 ; 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 and.w #$e700,d0
782 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 cmp.w #$1801,d0 ;movec vbr,d1?
827 beq movecvbrd1
828 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 cmp.w #$1000,d0 ;movec sfc,d1?
837 beq movecsfcd1
838 cmp.w #$1001,d0 ;movec dfc,d1?
839 beq movecdfcd1
840 cmp.w #$0806,d0 ;movec urp,d0?
841 beq movecurpd0
842 cmp.w #$0807,d0 ;movec srp,d0?
843 beq.s movecsrpd0
844 cmp.w #$0004,d0 ;movec itt0,d0
845 beq.s movecitt0d0
846 cmp.w #$0005,d0 ;movec itt1,d0
847 beq.s movecitt1d0
848 cmp.w #$0006,d0 ;movec dtt0,d0
849 beq.s movecdtt0d0
850 cmp.w #$0007,d0 ;movec dtt1,d0
851 beq.s movecdtt1d0
852
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 ; 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 ; 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 ; 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 ; movec sfc,d1 +jl+
898 movecsfcd1 move.l (sp)+,d0 ;Restore d0
899 moveq #0,d1
900 addq.l #4,2(sp)
901 rte
902
903 ; movec dfc,d1 +jl+
904 movecdfcd1 move.l (sp)+,d0 ;Restore d0
905 moveq #0,d1
906 addq.l #4,2(sp)
907 rte
908
909 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 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 ; 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 cmp.w #$1801,d0 ;movec d1,vbr?
926 beq.s movectovbr
927 cmp.w #$0002,d0 ;movec d0,cacr?
928 beq.s movectocacr
929 cmp.w #$1002,d0 ;movec d1,cacr?
930 beq.s movectocacr
931 cmp.w #$1000,d0 ;movec d1,sfc?
932 beq.s movectoxfc
933 cmp.w #$1001,d0 ;movec d1,dfc?
934 beq.s movectoxfc
935
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 ; movec x,sfc
953 ; movec x,dfc
954 movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC
955 addq.l #4,2(sp)
956 rte
957
958 ; 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
968 ; move usp,a1 +jl+
969 moveuspa1 move.l (sp)+,d0
970 move usp,a1
971 addq.l #2,2(sp)
972 rte
973
974 ; move usp,a0 +jl+
975 moveuspa0 move.l (sp)+,d0
976 move usp,a0
977 addq.l #2,2(sp)
978 rte
979
980 ; move a1,usp +jl+
981 moved1usp move.l (sp)+,d0
982 move a1,usp
983 addq.l #2,2(sp)
984 rte
985
986 ;
987 ; Trigger NMI (Pop up debugger)
988 ;
989
990 _AsmTriggerNMI move.l d0,-(sp) ;Save d0
991 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
1005 END