home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / BasiliskII / src / AmigaOS / asm_support.asm next >
Assembly Source File  |  1999-11-01  |  18KB  |  792 lines

  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.  
  39.         XREF    _OldTrapHandler
  40.         XREF    _OldExceptionHandler
  41.         XREF    _IllInstrHandler
  42.         XREF    _PrivViolHandler
  43.         XREF    _EmulatedSR
  44.         XREF    _IRQSigMask
  45.         XREF    _InterruptFlags
  46.         XREF    _MainTask
  47.         XREF    _SysBase
  48.         XREF    _quit_emulator
  49.  
  50.         SECTION    text,CODE
  51.  
  52. *
  53. * Atomic bit operations (don't trust the compiler)
  54. *
  55.  
  56. _AtomicAnd    move.l    4(sp),a0
  57.         move.l    8(sp),d0
  58.         and.l    d0,(a0)
  59.         rts
  60.  
  61. _AtomicOr    move.l    4(sp),a0
  62.         move.l    8(sp),d0
  63.         or.l    d0,(a0)
  64.         rts
  65.  
  66. *
  67. * Move VBR away from 0 if neccessary
  68. *
  69.  
  70. _MoveVBR    movem.l    d0-d1/a0-a1/a5-a6,-(sp)
  71.         move.l    _SysBase,a6
  72.  
  73.         lea    getvbr,a5        ;VBR at 0?
  74.         JSRLIB    Supervisor
  75.         tst.l    d0
  76.         bne.s    1$
  77.  
  78.         move.l    #$400,d0        ;Yes, allocate memory for new table
  79.         move.l    #MEMF_PUBLIC,d1
  80.         JSRLIB    AllocMem
  81.         tst.l    d0
  82.         beq.s    1$
  83.  
  84.         JSRLIB    Disable
  85.  
  86.         move.l    d0,a5            ;Copy old table
  87.         move.l    d0,a1
  88.         sub.l    a0,a0
  89.         move.l    #$400,d0
  90.         JSRLIB    CopyMem
  91.         JSRLIB    CacheClearU
  92.  
  93.         move.l    a5,d0            ;Set VBR
  94.         lea    setvbr,a5
  95.         JSRLIB    Supervisor
  96.  
  97.         JSRLIB    Enable
  98.  
  99. 1$        movem.l    (sp)+,d0-d1/a0-a1/a5-a6
  100.         rts
  101.  
  102. getvbr        movec    vbr,d0
  103.         rte
  104.  
  105. setvbr        movec    d0,vbr
  106.         rte
  107.  
  108. *
  109. * Execute 68k subroutine (must be ended with rts)
  110. * r->a[7] and r->sr are unused!
  111. *
  112.  
  113. ; void Execute68k(uint32 addr, M68kRegisters *r);
  114. _Execute68k
  115.         move.l    4(sp),d0        ;Get arguments
  116.         move.l    8(sp),a0
  117.  
  118.         movem.l    d2-d7/a2-a6,-(sp)    ;Save registers
  119.  
  120.         move.l    a0,-(sp)        ;Push pointer to M68kRegisters on stack
  121.         pea    1$            ;Push return address on stack
  122.         move.l    d0,-(sp)        ;Push pointer to 68k routine on stack
  123.         movem.l    (a0),d0-d7/a0-a6    ;Load registers from M68kRegisters
  124.  
  125.         rts                ;Jump into 68k routine
  126.  
  127. 1$        move.l    a6,-(sp)        ;Save a6
  128.         move.l    4(sp),a6        ;Get pointer to M68kRegisters
  129.         movem.l    d0-d7/a0-a5,(a6)    ;Save d0-d7/a0-a5 to M68kRegisters
  130.         move.l    (sp)+,56(a6)        ;Save a6 to M68kRegisters
  131.         addq.l    #4,sp            ;Remove pointer from stack
  132.  
  133.         movem.l    (sp)+,d2-d7/a2-a6    ;Restore registers
  134.         rts
  135.  
  136. *
  137. * Execute MacOS 68k trap
  138. * r->a[7] and r->sr are unused!
  139. *
  140.  
  141. ; void Execute68kTrap(uint16 trap, M68kRegisters *r);
  142. _Execute68kTrap
  143.         move.l    4(sp),d0        ;Get arguments
  144.         move.l    8(sp),a0
  145.  
  146.         movem.l    d2-d7/a2-a6,-(sp)    ;Save registers
  147.  
  148.         move.l    a0,-(sp)        ;Push pointer to M68kRegisters on stack
  149.         move.w    d0,-(sp)        ;Push trap word on stack
  150.         subq.l    #8,sp            ;Create fake A-Line exception frame
  151.         movem.l    (a0),d0-d7/a0-a6    ;Load registers from M68kRegisters
  152.  
  153.         move.l    a2,-(sp)        ;Save a2 and d2
  154.         move.l    d2,-(sp)
  155.         lea    1$,a2            ;a2 points to return address
  156.         move.w    16(sp),d2        ;Load trap word into d2
  157.  
  158.         jmp    ([$28.w],10)        ;Jump into MacOS A-Line handler
  159.  
  160. 1$        move.l    a6,-(sp)        ;Save a6
  161.         move.l    6(sp),a6        ;Get pointer to M68kRegisters
  162.         movem.l    d0-d7/a0-a5,(a6)    ;Save d0-d7/a0-a5 to M68kRegisters
  163.         move.l    (sp)+,56(a6)        ;Save a6 to M68kRegisters
  164.         addq.l    #6,sp            ;Remove pointer and trap word from stack
  165.  
  166.         movem.l    (sp)+,d2-d7/a2-a6    ;Restore registers
  167.         rts
  168.  
  169. *
  170. * Exception handler of main task (for 60Hz interrupts)
  171. *
  172.  
  173. _ExceptionHandlerAsm
  174.         move.l    d0,-(sp)        ;Save d0
  175.  
  176.         and.l    #SIGBREAKF_CTRL_C,d0    ;CTRL-C?
  177.         bne.s    2$
  178.  
  179.         move.w    _EmulatedSR,d0        ;Interrupts enabled in emulated SR?
  180.         and.w    #$0700,d0
  181.         bne    1$
  182.         move.w    #$0064,-(sp)        ;Yes, fake interrupt stack frame
  183.         pea    1$
  184.         move.w    _EmulatedSR,d0
  185.         move.w    d0,-(sp)
  186.         or.w    #$0100,d0        ;Set interrupt level in SR
  187.         move.w    d0,_EmulatedSR
  188.         move.l    $64.w,a0        ;Jump to MacOS interrupt handler
  189.         jmp    (a0)
  190.  
  191. 1$        move.l    (sp)+,d0        ;Restore d0
  192.         rts
  193.  
  194. 2$        JSRLIB    Forbid            ;Waiting for Dos signal?
  195.         sub.l    a1,a1
  196.         JSRLIB    FindTask
  197.         move.l    d0,a0
  198.         move.l    TC_SIGWAIT(a0),d0
  199.         move.l    TC_SIGRECVD(a0),d1
  200.         JSRLIB    Permit
  201.         btst    #SIGB_DOS,d0
  202.         beq    3$
  203.         btst    #SIGB_DOS,d1
  204.         bne    4$
  205.  
  206. 3$        lea    TC_SIZE(a0),a0        ;No, remove pending Dos packets
  207.         JSRLIB    GetMsg
  208.  
  209.         move.w    _EmulatedSR,d0
  210.         or.w    #$0700,d0        ;Disable all interrupts
  211.         move.w    d0,_EmulatedSR
  212.         moveq    #0,d0            ;Disable all exception signals
  213.         moveq    #-1,d1
  214.         JSRLIB    SetExcept
  215.         jsr    _quit_emulator        ;CTRL-C, quit emulator
  216. 4$        move.l    (sp)+,d0
  217.         rts
  218.  
  219. *
  220. * Process Manager 68060 FPU patches
  221. *
  222.  
  223. _Scod060Patch1    fsave    -(sp)        ;Save FPU state
  224.         tst.b    2(sp)        ;Null?
  225.         beq.s    1$
  226.         fmovem.x fp0-fp7,-(sp)    ;No, save FPU registers
  227.         fmove.l    fpiar,-(sp)
  228.         fmove.l    fpsr,-(sp)
  229.         fmove.l    fpcr,-(sp)
  230.         pea    -1        ;Push "FPU state saved" flag
  231. 1$        move.l    d1,-(sp)
  232.         move.l    d0,-(sp)
  233.         bsr.s    3$        ;Switch integer registers and stack
  234.         addq.l    #8,sp
  235.         tst.b    2(sp)        ;New FPU state null or "FPU state saved" flag set?
  236.         beq.s    2$
  237.         addq.l    #4,sp        ;Flag set, skip it
  238.         fmove.l    (sp)+,fpcr    ;Restore FPU registers and state
  239.         fmove.l    (sp)+,fpsr
  240.         fmove.l    (sp)+,fpiar
  241.         fmovem.x (sp)+,fp0-fp7
  242. 2$        frestore (sp)+
  243.         movem.l    (sp)+,d0-d1
  244.         rts
  245.  
  246. 3$        move.l    4(sp),a0    ;Switch integer registers and stack
  247.         move    sr,-(sp)
  248.         movem.l    d2-d7/a2-a6,-(sp)
  249.         cmp.w    #0,a0
  250.         beq.s    4$
  251.         move.l    sp,(a0)
  252. 4$        move.l    $36(sp),a0
  253.         movem.l    (a0)+,d2-d7/a2-a6
  254.         move    (a0)+,sr
  255.         move.l    a0,sp
  256.         rts
  257.  
  258. _Scod060Patch2    move.l    d0,-(sp)    ;Create 68060 null frame on stack
  259.         move.l    d0,-(sp)
  260.         move.l    d0,-(sp)
  261.         frestore (sp)+        ;and load it
  262.         rts
  263.  
  264. *
  265. * Thread Manager 68060 FPU patches
  266. *
  267.  
  268. _ThInitFPUPatch    tst.b    $40(a4)
  269.         bne.s    1$
  270.         moveq    #0,d0        ;Create 68060 null frame on stack
  271.         move.l    d0,-(a3)
  272.         move.l    d0,-(a3)
  273.         move.l    d0,-(a3)
  274. 1$        rts
  275.  
  276. *
  277. * Trap handler of main task
  278. *
  279.  
  280. _TrapHandlerAsm    cmp.l    #4,(sp)            ;Illegal instruction?
  281.         beq.s    doillinstr
  282.         cmp.l    #10,(sp)        ;A-Line exception?
  283.         beq.s    doaline
  284.         cmp.l    #8,(sp)            ;Privilege violation?
  285.         beq.s    doprivviol
  286.  
  287.         move.l    _OldTrapHandler,-(sp)    ;No, jump to old trap handler
  288.         rts
  289.  
  290. *
  291. * A-Line handler: call MacOS A-Line handler
  292. *
  293.  
  294. doaline        move.l    a0,(sp)            ;Save a0
  295.         move.l    usp,a0            ;Get user stack pointer
  296.         move.l    8(sp),-(a0)        ;Copy stack frame to user stack
  297.         move.l    4(sp),-(a0)
  298.         move.l    a0,usp            ;Update USP
  299.         move.l    (sp)+,a0        ;Restore a0
  300.  
  301.         addq.l    #8,sp            ;Remove exception frame from supervisor stack
  302.         andi    #$d8ff,sr        ;Switch to user mode, enable interrupts
  303.  
  304.         move.l    $28.w,-(sp)        ;Jump to MacOS exception handler
  305.         rts
  306.  
  307. *
  308. * Illegal instruction handler: call IllInstrHandler() (which calls EmulOp())
  309. *   to execute extended opcodes (see emul_op.h)
  310. *
  311.  
  312. doillinstr    move.l    a6,(sp)            ;Save a6
  313.         move.l    usp,a6            ;Get user stack pointer
  314.  
  315.         move.l    a6,-10(a6)        ;Push USP (a7)
  316.         move.l    6(sp),-(a6)        ;Push PC
  317.         move.w    4(sp),-(a6)        ;Push SR
  318.         subq.l    #4,a6            ;Skip saved USP
  319.         move.l    (sp),-(a6)        ;Push old a6
  320.         movem.l    d0-d7/a0-a5,-(a6)    ;Push remaining registers
  321.         move.l    a6,usp            ;Update USP
  322.  
  323.         add.w    #12,sp            ;Remove exception frame from supervisor stack
  324.         andi    #$d8ff,sr        ;Switch to user mode, enable interrupts
  325.  
  326.         move.l    a6,-(sp)        ;Jump to IllInstrHandler() in main.cpp
  327.         jsr    _IllInstrHandler
  328.         addq.l    #4,sp
  329.  
  330.         movem.l    (sp)+,d0-d7/a0-a6    ;Restore registers
  331.         addq.l    #4,sp            ;Skip saved USP (!!)
  332.         rtr                ;Return from exception
  333.  
  334. *
  335. * Privilege violation handler: MacOS runs in supervisor mode,
  336. *   so we have to emulate certain privileged instructions
  337. *
  338.  
  339. doprivviol    move.l    d0,(sp)            ;Save d0
  340.         move.w    ([6,sp]),d0        ;Get instruction word
  341.  
  342.         cmp.w    #$40e7,d0        ;move sr,-(sp)?
  343.         beq    pushsr
  344.         cmp.w    #$46df,d0        ;move (sp)+,sr?
  345.         beq    popsr
  346.  
  347.         cmp.w    #$007c,d0        ;ori #xxxx,sr?
  348.         beq    orisr
  349.         cmp.w    #$027c,d0        ;andi #xxxx,sr?
  350.         beq    andisr
  351.  
  352.         cmp.w    #$46fc,d0        ;move #xxxx,sr?
  353.         beq    movetosrimm
  354.  
  355.         cmp.w    #$46ef,d0        ;move (xxxx,sp),sr?
  356.         beq    movetosrsprel
  357.         cmp.w    #$46d8,d0        ;move (a0)+,sr?
  358.         beq    movetosra0p
  359.         cmp.w    #$46d9,d0        ;move (a1)+,sr?
  360.         beq    movetosra1p
  361.  
  362.         cmp.w    #$40f8,d0        ;move sr,xxxx.w?
  363.         beq    movefromsrabs
  364.         cmp.w    #$40d0,d0        ;move sr,(a0)?
  365.         beq    movefromsra0
  366.         cmp.w    #$40d7,d0        ;move sr,(sp)?
  367.         beq    movefromsra0
  368.  
  369.         cmp.w    #$f327,d0        ;fsave -(sp)?
  370.         beq    fsavepush
  371.         cmp.w    #$f35f,d0        ;frestore (sp)+?
  372.         beq    frestorepop
  373.  
  374.         cmp.w    #$4e73,d0        ;rte?
  375.         beq    pvrte
  376.  
  377.         cmp.w    #$40c0,d0        ;move sr,d0?
  378.         beq    movefromsrd0
  379.         cmp.w    #$40c1,d0        ;move sr,d1?
  380.         beq    movefromsrd1
  381.         cmp.w    #$40c2,d0        ;move sr,d2?
  382.         beq    movefromsrd2
  383.         cmp.w    #$40c3,d0        ;move sr,d3?
  384.         beq    movefromsrd3
  385.         cmp.w    #$40c4,d0        ;move sr,d4?
  386.         beq    movefromsrd4
  387.         cmp.w    #$40c5,d0        ;move sr,d5?
  388.         beq    movefromsrd5
  389.         cmp.w    #$40c6,d0        ;move sr,d6?
  390.         beq    movefromsrd6
  391.         cmp.w    #$40c7,d0        ;move sr,d7?
  392.         beq    movefromsrd7
  393.  
  394.         cmp.w    #$46c0,d0        ;move d0,sr?
  395.         beq    movetosrd0
  396.         cmp.w    #$46c1,d0        ;move d1,sr?
  397.         beq    movetosrd1
  398.         cmp.w    #$46c2,d0        ;move d2,sr?
  399.         beq    movetosrd2
  400.         cmp.w    #$46c3,d0        ;move d3,sr?
  401.         beq    movetosrd3
  402.         cmp.w    #$46c4,d0        ;move d4,sr?
  403.         beq    movetosrd4
  404.         cmp.w    #$46c5,d0        ;move d5,sr?
  405.         beq    movetosrd5
  406.         cmp.w    #$46c6,d0        ;move d6,sr?
  407.         beq    movetosrd6
  408.         cmp.w    #$46c7,d0        ;move d7,sr?
  409.         beq    movetosrd7
  410.  
  411.         cmp.w    #$4e7a,d0        ;movec cr,x?
  412.         beq    movecfromcr
  413.         cmp.w    #$4e7b,d0        ;movec x,cr?
  414.         beq    movectocr
  415.  
  416.         cmp.w    #$f478,d0        ;cpusha dc?
  417.         beq    cpushadc
  418.         cmp.w    #$f4f8,d0        ;cpusha dc/ic?
  419.         beq    cpushadcic
  420.  
  421. pv_unhandled    move.l    (sp),d0            ;Unhandled instruction, jump to handler in main.cpp
  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 PrivViolHandler() in main.cpp
  437.         jsr    _PrivViolHandler
  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. ; move sr,-(sp)
  445. pushsr        move.l    a0,-(sp)        ;Save a0
  446.         move.l    usp,a0            ;Get user stack pointer
  447.         move.w    8(sp),d0        ;Get CCR from exception stack frame
  448.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  449.         move.w    d0,-(a0)        ;Store SR on user stack
  450.         move.l    a0,usp            ;Update USP
  451.         move.l    (sp)+,a0        ;Restore a0
  452.         move.l    (sp)+,d0        ;Restore d0
  453.         addq.l    #2,2(sp)        ;Skip instruction
  454.         rte
  455.  
  456. ; move (sp)+,sr
  457. popsr        move.l    a0,-(sp)        ;Save a0
  458.         move.l    usp,a0            ;Get user stack pointer
  459.         move.w    (a0)+,d0        ;Get SR from user stack
  460.         move.w    d0,8(sp)        ;Store into CCR on exception stack frame
  461.         and.w    #$00ff,8(sp)
  462.         and.w    #$2700,d0        ;Extract supervisor bits
  463.         move.w    d0,_EmulatedSR        ;And save them
  464.  
  465.         and.w    #$0700,d0        ;Rethrow exception if interrupts are pending and reenabled
  466.         bne    1$
  467.         tst.l    _InterruptFlags
  468.         beq    1$
  469.         movem.l    d0-d1/a0-a1/a6,-(sp)
  470.         move.l    _SysBase,a6
  471.         move.l    _MainTask,a1
  472.         move.l    _IRQSigMask,d0
  473.         JSRLIB    Signal
  474.         movem.l    (sp)+,d0-d1/a0-a1/a6
  475. 1$
  476.         move.l    a0,usp            ;Update USP
  477.         move.l    (sp)+,a0        ;Restore a0
  478.         move.l    (sp)+,d0        ;Restore d0
  479.         addq.l    #2,2(sp)        ;Skip instruction
  480.         rte
  481.  
  482. ; ori #xxxx,sr
  483. orisr        move.w    4(sp),d0        ;Get CCR from stack
  484.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  485.         or.w    ([6,sp],2),d0        ;Or with immediate value
  486.         move.w    d0,4(sp)        ;Store into CCR on stack
  487.         and.w    #$00ff,4(sp)
  488.         and.w    #$2700,d0        ;Extract supervisor bits
  489.         move.w    d0,_EmulatedSR        ;And save them
  490.         move.l    (sp)+,d0        ;Restore d0
  491.         addq.l    #4,2(sp)        ;Skip instruction
  492.         rte
  493.  
  494. ; andi #xxxx,sr
  495. andisr        move.w    4(sp),d0        ;Get CCR from stack
  496.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  497.         and.w    ([6,sp],2),d0        ;And with immediate value
  498. storesr4    move.w    d0,4(sp)        ;Store into CCR on stack
  499.         and.w    #$00ff,4(sp)
  500.         and.w    #$2700,d0        ;Extract supervisor bits
  501.         move.w    d0,_EmulatedSR        ;And save them
  502.  
  503.         and.w    #$0700,d0        ;Rethrow exception if interrupts are pending and reenabled
  504.         bne.s    1$
  505.         tst.l    _InterruptFlags
  506.         beq.s    1$
  507.         movem.l    d0-d1/a0-a1/a6,-(sp)
  508.         move.l    _SysBase,a6
  509.         move.l    _MainTask,a1
  510.         move.l    _IRQSigMask,d0
  511.         JSRLIB    Signal
  512.         movem.l    (sp)+,d0-d1/a0-a1/a6
  513. 1$        move.l    (sp)+,d0        ;Restore d0
  514.         addq.l    #4,2(sp)        ;Skip instruction
  515.         rte
  516.  
  517. ; move #xxxx,sr
  518. movetosrimm    move.w    ([6,sp],2),d0        ;Get immediate value
  519.         bra.s    storesr4
  520.  
  521. ; move (xxxx,sp),sr
  522. movetosrsprel    move.l    a0,-(sp)        ;Save a0
  523.         move.l    usp,a0            ;Get user stack pointer
  524.         move.w    ([10,sp],2),d0        ;Get offset
  525.         move.w    (a0,d0.w),d0        ;Read word
  526.         move.l    (sp)+,a0        ;Restore a0
  527.         bra.s    storesr4
  528.  
  529. ; move (a0)+,sr
  530. movetosra0p    move.w    (a0)+,d0        ;Read word
  531.         bra    storesr2
  532.  
  533. ; move (a1)+,sr
  534. movetosra1p    move.w    (a1)+,d0        ;Read word
  535.         bra    storesr2
  536.  
  537. ; move sr,xxxx.w
  538. movefromsrabs    move.l    a0,-(sp)        ;Save a0
  539.         move.w    ([10,sp],2),a0        ;Get address
  540.         move.w    8(sp),d0        ;Get CCR
  541.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  542.         move.w    d0,(a0)            ;Store SR
  543.         move.l    (sp)+,a0        ;Restore a0
  544.         move.l    (sp)+,d0        ;Restore d0
  545.         addq.l    #4,2(sp)        ;Skip instruction
  546.         rte
  547.  
  548. ; move sr,(a0)
  549. movefromsra0    move.w    4(sp),d0        ;Get CCR
  550.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  551.         move.w    d0,(a0)            ;Store SR
  552.         move.l    (sp)+,d0        ;Restore d0
  553.         addq.l    #2,2(sp)        ;Skip instruction
  554.         rte
  555.  
  556. ; move sr,(sp)
  557. movefromsrsp    move.l    a0,-(sp)        ;Save a0
  558.         move.l    usp,a0            ;Get user stack pointer
  559.         move.w    8(sp),d0        ;Get CCR
  560.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  561.         move.w    d0,(a0)            ;Store SR
  562.         move.l    (sp)+,a0        ;Restore a0
  563.         move.l    (sp)+,d0        ;Restore d0
  564.         addq.l    #2,2(sp)        ;Skip instruction
  565.         rte
  566.  
  567. ; fsave -(sp)
  568. fsavepush    move.l    (sp),d0            ;Restore d0
  569.         move.l    a0,(sp)            ;Save a0
  570.         move.l    usp,a0            ;Get user stack pointer
  571.         fsave    -(a0)            ;Push FP state
  572.         move.l    a0,usp            ;Update USP
  573.         move.l    (sp)+,a0        ;Restore a0
  574.         addq.l    #2,2(sp)        ;Skip instruction
  575.         rte
  576.  
  577. ; frestore (sp)+
  578. frestorepop    move.l    (sp),d0            ;Restore d0
  579.         move.l    a0,(sp)            ;Save a0
  580.         move.l    usp,a0            ;Get user stack pointer
  581.         frestore (a0)+            ;Restore FP state
  582.         move.l    a0,usp            ;Update USP
  583.         move.l    (sp)+,a0        ;Restore a0
  584.         addq.l    #2,2(sp)        ;Skip instruction
  585.         rte
  586.  
  587. ; rte (only handles format 0)
  588. pvrte        move.l    a0,-(sp)        ;Save a0
  589.         move.l    usp,a0            ;Get user stack pointer
  590.         move.w    (a0)+,d0        ;Get SR from user stack
  591.         move.w    d0,8(sp)        ;Store into CCR on exception stack frame
  592.         and.w    #$00ff,8(sp)
  593.         and.w    #$2700,d0        ;Extract supervisor bits
  594.         move.w    d0,_EmulatedSR        ;And save them
  595.         move.l    (a0)+,10(sp)        ;Store return address in exception stack frame
  596.         addq.l    #2,a0            ;Skip format word
  597.         move.l    a0,usp            ;Update USP
  598.         move.l    (sp)+,a0        ;Restore a0
  599.         move.l    (sp)+,d0        ;Restore d0
  600.         rte
  601.  
  602. ; move sr,dx
  603. movefromsrd0    addq.l    #4,sp            ;Skip saved d0
  604.         moveq    #0,d0
  605.         move.w    (sp),d0            ;Get CCR
  606.         or.w    _EmulatedSR,d0        ;Add emulated supervisor bits
  607.         addq.l    #2,2(sp)        ;Skip instruction
  608.         rte
  609.  
  610. movefromsrd1    move.l    (sp)+,d0
  611.         moveq    #0,d1
  612.         move.w    (sp),d1
  613.         or.w    _EmulatedSR,d1
  614.         addq.l    #2,2(sp)
  615.         rte
  616.  
  617. movefromsrd2    move.l    (sp)+,d0
  618.         moveq    #0,d2
  619.         move.w    (sp),d2
  620.         or.w    _EmulatedSR,d2
  621.         addq.l    #2,2(sp)
  622.         rte
  623.  
  624. movefromsrd3    move.l    (sp)+,d0
  625.         moveq    #0,d3
  626.         move.w    (sp),d3
  627.         or.w    _EmulatedSR,d3
  628.         addq.l    #2,2(sp)
  629.         rte
  630.  
  631. movefromsrd4    move.l    (sp)+,d0
  632.         moveq    #0,d4
  633.         move.w    (sp),d4
  634.         or.w    _EmulatedSR,d4
  635.         addq.l    #2,2(sp)
  636.         rte
  637.  
  638. movefromsrd5    move.l    (sp)+,d0
  639.         moveq    #0,d5
  640.         move.w    (sp),d5
  641.         or.w    _EmulatedSR,d5
  642.         addq.l    #2,2(sp)
  643.         rte
  644.  
  645. movefromsrd6    move.l    (sp)+,d0
  646.         moveq    #0,d6
  647.         move.w    (sp),d6
  648.         or.w    _EmulatedSR,d6
  649.         addq.l    #2,2(sp)
  650.         rte
  651.  
  652. movefromsrd7    move.l    (sp)+,d0
  653.         moveq    #0,d7
  654.         move.w    (sp),d7
  655.         or.w    _EmulatedSR,d7
  656.         addq.l    #2,2(sp)
  657.         rte
  658.  
  659. ; move dx,sr
  660. movetosrd0    move.l    (sp),d0
  661. storesr2    move.w    d0,4(sp)
  662.         and.w    #$00ff,4(sp)
  663.         and.w    #$2700,d0
  664.         move.w    d0,_EmulatedSR
  665.  
  666.         and.w    #$0700,d0        ;Rethrow exception if interrupts are pending and reenabled
  667.         bne.s    1$
  668.         tst.l    _InterruptFlags
  669.         beq.s    1$
  670.         movem.l    d0-d1/a0-a1/a6,-(sp)
  671.         move.l    _SysBase,a6
  672.         move.l    _MainTask,a1
  673.         move.l    _IRQSigMask,d0
  674.         JSRLIB    Signal
  675.         movem.l    (sp)+,d0-d1/a0-a1/a6
  676. 1$        move.l    (sp)+,d0
  677.         addq.l    #2,2(sp)
  678.         rte
  679.  
  680. movetosrd1    move.l    d1,d0
  681.         bra.s    storesr2
  682.  
  683. movetosrd2    move.l    d2,d0
  684.         bra.s    storesr2
  685.  
  686. movetosrd3    move.l    d3,d0
  687.         bra.s    storesr2
  688.  
  689. movetosrd4    move.l    d4,d0
  690.         bra.s    storesr2
  691.  
  692. movetosrd5    move.l    d5,d0
  693.         bra.s    storesr2
  694.  
  695. movetosrd6    move.l    d6,d0
  696.         bra.s    storesr2
  697.  
  698. movetosrd7    move.l    d7,d0
  699.         bra.s    storesr2
  700.  
  701. ; movec cr,x
  702. movecfromcr    move.w    ([6,sp],2),d0        ;Get next instruction word
  703.  
  704.         cmp.w    #$8801,d0        ;movec vbr,a0?
  705.         beq.s    movecvbra0
  706.         cmp.w    #$9801,d0        ;movec vbr,a1?
  707.         beq.s    movecvbra1
  708.         cmp.w    #$0002,d0        ;movec cacr,d0?
  709.         beq.s    moveccacrd0
  710.         cmp.w    #$1002,d0        ;movec cacr,d1?
  711.         beq.s    moveccacrd1
  712.         cmp.w    #$0003,d0        ;movec tc,d0?
  713.         beq.s    movectcd0
  714.         cmp.w    #$1003,d0        ;movec tc,d1?
  715.         beq.s    movectcd1
  716.  
  717.         bra    pv_unhandled
  718.  
  719. ; movec cacr,d0
  720. moveccacrd0    move.l    (sp)+,d0
  721.         move.l    #$3111,d0        ;All caches and bursts on
  722.         addq.l    #4,2(sp)
  723.         rte
  724.  
  725. ; movec cacr,d1
  726. moveccacrd1    move.l    (sp)+,d0
  727.         move.l    #$3111,d1        ;All caches and bursts on
  728.         addq.l    #4,2(sp)
  729.         rte
  730.  
  731. ; movec vbr,a0
  732. movecvbra0    move.l    (sp)+,d0
  733.         sub.l    a0,a0            ;VBR always appears to be at 0
  734.         addq.l    #4,2(sp)
  735.         rte
  736.  
  737. ; movec vbr,a1
  738. movecvbra1    move.l    (sp)+,d0
  739.         sub.l    a1,a1            ;VBR always appears to be at 0
  740.         addq.l    #4,2(sp)
  741.         rte
  742.  
  743. ; movec tc,d0
  744. movectcd0    addq.l    #4,sp
  745.         moveq    #0,d0            ;MMU is always off
  746.         addq.l    #4,2(sp)
  747.         rte
  748.  
  749. ; movec tc,d1
  750. movectcd1    addq.l    #4,sp
  751.         moveq    #0,d1            ;MMU is always off
  752.         addq.l    #4,2(sp)
  753.         rte
  754.  
  755. ; movec x,cr
  756. movectocr    move.w    ([6,sp],2),d0        ;Get next instruction word
  757.  
  758.         cmp.w    #$0801,d0        ;movec d0,vbr?
  759.         beq.s    movectovbr
  760.         cmp.w    #$0002,d0        ;movec d0,cacr?
  761.         beq.s    movectocacr
  762.         cmp.w    #$1002,d0        ;movec d1,cacr?
  763.         beq.s    movectocacr
  764.  
  765.         bra    pv_unhandled
  766.  
  767. ; movec x,vbr
  768. movectovbr    move.l    (sp)+,d0        ;Ignore moves to VBR
  769.         addq.l    #4,2(sp)
  770.         rte
  771.  
  772. ; movec dx,cacr
  773. movectocacr    movem.l    d1/a0-a1/a6,-(sp)    ;Move to CACR, clear caches
  774.         move.l    _SysBase,a6
  775.         JSRLIB    CacheClearU
  776.         movem.l    (sp)+,d1/a0-a1/a6
  777.         move.l    (sp)+,d0
  778.         addq.l    #4,2(sp)
  779.         rte
  780.  
  781. ; cpusha
  782. cpushadc
  783. cpushadcic    movem.l    d1/a0-a1/a6,-(sp)    ;Clear caches
  784.         move.l    _SysBase,a6
  785.         JSRLIB    CacheClearU
  786.         movem.l    (sp)+,d1/a0-a1/a6
  787.         move.l    (sp)+,d0
  788.         addq.l    #2,2(sp)
  789.         rte
  790.  
  791.         END
  792.