jumps
.286
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
;------------- Interceptor -------------
        mov ax, 3d00h
        mov dx, offset _iname
        int 21h
        jc IOErr
        mov bx, ax

        mov ah, 3fh
        mov dx, offset buffer
        mov cx, 07B00h
        int 21h

        mov _isize, ax

        mov ah, 3eh
        int 21h
;------------- Interceptor -------------

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

        mov ah, 3fh
        mov dx, offset header
        mov cx, 28
        int 21h
;------------- 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
        test cx, cx
        jz pass_error
        ;-----------------------------------
        ; Done

        lea di, [buffer+21Eh]
        mov cx, 9
        call encode

;------------- Header ------------------
        mov ax, word ptr header + 22                    ; Old rCS1
        mov word ptr buffer + 11, ax                    ; Save
        mov ax, word ptr header + 20                    ; Old rIP1
        mov word ptr buffer + 9, ax                     ; Save


        ;My new entry-point calculation method
;        mov bx, [header+8]
;        mov cx, bx
;        shr bx, 5
;        mov ax, [header+4]
;        dec ax
;        sub ax, bx      ; AX - 512b page count

;        and cx, 11111b
;        shl cx, 4
;        mov bx, [header+2]
;        sub bx, cx      ; BX - partial page size
;        sbb ax, 0

;        mov [cntH], ax
;        mov [cntL], bx
;        add bx, 10      ; Ten bytes for test_pass
 ;       adc ax, 0
         
;        and bx, 111111111b
;        and ax, 11111111111b

;        mov cx, ax
;        shl cx, 5
;        mov dx, bx
;        shr bx, 4
;        add cx, bx      ; CX - new rCS2
;        and dx, 0Fh     ; DX - new rIP2
        
        ; My second method 
;        mov bx, handle
        mov ax, 4202h
        xor cx, cx
        xor dx, dx
        int 21h ; In dx-ax we got size

        xor bx, bx
        mov cx, [header+8]
        clc 
        rcl cx, 1
        rcl bx, 1

        rcl cx, 1
        rcl bx, 1

        rcl cx, 1
        rcl bx, 1

        rcl cx, 1
        rcl bx, 1

        sub ax, cx
        sbb dx, bx

        mov [cntH], dx
        mov [cntL], ax

        and dx, 1111b
        shl dx, 12
        mov cx, ax
        shr cx, 4
        or  dx, cx
        and ax, 1111b


        mov [buffer+15], dx     ; Code segment
        mov [header+22], dx
        mov [header+14], dx

        mov [buffer+13], ax     ; Code offset
        mov [header+20], ax
        xor ax, ax
        not ax
        mov [header+16], ax

        mov dx, [header+6]                              ; Relocation table item count
        mov [buffer+17], dx

        mov cx, dx
        shr cx, 7
        and dx, 1111111b
        shl dx, 2

        mov ax, [header+2]
        add ax, _isize
        add ax, dx

        mov bx, ax
        shr bx, 9
        add bx, cx
        add [header+4], bx
        and ax, 1FFh
        mov [header+2], ax
;------------- Header ------------------



;------------- Host --------------------
        mov bx, handle
        mov ax, 4202h
        xor cx, cx
        xor dx, dx
        int 21h

        mov ah, 40h
        mov cx, _isize
        mov dx, offset buffer
        int 21h

        mov ah, 3eh
        int 21h

        mov ax, 3d02h
        mov dx, offset _hname
        int 21h
        mov bx, ax
        mov handle, ax


;------------- Host --------------------
;--- Add to host additional relocation table ---
        mov word ptr [lastOffsH], 0
        mov ax, [header+18h]
        mov [lastOffsL], ax

big_loop:
        cmp [header+6], 100
        jl small_loop
        sub [header+6], 100
        mov ax, 4200h
        mov cx, [lastOffsH]
        mov dx, [lastOffsL]
        int 21h

        mov ah, 3fh
        mov dx, offset reloBuf
        mov cx, 400
        int 21h

        mov cx, 399
        mov di, offset reloBuf
        call addmagic
        mov di, offset reloBuf
        call encode

        mov ax, 4202h
        xor cx, cx
        xor dx, dx
        int 21h

        mov ah, 40h
        mov cx, 400
        mov dx, offset reloBuf
        int 21h

        mov ax, 4200h
        mov cx, [lastOffsH]
        mov dx, [lastOffsL]
        int 21h

        mov ah, 40h
        mov cx, 400
        mov dx, offset zeroBuf
        int 21h

        add [lastOffsL], 400
        adc [lastOffsH], 0
        jmp big_loop

