ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.7
Committed: 2000-10-17T12:24:58Z (24 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.6: +21 -43 lines
Log Message:
- FPU is now available under NetBSD/m68k
- main_unix.cpp: added more emulated privileged instructions

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