QuakeGod
2022-07-22 dd67df95a7303aee3bed65ffa935465f20ee8b32
提交 | 用户 | age
0ed438 1 #include "pch.h"
Q 2 #include "KMachine.h"
3
4 KMachine::KMachine()
5 {
6     StartTime = GetTimemS();
7 }
8 KMachine::~KMachine()
9 {
10
11 }
12
13 double KMachine::GetTimemS()
14 {
15     LARGE_INTEGER perfreq;
16     LARGE_INTEGER percounter1;
17     QueryPerformanceFrequency(&perfreq);
18     QueryPerformanceCounter(&percounter1);
19
20     double time1 = (double)percounter1.QuadPart / perfreq.QuadPart;
21     return (time1 * 1000);
22 };
23
24 int KMachine::GetTick100uS()
25 {
26     int thistime = int((GetTimemS() - StartTime) * 10);
27     return thistime;
28 }
29
30 int KMachine::Init()
31 {
32     return 0;
33 }
34
35 int KMachine::Download(stBinProg1 * pBinrog, int nBinSteps)
36 {
37     for (int i = 0; i < nBinSteps; i++)
38     {
39         BinProgs[i] = pBinrog[i];
40     }
41     nBinProgSteps = nBinSteps;
42     return 0;
43 }
44
45 int KMachine::ProcPLC()
46 {
47     ProcessPLCBinProg(BinProgs, nBinProgSteps);
48     return 0;
49 }
50
51 int KMachine::StartPLC()
52 {
53     for (int i = 0; i < KLDataWXCount; i++) {
54         KMem.WX[i] = 0;
55     }
56     for (int i = 0; i < KLDataWYCount; i++) {
57         KMem.WY[i] = 0;
58     }
59     for (int i = 0; i < KLDataWRCount; i++) {
60         KMem.WR[i] = 0;
61     }
62     for (int i = 0; i < KLDataDTCount; i++) {
63         KMem.DT[i] = 0;
64     }
65     for (int i = 0; i < TOTALTIMERS; i++) {
66         KMem.Timers[i] = { 0 };
67     }
68     nScanCount = 0;
69     m_bPlcRunning = 1;
70
71     return 0;
72 }
73
74 int KMachine::StopPLC()
75 {
76     m_bPlcRunning = 0;
77     return 0;
78 }
79
80
81
82
83 const unsigned short bitMasks[16] =
84 {
85     0x1 << 0,    0x1 << 1,    0x1 << 2,    0x1 << 3,    0x1 << 4,    0x1 << 5,    0x1 << 6,    0x1 << 7,
86     0x1 << 8,    0x1 << 9,    0x1 << 10,    0x1 << 11,    0x1 << 12,    0x1 << 13,    0x1 << 14,    0x1 << 15,
87 };
88
89 inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr)
90 {
91     (*pW) |= bitMasks[bitAddr & 0xf];
92 }
93
94 inline void ResetBit(unsigned short * pW, unsigned char bitAddr)
95 {
96     (*pW) &= ~bitMasks[bitAddr & 0xf];
97 }
98
99 static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value)
100 {
101     if (Value) { SetAddrBit(pW, bitAddr); }
102     else { ResetBit(pW, bitAddr); }
103 }
104
105 static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr)
106 {
107     if (W&bitMasks[bitAddr & 0xf]) return 1;
108     else return 0;
109 }
110
111 int KMachine::GetCoilValue(int nCoilType, int nCoilAddr)
112 {
113     // TODO: 在此处添加实现代码.
114
115     int nWordAddr = nCoilAddr >> 4;
116     int nBitAddr = nCoilAddr & 0x0F;
117
118     switch (nCoilType)
119     {
120     case KLCoilTypeX:
121         if (nCoilAddr >= KLCoilXCount) return 0;
122         return GetBitValue(KMem.WX[nWordAddr], nBitAddr);
123         break;
124     case KLCoilTypeY:
125         if (nCoilAddr >= KLCoilYCount) return 0;
126         return GetBitValue(KMem.WY[nWordAddr], nBitAddr);
127         break;
128     case KLCoilTypeR:
129         if (nCoilAddr >= KLCoilRCount) return 0;
130         return GetBitValue(KMem.WR[nWordAddr], nBitAddr);
131         break;
132     case KLCoilTypeLX:
133         if (nCoilAddr >= KLCoilLXCount) return 0;
134         return GetBitValue(KMem.WLX[nWordAddr], nBitAddr);
135         break;
136     case KLCoilTypeLY:
137         if (nCoilAddr >= KLCoilLYCount) return 0;
138         return GetBitValue(KMem.WLY[nWordAddr], nBitAddr);
139         break;
140     case KLCoilTypeT:
141         if (nCoilAddr >= KLCoilTCount) return 0;
142         return GetBitValue(KMem.WT[nWordAddr], nBitAddr);
143         break;
144     case KLCoilTypeC:
145         if (nCoilAddr >= KLCoilCCount) return 0;
146         return GetBitValue(KMem.WC[nWordAddr], nBitAddr);
147         break;
148     case KLCoilTypeLR:
149         if (nCoilAddr >= KLCoilLRCount) return 0;
150         return GetBitValue(KMem.WLR[nWordAddr], nBitAddr);
151         break;
152     case KLCoilTypeSR:
153         if (nCoilAddr >= KLCoilSRCount) return 0;
154         return GetBitValue(KMem.WSR[nWordAddr], nBitAddr);
155         break;
156     }
157     return 0;
158 }
159
160
161 int KMachine::SetCoilValue(int nCoilType, int nCoilAddr, int nCoilValue)
162 {
163     // TODO: 在此处添加实现代码.
164
165     int nWordAddr = nCoilAddr >> 4;
166     int nBitAddr = nCoilAddr & 0x0F;
167
168     switch (nCoilType)
169     {
170     case KLCoilTypeX:
171         if (nCoilAddr >= KLCoilXCount) return 0;
172         SetBitValue(&KMem.WX[nWordAddr], nBitAddr, nCoilValue);
173         break;
174     case KLCoilTypeY:
175         if (nCoilAddr >= KLCoilYCount) return 0;
176         SetBitValue(&KMem.WY[nWordAddr], nBitAddr, nCoilValue);
177         break;
178     case KLCoilTypeR:
179         if (nCoilAddr >= KLCoilRCount) return 0;
180         SetBitValue(&KMem.WR[nWordAddr], nBitAddr, nCoilValue);
181         break;
182     case KLCoilTypeLX:
183         if (nCoilAddr >= KLCoilLXCount) return 0;
184         SetBitValue(&KMem.WLX[nWordAddr], nBitAddr, nCoilValue);
185         break;
186     case KLCoilTypeLY:
187         if (nCoilAddr >= KLCoilLYCount) return 0;
188         SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue);
189         break;
190     case KLCoilTypeT:
191         if (nCoilAddr >= KLCoilTCount) return 0;
192         SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue);
193         break;
194     case KLCoilTypeC:
195         if (nCoilAddr >= KLCoilCCount) return 0;
196         SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue);
197         break;
198     case KLCoilTypeLR:
199         if (nCoilAddr >= KLCoilLRCount) return 0;
200         SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue);
201         break;
202     case KLCoilTypeSR:
203         if (nCoilAddr >= KLCoilSRCount) return 0;
204         SetBitValue(&KMem.WSR[nWordAddr], nBitAddr, nCoilValue);
205
206         break;
207     }
208     return 0;
209 }
210
211 int KMachine::GetVarData(int nDataType, int nDataAddr)
212 {
213     // TODO: 在此处添加实现代码.
214
215     switch (nDataType)
216     {
217     case KLDataTypeDEC:
218     case KLDataTypeHEX:
219         return nDataAddr;
220         break;
221     case KLDataTypeWX:
222         if (nDataAddr >= KLDataWXCount) return 0;
223         return KMem.WX[nDataAddr];
224         break;
225     case KLDataTypeWY:
226         if (nDataAddr >= KLDataWYCount) return 0;
227         return KMem.WY[nDataAddr];
228         break;
229     case KLDataTypeWR:
230         if (nDataAddr >= KLDataWRCount) return 0;
231         return KMem.WR[nDataAddr];
232         break;
233     case KLDataTypeWLX:
234         if (nDataAddr >= KLDataWLCount) return 0;
235         return KMem.WLX[nDataAddr];
236         break;
237     case KLDataTypeWLY:
238         if (nDataAddr >= KLDataWLCount) return 0;
239         return KMem.WLY[nDataAddr];
240         break;
241     case KLDataTypeDT:
242         if (nDataAddr >= KLDataDTCount) return 0;
243         return (signed short)KMem.DT[nDataAddr];
244         break;
245     case KLDataTypeSDT:
246         if (nDataAddr >= KLDataSDTCount) return 0;
247         return KMem.SDT[nDataAddr];
248         break;
249     case KLDataTypeWSR:
250         if (nDataAddr >= KLCoilLRCount) return 0;
251         return KMem.WSR[nDataAddr];
252         break;
253     case KLDataTypeSV:
254         if (nDataAddr >= KLDataSVCount) return 0;
255         return KMem.SV[nDataAddr];
256         break;
257     case KLDataTypeEV:
258         if (nDataAddr >= KLDataEVCount) return 0;
259         return KMem.EV[nDataAddr];
260         break;
261     case KLDataTypeLD:
262         if (nDataAddr >= KLDataLDCount) return 0;
263         return KMem.DT[nDataAddr];
264         break;
265     case KLDataSysCfg:
266         if (nDataAddr >= KLCoilSRCount) return 0;
267         return KMem.SDT[nDataAddr];
268         break;
269     case KLDataTypeFlash:
270         if (nDataAddr >= KLCoilSRCount) return 0;
271         return KMem.SDT[nDataAddr];
272         break;
273     case KLDataTypeTest:
274         if (nDataAddr >= KLCoilSRCount) return 0;
275         return KMem.SDT[nDataAddr];
276         break;
277     }
278     return 0;
279 }
280
281
282 int KMachine::SetVarData(int nDataType, int nDataAddr, int nDataValue)
283 {
284     // TODO: 在此处添加实现代码.
285
286     switch (nDataType)
287     {
288         //    case KLDataTypeDEC:
289         //    case KLDataTypeHEX:
290         //        break;
291     case KLDataTypeWX:
292         if (nDataAddr >= KLDataWXCount) return 0;
293         KMem.WX[nDataAddr] = nDataValue;
294         break;
295     case KLDataTypeWY:
296         if (nDataAddr >= KLDataWYCount) return 0;
297         KMem.WY[nDataAddr] = nDataValue;
298         break;
299     case KLDataTypeWR:
300         if (nDataAddr >= KLDataWRCount) return 0;
301         KMem.WR[nDataAddr] = nDataValue;
302         break;
303     case KLDataTypeWLX:
304         if (nDataAddr >= KLDataWLCount) return 0;
305         KMem.WLX[nDataAddr] = nDataValue;
306         break;
307     case KLDataTypeWLY:
308         if (nDataAddr >= KLDataWLCount) return 0;
309         KMem.WLY[nDataAddr] = nDataValue;
310         break;
311     case KLDataTypeDT:
312         if (nDataAddr >= KLDataDTCount) return 0;
313         KMem.DT[nDataAddr] = nDataValue;
314         break;
315     case KLDataTypeSDT:
316         if (nDataAddr >= KLDataSDTCount) return 0;
317         KMem.SDT[nDataAddr] = nDataValue;
318         break;
319     case KLDataTypeWSR:
320         if (nDataAddr >= KLCoilLRCount) return 0;
321         KMem.WSR[nDataAddr] = nDataValue;
322         break;
323     case KLDataTypeSV:
324         if (nDataAddr >= KLDataSVCount) return 0;
325         KMem.SV[nDataAddr] = nDataValue;
326         break;
327     case KLDataTypeEV:
328         if (nDataAddr >= KLDataEVCount) return 0;
329         KMem.EV[nDataAddr] = nDataValue;
330         break;
331     case KLDataTypeLD:
332         if (nDataAddr >= KLDataLDCount) return 0;
333         KMem.DT[nDataAddr] = nDataValue;
334         break;
335     case KLDataSysCfg:
336         if (nDataAddr >= KLCoilSRCount) return 0;
337         KMem.SDT[nDataAddr] = nDataValue;
338         break;
339     case KLDataTypeFlash:
340         if (nDataAddr >= KLCoilSRCount) return 0;
341         KMem.SDT[nDataAddr] = nDataValue;
342         break;
343     case KLDataTypeTest:
344         if (nDataAddr >= KLCoilSRCount) return 0;
345         KMem.SDT[nDataAddr] = nDataValue;
346         break;
347     }
348
349     return 0;
350 }
351
352 int KMachine::InitTimer(int nIndex, int nType)
353 {
354     if (nIndex >= TOTALTIMERS) return -1;
355     KMem.Timers[nIndex].StatByte = 0x0010 | nType;
356     //    Timers[nIndex].nType = 0;
357     KMem.SV[nIndex] = 0;
358     KMem.EV[nIndex] = 0;
359     KMem.Timers[nIndex].LastActTime = GetTick100uS();
360     return 0;
361 }
362 int KMachine::RunTimer(int nIndex, int SV)
363 {
364     if (nIndex >= TOTALTIMERS) return -1;
365     if (!KMem.Timers[nIndex].bSet)
366     {
367         KMem.SV[nIndex] = SV;
368         KMem.EV[nIndex] = 0;
369         KMem.Timers[nIndex].LastActTime = GetTick100uS();
370         KMem.Timers[nIndex].bSet = 1;
371     }
372     return 0;
373 }
374 int KMachine::StopTimer(int nIndex)
375 {
376     if (nIndex >= TOTALTIMERS) return -1;
377     if (KMem.Timers[nIndex].bSet)
378     {
379         KMem.EV[nIndex] = 0;
380         KMem.Timers[nIndex].LastActTime = GetTick100uS();
381         KMem.Timers[nIndex].bSet = 0;
382     }
383     return 0;
384 }
385 int KMachine::ResetTimer(int nIndex)
386 {
387     if (nIndex >= TOTALTIMERS) return -1;
388     KMem.EV[nIndex] = 0;
389     KMem.Timers[nIndex].bTon = 0;
390     KMem.Timers[nIndex].LastActTime = GetTick100uS();
391     return 0;
392 }
393 int KMachine::SetTimerValue(int nIndex, int bSet, int SV)
394 {
395     if (nIndex >= TOTALTIMERS) return -1;
396     if (bSet) { RunTimer(nIndex, SV); }
397     else { StopTimer(nIndex); }
398     return KMem.Timers[nIndex].bTon;
399 }
400 int KMachine::ProcessTimer(int nIndex)
401 {
402     if (nIndex >= TOTALTIMERS) return -1;
403     if (!KMem.Timers[nIndex].nInited) return 0;
404     if (KMem.Timers[nIndex].bSet)        // bSet =1;
405     {
406         if (!KMem.Timers[nIndex].bTon)
407         {
408             int TimeDiff = GetTick100uS() - KMem.Timers[nIndex].LastActTime;
409             int nScale = TICK_OF_MS;
410             if (KMem.Timers[nIndex].nScale == 0)
411             {
412                 nScale = TICK_OF_MS;
413             }
414             else if (KMem.Timers[nIndex].nScale == 1)
415             {
416                 nScale = TICK_OF_RS;
417             }
418             else if (KMem.Timers[nIndex].nScale == 2)
419             {
420                 nScale = TICK_OF_XS;
421             }
422             else if (KMem.Timers[nIndex].nScale == 3)
423             {
424                 nScale = TICK_OF_YS;
425             }
426             else {}
427
428
429             //if (TimeDiff >= nScale)
430             {
431                 int TimeDiffmS = TimeDiff / nScale;
432                 unsigned short NextEV = KMem.EV[nIndex] + TimeDiffmS;
433                 KMem.Timers[nIndex].LastActTime += TimeDiffmS * nScale;
434
435                 if (NextEV >= KMem.SV[nIndex])
436                 {
437                     NextEV = KMem.SV[nIndex];
438                     KMem.Timers[nIndex].bTon = 1;
439                 }
440                 KMem.EV[nIndex] = NextEV;
441             }
442         }
443     }
444     else         //bSet=0;
445     {
446         if (KMem.Timers[nIndex].bTon)
447         {
448             KMem.Timers[nIndex].bTon = 0;
449         }
450         KMem.EV[nIndex] = 0;
451     }
452     SetCoilValue(KLCoilTypeT, nIndex, KMem.Timers[nIndex].bTon);
453     return KMem.Timers[nIndex].bTon;
454 }
455 int KMachine::IsTimerOn(int nIndex)
456 {
457     if (nIndex >= TOTALTIMERS) return 0;
458     ProcessTimer(nIndex);
459     return KMem.Timers[nIndex].bTon;
460 }
461 int KMachine::GetTimerSV(int nIndex)
462 {
463     if (nIndex >= TOTALTIMERS) return 0;
464     //    ProcessTimer(nIndex);    
465     return KMem.SV[nIndex];
466     //    return 0;    
467 }
468 int KMachine::GetTimerEV(int nIndex)
469 {
470     if (nIndex >= TOTALTIMERS) return 0;
471     //    ProcessTimer(nIndex);    
472     return KMem.EV[nIndex];
473     //    return 0;
474
475 }
476
477
478 int KMachine::PushInVal(void)
479 {
480     for (int i = TOTAL_CurVAL - 1; i > 0; i--)
481     {
482         KMem.CurVALs[i] = KMem.CurVALs[i - 1];
483     }
484     KMem.CurVALs[0] = KMem.CurVAL ? '1' : '0';
485     return KMem.CurVAL;
486 }
487
488 int KMachine::PopOutVal(void)
489 {
490     unsigned char theVAL = (KMem.CurVALs[0] == '1');
491     for (int i = 0; i < TOTAL_CurVAL - 1; i++)
492     {
493         KMem.CurVALs[i] = KMem.CurVALs[i + 1];
494     }
495     return theVAL;
496 }
497
498
499 int KMachine::ProcessPLCBinProg(const stBinProg1 * pBinprog, int nSize)
500 {
501     if (nScanCount == 0) {
502         SetCoilValue(KLCoilTypeSR, 13, 1);
503         SetCoilValue(KLCoilTypeSR, 0, 0);
504         SetCoilValue(KLCoilTypeSR, 1, 1);
505     }
506     else
507     {
508         SetCoilValue(KLCoilTypeSR, 13, 0);
509         SetCoilValue(KLCoilTypeSR, 0, 0);
510         SetCoilValue(KLCoilTypeSR, 1, 1);
511     }
512     for (int i = 0; i < TOTAL_CurVAL; i++) {
513         KMem.CurVALs[i] = '0';
514     }
515     int CurPos = 0;
516     //    stBinProg1 * pBinProg1;
517     stBinProg15 * pBinProg15;
518     stBinProg2 * pBinProg2;
519     stBinProg3 * pBinProg3;
520     //        unsigned int AddrType2 ;
521     //        unsigned short Addr2 ;
522
523     //        unsigned int AddrType3 ;
524     //        unsigned short Addr3 ;
525 //    pBinProg15 = (stBinProg15 *)&pBinprog[CurPos];
526 //    pBinProg2 = (stBinProg2 *)&pBinprog[CurPos];
527 //    pBinProg3 = (stBinProg3 *)&pBinprog[CurPos];
528
529     int lastScanInputVal = 1;//上个扫描周期,当前指令输入状态,为 微分 做参考
530
531     while (CurPos < nSize)
532     {
533         unsigned int nNextPos = 1;
534         unsigned int thisOP = pBinprog[CurPos].nOp;
535         //        unsigned int nParamCount = 0
536         unsigned char thisAddrType = pBinprog[CurPos].nParamType;
537         unsigned short thisAddr = pBinprog[CurPos].nParamAddr;
538
539
540         switch (thisOP)
541         {
542         case OP_NONE:
543             break;
544             //        case OP_NOP:
545             break;
546             //无参数 指令
547         case OP_NOT:
548         case OP_ANS:
549         case OP_ORS:
550         case OP_PSHS:
551         case OP_RDS:
552         case OP_POPS:
553         case OP_DF:
554         case OP_DF_:
555             switch (thisOP)
556             {
557             case OP_NOT:
558                 KMem.CurVAL = !KMem.CurVAL;
559                 break;
560             case OP_ANS:
561                 KMem.CurVAL = PopOutVal() && KMem.CurVAL;
562                 break;
563             case OP_ORS:
564                 KMem.CurVAL = PopOutVal() || KMem.CurVAL;
565                 break;
566             case OP_PSHS:
567                 PushInVal();
568                 break;
569             case OP_RDS:
570                 KMem.CurVAL = KMem.CurVALs[0] == '1';
571                 break;
572             case OP_POPS:
573                 KMem.CurVAL = PopOutVal();
574                 break;
575             case OP_DF:
576                 KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
577                 break;
578             case OP_DF_:
579                 KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
580                 break;
581
582             default:
583                 break;
584             }
585             break;
586             // 1参数指令
587         case OP_ST:
588         case OP_ST_:
589         case OP_AN:
590         case OP_AN_:
591         case OP_OR:
592         case OP_OR_:
593             switch (thisOP)
594             {
595             case OP_ST:
596                 PushInVal();
597                 KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
598                 break;
599             case OP_ST_:
600                 PushInVal();
601                 KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
602                 break;
603             case OP_AN:
604                 KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
605                 break;
606             case OP_AN_:
607                 KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr));
608                 break;
609             case OP_OR:
610                 KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr);
611                 break;
612             case OP_OR_:
613                 KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
614                 break;
615             default:
616                 break;
617             }
618             break;
619             // 1 参数 输出
620         case OP_OUT:
621         case OP_SET:
622         case OP_RESET:
623             switch (thisOP)
624             {
625             case OP_OUT:
626                 SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
627                 break;
628             case OP_SET:
629                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
630                 break;
631             case OP_RESET:
632                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
633                 break;
634             default:
635                 break;
636             }
637             break;
638             // 比较指令
639         case OP_ST_EQ:
640         case OP_ST_NE:
641         case OP_ST_LT:
642         case OP_ST_GT:
643         case OP_ST_LE:
644         case OP_ST_GE:
645         case OP_AN_EQ:
646         case OP_AN_NE:
647         case OP_AN_LT:
648         case OP_AN_GT:
649         case OP_AN_LE:
650         case OP_AN_GE:
651         case OP_OR_EQ:
652         case OP_OR_NE:
653         case OP_OR_LT:
654         case OP_OR_GT:
655         case OP_OR_LE:
656         case OP_OR_GE:
657             pBinProg2 = (stBinProg2 *)&pBinprog[CurPos];
658             thisAddrType = pBinProg2->nParamType1;
659
660             switch (thisOP)
661             {
662             case OP_ST_EQ:
663                 PushInVal();
664                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
665                 break;
666             case OP_ST_NE:
667                 PushInVal();
668                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
669                 break;
670             case OP_ST_LT:
671                 PushInVal();
672                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
673                 break;
674             case OP_ST_GT:
675                 PushInVal();
676                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
677                 break;
678             case OP_ST_LE:
679                 PushInVal();
680                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
681                 break;
682             case OP_ST_GE:
683                 PushInVal();
684                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
685                 break;
686             case OP_AN_EQ:
687                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
688                 break;
689             case OP_AN_NE:
690                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
691                 break;
692             case OP_AN_LT:
693                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
694                 break;
695             case OP_AN_GT:
696                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
697                 break;
698             case OP_AN_LE:
699                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
700                 break;
701             case OP_AN_GE:
702                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
703                 break;
704
705             case OP_OR_EQ:
706                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
707                 break;
708             case OP_OR_NE:
709                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
710                 break;
711             case OP_OR_LT:
712                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
713                 break;
714             case OP_OR_GT:
715                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
716                 break;
717             case OP_OR_LE:
718                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
719                 break;
720             case OP_OR_GE:
721                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
722                 break;
723
724             default:
725                 break;
726             }
727             nNextPos = 2;
728             break;
729             // 定时器
730         case OP_TML:
731         case OP_TMR:
732         case OP_TMX:
733         case OP_TMY:
734             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
735             {
736                 unsigned char thisNum = pBinProg15->nOpNum;
737                 thisAddrType = pBinProg15->nParamType1;
738                 thisAddr = pBinProg15->nParamAddr1;
739                 switch (thisOP)
740                 {
741                 case OP_TML:
742                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 0);
743                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
744                     else StopTimer(thisNum);
745                     KMem.CurVAL = ProcessTimer(thisNum);
746
747                     break;
748                 case OP_TMR:
749                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 1);
750                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
751                     else StopTimer(thisNum);
752                     KMem.CurVAL = ProcessTimer(thisNum);
753                     break;
754                 case OP_TMX:
755                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 2);
756                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
757                     else StopTimer(thisNum);
758                     KMem.CurVAL = ProcessTimer(thisNum);
759
760                     break;
761                 case OP_TMY:
762                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 3);
763                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
764                     else StopTimer(thisNum);
765                     KMem.CurVAL = ProcessTimer(thisNum);
766                     break;
767                 default:
768                     break;
769                 }
770
771             }
772             nNextPos = 2;
773             break;
774             // 1 参数高级指令
775         case OP_INC:
776         case OP_DEC:
777             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
778             thisAddrType = pBinProg15->nParamType1;
779             thisAddr = pBinProg15->nParamAddr1;
780             nNextPos = 2;
781             switch (thisOP)
782             {
783             case OP_INC:
784                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
785                 break;
786             case OP_DEC:
787                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
788                 break;
789
790             default:
791                 break;
792             }
793             break;
794             // 2参数高级指令
795         case OP_MV:
796         case OP_ADD2:
797         case OP_SUB2:
798             pBinProg2 = (stBinProg2 *)(&pBinprog[CurPos]);
799             {
800                 int nParamType2, nParamAddr2;
801                 thisAddrType = pBinProg2->nParamType1;
802                 thisAddr = pBinProg2->nParamAddr1;
803                 nParamType2 = pBinProg2->nParamType2;
804                 nParamAddr2 = pBinProg2->nParamAddr2;
805
806                 switch (thisOP)
807                 {
808                 case OP_MV:
809                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr));
810                     break;
811                 case OP_ADD2:
812                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
813                     break;
814                 case OP_SUB2:
815                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr));
816                     break;
817
818                 default:
819                     break;
820                 }
821
822             }
823             nNextPos = 2;
824             break;
825             // 3 参数高级指令
826         case OP_ADD3:
827         case OP_SUB3:
828         case OP_MUL:
829         case OP_DIV:
830             pBinProg3 = (stBinProg3 *)(&pBinprog[CurPos]);
831             int nParamType2, nParamAddr2;
832             int nParamType3, nParamAddr3;
833             thisAddrType = pBinProg3->nParamType1;
834             thisAddr = pBinProg3->nParamAddr1;
835             nParamType2 = pBinProg3->nParamType2;
836             nParamAddr2 = pBinProg3->nParamAddr2;
837             nParamType3 = pBinProg3->nParamType3;
838             nParamAddr3 = pBinProg3->nParamAddr3;
839             switch (thisOP)
840             {
841             case OP_ADD3:
842                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
843                 break;
844             case OP_SUB3:
845                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2));
846                 break;
847             case OP_MUL:
848                 if (KMem.CurVAL) {
849                     short multiplicand = GetVarData(thisAddrType, thisAddr);
850                     short multiplier = GetVarData(nParamType2, nParamAddr2);
851                     int product = multiplicand * multiplier;
852                     SetVarData(nParamType3, nParamAddr3, product);
853                     SetVarData(nParamType3, nParamAddr3 + 1, product >> 16);
854                 }
855                 break;
856             case OP_DIV:
857                 if (KMem.CurVAL) {
858                     short dividend = GetVarData(thisAddrType, thisAddr);
859                     short divisor = GetVarData(nParamType2, nParamAddr2);
860                     short quotient = dividend / divisor;
861                     short remainder = dividend % divisor;
862                     SetVarData(nParamType3, nParamAddr3, quotient);
863                     SetVarData(nParamType3, nParamAddr3 + 1, remainder);
864                 }
865                 break;
866
867             default:
868                 break;
869             }
870             nNextPos = 3;
871             break;
872
873         default:
874             break;
875         }
876
877         lastScanInputVal = ProgTrace[CurPos];
878         ProgTrace[CurPos] = KMem.CurVAL;
879         CurPos += nNextPos;
880     }
881     nScanCount++;
882     return 0;
883 }
884
885 /*
886 int KMachine::ProcessPLCProg(const stProg * prog, int nSize)
887 {
888     if (nScanCount == 0) {
889         SetCoilValue(KLCoilTypeSR, 13, 1);
890         SetCoilValue(KLCoilTypeSR, 0, 0);
891         SetCoilValue(KLCoilTypeSR, 1, 1);
892     }
893     else
894     {
895         SetCoilValue(KLCoilTypeSR, 13, 0);
896         SetCoilValue(KLCoilTypeSR, 0, 0);
897         SetCoilValue(KLCoilTypeSR, 1, 1);
898     }
899     for (int i = 0; i < TOTAL_CurVAL; i++) {
900         KMem.CurVALs[i] = '0';
901     }
902     int lastScanInputVal = 1;//上个扫描周期,当前指令输入状态,为 微分 做参考
903     for (int i = 0; i < nSize; i++)
904     {
905         unsigned int thisOP = prog[i].nOpType1;
906         unsigned int nParamCount = prog[i].nParamCount;
907         unsigned int thisAddrType = prog[i].Params[0].nParamType;
908         unsigned short thisAddr = prog[i].Params[0].nParamAddr;
909
910         unsigned int AddrType2 = prog[i].Params[1].nParamType;
911         unsigned short Addr2 = prog[i].Params[1].nParamAddr;
912
913         unsigned int AddrType3 = prog[i].Params[2].nParamType;
914         unsigned short Addr3 = prog[i].Params[2].nParamAddr;
915
916         switch (thisOP)
917         {
918         case OP_NOP:
919             break;
920         case OP_ST:
921             PushInVal();
922             KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
923             break;
924         case OP_ST_:
925             PushInVal();
926             KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
927             break;
928         case OP_AN:
929             KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
930             break;
931         case OP_AN_:
932             KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr));
933             break;
934         case OP_OR:
935             KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr);
936             break;
937         case OP_OR_:
938             KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
939             break;
940         case OP_NOT:
941             KMem.CurVAL = !KMem.CurVAL;
942             break;
943         case OP_ANS:
944             KMem.CurVAL = PopOutVal() && KMem.CurVAL;
945             break;
946         case OP_ORS:
947             KMem.CurVAL = PopOutVal() || KMem.CurVAL;
948             break;
949         case OP_PSHS:
950             PushInVal();
951             break;
952         case OP_RDS:
953             KMem.CurVAL = KMem.CurVALs[0] == '1';
954             break;
955         case OP_POPS:
956             KMem.CurVAL = PopOutVal();
957             break;
958         case OP_OUT:
959             SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
960             break;
961         case OP_SET:
962             if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
963             break;
964         case OP_RESET:
965             if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
966             break;
967         case OP_DF:
968             KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
969             break;
970         case OP_DF_:
971             KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
972             break;
973         case OP_ST_EQ:
974             PushInVal();
975             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
976             break;
977         case OP_ST_NE:
978             PushInVal();
979             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
980             break;
981         case OP_ST_LT:
982             PushInVal();
983             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
984             break;
985         case OP_ST_GT:
986             PushInVal();
987             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
988             break;
989         case OP_ST_LE:
990             PushInVal();
991             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
992             break;
993         case OP_ST_GE:
994             PushInVal();
995             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
996             break;
997         case OP_AN_EQ:
998             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
999             break;
1000         case OP_AN_NE:
1001             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
1002             break;
1003         case OP_AN_LT:
1004             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
1005             break;
1006         case OP_AN_GT:
1007             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
1008             break;
1009         case OP_AN_LE:
1010             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
1011             break;
1012         case OP_AN_GE:
1013             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
1014             break;
1015
1016         case OP_OR_EQ:
1017             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
1018             break;
1019         case OP_OR_NE:
1020             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
1021             break;
1022         case OP_OR_LT:
1023             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
1024             break;
1025         case OP_OR_GT:
1026             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
1027             break;
1028         case OP_OR_LE:
1029             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
1030             break;
1031         case OP_OR_GE:
1032             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
1033             break;
1034
1035
1036         case OP_TML:
1037             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 0);
1038             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1039             else StopTimer(thisAddr);
1040             KMem.CurVAL = ProcessTimer(thisAddr);
1041
1042             break;
1043         case OP_TMR:
1044             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 1);
1045             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1046             else StopTimer(thisAddr);
1047             KMem.CurVAL = ProcessTimer(thisAddr);
1048             break;
1049         case OP_TMX:
1050             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 2);
1051             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1052             else StopTimer(thisAddr);
1053             KMem.CurVAL = ProcessTimer(thisAddr);
1054
1055             break;
1056         case OP_TMY:
1057             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 3);
1058             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1059             else StopTimer(thisAddr);
1060             KMem.CurVAL = ProcessTimer(thisAddr);
1061             break;
1062         case OP_MV:
1063             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr));
1064             break;
1065         case OP_INC:
1066             if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
1067             break;
1068         case OP_DEC:
1069             if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
1070             break;
1071         case OP_ADD2:
1072             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2));
1073             break;
1074         case OP_SUB2:
1075             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(AddrType2, Addr2) - GetVarData(thisAddrType, thisAddr));
1076             break;
1077         case OP_ADD3:
1078             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2));
1079             break;
1080         case OP_SUB3:
1081             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) - GetVarData(AddrType2, Addr2));
1082             break;
1083         case OP_MUL:
1084             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) * GetVarData(AddrType2, Addr2));
1085             break;
1086         case OP_DIV:
1087             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) / GetVarData(AddrType2, Addr2));
1088             break;
1089
1090             
1091             //    OP_BKMV = 60,
1092             //    OP_COPY = 61,
1093             //    OP_CLR = 62,
1094             
1095
1096         default:
1097             break;
1098         }
1099         lastScanInputVal = ProgTrace[i];
1100         ProgTrace[i] = KMem.CurVAL;
1101     }
1102     nScanCount++;
1103     return 0;
1104 }
1105
1106 */
1107