9. STR_INSERT

*------------------------------------------------------------------------------
* NAME          STR_INSERT
*------------------------------------------------------------------------------
* DEPENDENCY    STR_APPEND
* PURPOSE       Insert the string at (A2) into the string at (A1) at pos D0.
* DESCRIPTION   Inserts the string whose address is passed in A2 into the string
*               whose address is passed in A1 at the position passed in D0.W so
*               the first character in the inserted string will be character D0
*               after the insertion. (Zero is the very first character !)
*               If D0 >= length (A1) then call STR_APPEND to do the work.
* INPUTS :
*               A1.L = Address of the receiving string
*               A2.L = Address of the string to be inserted
*               D0.W = Position (starting at 0) where to insert before
* OUTPUTS :
*               D0 = Error code
*               A1.L = Address of the receiving string (preserved)
*               A2.L = Address of the string to be inserted (preserved)
*               Z flag set if no errors, unset otherwise.
*------------------------------------------------------------------------------
str_insert  cmp.w   d0,(a1)             ; Are we appending perhaps ?
            bge     str_append          ; Yes, easy case to deal with !
            tst.w   d0                  ; Is there anything in D0 ?
            bge.s   si_ok               ; Yes, negatives are bad !
            moveq   #-15,d0             ; Bad parameter
            rts                         ; Z is unset, D0 = error code

si_ok       movem.l d1/a1-a4,-(a7)      ; Save those workers
            move.l  a1,a3               ; A3 = Address of A1 string
            adda.w  (a1),a3             ; Plus the size ...
            addq.l  #2,a3               ; A3 = final char of A1 string plus one.
            move.l  a3,a4               ; A4 to be the new last char after insert
            adda.w  (a2),a4             ; Add the extra length to the last character
            addq.l  #2,a4               ; And now we are there (plus one)
            move.w  (a2),d1             ; Size of inserted string
            bra.s   si_dnext            ; Skip dbra
si_dmove    move.b  -(a3),-(a4)         ; Move a byte
si_dnext    dbra    d1,si_dmove         ; Do the rest
            move.w  (a2),d1             ; Fetch the inserted length again
            adda.w  d1,a2               ; A2 now nearly at the last character
            addq.w  #2,a2               ; One past the last character
            bra.s   si_inext            ; Skip dbra stuff
si_imove    move.b  -(a3),-(a4)         ; Insert a byte
si_inext    dbra    d1,si_imove         ; Insert the rest
            movem.l (a7)+,d1/a1-a4      ; Restore those workers
            clr.l   d0                  ; No errors
            rts