1999-10-03 14:16:26 +00:00
|
|
|
*
|
|
|
|
* asm_support.asm - AmigaOS utility functions in assembly language
|
|
|
|
*
|
|
|
|
* Basilisk II (C) 1997-1999 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
|
|
|
|
* 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 _Execute68k
|
|
|
|
XDEF _Execute68kTrap
|
|
|
|
XDEF _TrapHandlerAsm
|
|
|
|
XDEF _ExceptionHandlerAsm
|
|
|
|
XDEF _Scod060Patch1
|
|
|
|
XDEF _Scod060Patch2
|
|
|
|
XDEF _ThInitFPUPatch
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
|
|
|
|
*
|
|
|
|
* 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)
|
2000-07-22 16:00:36 +00:00
|
|
|
or.w #$2100,d0 ;Set interrupt level in SR
|
1999-10-03 14:16:26 +00:00
|
|
|
move.w d0,_EmulatedSR
|
|
|
|
move.l $64.w,a0 ;Jump to MacOS interrupt handler
|
|
|
|
jmp (a0)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
*
|
|
|
|
* Process Manager 68060 FPU patches
|
|
|
|
*
|
|
|
|
|
|
|
|
_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
|
|
|
|
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
|
|
|
|
rts
|
|
|
|
|
|
|
|
*
|
|
|
|
* Thread Manager 68060 FPU patches
|
|
|
|
*
|
|
|
|
|
|
|
|
_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
|
|
|
|
|
|
|
|
*
|
|
|
|
* Trap handler of main task
|
|
|
|
*
|
|
|
|
|
|
|
|
_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
|
|
|
|
|
|
|
|
move.l _OldTrapHandler,-(sp) ;No, jump to old trap handler
|
|
|
|
rts
|
|
|
|
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
|
|
|
|
move.l $28.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
|
|
|
|
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 movefromsra0
|
|
|
|
|
|
|
|
cmp.w #$f327,d0 ;fsave -(sp)?
|
|
|
|
beq fsavepush
|
|
|
|
cmp.w #$f35f,d0 ;frestore (sp)+?
|
|
|
|
beq frestorepop
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
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)
|
|
|
|
and.w #$2700,d0 ;Extract supervisor bits
|
|
|
|
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)
|
|
|
|
and.w #$2700,d0 ;Extract supervisor bits
|
|
|
|
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)
|
|
|
|
and.w #$2700,d0 ;Extract supervisor bits
|
|
|
|
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
|
|
|
|
fsave -(a0) ;Push FP state
|
|
|
|
move.l a0,usp ;Update USP
|
|
|
|
move.l (sp)+,a0 ;Restore a0
|
|
|
|
addq.l #2,2(sp) ;Skip instruction
|
|
|
|
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
|
|
|
|
move.l a0,usp ;Update USP
|
|
|
|
move.l (sp)+,a0 ;Restore a0
|
|
|
|
addq.l #2,2(sp) ;Skip instruction
|
|
|
|
rte
|
|
|
|
|
|
|
|
; rte (only handles format 0)
|
|
|
|
pvrte 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)
|
|
|
|
and.w #$2700,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,usp ;Update USP
|
|
|
|
move.l (sp)+,a0 ;Restore a0
|
|
|
|
move.l (sp)+,d0 ;Restore d0
|
|
|
|
rte
|
|
|
|
|
|
|
|
; 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)
|
|
|
|
and.w #$2700,d0
|
|
|
|
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
|
|
|
|
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
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
; movec tc,d0
|
|
|
|
movectcd0 addq.l #4,sp
|
|
|
|
moveq #0,d0 ;MMU is always off
|
|
|
|
addq.l #4,2(sp)
|
|
|
|
rte
|
|
|
|
|
|
|
|
; movec tc,d1
|
|
|
|
movectcd1 addq.l #4,sp
|
|
|
|
moveq #0,d1 ;MMU is always off
|
|
|
|
addq.l #4,2(sp)
|
|
|
|
rte
|
|
|
|
|
|
|
|
; movec x,cr
|
|
|
|
movectocr move.w ([6,sp],2),d0 ;Get next instruction word
|
|
|
|
|
|
|
|
cmp.w #$0801,d0 ;movec d0,vbr?
|
|
|
|
beq.s movectovbr
|
|
|
|
cmp.w #$0002,d0 ;movec d0,cacr?
|
|
|
|
beq.s movectocacr
|
|
|
|
cmp.w #$1002,d0 ;movec d1,cacr?
|
|
|
|
beq.s movectocacr
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
; 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
|
|
|
|
|
|
|
|
END
|