small_loop:
        mov ax, 4200h
        mov cx, [lastOffsH]
        mov dx, [lastOffsL]
        int 21h

        mov ah, 3fh
        mov dx, offset reloBuf
        mov cx, [header+6]
        sub [header+6], cx
        shl cx, 2
        push cx
        int 21h

        dec cx
        mov di, offset reloBuf
        call addmagic
        mov di, offset reloBuf
        call encode

        mov ax, 4202h
        xor cx, cx
        xor dx, dx
        int 21h

        mov ah, 40h
        pop cx
        push cx
        mov dx, offset reloBuf
        int 21h

        mov ax, 4200h
        mov cx, [lastOffsH]
        mov dx, [lastOffsL]
        int 21h

        mov ah, 40h
        pop cx
        mov dx, offset zeroBuf
        int 21h

        ; Write EXE header
        mov ax, 4200h
        mov bx, handle
        xor cx, cx
        xor dx, dx
        int 21h

        mov ah, 40h
        mov cx, 28
        mov dx, offset header
        int 21h

        ; Calculate count of encode bytes
        mov dx, [cntL]
;        mov cx, ax
 ;       shr cx, 7
  ;      and ax, 1111111b
   ;     shl ax, 9
        mov cx, [cntH]
;        add dx, ax
 ;       adc cx, 0

        assume cs:cseg, ds:dseg, es:dseg
        mov ax, seg dseg
        mov es, ax
        mov ds, ax
        
        mov bx, cs:[header+8]
        mov ax, bx
        shr ax, 12
        mov cs:[lastOffsH], ax
        shl bx, 4
        mov cs:[lastOffsL], bx

        mov bx, [handle]

        push dx        
seg_loop:
        test cx, cx
        jz no_seg
;        jnz begins
;        cmp dx, 20000
 ;       jb no_seg
begins: push cx
;        push dx        
        mov ax, 4200h
        mov cx, cs:[lastOffsH]        
        mov dx, cs:[lastOffsL]
        int 21h

        mov ah, 3Fh     ; Read segment of 
        mov cx, 0ffffh  ; input file
        mov dx, 0       ;
        int 21h         ;
        mov ah, 3Fh     ; Read segment of 
        mov cx, 1h      ; input file
        mov dx, 0ffffh  ;
        int 21h         ;

        xor di, di
        xor cx, cx
        not cx
        call addmagic
        call encode

        mov ax, 4200h
        mov cx, cs:[lastOffsH]        
        mov dx, cs:[lastOffsL]
        int 21h

        mov ah, 40h     ; Write segment to
        mov cx, 0FFFFh   ; the input file
        mov dx, 0       ;
        int 21h         ;
        mov ah, 40h     ; Write segment to
        mov dx, 0FFFFh   ; the input file
        mov cx, 1       ;
        int 21h         ;

;        add cs:[lastOffsL], 20000
;        adc cs:[lastOffsH], 0
        inc cs:[lastOffsH]

;        pop dx
        pop cx
 ;       sub dx, 20000
  ;      sbb cx, 0
        dec cx
        jmp seg_loop
no_seg: 
        mov ax, 4200h
        mov cx, cs:[lastOffsH]        
        mov dx, cs:[lastOffsL]
        int 21h
        mov ah, 3Fh     ; Read data of 
        pop cx          ; input file
        push cx
        mov dx, 0       ;
        int 21h         ;

        xor di, di
        pop cx
        push cx
        dec cx
        call addmagic
        xor di, di
        call encode

        mov ax, 4200h
        mov cx, cs:[lastOffsH]        
        mov dx, cs:[lastOffsL]
        int 21h

        mov ah, 40h     ; Write segment to
        pop cx
        mov dx, 0       ;
        int 21h         ;

        pop dx
        ; Close host file
        mov ah, 3eh
        int 21h
        ;- Done
;--------------------------------------------------        
        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
cntH            dw 0
cntL            dw 0
io_err_str      db 'Error in file io', 0dh, 0ah, '$'
enter_pass db 'Please enter pass: $'
errstr     db 'usage: "crypt.exe source"', 0dh, 0ah,'$'
_hname          db 13 dup (0)
_iname          db 'interc.com',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          dw 07B00h dup (?)
ends
dseg segment para public 'DATA'
file_buf db 0FFFFh dup (?)
ends
sseg segment stack
 db 200 dup (?)
ends
end start