Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
101
Добавлен:
26.05.2014
Размер:
104 Кб
Скачать
{$A+,B-,D+,E+,F-,G+,I-,L+,N+,O-,P-,Q+,R-,S-,T-,V+,X+}
{$M 16384,0,655360}
Unit a96sim;
interface
Const
  { Є®­бв ­вл, ЇҐаҐ¤ ў Ґ¬лҐ Є®­бвагЄв®аг TSimulator.init }
  MCS_BH    = 0;
  MCS_JF    = 1;
  MCS_KB    = 2;
  MCS_KC    = 3;
  MCS_KD    = 4;
  MCS_KR    = 5;
  MCS_JR    = 6;
  MCS_KQ    = 7;
  MCS_JQ    = 8;
  MCS_KT    = 9;
  MCS_KS    = 10;
  MCS_NT    = 11;
  MCS_NQ    = 12;
  MCS_MC    = 13;
  MCS_MD    = 14;

  { ¬ бЄЁ ЎЁв®ў д« Ј®ў, ­ «®¦Ґ­­лҐ ­  PSW }
  Flag_ST   = $01;
  Flag_I    = $02;
  Flag_PSE  = $04;
  Flag_C    = $08;
  Flag_VT   = $10;
  Flag_V    = $20;
  Flag_N    = $40;
  Flag_Z    = $80;

  { ¬ бЄЁ ЎЁв®ў ЇаҐалў ­Ё©, ­ «®¦Ґ­­лҐ ­  IntSignals }
  int_16    = $0001;
  int_15    = $0002;
  int_14    = $0004;
  int_13    = $0008;
  int_12    = $0010;
  int_11    = $0020;
  int_10    = $0040;
  int_9     = $0080;
  int_8     = $0100;
  int_7     = $0200;
  int_6     = $0400;
  int_5     = $0800;
  int_4     = $1000;
  int_3     = $2000;
  int_2     = $4000;
  int_1     = $8000;

  { вЁЇл Ё гбва®©вў  MCS }
  MF_Vwindow = $0001;
  MF_Hwindow = $0002;
  MF_BH      = $0000;
  MF_KB      = $2000;
  MF_KC      = $4000;
  MF_KR      = $6000;
  MF_NT      = $8000;
  MF_MC      = $A000;
  MF_SLP     = $0004;
  MF_TI5     = $0008;
  MF_Mask    = $E000;

  MF_FG      = $0010;
  MF_MD      = $0020;


