⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intcode.cpp

📁 plc软件的源代码 支持PIC ATMEGA单片机
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                    stateInOut);
            }
            Comment("] finish series");
            break;
        }
        case ELEM_PARALLEL_SUBCKT: {
            char parThis[MAX_NAME_LEN];
            GenSymParThis(parThis);

            char parOut[MAX_NAME_LEN];
            GenSymParOut(parOut);

            Comment("start parallel [");

            Op(INT_CLEAR_BIT, parOut);

            ElemSubcktParallel *p = (ElemSubcktParallel *)any;
            int i;
            for(i = 0; i < p->count; i++) {
                Op(INT_COPY_BIT_TO_BIT, parThis, stateInOut);

                IntCodeFromCircuit(p->contents[i].which, p->contents[i].d.any,
                    parThis);

                Op(INT_IF_BIT_SET, parThis);
                Op(INT_SET_BIT, parOut);
                Op(INT_END_IF);
            }
            Op(INT_COPY_BIT_TO_BIT, stateInOut, parOut);
            Comment("] finish parallel");
            
            break;
        }
        case ELEM_CONTACTS: {
            if(l->d.contacts.negated) {
                Op(INT_IF_BIT_SET, l->d.contacts.name);
            } else {
                Op(INT_IF_BIT_CLEAR, l->d.contacts.name);
            }
            Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_END_IF);
            break;
        }
        case ELEM_COIL: {
            if(l->d.coil.negated) {
                Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_CLEAR_BIT, l->d.contacts.name);
                Op(INT_ELSE);
                Op(INT_SET_BIT, l->d.contacts.name);
                Op(INT_END_IF);
            } else if(l->d.coil.setOnly) {
                Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_SET_BIT, l->d.contacts.name);
                Op(INT_END_IF);
            } else if(l->d.coil.resetOnly) {
                Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_CLEAR_BIT, l->d.contacts.name);
                Op(INT_END_IF);
            } else {
                Op(INT_COPY_BIT_TO_BIT, l->d.contacts.name, stateInOut);
            }
            break;
        }
        case ELEM_RTO: {
            int period = TimerPeriod(l);

            Op(INT_IF_VARIABLE_LES_LITERAL, l->d.timer.name, period);

            Op(INT_IF_BIT_SET, stateInOut);
            Op(INT_INCREMENT_VARIABLE, l->d.timer.name);
            Op(INT_END_IF);
            Op(INT_CLEAR_BIT, stateInOut);

            Op(INT_ELSE);

            Op(INT_SET_BIT, stateInOut);

            Op(INT_END_IF);

            break;
        }
        case ELEM_RES:
            Op(INT_IF_BIT_SET, stateInOut);
            Op(INT_SET_VARIABLE_TO_LITERAL, l->d.reset.name);
            Op(INT_END_IF);
            break;

        case ELEM_TON: {
            int period = TimerPeriod(l);

            Op(INT_IF_BIT_SET, stateInOut);

            Op(INT_IF_VARIABLE_LES_LITERAL, l->d.timer.name, period);

            Op(INT_INCREMENT_VARIABLE, l->d.timer.name);
            Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_END_IF);

            Op(INT_ELSE);

            Op(INT_SET_VARIABLE_TO_LITERAL, l->d.timer.name);

            Op(INT_END_IF);

            break;
        }
        case ELEM_TOF: {
            int period = TimerPeriod(l);

            // All variables start at zero by default, so by default the
            // TOF timer would start out with its output forced HIGH, until
            // it finishes counting up. This does not seem to be what
            // people expect, so add a special case to fix that up.
            char antiGlitchName[MAX_NAME_LEN];
            sprintf(antiGlitchName, "$%s_antiglitch", l->d.timer.name);
            Op(INT_IF_BIT_CLEAR, antiGlitchName);
                Op(INT_SET_VARIABLE_TO_LITERAL, l->d.timer.name, period);
            Op(INT_END_IF);
            Op(INT_SET_BIT, antiGlitchName);
            
            Op(INT_IF_BIT_CLEAR, stateInOut);

            Op(INT_IF_VARIABLE_LES_LITERAL, l->d.timer.name, period);

            Op(INT_INCREMENT_VARIABLE, l->d.timer.name);
            Op(INT_SET_BIT, stateInOut);
            Op(INT_END_IF);

            Op(INT_ELSE);

            Op(INT_SET_VARIABLE_TO_LITERAL, l->d.timer.name);

            Op(INT_END_IF);
            break;
        }
        case ELEM_CTU: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);

            Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_IF_BIT_CLEAR, storeName);
                    Op(INT_INCREMENT_VARIABLE, l->d.counter.name);
                Op(INT_END_IF);
            Op(INT_END_IF);
            Op(INT_COPY_BIT_TO_BIT, storeName, stateInOut);

            Op(INT_IF_VARIABLE_LES_LITERAL, l->d.counter.name,
                l->d.counter.max);
                Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_ELSE);
                Op(INT_SET_BIT, stateInOut);
            Op(INT_END_IF);
            break;
        }
        case ELEM_CTD: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);

            Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_IF_BIT_CLEAR, storeName);
                    Op(INT_SET_VARIABLE_TO_LITERAL, "$scratch", 1);
                    Op(INT_SET_VARIABLE_SUBTRACT, l->d.counter.name,
                        l->d.counter.name, "$scratch", 0);
                Op(INT_END_IF);
            Op(INT_END_IF);
            Op(INT_COPY_BIT_TO_BIT, storeName, stateInOut);

            Op(INT_IF_VARIABLE_LES_LITERAL, l->d.counter.name,
                l->d.counter.max);
                Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_ELSE);
                Op(INT_SET_BIT, stateInOut);
            Op(INT_END_IF);
            break;
        }
        case ELEM_CTC: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);

            Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_IF_BIT_CLEAR, storeName);
                    Op(INT_INCREMENT_VARIABLE, l->d.counter.name);
                    Op(INT_IF_VARIABLE_LES_LITERAL, l->d.counter.name,
                        l->d.counter.max+1);
                    Op(INT_ELSE);
                        Op(INT_SET_VARIABLE_TO_LITERAL, l->d.counter.name,
                            (SWORD)0);
                    Op(INT_END_IF);
                Op(INT_END_IF);
            Op(INT_END_IF);
            Op(INT_COPY_BIT_TO_BIT, storeName, stateInOut);
            break;
        }
        case ELEM_GRT:
        case ELEM_GEQ:
        case ELEM_LES:
        case ELEM_LEQ:
        case ELEM_NEQ:
        case ELEM_EQU: {
            char *op1 = VarFromExpr(l->d.cmp.op1, "$scratch");
            char *op2 = VarFromExpr(l->d.cmp.op2, "$scratch2");
            
            if(which == ELEM_GRT) {
                Op(INT_IF_VARIABLE_GRT_VARIABLE, op1, op2);
                Op(INT_ELSE);
            } else if(which == ELEM_GEQ) {
                Op(INT_IF_VARIABLE_GRT_VARIABLE, op2, op1);
            } else if(which == ELEM_LES) {
                Op(INT_IF_VARIABLE_GRT_VARIABLE, op2, op1);
                Op(INT_ELSE);
            } else if(which == ELEM_LEQ) {
                Op(INT_IF_VARIABLE_GRT_VARIABLE, op1, op2);
            } else if(which == ELEM_EQU) {
                Op(INT_IF_VARIABLE_EQUALS_VARIABLE, op1, op2);
                Op(INT_ELSE);
            } else if(which == ELEM_NEQ) {
                Op(INT_IF_VARIABLE_EQUALS_VARIABLE, op1, op2);
            } else oops();

            Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_END_IF);
            break;
        }
        case ELEM_ONE_SHOT_RISING: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);

            Op(INT_COPY_BIT_TO_BIT, "$scratch", stateInOut);
            Op(INT_IF_BIT_SET, storeName);
            Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_END_IF);
            Op(INT_COPY_BIT_TO_BIT, storeName, "$scratch");
            break;
        }
        case ELEM_ONE_SHOT_FALLING: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);
        
            Op(INT_COPY_BIT_TO_BIT, "$scratch", stateInOut);

            Op(INT_IF_BIT_CLEAR, stateInOut);
            Op(INT_IF_BIT_SET, storeName);
            Op(INT_SET_BIT, stateInOut);
            Op(INT_END_IF);
            Op(INT_ELSE);
            Op(INT_CLEAR_BIT, stateInOut);
            Op(INT_END_IF);

            Op(INT_COPY_BIT_TO_BIT, storeName, "$scratch");
            break;
        }
        case ELEM_MOVE: {
            if(IsNumber(l->d.move.dest)) {
                Error(_("Move instruction: '%s' not a valid destination."),
                    l->d.move.dest);
                CompileError();
            }
            Op(INT_IF_BIT_SET, stateInOut);
            if(IsNumber(l->d.move.src)) {
                Op(INT_SET_VARIABLE_TO_LITERAL, l->d.move.dest,
                    CheckMakeNumber(l->d.move.src));
            } else {
                Op(INT_SET_VARIABLE_TO_VARIABLE, l->d.move.dest, l->d.move.src,
                    0);
            }
            Op(INT_END_IF);
            break;
        }

        // These four are highly processor-dependent; the int code op does
        // most of the highly specific work
        {
            case ELEM_READ_ADC:
                Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_READ_ADC, l->d.readAdc.name);
                Op(INT_END_IF);
                break;

            case ELEM_SET_PWM: {
                Op(INT_IF_BIT_SET, stateInOut);
                char line[80];
                // ugh; need a >16 bit literal though, could be >64 kHz
                sprintf(line, "%d", l->d.setPwm.targetFreq);
                Op(INT_SET_PWM, l->d.readAdc.name, line);
                Op(INT_END_IF);
                break;
            }
            case ELEM_PERSIST: {
                Op(INT_IF_BIT_SET, stateInOut);

                // At startup, get the persistent variable from flash.
                char isInit[MAX_NAME_LEN];
                GenSymOneShot(isInit);
                Op(INT_IF_BIT_CLEAR, isInit);
                    Op(INT_CLEAR_BIT, "$scratch");
                    Op(INT_EEPROM_BUSY_CHECK, "$scratch");
                    Op(INT_IF_BIT_CLEAR, "$scratch");
                        Op(INT_SET_BIT, isInit);
                        Op(INT_EEPROM_READ, l->d.persist.var, EepromAddrFree);
                    Op(INT_END_IF);
                Op(INT_END_IF);

                // While running, continuously compare the EEPROM copy of
                // the variable against the RAM one; if they are different,
                // write the RAM one to EEPROM. 
                Op(INT_CLEAR_BIT, "$scratch");
                Op(INT_EEPROM_BUSY_CHECK, "$scratch");
                Op(INT_IF_BIT_CLEAR, "$scratch");
                    Op(INT_EEPROM_READ, "$scratch", EepromAddrFree);
                    Op(INT_IF_VARIABLE_EQUALS_VARIABLE, "$scratch",
                        l->d.persist.var);
                    Op(INT_ELSE);
                        Op(INT_EEPROM_WRITE, l->d.persist.var, EepromAddrFree);
                    Op(INT_END_IF);
                Op(INT_END_IF);

                Op(INT_END_IF);

                EepromAddrFree += 2;
                break;
            }
            case ELEM_UART_SEND:
                Op(INT_UART_SEND, l->d.uart.name, stateInOut);
                break;

            case ELEM_UART_RECV:
                Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_UART_RECV, l->d.uart.name, stateInOut);
                Op(INT_END_IF);
                break;
        }

        case ELEM_ADD:
        case ELEM_SUB:
        case ELEM_MUL:
        case ELEM_DIV: {
            if(IsNumber(l->d.math.dest)) {
                Error(_("Math instruction: '%s' not a valid destination."),
                    l->d.math.dest);
                CompileError();
            }
            Op(INT_IF_BIT_SET, stateInOut);

            char *op1 = VarFromExpr(l->d.math.op1, "$scratch");
            char *op2 = VarFromExpr(l->d.math.op2, "$scratch2");

            int intOp;
            if(which == ELEM_ADD) {
                intOp = INT_SET_VARIABLE_ADD;
            } else if(which == ELEM_SUB) {
                intOp = INT_SET_VARIABLE_SUBTRACT;
            } else if(which == ELEM_MUL) {
                intOp = INT_SET_VARIABLE_MULTIPLY;
            } else if(which == ELEM_DIV) {
                intOp = INT_SET_VARIABLE_DIVIDE;
            } else oops();

            Op(intOp, l->d.math.dest, op1, op2, 0);

            Op(INT_END_IF);
            break;
        }
        case ELEM_MASTER_RELAY:
            // Tricky: must set the master control relay if we reach this
            // instruction while the master control relay is cleared, because
            // otherwise there is no good way for it to ever become set
            // again.
            Op(INT_IF_BIT_CLEAR, "$mcr");
            Op(INT_SET_BIT, "$mcr");
            Op(INT_ELSE);
            Op(INT_COPY_BIT_TO_BIT, "$mcr", stateInOut);
            Op(INT_END_IF);
            break;

        case ELEM_SHIFT_REGISTER: {
            char storeName[MAX_NAME_LEN];
            GenSymOneShot(storeName);
            Op(INT_IF_BIT_SET, stateInOut);
                Op(INT_IF_BIT_CLEAR, storeName);
                    int i;
                    for(i = (l->d.shiftRegister.stages-2); i >= 0; i--) {
                        char dest[MAX_NAME_LEN+10], src[MAX_NAME_LEN+10];
                        sprintf(src, "%s%d", l->d.shiftRegister.name, i);
                        sprintf(dest, "%s%d", l->d.shiftRegister.name, i+1);
                        Op(INT_SET_VARIABLE_TO_VARIABLE, dest, src);
                    }
                Op(INT_END_IF);
            Op(INT_END_IF);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -