macemu/BasiliskII/src/AmigaOS/asm_support.asm

1006 lines
23 KiB
NASM
Raw Normal View History

1999-10-03 14:16:26 +00:00
*
* asm_support.asm - AmigaOS utility functions in assembly language
*
* Basilisk II (C) 1997-2002 Christian Bauer
1999-10-03 14:16:26 +00:00
*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
INCLUDE "exec/types.i"
INCLUDE "exec/macros.i"
INCLUDE "exec/memory.i"
INCLUDE "exec/tasks.i"
INCLUDE "dos/dos.i"
INCLUDE "devices/timer.i"
XDEF _AtomicAnd
XDEF _AtomicOr
XDEF _MoveVBR
XDEF _DisableSuperBypass
1999-10-03 14:16:26 +00:00
XDEF _Execute68k
XDEF _Execute68kTrap
XDEF _TrapHandlerAsm
XDEF _ExceptionHandlerAsm
2000-08-20 14:08:44 +00:00
XDEF _AsmTriggerNMI
1999-10-03 14:16:26 +00:00
XREF _OldTrapHandler
XREF _OldExceptionHandler
XREF _IllInstrHandler
XREF _PrivViolHandler
XREF _EmulatedSR
XREF _IRQSigMask
XREF _InterruptFlags
XREF _MainTask
XREF _SysBase
1999-10-19 19:28:28 +00:00
XREF _quit_emulator
1999-10-03 14:16:26 +00:00
SECTION text,CODE
MACHINE 68020
1999-10-03 14:16:26 +00:00
*
* Atomic bit operations (don't trust the compiler)
*
_AtomicAnd move.l 4(sp),a0
move.l 8(sp),d0
and.l d0,(a0)
rts
_AtomicOr move.l 4(sp),a0
move.l 8(sp),d0
or.l d0,(a0)
rts
*
* Move VBR away from 0 if neccessary
*
_MoveVBR movem.l d0-d1/a0-a1/a5-a6,-(sp)
move.l _SysBase,a6
lea getvbr,a5 ;VBR at 0?
JSRLIB Supervisor
tst.l d0
bne.s 1$
move.l #$400,d0 ;Yes, allocate memory for new table
move.l #MEMF_PUBLIC,d1
JSRLIB AllocMem
tst.l d0
beq.s 1$
JSRLIB Disable
move.l d0,a5 ;Copy old table
move.l d0,a1
sub.l a0,a0
move.l #$400,d0
JSRLIB CopyMem
JSRLIB CacheClearU
move.l a5,d0 ;Set VBR
lea setvbr,a5
JSRLIB Supervisor
JSRLIB Enable
1$ movem.l (sp)+,d0-d1/a0-a1/a5-a6
rts
getvbr movec vbr,d0
rte
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
1999-10-03 14:16:26 +00:00
*
* Execute 68k subroutine (must be ended with rts)
* r->a[7] and r->sr are unused!
*
; void Execute68k(uint32 addr, M68kRegisters *r);
_Execute68k
move.l 4(sp),d0 ;Get arguments
move.l 8(sp),a0
movem.l d2-d7/a2-a6,-(sp) ;Save registers
move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
pea 1$ ;Push return address on stack
move.l d0,-(sp) ;Push pointer to 68k routine on stack
movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
rts ;Jump into 68k routine
1$ move.l a6,-(sp) ;Save a6
move.l 4(sp),a6 ;Get pointer to M68kRegisters
movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
addq.l #4,sp ;Remove pointer from stack
movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
rts
*
* Execute MacOS 68k trap
* r->a[7] and r->sr are unused!
*
; void Execute68kTrap(uint16 trap, M68kRegisters *r);
_Execute68kTrap
move.l 4(sp),d0 ;Get arguments
move.l 8(sp),a0
movem.l d2-d7/a2-a6,-(sp) ;Save registers
move.l a0,-(sp) ;Push pointer to M68kRegisters on stack
move.w d0,-(sp) ;Push trap word on stack
subq.l #8,sp ;Create fake A-Line exception frame
movem.l (a0),d0-d7/a0-a6 ;Load registers from M68kRegisters
move.l a2,-(sp) ;Save a2 and d2
move.l d2,-(sp)
lea 1$,a2 ;a2 points to return address
move.w 16(sp),d2 ;Load trap word into d2
jmp ([$28.w],10) ;Jump into MacOS A-Line handler
1$ move.l a6,-(sp) ;Save a6
move.l 6(sp),a6 ;Get pointer to M68kRegisters
movem.l d0-d7/a0-a5,(a6) ;Save d0-d7/a0-a5 to M68kRegisters
move.l (sp)+,56(a6) ;Save a6 to M68kRegisters
addq.l #6,sp ;Remove pointer and trap word from stack
movem.l (sp)+,d2-d7/a2-a6 ;Restore registers
rts
*
* Exception handler of main task (for 60Hz interrupts)
*
_ExceptionHandlerAsm
move.l d0,-(sp) ;Save d0
and.l #SIGBREAKF_CTRL_C,d0 ;CTRL-C?
bne.s 2$
move.w _EmulatedSR,d0 ;Interrupts enabled in emulated SR?
and.w #$0700,d0
bne 1$
move.w #$0064,-(sp) ;Yes, fake interrupt stack frame
pea 1$
move.w _EmulatedSR,d0
move.w d0,-(sp)
or.w #$2100,d0 ;Set interrupt level in SR, enter (virtual) supervisor mode
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR
2000-08-20 14:08:44 +00:00
move.l $64.w,-(sp) ;Jump to MacOS interrupt handler
rts
1999-10-03 14:16:26 +00:00
1$ move.l (sp)+,d0 ;Restore d0
rts
2$ JSRLIB Forbid ;Waiting for Dos signal?
sub.l a1,a1
JSRLIB FindTask
move.l d0,a0
move.l TC_SIGWAIT(a0),d0
move.l TC_SIGRECVD(a0),d1
JSRLIB Permit
btst #SIGB_DOS,d0
beq 3$
btst #SIGB_DOS,d1
bne 4$
3$ lea TC_SIZE(a0),a0 ;No, remove pending Dos packets
JSRLIB GetMsg
move.w _EmulatedSR,d0
or.w #$0700,d0 ;Disable all interrupts
move.w d0,_EmulatedSR
moveq #0,d0 ;Disable all exception signals
moveq #-1,d1
JSRLIB SetExcept
1999-10-19 19:28:28 +00:00
jsr _quit_emulator ;CTRL-C, quit emulator
1999-10-03 14:16:26 +00:00
4$ move.l (sp)+,d0
rts
*
* Trap handler of main task
*
2000-08-20 14:08:44 +00:00
_TrapHandlerAsm:
cmp.l #4,(sp) ;Illegal instruction?
1999-10-03 14:16:26 +00:00
beq.s doillinstr
cmp.l #10,(sp) ;A-Line exception?
beq.s doaline
cmp.l #8,(sp) ;Privilege violation?
beq.s doprivviol
2000-08-20 14:08:44 +00:00
cmp.l #9,(sp) ;Trace?
beq dotrace
cmp.l #3,(sp) ;Illegal Address?
beq.s doilladdr
cmp.l #32,(sp)
blt 1$
cmp.l #47,(sp)
ble doTrapXX ; Vector 32-47 : TRAP #0 - 15 Instruction Vectors
1$ move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler
2000-08-20 14:08:44 +00:00
rts
*
* TRAP #0 - 15 Instruction Vectors
*
doTrapXX move.l a0,(sp) ;Save a0
2000-08-20 14:08:44 +00:00
move.l usp,a0 ;Get user stack pointer
move.l 2*4(sp),-(a0) ;Copy 4-word stack frame to user stack
move.l 1*4(sp),-(a0)
move.l a0,usp ;Update USP
move.l (sp)+,a0 ;Restore a0
addq.l #4*2,sp ;Remove exception frame from supervisor stack
andi #$d8ff,sr ;Switch to user mode, enable interrupts
1999-10-03 14:16:26 +00:00
2000-08-20 14:08:44 +00:00
move.l $2d*4.w,-(sp) ;Jump to MacOS exception handler
1999-10-03 14:16:26 +00:00
rts
2000-08-20 14:08:44 +00:00
*
* trace Vector
*
dotrace move.l a0,(sp) ;Save a0
2000-08-20 14:08:44 +00:00
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
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
1999-10-03 14:16:26 +00:00
*
* A-Line handler: call MacOS A-Line handler
*
doaline 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
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 #$d8ff,_EmulatedSR ;enable interrupts in EmulatedSR
1999-10-03 14:16:26 +00:00
move.l $28.w,-(sp) ;Jump to MacOS exception handler
rts
2000-08-20 14:08:44 +00:00
*
* Illegal address handler
*
doilladdr move.l a0,(sp) ;Save a0
2000-08-20 14:08:44 +00:00
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
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
1999-10-03 14:16:26 +00:00
*
* Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
* to execute extended opcodes (see emul_op.h)
*
doillinstr movem.l a0/d0,-(sp)
2000-08-20 14:08:44 +00:00
move.w ([6+2*4,sp]),d0
and.w #$ff00,d0
cmp.w #$7100,d0
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
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
1999-10-03 14:16:26 +00:00
move.l usp,a6 ;Get user stack pointer
move.l a6,-10(a6) ;Push USP (a7)
move.l 6(sp),-(a6) ;Push PC
move.w 4(sp),-(a6) ;Push SR
subq.l #4,a6 ;Skip saved USP
move.l (sp),-(a6) ;Push old a6
movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
move.l a6,usp ;Update USP
add.w #12,sp ;Remove exception frame from supervisor stack
andi #$d8ff,sr ;Switch to user mode, enable interrupts
move.l a6,-(sp) ;Jump to IllInstrHandler() in main.cpp
jsr _IllInstrHandler
addq.l #4,sp
movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
addq.l #4,sp ;Skip saved USP (!!)
rtr ;Return from exception
*
* Privilege violation handler: MacOS runs in supervisor mode,
* so we have to emulate certain privileged instructions
*
doprivviol move.l d0,(sp) ;Save d0
move.w ([6,sp]),d0 ;Get instruction word
cmp.w #$40e7,d0 ;move sr,-(sp)?
beq pushsr
cmp.w #$46df,d0 ;move (sp)+,sr?
beq popsr
cmp.w #$007c,d0 ;ori #xxxx,sr?
beq orisr
cmp.w #$027c,d0 ;andi #xxxx,sr?
beq andisr
cmp.w #$46fc,d0 ;move #xxxx,sr?
beq movetosrimm
cmp.w #$46ef,d0 ;move (xxxx,sp),sr?
beq movetosrsprel
cmp.w #$46d8,d0 ;move (a0)+,sr?
beq movetosra0p
cmp.w #$46d9,d0 ;move (a1)+,sr?
beq movetosra1p
cmp.w #$40f8,d0 ;move sr,xxxx.w?
beq movefromsrabs
cmp.w #$40d0,d0 ;move sr,(a0)?
beq movefromsra0
cmp.w #$40d7,d0 ;move sr,(sp)?
beq movefromsrsp
1999-10-03 14:16:26 +00:00
cmp.w #$f327,d0 ;fsave -(sp)?
beq fsavepush
cmp.w #$f35f,d0 ;frestore (sp)+?
beq frestorepop
2000-08-20 14:08:44 +00:00
cmp.w #$f32d,d0 ;fsave xxx(a5) ?
beq fsavea5
cmp.w #$f36d,d0 ;frestore xxx(a5) ?
beq frestorea5
1999-10-03 14:16:26 +00:00
cmp.w #$4e73,d0 ;rte?
beq pvrte
cmp.w #$40c0,d0 ;move sr,d0?
beq movefromsrd0
cmp.w #$40c1,d0 ;move sr,d1?
beq movefromsrd1
cmp.w #$40c2,d0 ;move sr,d2?
beq movefromsrd2
cmp.w #$40c3,d0 ;move sr,d3?
beq movefromsrd3
cmp.w #$40c4,d0 ;move sr,d4?
beq movefromsrd4
cmp.w #$40c5,d0 ;move sr,d5?
beq movefromsrd5
cmp.w #$40c6,d0 ;move sr,d6?
beq movefromsrd6
cmp.w #$40c7,d0 ;move sr,d7?
beq movefromsrd7
cmp.w #$46c0,d0 ;move d0,sr?
beq movetosrd0
cmp.w #$46c1,d0 ;move d1,sr?
beq movetosrd1
cmp.w #$46c2,d0 ;move d2,sr?
beq movetosrd2
cmp.w #$46c3,d0 ;move d3,sr?
beq movetosrd3
cmp.w #$46c4,d0 ;move d4,sr?
beq movetosrd4
cmp.w #$46c5,d0 ;move d5,sr?
beq movetosrd5
cmp.w #$46c6,d0 ;move d6,sr?
beq movetosrd6
cmp.w #$46c7,d0 ;move d7,sr?
beq movetosrd7
cmp.w #$4e7a,d0 ;movec cr,x?
beq movecfromcr
cmp.w #$4e7b,d0 ;movec x,cr?
beq movectocr
cmp.w #$f478,d0 ;cpusha dc?
beq cpushadc
cmp.w #$f4f8,d0 ;cpusha dc/ic?
beq cpushadcic
2000-08-20 14:08:44 +00:00
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
1999-10-03 14:16:26 +00:00
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
move.l a6,-10(a6) ;Push USP (a7)
move.l 6(sp),-(a6) ;Push PC
move.w 4(sp),-(a6) ;Push SR
subq.l #4,a6 ;Skip saved USP
move.l (sp),-(a6) ;Push old a6
movem.l d0-d7/a0-a5,-(a6) ;Push remaining registers
move.l a6,usp ;Update USP
add.w #12,sp ;Remove exception frame from supervisor stack
andi #$d8ff,sr ;Switch to user mode, enable interrupts
move.l a6,-(sp) ;Jump to PrivViolHandler() in main.cpp
jsr _PrivViolHandler
addq.l #4,sp
movem.l (sp)+,d0-d7/a0-a6 ;Restore registers
addq.l #4,sp ;Skip saved USP
rtr ;Return from exception
; move sr,-(sp)
pushsr move.l a0,-(sp) ;Save a0
move.l usp,a0 ;Get user stack pointer
move.w 8(sp),d0 ;Get CCR from exception stack frame
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
move.w d0,-(a0) ;Store SR on user stack
move.l a0,usp ;Update USP
move.l (sp)+,a0 ;Restore a0
move.l (sp)+,d0 ;Restore d0
addq.l #2,2(sp) ;Skip instruction
rte
; move (sp)+,sr
popsr move.l a0,-(sp) ;Save a0
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)
2000-08-20 14:08:44 +00:00
and.w #$e700,d0 ;Extract supervisor bits
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR ;And save them
and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
bne 1$
tst.l _InterruptFlags
beq 1$
movem.l d0-d1/a0-a1/a6,-(sp)
move.l _SysBase,a6
move.l _MainTask,a1
move.l _IRQSigMask,d0
JSRLIB Signal
movem.l (sp)+,d0-d1/a0-a1/a6
1$
move.l a0,usp ;Update USP
move.l (sp)+,a0 ;Restore a0
move.l (sp)+,d0 ;Restore d0
addq.l #2,2(sp) ;Skip instruction
rte
; ori #xxxx,sr
orisr move.w 4(sp),d0 ;Get CCR from stack
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
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)
2000-08-20 14:08:44 +00:00
and.w #$e700,d0 ;Extract supervisor bits
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR ;And save them
move.l (sp)+,d0 ;Restore d0
addq.l #4,2(sp) ;Skip instruction
rte
; andi #xxxx,sr
andisr move.w 4(sp),d0 ;Get CCR from stack
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
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)
2000-08-20 14:08:44 +00:00
and.w #$e700,d0 ;Extract supervisor bits
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR ;And save them
and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
bne.s 1$
tst.l _InterruptFlags
beq.s 1$
movem.l d0-d1/a0-a1/a6,-(sp)
move.l _SysBase,a6
move.l _MainTask,a1
move.l _IRQSigMask,d0
JSRLIB Signal
movem.l (sp)+,d0-d1/a0-a1/a6
1$ move.l (sp)+,d0 ;Restore d0
addq.l #4,2(sp) ;Skip instruction
rte
; move #xxxx,sr
movetosrimm move.w ([6,sp],2),d0 ;Get immediate value
bra.s storesr4
; move (xxxx,sp),sr
movetosrsprel move.l a0,-(sp) ;Save a0
move.l usp,a0 ;Get user stack pointer
move.w ([10,sp],2),d0 ;Get offset
move.w (a0,d0.w),d0 ;Read word
move.l (sp)+,a0 ;Restore a0
bra.s storesr4
; move (a0)+,sr
movetosra0p move.w (a0)+,d0 ;Read word
bra storesr2
; move (a1)+,sr
movetosra1p move.w (a1)+,d0 ;Read word
bra storesr2
; move sr,xxxx.w
movefromsrabs move.l a0,-(sp) ;Save a0
move.w ([10,sp],2),a0 ;Get address
move.w 8(sp),d0 ;Get CCR
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
move.w d0,(a0) ;Store SR
move.l (sp)+,a0 ;Restore a0
move.l (sp)+,d0 ;Restore d0
addq.l #4,2(sp) ;Skip instruction
rte
; move sr,(a0)
movefromsra0 move.w 4(sp),d0 ;Get CCR
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
move.w d0,(a0) ;Store SR
move.l (sp)+,d0 ;Restore d0
addq.l #2,2(sp) ;Skip instruction
rte
; move sr,(sp)
movefromsrsp move.l a0,-(sp) ;Save a0
move.l usp,a0 ;Get user stack pointer
move.w 8(sp),d0 ;Get CCR
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
move.w d0,(a0) ;Store SR
move.l (sp)+,a0 ;Restore a0
move.l (sp)+,d0 ;Restore d0
addq.l #2,2(sp) ;Skip instruction
rte
; fsave -(sp)
fsavepush move.l (sp),d0 ;Restore d0
move.l a0,(sp) ;Save a0
move.l usp,a0 ;Get user stack pointer
move.l #$41000000,-(a0) ;Push idle frame
1999-10-03 14:16:26 +00:00
move.l a0,usp ;Update USP
move.l (sp)+,a0 ;Restore a0
addq.l #2,2(sp) ;Skip instruction
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
rte
1999-10-03 14:16:26 +00:00
; frestore (sp)+
frestorepop move.l (sp),d0 ;Restore d0
move.l a0,(sp) ;Save a0
move.l usp,a0 ;Get user stack pointer
addq.l #4,a0 ;Nothing to do...
1999-10-03 14:16:26 +00:00
move.l a0,usp ;Update USP
move.l (sp)+,a0 ;Restore a0
addq.l #2,2(sp) ;Skip instruction
rte
; frestore xxx(a5)
2000-08-20 14:08:44 +00:00
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
rte
; rte
pvrte movem.l a0/a1,-(sp) ;Save a0 and a1
1999-10-03 14:16:26 +00:00
move.l usp,a0 ;Get user stack pointer
2000-08-20 14:08:44 +00:00
1999-10-03 14:16:26 +00:00
move.w (a0)+,d0 ;Get SR from user stack
2000-08-20 14:08:44 +00:00
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
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR ;And save them
2000-08-20 14:08:44 +00:00
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$
2000-08-20 14:08:44 +00:00
1999-10-03 14:16:26 +00:00
move.l a0,usp ;Update USP
2000-08-20 14:08:44 +00:00
movem.l (sp)+,a0/a1 ;Restore a0 and a1
1999-10-03 14:16:26 +00:00
move.l (sp)+,d0 ;Restore d0
rte
2000-08-20 14:08:44 +00:00
; 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
1999-10-03 14:16:26 +00:00
; move sr,dx
movefromsrd0 addq.l #4,sp ;Skip saved d0
moveq #0,d0
move.w (sp),d0 ;Get CCR
or.w _EmulatedSR,d0 ;Add emulated supervisor bits
addq.l #2,2(sp) ;Skip instruction
rte
movefromsrd1 move.l (sp)+,d0
moveq #0,d1
move.w (sp),d1
or.w _EmulatedSR,d1
addq.l #2,2(sp)
rte
movefromsrd2 move.l (sp)+,d0
moveq #0,d2
move.w (sp),d2
or.w _EmulatedSR,d2
addq.l #2,2(sp)
rte
movefromsrd3 move.l (sp)+,d0
moveq #0,d3
move.w (sp),d3
or.w _EmulatedSR,d3
addq.l #2,2(sp)
rte
movefromsrd4 move.l (sp)+,d0
moveq #0,d4
move.w (sp),d4
or.w _EmulatedSR,d4
addq.l #2,2(sp)
rte
movefromsrd5 move.l (sp)+,d0
moveq #0,d5
move.w (sp),d5
or.w _EmulatedSR,d5
addq.l #2,2(sp)
rte
movefromsrd6 move.l (sp)+,d0
moveq #0,d6
move.w (sp),d6
or.w _EmulatedSR,d6
addq.l #2,2(sp)
rte
movefromsrd7 move.l (sp)+,d0
moveq #0,d7
move.w (sp),d7
or.w _EmulatedSR,d7
addq.l #2,2(sp)
rte
; move dx,sr
movetosrd0 move.l (sp),d0
storesr2 move.w d0,4(sp)
and.w #$00ff,4(sp)
2000-08-20 14:08:44 +00:00
and.w #$e700,d0
1999-10-03 14:16:26 +00:00
move.w d0,_EmulatedSR
and.w #$0700,d0 ;Rethrow exception if interrupts are pending and reenabled
bne.s 1$
tst.l _InterruptFlags
beq.s 1$
movem.l d0-d1/a0-a1/a6,-(sp)
move.l _SysBase,a6
move.l _MainTask,a1
move.l _IRQSigMask,d0
JSRLIB Signal
movem.l (sp)+,d0-d1/a0-a1/a6
1$ move.l (sp)+,d0
addq.l #2,2(sp)
rte
movetosrd1 move.l d1,d0
bra.s storesr2
movetosrd2 move.l d2,d0
bra.s storesr2
movetosrd3 move.l d3,d0
bra.s storesr2
movetosrd4 move.l d4,d0
bra.s storesr2
movetosrd5 move.l d5,d0
bra.s storesr2
movetosrd6 move.l d6,d0
bra.s storesr2
movetosrd7 move.l d7,d0
bra.s storesr2
; movec cr,x
movecfromcr move.w ([6,sp],2),d0 ;Get next instruction word
cmp.w #$8801,d0 ;movec vbr,a0?
beq.s movecvbra0
cmp.w #$9801,d0 ;movec vbr,a1?
beq.s movecvbra1
2000-08-20 14:08:44 +00:00
cmp.w #$1801,d0 ;movec vbr,d1?
beq movecvbrd1
1999-10-03 14:16:26 +00:00
cmp.w #$0002,d0 ;movec cacr,d0?
beq.s moveccacrd0
cmp.w #$1002,d0 ;movec cacr,d1?
beq.s moveccacrd1
cmp.w #$0003,d0 ;movec tc,d0?
beq.s movectcd0
cmp.w #$1003,d0 ;movec tc,d1?
beq.s movectcd1
cmp.w #$1000,d0 ;movec sfc,d1?
2000-08-20 14:08:44 +00:00
beq movecsfcd1
cmp.w #$1001,d0 ;movec dfc,d1?
2000-08-20 14:08:44 +00:00
beq movecdfcd1
cmp.w #$0806,d0 ;movec urp,d0?
2000-08-20 14:08:44 +00:00
beq movecurpd0
cmp.w #$0807,d0 ;movec srp,d0?
2000-08-20 14:08:44 +00:00
beq.s movecsrpd0
cmp.w #$0004,d0 ;movec itt0,d0
2000-08-20 14:08:44 +00:00
beq.s movecitt0d0
cmp.w #$0005,d0 ;movec itt1,d0
2000-08-20 14:08:44 +00:00
beq.s movecitt1d0
cmp.w #$0006,d0 ;movec dtt0,d0
2000-08-20 14:08:44 +00:00
beq.s movecdtt0d0
cmp.w #$0007,d0 ;movec dtt1,d0
2000-08-20 14:08:44 +00:00
beq.s movecdtt1d0
1999-10-03 14:16:26 +00:00
bra pv_unhandled
; movec cacr,d0
moveccacrd0 move.l (sp)+,d0
move.l #$3111,d0 ;All caches and bursts on
addq.l #4,2(sp)
rte
; movec cacr,d1
moveccacrd1 move.l (sp)+,d0
move.l #$3111,d1 ;All caches and bursts on
addq.l #4,2(sp)
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)
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)
rte
2000-08-20 14:08:44 +00:00
; movec vbr,d1
movecvbrd1 move.l (sp)+,d0
moveq.l #0,d1 ;VBR always appears to be at 0
addq.l #4,2(sp)
rte
1999-10-03 14:16:26 +00:00
; movec tc,d0
movectcd0 addq.l #4,sp
moveq #0,d0 ;MMU is always off
addq.l #4,2(sp)
rte
2000-08-20 14:08:44 +00:00
; movec tc,d1 +jl+
movectcd1 move.l (sp)+,d0 ;Restore d0
moveq #0,d1 ;MMU is always off
addq.l #4,2(sp)
rte
; movec sfc,d1 +jl+
movecsfcd1 move.l (sp)+,d0 ;Restore d0
moveq #0,d1
2000-08-20 14:08:44 +00:00
addq.l #4,2(sp)
rte
; movec dfc,d1 +jl+
movecdfcd1 move.l (sp)+,d0 ;Restore d0
moveq #0,d1
1999-10-03 14:16:26 +00:00
addq.l #4,2(sp)
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
2000-08-20 14:08:44 +00:00
addq.l #4,sp
moveq.l #0,d0 ;MMU is always off
addq.l #4,2(sp) ;skip instruction
rte
1999-10-03 14:16:26 +00:00
; movec x,cr
movectocr move.w ([6,sp],2),d0 ;Get next instruction word
cmp.w #$0801,d0 ;movec d0,vbr?
beq.s movectovbr
2000-08-20 14:08:44 +00:00
cmp.w #$1801,d0 ;movec d1,vbr?
beq.s movectovbr
1999-10-03 14:16:26 +00:00
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?
2000-08-20 14:08:44 +00:00
beq.s movectoxfc
cmp.w #$1001,d0 ;movec d1,dfc?
2000-08-20 14:08:44 +00:00
beq.s movectoxfc
1999-10-03 14:16:26 +00:00
bra pv_unhandled
; movec x,vbr
movectovbr move.l (sp)+,d0 ;Ignore moves to VBR
addq.l #4,2(sp)
rte
; movec dx,cacr
movectocacr movem.l d1/a0-a1/a6,-(sp) ;Move to CACR, clear caches
move.l _SysBase,a6
JSRLIB CacheClearU
movem.l (sp)+,d1/a0-a1/a6
move.l (sp)+,d0
addq.l #4,2(sp)
rte
; movec x,sfc
; movec x,dfc
2000-08-20 14:08:44 +00:00
movectoxfc move.l (sp)+,d0 ;Ignore moves to SFC, DFC
addq.l #4,2(sp)
rte
1999-10-03 14:16:26 +00:00
; cpusha
cpushadc
cpushadcic movem.l d1/a0-a1/a6,-(sp) ;Clear caches
move.l _SysBase,a6
JSRLIB CacheClearU
movem.l (sp)+,d1/a0-a1/a6
move.l (sp)+,d0
addq.l #2,2(sp)
rte
2000-08-20 14:08:44 +00:00
; move usp,a1 +jl+
moveuspa1 move.l (sp)+,d0
2000-08-20 14:08:44 +00:00
move usp,a1
addq.l #2,2(sp)
rte
; move usp,a0 +jl+
moveuspa0 move.l (sp)+,d0
2000-08-20 14:08:44 +00:00
move usp,a0
addq.l #2,2(sp)
rte
; move a1,usp +jl+
moved1usp move.l (sp)+,d0
2000-08-20 14:08:44 +00:00
move a1,usp
addq.l #2,2(sp)
rte
;
; Trigger NMI (Pop up debugger)
;
_AsmTriggerNMI move.l d0,-(sp) ;Save d0
2000-08-20 14:08:44 +00:00
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
1999-10-03 14:16:26 +00:00
END