        section code


*
*   In both functions, we need a buffer area.  Here's what will be in the
*   buffer area:
*
*     area - area+6    : backup of what was in the DosBase jump table
*     area+6 - area+12 : a jump to the new code (serves also as linked list)
*     area+12 - area+20: the "old code", made either of:
*
*                            moveq.l #xx, d0
*                            jmp     #longadd
*
*                                   or
*
*                            nop
*                            jmp     #longadd
*
*                        depending if we were the first to modify the DosBase
*                        function.
*


*   DosWedge
*
*     On entry, on the stack we have:
*
*       sp+16:  new function address
*       sp+12:  backup area (10 words == 20 bytes)
*       sp+8 :  offset of function in DosBase   
*       sp+4 :  DosBase
*       sp   :  return address (what did ya think?)
*
*     You can declare the DosWedge function like this in Lattice 5.10:
*
*     __fptr __stdargs DosWedge (struct DosBase *, LONG Offset, WORD *BackUp, __fptrNewFunc);
*

JUMP    equ $4EF9

    XDEF    _DosWedge

_DosWedge:

    move.l  a6,-(a7)
    move.l  4,a6
    jsr     -$84(a6)            ; Forbid
    move.l  8(a7),a0            ; DosBase
    add.l   12(a7),a0           ; add offset of function
    move.l  16(a7),a1           ; backup for old jump
    move.w  (a0),(a1)           ; contains a moveq+bra or jmp
    move.l  2(a0),2(a1)
    cmp.w   #JUMP,(a1)          ; if old stuff is a jmp someone passed b4 us
    beq     NotFirst

HereFirst:
    move.w  (a0),12(a1)         ; get old moveq code
    move.w  #JUMP,14(a1)        ; put a JMP #longaddr instruction
    move.l  a0,16(a1)           ; get DosBase+offset
    moveq.l #0,d1               ; clear register
    move.w  4(a0),d1            ; get old BRA offset
    addq.l  #4,d1               ; add 4 : offset relative to PC at fetch time
    add.l   d1,16(a1)           ; and add it
    bra     SetJump             ; go set new jump address

NotFirst:
    move.w  #$4E71,12(a1)       ; put a NOP
    move.w  #JUMP,14(a1)        ; put a jmp instruction
    move.l  2(a0),16(a1)        ; get address of the one who passed here

SetJump:
    move.w  #JUMP,(a0)          ; put a JMP #longaddr instruction
    addq.l  #6,a1               ; start of new code
    move.l  a1,2(a0)            ; put new code jumper
    move.w  #JUMP,(a1)          ; put a JMP #longaddr instruction
    move.l  20(a7),2(a1)        ; put address of new function
    move.l  a1,d0
    addq.l  #6,d0               ; this is the "old function ptr"
    move.l  8(a7),a0            ; get DOSBase
    move.l  d0,-(a7)
    jsr     CheckSum            ; calculate checksum
    jsr     -$8A(a6)            ; Permit
    move.l  (a7)+,d0
    move.l  (a7)+,a6
    rts


*   UnWedge
*
*     On entry, on the stack we have:
*
*       sp+12:  backup area (10 words == 20 bytes)
*       sp+8 :  offset of function in DosBase   
*       sp+4 :  DosBase
*       sp   :  return address (what did ya think?)
*
*     You can declare the UnWedge function like this in Lattice 5.10:
*
*     void __stdargs UnWedge (struct DosBase *, LONG Offset, WORD *Backup);
*

    XDEF    _UnWedge

_UnWedge:
    move.l  a6,-(a7)
    move.l  4,a6
    jsr     -$84(a6)            ; Forbid
    move.l  8(a7),a0            ; DosBase
    add.l   12(a7),a0           ; offset
    move.l  16(a7),a1           ; backup area
    move.l  a1,d0               ; get our new function address
    addq.l  #6,d0
    cmp.l   2(a0),d0            ; check if it's in DosBase
    beq     Alone

NotAlone:
    move.l  2(a0),a0            ; get the address of the one who passed here
    subq.l  #6,a0               ; get start of his backup
    cmp.l   2(a0),d0            ; check if its backup contains that
    bne     NotAlone            ; if not, get next in "list"
    move.w  12(a1),12(a0)       ; copy noop or moveq
    move.l  16(a1),16(a0)       ; modify its "old function pointer"

Alone:
    move.w  (a1),(a0)           ; no one passed after us
    move.l  2(a1),2(a0)         ; so we restore what was there
    move.l  8(a7),a0            ; get DOSBase
    jsr     CheckSum            ; do checksum
    jsr     -$8A(a6)            ; Permit
    move.l  (a7)+,a6
    rts

CheckSum:
    move.l  a0,a1
    move.w  16(a1),d0
    lsr.w   #1,d0
    moveq.l #0,d1
    bra     later
loop:
    add.w   -(a1),d1
later:
    dbf     d0,loop
    move.w  d1,28(a0)
    rts

    end