Type
  { ®б­®ў­®© ®ЎкҐЄв н¬г«пв®а  }
  TSimulator = Object
     Addr1, Addr2, Addr3 : Word; { гб«®ў­лҐ  ¤аҐб  а §¤Ґ«Ґ­Ёп Ї ¬пвЁ,
                                   ўлбв ў«повбп Є®­бвагЄв®а®¬ init }

     PortsLegs : Array[0..8] Of Byte; { б®бв®п­ЁҐ ўе®¤®ў/ўл室®ў Є ¦¤®Ј®
                                       Ї®ав  P0..P7,EP }
     IntSignals : Word;  { ¬ ббЁў ЎЁв®ў § Їа®б  ЇаҐалў ­Ёп
                           Ї®б«Ґ Є ¦¤®Ј® Step бЎа блў Ґвбп. б¬. int_xxx }

     Memory  : Pointer;
     IDLPD   : Byte; { =0 - ­®а¬ «м­л© ०Ё¬ а Ў®вл
                       =1 - idle ( ०Ё¬ е®«®бв®Ј® 室 )
                       =2 - Powerdown (०Ё¬ Ї®­Ё¦Ґ­®Ј® н«Ґва®Ї®вॡ«Ґ­Ёп) }
     ErFlag : Boolean; { True - ®иЁЎ®з­ п Є®¬ ­¤  «Ё ­ҐўҐа­л©  ¤аҐб }

     { Ќ Їа殮­Ёп ¤«п Ђ–Џ }
     Vref  : Real; { ­ Їа殮­ЁҐ ­  ўе®¤Ґ Vref }
     ANGND : Real; { ­ Їа殮­ЁҐ ­  ўе®¤Ґ ANGND }
     Uin   : Array[0..13] of Real; { P0, P1  ­ «®Ј®ў®Ґ ­ Їа殮­ЁҐ }


     { Read Only }
     PC     : Word;
     PSW    : Word;
     PPW    : Word;

     MCSFunc : Word; { ­ Ў®а ў®§¬®¦­®б⥩ б¬. MF_xxx }
     reg_x  : Word;

     P_Out : Array[0..8] Of Byte; { зЁб«® ўлў®¤®ў,   зЁб«® ўлў®¤®ў  «мвҐа.дг­ЄжЁ© }


     { ॣЁбвал }
     AD_COMMAND : ^Byte;
     AD_RESULT  : ^Word;
     AD_TEST    : ^Byte;
     AD_TIME    : ^Byte;

     COMPx_CON  : Array[0..5] of ^Byte;
     COMPx_TIME : Array[0..5] of ^Word;

     EPA_MASK   : ^Word;
     EPA_MASK1  : ^Byte;
     EPA_PEND   : ^Word;
     EPA_PEND1  : ^Byte;
     EPAx_CON  : Array[0..9] Of ^Byte;
     EPAx_TIME : Array[0..9] Of ^Word;
     EPAIPV     : ^BYTE;

     INT_MASK   : ^Byte;
     INT_MASK1  : ^Byte;
     INT_PEND   : ^Byte;
     INT_PEND1  : ^Byte;

     IRAM_CON   : ^Byte;
     ONES_REG   : ^Word;
     PX_MODE, PX_DIR, PX_REG, PX_PIN : Array[0..8] Of ^Byte;{ nil - ॣЁбва ®вбгвбвўгҐв }
     P34_DRV    :  ^Byte;
     PTSSEL     : ^Word;
     PTSSRV     : ^Word;
     SBUF_RX    : ^Byte;
     SBUF_TX    : ^Byte;
     SLP_CMD    : ^Byte;
     SLP_CON    : ^Byte;
     SLP_STAT   : ^Byte;
     SP         : ^Word;
     SP_BAUD    : ^Word;
     SP_CON     : ^Byte;
     SP_STAT    : ^Byte;
     SSIO_BAUD  : ^Byte;
     SSIOx_BUF  : Array[0..1] of ^Byte;
     SSIOx_CON  : Array[0..1] Of ^Byte;
     TxCONTROL  : Array[1..2] Of ^Byte;
     TIMERx     : Array[1..2] Of ^Word;
     USFR       : ^Byte;
     WATCHDOG   : ^Byte;
     WSR        : ^Byte;
     ZERO_REG   : ^Word;

     T1RELOAD   : ^Word;
     WG_COMPx   : Array[1..3] Of ^Word;
     WG_CONTROL : ^Word;
     WG_COUNT   : ^Word;
     WG_OUT     : ^Word;
     WG_PROTECT : ^Byte;
     WG_RELOAD  : ^Word;

     PWM_COUNT  : ^Byte;
     PWM_RELOAD : ^Byte;
     PWM_Control: Array[0..2] Of ^Byte;

     FG_COUNT   : ^Byte;
     FG_CON     : ^Byte;
     IOCx       : Array[0..3] Of ^Byte;


     BRGcount: Longint; { бзҐвзЁЄ в Єв®ў®Ј® ЈҐ­Ґа в®а  ¤«п Serial port'a }
     PWMCount: Integer; { бзҐвзЁЄ ¤«п €Њ  }
     WDCount   : Word;  { бзҐвзЁЄ WatchDog в ©¬Ґp  }


     Constructor init( MCSType : Byte); { Ё­ЁжЁ жЁп CPU }
     function    WriteData(Address,Count:Word; Var buf):Boolean; { Їа®жҐ¤га  § ЇЁбЁ ў RAM. True - Ok , False - Error }
     function    ReadData(Address,Count:Word; Var Buf):boolean;  { --//-- з⥭Ёп --//-- }
     Procedure   Reset; { бЁЈ­ « RESET }
     procedure   Step;  { ўлЇ®«­Ёвм и Ј а Ў®вл CPU }
     Destructor  Done; virtual;

     private
     WDDiver   : Integer;

     E11E      : Boolean;
     EPAHold   : Array[0..9] Of Byte;
     COMPHold  : Array[0..5] Of byte;
     BuffReg         : Array[0..9] Of Word;
     COMPBuff        : Array[0..5] Of Word;
     COMPTrigger     : Array[0..5] Of Boolean;
     EPATrigger      : Array[0..9] Of Boolean;
     TxTrigger       : Array[1..4] Of Boolean;
     Fcr4            : Integer;
     PSxDiver        : Array[1..2] Of Integer;
     U               : Real; { Ё§¬Ґа塞®Ґ ­ Їа殮­ЁҐ }
     ADCDiver        : Integer;
     ADCmustGo       : Boolean;
     FGDiver         : Integer;

     PWMDiver        : Integer;
     PWMHoldReg      : Array[0..2] Of Byte;


     SerialPortCount : Byte;
     BRGDiver    : Shortint;
     SSIOBUF     : Array[0..1] Of Byte;
     SSIOCount   : Array[0..1] Of Byte;
     SCxTrigger  : Array[0..1] Of Boolean;
     BRGSSIO     : Byte;
     BRG8        : Byte;
     WorkPTS     : Word;
     OldIntsignals: Word;
     ca          : Boolean;
     int_TI_Mask : Word;
     Int_RI_Mask : Word;
     TriggerP2_1 : Boolean;

     Circles : Word;

     IntEnabled: Boolean;
     Perfex : Byte;
     { ----------------- ЇҐаҐдҐаЁ©­лҐ гбва®©бвў  ----------- }
     function    ICC( Var IntVec:Word):boolean;
         { Є®­ва®««Ґа ЇаҐалў ­Ё©. …б«Ё ў®§­ЁЄ«® ЇаҐалў ­ЁҐ,
             ЇаЁ§­ Є нв®Ј® 1 ў ®ЇаҐ¤Ґ«Ґ­­®¬ а §а拉 IntSignals,
           в® Їа®жҐ¤га  ¤®«¦­  ўҐа­гвм True,   IntVec Ї®¬ҐбвЁвм
           ўҐбва® ЇаҐалў ­Ёп ( ¤аҐб  ¤аҐб  ®Ўа Ў®взЁЄ ).
           ЌЁЄ®Ј¤  ­Ґ ўл§лў Ґвбп ­ Їап¬го. …Ґ ўл§лў Ґв Їа®жҐ¤га  Step. }
     procedure   Ports;
         { ‚л§лў Ґвбп Їа®жҐ¤га®© Step  ўв®¬ вЁзҐбЄЁ, ¤ Ўл ®бгйҐбвўЁвм а Ў®вл
           Ї а ««Ґ«м­ле Ї®ав®ў }
     procedure   SlavePort;
         { ўл§лў Ґвбп Їа®жҐ¤га®© Step  ўв®¬ вЁзҐбЄЁ. ЋбгйҐбвў«пҐв а Ў®вг
           Їа®жҐбб®а­®Ј® Ї®ав  }
     procedure   SerialPort;
     Function    BRG:Boolean;

     Procedure   SSIO;

     Procedure   PWM;
     Procedure   FG;
     Procedure   ADC;
     Procedure   EPA;

     procedure   ExecutePTS(i:Word);
           { WorkPTS:=WorkPTS or i
             㬥­ми Ґв бзҐвзЁЄ. ЏpЁ ®Є®­з ­ЁЁ PTSSEL^:=PTSSEL^ and not i
                                              PTSSRV^:=PTSSRV^ or i
                                              WorkPTS:=WorsPTS or i}

  End;

  function IsPAR( A : Byte):byte;

implementation

constructor TSimulator.init;
const
  Addrs : Array[MCS_BH..MCS_MD,0..3] Of Word=
    (($00FF, $0000, $3FFF, MF_BH),
     ($00FF, $01FF, $5FFF, MF_BH),
     ($00FF, $0000, $3FFF, MF_HWindow or MF_KB),
     ($01FF, $0000, $5FFF, MF_HWindow or MF_KC),
     ($03FF, $0000, $9FFF, MF_HWindow or MF_KC),
     ($01FF, $04FF, $5FFF, MF_VWindow or MF_KR or MF_SLP or MF_TI5),
     ($01FF, $04FF, $5FFF, MF_VWindow or MF_KR or MF_TI5),
     ($017F, $047F, $4FFF, MF_VWindow or MF_KR or MF_SLP or MF_TI5),
     ($017F, $047F, $4FFF, MF_VWindow or MF_KR or MF_TI5),
     ($03FF, $05FF, $9FFF, MF_VWindow or MF_KR or MF_SLP or MF_TI5),
     ($03FF, $04FF, $7FFF, MF_VWindow or MF_KR or MF_SLP or MF_TI5),
     ($03FF, $05FF, $9FFF, MF_VWindow or MF_NT or MF_SLP or MF_TI5),
     ($017F, $047F, $4FFF, MF_VWindow or MF_NT or MF_SLP or MF_TI5),
     ($01FF, $0000, $5FFF, MF_VWindow or MF_MC),
     ($03FF, $0000, $9FFF, MF_VWindow or MF_MC or MF_FG or MF_MD));

  LPortOut : Array[MCS_BH..MCS_MD,0..8] Of Byte= { ABh  A/ॣ }
     (($88,$8D,$8D,$8C,$8C,  0,  0,  0,  0),
      ($88,$8D,$8D,$8C,$8C,  0,  0,  0,  0),
      ($88,$8D,$8D,$8C,$8C,  0,  0,  0,  0),
      ($88,$8D,$8D,$8C,$8C,  0,  0,  0,  0),
      ($88,$8D,$8D,$8C,$8C,  0,  0,  0,  0),
      ($88,$8F,$8F,$8C,$8C,$8F,$8F,  0,  0),
      ($68,$4F,$6F,$8C,$8C,$3F,$6F,  0,  0),
      ($88,$8F,$8F,$8C,$8C,$8F,$8F,  0,  0),
      ($68,$4F,$6F,$8C,$8C,$3F,$6F,  0,  0),
      ($88,$8F,$8F,$8C,$8C,$8F,$8F,  0,  0),
      ($88,$8F,$8F,$8C,$8C,$8F,$8F,  0,  0),
      ($48,$8F,$8F,$8C,$8C,$8F,$8F,  0,$48),
      ($48,$8F,$8F,$8C,$8C,$8F,$8F,  0,$48),
      ($88,$58,$8F,$8C,$8C,$8F,$80,$8F,  0),
      ($88,$88,$8F,$8C,$8C,$8F,$80,$8F,  0));

  Px_BASE : Array[0..8] Of Word=
  ($1FD4, $1FD0, $1FC9, $1FF8, $1FF9, $1FF1, $1FD1, $1FD1, $1FE1);

Function RegAdr(Adr:Word):Pointer;
Var
  D : ^Byte;
Begin
  D:=Memory;
  inc(D, Adr);
  RegADr:=D;
end;

var
  i : Byte;


Begin
  Addr1:=Addrs[MCSType, 0];
  Addr2:=Addrs[MCSType, 1];
  Addr3:=Addrs[MCSType, 2];
  BRGCount:=0;


  getmem(Memory, $FFF2);
  MCSFunc:=Addrs[MCSType,3];
  if MCSFunc and MF_BH<>0 then
  begin
    int_TI_Mask:=0;
    int_RI_Mask:=0;
  end
  Else
  if MCSFunc and MF_TI5<>0 then
  begin
    int_TI_Mask:=int_5;
    int_RI_Mask:=int_4;
  End
  Else
  begin
    int_TI_Mask:=int_8;
    int_RI_Mask:=int_7;
  end;



  fillChar(memory^, Addr3+1, 0);

     AD_COMMAND :=RegAdr($1FAC);
     AD_RESULT  :=RegAdr($1FAA);
     AD_TEST    :=RegAdr($1FAE);
     AD_TIME    :=RegAdr($1FAF);

     COMPx_CON[0]:=RegAdr($1F88);
     COMPx_TIME[0]:=RegAdr($1F8A);
     COMPx_CON[1]:=RegAdr($1F8C);
     COMPx_TIME[1]:=RegAdr($1F8E);
     COMPx_CON[2]:=RegAdr($1F60);
     COMPx_TIME[2]:=RegAdr($1F62);
     COMPx_CON[3]:=RegAdr($1F64);
     COMPx_TIME[3]:=RegAdr($1F66);
     COMPx_CON[4]:=RegAdr($1F68);
     COMPx_TIME[4]:=RegAdr($1F6A);
     COMPx_CON[5]:=RegAdr($1F6C);
     COMPx_TIME[5]:=RegAdr($1F6E);

     EPA_MASK   :=RegAdr($1FA0);
     EPA_MASK1  :=RegAdr($1FA4);
     EPA_PEND   :=RegAdr($1FA2);
     EPA_PEND1  :=RegAdr($1FA6);
     for i:=0 to 9 do
     begin
       EPAx_CON[i]:=RegAdr($1F60+i shl 2);
       EPAx_TIME[i]:=RegAdr($1F62+i shl 2)
     end;
     EPAIPV  :=RegAdr($1FA8);

     INT_MASK   :=RegAdr($8);
     INT_MASK1  :=RegAdr($13);
     INT_PEND   :=RegAdr($9);
     INT_PEND1  :=RegAdr($12);

     IRAM_CON   :=RegAdr($1FF0);
     ONES_REG   :=RegAdr($2);

     for i:=0 to 8 do
     begin
       if LPortOut[MCSType,i] and 1<>0 then PX_MODE[i]:=RegAdr(Px_BASE[i]) Else PX_MODE[i]:=NIL;
       if LPortOut[MCSType,i] and 2<>0 then PX_DIR[i]:=RegAdr(Px_BASE[i]+2) Else PX_DIR[i]:=NIL;
       if LPortOut[MCSType,i] and 4<>0 then PX_REG[i]:=RegAdr(Px_BASE[i]+4) Else PX_REG[i]:=NIL;
       if LPortOut[MCSType,i] and 8<>0 then PX_PIN[i]:=RegAdr(Px_BASE[i]+6) Else PX_PIN[i]:=NIL;
       P_Out[i]:=LPortOut[MCSType, i] shr 4;
       PortsLegs[i]:=$FF;
     End;
     P34_DRV    :=RegAdr($1FF4);
     PTSSEL     :=RegAdr($4);
     PTSSRV     :=RegAdr($6);
     SBUF_RX    :=RegAdr($1FB8);
     SBUF_TX    :=RegAdr($1FBA);
     SLP_CMD    :=RegAdr($1FFA);
     if MCSFunc and MF_SLP<>0 then SLP_CON:=RegAdr($1FFB) Else SLP_CON:=NIL;
     SLP_STAT   :=RegAdr($1FF8);
     SP         :=RegAdr($18);
     SP_BAUD    :=RegAdr($1FBC);
     SP_CON     :=RegAdr($1FBB);
     SP_STAT    :=RegAdr($1FB9);
     SSIO_BAUD  :=RegAdr($1FB4);
     SSIOx_BUF[0]:=RegAdr($1FB0);
     SSIOx_BUF[1]:=RegAdr($1FB2);
     SSIOx_CON[0]:=RegAdr($1FB1);
     SSIOx_CON[1]:=RegAdr($1FB3);
     TxCONTROL[1]:=RegAdr($1F98);
     TxCONTROL[2]:=RegAdr($1F9C);
     TIMERx[1]  :=RegAdr($1F9A);
     TIMERx[2]  :=RegAdr($1F9E);
     USFR       :=RegAdr($1FF6);
     WATCHDOG   :=RegAdr($000A);
     WSR        :=RegAdr($14);
     ZERO_REG   :=RegAdr(0);

     T1RELOAD   :=RegAdr($1F72);
     WG_COMPx[1]:=RegAdr($1FC2);
     WG_COMPx[2]:=RegAdr($1FC4);
     WG_COMPx[3]:=RegAdr($1FC6);
     WG_CONTROL :=RegAdr($1FCC);
     WG_COUNT   :=RegAdr($1FCA);
     WG_PROTECT :=RegAdr($1FCE);

     FG_CON:=RegAdr($1FB8);
     FG_COUNT:=RegAdr($1FBA);
     WG_OUT     :=RegAdr($1FC0);


     WG_RELOAD  :=RegAdr($1FC8);

     PWM_COUNT  :=RegAdr($1FB6);
     PWM_RELOAD :=RegAdr($1FB4);
     PWM_Control[0]:=RegAdr($1FB0);
     PWM_Control[1]:=RegAdr($1FB2);
     PWM_Control[2]:=RegAdr($1FB4);

     IOCx[0]:=RegAdr($1FB2);
     IOCx[1]:=RegAdr($1FB3);
     IOCx[2]:=RegAdr($1FB4);
     IOCx[3]:=RegAdr($1FB5);

  IntSignals:=0;
  FillChar(Uin, SizeOf(Uin),0);
  Vref:=5.25;
  ANGND:=0;
End;

Function TSimulator.WriteData;
Var
  b : ^Byte;
Begin
  if Address+Count>Addr3+1 then
  Begin
    WriteData:=False;
    Exit;
  End;
  WriteData:=True;

  b:=Memory;
  inc(b, Address);
  move(Buf, b^, Count);
end;

Function TSimulator.ReadData;
Var
  b : ^Byte;
Begin
  if Address+Count>Addr3+1 then
  Begin
    ReadData:=False;
    Exit;
  End;
  ReadData:=True;

  b:=Memory;
  inc(b, Address);
  move(b^, Buf, Count);
end;


Procedure Tsimulator.Reset;
Var
  i : Byte;
Begin
  fillchar(EPAHold, sizeOf(EPAHold),0);
  fillchar(COMPHold,sizeof(COMPHold),0);
  WDDiver:=0;
  WDCount:=0;
  E11E:=False;
  FillChar(EPATrigger, SizeOf(EPATrigger), 0);
  Fcr4:=0;
  PSxDiver[1]:=0;
  PSxDiver[2]:=0;
  ADCmustGo:=False;
  PWMCount:=0;
  PWMHoldReg[0]:=0;
  PWMHoldReg[1]:=0;
  PWMHoldReg[2]:=0;
  TriggerP2_1:=True;
  SSIOCount[0]:=0;
  SSIOCount[1]:=0;
  BRG8:=0;
  WorkPTS:=0;
  OldintSignals:=$FFFF;
  SerialPortCount:=0;
  Circles:=0;
  BRGCount:=0;
  IntEnabled:=True;
  PC:=$2080;
  PSW:=0;
  Perfex:=0;
  reg_x:=0;
  IDLPD:=0;
  ErFlag:=False;
  Perfex:=0;

  AD_COMMAND^ :=$C0;
  AD_RESULT^  :=$7FC0;
  AD_TEST^    :=$C0;
  AD_TIME^    :=$FF;

  COMPx_CON[0]^:=0;
  COMPx_CON[1]^:=0;
  COMPx_CON[2]^:=0;
  if MCSFunc and MF_Mask=MF_MC then
  begin
    COMPx_CON[3]^:=0;
    COMPx_CON[4]^:=0;
    COMPx_CON[5]^:=0;
    COMPx_TIME[3]^:=0;
    COMPx_TIME[4]^:=0;
    COMPx_TIME[5]^:=0;
  end;

  COMPx_TIME[0]^:=0;
  COMPx_TIME[1]^:=0;
  COMPx_TIME[2]^:=0;


  EPA_MASK^   :=0;
  EPA_MASK1^  :=0;
  EPA_PEND^   :=0;
  EPA_PEND1^  :=0;
  for i:=0 to 9 do
  begin
    {if i in [1,3] then EPAx_CON[i]^:=$FE00 else byte(Pointer(}
    EPAx_CON[i]^:=0;
    EPAx_TIME[i]^:=0;
  end;
  EPAIPV^     :=0;

  INT_MASK^   :=0;
  INT_MASK1^  :=0;
  INT_PEND^   :=0;
  INT_PEND1^  :=0;

  IRAM_CON^   :=0;
  ONES_REG^   :=$FFFF;
  for i:=0 to 7 do
  begin
    if PX_MODE[i]<>nil then
    begin
      if i in [2,5] then Px_MODE[i]^:=$80 Else Px_MODE[i]^:=0;
    end;
    if Px_DIR[i]<>nil then
    begin
      if i=2 then Px_DIR[i]^:=$7F Else Px_DIR[i]^:=$FF;
    end;
    if Px_REG[i]<>nil then
    begin
      if i=2 then Px_REG[i]^:=$7F else Px_REG[i]^:=$FF;
    end;
    if PX_PIN[i]<>nil then
    begin
      if i in [2,5] then Px_PIN[i]^:=Px_PIN[i]^ or $80;
    end;
  end;
  if Px_MODE[8]<>nil then
  begin
    Px_MODE[8]^:=$FF;
    Px_DIR[8]^:=$FF;
    Px_REG[8]^:=0;
  end;

  P34_DRV^   :=0;
  PTSSEL^    :=0;
  PTSSRV^    :=0;
  SBUF_RX^   :=0;
  SBUF_TX^   :=0;
  SLP_STAT^  :=SLP_STAT^ and $FE or 6;
  SP_BAUD^   :=0;
  SP_CON^    :=$C0;
  SP_STAT^   :=$08;
  SSIO_BAUD^ :=SSIO_BAUD^ and $7F;
  SSIOx_BUF[0]^:=0;
  SSIOx_BUF[1]^:=0;
  SSIOx_CON[0]^:=0;
  SSIOx_CON[1]^:=0;
  TxCONTROL[1]^:=0;
  TxCONTROL[2]^:=0;
  TIMERx[1]^:=0;
  TIMERx[2]^:=0;
  WSR^        :=0;
  ZERO_REG^   :=0;


  WG_COMPx[1]^:=0;
  WG_COMPx[2]^:=0;
  WG_COMPx[3]^:=0;
  WG_OUT^     :=0;
  if MCSFunc and MF_Mask=MF_MC then
  begin
    WG_CONTROL^ :=$C0;
    T1RELOAD^   :=0;

    FG_COUNT^:=0;
    FG_CON^:=0;

    WG_PROTECT^ :=$F0;
  end;
  WG_RELOAD^  :=0;

  PWM_COUNT^  :=0;
  PWM_RELOAD^ :=0;
  PWM_Control[0]^:=0;
  PWM_Control[1]^:=0;

End;

Procedure TSimulator.Step;
Var
  OPC : Byte;
  CodeAdr : Pointer;

  Fl      : Word;
  COP     : Longint;

  Op2Is   : Byte;

  OpB,OpB1, OpB2 : Byte;
  OpW,OpW1, OpW2 : Word;
  OpL,OpL1, OpL2 : Longint;


  Op1Adr  : Word;
  Op2Adr  : Word;
  ResAdr  : Word;


  Function LoadB:Byte;
  Begin
    if ErFlag then Exit;
    if PC>addr3 then
    Begin
      ErFlag:=True;
      Exit;
    End;
    LoadB:=Byte(CodeAdr^);
    inc(word(CodeAdr));
    inc(PC);
  End;

  Function LoadW:Word;
  Begin
    if ErFlag then Exit;
    if PC+1>addr3 then
    Begin
      ErFlag:=True;
      Exit;
    End;
    LoadW:=Word(CodeAdr^);
    inc(Word(CodeAdr),2);
    inc(PC,2);
  End;

  Function LoadT:Longint;
  Var
    L : Longint;
  Begin
    if ErFlag then Exit;
    if PC+2>Addr3 then
    Begin
      ErFlag:=True;
      Exit;
    End;
    L:=Longint(CodeAdr^) and $FFFFFF;
    if L and $800000<>0 then L:=L or $FF000000;
    LoadT:=L;
    inc(Word(CodeAdr),3);
    inc(PC,3);
  End;

  Function LoadL:Longint;
  Begin
    if ErFlag then Exit;
    if PC+4>Addr3 then
    Begin
      ErFlag:=True;
      Exit;
    End;
    LoadL:=Longint(CodeAdr^);
    inc(Word(CodeAdr),4);
    inc(PC,4);
  End;

  Function CorrectAdr(Var Adr:Byte):Pointer;
  Var
    B   : ^Byte;
    Wnd : Byte;
    D   : Byte;
    W   : Word;
    DD  : Byte;
  Label L1;
  Begin
    CorrectAdr:=Memory;
    if MCSFunc and MF_HWindow<>0 then
    Begin
      if (Adr<$18) and (Adr<>$14) then
      Begin
        if WSR^=$0F then
        begin
          b:=Memory;
          inc(b, $1FB0);
          CorrectAdr:=b;
        end
        Else
        if (MCSFunc and MF_Mask = MF_KB) and (WSR^=$0E) or
           (MCSFunc and MF_Mask = MF_KC) and (WSR^=$01) then
        Begin
          b:=Memory;
          inc(b,$1FC8);
          CorrectAdr:=b;
        End;
      End;
    End;

    if MCSFunc and MF_VWindow<>0 then
    Begin
      D:=WSR^;
      DD:=Adr;
      asm
           les   di,Adr
           shl   D,1
           shl   D,1
           jnc   @1
           mov   Wnd,0E0h
           and   byte ptr es:[di],$1F
           jmp   @ex
      @1:  shl   D,1
           jnc   @2
           mov   Wnd,0C0h
           and   byte ptr es:[di],$3F
           jmp   @ex
      @2:  shl   D,1
           jnc   L1
           mov   Wnd,080h
           and   byte ptr es:[di],$7F
      @ex:
      end;
      if DD>=Wnd then
      Begin
        if D and $E0=$E0 then W:=$1800 Else W:=0;
        W:=W or (Word(D) shl 3);
        b:=Memory;
        inc(b,W);
        CorrectAdr:=b;
      End;
      L1:
    End;
  End;

  Procedure WriteInReg(b:Pointer);
  var
    i : Byte;
  Begin
    if (SLP_CMD<>nil) then
    begin
      if b = PX_PIN[3] then
      Begin
        SLP_STAT^:=SLP_STAT^ or 2; { IBE }
        if SLP_CON^ and $A=$A then PortsLegs[5]:=PortsLegs[5] or $10;
      end;

      if b = SLP_CMD then
        SLP_STAT^:=SLP_STAT^ or 4;
    end;

    if (MCSFunc and MF_Mask=MF_NT) or (MCSFunc and MF_Mask = MF_KR) then
    begin
      if b = SSIO_BAUD then BRGSSIO:=SSIO_BAUD^;
      if b = SSIOX_BUF[0] then
      begin
        if SSIOx_CON[0]^ and 8<>0 then
        Begin
           SSIOx_CON[0]^:=SSIOx_CON[0]^ or 2;
           SSIOx_BUF[0]^:=SSIOBuf[0];
        End
        Else
        begin
          SSIOx_CON[0]^:=SSIOx_CON[0]^ or 8;
          SSIOCount[0]:=0;
        end;
      End;

      if b = SSIOX_BUF[1] then
      begin
        if SSIOx_CON[1]^ and 8<>0 then
        Begin
          SSIOx_CON[1]^:=SSIOx_CON[1]^ or 2;
          SSIOx_BUF[1]^:=SSIOBuf[1];
        End
        Else
        begin
          SSIOx_CON[1]^:=SSIOx_CON[1]^ or 8;
          SSIOCount[1]:=0;
        end;
      End;
    end;
    if b = AD_COMMAND then
    begin
      if (MCSfunc and MF_Mask=MF_MC) then
      Begin
        if AD_COMMAND^ and $10<>0 then ADCMustGo:=True;
      End
      Else
        if AD_COMMAND^ and $8<>0 then ADCMustGo:=True;
      ADCDiver:=0;
    end;
    if b= WatchDog then
    begin
      if E11E and (WatchDog^=$E1) then
      begin
        WDCount:=0;
        E11E:=False;
      end
      Else
        if not E11E and (WatchDog^=$1E) then E11E:=True;
    end;

    if (mcsfunc and mf_mask>=MF_KR) then
    begin
      if mcsfunc and mf_mc<>0 then
      begin
        for i:=0 to 9 do
        if b=EPAx_TIME[i] then EPAHold[i]:=0;
        for i:=0 to 1 do
        if b=COMPx_TIME[i] then COMPHold[i]:=0;
      end;
    end;
  end;

  procedure ReadFromReg(b:Pointer);
  Var
    i : Byte;
  begin
    if b = SBUF_TX then
    Begin
      SP_STAT^:=SP_STAT^ and $DF;
      BRGCount:=SP_BAUD^ and $7FFF;
    end;
    if (b = PX_REG[3]) and (SLP_CMD<>nil) then
    Begin
      SLP_STAT^:=SLP_STAT^ and $FE; { OBF }
      if SLP_CON^ and 9=9 then  PortsLegs[5]:=PortsLegs[5] or $10;
    End;
    if (MCSFunc and MF_Mask=MF_NT) or (MCSFunc and MF_Mask = MF_KR) then
    begin
      if b = SSIOx_BUF[0] then
      begin
        if SSIOx_CON[0]^ and 8<>0 then SSIOx_CON[0]^:=SSIOx_CON[0]^ or 2
        Else
        begin
          SSIOx_CON[0]^:=SSIOx_CON[0]^ or 8;
          SSIOCount[0]:=0;
        end;
      End;

      if b = SSIOx_BUF[1] then
      begin
        if SSIOx_CON[1]^ and 8<>0 then SSIOx_CON[1]^:=SSIOx_CON[1]^ or 2
        Else
        begin
          SSIOx_CON[1]^:=SSIOx_CON[1]^ or 8;
          SSIOCount[1]:=0;
        end;
      End;
    end;

    if (mcsfunc and mf_mask>=MF_KR) then
    begin
      if mcsfunc and mf_mc<>0 then
      begin
        for i:=0 to 9 do
        if b=EPAx_TIME[i] then
          Case EPAHold[i] Of
            1:EPAHold[i]:=0;
            2:Begin
                EPAx_TIME[i]^:=BuffReg[i];
                EPAHold[i]:=1;
              End;
          end;
        for i:=0 to 1 do
        if b=COMPx_TIME[i] then
          case COMPHold[i] of
            1:COMPHold[i]:=0;
            2:Begin
                COMPx_TIME[i]^:=COMPBuff[i];
                COMPHold[i]:=1;
              end;
          end;
      end;
    end;
  end;


  Function GetReg(Adr:Byte):Byte;
  Var
    b : ^Byte;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr);
    Getreg:=b^;
    ReadFromReg(b);
  End;

  Procedure SetReg(Adr:Byte; Bt:Byte);
  Var
    b : ^Byte;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr);
    b^:=Bt;
    WriteInReg(b);
  End;

  Function Get3Reg(Adr:Byte):Longint;
  Var
    b : ^Byte;
    L : Longint;
  Begin
    if ErFlag then Exit;
    Adr:=Adr and $FFFC;
    b:=CorrectAdr(Adr);
    inc(b,Adr);
    ReadFromReg(b);
    L:=Longint(Pointer(b)^) and $FFFFFF;
    if L and $800000<>0 then L:=L or $FF000000;
    Get3reg:=L;
  End;

  Procedure Set3Reg(Adr:Byte; t:LongInt);
  Var
    b : ^Byte;
  Begin
    if ErFlag then Exit;
    Adr:=Adr and $FFFC;
    b:=CorrectAdr(Adr);
    inc(b,Adr);
    move(t, b^, 3);
    WriteInReg(b);
  End;


  Function Get2reg(Adr:byte):Word;
  Var
    b : ^Word;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr shr 1);
    Get2Reg:=b^;
    ReadFromReg(b);
  End;

  Procedure Set2Reg(Adr:Byte; Wr:Word);
  Var
    b : ^Word;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr shr 1);
    b^:=Wr;
    WriteInReg(b);
  End;

  Function Get4Reg(Adr:Byte):Longint;
  Var
    b : ^Longint;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr shr 2);
    Get4Reg:=b^;
    ReadFromReg(b);
  End;

  Procedure Set4reg(Adr:Byte; Lg:Longint);
  Var
    b : ^Longint;
  Begin
    if ErFlag then Exit;
    b:=CorrectAdr(Adr);
    inc(b,Adr shr 2);
    b^:=Lg;
    WriteInReg(b);
  End;



  Function Getloc(Adr:Word):Byte;
  Var
    b : ^Byte;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr);
    Getloc:=b^;
    ReadFromReg(b);
  End;

  Function GetLocM(Adr:Word):Byte;
  Begin
    Case Op2Is Of
      0:GetLocM:=GetLoc(Adr);
      1:GetLocM:=GetReg(Adr);
      2:GetLocM:=Byte(COP);
    end;
  End;


  Procedure Setloc(Adr:Word; Bt:Byte);
  Var
    b : ^Byte;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr);
    b^:=Bt;
    WriteInReg(b);
  End;

  procedure SetLocM(Adr:Word; Bt:Byte);
  Begin
    Case Op2Is Of
      0:SetLoc(Adr,Bt);
      1:SetReg(Adr,Bt);
    End;
  End;

  Function Get2loc(Adr:Word):Word;
  Var
    b : ^Word;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr shr 1);
    Get2loc:=b^;
    ReadFromReg(b);
  End;

  Function Get2LocM(Adr:Word):Word;
  Begin
    Case Op2Is Of
      0:Get2LocM:=Get2Loc(Adr);
      1:Get2LocM:=Get2Reg(Adr);
      2:Get2LocM:=Word(COP);
    End;
  End;

  Procedure Set2loc(Adr:Word; Wr:Word);
  Var
    b : ^Word;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr shr 1);
    b^:=Wr;
    WriteInReg(b);
  End;

  Procedure Set2LocM(Adr:Word; Wr:Word);
  Begin
    Case Op2Is Of
      0:Set2Loc(Adr,Wr);
      1:Set2Reg(Adr,Wr);
    End;
  End;

  Function Get4loc(Adr:Word):Longint;
  Var
    b : ^Longint;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr shr 2);
    Get4loc:=b^;
    ReadFromReg(b);
  End;

  Function Get4LocM(Adr:Word):Longint;
  Begin
    Case Op2Is Of
      0:Get4LocM:=Get4Loc(Adr);
      1:Get4LocM:=Get4Reg(Adr);
      2:Get4LocM:=COP;
    End;
  End;

  Procedure Set4loc(Adr:Word; Lg:Longint);
  Var
    b : ^Longint;
  Begin
    if ErFlag then Exit;
    if Adr>$FFF0 then
    begin
      ErFlag:=True;
      Exit;
    End;
    b:=Memory;
    inc(b,Adr shr 2);
    b^:=Lg;
    WriteInReg(b);
  End;

  Procedure Set4LocM(Adr:Word; Lg:Longint);
  Begin
    Case Op2Is Of
      0:Set4Loc(Adr,Lg);
      1:Set4Reg(Adr,Lg);
    End;
  End;


  Procedure Std(Addressation, OpSize:Byte);
  Var
    R : Byte;
  Begin
    Op2Is:=0;
    Case Addressation Of
      0:Begin
          Op2Adr:=LoadB;
          Op2Is:=1;
        End;
      1:Begin
          Op2Is:=2;
          case OpSize Of
            1:byte(COP):=LoadB;
            2:word(COP):=LoadW;
            4:Longint(COP):=LoadL;
          End;
        End;
      2:Begin
          R:=LoadB;
          Op2Adr:=Get2reg(R);
          if R and 1<>0 then Set2reg(R,Op2Adr+OpSize);
        End;
      3:Begin
          R:=LoadB;
          if R and 1<>0 then Op2Adr:=LoadW Else Op2Adr:=LoadB;
          inc(Op2Adr, Get2reg(R));
        End;
    End;
  End;

  Procedure Flags( SetF, ClrF : Word);
  Begin
    PSW:=PSW and not ClrF or SetF;
  End;

  Procedure PushW( w : Word);
  Begin
    dec(SP^,2);
    Set2Loc( SP^, w);

  End;

  Function PopW : Word;
  Begin
    PopW:=Get2Loc( SP^);
    inc(SP^,2);
  End;


