QuakeGod
2024-08-08 1fb934cda3067a81f82a7add0fa5b39f5ebf3094
ComLib/Src/PLCfunctions.c
@@ -10,6 +10,7 @@
#include "stm32f0xx_hal.h"
#include <core_cmInstr.h>
#if (ENABLE_PLC)
extern __IO uint32_t uwTick;
//unsigned short WDFs[TOTAL_WDFS];
@@ -36,23 +37,23 @@
int InitTimer(int nIndex, int nType)
{
   if (nIndex >= TOTALTIMERS) return -1;
   KMem.Timers[nIndex].StatByte = 0x0010 | nType;
   PLCMem.Timers[nIndex].StatByte = 0x0010 | nType;
//   Timers[nIndex].nType = 0;
   KMem.SV[nIndex] = 0;
   KMem.EV[nIndex] = 0;
   KMem.Timers[nIndex].LastActTime = GetTick();
   PLCMem.SV[nIndex] = 0;
   PLCMem.EV[nIndex] = 0;
   PLCMem.Timers[nIndex].LastActTime = GetTick();
   return 0;
}
int RunTimer(int nIndex , int SV)
{
   if (nIndex >= TOTALTIMERS) return -1;   
   if (!KMem.Timers[nIndex].bSet)
   if (!PLCMem.Timers[nIndex].bSet)
   {
      KMem.SV[nIndex] = SV;
      KMem.EV[nIndex]= 0;
      KMem.Timers[nIndex].LastActTime = GetTick();
      KMem.Timers[nIndex].bSet = 1;
      PLCMem.SV[nIndex] = SV;
      PLCMem.EV[nIndex]= 0;
      PLCMem.Timers[nIndex].LastActTime = GetTick();
      PLCMem.Timers[nIndex].bSet = 1;
   }
   return 0;
}
@@ -60,20 +61,20 @@
int StopTimer(int nIndex)
{
   if (nIndex >= TOTALTIMERS) return -1;   
   if (KMem.Timers[nIndex].bSet)
   if (PLCMem.Timers[nIndex].bSet)
   {
      KMem.EV[nIndex] = 0;
      KMem.Timers[nIndex].LastActTime = GetTick();
      KMem.Timers[nIndex].bSet = 0;
      PLCMem.EV[nIndex] = 0;
      PLCMem.Timers[nIndex].LastActTime = GetTick();
      PLCMem.Timers[nIndex].bSet = 0;
   }
   return 0;
}
int ResetTimer(int nIndex)
{
   if (nIndex >= TOTALTIMERS) return -1;
   KMem.EV[nIndex] = 0;
   KMem.Timers[nIndex].bTon = 0;
   KMem.Timers[nIndex].LastActTime=GetTick();
   PLCMem.EV[nIndex] = 0;
   PLCMem.Timers[nIndex].bTon = 0;
   PLCMem.Timers[nIndex].LastActTime=GetTick();
   return 0;
}
@@ -82,60 +83,60 @@
   if (nIndex >= TOTALTIMERS) return -1;   
   if (bSet) {RunTimer(nIndex, SV);}
   else {StopTimer(nIndex);}
   return KMem.Timers[nIndex].bTon;
   return PLCMem.Timers[nIndex].bTon;
}
int ProcessTimer(int nIndex)
{
   if (nIndex >= TOTALTIMERS) return -1;
   if (!KMem.Timers[nIndex].nInited) return 0;
   if (KMem.Timers[nIndex].bSet)      // bSet =1;
   if (!PLCMem.Timers[nIndex].nInited) return 0;
   if (PLCMem.Timers[nIndex].bSet)      // bSet =1;
   {
      if (!KMem.Timers[nIndex].bTon)
      if (!PLCMem.Timers[nIndex].bTon)
      {
         int TimeDiff = GetTick() - KMem.Timers[nIndex].LastActTime;
         int nScale = TICK_OF_MS;
         if (KMem.Timers[nIndex].nScale == 0)
         if (PLCMem.Timers[nIndex].nScale == 0)
         {nScale = TICK_OF_MS;
         }else if (KMem.Timers[nIndex].nScale == 1)
         }else if (PLCMem.Timers[nIndex].nScale == 1)
         {nScale = TICK_OF_RS;
         }else if (KMem.Timers[nIndex].nScale == 2)
         }else if (PLCMem.Timers[nIndex].nScale == 2)
         {nScale = TICK_OF_XS;
         }else if (KMem.Timers[nIndex].nScale == 3)
         }else if (PLCMem.Timers[nIndex].nScale == 3)
         {nScale = TICK_OF_YS;
         }else {}
         
         int TimeDiff = GetTick() - PLCMem.Timers[nIndex].LastActTime;
         if (TimeDiff < 0) { TimeDiff = nScale;}
         if (TimeDiff >= nScale)
         {
            int TimeDiffmS = TimeDiff / nScale;
            unsigned short NextEV = KMem.EV[nIndex] + TimeDiffmS;
            KMem.Timers[nIndex].LastActTime += TimeDiffmS*nScale;
            unsigned short NextEV = PLCMem.EV[nIndex] + TimeDiffmS;
            PLCMem.Timers[nIndex].LastActTime += TimeDiffmS*nScale;
            
            if (NextEV >= KMem.SV[nIndex])
            if (NextEV >= PLCMem.SV[nIndex])
            {
               NextEV = KMem.SV[nIndex];
               KMem.Timers[nIndex].bTon =1;
               NextEV = PLCMem.SV[nIndex];
               PLCMem.Timers[nIndex].bTon =1;
            }
            KMem.EV[nIndex] = NextEV;
            PLCMem.EV[nIndex] = NextEV;
         }
      }
   }else       //bSet=0;
   {
      if(KMem.Timers[nIndex].bTon)
      if(PLCMem.Timers[nIndex].bTon)
      {
         KMem.Timers[nIndex].bTon =   0;
         PLCMem.Timers[nIndex].bTon =   0;
      }
   }
   SetCoilValue(KLCoilTypeT, nIndex, KMem.Timers[nIndex].bTon);
   return KMem.Timers[nIndex].bTon;
   SetCoilValue(KLCoilTypeT, nIndex, PLCMem.Timers[nIndex].bTon);
   return PLCMem.Timers[nIndex].bTon;
}
int IsTimerOn(int nIndex)
{
   if (nIndex >= TOTALTIMERS) return 0;
   ProcessTimer(nIndex);
   return KMem.Timers[nIndex].bTon;
   return PLCMem.Timers[nIndex].bTon;
}
@@ -143,14 +144,14 @@
{
   if (nIndex >= TOTALTIMERS) return 0;
//   ProcessTimer(nIndex);   
   return KMem.SV[nIndex];
   return PLCMem.SV[nIndex];
//   return 0;   
}
int GetTimerEV(int nIndex)
{
   if (nIndex >= TOTALTIMERS) return 0;
//   ProcessTimer(nIndex);   
   return KMem.EV[nIndex];
   return PLCMem.EV[nIndex];
//   return 0;
}
@@ -158,186 +159,22 @@
{
   for (int i=TOTAL_CurVAL -1 ;i>0;i--)
   {
      KMem.CurVALs[i]=KMem.CurVALs[i-1];
      PLCMem.CurVALs[i]=PLCMem.CurVALs[i-1];
   }
   KMem.CurVALs[0]=KMem.CurVAL;
   return KMem.CurVAL;
   PLCMem.CurVALs[0]=PLCMem.CurVAL;
   return PLCMem.CurVAL;
}
int PopOutVal(void)
{
   unsigned char theVAL=KMem.CurVALs[0];
   unsigned char theVAL=PLCMem.CurVALs[0];
   for (int i=0;i<TOTAL_CurVAL-1;i++)
   {
      KMem.CurVALs[i]=KMem.CurVALs[i+1];
      PLCMem.CurVALs[i]=PLCMem.CurVALs[i+1];
   }
   return theVAL;
}
stBinProg1 const  prog1[]= //__attribute__((at(0X8008000)))
{
   {OP_ST,KLCoilTypeSR,13},
   {OP_MV,0,50},   {KLDataTypeDEC,KLDataTypeDT,1},
   {OP_MV,0,20},   {KLDataTypeDEC,KLDataTypeDT,2},
   {OP_MV,0,30},   {KLDataTypeDEC,KLDataTypeDT,3},
   {OP_MV,0,40},   {KLDataTypeDEC,KLDataTypeDT,4},
   {OP_SET,KLCoilTypeR,0},
//   {OP_SET,KLCoilTypeY,0},
   {OP_ST,KLCoilTypeR,0},
      {OP_TMX,1,1},   {KLDataTypeDT,0,0},
      {OP_DF},
      {OP_SET,KLCoilTypeR,10},
   {OP_ST,KLCoilTypeX,0},
   {OP_DF},
   {OP_SET,KLCoilTypeR,10},
   {OP_ST,KLCoilTypeX,1},
   {OP_DF},
   {OP_RESET,KLCoilTypeR,10},
/*
   {OP_ST,KLCoilTypeR,10},
   {OP_AN,KLCoilTypeR,51},
   {OP_AN,KLCoilTypeR,52},
   {OP_AN,KLCoilTypeR,53},
   {OP_ADD3,0,21},      {KLDataTypeDT,KLDataTypeDT,31},      {0,KLDataTypeDT,32},
   {OP_ST,KLCoilTypeR,10},
   {OP_AN,KLCoilTypeR,54},
   {OP_AN,KLCoilTypeR,55},
   {OP_AN,KLCoilTypeR,56},
   {OP_ADD3,0,23},      {KLDataTypeDT,KLDataTypeDT,33},      {0,KLDataTypeDT,34},
*/
   {OP_ST,KLCoilTypeSR,1},
   {OP_PSHS},
   {OP_AN,KLCoilTypeR,51},
   {OP_OUT,KLCoilTypeY,1},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,52},
   {OP_OUT,KLCoilTypeY,2},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,53},
   {OP_OUT,KLCoilTypeY,3},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,54},
   {OP_OUT,KLCoilTypeY,4},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,55},
   {OP_OUT,KLCoilTypeY,5},
   {OP_POPS},
   {OP_AN,KLCoilTypeR,56},
   {OP_OUT,KLCoilTypeY,6},
   {OP_ST,KLCoilTypeR,10},
   {OP_DF},
   {OP_PSHS},
   {OP_MV,0,150},   {KLDataTypeDEC,KLDataTypeDT,11},
   {OP_MV,0,30},   {KLDataTypeDEC,KLDataTypeDT,12},
   {OP_RDS},
   {OP_MV,0,150},   {KLDataTypeDEC,KLDataTypeDT,13},
   {OP_MV,0,30},   {KLDataTypeDEC,KLDataTypeDT,14},
   {OP_POPS},
   {OP_AN_,KLCoilTypeR,11},
   {OP_AN_,KLCoilTypeR,12},
   {OP_AN_,KLCoilTypeR,13},
   {OP_AN_,KLCoilTypeR,14},
   {OP_SET,KLCoilTypeR,14},
   {OP_ST,KLCoilTypeR,10},
   {OP_PSHS},
   {OP_AN,KLCoilTypeR,11},
   {OP_DF},
   {OP_SET,KLCoilTypeR,51},
   {OP_RESET,KLCoilTypeR,52},
   {OP_RESET,KLCoilTypeR,53},
   {OP_RESET,KLCoilTypeR,54},
   {OP_RESET,KLCoilTypeR,55},
   {OP_SET,KLCoilTypeR,56},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,11},
      {OP_PSHS},
      {OP_TMX,11,11},   {KLDataTypeDT,0,0},
         {OP_RESET,KLCoilTypeR,11},
         {OP_SET,KLCoilTypeR,12},
      {OP_POPS},
         {OP_SUB3,0,11},      {KLDataTypeSV,KLDataTypeEV,11},      {0,KLDataTypeDT,21},
         {OP_AN_LE,0,21},{KLDataTypeDT,KLDataTypeDEC,30},
         {OP_PSHS},
            {OP_DIV,0,21},      {KLDataTypeDT,KLDataTypeDEC,10},      {0,KLDataTypeDT,31},
         {OP_RDS},
            {OP_AN_GE,0,32},{KLDataTypeDT,KLDataTypeDEC,5},
            {OP_SET,KLCoilTypeR,51},
         {OP_POPS},
            {OP_AN_LT,0,32},{KLDataTypeDT,KLDataTypeDEC,5},
            {OP_RESET,KLCoilTypeR,51},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,12},
   {OP_DF},
   {OP_RESET,KLCoilTypeR,51},
   {OP_SET,KLCoilTypeR,52},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,12},
      {OP_TMX,12,12},   {KLDataTypeDT,0,0},
         {OP_RESET,KLCoilTypeR,12},
         {OP_SET,KLCoilTypeR,13},
   {OP_POPS},
   {OP_AN,KLCoilTypeR,12},
   {OP_OUT,KLCoilTypeR,52},
   {OP_ST,KLCoilTypeR,10},
   {OP_PSHS},
   {OP_AN,KLCoilTypeR,13},
   {OP_DF},
   {OP_RESET,KLCoilTypeR,52},
   {OP_SET,KLCoilTypeR,53},
   {OP_SET,KLCoilTypeR,54},
   {OP_RESET,KLCoilTypeR,56},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,13},
      {OP_TMX,13,13},   {KLDataTypeDT,0,0},
         {OP_RESET,KLCoilTypeR,13},
         {OP_SET,KLCoilTypeR,14},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,13},
         {OP_SUB3,0,13},      {KLDataTypeSV,KLDataTypeEV,13},      {0,KLDataTypeDT,23},
         {OP_AN_LE,0,23},{KLDataTypeDT,KLDataTypeDEC,30},
         {OP_PSHS},
            {OP_DIV,0,23},      {KLDataTypeDT,KLDataTypeDEC,10},      {0,KLDataTypeDT,33},
         {OP_RDS},
            {OP_AN_GE,0,34},{KLDataTypeDT,KLDataTypeDEC,5},
            {OP_SET,KLCoilTypeR,54},
         {OP_POPS},
            {OP_AN_LT,0,34},{KLDataTypeDT,KLDataTypeDEC,5},
            {OP_RESET,KLCoilTypeR,54},
   {OP_RDS},
   {OP_AN,KLCoilTypeR,14},
   {OP_DF},
   {OP_RESET,KLCoilTypeR,54},
   {OP_SET,KLCoilTypeR,55},
   {OP_POPS},
   {OP_AN,KLCoilTypeR,14},
      {OP_TMX,14,14},   {KLDataTypeDT,0,0},
         {OP_RESET,KLCoilTypeR,14},
         {OP_SET,KLCoilTypeR,11},
};
/*
   {OP_ST,Addr_R,1},
   {OP_PSHS,0,0},
   {OP_AN_,Addr_Y,1},
   {OP_TMR,5,200},
   {OP_SET,Addr_Y,1},
   {OP_POPS,0,0},
   {OP_AN,Addr_Y,1},
   {OP_TMR,6,200},
   {OP_RESET,Addr_Y,1},
*/
int nSizeProg1=sizeof(prog1)/sizeof(stBinProg1);
int InitPLC()
{
@@ -363,7 +200,7 @@
      KMem.DT[i]=0;
   }
   for (int i=0;i<TOTALTIMERS;i++){
      KMem.Timers[i].nInited=0;
      PLCMem.Timers[i].nInited=0;
   }
   
   PLCMem.bPLCRunning=1;
