home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / source / except.lha / NullHandler.a < prev    next >
Text File  |  1992-08-12  |  3KB  |  102 lines

  1. *********************************************************************************
  2. *                                        *
  3. *    NullHandler -- Exception handler for taking care of division by zero    *
  4. *                                        *
  5. *    $VER: NullHandler.a 37.1 (12.8.92) -- An exception handler example    *
  6. *                                        *
  7. *    Copyright (C) 1992 Compos Mentis Software Systems -- Jesper Kehlet    *
  8. *                                        *
  9. *********************************************************************************
  10.  
  11.         include        'exec/execbase.i'
  12.         include        'dos/dos.i'
  13.         include        'lvo/exec_lvo.i'
  14.  
  15. IDENT        equ        'NULL'            ; Identifier for checking existence
  16.  
  17.         section        NullHandler,code
  18.  
  19. *********************************************************************************
  20. *                                        *
  21. *    This is the main stuff -- the handler installation            *
  22. *                                        *
  23. *********************************************************************************
  24.  
  25.         moveq        #RETURN_FAIL,d0        ; FAIL if not V37+
  26.         movea.l        (4).w,a6        ; Get ExecBase
  27.         cmpi.w        #37,LIB_VERSION(a6)    ; We want V37+ for AllocVec
  28.         blt.b        NotV37            ; Bail out
  29.  
  30.         suba.l        a5,a5            ; VBR is NULL per default
  31.         btst.b        #AFB_68010,AttnFlags+1(a6)    ; Get MC type
  32.         beq.b        Plain68000
  33.  
  34.         lea        GetVBR(pc),a5        ; Address of GetVBR
  35.         jsr        _LVOSupervisor(a6)    ; Get that VBR base
  36.         movea.l        d0,a5            ; and save it
  37.  
  38. Plain68000    movea.l        $14(a5),a1        ; Is there a handler already
  39.         cmpi.l        #IDENT,2(a1)        ; Check for identifier
  40.         beq.b        RemoveUs        ; Yup, remove us
  41.  
  42.         move.l        a1,OrigHandler        ; Store original handler address
  43.  
  44.         moveq        #HandlerEnd-Handler,d0    ; We want some memory for handler
  45.         moveq        #1,d1            ; Clear it for us
  46.         jsr        _LVOAllocVec(a6)    ; Now, get it!
  47.  
  48.         move.l        d0,$14(a5)        ; Install vector #5
  49.  
  50.         movea.l        d0,a1            ; Destination
  51.         lea        Handler(pc),a0        ; Our code
  52.         moveq        #HandlerEnd-Handler,d0    ; Length for copying
  53.         jsr        _LVOCopyMem(a6)        ; Throw us up in allocated memory
  54.  
  55.         moveq        #RETURN_OK,d0        ; Return OK
  56. NotV37        rts                    ; And get out
  57.  
  58. RemoveUs    move.l        6(a1),$14(a5)        ; Restore old pointer
  59.         jsr        _LVOFreeVec(a6)        ; Free it
  60.         moveq        #RETURN_WARN,d0        ; Return WARN when removed
  61.         rts                    ; And get out
  62.  
  63. *********************************************************************************
  64. *                                        *
  65. *    This is for getting address of VBR on 68010+                *
  66. *    The MOVEC.L VBR,D0 instruction is restricted to Supervisor state, so...    *
  67. *                                        *
  68. *********************************************************************************
  69.  
  70. GetVBR        movec.l        vbr,d0            ; Get VBR
  71.         rte                    ; Return
  72.  
  73. *********************************************************************************
  74. *                                        *
  75. *    This is the handler itself, the meat                    *
  76. *                                        *
  77. *********************************************************************************
  78.  
  79. Handler        bra.b        RealHandler        ; Skip identifier -- it's not code
  80.  
  81.         dc.l        IDENT            ; Identifier
  82. OrigHandler    dc.l        0            ; Original handler address
  83.  
  84. RealHandler    movem.l        d0-d1/a0,-(sp)        ; Save a couple of registers
  85.  
  86.         movea.l        $e(sp),a0        ; Get address of data
  87.         move.w        -2(a0),d0        ; Get numerator
  88.         move.l        #$ffff,d1        ; Largest negative number for denominator
  89.         btst        #8,d0            ; Is it <0 ?
  90.         beq.b        Negative        ; Yup, jump...
  91.         move.l        #$7fff,d1        ; Use largest positive instead
  92.  
  93. Negative    lsr.w        #7,d0            ; Put the denominator
  94.         andi.l        #$1c,d0            ; back on the stack
  95.         move.l        d1,0(sp,d0.l)        ; instead of the zero
  96.  
  97.         movem.l        (sp)+,d0-d1/a0        ; Restore registers
  98.         rte                    ; Back to normal execution
  99. HandlerEnd
  100.  
  101.         end
  102.