;       Static Name Aliases
;
        TITLE   substr
;       NAME    substr.C

;   char *substr(destination, source, offset, length)
;
;   copies length bytes from source+offset to destination, stopping
;   early if a NUL is encountered.  The difference between this and
;
;   strncpy(destination, source+offset, length)
;
;   is that if the offset is negative, it has the same effect as 0,
;   and if it exceeds strlen(source), it has the same effect as
;   strlen(source).
;
;   After the substring of source is moved to destination, a NUL byte
;   is moved to terminate the string, and the result is a pointer to
;   this NUL byte, ready to have new stuff stuck on the end.

        .287
_TEXT   SEGMENT  BYTE PUBLIC 'CODE'
_TEXT   ENDS
_DATA   SEGMENT  WORD PUBLIC 'DATA'
_DATA   ENDS
CONST   SEGMENT  WORD PUBLIC 'CONST'
CONST   ENDS
_BSS    SEGMENT  WORD PUBLIC 'BSS'
_BSS    ENDS
DGROUP  GROUP   CONST,  _BSS,   _DATA
        ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
_TEXT      SEGMENT

        PUBLIC  _substr
_substr PROC NEAR
        push    bp
        mov     bp,sp
        push    di
        push    si
        mov     di,[bp+4]       ;dst
        mov     si,[bp+6]       ;src

;       dst = 4
;       register di = dst
;       src = 6
;       register si = src
;       off = 8
;       len = 10

        mov     cx,[bp+8]               ;off
        cmp     cx,0                    ;off
        jge     $WC14
        xor     cx,cx
$WC14:
        jcxz    $ck_len
        inc     si
        dec     cx
        cmp     BYTE PTR [si-1],0
        jne     $WC14
$L20004:
        mov     BYTE PTR [di],0
        mov     ax,di
        jmp     SHORT $EX13
$ck_len:
        mov     cx,word ptr [bp+10]
$WB15:
        jcxz    $L20004
        dec     cx                  ;len
        lodsb
        stosb
        or      al,al
        jne     $WB15
        lea     ax,[di-1]
$EX13:
        pop     si
        pop     di
        mov     sp,bp
        pop     bp
        ret

_substr ENDP
_TEXT   ENDS
END
