          OPT c+,l-

****************************************
* DevPatch II                          *
* © J.Tyberghein N.François P.Marivoet *
* Dec 1989                             *
****************************************

   incdir  ":include/"
   include "exec/types.i"
   include "exec/memory.i"
   include "exec/ports.i"
   include "exec/exec_lib.i"

   ;IntuitionBase routines
_LVOOpenWindow  equ   -204
   ;DosBase
_LVOOutput      equ   -60
_LVOWrite       equ   -48

nw_Title        equ   $1a
nw_Height       equ   6
PRI             equ   0

   ;*** Start code ***

   ;IntuitionLibrary
      lea IntLib(PC),a1
      CALLEXEC   OldOpenLibrary
      move.l d0,_IntBase
   ;DosLibrary
      lea DosLib(PC),a1
      CALLEXEC   OldOpenLibrary
      move.l d0,_DosBase
   ;Say we exist
      lea StartupMsg(PC),a2
      moveq #StartupMsgLen,d2
      bsr myPuts
   ;Test if the MsgPort exists
      lea StartBlock(PC),a1
      lea PortName(a1),a1
      CALLEXEC FindPort
      tst.l d0
      bne.s PortAlreadyExists

   ;Create MsgPort
      move.l #BlockLen,d0
      move.l #MEMF_CLEAR+MEMF_PUBLIC,d1
      CALLEXEC AllocMem
      tst.l d0
      beq CloseLib
      move.l d0,Port
      lea StartBlock(PC),a0
      move.l d0,a1
      move.l #BlockLen,d0
      CALLEXEC CopyMem
      move.l Port(PC),a1
      lea PortName(a1),a0
      move.l a0,LN_NAME(a1)
      CALLEXEC AddPort
   ;Install patch
      move.l Port(PC),a1
      lea OpenPatch(a1),a0
      move.l a0,d0
      move.l _IntBase(PC),a1
      move.l #_LVOOpenWindow,a0
      CALLEXEC   SetFunction
      move.l Port(PC),a1
      move.l d0,JmpLab1(a1)
      lea PatchedMsg(PC),a2
      moveq #PatchedMsgLen,d2
      bsr.s myPuts
      bra.s CloseLib

PortAlreadyExists:
      move.l d0,a2
   ;Remove patch
      move.l JmpLab1(a2),d0
      move.l _IntBase(PC),a1
      move.l #_LVOOpenWindow,a0
      CALLEXEC   SetFunction
   ;Remove Port
      move.l a2,a1
      CALLEXEC RemPort
   ;Free Patch memory
      move.l a2,a1
      move.l #BlockLen,d0
      CALLEXEC FreeMem
   ;Say it's done
      lea RemovedMsg(PC),a2
      moveq #RemovedMsgLen,d2
      bsr.s myPuts
CloseLib:
   ;Close libraries
      move.l _DosBase(PC),a1
      CALLEXEC   CloseLibrary
      move.l _IntBase(PC),a1
      CALLEXEC   CloseLibrary
      rts

myPuts:
      move.l _DosBase(PC),a6
      jsr _LVOOutput(a6)
      move.l d0,d1
      move.l d2,d3
      move.l a2,d2
      jsr _LVOWrite(a6)
      rts

*****************************************************************************

   ;This is our MsgPort followed by our patch function
   ;this data and code will be copied in one block
StartBlock:
      dc.l   0,0
      dc.b   NT_MSGPORT,PRI
      dc.l   0                     ;Pointer to our MsgPort name
      dc.b   0,0
      dc.l   0,0,0,0
      dc.b   0,0

OpenPatch equ *-StartBlock
      movem.l   d7/a2-a3,-(a7)
      move.l nw_Title(a0),a2
      lea Assembling(PC),a3
      moveq #13,d7
CmpLoop:
      cmp.b (a2)+,(a3)+
      dbne d7,CmpLoop
      addq.w #1,d7
      beq.s PatchIt
      move.l nw_Title(a0),a2
      lea DefaultOutput(PC),a3
      moveq #21,d7
CmpLoop2:
      cmp.b (a2)+,(a3)+
      dbne d7,CmpLoop2
      addq.w #1,d7
      bne.s NotDevpac
PatchIt:
      move.w #45,nw_Height(a0)
NotDevpac:
      movem.l (a7)+,d7/a2-a3
JmpLab1 equ *+2-StartBlock
      jmp $0.l

PortName equ *-StartBlock
                 dc.b "DevPatch.port",0
Assembling:      dc.b "Assembling...",0
DefaultOutput:   dc.b "Default Output Window",0

BlockLen equ *-StartBlock

*****************************************************************************

_IntBase:     dc.l 0
_DosBase:     dc.l 0
Port:         dc.l 0
IntLib:       dc.b "intuition.library",0
DosLib:       dc.b "dos.library",0
StartupMsg:   dc.b 27,"[33mDevPatch II",27,"[0m by PowerPeak",10,0
StartupMsgLen equ *-StartupMsg
PatchedMsg:   dc.b "Patch installed.",10,0
PatchedMsgLen equ *-PatchedMsg
RemovedMsg:   dc.b "Patch removed.",10,0
RemovedMsgLen equ *-RemovedMsg

   END

