{=============}  UNIT F_Jump;  {==============}
{
 +----------------------------------------------------------+
 | Модуль  содержит макроопределения, позволяющие запомнить |
 | любую точку программы с тем, чтобы после обработки ошибки|
 | периода исполнения передать управление в эту точку.      |
 +----------------------------------------------------------+
}
                   INTERFACE
type
  JumpRec = record
    SPsave,            {Сохраняет регистр SP}
    BPsave: Word;      {Сохраняет регистр DP}
    JmpPtr: Pointer    {FAR-адрес продолжения}
  end;  {JumpRec}
{-------------------}
Procedure SetJump(var JumpDest: JumpRec);
  {Этот макрос обеспечивает сохранение содержимого регистров
   SP,BP и IP в записи JumpDest. Запоминается состояние,
   которое имели регистры в момент вызова макроса. Это
   обеспечивает последующий возврат процедурой LongJump в точку,
   непосредственно следующую за вызовом.}
InLine(
  $5F/
    {pop    di           ;DI=Ofs(JumpDest)     }
  $07/
    {pop    es           ;ES=Seg(JumpDest)     }
  $26/$89/$25/
    {mov    es:[di],sp   ;помещаем SP в SPsave }
  $26/$89/$6D/$02/
    {mov    es:[di+2],bp ;помещаем BP в BPsave }
  $E8/$00/$00/
    {call   null       	;помещаем в стек текущий	}
    {null:               	;адрес командой CALL  	}
  $58/
    {pop    ax           	;АХ=текущий адрес	}	
  $05/$0C/$00/
    {add    ax,12        	;смещение команды NEXT	}
  $26/$89/$45/$04/
    {mov    es:[di+4],ax 	;сохраняем FAR-адрес	}
  $26/$8C/$4D/$06);
    {mov    es:[di+6],cs ;команды NEXT в JmpPtr	}
    {NEXT: ; эта инструкция идет сразу за макросом и связана
	с началом очередного оператора Турбо Паскаля}
{-------------------}
Procedure LongJump(var JumpDest: JumpRec);
  {Этот макрос восстанавливает содержимое регистров SP и BP
  из полей SPsave, BPsave записи JumpDest и делает
   FAR-переход по адресу JmpPtr.}

inline(
  $5F/
   {pop    di              ;DI=Ofs(JumpDest) 	}
  $07/
   {pop    es              ;ES=Seg(JumpDest)	}
  $26/$8B/$25/
   {mov    sp,es:[di]      ;восстанавливаем SP	}
  $26/$8B/$6D/$02/
   {mov    sp,es:[di+2]    ;восстанавливаем BP	}
  $26/$FF/$6D/$04);
   {jmp    far es:[di+4]   ;FAR-переход       	}
               IMPLEMENTATION
{============} end. {F_Jump} {=============}
