ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.8
Committed: 2001-01-25T22:24:36Z (23 years, 4 months ago) by cebix
Branch: MAIN
Changes since 1.7: +26 -0 lines
Log Message:
- AmigaOS: implemented XPRAM watchdog thread
- AmigaOS: disabled 68060 Super Bypass mode because of CPU bug triggered
  by MacOS 8
- minor documentation updates

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