@@ -376,6 +213,7 @@
   PLCMem.bPLCRunning=0;
   for (int i=0;i<KLDataWXCount;i++) KMem.WY[i]=0;
   for (int i=0;i<KLDataWLCount;i++) KMem.WLY[i]=0;
   KMRunStat.WorkMode2=PLCMem.bPLCRunning;
   return 0;
}
@@ -401,39 +239,45 @@
}
int ProcessPLCBinProg(const stBinProg1 * pBinprog, int nStepSize)
int ProcessPLCBinProg(const stBinInstrcn1 * pBinProg, int nProgSteps)
{
   if (!PLCMem.bPLCRunning) return 0;
   
   if (PLCMem.nScanCount == 0) {
      SetCoilValue(KLCoilTypeSR, 13, 1);
      SetCoilValue(KLCoilTypeSR, 0, 0);
      SetCoilValue(KLCoilTypeSR, 1, 1);
      SetCoilValue(KLCoilTypeSR, 10, 1);
      SetCoilValue(KLCoilTypeSR, 11, 0);
      SetCoilValue(KLCoilTypeSR, 13, 1);
   }
   else
   {
      SetCoilValue(KLCoilTypeSR, 13, 0);
      SetCoilValue(KLCoilTypeSR, 0, 0);
      SetCoilValue(KLCoilTypeSR, 1, 1);
      SetCoilValue(KLCoilTypeSR, 10, 1);
      SetCoilValue(KLCoilTypeSR, 11, 0);
      SetCoilValue(KLCoilTypeSR, 13, 0);
   }
   for (int i = 0; i < TOTAL_CurVAL; i++) {
      KMem.CurVALs[i] = 0;
      PLCMem.CurVALs[i] = 0;
   }
   int CurPos = 0;
//   stBinProg1 * pBinProg1;
   stBinProg15 * pBinProg15;
   stBinProg2 * pBinProg2;
   stBinProg3 * pBinProg3;
//   stBinInstrcn1 * pBinInstrcn1;
   stBinInstrcn15 * pBinInstrcn15;
   stBinInstrcn2 * pBinInstrcn2;
   stBinInstrcn3 * pBinInstrcn3;
   int lastScanInputVal = 1;//??????,????????,? ?? ???
   while (CurPos < nStepSize)
   const stBinInstrcn1 * pBinInstrcn = pBinProg;
   while (CurPos < nProgSteps)
   {
      unsigned int nNextPos = 1;
      unsigned int thisOP = pBinprog[CurPos].nOp;
      unsigned int thisOP = pBinInstrcn[CurPos].nOp;
//      unsigned int nParamCount = 0
      unsigned char thisAddrType = pBinprog[CurPos].nParamType;
      unsigned short thisAddr = pBinprog[CurPos].nParamAddr;
      unsigned char thisAddrType = pBinInstrcn[CurPos].nParamType;
      unsigned short thisAddr = pBinInstrcn[CurPos].nParamAddr;
      switch (thisOP)
@@ -443,6 +287,9 @@
      case OP_NOP:
         break;
         //??? ??
      case OP_END:
         nNextPos = nProgSteps;
         break;
      case OP_NOT:
      case OP_ANS:
      case OP_ORS:
@@ -454,28 +301,28 @@
         switch (thisOP)
         {
         case OP_NOT:
            KMem.CurVAL = !KMem.CurVAL;
            PLCMem.CurVAL = !PLCMem.CurVAL;
            break;
         case OP_ANS:
            KMem.CurVAL = PopOutVal() && KMem.CurVAL;
            PLCMem.CurVAL = PopOutVal() && PLCMem.CurVAL;
            break;
         case OP_ORS:
            KMem.CurVAL = PopOutVal() || KMem.CurVAL;
            PLCMem.CurVAL = PopOutVal() || PLCMem.CurVAL;
            break;
         case OP_PSHS:
            PushInVal();
            break;
         case OP_RDS:
            KMem.CurVAL = KMem.CurVALs[0] != 0;
            PLCMem.CurVAL = PLCMem.CurVALs[0] != 0;
            break;
         case OP_POPS:
            KMem.CurVAL = PopOutVal();
            PLCMem.CurVAL = PopOutVal();
            break;
         case OP_DF:
            KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
            PLCMem.CurVAL = PLCMem.CurVAL && !lastScanInputVal;
            break;
         case OP_DF_:
            KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
            PLCMem.CurVAL = !PLCMem.CurVAL && lastScanInputVal;
            break;
         default:
@@ -493,23 +340,23 @@
         {
         case OP_ST:
            PushInVal();
            KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
            PLCMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
            break;
         case OP_ST_:
            PushInVal();
            KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
            PLCMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
            break;
         case OP_AN:
            KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
            PLCMem.CurVAL = PLCMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
            break;
         case OP_AN_:
            KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr));
            PLCMem.CurVAL = PLCMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr));
            break;
         case OP_OR:
            KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr);
            PLCMem.CurVAL = PLCMem.CurVAL || GetCoilValue(thisAddrType, thisAddr);
            break;
         case OP_OR_:
            KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
            PLCMem.CurVAL = PLCMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
            break;
         default:
            break;
