ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/AmigaOS/asm_support.asm
Revision: 1.5
Committed: 2000-08-20T14:08:41Z (23 years, 10 months ago) by jlachmann
Branch: MAIN
Changes since 1.4: +292 -21 lines
Log Message:
added MacsBug Support -jl-

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