QuakeGod
2024-12-24 61deef5cdf96cbfdd6ad45be49e80d597c00ca65
提交 | 用户 | age
418cb3 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
61deef 499 int KMachine::ProcessPLCBinProg(const stBinProg1 * pBinprog, int nProgSteps)
418cb3 500 {
Q 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
61deef 531     while (CurPos < nProgSteps)
418cb3 532     {
Q 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             //无参数 指令
61deef 547         case OP_END:
Q 548             nNextPos = nProgSteps;
549             break;
418cb3 550         case OP_NOT:
Q 551         case OP_ANS:
552         case OP_ORS:
553         case OP_PSHS:
554         case OP_RDS:
555         case OP_POPS:
556         case OP_DF:
557         case OP_DF_:
558             switch (thisOP)
559             {
560             case OP_NOT:
561                 KMem.CurVAL = !KMem.CurVAL;
562                 break;
563             case OP_ANS:
564                 KMem.CurVAL = PopOutVal() && KMem.CurVAL;
565                 break;
566             case OP_ORS:
567                 KMem.CurVAL = PopOutVal() || KMem.CurVAL;
568                 break;
569             case OP_PSHS:
570                 PushInVal();
571                 break;
572             case OP_RDS:
573                 KMem.CurVAL = KMem.CurVALs[0] == '1';
574                 break;
575             case OP_POPS:
576                 KMem.CurVAL = PopOutVal();
577                 break;
578             case OP_DF:
579                 KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
580                 break;
581             case OP_DF_:
582                 KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
583                 break;
584
585             default:
586                 break;
587             }
588             break;
589             // 1参数指令
590         case OP_ST:
591         case OP_ST_:
592         case OP_AN:
593         case OP_AN_:
594         case OP_OR:
595         case OP_OR_:
596             switch (thisOP)
597             {
598             case OP_ST:
599                 PushInVal();
600                 KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
601                 break;
602             case OP_ST_:
603                 PushInVal();
604                 KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
605                 break;
606             case OP_AN:
607                 KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
608                 break;
609             case OP_AN_:
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             case OP_OR_:
616                 KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
617                 break;
618             default:
619                 break;
620             }
621             break;
622             // 1 参数 输出
623         case OP_OUT:
624         case OP_SET:
625         case OP_RESET:
626             switch (thisOP)
627             {
628             case OP_OUT:
629                 SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
630                 break;
631             case OP_SET:
632                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
633                 break;
634             case OP_RESET:
635                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
636                 break;
637             default:
638                 break;
639             }
640             break;
641             // 比较指令
642         case OP_ST_EQ:
643         case OP_ST_NE:
644         case OP_ST_LT:
645         case OP_ST_GT:
646         case OP_ST_LE:
647         case OP_ST_GE:
648         case OP_AN_EQ:
649         case OP_AN_NE:
650         case OP_AN_LT:
651         case OP_AN_GT:
652         case OP_AN_LE:
653         case OP_AN_GE:
654         case OP_OR_EQ:
655         case OP_OR_NE:
656         case OP_OR_LT:
657         case OP_OR_GT:
658         case OP_OR_LE:
659         case OP_OR_GE:
660             pBinProg2 = (stBinProg2 *)&pBinprog[CurPos];
661             thisAddrType = pBinProg2->nParamType1;
662
663             switch (thisOP)
664             {
665             case OP_ST_EQ:
666                 PushInVal();
667                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
668                 break;
669             case OP_ST_NE:
670                 PushInVal();
671                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
672                 break;
673             case OP_ST_LT:
674                 PushInVal();
675                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
676                 break;
677             case OP_ST_GT:
678                 PushInVal();
679                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
680                 break;
681             case OP_ST_LE:
682                 PushInVal();
683                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
684                 break;
685             case OP_ST_GE:
686                 PushInVal();
687                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
688                 break;
689             case OP_AN_EQ:
690                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
691                 break;
692             case OP_AN_NE:
693                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
694                 break;
695             case OP_AN_LT:
696                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
697                 break;
698             case OP_AN_GT:
699                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
700                 break;
701             case OP_AN_LE:
702                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
703                 break;
704             case OP_AN_GE:
705                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
706                 break;
707
708             case OP_OR_EQ:
709                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
710                 break;
711             case OP_OR_NE:
712                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
713                 break;
714             case OP_OR_LT:
715                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
716                 break;
717             case OP_OR_GT:
718                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
719                 break;
720             case OP_OR_LE:
721                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
722                 break;
723             case OP_OR_GE:
724                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
725                 break;
726
727             default:
728                 break;
729             }
730             nNextPos = 2;
731             break;
732             // 定时器
733         case OP_TML:
734         case OP_TMR:
735         case OP_TMX:
736         case OP_TMY:
737             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
738             {
739                 unsigned char thisNum = pBinProg15->nOpNum;
740                 thisAddrType = pBinProg15->nParamType1;
741                 thisAddr = pBinProg15->nParamAddr1;
742                 switch (thisOP)
743                 {
744                 case OP_TML:
745                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 0);
746                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
747                     else StopTimer(thisNum);
748                     KMem.CurVAL = ProcessTimer(thisNum);
749
750                     break;
751                 case OP_TMR:
752                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 1);
753                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
754                     else StopTimer(thisNum);
755                     KMem.CurVAL = ProcessTimer(thisNum);
756                     break;
757                 case OP_TMX:
758                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 2);
759                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
760                     else StopTimer(thisNum);
761                     KMem.CurVAL = ProcessTimer(thisNum);
762
763                     break;
764                 case OP_TMY:
765                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 3);
766                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
767                     else StopTimer(thisNum);
768                     KMem.CurVAL = ProcessTimer(thisNum);
769                     break;
770                 default:
771                     break;
772                 }
773
774             }
775             nNextPos = 2;
776             break;
777             // 1 参数高级指令
778         case OP_INC:
779         case OP_DEC:
780             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
781             thisAddrType = pBinProg15->nParamType1;
782             thisAddr = pBinProg15->nParamAddr1;
783             nNextPos = 2;
784             switch (thisOP)
785             {
786             case OP_INC:
787                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
788                 break;
789             case OP_DEC:
790                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
791                 break;
792
793             default:
794                 break;
795             }
796             break;
797             // 2参数高级指令
798         case OP_MV:
799         case OP_ADD2:
800         case OP_SUB2:
801             pBinProg2 = (stBinProg2 *)(&pBinprog[CurPos]);
802             {
803                 int nParamType2, nParamAddr2;
804                 thisAddrType = pBinProg2->nParamType1;
805                 thisAddr = pBinProg2->nParamAddr1;
806                 nParamType2 = pBinProg2->nParamType2;
807                 nParamAddr2 = pBinProg2->nParamAddr2;
808
809                 switch (thisOP)
810                 {
811                 case OP_MV:
812                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr));
813                     break;
814                 case OP_ADD2:
815                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
816                     break;
817                 case OP_SUB2:
818                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr));
819                     break;
820
821                 default:
822                     break;
823                 }
824
825             }
826             nNextPos = 2;
827             break;
828             // 3 参数高级指令
829         case OP_ADD3:
830         case OP_SUB3:
831         case OP_MUL:
832         case OP_DIV:
833             pBinProg3 = (stBinProg3 *)(&pBinprog[CurPos]);
834             int nParamType2, nParamAddr2;
835             int nParamType3, nParamAddr3;
836             thisAddrType = pBinProg3->nParamType1;
837             thisAddr = pBinProg3->nParamAddr1;
838             nParamType2 = pBinProg3->nParamType2;
839             nParamAddr2 = pBinProg3->nParamAddr2;
840             nParamType3 = pBinProg3->nParamType3;
841             nParamAddr3 = pBinProg3->nParamAddr3;
842             switch (thisOP)
843             {
844             case OP_ADD3:
845                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
846                 break;
847             case OP_SUB3:
848                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2));
849                 break;
850             case OP_MUL:
851                 if (KMem.CurVAL) {
852                     short multiplicand = GetVarData(thisAddrType, thisAddr);
853                     short multiplier = GetVarData(nParamType2, nParamAddr2);
854                     int product = multiplicand * multiplier;
855                     SetVarData(nParamType3, nParamAddr3, product);
856                     SetVarData(nParamType3, nParamAddr3 + 1, product >> 16);
857                 }
858                 break;
859             case OP_DIV:
860                 if (KMem.CurVAL) {
861                     short dividend = GetVarData(thisAddrType, thisAddr);
862                     short divisor = GetVarData(nParamType2, nParamAddr2);
863                     short quotient = dividend / divisor;
864                     short remainder = dividend % divisor;
865                     SetVarData(nParamType3, nParamAddr3, quotient);
866                     SetVarData(nParamType3, nParamAddr3 + 1, remainder);
867                 }
868                 break;
869
870             default:
871                 break;
872             }
873             nNextPos = 3;
874             break;
875
876         default:
877             break;
878         }
879
880         lastScanInputVal = ProgTrace[CurPos];
881         ProgTrace[CurPos] = KMem.CurVAL;
882         CurPos += nNextPos;
883     }
884     nScanCount++;
885     return 0;
886 }
887
888 /*
889 int KMachine::ProcessPLCProg(const stProg * prog, int nSize)
890 {
891     if (nScanCount == 0) {
892         SetCoilValue(KLCoilTypeSR, 13, 1);
893         SetCoilValue(KLCoilTypeSR, 0, 0);
894         SetCoilValue(KLCoilTypeSR, 1, 1);
895     }
896     else
897     {
898         SetCoilValue(KLCoilTypeSR, 13, 0);
899         SetCoilValue(KLCoilTypeSR, 0, 0);
900         SetCoilValue(KLCoilTypeSR, 1, 1);
901     }
902     for (int i = 0; i < TOTAL_CurVAL; i++) {
903         KMem.CurVALs[i] = '0';
904     }
905     int lastScanInputVal = 1;//上个扫描周期,当前指令输入状态,为 微分 做参考
906     for (int i = 0; i < nSize; i++)
907     {
908         unsigned int thisOP = prog[i].nOpType1;
909         unsigned int nParamCount = prog[i].nParamCount;
910         unsigned int thisAddrType = prog[i].Params[0].nParamType;
911         unsigned short thisAddr = prog[i].Params[0].nParamAddr;
912
913         unsigned int AddrType2 = prog[i].Params[1].nParamType;
914         unsigned short Addr2 = prog[i].Params[1].nParamAddr;
915
916         unsigned int AddrType3 = prog[i].Params[2].nParamType;
917         unsigned short Addr3 = prog[i].Params[2].nParamAddr;
918
919         switch (thisOP)
920         {
921         case OP_NOP:
922             break;
923         case OP_ST:
924             PushInVal();
925             KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
926             break;
927         case OP_ST_:
928             PushInVal();
929             KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
930             break;
931         case OP_AN:
932             KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
933             break;
934         case OP_AN_:
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_OR_:
941             KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
942             break;
943         case OP_NOT:
944             KMem.CurVAL = !KMem.CurVAL;
945             break;
946         case OP_ANS:
947             KMem.CurVAL = PopOutVal() && KMem.CurVAL;
948             break;
949         case OP_ORS:
950             KMem.CurVAL = PopOutVal() || KMem.CurVAL;
951             break;
952         case OP_PSHS:
953             PushInVal();
954             break;
955         case OP_RDS:
956             KMem.CurVAL = KMem.CurVALs[0] == '1';
957             break;
958         case OP_POPS:
959             KMem.CurVAL = PopOutVal();
960             break;
961         case OP_OUT:
962             SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
963             break;
964         case OP_SET:
965             if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
966             break;
967         case OP_RESET:
968             if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
969             break;
970         case OP_DF:
971             KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
972             break;
973         case OP_DF_:
974             KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
975             break;
976         case OP_ST_EQ:
977             PushInVal();
978             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
979             break;
980         case OP_ST_NE:
981             PushInVal();
982             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
983             break;
984         case OP_ST_LT:
985             PushInVal();
986             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
987             break;
988         case OP_ST_GT:
989             PushInVal();
990             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
991             break;
992         case OP_ST_LE:
993             PushInVal();
994             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
995             break;
996         case OP_ST_GE:
997             PushInVal();
998             KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
999             break;
1000         case OP_AN_EQ:
1001             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
1002             break;
1003         case OP_AN_NE:
1004             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
1005             break;
1006         case OP_AN_LT:
1007             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
1008             break;
1009         case OP_AN_GT:
1010             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
1011             break;
1012         case OP_AN_LE:
1013             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
1014             break;
1015         case OP_AN_GE:
1016             KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
1017             break;
1018
1019         case OP_OR_EQ:
1020             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2));
1021             break;
1022         case OP_OR_NE:
1023             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2));
1024             break;
1025         case OP_OR_LT:
1026             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2));
1027             break;
1028         case OP_OR_GT:
1029             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2));
1030             break;
1031         case OP_OR_LE:
1032             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2));
1033             break;
1034         case OP_OR_GE:
1035             KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2));
1036             break;
1037
1038
1039         case OP_TML:
1040             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 0);
1041             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1042             else StopTimer(thisAddr);
1043             KMem.CurVAL = ProcessTimer(thisAddr);
1044
1045             break;
1046         case OP_TMR:
1047             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 1);
1048             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1049             else StopTimer(thisAddr);
1050             KMem.CurVAL = ProcessTimer(thisAddr);
1051             break;
1052         case OP_TMX:
1053             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 2);
1054             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1055             else StopTimer(thisAddr);
1056             KMem.CurVAL = ProcessTimer(thisAddr);
1057
1058             break;
1059         case OP_TMY:
1060             if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 3);
1061             if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2));
1062             else StopTimer(thisAddr);
1063             KMem.CurVAL = ProcessTimer(thisAddr);
1064             break;
1065         case OP_MV:
1066             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr));
1067             break;
1068         case OP_INC:
1069             if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
1070             break;
1071         case OP_DEC:
1072             if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
1073             break;
1074         case OP_ADD2:
1075             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2));
1076             break;
1077         case OP_SUB2:
1078             if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(AddrType2, Addr2) - GetVarData(thisAddrType, thisAddr));
1079             break;
1080         case OP_ADD3:
1081             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2));
1082             break;
1083         case OP_SUB3:
1084             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) - GetVarData(AddrType2, Addr2));
1085             break;
1086         case OP_MUL:
1087             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) * GetVarData(AddrType2, Addr2));
1088             break;
1089         case OP_DIV:
1090             if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) / GetVarData(AddrType2, Addr2));
1091             break;
1092
1093             
1094             //    OP_BKMV = 60,
1095             //    OP_COPY = 61,
1096             //    OP_CLR = 62,
1097             
1098
1099         default:
1100             break;
1101         }
1102         lastScanInputVal = ProgTrace[i];
1103         ProgTrace[i] = KMem.CurVAL;
1104     }
1105     nScanCount++;
1106     return 0;
1107 }
1108
1109 */
1110