jumps
.286
cBUF_SIZE   equ 512

cseg segment byte public 'CODE'
        assume cs:cseg, ds:cseg, es:cseg
start:
        mov ax, seg cseg
        mov es, ax
        push ax

        mov si, 80h
        cmp byte ptr ds:[si], 0
        je errusg
        xor ax, ax
        mov al, ds:[si]
        dec ax
        mov cx, ax
        inc si
        inc si

        mov di, offset _hname

lp:     cmp byte ptr ds:[si], 0dh
        je wrk
        movsb
        loop lp

wrk:    pop ds

;------------- Host --------------------
        mov ax, 3d02h
        mov dx, offset _hname
        int 21h
        jc IOErr
        mov bx, ax
        mov handle, ax
;------------- Host --------------------

;------- Password ----------------------
        mov ah, 09h
        mov dx, offset enter_pass
        int 21h
        ; Read password from stdin
        ;-------------------------------
        lea di, [pass]
        mov cx, 20
chrloop:mov ah, 08h
        int 21h
        cmp al, 0Dh
        jz pass_end
        stosb
        mov ah, 02h
        mov dl, '*'
        int 21h
        dec cx
        jnz chrloop
pass_end:
        mov ah, 09h
        mov dx, offset newline
        int 21h
        sub cx, 20
        neg cx
        mov [pass_len], cx
        cmp cx, 3
        jl pass_error
        ;-----------------------------------
        ; Done

;-------------------------
; Encode all the file
;------------------------- 
        ; Calculate count of encoded bytes
        mov ax, 4202h
        xor cx, cx
        xor dx, dx
        int 21h

        mov cx, dx      ; Hi part
        mov dx, ax      ; Lo part

        sub dx, 2
        sbb cx, 0

        push cx
        push dx

        mov bx, handle
        mov ax, 4200h
        xor cx, cx
        mov dx, 2
        int 21h

        pop dx
        pop cx
buf_loop:
        push cx
        push dx

        sub dx, cBUF_SIZE
        sbb cx, 0
        jl last_buf

begins:
        mov ah, 3Fh             ; Read full buffer of
        mov cx, cBUF_SIZE       ; EXECing file
        lea dx, ds:[buffer]
        int 21h         

        mov cx, ax
        dec cx
        lea di, ds:[buffer]
        call addmagic
        lea di, ds:[buffer]
        call encode 

        mov ax, 4201h
        mov dx, cBUF_SIZE
        neg dx
        xor cx, cx
        not cx
        int 21h

        mov ah, 40h     ; Write segment to
        mov cx, cBUF_SIZE ; the input file
        lea dx, ds:[buffer]
        int 21h         ;

        pop dx
        pop cx

        sub dx, cBUF_SIZE
        sbb cx, 0
        jmp buf_loop

last_buf:
        pop cx
        pop dx

        mov ah, 3Fh     ; Read data of
        push cx
        lea dx, ds:[buffer]
        int 21h         ;

        lea di, ds:[buffer]
        pop cx
        push cx
        dec cx
        lea di, ds:[buffer]
        call addmagic
        lea di, ds:[buffer]
        call encode 

        mov ax, 4201h
        pop dx
        push dx
        neg dx
        xor cx, cx
        not cx
        int 21h

        mov ah, 40h     ; Write segment to
        pop cx
        lea dx, ds:[buffer]
        int 21h         ;
        ;- Done 
 close:
  mov ah,3eh                                ;close file
  int 21h

;--------------------------------------------------        
        mov ah, 4ch
        int 21h
;--------------------------------------------------
;==================================================
;--------------------------------------------------
pass_error:
        mov dx, offset bad_pass
        mov ah, 09h
        int 21h

        mov ax, 4cFFh
        int 21h
errusg: pop ds
        mov ah, 09h
        mov dx, offset errstr
        int 21h
        mov ax, 4cFEh
        int 21h

IOErr: mov ah, 09h
        mov dx, offset errstr
        int 21h
        mov ax, 4cFDh
        int 21h

;-----------------------------------------------
encode proc near 
        push si
        push ax
        push cx
loops2: mov si, offset pass
        cmp cx, cs:[pass_len]
        jb lasts2
        push cx
        mov cx, cs:[pass_len]
addmag2: mov al, cs:[si]
        xor es:[di], al
        inc si
        inc di
        loop addmag2
        pop cx
        sub cx, cs:[pass_len]
        jmp loops2

lasts2: inc cx
lasts3: mov al, cs:[si]
        xor es:[di], al
        inc si
        inc di
        loop lasts3

        pop cx
        pop ax
        pop si
        ret
endp

addmagic proc near 
        push si
        push ax
        push cx
loops:  mov si, offset test_pass
        cmp cx, 10
        jb lasts
        push cx
        mov cx, 10
addmag: mov al, cs:[si]
        add es:[di], al
        inc si
        inc di
        loop addmag
        pop cx
        sub cx, 10
        jmp loops

lasts:  inc cx
lasts0: mov al, cs:[si]
        add es:[di], al
        inc si
        inc di
        loop lasts0

        pop cx
        pop ax
        pop si
        ret
endp

test_pass db 10, 12, 15, 17, -20, -13, 05, -30, 55, -51
io_err_str      db 'Error in file io', 0dh, 0ah, '$'
enter_pass db 'Please enter pass: $'
errstr     db 'usage: "coder.exe source"', 0dh, 0ah,'$'
_hname          db 13 dup (0)
bad_pass        db 'Bad password',0dh,0ah,'$'
newline         db 0dh,0ah,'$'
zeroBuf         db 400 dup (0)
pass            db 20 dup (0)
pass_len        dw ?
handle          dw ?
header          dw 14 dup (?)
_isize          dw ?
lastOffsH       dw ?
lastOffsL       dw ?
rCS2            dw ?
rIP2            dw ?
reloBuf         dw 200 dup (?)
buffer          db cBUF_SIZE dup (?)
ends
ends

sseg segment stack
 db 200 dup (?)
ends
end start