      *****************************************
      *                                       *
      *             PatchMult64.s             *
      *    $VER: PatchMult64 1.3 (26.9.98)    *
      *                                       *
      *****************************************


   INCDIR   include:

   include  exec/execbase.i
   include  exec/memory.i
   include  exec/ports.i
   include  dos/dos.i
   include  LVO.i

*=========================================================================

PatchMult64 ;   movem.l  d5-d7/a6,-(sp)

      movea.l  4.w,a6

   ;------ Check if the patches are already installed.

      lea      PortName(pc),a1
      jsr      _LVOFindPort(a6)
      tst.l    d0
      bne      .Warn        ; Patches done.

   ;------ Check for AFB_68040

      btst     #AFB_68040,AttnFlags+1(a6)
      beq      .Error       ; No 68040 or 68060 ...

   ;------ Open the "utility.library"

      moveq    #39,d0
      lea      _UtilityName(pc),a1
      jsr      _LVOOpenLibrary(a6)
      move.l   d0,d4        ; UtilityBase nach d4
      beq      .Error       ; Oupsss...

   ;------ Allocate a buffer to store the patches.

      move.l   #Patch_End-Patch_Start,d0
      move.l   d0,d5
      moveq    #MEMF_PUBLIC,d1
      jsr      _LVOAllocMem(a6)
      move.l   d0,d6
      beq.s    .CloseUtility

   ;------ Copy our patches in the buffer.

      lea      Patch_Start(pc),a0
      movea.l  d6,a1
      move.l   d5,d0
      jsr      _LVOCopyMemQuick(a6)

   ;------ Create a message port.

      jsr      _LVOCreateMsgPort(a6)
      tst.l    d0
      beq.s    .FreeBuffer

      movea.l  d0,a1
      move.l   #PortName-Patch_Start,d0
      add.l    d6,d0
      move.l   d0,LN_NAME(a1)
      move.b   #PA_IGNORE,MP_FLAGS(a1)
      move.b   #-127,LN_PRI(a1)
      clr.b    MP_SIGBIT(a1)
      clr.l    MP_SIGTASK(a1)
      jsr      _LVOAddPort(a6)      ; Add the port to the public list
                                    ; so we can find it later.

   ;------ Install the patches.

      jsr      _LVODisable(a6)      ; UMult64 and SMult64 can be called
                                    ; from interrupts...

      movea.l  d4,a1
      lea      _LVOUMult64,a0
      move.l   d6,d0
      jsr      _LVOSetFunction(a6)

      movea.l  d4,a1
      lea      _LVOSMult64,a0
      moveq    #SMult64-UMult64,d0
      add.l    d6,d0
      jsr      _LVOSetFunction(a6)

      jsr      _LVOEnable(a6)

      ; SetFunction() flushes the instruction cache
      ; so we don't need to do it ourself.

      btst     #7,AttnFlags+1(a6)
      beq      .Warn               ; No 68060...

      moveq    #RETURN_OK,d0
      rts

.Warn moveq    #RETURN_WARN,d0     ; That's all.
      rts

   ;------ Free the patch buffer if we can't allocate a MsgPort.

.FreeBuffer
      move.l   d5,d0
      movea.l  d6,a1
      jsr      _LVOFreeMem(a6)

   ;------ Close utility.library if we can't patch it.

.CloseUtility
      movea.l  d4,a1
      jsr      _LVOCloseLibrary(a6)
.Error
      moveq    #RETURN_ERROR,d0
      rts

*=========================================================================

   include     UMult_SMult_060.s

*=========================================================================

_UtilityName:  dc.b  "utility.library",0

      dc.b     "$VER: PatchMult64 1.3 (26.Sep.1998)",0
