Printable .COM file, 106 bytes
^FZXjlXD4l@PL\H,LPXD$$4"PXD,lHPXDjJXDRDX@PXDjtXDH,nPXDj@XD4`@PXD,ZHPXD4,@PXD4:4"PXDH,\PXD4"PXD,hPXDRDX@P\\
Hexdump:
00000000 5e 46 5a 58 6a 6c 58 44 34 6c 40 50 4c 5c 48 2c |^FZXjlXD4l@PL\H,|
00000010 4c 50 58 44 24 24 34 22 50 58 44 2c 6c 48 50 58 |LPXD$$4"PXD,lHPX|
00000020 44 6a 4a 58 44 52 44 58 40 50 58 44 6a 74 58 44 |DjJXDRDX@PXDjtXD|
00000030 48 2c 6e 50 58 44 6a 40 58 44 34 60 40 50 58 44 |H,nPXDj@XD4`@PXD|
00000040 2c 5a 48 50 58 44 34 2c 40 50 58 44 34 3a 34 22 |,ZHPXD4,@PXD4:4"|
00000050 50 58 44 48 2c 5c 50 58 44 34 22 50 58 44 2c 68 |PXDH,\PXD4"PXD,h|
00000060 50 58 44 52 44 58 40 50 5c 5c |PXDRDX@P\\|
0000006a
Using a very loose definition of source as something that can be reasonably typed by a human, and inspired by EICAR Standard Antivirus Test File (more info at "Let's have fun with EICAR test file" at Bugtraq).
Using only printable non-odd ASCII bytes (side note: opcodes affecting words tend to be odd, the W bit is the lsb of some opcodes), it constructs a fragment of code at SP (which we conveniently set just past our generating code), and execution ends up falling through to the generated code.
It uses the fact that the stack initially contains a near pointer to the start of the PSP, and that the start of the PSP contains the INT 20h instruction (more info on this at http://stackoverflow.com/questions/12591673/).
Real source:
; we want to generate the following fragment of code
; 5E pop si ; zero SI (pop near pointer to start of PSP)
; 46 inc si ; set SI to 1
; loop:
; B406 mov ah,0x6 ; \
; 99 cwd ; >
; 4A dec dx ; > D-2106--DLFF
; CD21 int 0x21 ; > DIRECT CONSOLE INPUT
; 7405 jz end ; > jump if no more input
; 40 inc ax ; > lsb 0/1 odd/even
; 21C6 and si,ax ; > zero SI on first odd byte
; EBF3 jmp short loop ; /
; end:
; 96 xchg ax,si ; return code
; B44C mov ah,0x4c ; D-214C
; CD21 int 0x21 ; TERMINATE WITH RETURN CODE
pop si ; this two opcodes don't need to be encoded
inc si
pop dx ; DX = 20CD (int 0x20 at start of PSP)
pop ax
push byte +0x6c
pop ax
inc sp
xor al,0x6c
inc ax
push ax
dec sp
pop sp ; SP = 0x016C
dec ax
sub al,0x4c ; B4
push ax
pop ax
inc sp
and al,0x24
xor al,0x22 ; 06
push ax
pop ax
inc sp
sub al,0x6c
dec ax ; 99
push ax
pop ax
inc sp
push byte +0x4a ; 4A
pop ax
inc sp
push dx ; [20]CD
inc sp
pop ax
inc ax ; 21
push ax
pop ax
inc sp
push byte +0x74 ; 74
pop ax
inc sp
dec ax
sub al,0x6e ; 05
push ax
pop ax
inc sp
push byte +0x40 ; 40
pop ax
inc sp
xor al,0x60
inc ax ; 21
push ax
pop ax
inc sp
sub al,0x5a
dec ax ; C6
push ax
pop ax
inc sp
xor al,0x2c
inc ax ; EB
push ax
pop ax
inc sp
xor al,0x3a
xor al,0x22 ; F3
push ax
pop ax
inc sp
dec ax
sub al,0x5c ; 96
push ax
pop ax
inc sp
xor al,0x22 ; B4
push ax
pop ax
inc sp
sub al,0x68 ; 4C
push ax
pop ax
inc sp
push dx ; [20]CD
inc sp
pop ax
inc ax
push ax ; 21
pop sp ; now get the stack out of the way
pop sp ; dummy insn for even alignment