@@ -522,13 +369,13 @@
         switch (thisOP)
         {
         case OP_OUT:
            SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
            SetCoilValue(thisAddrType, thisAddr, PLCMem.CurVAL);
            break;
         case OP_SET:
            if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
            if (PLCMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
            break;
         case OP_RESET:
            if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
            if (PLCMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
            break;
         default:
            break;
@@ -553,71 +400,71 @@
      case OP_OR_GT:
      case OP_OR_LE:
      case OP_OR_GE:
         pBinProg2 = (stBinProg2 *)&pBinprog[CurPos];
         thisAddrType = pBinProg2->nParamType1;
         pBinInstrcn2 = (stBinInstrcn2 *)&pBinInstrcn[CurPos];
         thisAddrType = pBinInstrcn2->nParamType1;
         switch (thisOP)
         {
         case OP_ST_EQ:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_ST_NE:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_ST_LT:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_ST_GT:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_ST_LE:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_ST_GE:
            PushInVal();
            KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_EQ:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_NE:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_LT:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_GT:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_LE:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_AN_GE:
            KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_EQ:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_NE:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_LT:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_GT:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_LE:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         case OP_OR_GE:
            KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
            PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2));
            break;
         default:
@@ -630,38 +477,38 @@
      case OP_TMR:
      case OP_TMX:
      case OP_TMY:
         pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
         pBinInstrcn15 = (stBinInstrcn15 *)(&pBinInstrcn[CurPos]);
         {
            unsigned char thisNum= pBinProg15->nOpNum;
            thisAddrType = pBinProg15->nParamType1;
            thisAddr = pBinProg15->nParamAddr1;
            unsigned char thisNum= pBinInstrcn15->nOpNum;
            thisAddrType = pBinInstrcn15->nParamType1;
            thisAddr = pBinInstrcn15->nParamAddr1;
            switch (thisOP)
            {
            case OP_TML:
               if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 0);
               if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 0);
               if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               else StopTimer(thisNum);
               KMem.CurVAL = ProcessTimer(thisNum);
               PLCMem.CurVAL = ProcessTimer(thisNum);
               break;
            case OP_TMR:
               if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 1);
               if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 1);
               if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               else StopTimer(thisNum);
               KMem.CurVAL = ProcessTimer(thisNum);
               PLCMem.CurVAL = ProcessTimer(thisNum);
               break;
            case OP_TMX:
               if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 2);
               if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 2);
               if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               else StopTimer(thisNum);
               KMem.CurVAL = ProcessTimer(thisNum);
               PLCMem.CurVAL = ProcessTimer(thisNum);
               break;
            case OP_TMY:
               if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 3);
               if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 3);
               if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
               else StopTimer(thisNum);
               KMem.CurVAL = ProcessTimer(thisNum);
               PLCMem.CurVAL = ProcessTimer(thisNum);
               break;
            default:
               break;
