{$M 16384, 0, 16384}
type
	TEPB = record
		Env: Word;
		PCmd: Pointer;
		PFCB1: Pointer;
		PFCB2: Pointer;
		PRest: Pointer;
		PQuit: Pointer;
	end;

const
	Cmd: array[1..2] of Char = (#0,#13);
	ExeProg: array[1..9] of Char = ('T','E','S','T','.','E','X','E',#0);

var
	FCBs: array[1..2,1..16] of Byte;
	Handle: Word;
	Header: array[1..32] of Byte;
	LastPSP: Word;

const
	EPB: TEPB = (Env: 0;
							 PCmd: @Cmd;
							 PFCB1: @FCBs[1,1];
							 PFCB2: @FCBs[2,1];
							 PRest: nil;
							 PQuit: nil);

function ReadHeader: Word;
assembler;
asm
	MOV     AX,3D02H
	LEA     DX,ExeProg
	INT     21H
	JC      @Error
	MOV     Handle,AX
	XOR     AX,AX
	MOV     AH,3FH
	MOV     BX,Handle
	MOV     CX,32
	LEA     DX,Header
	INT     21H
	JC			@Error
	MOV     AH,3EH
	MOV     BX,Handle
	INT     21H
	JC      @Error
	XOR			AX,AX
@Error:
end;{ function ReadHeader }

function LoadExecutionFile: Word;
assembler;
asm
	MOV     AH,4BH                 { Загружаем в освобожденную память }
	MOV     AL,1                   { программу, указанную }
	LEA     BX,EPB                 { в переменной ExeProg }
	LEA     DX,ExeProg
	INT     21H
	JC      @Error
	MOV     AH,62H
	INT     21H
	MOV     LastPSP,BX
@Error:
end;{ function LoadExecutionFile }

procedure RunExecutionFile;
assembler;
asm
	JMP     @Next
@SaveDS:
	DW  		0
@Next:
	MOV     BX,LastPSP
	ADD     BX,10H                 { Настраиваем SS:SP на стек загруженной }
	MOV     SP,WORD PTR Header.10H
	MOV     AX,BX                  { программы }
	ADD     AX,WORD PTR Header.0EH
	MOV     SS,AX
	MOV     AX,BX
	ADD     AX,WORD PTR Header.16H
	PUSH    AX                     { Устанавливаем точку входа в }
	MOV     AX,WORD PTR Header.14H { программу }
	PUSH    AX
	SUB     BX,10H
	MOV     AX,DS
	MOV     Word Ptr @SaveDS,AX
	MOV     DS,BX                  { Настраиваем DS и ES на новый PSP }
	MOV     ES,BX
	LEA     DX,@Rest
	MOV     BX,0AH
	MOV     [BX],DX                { Точку возврата на @Rest }
	RETF
@Rest:                           { Восстанавливаем DS после отработки }
	MOV     AX,Word Ptr @SaveDS    { в чужой программе }
	MOV     DS,AX
end;{ procedure RunExecutionFile }

begin
	if (ReadHeader = 0) then begin
		if (LoadExecutionFile = 0) then {};
		RunExecutionFile;
	end;{ if..}
end.{ Программа загрузки (отдельно) и запуска exe-файлов }