Label Table, EndCmd, AndLab,  AddLab,sublab, mullab,
                     andBLab, AddBLab, subBlab, mulblab,
c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, c0A, c0B, c0C, c0D, c0E, c0F,
c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, c1A, c1B, c1C, c1D, c1E, c1F,
c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, c2A, c2B, c2C, c2D, c2E, c2F,
c30, c31, c32, c33, c34, c35, c36, c37, c38, c39, c3A, c3B, c3C, c3D, c3E, c3F,
c40, c41, c42, c43, c44, c45, c46, c47, c48, c49, c4A, c4B, c4C, c4D, c4E, c4F,
c50, c51, c52, c53, c54, c55, c56, c57, c58, c59, c5A, c5B, c5C, c5D, c5E, c5F,
c60, c61, c62, c63, c64, c65, c66, c67, c68, c69, c6A, c6B, c6C, c6D, c6E, c6F,
c70, c71, c72, c73, c74, c75, c76, c77, c78, c79, c7A, c7B, c7C, c7D, c7E, c7F,
c80, c81, c82, c83, c84, c85, c86, c87, c88, c89, c8A, c8B, c8C, c8D, c8E, c8F,
c90, c91, c92, c93, c94, c95, c96, c97, c98, c99, c9A, c9B, c9C, c9D, c9E, c9F,
cA0, cA1, cA2, cA3, cA4, cA5, cA6, cA7, cA8, cA9, cAA, cAB, cAC, cAD, cAE, cAF,
cB0, cB1, cB2, cB3, cB4, cB5, cB6, cB7, cB8, cB9, cBA, cBB, cBC, cBD, cBE, cBF,
cC0, cC1, cC2, cC3, cC4, cC5, cC6, cC7, cC8, cC9, cCA, cCB, cCC, cCD, cCE, cCF,
cD0, cD1, cD2, cD3, cD4, cD5, cD6, cD7, cD8, cD9, cDA, cDB, cDC, cDD, cDE, cDF,
cE0, cE1, cE2, cE3, cE4, cE5, cE6, cE7, cE8, cE9, cEA, cEB, cEC, cED, cEE, cEF,
cF0, cF1, cF2, cF3, cF4, cF5, cF6, cF7, cF8, cF9, cFA, cFB, cFC, cFD, cFE, cFF;