@@ -673,17 +520,17 @@
         // 1 ??????
      case OP_INC:
      case OP_DEC:
         pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
         thisAddrType = pBinProg15->nParamType1;
         thisAddr = pBinProg15->nParamAddr1;
         pBinInstrcn15 = (stBinInstrcn15 *)(&pBinInstrcn[CurPos]);
         thisAddrType = pBinInstrcn15->nParamType1;
         thisAddr = pBinInstrcn15->nParamAddr1;
         nNextPos = 2;
         switch (thisOP)
         {
         case OP_INC:
            if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
            if (PLCMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
            break;
         case OP_DEC:
            if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
            if (PLCMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
            break;
         default:
@@ -694,24 +541,24 @@
      case OP_MV:
      case OP_ADD2:
      case OP_SUB2:
         pBinProg2 = (stBinProg2 *)(&pBinprog[CurPos]);
         pBinInstrcn2 = (stBinInstrcn2 *)(&pBinInstrcn[CurPos]);
         {
            int nParamType2, nParamAddr2;
            thisAddrType = pBinProg2->nParamType1;
            thisAddr = pBinProg2->nParamAddr1;
            nParamType2 = pBinProg2->nParamType2;
            nParamAddr2 = pBinProg2->nParamAddr2;
            thisAddrType = pBinInstrcn2->nParamType1;
            thisAddr = pBinInstrcn2->nParamAddr1;
            nParamType2 = pBinInstrcn2->nParamType2;
            nParamAddr2 = pBinInstrcn2->nParamAddr2;
            switch (thisOP)
            {
            case OP_MV:
               if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr));
               if (PLCMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr));
               break;
            case OP_ADD2:
               if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
               if (PLCMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
               break;
            case OP_SUB2:
               if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr));
               if (PLCMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr));
               break;
            default:
