home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / AmigaOS / asm_support.asm next >
Encoding:
Assembly Source File  |  2001-02-02  |  24.3 KB  |  1,067 lines

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