Begin
  EPA;
  inc(WDDiver, Circles);
  While WDDiver>0 do
  Begin
    Dec(WDDiver);
    inc(WDCount);
    if WDCount=$FFFF then Reset;
  End;

  FG;
  PWM;
  SSIO;
  SerialPort;
  Ports;
  SlavePort;
  if ICC( OpW ) then
  Begin
    IDLPD:=0;
    pushW(PC);
    PC:=Get2Loc(OpW);
  End;

  if IDLPD<>0 then Exit;
  CodeAdr:=Memory;
  inc(Word(CodeAdr), PC);
  Circles:=3;

  Case Perfex Of
    0:;
    1:Perfex:=2;
    2:Perfex:=0;
  End;

  OPC:=LoadB;
  asm

           mov     bl,OPC
           xor     bh,bh
           shl     bx,1
           jmp     word ptr Table[bx]
  end;

  c00:  {------------ OPC = 00 = SKIP --------}
  loadB;

  goto EndCmd;


  c01:  {------------ OPC = 01 = CLR --------}
  Set2Reg(LoadB,0);
  Flags(flag_z,flag_n or flag_v or flag_c);

  goto EndCmd;


  c02:  {------------ OPC = 02 = NOT --------}
  Op1Adr:=LoadB;
  OpW:=not Get2Reg(Op1Adr);
  Set2Reg(Op1Adr, OpW);
  fl:=0;
  if OpW=0 then fl:=flag_z
  Else
    if integer(OpW)<0 then fl:=fl or flag_n;
  Flags(fl, flag_n or flag_z or flag_v or flag_c);
  goto EndCmd;


  c03:  {------------ OPC = 03 = NEG --------}
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  asm
        mov    ax, OpW
        neg    ax
        mov    OpW1,ax
  end;
  Set2Reg(Op1Adr, OpW1);
  fl:=0;
  if OpW1=0 then fl:=flag_z
  Else
    if integer(OpW1)<0 then fl:=fl or flag_n;
  if OpW=OpW1 then fl:=fl or flag_v or flag_vt;

  Flags(fl, flag_n or flag_z or flag_v or flag_c);
  goto EndCmd;


  c04:  {------------ OPC = 04 = xch --------}
  std(3*ord(OPC=$0B),2);
  Op1Adr:=LoadB;

  OpW:=Get2LocM(Op2Adr);
  Set2LocM(Op2Adr,  Get2Reg(Op1Adr));
  Set2Reg(Op1Adr,  OpW);

  goto EndCmd;


  c05:  {------------ OPC = 05 = DEC --------}
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  OpW1:=OpW-1;
  Set2Reg(Op1Adr,OpW1);

  fl:=0;
  if OpW1=0 then fl:=flag_z;
  if Integer(OpW1)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000=OpW and $8000) then fl:=fl or flag_c;
  if (OpW and $8000<>0) and (OpW1 and $8000=0) then fl:=fl or flag_v or flag_vt;
  Flags( fl, flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c06:  {------------ OPC = 06 = EXT --------}
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  asm
          mov    ax,OpW
          cwd
          mov    word ptr OpL,ax
          mov    word ptr OpL[2],dx
  end;
  Set4Reg(Op1Adr, OpL);
  fl:=0;
  if OpL=0 then Fl:=flag_z;
  if OpL<0 then Fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c07:  {------------ OPC = 07 = INC --------}
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  OpW1:=OpW+1;
  Set2Reg(Op1Adr, OpW1);

  fl:=0;
  if OpW1=0 then fl:=flag_z;
  if Integer(OpW1)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000<>OpW and $8000) then fl:=fl or flag_c;
  if (OpW and $8000=0) and (OpW1 and $8000<>0) then fl:=fl or flag_v or flag_vt;
  Flags( fl, flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c08:  {------------ OPC = 08 = SHR --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shr    OpW,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1
  end;
  Set2reg(Op1Adr,OpW);
  if OpW=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);
  goto EndCmd;


  c09:  {------------ OPC = 09 = SHL --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shl    OpW,1
          jnc    @2
          or     fl, flag_c or flag_v or flag_vt
  @2:     loop   @1
  end;
  Set2reg(Op1Adr,OpW);
  if OpW=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_c or flag_v);
  goto EndCmd;


  c0A:  {------------ OPC = 0A = SHRA --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpW:=Get2Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          sar    OpW,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1
  end;
  Set2reg(Op1Adr,OpW);
  if OpW=0 then fl:=fl or flag_z;
  if integeR(OpW)<0 then fl:=fl or flag_n;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);
  goto EndCmd;


  c0C:  {------------ OPC = 0C = SHRL --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpL:=Get4Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shr    word ptr OpL[2],1
          rcr    word ptr OpL,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1

  end;
  Set4reg(Op1Adr,OpL);
  if OpL=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);
  goto EndCmd;


  c0D:  {------------ OPC = 0D = SHLL --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpL:=Get4Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shl    word ptr OpL,1
          rcl    word ptr OpL[2],1
          jnc    @2
          or     fl, flag_c or flag_v or flag_vt
  @2:     loop   @1
  end;
  Set4reg(Op1Adr,OpL);
  if OpL=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c0E:  {------------ OPC = 0E = SHRAL --------}
  OpB:=LoadB;
  Op1Adr:=LoadB;
  OpL:=Get4Reg(Op1Adr);
  if OpB>$15 then OpB:=GetReg(OpB);
  asm
          mov    cl,OpB
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          sar    word ptr OpL[2],1
          rcr    word ptr OpL,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1
  end;
  Set4reg(Op1Adr,OpL);
  if OpL=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);
  goto EndCmd;


  c0F:  {------------ OPC = 0F = NORML --------}
  Op2Adr:=LoadB;
  Op1Adr:=LoadB;
  OpL:=Get4Reg(Op1Adr);
  fl:=0;
  if Opl=0 then fl:=flag_z
  Else
  Begin
    asm
          mov   cl,0FFh
    @1:   inc   cl
          shl   word ptr OpL,1
          shl   word ptr OpL[2],1
          test  Byte ptr OpL[2],80h
          jz    @1

          mov   OpB,cl
    end;
    Set4Reg(Op1Adr,OpL);
  end;
  Flags(fl, flag_z or flag_c);
  goto EndCmd;


  c10:  {------------ OPC = 10 --------}
  ErFlag:=true;
  goto EndCmd;


  c11:  {------------ OPC = 11 = CLRB --------}
  SetReg(LoadB,0);
  Flags(flag_z,flag_n or flag_v or flag_c);
  goto EndCmd;


  c12:  {------------ OPC = 12 = notb --------}
  Op1Adr:=LoadB;
  OpB:=not GetReg(Op1Adr);
  Set2Reg(Op1Adr, OpB);
  fl:=0;
  if OpB=0 then fl:=flag_z
  Else
    if shortint(OpB)<0 then fl:=fl or flag_n;
  Flags(fl, flag_n or flag_z or flag_v or flag_c);
  goto EndCmd;


  c13:  {------------ OPC = 13 = NEGB --------}
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  asm
        mov    al, OpB
        neg    al
        mov    OpB1,al
  end;
  SetReg(Op1Adr, OpB1);
  fl:=0;
  if OpB1=0 then fl:=flag_z
  Else
    if Shortint(OpB1)<0 then fl:=fl or flag_n;
  if OpB=OpB1 then fl:=fl or flag_v or flag_vt;

  Flags(fl, flag_n or flag_z or flag_v or flag_c);

  goto EndCmd;


  c14:  {------------ OPC = 14 = XCHB --------}
  std(3*ord(OPC=$1B),2);
  Op1Adr:=LoadB;

  OpB:=GetLocM(Op2Adr);
  SetLocM(Op2Adr,  GetReg(Op1Adr));
  SetReg(Op1Adr,  OpB);
  goto EndCmd;


  c15:  {------------ OPC = 15 = DECB --------}
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  OpB1:=OpB-1;
  SetReg(Op1Adr,OpB1);

  fl:=0;
  if OpB1=0 then fl:=flag_z;
  if ShortInt(OpB1)<0 then fl:=fl or flag_n;
  if (OpB1 and $80=OpB and $80) then fl:=fl or flag_c;
  if (OpB and $80<>0) and (OpB1 and $80=0) then fl:=fl or flag_v or flag_vt;
  Flags( fl, flag_z or flag_n or flag_c or flag_v);

  goto EndCmd;


  c16:  {------------ OPC = 16 = EXTB --------}
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  asm
       mov    al,OpB
       cbw
       mov    OpW,ax
  end;
  set2reg(Op1Adr, OpW);
  fl:=0;
  if OpW=0 then Fl:=flag_z;
  if integer(OpW)<0 then Fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c17:  {------------ OPC = 17 = INCB --------}
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  OpB1:=OpB+1;
  SetReg(Op1Adr,OpB1);

  fl:=0;
  if OpB1=0 then fl:=flag_z;
  if ShortInt(OpB1)<0 then fl:=fl or flag_n;
  if (OpB1 and $80<>OpB and $80) then fl:=fl or flag_c;
  if (OpB and $80=0) and (OpB1 and $80<>0) then fl:=fl or flag_v or flag_vt;
  flags( fl, flag_z or flag_n or flag_c or flag_v);
  goto EndCmd;


  c18:  {------------ OPC = 18 = SHRB --------}
  OpB1:=LoadB;
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  if OpB1>$15 then OpB1:=GetReg(OpB1);
  asm
          mov    cl,OpB1
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shr    OpB,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1
  end;
  Setreg(Op1Adr,OpB);
  if OpW=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);

  goto EndCmd;


  c19:  {------------ OPC = 19 = SHLB --------}
  OpB1:=LoadB;
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  if OpB1>$15 then OpB1:=GetReg(OpB1);
  asm
          mov    cl,OpB1
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          shl    OpB,1
          jnc    @2
          or     fl, flag_c or flag_v or flag_vt
  @2:     loop   @1
  end;
  Setreg(Op1Adr,OpB);
  if OpB=0 then fl:=fl or flag_z;
  flags(fl,flag_z or flag_c or flag_v);

  goto EndCmd;


  c1A:  {------------ OPC = 1A = SHRAB --------}
  OpB1:=LoadB;
  Op1Adr:=LoadB;
  OpB:=GetReg(Op1Adr);
  if OpB1>$15 then OpB1:=GetReg(OpB1);
  asm
          mov    cl,OpB1
          xor    ch,ch
          mov    fl,0

  @1:     and    fl,not flag_c
          sar    OpB,1
          jnc    @2
          or     fl, flag_c or flag_st
  @2:     loop   @1
  end;
  Setreg(Op1Adr,OpB);
  if OpB=0 then fl:=fl or flag_z;
  if shortint(OpB)<0 then fl:=fl or flag_n;
  flags(fl,flag_z or flag_n or flag_c or flag_v or flag_st);

  goto EndCmd;


  c1C:  {------------ OPC = 1C = EST --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  if OPC=$1D then
  Begin
    OpL:=LoadT+Get3Reg(Op2Adr);
  End
  Else
    OpL:=Get3Reg(Op2Adr);
  if OpL>Addr3 then ErFlag:=True;

  Set2Loc(OpL, Get2Reg(LoadB));
  if (OPC=$1C) and (Op2Adr and 3=1) then Set3Reg(Op2Adr,OpL+2);
  goto EndCmd;


  c1E:  {------------ OPC = 1E = ESTB --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  Op1Adr:=LoadB;
  if OPC=$1D then
  Begin
    OpL:=LoadT+Get3Reg(Op2Adr);
  End
  Else
    OpL:=Get3Reg(Op2Adr);
  if OpL>Addr3 then ErFlag:=True;

  Setloc(OpL, Getloc(LoadB));
  if (OPC=$1C) and (Op2Adr and 3=1) then Set3Reg(Op2Adr,OpL+1);
  goto EndCmd;


  c20:  {------------ OPC = 20 = SJMP --------}
  OPW:=LoadB or swap(OPC and 7);
  if OPW and $400<>0 then OPW:=OPW or $F800;
  inc(PC,integer(OPW));
  goto EndCmd;


  c28:  {------------ OPC = 28 = SCALL --------}
  PushW(PC+1);
  goto c20;


  c30:  {------------ OPC = 30 JBC --------}
  OpB:=GetReg(LoadB);
  OpB1:=LoadB;
  if OpB and (1 shl (OPC and 7))=0 then inc(PC,shortint(OpB1));
  goto EndCmd;


  c38:  {------------ OPC = 38 JBS --------}
  OpB:=GetReg(LoadB);
  OpB1:=LoadB;
  if OpB and (1 shl (OPC and 7))<>0 then inc(PC,shortint(OpB1));
  goto EndCmd;


  c40:  {------------ OPC = 40 = AND (3) --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  AndLab:
  OpW:=Get2LocM(Op2Adr) and Get2reg(Op1Adr);
  Set2reg(ResAdr, OpW);

  fl:=0;
  if OpW=0 then fl:=flag_z;
  if integer(OPW)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c44:  {------------ OPC = 44 = ADD --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  AddLab:
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  fl:=0;
  asm
     mov   ax,OpW1
     add   ax,OpW2
     mov   OpW,ax
     jnc   @1
     mov   fl,flag_c
  @1:
  end;
  Set2Reg(ResAdr, OpW);

  if OpW=0 then fl:=fl or flag_z;
  if integer(OpW)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000=OpW2 and $8000) and (OpW1 and $8000<>OpW and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c48:  {------------ OPC = 48 = SUB --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  SubLab:
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  fl:=0;
  asm
     mov   ax,OpW1
     sub   ax,OpW2
     mov   OpW,ax
     jc    @1
     mov   fl,flag_c
  @1:
  end;
  Set2Reg(ResAdr, OpW);

  if OpW=0 then fl:=fl or flag_z;
  if integer(OpW)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000<>OpW2 and $8000) and (OpW1 and $8000<>OpW and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c4C:  {------------ OPC = 4C = mul, mulu --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  mulLab:
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  if perfex=0 then
  asm
     mov   ax,OpW1
     imul  OpW2
     mov   word ptr OpL,ax
     mov   word ptr OpL[2],dx
  end
  Else
  asm
     mov   ax,OpW1
     mul   OpW2
     mov   word ptr OpL,ax
     mov   word ptr OpL[2],dx
  end;
  Set4Reg(ResAdr, OpL);
  goto EndCmd;


  c50:  {------------ OPC = 50 = and --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  AndBLab:
  OpB:=GetLocM(Op2Adr) and Getreg(Op1Adr);
  Setreg(ResAdr, OpB);

  fl:=0;
  if OpB=0 then fl:=flag_z;
  if ShortInt(OPB)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c54:  {------------ OPC = 54 = ADDB --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  AddBLab:
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  fl:=0;
  asm
     mov   al,OpB1
     add   al,OpB2
     mov   OpB,al
     jnc   @1
     mov   fl,flag_c
  @1:
  end;
  SetReg(ResAdr, OpB);

  if OpB=0 then fl:=fl or flag_z;
  if ShortInt(OpB)<0 then fl:=fl or flag_n;
  if (OpB1 and $8000=OpB2 and $8000) and (OpB1 and $8000<>OpB and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c58:  {------------ OPC = 58 SUBB --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  SubBLab:
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  fl:=0;
  asm
     mov   al,OpB1
     sub   al,OpB2
     mov   OpB,al
     jc    @1
     mov   fl,flag_c
  @1:
  end;
  SetReg(ResAdr, OpB);

  if OpB=0 then fl:=fl or flag_z;
  if ShortInt(OpB)<0 then fl:=fl or flag_n;
  if (OpB1 and $8000<>OpB2 and $8000) and (OpB1 and $8000<>OpB and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c5C:  {------------ OPC = 5C mulb, mulub--------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  ResAdr:=LoadB;
  mulbLab:
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  if perfex=0 then
  asm
     mov   al,OpB1
     imul  OpB2
     mov   OpW,ax
  end
  Else
  asm
     mov   al,OpB1
     mul   OpB2
     mov   OpW,ax
  end;
  Set2Reg(ResAdr, OpW);
  goto EndCmd;


  c60:  {------------ OPC = 60 = AND (2)--------}
  std(OPC and 3,2);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto andlab;


  c64:  {------------ OPC = 64 = ADD (2)--------}
  std(OPC and 3,2);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto addlab;


  c68:  {------------ OPC = 68 = SUB (2) --------}
  std(OPC and 3,2);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto sublab;


  c6C:  {------------ OPC = 6C = MUL (2)--------}
  std(OPC and 3,2);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto mullab;


  c70:  {------------ OPC = 70 = andb --------}
  std(OPC and 3,1);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto andblab;


  c74:  {------------ OPC = 74 = addb --------}
  std(OPC and 3,1);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto addblab;

  c78:  {------------ OPC = 78 = subb --------}
  std(OPC and 3,1);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto subblab;


  c7C:  {------------ OPC = 7C mulb --------}
  std(OPC and 3,1);
  Op1Adr:=loadB;
  ResAdr:=Op1Adr;
  goto mulblab;



  c80:  {------------ OPC = 80 = or --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpW:=Get2LocM(Op2Adr) or Get2reg(Op1Adr);
  Set2reg(Op1Adr, OpW);

  fl:=0;
  if OpW=0 then fl:=flag_z;
  if integer(OPW)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c84:  {------------ OPC = 84 = xor --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpW:=Get2LocM(Op2Adr) xor Get2reg(Op1Adr);
  Set2reg(Op1Adr, OpW);

  fl:=0;
  if OpW=0 then fl:=flag_z;
  if integer(OPW)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);

  goto EndCmd;


  c88:  {------------ OPC = 88 = cmp --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  fl:=0;
  asm
     mov   ax,OpW1
     sub   ax,OpW2
     mov   OpW,ax
     jc    @1
     mov   fl,flag_c
  @1:
  end;

  if OpW=0 then fl:=fl or flag_z;
  if integer(OpW)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000<>OpW2 and $8000) and (OpW1 and $8000<>OpW and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c8C:  {------------ OPC = 8C = div --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpL1:=Get4Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  if OpW2=0 then
  Begin
    flags(flag_v or flag_vt,0);
  End
  Else
  Begin
    flags(0,flag_v);
    if perfex=0 then
    asm
       mov   ax,word ptr OpL1
       mov   dx,word ptr OpL1[2]
       idiv  OpW2
       mov   word ptr OpL,ax
       mov   word ptr OpL[2],dx
    end
    Else
    asm
       mov   ax,word ptr OpL1
       mov   dx,word ptr OpL1[2]
       div   OpW2
       mov   word ptr OpL,ax
       mov   word ptr OpL[2],dx
    end;
  end;
  Set4Reg(Op1Adr, OpL);

  goto EndCmd;


  c90:  {------------ OPC = 90 = orb --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  OpB:=GetLocM(Op2Adr) or Getreg(Op1Adr);
  Setreg(Op1Adr, OpB);

  fl:=0;
  if OpB=0 then fl:=flag_z;
  if shortint(OPB)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c94:  {------------ OPC = 94 = xorb --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  OpB:=GetLocM(Op2Adr) xor Getreg(Op1Adr);
  Setreg(Op1Adr, OpB);

  fl:=0;
  if OpB=0 then fl:=flag_z;
  if shortint(OPB)<0 then fl:=fl or flag_n;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c98:  {------------ OPC = 98 = cmpb --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  fl:=0;
  asm
     mov   al,OpB1
     sub   al,OpB2
     mov   OpB,al
     jc    @1
     mov   fl,flag_c
  @1:
  end;

  if OpB=0 then fl:=fl or flag_z;
  if shortint(OpB)<0 then fl:=fl or flag_n;
  if (OpB1 and $80<>OpB2 and $80) and (OpB1 and $80<>OpB and $80) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  c9C:  {------------ OPC = 9C --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  OpW1:=Get2Reg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  if OpB2=0 then
  Begin
    flags(flag_v or flag_vt,0);
  End
  Else
  Begin
    flags(0,flag_v);
    if perfex=0 then
    asm
       mov   ax,OpW1
       idiv  OpB2
       mov   OpW,ax
    end
    Else
    asm
       mov   ax,OpW1
       div   OpB2
       mov   OpW,ax
    end;
  end;
  Set2Reg(Op1Adr, OpW);
  goto EndCmd;


  cA0:  {------------ OPC = A0 = LD --------}
  std(OPC and 3, 2);
  Set2Reg(LoadB, Get2LocM(Op2Adr));
  goto EndCmd;


  cA4:  {------------ OPC = A4 = ADDC --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  OpW:=PSW and flag_c;
  fl:=0;
  asm
     cmp   OpW,0
     jnz   @3
     clc
     jmp   @2
  @3:stc
  @2:
     mov   ax,OpW1
     adc   ax,OpW2
     mov   OpW,ax
     jnc   @1
     mov   fl,flag_c
  @1:
  end;
  Set2Reg(Op1Adr, OpW);

  if OpW=0 then fl:=fl or flag_z;
  if integer(OpW)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000=OpW2 and $8000) and (OpW1 and $8000<>OpW and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  cA8:  {------------ OPC = A8 = subc --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpW1:=Get2Reg(Op1Adr);
  OpW2:=Get2LocM(Op2Adr);
  OpW:=PSW and flag_c;
  fl:=0;
  asm
     cmp   OpW,0
     jnz   @3
     stc
     jmp   @2
  @3:clc
  @2:
     mov   ax,OpW1
     sbb   ax,OpW2
     mov   OpW,ax
     jnc   @1
     mov   fl,flag_c
  @1:
  end;
  Set2Reg(Op1Adr, OpW);
  if OpW=0 then fl:=fl or flag_z;
  if integer(OpW)<0 then fl:=fl or flag_n;
  if (OpW1 and $8000<>OpW2 and $8000) and (OpW1 and $8000<>OpW and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  cAC:  {------------ OPC = AC = LDBZE --------}
  std(OPC and 3,1);
  Set2Reg(LoadB, GetLocM(Op2Adr));
  goto EndCmd;


  cB0:  {------------ OPC = B0 = LDB --------}
  std(OPC and 3, 1);
  SetReg(LoadB, GetLocM(Op2Adr));
  goto EndCmd;


  cB4:  {------------ OPC = B4 = ADDCB --------}
  std(OPC and 3,2);
  Op1Adr:=LoadB;
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  OpB:=PSW and flag_c;
  fl:=0;
  asm
     cmp   OpB,0
     jnz   @3
     clc
     jmp   @2
  @3:stc
  @2:
     mov   al,OpB1
     adc   al,OpB2
     mov   OpB,al
     jnc   @1
     mov   fl,flag_c
  @1:
  end;
  SetReg(Op1Adr, OpB);

  if OpB=0 then fl:=fl or flag_z;
  if shortint(OpB)<0 then fl:=fl or flag_n;
  if (OpB1 and $8000=OpB2 and $8000) and (OpB1 and $8000<>OpB and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;

  cB8:  {------------ OPC = B8 = SUBCB --------}
  std(OPC and 3,1);
  Op1Adr:=LoadB;
  OpB1:=GetReg(Op1Adr);
  OpB2:=GetLocM(Op2Adr);
  OpB:=PSW and flag_c;
  fl:=0;
  asm
     cmp   OPB,0
     jnz   @2
     stc
     jmp   @3
  @2:clc
  @3:
     mov   al,OpB1
     sub   al,OpB2
     mov   OpB,al
     jc    @1
     mov   fl,flag_c
  @1:
  end;
  SetReg(Op1Adr, OpB);

  if OpB=0 then fl:=fl or flag_z;
  if ShortInt(OpB)<0 then fl:=fl or flag_n;
  if (OpB1 and $8000<>OpB2 and $8000) and (OpB1 and $8000<>OpB and $8000) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);
  goto EndCmd;


  cBC:  {------------ OPC = BC = LDBSE --------}
  std(OPC and 3,1);
  OpB:=GetLocM(Op2Adr);
  asm mov  al,OpB
      cbw
      mov  OpW,ax
  end;
  Set2Reg(LoadB, OpW);
  goto EndCmd;


  cC0:  {------------ OPC = C0 = ST --------}
  std(OPC and 3,2);
  Set2LocM(Op2Adr, Get2Reg(LoadB));
  goto EndCmd;


  cC1:  {------------ OPC = C1 --------}
  IntEnabled:=False;
  OpW1:=LoadW;
  OpW:=reg_x;
  if OpW=0 then OpW:=OpW1;
  Op1Adr:=LoadB;
  if OpW>0 then
  Begin
    Set2Loc(Get2Reg(Op1Adr+2),Get2Loc(Get2Reg(Op2Adr)));
    Dec(OpW);
  End;
  if OpW>0 then Dec(PC,3) Else IntEnabled:=True;
  Reg_x:=OpW;
  goto EndCmd;


  cC4:  {------------ OPC = C4 --------}
  std(OPC and 3,1);
  SetLocM(Op2Adr, GetReg(LoadB));
  goto EndCmd;


  cC5:  {------------ OPC = C5 --------}
  if MCSFunc and MF_Mask=MF_BH then ErFlag:=True;
  Op2Adr:=LoadB;
  Op1Adr:=LoadB;
  OpL1:=Get4Reg(Op1Adr);
  OpL2:=Get4Reg(Op2Adr);
  fl:=0;
  asm
     mov   ax,word ptr OpL1
     mov   dx,word ptr OpL1[2]
     sub   ax,word ptr OpL2
     sbb   dx,word ptr OpL2[2]
     mov   word ptr OpL,ax
     mov   word ptr OpL[2],dx
     jc    @1
     mov   fl,flag_c
  @1:
  end;

  if OpL=0 then fl:=fl or flag_z;
  if OpL<0 then fl:=fl or flag_n;
  if (OpL1 shr 31<>OpL2 shr 31) and (OpL1 shr 31<>OpL shr 31) then
       fl:=fl or flag_v or flag_vt;
  flags(fl, flag_z or flag_n or flag_v or flag_c);

  goto EndCmd;


  cC8:  {------------ OPC = C8 --------}
  Std(OPC and 3,2);
  PushW(Get2LocM(Op2Adr));
  goto EndCmd;


  cCC:  {------------ OPC = CC --------}
  Std(OPC and 3,2);
  Set2LocM(Op2Adr,PopW);
  goto EndCmd;


  cCD:  {------------ OPC = CD --------}
  OpW1:=LoadW;
  OpW:=reg_x;
  if OpW=0 then OpW:=OpW1;
  Op1Adr:=LoadB;
  if OpW>0 then
  Begin
    Set2Loc(Get2Reg(Op1Adr+2),Get2Loc(Get2Reg(Op2Adr)));
    Dec(OpW);
  End;
  if OpW>0 then Dec(PC,3);
  Reg_x:=OpW;
  goto EndCmd;


  cD0:  {------------ OPC = D0 --------}
  OpB:=LoadB;
  if PSW and flag_st=0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cD1:  {------------ OPC = D1 --------}
  OpB:=LoadB;
  if (PSW and flag_c=0) or (PSW and flag_z<>0) then inc(PC,shortint(OpB));
  goto EndCmd;


  cD2:  {------------ OPC = D2 --------}
  OpB:=LoadB;
  if (PSW and (flag_N or flag_z)=0) then inc(PC,shortint(OpB));
  goto EndCmd;


  cD3:  {------------ OPC = D3 --------}
  OpB:=LoadB;
  if (PSW and flag_c=0) then inc(PC,shortint(OpB));
  goto EndCmd;



  cD4:  {------------ OPC = D4 --------}
  OpB:=LoadB;
  if (PSW and flag_vt=0) then inc(PC,shortint(OpB));
  goto EndCmd;


  cD5:  {------------ OPC = D5 --------}
  OpB:=LoadB;
  if (PSW and flag_v=0) then inc(PC,shortint(OpB));
  goto EndCmd;


  cD6:  {------------ OPC = D6 --------}
  OpB:=LoadB;
  if PSW and flag_N=0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cD7:  {------------ OPC = D7 --------}
  OpB:=LoadB;
  if PSW and flag_Z=0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cD8:  {------------ OPC = D8 --------}
  OpB:=LoadB;
  if PSW and flag_st<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cD9:  {------------ OPC = D9 --------}
  OpB:=LoadB;
  if (PSW and (flag_C or flag_z)=flag_c) then inc(PC,shortint(OpB));
  goto EndCmd;


  cDA:  {------------ OPC = DA --------}
  OpB:=LoadB;
  if (PSW and (flag_N or flag_z)<>0) then inc(PC,shortint(OpB));
  goto EndCmd;


  cDB:  {------------ OPC = DB --------}
  OpB:=LoadB;
  if PSW and flag_C<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cDC:  {------------ OPC = DC --------}
  OpB:=LoadB;
  if PSW and flag_VT<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cDD:  {------------ OPC = DD --------}
  OpB:=LoadB;
  if PSW and flag_v<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cDE:  {------------ OPC = DE --------}
  OpB:=LoadB;
  if PSW and flag_N<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cDF:  {------------ OPC = DF --------}
  OpB:=LoadB;
  if PSW and flag_Z<>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cE0:  {------------ OPC = E0 --------}
  OpB2:=LoadB;
  OpB:=GetReg(OpB2)-1;
  setreg(OpB2,OpB);
  OpB2:=LoadB;
  if OpB>0 then inc(PC,shortint(OpB2));
  goto EndCmd;


  cE1:  {------------ OPC = E1 --------}
  if MCSFunc and MF_Mask=MF_BH then ErFlag:=True;
  OpB:=LoadB;
  OpW:=Get2Reg(OpB)-1;
  Set2Reg(OpB, OpW);
  OpB:=LoadB;
  if OpW>0 then inc(PC,shortint(OpB));
  goto EndCmd;


  cE2:  {------------ OPC = E2 --------}
  if (MCSFunc and MF_Mask=MF_BH) or (MCSFunc and MF_Mask=MF_KB) then ErFlag:=True;
  PC:=Get2Loc(word(GetLoc(Get2Reg(LoadB)) and LoadB) shl 1+Get2Reg(LoadB));
  goto EndCmd;


  cE3:  {------------ OPC = E3 --------}
  PC:=Get2Reg(LoadB);
  goto EndCmd;


  cE4:  {------------ OPC = E4 --------}
  OpW1:=LoadW;
  OpW:=Reg_X;
  if OpW=0 then OpW:=OpW1;
  Op1Adr:=LoadB;
  if OpW>0 then
  Begin
    Set2Loc(Get3Reg(Op1Adr+4),Get2Loc(Get3Reg(Op2Adr)));
    Dec(OpW);
  End;
  if OpW>0 then Dec(PC,3);
  Reg_x:=OpW;
  goto EndCmd;


  cE5:  {------------ OPC = E5 --------}
  ErFlag:=True;
  goto EndCmd;


  cE6:  {------------ OPC = E6 --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  OpL:=LoadT;
  if OpL and $800000<>0 then OpL:=OpL or $FF000000;
  inc(PC,OpL);
  goto EndCmd;


  cE7:  {------------ OPC = E7 --------}
  inc(PC, integer(LoadW));
  goto EndCmd;


  cE8:  {------------ OPC = E8 --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  OpL:=Get3Reg(Op2Adr);
  Set2Reg(LoadB, Get2loc(OpL));
  if Op2Adr and 3=1 then Set3Reg(Op2Adr, OpL+2);
  goto EndCmd;


  cE9:  {------------ OPC = E9 --------}
  if MCSFunc and MF_MAsk<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  OpL:=Get3Reg(Op2Adr)+LoadT;
  Set2Reg(LoadB, Get2Loc(OpL));
  goto EndCmd;


  cEA:  {------------ OPC = EA --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  OpL:=Get3Reg(Op2Adr);
  SetReg(LoadB, Getloc(OpL));
  if Op2Adr and 3=1 then Set3Reg(Op2Adr, OpL+1);
  goto EndCmd;

  cEB:  {------------ OPC = EB --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  Op2Adr:=LoadB;
  OpL:=Get3Reg(Op2Adr)+LoadT;
  SetReg(LoadB, Getloc(OpL));
  goto EndCmd;



  cEC:  {------------ OPC = EC --------}
  if (MCSFunc and MF_Mask=MF_BH) or (MCSFunc and MF_Mask=MF_KB) then ErFlag:=True;
  flags(0,flag_pse);
  goto EndCmd;


  cED:  {------------ OPC = ED --------}
  if (MCSFunc and MF_Mask=MF_BH) or (MCSFunc and MF_Mask=MF_KB) then ErFlag:=True;
  flags(flag_pse,0);
  goto EndCmd;


  cEE:  {------------ OPC = EE --------}
  ErFlag:=True;
  goto EndCmd;


  cEF:  {------------ OPC = EF --------}
  OpW:=LoadW;
  pushW(PC);
  inc(PC,Integer(OpW));
  goto EndCmd;


  cF0:  {------------ OPC = F0 --------}
  PC:=popW;
  goto EndCmd;


  cF1:  {------------ OPC = F1 --------}
  if MCSFunc and MF_Mask<>MF_NT then ErFlag:=True;
  OpL:=LoadT;
  if OpL and $800000<>0 then OPL:=OPL or $FF000000;
  inc(PC,OPL);
  goto EndCmd;


  cF2:  {------------ OPC = F2 --------}
  PushW(swap(PSW) or Int_Mask^);
  PSW:=0;
  Int_Mask^:=0;
  goto EndCmd;


  cF3:  {------------ OPC = F3 --------}
  OpW:=PopW;
  PSW:=Hi(OpW);
  Int_Mask^:=Lo(OpW);
  goto EndCmd;


  cF4:  {------------ OPC = F4 --------}
  if MCSFunc and MF_Mask=MF_BH then ErFlag:=True;
  PushW(swap(PSW) or Int_Mask^);
  PushW(swap(Int_Mask1^) or WSR^);
  PSW:=0;
  Int_Mask^:=0;
  Int_Mask1^:=0;
  goto EndCmd;


  cF5:  {------------ OPC = F5 --------}
  if MCSFunc and MF_Mask=MF_BH then ErFlag:=True;
  OpW:=PopW;
  Int_Mask1^:=Hi(OpW);
  WSR^:=Lo(OpW);
  OpW:=PopW;
  PSW:=Hi(OpW);
  Int_Mask^:=Lo(OpW);
  goto EndCmd;


  cF6:  {------------ OPC = F6 --------}
  if MCSFunc and MF_Mask=MF_BH then ErFlag:=True;
  Case LoadB Of
    1:IDLPD:=1;
    2:IDLPD:=2;
    Else
      ErFlag:=True;
  End;
  goto EndCmd;


  cF7:  {------------ OPC = F7 --------}
  PushW(PC);
  PC:=Get2Loc($2010);
  goto EndCmd;


  cF8:  {------------ OPC = F8 --------}
  flags(0,flag_c);
  goto EndCmd;


  cF9:  {------------ OPC = F9 --------}
  flags(flag_c,0);
  goto EndCmd;


  cFA:  {------------ OPC = FA --------}
  flags(0,flag_i);
  goto EndCmd;


  cFB:  {------------ OPC = FB --------}
  flags(flag_i,0);
  goto EndCmd;


  cFC:  {------------ OPC = FC --------}
  flags(0,flag_vt);
  goto EndCmd;


  cFD:  {------------ OPC = FD = nop --------}
  goto EndCmd;


  cFE:  {------------ OPC = FE --------}
  Perfex:=1;
  goto EndCmd;


  cFF:  {------------ OPC = FF --------}
  Reset;
  goto EndCmd;


  asm
    Table:
           dw       c00
           dw       c01
           dw       c02
           dw       c03
           dw       c04
           dw       c05
           dw       c06
           dw       c07
           dw       c08
           dw       c09
           dw       c0A
           dw       c04
           dw       c0C
           dw       c0D
           dw       c0E
           dw       c0F
           dw       c10
           dw       c11
           dw       c12
           dw       c13
           dw       c14
           dw       c15
           dw       c16
           dw       c17
           dw       c18
           dw       c19
           dw       c1A
           dw       c14
           dw       c1C
           dw       c1C
           dw       c1E
           dw       c1E
           dw       c20
           dw       c20
           dw       c20
           dw       c20
           dw       c20
           dw       c20
           dw       c20
           dw       c20
           dw       c28
           dw       c28
           dw       c28
           dw       c28
           dw       c28
           dw       c28
           dw       c28
           dw       c28
           dw       c30
           dw       c30
           dw       c30
           dw       c30
           dw       c30
           dw       c30
           dw       c30
           dw       c30
           dw       c38
           dw       c38
           dw       c38
           dw       c38
           dw       c38
           dw       c38
           dw       c38
           dw       c38
           dw       c40
           dw       c40
           dw       c40
           dw       c40
           dw       c44
           dw       c44
           dw       c44
           dw       c44
           dw       c48
           dw       c48
           dw       c48
           dw       c48
           dw       c4C
           dw       c4C
           dw       c4C
           dw       c4C
           dw       c50
           dw       c50
           dw       c50
           dw       c50
           dw       c54
           dw       c54
           dw       c54
           dw       c54
           dw       c58
           dw       c58
           dw       c58
           dw       c58
           dw       c5C
           dw       c5C
           dw       c5C
           dw       c5C
           dw       c60
           dw       c60
           dw       c60
           dw       c60
           dw       c64
           dw       c64
           dw       c64
           dw       c64
           dw       c68
           dw       c68
           dw       c68
           dw       c68
           dw       c6C
           dw       c6C
           dw       c6C
           dw       c6C
           dw       c70
           dw       c70
           dw       c70
           dw       c70
           dw       c74
           dw       c74
           dw       c74
           dw       c74
           dw       c78
           dw       c78
           dw       c78
           dw       c78
           dw       c7C
           dw       c7C
           dw       c7C
           dw       c7C
           dw       c80
           dw       c80
           dw       c80
           dw       c80
           dw       c84
           dw       c84
           dw       c84
           dw       c84
           dw       c88
           dw       c88
           dw       c88
           dw       c88
           dw       c8C
           dw       c8C
           dw       c8C
           dw       c8C
           dw       c90
           dw       c90
           dw       c90
           dw       c90
           dw       c94
           dw       c94
           dw       c94
           dw       c94
           dw       c98
           dw       c98
           dw       c98
           dw       c98
           dw       c9C
           dw       c9C
           dw       c9C
           dw       c9C
           dw       cA0
           dw       cA0
           dw       cA0
           dw       cA0
           dw       cA4
           dw       cA4
           dw       cA4
           dw       cA4
           dw       cA8
           dw       cA8
           dw       cA8
           dw       cA8
           dw       cAC
           dw       cAC
           dw       cAC
           dw       cAC
           dw       cB0
           dw       cB0
           dw       cB0
           dw       cB0
           dw       cB4
           dw       cB4
           dw       cB4
           dw       cB4
           dw       cB8
           dw       cB8
           dw       cB8
           dw       cB8
           dw       cBC
           dw       cBC
           dw       cBC
           dw       cBC
           dw       cC0
           dw       cC1
           dw       cC0
           dw       cC0
           dw       cC4
           dw       cC5
           dw       cC4
           dw       cC4
           dw       cC8
           dw       cC8
           dw       cC8
           dw       cC8
           dw       cCC
           dw       cCD
           dw       cCC
           dw       cCC
           dw       cD0
           dw       cD1
           dw       cD2
           dw       cD3
           dw       cD4
           dw       cD5
           dw       cD6
           dw       cD7
           dw       cD8
           dw       cD9
           dw       cDA
           dw       cDB
           dw       cDC
           dw       cDD
           dw       cDE
           dw       cDF
           dw       cE0
           dw       cE1
           dw       cE2
           dw       cE3
           dw       cE4
           dw       cE5
           dw       cE6
           dw       cE7
           dw       cE8
           dw       cE9
           dw       cEA
           dw       cEB
           dw       cEC
           dw       cED
           dw       cEE
           dw       cEF
           dw       cF0
           dw       cF1
           dw       cF2
           dw       cF3
           dw       cF4
           dw       cF5
           dw       cF6
           dw       cF7
           dw       cF8
           dw       cF9
           dw       cFA
           dw       cFB
           dw       cFC
           dw       cFD
           dw       cFE
           dw       cFF
  end;
  EndCmd:
  if ErFlag and (MCSFunc and MF_BH<>0) then PC:=Get2Loc($2012);
  Ports;
  ADC;
End;

Destructor TSimulator.Done;
Begin
  Freemem(Memory,$FFF2);
End;

procedure TSimulator.ExecutePTS;
begin
  WorkPTS:=WorkPTS or i;

  WorkPTS:=WorkPTS and not i;
  PTSSEL^:=PTSSEL^ and not i;
  PTSSRV^:=PTSSRV^ or i;
end;

Function TSimulator.ICC;
Var
  k,k1,k2 : word;
  i       : Byte;
  isPTS   : Boolean;

procedure RstPend(int:Word);
Begin
  if isPTS and (PTSSRV^ and int<>0) then
     PTSSRV^:=PTSSRV^ and not int
  Else
  begin
    if int and $FF00<>0 then
      int_pend1^:=int_Pend1^ and not swap(int)
    Else
      int_pend^:=int_pend^ and not int;
  end;
end;

Begin
    ICC:=False;
    { „ҐвҐЄв®p ЇҐpҐЇ ¤  }
    int_pend^:=int_pend^ or lo(IntSignals) and Lo(OldIntSignals);
    int_pend1^:=int_pend1^ or hi(IntSignals) and hi(OldIntSignals);
    OldIntSignals:=not IntSignals;
    IntSignals:=0;

    isPTS:=(mcsfunc and MF_Mask<>mf_BH) and (mcsfunc and MF_MASK<>mf_KB);

    if int_pend1^ and $80<>0 then { NMI }
    Begin
      if isPTS and (PTSSRV^ and $8000<>0) then
        PTSSRV^:=PTSSRV^ and $7FFF
      Else
        int_pend1^:=int_pend1^ and $7F;
      ICC:=True;
      IntVec:=$203E;
      exit;
    end;

    k:=int_pend^ and int_mask^ or swap(int_pend1^ and int_mask1^); { MC - ¬ бЄЁа®ў ­ЁҐ }

    { DMX - ¤Ґ¬г«мвЁЇ«ҐЄб®а }
    if not isPTS then
    Begin
      k1:=k;
      k2:=0;
    end
    Else
    Begin
      k:=k or PTSSRV^;
      k1:=k and not(ptssel^);
      k2:=k and ptssel^ or WorkPTS;
    end;

    { K1, K2 - Є«озҐўл© б奬л }
    if PSW and 2=0 then k1:=0;
    if PSW and 4=0 then k2:=0;

    { PE }
    if (k2=0) and (k1=0) then Exit;
    asm
         mov   i,30
         mov   cx,15
         mov   ax,k2
    @1:  rcl   ax,1
         jc    @ex
         dec   i
         loop  @1

         mov   cx,15
         mov   ax,k1
    @2:  rcl   ax,1
         jc    @ex
         dec   i
         loop  @2
    @ex:
    end;

    case i Of
      29:begin
           int_pend1^:=int_pend1^ and $BF;
           ExecutePTS(int_2);
         end;
      28:if (MCSFunc and MF_MASK=MF_KR) or (MCSFunc and MF_MASK=MF_NT) then
         Begin
           int_Pend1^:=int_pend1^ and $DF;
           ExecutePTS(int_3);
         end;

      27:begin
           int_pend1^:=int_pend1^ and $EF;
           ExecutePTS(int_4);
         end;
      26:Begin
           int_pend1^:=int_pend1^ and $F7;
           ExecutePTS(int_5);
         end;
      25:begin
           int_pend1^:=int_pend1^ and $FB;
           ExecutePTS(int_6);
         end;
      24:begin
           int_pend1^:=int_pend1^ and $FD;
           ExecutePTS(int_7);
         end;
      23:begin
           int_pend1^:=int_pend1^ and $FE;
           ExecutePTS(int_8);
         end;
      22:begin
           int_pend^:=int_pend^ and $7F;
           ExecutePTS(int_9);
         end;
      21:begin
           int_pend^:=int_pend^ and $BF;
           ExecutePTS(int_10);
         end;
      20:begin
           int_pend^:=int_pend^ and $DF;
           ExecutePTS(int_11);
         end;
      19:begin
           int_pend^:=int_pend^ and $EF;
           ExecutePTS(int_12);
         end;
      18:begin
           int_pend^:=int_pend^ and $F7;
           ExecutePTS(int_13);
         end;
      17:begin
           int_pend^:=int_pend^ and $FB;
           ExecutePTS(int_14);
         end;
      16:begin
           int_pend^:=int_pend^ and $FD;
           ExecutePTS(int_15);
         end;
      15:begin
           int_pend^:=int_pend^ and $FE;
           ExecutePTS(int_16);
         end;

      14:begin RstPend(int_2); ICC:=True; IntVec:=$203C;end;
      13:if (MCSFunc and MF_MASK=MF_KR) or (MCSFunc and MF_MASK=MF_NT) then
         Begin rstpend(int_3); ICC:=True; IntVec:=$203A; end;
      12:Begin rstPend(int_4); ICC:=True; IntVec:=$2038; end;
      11:Begin rstpend(int_5); ICC:=True; IntVec:=$2036; end;
      10:Begin rstpend(int_6); ICC:=True; IntVec:=$2034; end;
      9: Begin rstpend(int_7); ICC:=True; IntVec:=$2032; end;
      8: Begin rstpend(int_8); ICC:=True; IntVec:=$2030; end;
      7: Begin rstpend(int_9); ICC:=True; IntVec:=$200E; end;
      6: Begin rstpend(int_10);ICC:=True; IntVec:=$200C; end;
      5: Begin rstpend(int_11);ICC:=True; IntVec:=$200A; end;
      4: Begin rstpend(int_12);ICC:=True; IntVec:=$2008; end;
      3: Begin rstpend(int_13);ICC:=True; IntVec:=$2006; end;
      2: Begin rstpend(int_14);ICC:=True; IntVec:=$2004; end;
      1: Begin rstpend(int_15);ICC:=True; IntVec:=$2002; end;
      0: Begin rstpend(int_16);ICC:=True; IntVec:=$2000; end;
    end;
end;

Procedure TSimulator.Ports;
Var
  P, Mask, ZeroMask, Code : Byte;
Begin
 for p:=0 to 8 do
 begin
  if PX_PIN[p]=nil then continue;
  case P of
    3,5:if (MCSFunc and MF_SLP<>0) and (SLP_CON^ and 8<>0) then Continue;
  end;



  Code:=PortsLegs[p];
  { 1. Њ бЄ  ўлў®¤®ў I/O }
  mask:=hi(word($FF) shl P_Out[p]);

  { 2. Њ бЄ  ўлў®¤®ў, ­ҐўлЇ®«­пойЁе  «вҐа­ вЁў­®© дг­ЄжЁЁ }
  if PX_Mode[p]<>nil then mask:=mask and not(PX_mode[p]^);

  { 3. ‚лў®¤ зҐаҐ§ Ї®ав }
  if PX_DIR[p]<>nil then
  begin
    { 3.1 ¬ бЄ  § ­г«пҐ¬ле ЎЁв®ў }
    ZeroMask:=(not PX_Dir[p]^ or not PX_Reg[p]^) and Mask;
    Code:=Code and not ZeroMask or (PX_Reg[p]^ and mask and not PX_Dir[p]^);
  end
  Else
    if PX_Reg[p]<>nil then
    Begin
      if (P=3) and (P34_drv<>nil) and (P34_drv^ and $80<>0) then
      begin
        Code:=PX_Reg[3]^ and mask or (Code and not mask);
      End
      Else
      if (P=4) and (P34_drv<>nil) and (P34_DRV^ and $40<>0) then
      begin
        Code:=PX_Reg[4]^ and mask or (Code and not mask);
      end
      Else
      begin
        ZeroMask:=not PX_Reg[p]^ and mask;
        Code:=Code and not ZeroMask;
      end;
    end;

   { 4. —⥭ЁҐ зҐаҐ§ Ї®ав }
   Px_pin[p]^:=Code;
   PortsLegs[p]:=Code;
 end;
end;


Procedure TSimulator.SlavePort;
begin
  if (MCSFunc and MF_SLP<>0) and (SLP_CON^ and 8<>0) then
  Begin
    PortsLegs[5]:=PortsLegs[5] and $EF;
    if SLP_CON^ and $10<>0 then
    begin
      if MCSFunc and MF_MASK=MF_NT then
      begin
        Case PortsLegs[5] and $0F Of
          $0F: { ALE }
           Begin
             SLP_CMD^:=PortsLegs[3];
             IntSignals:=IntSignals or Int_8;
           end;
              { __ }
          $8: { WR }
            Begin
              PX_PIN[3]^:=PortsLegs[3];
              IntSignals:=IntSignals or Int_9;
              SLP_STAT^:=SLP_STAT^ or $80;
            End;
             { __ }
          $4:{ RD }
            Begin
              PortsLegs[3]:=PX_REG[3]^;
              IntSignals:=IntSignals or int_10;
              SLP_STAT^:=SLP_STAT^ and $7F;
            End;
        End;
      End
      Else
        SLP_CON^:=SLP_CON^ and $EF;
    end
    Else
    Begin
      if SLP_CON^ and 4<>0 then
      begin
         if PortsLegs[5] and 1<>0 then ca:=PortsLegs[3] and 2<>0;
      end
      Else
        ca:=PortsLegs[5] and 1<>0;

      Case PortsLegs[5] and $0E Of
            { __     _____ }
        $8: { WR and SLPCS }
        begin
          if ca then
          begin
            SLP_CMD^:=PortsLegs[3];
            IntSignals:=IntSignals or Int_8;
          end
          Else
          begin
            PX_PIN[3]^:=PortsLegs[3];
            IntSignals:=IntSignals or Int_9;
          end;
        End;
           { __     _____ }
        $4:{ RD and SLPCS }
        Begin
          if ca then
            PortsLegs[3]:=SLP_STAT^
          Else
          Begin
            PortsLegs[3]:=PX_REG[3]^;
            IntSignals:=IntSignals or Int_10;
          end;
        End;
      End;
    end;
  end;
end;


Function TSimulator.BRG;
Var
  Leg : Boolean;
Begin
  BRG:=False;
  if SP_BAUD^ and $7FFF=0 then Exit;

  if SP_BAUD^ and $8000<>0 then
  begin
    Dec(BRGDiver, Circles);
    While BRGDiver<=0 do
    Begin
      if SP_CON^ and 3<>0 then inc(BRGDiver,16) Else inc(BRGDiver,2);
      Dec(BRGCount);
      if BRGCount<0 then
      begin
        BRGCount:=SP_BAUD^ and $7FFF;
        BRG:=TRUE;
      End;
    end;
  end
  Else
  Begin
    if (MCSFunc and MF_Mask=MF_KR) or (MCSFunc and MF_Mask=MF_NT) then
      leg:=PortsLegs[6] and 4<>0
    Else
      leg:=PortsLegs[2] and 8<>0;
    if leg then
    begin
      if SP_CON^ and 3<>0 then Dec(BRGDiver) Else BRGDiver:=0;
      if BRGDiver<=0 then
      Begin
        BRGDiver:=8;
        Dec(BRGCount);
        if BRGCount<=0 then
        Begin
          BRGCount:=SP_BAUD^ and $7FFF;
          BRG:=TRUE;
        end;
      end;
    End;
  end;
End;

function IsPAR( A : Byte):byte; Assembler;
asm
      mov   al,A
      or    al,al
      lahf
      shr   ah,2
      and   ah,1
      mov   al,ah
end;



Procedure TSimulator.SerialPort;
Var
  P2_1 : Boolean;
  bit  : Byte;

begin
  if MCSFunc and MF_Mask=MF_MC then Exit;
  if SP_BAUD^ and $7FFF=0 then Exit;
  Case SP_CON^ and $0B of
    0:begin
        { бЁ­еа®­­л© ०Ё¬ ЇҐаҐ¤ з  }
        { д®а¬Ёа㥬 ¬Ґ ­¤а ­  P2.0 }
        if (PX_MODE[2]^ and 1<>0) then
          PortsLegs[2]:=PortsLegs[2] and $FE or Ord(BRGCount > SP_BAUD^ and $7FFF shr 1);

        if BRG then
        begin
          if SP_STAT^ and $20=0 then
          begin
            if PX_Mode[2]^ and 2<>0 then PortsLegs[2]:=PortsLegs[2] and $FD or
              SBUF_TX^ shr SerialPortCount and 1 shl 1;
            inc(SerialPortCount);
            if SerialPortCount>7 then
            begin
              IntSignals:=IntSignals or int_TI_Mask;
              SerialPortCount:=0;
              SP_STAT^:=SP_STAT^ or $20;
            end;
          end
        end;
      end;
    8:Begin
       { бЁ­еа®­­л© ЇаЁҐ¬ }
       { д®а¬Ёа㥬 ¬Ґ ­¤а ­  P2.0 }
       if (PX_MODE[2]^ and 1<>0) then
          PortsLegs[2]:=PortsLegs[2] and $FE or Ord(BRGCount > SP_BAUD^ and $7FFE shr 1);

       if BRG then
       begin
        if SP_STAT^ and $40=0 then
        begin
         if PX_Mode[2]^ and 2<>0 then SBUF_RX^:=SBUF_RX^ shr 1 or (PortsLegs[2] and 2 shl 6);
         inc(SerialPortCount);
         if SerialPortCount>7 then
         begin
           IntSignals:=IntSignals or int_RI_Mask;
           SerialPortCount:=0;
           SP_STAT^:=SP_STAT^ or $40;
         end;
        end;
       End;
      end;

    1:Begin
        {  бЁ­еа®­­л© ०Ё¬ 01 ЇҐаҐ¤ з  }
        if SP_STAT^ and $20=0 then
        begin
          if BRG then
          begin
            Case SerialPortCount Of
              0:bit:=0;
              1..7:bit:=SBUF_TX^ shr (SerialPortCount-1) and 1;
              8:if SP_CON^ and 4<>0 then
                  bit:=isPAR(SBUF_TX^ and $7F) xor (SP_CON^ shr 5 and 1)
                Else
                  bit:=SBUF_TX^ shr 7;
              9:begin
                  bit:=1;
                  SerialPortCount:=$FF;
                  SP_STAT^:=SP_STAT^ or $20;
                  IntSignals:=IntSignals or Int_TI_Mask;
                end;
            end;
            inc(SerialPortCount);
            if PX_Mode[2]^ and 1<>0 then PortsLegs[2]:=PortsLegs[2] and $FE or bit;
          end
        end
      end;
    9:begin
        {  бЁ­еа®­­л© 01 ЇаЁҐ¬ }
        if PX_MODE[2]^ and 2=0 then Exit;
        P2_1:=PortsLegs[2] and 2<>0;
        if (SerialPortCount=0) then
        begin
          if (P2_1 and not TriggerP2_1) then SerialPortCount:=1;
          TriggerP2_1:=P2_1;
          BRGCount:=SP_BAUD^ and $7FFF;
          exit;
        end;
        TriggerP2_1:=P2_1;
        if not BRG then Exit;
        Case SerialPortCount Of
          1..7:SBUF_RX^:=SBUF_RX^ shr 1 or (ord(P2_1) shl 6);
          8:if SP_CON^ and 4<>0 then
            begin
              bit:=isPAR(SBUF_RX^) xor (SP_CON^ shr 5 and 1) xor ord(P2_1);
              SP_STAT^:=SP_STAT^ and $7F or bit shl 7;
            end
            Else
              SBUF_RX^:=SBUF_RX^ or bit shl 7;
          9:begin
              SP_STAT^:=SP_STAT^ and $EF or ord(not(P2_1)) shl 4;
              SP_STAT^:=SP_STAT^ or $40;
              IntSignals:=IntSignals or int_RI_Mask;
              SerialPortCount:=$FF;
            end;
        end;
        inc(SerialPortCount);
      end;

    2:Begin
        {  бЁ­еа®­­л© ०Ё¬ 10 ЇҐаҐ¤ з  }
        if SP_STAT^ and $20=0 then
        begin
          if BRG then
          begin
            Case SerialPortCount Of
              0:bit:=0;
              1..8:bit:=SBUF_TX^ shr (SerialPortCount-1) and 1;
              9:bit:=SP_CON^ shr 4 and 1;
              10:begin
                  bit:=1;
                  SerialPortCount:=$FF;
                  SP_STAT^:=SP_STAT^ or $20;
                  IntSignals:=IntSignals or Int_TI_Mask;
                end;
            end;
            inc(SerialPortCount);
            if PX_Mode[2]^ and 1<>0 then PortsLegs[2]:=PortsLegs[2] and $FE or bit;
          end
        end
      end;
    $A:begin
        {  бЁ­еа®­­л© 10 ЇаЁҐ¬ }
        if PX_MODE[2]^ and 2=0 then Exit;
        P2_1:=PortsLegs[2] and 2<>0;
        if (SerialPortCount=0) then
        begin
          if (P2_1 and not TriggerP2_1) then SerialPortCount:=1;
          TriggerP2_1:=P2_1;
          BRGCount:=SP_BAUD^ and $7FFF;
          exit;
        end;
        TriggerP2_1:=P2_1;
        if not BRG then Exit;
        Case SerialPortCount Of
          1..8:SBUF_RX^:=SBUF_RX^ shr 1 or (ord(P2_1) shl 7);
          9:SP_STAT^:=SP_STAT^ and $7F or (ord(P2_1) shl 7);
          10:begin
              SP_STAT^:=SP_STAT^ and $EF or ord(not(P2_1)) shl 4;
              if SP_STAT^ and $80<>0 then
              begin
                SP_STAT^:=SP_STAT^ or $40;
                IntSignals:=IntSignals or int_RI_Mask;
              end;
              SerialPortCount:=$FF;
            end;
        end;
        inc(SerialPortCount);
      end;

    3:Begin
        {  бЁ­еа®­­л© ०Ё¬ 11 ЇҐаҐ¤ з  }
        if SP_STAT^ and $20=0 then
        begin
          if BRG then
          begin
            Case SerialPortCount Of
              0:bit:=0;
              1..8:bit:=SBUF_TX^ shr (SerialPortCount-1) and 1;
              9:if SP_CON^ and 4<>0 then
                  bit:=isPAR(SBUF_TX^) xor (SP_CON^ shr 5 and 1)
                Else
                  bit:=SP_CON^ shr 4 and 1;
              10:begin
                  bit:=1;
                  SerialPortCount:=$FF;
                  SP_STAT^:=SP_STAT^ or $20;
                  IntSignals:=IntSignals or Int_TI_Mask;
                end;
            end;
            inc(SerialPortCount);
            if PX_Mode[2]^ and 2<>0 then PortsLegs[2]:=PortsLegs[2] and $FE or bit;
          end
        end
      end;
    $B:begin
        {  бЁ­еа®­­л© 11 ЇаЁҐ¬ }
        if PX_MODE[2]^ and 2=0 then Exit;
        P2_1:=PortsLegs[2] and 2<>0;
        if (SerialPortCount=0) then
        begin
          if (not P2_1 and TriggerP2_1) then SerialPortCount:=1;
          TriggerP2_1:=P2_1;
          BRGCount:=SP_BAUD^ and $7FFF;
          exit;
        end;
        TriggerP2_1:=P2_1;
        if not BRG then Exit;
        Case SerialPortCount Of
          1..8:
            SBUF_RX^:=SBUF_RX^ shr 1 or (ord(P2_1) shl 7);
          9:if SP_CON^ and 4<>0 then
            begin
              bit:=isPAR(SBUF_RX^) xor (SP_CON^ shr 5 and 1) xor ord(P2_1);
              SP_STAT^:=SP_STAT^ and $7F or bit shl 7;
            End
            Else
              SP_STAT^:=SP_STAT^ and $7F or (ord(P2_1) shl 7);
          10:begin
              SP_STAT^:=SP_STAT^ and $EF or ord(not(P2_1)) shl 4;
              SP_STAT^:=SP_STAT^ or $40;
              IntSignals:=IntSignals or int_RI_Mask;
              SerialPortCount:=$FF;
            end;
        end;
        inc(SerialPortCount);
      end;
  End;
End;

procedure TSimulator.SSIO;
Var
  Ch     : Byte;
  Synh   : Boolean;
  Meandr : Boolean;
  i      : Byte;

  inti   : Boolean;
const
  SDx : Array[0..1] Of Byte=($20,$80);
  SCx : Array[0..1] Of Byte=($10,$40);
  SSIOInt : Array[0..1] Of Word=(int_7, int_6);
Begin
  if (MCSFunc and MF_Mask<>MF_KR) and (MCSFunc and MF_Mask<>MF_NT) then Exit;
  inc(BRG8,Circles);
  if BRG8>7 then
  Begin
    Dec(BRG8,8);
    if SSIO_BAUD^ and $80<>0 then
    asm
        les   bx,[bp+6]
        mov   al,byte ptr es:TSimulator.Circles[bx]
        mov   ah,es:TSimulator.BRGSSIO[bx]
        and   ah,7Fh
        les   bx, dword ptr es:TSimulator.SSIO_BAUD[bx]
        sub   es:[bx],al
        jnc   @1
        mov   es:[bx],ah
    @1: or    byte ptr es:[bx],80h
    end;
  end;
  Meandr:=Ord(SSIO_BAUD^ and $7F) >= BRGSSIO and $7F shr 1;

  for ch:=0 to 1 do
  begin
    inti:=False;
    if Px_MODE[6]^ and SCx[ch]<>0 then
    begin
      if SSIOx_CON[ch]^ and $14=$14 then
      Begin
        if (SSIOx_CON[ch]^ and $80<>0) and (SSIOCount[ch]<9) then
        begin
          if not Meandr then PortsLegs[6]:=PortsLegs[6] or (SCx[Ch] and $FF)
          Else
          PortsLegs[6]:=PortsLegs[6] and not SCx[ch];
        End;
        if (SSIOCount[ch]=9) and (PortsLegs[6] and SCx[ch]<>0) then inti:=true;
        if (PortsLegs[6] and SCx[ch]=0) and SCxTrigger[ch] then Synh:=True;
        SCxTrigger[ch]:=PortsLegs[6] and SCx[ch]<>0;
      End
      Else
      Begin
        if SSIOx_CON[ch]^ and $80<>0 then
        begin
          if Meandr then PortsLegs[6]:=PortsLegs[6] or (SCx[Ch] and $FF)
          Else
          PortsLegs[6]:=PortsLegs[6] and not SCx[ch];
        End;
        if (PortsLegs[6] and SCx[ch]<>0) and not SCxTrigger[ch] then Synh:=True;
        SCxTrigger[ch]:=PortsLegs[6] and SCx[ch]<>0;
        if SSIOCount[ch]=7 then inti:=True;
      end;
    End;

    if Synh and (Px_MODE[6]^ and SDx[ch]<>0) then
    begin
      if SSIOx_CON[ch]^ and $40<>0 then
      begin
        if SSIOCount[ch]=0 then SSIOBuf[ch]:=SSIOx_BUF[ch]^;
        if SSIOCount[ch]<8 then
        Begin
         if SSIOBuf[ch] and 1<>0 then
           PortsLegs[6]:=PortsLegs[6] or (SDx[ch] and $FF)
         Else
           PortsLegs[6]:=PortsLegs[6] and not SDx[ch];
         inc(SSIOCount[ch]);
         SSIOBuf[ch]:=SSIOBuf[ch] shr 1;
        End;
      End
      Else
      Begin
        if SSIOCount[ch]<8 then
        Begin
          if PortsLegs[6] and SDx[ch]<>0 then i:=$80 Else i:=0;
          SSIOx_Buf[ch]^:=SSIOx_Buf[ch]^ shr 1 or i;
          inc(SSIOCount[ch]);
        End;
      end;
      if inti then
      Begin
        SSIOx_CON[ch]^:=SSIOx_CON[ch]^ and $F7 or 1;
        if SSIOx_CON[ch]^ and $20<>0 then SSIOx_CON[ch]^:=SSIOx_CON[ch]^ xor $40;
        IntSignals:=IntSignals or SSIOInt[ch];
        SSIOCount[ch]:=0;
      End;
    End;
  end;
end;


Procedure TSimulator.PWM;
Var
  R          : Integer;
  HoldReload : Boolean;
  bit        : Byte;

Function CHx(x:Byte):Byte;
Begin
  if HoldReload then PWMHoldReg[x]:=PWM_Control[x]^;
  CHx:=ord(PWMcount<PWMHoldReg[x]);
end;

Begin
  HoldReload:=False;
  Case MCSFunc and MF_Mask Of
    MF_BH :
      begin
        inc(PWMDiver,Circles);
        While PWMDiver>0 do
        begin
          Dec(PWMDiver,3);
          Inc(PWMCount);
          if PWMCount>255 then
          Begin
            PWMCount:=0;
            HoldReload:=True;
          End;
        End;
        if (PX_MODE[2]^ and $20<>0) and (IOCx[1]^ and 1=1) then PortsLegs[2]:=PortsLegs[2] and not $20 or CHx(0) shl 5;
      End;
    MF_KB :
      begin
        inc(PWMDiver,Circles);
        While PWMDiver>0 do
        begin
          if IOCx[2]^ and 2<>0 then Dec(PWMDiver,2);
          Dec(PWMDiver,2);

          Inc(PWMCount);
          if PWMCount>255 then
          Begin
            PWMCount:=0;
            HoldReload:=True;
          End;
        End;
        if (PX_MODE[2]^ and $20<>0) and (IOCx[1]^ and 1=1) then PortsLegs[2]:=PortsLegs[2] and not $20 or CHx(0) shl 5;;
      end;
    MF_KC :
       Begin
        inc(PWMDiver,Circles);
        While PWMDiver>0 do
        begin
          if IOCx[2]^ and 4<>0 then Dec(PWMDiver,2);
          Dec(PWMDiver,2);

          Inc(PWMCount);
          if PWMCount>255 then
          Begin
            PWMCount:=0;
            HoldReload:=True;
          End;
        End;
        if (PX_MODE[2]^ and $20<>0) and (IOCx[1]^ and 1=1) then PortsLegs[2]:=PortsLegs[2] and not $20 or CHx(0) shl 5;
        if (IOCx[3]^ and 4<>0) then PortsLegs[1]:=PortsLegs[1] and not $08 or CHx(1) shl 3;
        if (IOCx[3]^ and 8<>0) then PortsLegs[1]:=PortsLegs[1] and not $10 or CHx(2) shl 4;
      end;
    MF_MC :
      Begin
        inc(PWMDiver,Circles);
        While PWMDiver>0 do
        begin
          Dec(PWMDiver,2);
          R:=PWM_Count^;
          Dec(R);
          PWM_Count^:=Byte(R);
          if R<0 then
          Begin
            PWM_Count^:=PWM_Reload^;
            inc(PWMCount);
            if PWMCount>255 then
            Begin
              PWMCount:=0;
              HoldReload:=true;
            End;
          End;
        End;
        bit:=CHx(0);
        if WG_Out^ and $800=0 then bit:=ord(WG_Out^ and $40<>0);
        PortsLegs[6]:=PortsLegs[6] and not $40 or bit shl 6;

        bit:=CHx(1);
        if WG_Out^ and $1000=0 then bit:=Ord(WG_Out^ and $80<>0);
        PortsLegs[6]:=PortsLegs[6] and not $80 or bit shl 7;
      End;
    Else Exit;
  End;
end;

Procedure TSimulator.FG;
Begin
  if MCSFunc and MF_FG<>0 then
  begin
    inc(FGDiver, Circles);
    While FGDiver>0 do
    begin
      Dec(FGDiver,16);
      Dec(FG_Count^);
      if FG_Count^=0 then
      Begin
        FG_Count^:=FG_CON^;
        if PX_MODE[7]^ and $80<>0 then PortsLegs[7]:=PortsLegs[7] xor $80;
      end;
    end;
  End;
End;


Procedure TSimulator.ADC;
Var
  B, T1,T2 : Integer;

Procedure UTest(Var U:Real);
begin
    if MCSFunc and MF_Mask=MF_MC then
    begin
      Case AD_Test^ and $14 Of
        $4: U:=U+2.5E-3;
        $10:U:=U-2.5E-3;
        $14:U:=U-5E-3;
      End
    End
    Else
    begin
      Case AD_Test^ and $3 of
        $1:U:=Vref;
        $3:U:=angnd;
      end;
      Case AD_Test^ and $C Of
        $4:U:=U+2.5E-3;
        $8:U:=U-2.5E-3;
        $C:U:=U-5E-3;
      End;
    End;
end;

Procedure GetU(Mask:Byte; u8_10, ADTest:Boolean);
Begin
  U:=Uin[AD_COMMAND^ and Mask];
  if ADTest then Utest(U);

  if Vref-angnd<2E-5 then U:=0
  Else
  begin
    U:=(U-angnd)/(Vref-angnd);
    if U>1 then U:=1;
    if U<0 then U:=0;
    if u8_10 then U:=U*1023 Else U:=U*255
  End;
End;

Function AD(MaskChx,MaskMode:Byte):Boolean;
Var
  UU, Upor : Real;
Begin
  UU:=Uin[AD_Command^ and MaskChx];
  UTest(UU);
  Upor:=Hi(AD_RESULT^)*(Vref-angnd)/255+angnd;

  AD:=(AD_Command^ and MaskMode<>0) and (UU > Upor) and (U < Upor) or
      (AD_Command^ and MaskMode=0)  and (UU < Upor) and (U > Upor);
  U:=UU;
End;


Begin
    Case MCSFunc and MF_Mask Of
      MF_BH:
        if ADCMustGo then
        Begin
          AD_RESULT^:=AD_RESULT^ or $8;
          if ADCDiver<=12 then GetU(7,True, False);
          if ADCDiver>264 then
          Begin
            ADCMustGo:=False;

            AD_RESULT^:=round(U) shl 6 or AD_COMMAND^ and 7;
            IntSignals:=IntSignals or Int_15;
          End;
        End;
      MF_KB:
        if ADCMustGo then
        Begin
          AD_RESULT^:=AD_RESULT^ or $8;
          if IOCx[2]^ and $10<>0 then
          Begin
            T1:=16;
            T2:=182+16;
          End
          Else
          Begin
            T1:=30;
            T2:=316+30;
          End;
          if ADCDiver<=T1 then GetU(7,True, False);
          if ADCDiver>T2 then
          Begin
            ADCMustGo:=False;

            AD_RESULT^:=round(U) shl 6 or AD_COMMAND^ and 7;
            IntSignals:=IntSignals or Int_15;
          End;
        End;
      MF_KC:
        if ADCMustGo then
        Begin
          AD_RESULT^:=AD_RESULT^ or $8;
          T1:=(4*(AD_Time^ shr 5)+1) shl 1;
          if AD_Command^ and $10<>0 then B:=8 Else B:=10;
          T2:=(B*(AD_Time^ and $1F+1)) shl 1+3;

          if ADCDiver<=T1 then GetU(7, B=10, False);
          if ADCDiver>T1+T2 then
          Begin
            ADCMustGo:=False;

            if B=8 then AD_RESULT^:=round(U) shl 8 or AD_COMMAND^ and 7
            Else
              AD_RESULT^:=round(U) shl 6 or AD_COMMAND^ and 7;
            IntSignals:=IntSignals or Int_15;
          End;
        End;
      MF_KR,MF_NT:
        Begin
         if AD_COMMAND^ and $20<>0 then
         begin
           if AD(7,$10) then IntSignals:=IntSignals or int_11
         End
         Else
         if ADCMustGo then
         begin
          AD_RESULT^:=AD_RESULT^ or $8;
          T1:=(4*(AD_Time^ shr 5)+1) shl 1;
          if AD_Command^ and $10<>0 then B:=8 Else B:=10;
          T2:=(B*(AD_Time^ and $1F+1)) shl 1+3;

          if ADCDiver<=T1 then GetU(7, B=10,True);
          if ADCDiver>T1+T2 then
          Begin
            ADCMustGo:=False;

            if B=8 then AD_RESULT^:=round(U) shl 8 or AD_COMMAND^ and 7
            Else
              AD_RESULT^:=round(U) shl 6 or AD_COMMAND^ and 7;
            IntSignals:=IntSignals or Int_11;
          End;
         End;
        End;
      MF_MC:
        Begin
         if AD_COMMAND^ and $40<>0 then
         begin
           if AD($F,$20) then IntSignals:=IntSignals or int_15
         End
         Else
         if ADCMustGo then
         begin
          AD_RESULT^:=AD_RESULT^ or $20;
          T1:=(4*(AD_Time^ shr 5)+1) shl 1;
          if AD_Command^ and $10<>0 then B:=8 Else B:=10;
          T2:=(B*(AD_Time^ and $1F+1)) shl 1+3;

          if ADCDiver<=T1 then GetU($F, B=10,True);
          if ADCDiver>T1+T2 then
          Begin
            ADCMustGo:=False;

            if B=8 then AD_RESULT^:=round(U) shl 8 or AD_COMMAND^ and $F
            Else
              AD_RESULT^:=round(U) shl 6 or AD_COMMAND^ and $F;
            IntSignals:=IntSignals or Int_15;
          End;
         End;
        End;
    End;
    inc(ADCDiver, circles);
End;

Procedure TSimulator.EPA;
Var
  Prt1,Prt6 : Byte;
  i       : Byte;
  Fcr     : Integer;
  OVRTMRx : Array[1..2] Of Boolean;
  ED, EPAY: Boolean;
  W       : Word;
  EPAInt  : Word;
  OVRINT  : Word;
  COMPCHx : Byte;

  Ints    : Word;
  Ints1   : Byte;

Procedure PSx(x:Byte; ExtDir, Sq:Boolean);
Var
  p  : Byte;
  Tx : Boolean;
Label 1;
Begin
  if Sq then goto 1;
  if TxControl[x]^ and $80=0 then Exit;
  p:=TxControl[x]^ and 7;
  if p>6 then p:=6;
  p:=1 shl p;

  inc(PSxDiver[x]);

  if (PSxDiver[x]>0) then
  begin
    1:
    Dec(PSxDiver[x],p);

    if TxControl[x]^ and $10=0 then
      ExtDir:=TxControl[x]^ and $40<>0;

    if ExtDir then
    Begin
      inc(Timerx[x]^);
      Tx:=Timerx[x]^=$FFFF;
    End
    Else
    Begin
      dec(Timerx[x]^);
      Tx:=Timerx[x]^=0;
    End;
    if Tx then
    Begin
      OVRTMRx[x]:=True;
      if (x=1) and (MCSFunc and MF_MC<>0) and (TxControl[x]^ and 7=1) then
        Timerx[1]^:=T1RELOAD^;
    end;
    if Sq then Exit;
  End;
End;

Begin
  if (MCSFunc and MF_Mask<MF_KR) and (MCSFunc and MF_Mask<>MF_MC)  then Exit;
  { TCM }
  Prt1:=PortsLegs[1] and Px_MODE[1]^;
  Prt6:=PortsLegs[6] and Px_MODE[6]^;

  inc(Fcr4,Circles);
  Fcr:=Fcr4;
  COMPCHx:=0;

  OVRTMRx[1]:=False;
  OVRTMRx[2]:=False;
  Case TxControl[1]^ and $38 Of
     $0,$10:
       While Fcr>0 do
       begin
          Dec(Fcr,4);
          PSx(1,Prt6 and 8<>0, False);
       end;
     $8,$18:if (Prt6 and 4=4) and not TxTrigger[1] then PSx(1, Prt6 and 8<>0, False);
     $38:
      Begin
        if (Prt6 and $C=$0) and TxTrigger[3] or
           (Prt6 and $C=$C) and not TxTrigger[3] or
           (Prt6 and $C=$4) and not TxTrigger[1] or
           (Prt6 and $C=$8) and TxTrigger[1] then
          PSx(1, True, True)
        Else
        if (Prt6 and $C=$8) and not TxTrigger[3] or
           (Prt6 and $C=$4) and TxTrigger[3] or
           (Prt6 and $C=$0) and TxTrigger[1] or
           (Prt6 and $C=$C) and not TxTrigger[1] then
          PSx(1, False, True);
      End;
  End;
  TxTrigger[1]:=Prt6 and 4<>0;
  TxTrigger[3]:=Prt6 and 8<>0;

  Case TxControl[2]^ and $38 Of
     $0,$10:
       While Fcr4>0 do
       begin
          Dec(Fcr4,4);
          PSx(2,Prt1 and 4<>0, False);
       end;
     $8,$18:begin
          if (Prt1 and 1=1) and not TxTrigger[2] then PSx(2, Prt1 and 4<>0, False);
          Fcr4:=0;
        end;
     $38:
      Begin
        Begin
        if (Prt1 and $5=$0) and TxTrigger[4] or
           (Prt1 and $5=$5) and not TxTrigger[4] or
           (Prt1 and $5=$1) and not TxTrigger[2] or
           (Prt1 and $5=$4) and TxTrigger[2] then
          PSx(1, True, True)
        Else
        if (Prt1 and $5=$4) and not TxTrigger[4] or
           (Prt1 and $5=$1) and TxTrigger[4] or
           (Prt1 and $5=$0) and TxTrigger[2] or
           (Prt1 and $5=$5) and not TxTrigger[2] then
          PSx(2, False, True);
      End;
        Fcr4:=0;
      End
      Else
        Fcr4:=0;
  End;
  TxTrigger[2]:=Prt1 and 1<>0;
  TxTrigger[4]:=Prt1 and 4<>0;

  { CMM }
  EPAInt:=0;
  OVRInt:=0;

    for i:=0 to 9 do
    Begin
      if EPAx_CON[i]^ and $40=0 then { ђҐ¦Ё¬ ЇpЁҐ¬  }
      Begin
        if i<8 then
          EPAY:=Prt1 shr i and 1<>0
        Else
          EPAY:=Prt6 shr (i-8) and 1<>0;
        ED:=False;
        if (EPAx_CON[i]^ and $10<>0) and EPAY and not EPATrigger[i] then ED:=True;
        if (EPAx_CON[i]^ and $20<>0) and not EPAY and EPATrigger[i] then ED:=True;
        EPATrigger[i]:=EPAY;
        if ED then
        Begin
          if EPAx_CON[i]^ and $80=0 then
            W:=TIMERx[1]^
          Else
            W:=TIMERx[2]^;

          Case EPAHold[i] of
            0:Begin
                EPAx_TIME[i]^:=W;
                EPAHold[i]:=1;
                EPAInt:=EPAInt or (1 shl i);
              End;
            1:Begin
                BuffReg[i]:=W;
                EPAHold[i]:=2;
              End;
            2:Begin
                OVRInt:=OVRInt or (1 shl i);
                if EPAx_CON[i]^ and 1<>0 then BuffReg[i]:=W;
              End;
          end;
          if EPAx_CON[i]^ and 2<>0 then
          Begin
            if EPAx_CON[i]^ and $80=0 then
              TIMERx[2]^:=0
            Else
              TIMERx[2]^:=0;
          End;
          if EPAx_CON[i]^ and 4<>0 then
          Begin
            ADCMustGo:=True;
            ADCDiver:=0;
          End;
        End;
      End
      Else
      begin { ђҐ¦Ё¬ ўл¤ зЁ }
        if EPAx_CON[i]^ and $80=0 then
          W:=Timerx[1]^
        Else
          W:=Timerx[2]^;
        if (EPAx_Time[i]^=W) and (EPAHold[i]=0) then
        Begin
          if i<8 then
            ED:=Prt1 shr i and 1<>0
          Else
            ED:=Prt6 shr (i-8) and 1<>0;
          EPAInt:=EPAInt or (1 shl i);
          Case EPAx_CON[i]^ and $30 Of
            $20:ED:=True;
            $10:ED:=False;
            $30:ED:=not ED;
          End;
          if i<8 then
            Prt1:=Prt1 and not (1 shl i) or (ord(ED) shl i)
          Else
            Prt6:=Prt6 and not (1 shl (i-8)) or (ord(ED) shl (i-8));

          Case EPAx_CON[i]^ and 3 Of
            1:if EPAx_CON[i]^ and $80=0 then
                Timerx[1]^:=0
              Else
                Timerx[2]^:=0;
            3:if EPAx_CON[i]^ and $80<>0 then
                Timerx[1]^:=0
              Else
                Timerx[2]^:=0;
          End;
          if EPAx_CON[i]^ and 4<>0 then
          Begin
            ADCMustGo:=True;
            ADCDiver:=0;
          End;
          if EPAx_CON[i]^ and 8=0 then EPAHold[i]:=1;
        end;
      end;
    End;

    { CM }
    for i:=0 to 1 do
    Begin
      if COMPx_CON[i]^ and $40=0 then { ђҐ¦Ё¬ ЇpЁҐ¬  }
      Begin
        EPAY:=Prt6 shr 1 and 1<>0;
        ED:=False;
        if (COMPx_CON[i]^ and $10<>0) and EPAY and not COMPTrigger[i] then ED:=True;
        if (COMPx_CON[i]^ and $20<>0) and not EPAY and COMPTrigger[i] then ED:=True;
        COMPTrigger[i]:=EPAY;
        if ED then
        Begin
          if COMPx_CON[i]^ and $80=0 then
            W:=TIMERx[1]^
          Else
            W:=TIMERx[2]^;

          Case CompHold[i] of
            0:Begin
                COMPx_TIME[i]^:=W;
                COMPHold[i]:=1;
                COMPCHx:=COMPCHx or (1 shl i);
              End;
            1:Begin
                COMPBuff[i]:=W;
                COMPHold[i]:=2;
              End;
            2:Begin
                if COMPx_CON[i]^ and 1<>0 then COMPBuff[i]:=W;
              End;
          end;
          if COMPx_CON[i]^ and 2<>0 then
          Begin
            if COMPx_CON[i]^ and $80=0 then
              TIMERx[2]^:=0
            Else
              TIMERx[2]^:=0;
          End;
          if COMPx_CON[i]^ and 4<>0 then
          Begin
            ADCMustGo:=True;
            ADCDiver:=0;
          End;
        End;
      End
      Else
      begin { ђҐ¦Ё¬ ўл¤ зЁ }
        if COMPx_CON[i]^ and $80=0 then
          W:=Timerx[1]^
        Else
          W:=Timerx[2]^;
        if COMPx_Time[i]^=W then
        Begin
          ED:=Prt6 shr i and 1<>0;
          COMPCHx:=COMPCHx or (1 shl i);
          Case COMPx_CON[i]^ and $30 Of
            $20:ED:=True;
            $10:ED:=False;
            $30:ED:=not ED;
          End;
          Prt6:=Prt6 and not (1 shl i) or (ord(ED) shl i);

          Case COMPx_CON[i]^ and 3 Of
            1:if COMPx_CON[i]^ and $80=0 then
                Timerx[1]^:=0
              Else
                Timerx[2]^:=0;
            3:if COMPx_CON[i]^ and $80<>0 then
                Timerx[1]^:=0
              Else
                Timerx[2]^:=0;
          End;
          if COMPx_CON[i]^ and 4<>0 then
          Begin
            ADCMustGo:=True;
            ADCDiver:=0;
          End;
          if COMPx_CON[i]^ and 8=0 then COMPHold[i]:=1;
        end;
      end;
    End;

    if EPAInt and 1<>0
Соседние файлы в папке SIM