@@ -726,25 +573,25 @@
      case OP_SUB3:
      case OP_MUL:
      case OP_DIV:
         pBinProg3 = (stBinProg3 *)(&pBinprog[CurPos]);
         pBinInstrcn3 = (stBinInstrcn3 *)(&pBinInstrcn[CurPos]);
         int nParamType2, nParamAddr2;
         int nParamType3, nParamAddr3;
         thisAddrType = pBinProg3->nParamType1;
         thisAddr = pBinProg3->nParamAddr1;
         nParamType2 = pBinProg3->nParamType2;
         nParamAddr2 = pBinProg3->nParamAddr2;
         nParamType3 = pBinProg3->nParamType3;
         nParamAddr3 = pBinProg3->nParamAddr3;
         thisAddrType = pBinInstrcn3->nParamType1;
         thisAddr = pBinInstrcn3->nParamAddr1;
         nParamType2 = pBinInstrcn3->nParamType2;
         nParamAddr2 = pBinInstrcn3->nParamAddr2;
         nParamType3 = pBinInstrcn3->nParamType3;
         nParamAddr3 = pBinInstrcn3->nParamAddr3;
         switch (thisOP)
         {
         case OP_ADD3:
            if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
            if (PLCMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
            break;
         case OP_SUB3:
            if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2));
            if (PLCMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2));
            break;
         case OP_MUL:
            if (KMem.CurVAL) {
            if (PLCMem.CurVAL) {
               short multiplicand = GetVarData(thisAddrType, thisAddr);
               short multiplier = GetVarData(nParamType2, nParamAddr2);
               int product = multiplicand * multiplier;
@@ -753,7 +600,7 @@
            }
            break;
         case OP_DIV:
            if (KMem.CurVAL) {
            if (PLCMem.CurVAL) {
               short dividend = GetVarData(thisAddrType, thisAddr);
               short divisor = GetVarData(nParamType2, nParamAddr2);
               short quotient = dividend / divisor;
@@ -772,13 +619,14 @@
      default:
         break;
      }
      lastScanInputVal =  GetBitValue( PLCMem.ProgTrace[CurPos>>4],CurPos&0xf); //GetBitValue(KMem.WDFs);
      SetBitValue( &PLCMem.ProgTrace[CurPos>>4],CurPos&0xf, KMem.CurVAL);
      lastScanInputVal =  GetBitValue( PLCMem.ProgTrace[CurPos>>4],CurPos&0xf); //GetBitValue(PLCMem.WDFs);
      SetBitValue( &PLCMem.ProgTrace[CurPos>>4],CurPos&0xf, PLCMem.CurVAL);
      
//      lastScanInputVal =  PLCMem.ProgTrace[CurPos]; //GetBitValue(KMem.WDFs);
//      PLCMem.ProgTrace[CurPos] = KMem.CurVAL;
//      lastScanInputVal =  PLCMem.ProgTrace[CurPos]; //GetBitValue(PLCMem.WDFs);
//      PLCMem.ProgTrace[CurPos] = PLCMem.CurVAL;
      CurPos += nNextPos;
   }
   PLCMem.nScanCount++;
   return 0;
   return CurPos;
}
#endif // ENABLE_PLC