--- BasiliskII/src/AmigaOS/asm_support.asm 2000/07/22 16:00:34 1.4 +++ BasiliskII/src/AmigaOS/asm_support.asm 2002/06/23 08:27:05 1.13 @@ -1,7 +1,7 @@ * * asm_support.asm - AmigaOS utility functions in assembly language * -* Basilisk II (C) 1997-1999 Christian Bauer +* Basilisk II (C) 1997-2001 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,16 +25,17 @@ INCLUDE "dos/dos.i" INCLUDE "devices/timer.i" + INCLUDE "asmsupp.i" + XDEF _AtomicAnd XDEF _AtomicOr XDEF _MoveVBR + XDEF _DisableSuperBypass XDEF _Execute68k XDEF _Execute68kTrap XDEF _TrapHandlerAsm XDEF _ExceptionHandlerAsm - XDEF _Scod060Patch1 - XDEF _Scod060Patch2 - XDEF _ThInitFPUPatch + XDEF _AsmTriggerNMI XREF _OldTrapHandler XREF _OldExceptionHandler @@ -47,8 +48,16 @@ XREF _SysBase XREF _quit_emulator +INFO_LEVEL equ 0 + SECTION text,CODE + MACHINE 68020 + + IFGE INFO_LEVEL +subSysName: dc.b '+',0 + ENDIF + * * Atomic bit operations (don't trust the compiler) * @@ -106,6 +115,29 @@ setvbr movec d0,vbr rte * +* Disable 68060 Super Bypass mode +* + +_DisableSuperBypass + movem.l d0-d1/a0-a1/a5-a6,-(sp) + move.l _SysBase,a6 + + lea dissb,a5 + JSRLIB Supervisor + + movem.l (sp)+,d0-d1/a0-a1/a5-a6 + rts + + MACHINE 68060 + +dissb movec pcr,d0 + bset #5,d0 + movec d0,pcr + rte + + MACHINE 68020 + +* * Execute 68k subroutine (must be ended with rts) * r->a[7] and r->sr are unused! * @@ -183,10 +215,10 @@ _ExceptionHandlerAsm pea 1$ move.w _EmulatedSR,d0 move.w d0,-(sp) - or.w #$2100,d0 ;Set interrupt level in SR + or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode move.w d0,_EmulatedSR - move.l $64.w,a0 ;Jump to MacOS interrupt handler - jmp (a0) + move.l $64.w,-(sp) ;Jump to MacOS interrupt handler + rts 1$ move.l (sp)+,d0 ;Restore d0 rts @@ -217,76 +249,133 @@ _ExceptionHandlerAsm rts * -* Process Manager 68060 FPU patches +* Trap handler of main task * -_Scod060Patch1 fsave -(sp) ;Save FPU state - tst.b 2(sp) ;Null? - beq.s 1$ - fmovem.x fp0-fp7,-(sp) ;No, save FPU registers - fmove.l fpiar,-(sp) - fmove.l fpsr,-(sp) - fmove.l fpcr,-(sp) - pea -1 ;Push "FPU state saved" flag -1$ move.l d1,-(sp) - move.l d0,-(sp) - bsr.s 3$ ;Switch integer registers and stack - addq.l #8,sp - tst.b 2(sp) ;New FPU state null or "FPU state saved" flag set? - beq.s 2$ - addq.l #4,sp ;Flag set, skip it - fmove.l (sp)+,fpcr ;Restore FPU registers and state - fmove.l (sp)+,fpsr - fmove.l (sp)+,fpiar - fmovem.x (sp)+,fp0-fp7 -2$ frestore (sp)+ - movem.l (sp)+,d0-d1 - rts - -3$ move.l 4(sp),a0 ;Switch integer registers and stack - move sr,-(sp) - movem.l d2-d7/a2-a6,-(sp) - cmp.w #0,a0 - beq.s 4$ - move.l sp,(a0) -4$ move.l $36(sp),a0 - movem.l (a0)+,d2-d7/a2-a6 - move (a0)+,sr - move.l a0,sp +_TrapHandlerAsm: + IFEQ INFO_LEVEL-1002 + move.w ([6,a0]),-(sp) + move.w #0,-(sp) + move.l (4+6,a0),-(sp) + PUTMSG 0,'%s/TrapHandlerAsm: addr=%08lx opcode=%04lx' + lea (2*4,sp),sp + ENDC + + cmp.l #4,(sp) ;Illegal instruction? + beq.s doillinstr + cmp.l #10,(sp) ;A-Line exception? + beq.s doaline + cmp.l #8,(sp) ;Privilege violation? + beq.s doprivviol + + cmp.l #9,(sp) ;Trace? + beq dotrace + cmp.l #3,(sp) ;Illegal Address? + beq.s doilladdr + cmp.l #11,(sp) ;F-Line exception + beq.s dofline + + cmp.l #32,(sp) + blt 1$ + cmp.l #47,(sp) + ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors + +1$: + cmp.l #48,(sp) + blt 2$ + cmp.l #55,(sp) + ble doTrapFPU +2$: + IFEQ INFO_LEVEL-1009 + PUTMSG 0,'%s/TrapHandlerAsm: stack=%08lx %08lx %08lx %08lx' + ENDC + + move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler rts -_Scod060Patch2 move.l d0,-(sp) ;Create 68060 null frame on stack - move.l d0,-(sp) - move.l d0,-(sp) - frestore (sp)+ ;and load it +* +* TRAP #0 - 15 Instruction Vectors +* + +doTrapXX: + IFEQ INFO_LEVEL-1009 + PUTMSG 0,'%s/doTrapXX: stack=%08lx %08lx %08lx %08lx' + ENDC + + movem.l a0/d0,-(sp) ;Save a0,d0 + move.l (2*4,sp),d0 ;vector number 32-47 + + move.l usp,a0 ;Get user stack pointer + move.l (4*4,sp),-(a0) ;Copy 4-word stack frame to user stack + move.l (3*4,sp),-(a0) + move.l a0,usp ;Update USP + or.w #$2000,(a0) ;set Supervisor bit in SR + + lsl.l #2,d0 ;convert vector number to vector offset + move.l d0,a0 + move.l (a0),d0 ;get mac trap vector + + move.l usp,a0 ;Get user stack pointer + move.l d0,-(a0) ;store vector offset as return address + move.l a0,usp ;Update USP + + movem.l (sp)+,a0/d0 ;Restore a0,d0 + addq.l #4*2,sp ;Remove exception frame from supervisor stack + + andi #$d8ff,sr ;Switch to user mode, enable interrupts rts + * -* Thread Manager 68060 FPU patches +* FPU Exception Instruction Vectors * -_ThInitFPUPatch tst.b $40(a4) - bne.s 1$ - moveq #0,d0 ;Create 68060 null frame on stack - move.l d0,-(a3) - move.l d0,-(a3) - move.l d0,-(a3) -1$ rts +doTrapFPU: + move.l d0,(sp) + fmove.l fpcr,d0 + and.w #$00ff,d0 ;disable FPU exceptions + fmove.l d0,fpcr + move.l (sp)+,d0 ;Restore d0 + rte + * -* Trap handler of main task +* trace Vector * -_TrapHandlerAsm cmp.l #4,(sp) ;Illegal instruction? - beq.s doillinstr - cmp.l #10,(sp) ;A-Line exception? - beq.s doaline - cmp.l #8,(sp) ;Privilege violation? - beq.s doprivviol +dotrace + IFEQ INFO_LEVEL-1009 + PUTMSG 0,'%s/dotrace: stack=%08lx %08lx %08lx %08lx' + ENDC - move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler + move.l a0,(sp) ;Save a0 + move.l usp,a0 ;Get user stack pointer + + IFEQ INFO_LEVEL-1009 + move.l (12,a0),-(sp) + move.l (8,a0),-(sp) + move.l (4,a0),-(sp) + move.l (0,a0),-(sp) + move.l a0,-(sp) + move.l a7,-(sp) + PUTMSG 0,'%s/dotrace: sp=%08lx usp=%08lx (%08lx %08lx %08lx %08lx)' + lea (6*4,sp),sp + ENDC + + move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack + move.l 2*4(sp),-(a0) + move.l 1*4(sp),-(a0) + move.l a0,usp ;Update USP + or.w #$2000,(a0) ;set Supervisor bit in SR + move.l (sp)+,a0 ;Restore a0 + + lea 6*2(sp),sp ;Remove exception frame from supervisor stack + andi #$18ff,sr ;Switch to user mode, enable interrupts, disable trace + + move.l $24.w,-(sp) ;Jump to MacOS exception handler rts + * * A-Line handler: call MacOS A-Line handler * @@ -296,20 +385,98 @@ doaline move.l a0,(sp) ;Save a0 move.l 8(sp),-(a0) ;Copy stack frame to user stack move.l 4(sp),-(a0) move.l a0,usp ;Update USP + + or.w #$2000,(a0) ;set Supervisor bit in SR move.l (sp)+,a0 ;Restore a0 addq.l #8,sp ;Remove exception frame from supervisor stack andi #$d8ff,sr ;Switch to user mode, enable interrupts + and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR + move.l $28.w,-(sp) ;Jump to MacOS exception handler rts * +* F-Line handler: call F-Line exception handler +* + +dofline move.l a0,(sp) ;Save a0 + move.l usp,a0 ;Get user stack pointer + move.l 8(sp),-(a0) ;Copy stack frame to user stack + move.l 4(sp),-(a0) + move.l a0,usp ;Update USP + or.w #$2000,(a0) ;set Supervisor bit in SR + move.l (sp)+,a0 ;Restore a0 + + addq.l #8,sp ;Remove exception frame from supervisor stack + andi #$d8ff,sr ;Switch to user mode, enable interrupts + + and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR + + move.l $2c.w,-(sp) ;Jump to MacOS exception handler + rts + +* +* Illegal address handler +* + +doilladdr: + IFEQ INFO_LEVEL-1009 + PUTMSG 0,'%s/doilladdr: stack=%08lx %08lx %08lx %08lx' + ENDC + + move.l a0,(sp) ;Save a0 + + move.l usp,a0 ;Get user stack pointer + move.l 3*4(sp),-(a0) ;Copy 6-word stack frame to user stack + move.l 2*4(sp),-(a0) + move.l 1*4(sp),-(a0) + move.l a0,usp ;Update USP + or.w #$2000,(a0) ;set Supervisor bit in SR + move.l (sp)+,a0 ;Restore a0 + + lea 6*2(sp),sp ;Remove exception frame from supervisor stack + andi #$d8ff,sr ;Switch to user mode, enable interrupts + + move.l $0c.w,-(sp) ;Jump to MacOS exception handler + rts + + +* * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp()) * to execute extended opcodes (see emul_op.h) * -doillinstr move.l a6,(sp) ;Save a6 +doillinstr movem.l a0/d0,-(sp) + move.w ([6+2*4,sp]),d0 + and.w #$ff00,d0 + cmp.w #$7100,d0 + + IFEQ INFO_LEVEL-1009 + move.l d0,-(sp) + PUTMSG 0,'%s/doillinst: d0=%08lx stack=%08lx %08lx %08lx %08lx' + lea (1*4,sp),sp + ENDC + movem.l (sp)+,a0/d0 + beq 1$ + + move.l a0,(sp) ;Save a0 + move.l usp,a0 ;Get user stack pointer + move.l 8(sp),-(a0) ;Copy stack frame to user stack + move.l 4(sp),-(a0) + move.l a0,usp ;Update USP + or.w #$2000,(a0) ;set Supervisor bit in SR + move.l (sp)+,a0 ;Restore a0 + + add.w #3*4,sp ;Remove exception frame from supervisor stack + andi #$d8ff,sr ;Switch to user mode, enable interrupts + + move.l $10.w,-(sp) ;Jump to MacOS exception handler + rts + +1$: + move.l a6,(sp) ;Save a6 move.l usp,a6 ;Get user stack pointer move.l a6,-10(a6) ;Push USP (a7) @@ -339,6 +506,13 @@ doillinstr move.l a6,(sp) ;Save a6 doprivviol move.l d0,(sp) ;Save d0 move.w ([6,sp]),d0 ;Get instruction word + IFEQ INFO_LEVEL-1001 + move.w ([6,a0]),-(sp) + move.w #0,-(sp) + PUTMSG 0,'%s/doprivviol: opcode=%04lx' + lea (1*4,sp),sp + ENDC + cmp.w #$40e7,d0 ;move sr,-(sp)? beq pushsr cmp.w #$46df,d0 ;move (sp)+,sr? @@ -364,12 +538,16 @@ doprivviol move.l d0,(sp) ;Save d0 cmp.w #$40d0,d0 ;move sr,(a0)? beq movefromsra0 cmp.w #$40d7,d0 ;move sr,(sp)? - beq movefromsra0 + beq movefromsrsp cmp.w #$f327,d0 ;fsave -(sp)? beq fsavepush cmp.w #$f35f,d0 ;frestore (sp)+? beq frestorepop + cmp.w #$f32d,d0 ;fsave xxx(a5) ? + beq fsavea5 + cmp.w #$f36d,d0 ;frestore xxx(a5) ? + beq frestorea5 cmp.w #$4e73,d0 ;rte? beq pvrte @@ -418,6 +596,14 @@ doprivviol move.l d0,(sp) ;Save d0 cmp.w #$f4f8,d0 ;cpusha dc/ic? beq cpushadcic + cmp.w #$4e69,d0 ;move usp,a1 + beq moveuspa1 + cmp.w #$4e68,d0 ;move usp,a0 + beq moveuspa0 + + cmp.w #$4e61,d0 ;move a1,usp + beq moved1usp + pv_unhandled move.l (sp),d0 ;Unhandled instruction, jump to handler in main.cpp move.l a6,(sp) ;Save a6 move.l usp,a6 ;Get user stack pointer @@ -451,6 +637,12 @@ pushsr move.l a0,-(sp) ;Save a0 move.l (sp)+,a0 ;Restore a0 move.l (sp)+,d0 ;Restore d0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; move (sp)+,sr @@ -459,7 +651,7 @@ popsr move.l a0,-(sp) ;Save a0 move.w (a0)+,d0 ;Get SR from user stack move.w d0,8(sp) ;Store into CCR on exception stack frame and.w #$00ff,8(sp) - and.w #$2700,d0 ;Extract supervisor bits + and.w #$e700,d0 ;Extract supervisor bits move.w d0,_EmulatedSR ;And save them and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled @@ -477,6 +669,12 @@ popsr move.l a0,-(sp) ;Save a0 move.l (sp)+,a0 ;Restore a0 move.l (sp)+,d0 ;Restore d0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; ori #xxxx,sr @@ -485,10 +683,16 @@ orisr move.w 4(sp),d0 ;Get CCR from st or.w ([6,sp],2),d0 ;Or with immediate value move.w d0,4(sp) ;Store into CCR on stack and.w #$00ff,4(sp) - and.w #$2700,d0 ;Extract supervisor bits + and.w #$e700,d0 ;Extract supervisor bits move.w d0,_EmulatedSR ;And save them move.l (sp)+,d0 ;Restore d0 addq.l #4,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; andi #xxxx,sr @@ -497,7 +701,7 @@ andisr move.w 4(sp),d0 ;Get CCR from s and.w ([6,sp],2),d0 ;And with immediate value storesr4 move.w d0,4(sp) ;Store into CCR on stack and.w #$00ff,4(sp) - and.w #$2700,d0 ;Extract supervisor bits + and.w #$e700,d0 ;Extract supervisor bits move.w d0,_EmulatedSR ;And save them and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled @@ -512,6 +716,12 @@ storesr4 move.w d0,4(sp) ;Store into CC movem.l (sp)+,d0-d1/a0-a1/a6 1$ move.l (sp)+,d0 ;Restore d0 addq.l #4,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; move #xxxx,sr @@ -543,6 +753,12 @@ movefromsrabs move.l a0,-(sp) ;Save a0 move.l (sp)+,a0 ;Restore a0 move.l (sp)+,d0 ;Restore d0 addq.l #4,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; move sr,(a0) @@ -551,6 +767,12 @@ movefromsra0 move.w 4(sp),d0 ;Get CCR move.w d0,(a0) ;Store SR move.l (sp)+,d0 ;Restore d0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; move sr,(sp) @@ -562,42 +784,127 @@ movefromsrsp move.l a0,-(sp) ;Save a0 move.l (sp)+,a0 ;Restore a0 move.l (sp)+,d0 ;Restore d0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; fsave -(sp) fsavepush move.l (sp),d0 ;Restore d0 move.l a0,(sp) ;Save a0 move.l usp,a0 ;Get user stack pointer - fsave -(a0) ;Push FP state + move.l #$41000000,-(a0) ;Push idle frame move.l a0,usp ;Update USP move.l (sp)+,a0 ;Restore a0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; fsave xxx(a5) +fsavea5 move.l (sp),d0 ;Restore d0 + move.l a0,(sp) ;Save a0 + move.l a5,a0 ;Get base register + add.w ([6,sp],2),a0 ;Add offset to base register + move.l #$41000000,(a0) ;Push idle frame + move.l (sp)+,a0 ;Restore a0 + addq.l #4,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; frestore (sp)+ frestorepop move.l (sp),d0 ;Restore d0 move.l a0,(sp) ;Save a0 move.l usp,a0 ;Get user stack pointer - frestore (a0)+ ;Restore FP state + addq.l #4,a0 ;Nothing to do... move.l a0,usp ;Update USP move.l (sp)+,a0 ;Restore a0 addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; frestore xxx(a5) +frestorea5 move.l (sp),d0 ;Restore d0 + move.l a0,(sp) ;Save a0 + move.l (sp)+,a0 ;Restore a0 + addq.l #4,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte -; rte (only handles format 0) -pvrte move.l a0,-(sp) ;Save a0 +; rte +pvrte movem.l a0/a1,-(sp) ;Save a0 and a1 move.l usp,a0 ;Get user stack pointer + move.w (a0)+,d0 ;Get SR from user stack - move.w d0,8(sp) ;Store into CCR on exception stack frame - and.w #$00ff,8(sp) - and.w #$2700,d0 ;Extract supervisor bits + move.w d0,8+4(sp) ;Store into CCR on exception stack frame + and.w #$c0ff,8+4(sp) + and.w #$e700,d0 ;Extract supervisor bits move.w d0,_EmulatedSR ;And save them - move.l (a0)+,10(sp) ;Store return address in exception stack frame - addq.l #2,a0 ;Skip format word + move.l (a0)+,10+4(sp) ;Store return address in exception stack frame + + move.w (a0)+,d0 ;get format word + lsr.w #7,d0 ;get stack frame Id + lsr.w #4,d0 + and.w #$001e,d0 + move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length + subq.w #4,d0 ; count only extra words + lea 16+4(sp),a1 ; destination address (in supervisor stack) + bra 1$ + +2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack +1$ dbf d0,2$ + move.l a0,usp ;Update USP - move.l (sp)+,a0 ;Restore a0 + movem.l (sp)+,a0/a1 ;Restore a0 and a1 move.l (sp)+,d0 ;Restore d0 - rte + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; sizes of exceptions stack frames +StackFormatTable: + dc.w 4 ; Four-word stack frame, format $0 + dc.w 4 ; Throwaway four-word stack frame, format $1 + dc.w 6 ; Six-word stack frame, format $2 + dc.w 6 ; MC68040 floating-point post-instruction stack frame, format $3 + dc.w 8 ; MC68EC040 and MC68LC040 floating-point unimplemented stack frame, format $4 + dc.w 4 ; Format $5 + dc.w 4 ; Format $6 + dc.w 30 ; MC68040 access error stack frame, Format $7 + dc.w 29 ; MC68010 bus and address error stack frame, format $8 + dc.w 10 ; MC68020 and MC68030 coprocessor mid-instruction stack frame, format $9 + dc.w 16 ; MC68020 and MC68030 short bus cycle stack frame, format $a + dc.w 46 ; MC68020 and MC68030 long bus cycle stack frame, format $b + dc.w 12 ; CPU32 bus error for prefetches and operands stack frame, format $c + dc.w 4 ; Format $d + dc.w 4 ; Format $e + dc.w 4 ; Format $f ; move sr,dx movefromsrd0 addq.l #4,sp ;Skip saved d0 @@ -605,6 +912,12 @@ movefromsrd0 addq.l #4,sp ;Skip saved move.w (sp),d0 ;Get CCR or.w _EmulatedSR,d0 ;Add emulated supervisor bits addq.l #2,2(sp) ;Skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd1 move.l (sp)+,d0 @@ -612,6 +925,12 @@ movefromsrd1 move.l (sp)+,d0 move.w (sp),d1 or.w _EmulatedSR,d1 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd2 move.l (sp)+,d0 @@ -619,6 +938,12 @@ movefromsrd2 move.l (sp)+,d0 move.w (sp),d2 or.w _EmulatedSR,d2 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd3 move.l (sp)+,d0 @@ -626,6 +951,12 @@ movefromsrd3 move.l (sp)+,d0 move.w (sp),d3 or.w _EmulatedSR,d3 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd4 move.l (sp)+,d0 @@ -633,6 +964,12 @@ movefromsrd4 move.l (sp)+,d0 move.w (sp),d4 or.w _EmulatedSR,d4 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd5 move.l (sp)+,d0 @@ -640,6 +977,12 @@ movefromsrd5 move.l (sp)+,d0 move.w (sp),d5 or.w _EmulatedSR,d5 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd6 move.l (sp)+,d0 @@ -647,6 +990,12 @@ movefromsrd6 move.l (sp)+,d0 move.w (sp),d6 or.w _EmulatedSR,d6 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movefromsrd7 move.l (sp)+,d0 @@ -654,13 +1003,19 @@ movefromsrd7 move.l (sp)+,d0 move.w (sp),d7 or.w _EmulatedSR,d7 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; move dx,sr movetosrd0 move.l (sp),d0 storesr2 move.w d0,4(sp) and.w #$00ff,4(sp) - and.w #$2700,d0 + and.w #$e700,d0 move.w d0,_EmulatedSR and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled @@ -675,6 +1030,12 @@ storesr2 move.w d0,4(sp) movem.l (sp)+,d0-d1/a0-a1/a6 1$ move.l (sp)+,d0 addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte movetosrd1 move.l d1,d0 @@ -705,6 +1066,10 @@ movecfromcr move.w ([6,sp],2),d0 ;Get n beq.s movecvbra0 cmp.w #$9801,d0 ;movec vbr,a1? beq.s movecvbra1 + cmp.w #$A801,d0 ;movec vbr,a2? + beq.s movecvbra2 + cmp.w #$1801,d0 ;movec vbr,d1? + beq movecvbrd1 cmp.w #$0002,d0 ;movec cacr,d0? beq.s moveccacrd0 cmp.w #$1002,d0 ;movec cacr,d1? @@ -713,6 +1078,22 @@ movecfromcr move.w ([6,sp],2),d0 ;Get n beq.s movectcd0 cmp.w #$1003,d0 ;movec tc,d1? beq.s movectcd1 + cmp.w #$1000,d0 ;movec sfc,d1? + beq movecsfcd1 + cmp.w #$1001,d0 ;movec dfc,d1? + beq movecdfcd1 + cmp.w #$0806,d0 ;movec urp,d0? + beq movecurpd0 + cmp.w #$0807,d0 ;movec srp,d0? + beq.s movecsrpd0 + cmp.w #$0004,d0 ;movec itt0,d0 + beq.s movecitt0d0 + cmp.w #$0005,d0 ;movec itt1,d0 + beq.s movecitt1d0 + cmp.w #$0006,d0 ;movec dtt0,d0 + beq.s movecdtt0d0 + cmp.w #$0007,d0 ;movec dtt1,d0 + beq.s movecdtt1d0 bra pv_unhandled @@ -720,36 +1101,137 @@ movecfromcr move.w ([6,sp],2),d0 ;Get n moveccacrd0 move.l (sp)+,d0 move.l #$3111,d0 ;All caches and bursts on addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec cacr,d1 moveccacrd1 move.l (sp)+,d0 move.l #$3111,d1 ;All caches and bursts on addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec vbr,a0 movecvbra0 move.l (sp)+,d0 sub.l a0,a0 ;VBR always appears to be at 0 addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec vbr,a1 movecvbra1 move.l (sp)+,d0 sub.l a1,a1 ;VBR always appears to be at 0 addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; movec vbr,a2 +movecvbra2 move.l (sp)+,d0 + sub.l a2,a2 ;VBR always appears to be at 0 + addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; movec vbr,d1 +movecvbrd1 move.l (sp)+,d0 + moveq.l #0,d1 ;VBR always appears to be at 0 + addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec tc,d0 movectcd0 addq.l #4,sp moveq #0,d0 ;MMU is always off addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte -; movec tc,d1 -movectcd1 addq.l #4,sp +; movec tc,d1 +jl+ +movectcd1 move.l (sp)+,d0 ;Restore d0 moveq #0,d1 ;MMU is always off addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; movec sfc,d1 +jl+ +movecsfcd1 move.l (sp)+,d0 ;Restore d0 + moveq #0,d1 + addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; movec dfc,d1 +jl+ +movecdfcd1 move.l (sp)+,d0 ;Restore d0 + moveq #0,d1 + addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +movecurpd0 ; movec urp,d0 +jl+ +movecsrpd0 ; movec srp,d0 +movecitt0d0 ; movec itt0,d0 +movecitt1d0 ; movec itt1,d0 +movecdtt0d0 ; movec dtt0,d0 +movecdtt1d0 ; movec dtt1,d0 + addq.l #4,sp + moveq.l #0,d0 ;MMU is always off + addq.l #4,2(sp) ;skip instruction + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec x,cr @@ -757,16 +1239,30 @@ movectocr move.w ([6,sp],2),d0 ;Get nex cmp.w #$0801,d0 ;movec d0,vbr? beq.s movectovbr + cmp.w #$1801,d0 ;movec d1,vbr? + beq.s movectovbr + cmp.w #$A801,d0 ;movec a2,vbr? + beq.s movectovbr cmp.w #$0002,d0 ;movec d0,cacr? beq.s movectocacr cmp.w #$1002,d0 ;movec d1,cacr? beq.s movectocacr + cmp.w #$1000,d0 ;movec d1,sfc? + beq.s movectoxfc + cmp.w #$1001,d0 ;movec d1,dfc? + beq.s movectoxfc bra pv_unhandled ; movec x,vbr movectovbr move.l (sp)+,d0 ;Ignore moves to VBR addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; movec dx,cacr @@ -776,11 +1272,36 @@ movectocacr movem.l d1/a0-a1/a6,-(sp) ;M movem.l (sp)+,d1/a0-a1/a6 move.l (sp)+,d0 addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; movec x,sfc +; movec x,dfc +movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC + addq.l #4,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC rte ; cpusha cpushadc -cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches +cpushadcic + IFEQ INFO_LEVEL-1003 + move.l (4),-(sp) + move.l d0,-(sp) + PUTMSG 0,'%s/cpushadc: opcode=%04lx Execbase=%08lx' + lea (2*4,sp),sp + ENDC + movem.l d1/a0-a1/a6,-(sp) ;Clear caches move.l _SysBase,a6 JSRLIB CacheClearU movem.l (sp)+,d1/a0-a1/a6 @@ -788,4 +1309,83 @@ cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Cl addq.l #2,2(sp) rte +; move usp,a1 +jl+ +moveuspa1 move.l (sp)+,d0 + move usp,a1 + addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1009 + move.l a1,-(sp) + move.l a7,-(sp) + PUTMSG 0,'%s/moveuspa1: a7=%08lx a1=%08lx' + lea (2*4,sp),sp + ENDC + + rte + +; move usp,a0 +jl+ +moveuspa0 move.l (sp)+,d0 + move usp,a0 + addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1009 + move.l a0,-(sp) + move.l a7,-(sp) + PUTMSG 0,'%s/moveuspa0: a7=%08lx a0=%08lx' + lea (2*4,sp),sp + ENDC + + rte + +; move a1,usp +jl+ +moved1usp move.l (sp)+,d0 + move a1,usp + addq.l #2,2(sp) + + IFEQ INFO_LEVEL-1001 + move.l (4),-(sp) + PUTMSG 0,'%s/doprivviol END: Execbase=%08lx' + lea (1*4,sp),sp + ENDC + rte + +; +; Trigger NMI (Pop up debugger) +; + +_AsmTriggerNMI move.l d0,-(sp) ;Save d0 + move.w #$007c,-(sp) ;Yes, fake NMI stack frame + pea 1$ + move.w _EmulatedSR,d0 + and.w #$f8ff,d0 ;Set interrupt level in SR + move.w d0,-(sp) + move.w d0,_EmulatedSR + + move.l $7c.w,-(sp) ;Jump to MacOS NMI handler + rts + +1$ move.l (sp)+,d0 ;Restore d0 + rts + + +CopyTrapStack: + movem.l d0/a0/a1,-(sp) + + move.w (5*4+6,sp),d0 ;get format word + lsr.w #7,d0 ;get stack frame Id + lsr.w #4,d0 + and.w #$001e,d0 + move.w (StackFormatTable,pc,d0.w),d0 ; get total stack frame length + + lea (5*4,sp),a0 ;get start of exception stack frame + move.l usp,a1 ;Get user stack pointer + bra 1$ + +2$ move.w (a0)+,(a1)+ ; copy additional stack words back to supervisor stack +1$ dbf d0,2$ + + move.l (3*4,sp),-(a0) ;copy return address to new top of stack + move.l a0,sp + rts + END