/* * Execute the FCMPG instruction */ void op_fcmpg() { float f2 = popFloat(); float f1 = popFloat(); int k = 1; if (f1 < f2) { k = -1; } if (f1 == f2) { k = 0; } pushInt(k); pc++; }
float get_float_parameter( StackFrame *stack, SimpleConstantPool *p) { float value = 0; if ( is_ref_entry(stack) ) { int index = popInt(stack); value = get_float_from_constant_pool(p, index); } else { value = popFloat(stack); } return value; }
void OSCServerThread::run() { oscpkt::UdpSocket server; server.bindTo(this->port); if (!server.isOk()) { std::cerr << "Error opening OSC server at " << port << std::endl; return; } std::cout << "Started OSC Server at " << port << std::endl; oscpkt::PacketReader reader; oscpkt::PacketWriter writer; while (server.isOk() && !mustQuit) { if (server.receiveNextPacket(30)) { reader.init(server.packetData(), server.packetSize()); oscpkt::Message *msg; while (reader.isOk() && (msg = reader.popMessage()) != 0) { QVariantList message; message.append(QString::fromStdString( msg->addressPattern())); auto args = msg->arg(); while (!args.isOkNoMoreArgs()) { if (args.isInt32()) { int32_t i; args = args.popInt32(i); message.append(i); } else if (args.isInt64()) { int64_t i; args = args.popInt64(i); message.append( static_cast<qlonglong>(i)); } else if (args.isFloat()) { float f; args = args.popFloat(f); message.append(f); } else if (args.isDouble()) { double d; args = args.popDouble(d); message.append(d); } else if (args.isStr()) { std::string s; args = args.popStr(s); message.append( QString::fromStdString(s)); } } emit messageIn(message); } } } }
//------------------------------------------------------------------------------ // An adaptation of a function of the same name in the original Babuino code. //------------------------------------------------------------------------------ void Babuino::code_exec() { //Serial.println("code_exec()"); if (!_storage.getReadyToRead()) { // TO DO: What now? How do I report an error? } while (_states.getRunRequest() == RUNNING) { _storage.readByte(_regs.pc, _regs.opCode); _regs.pc++; switch (_regs.opCode) { case OP_CONFIG: withConfig(); break; case OP_MATH: withMath(); break; case OP_BYTE: case OP_INT8: case OP_SPAN: { //Serial.println("int8 "); uint8_t value; _regs.pc = _storage.readByte(_regs.pc, value); pushUint8(_stack, value); } break; case OP_SHORT: case OP_UINT16: { //Serial.print("int16: "); uint16_t value; _regs.pc = _storage.read<uint16_t>(_regs.pc, value); //Serial.println(value); pushUint16(_stack, value); } break; case OP_GLOBAL: { //Serial.print("global: "); STACKPTR value; _regs.pc = _storage.read<STACKPTR>(_regs.pc, value); //Serial.println(value); pushStackPtr(_stack, value); //_stack.push(_stack.getBottom() - value); } break; case OP_INT32: case OP_UINT32: { //Serial.print("int32 "); uint32_t value; _regs.pc = _storage.read<uint32_t>(_regs.pc, value); #ifdef SUPPORT_32BIT pushUint32(_stack, value); #else pushUint16(_stack, (value >> 16) & 0xFFFF); // High 16 bits pushUint16(_stack, value & 0xFFFF); // Low 16 bits #endif } break; #ifdef SUPPORT_FLOAT case OP_FLOAT: { //Serial.print("float "); float value; _regs.pc = _storage.read<float>(_regs.pc, value); pushFloat(_stack, value); } break; #endif #ifdef SUPPORT_DOUBLE case OP_DOUBLE: { //Serial.print("double "); double value; _regs.pc = _storage.read<double>(_regs.pc, value); pushDouble(_stack, value); } break; #endif case OP_BOOL: { //Serial.print("bool "); bool value; _regs.pc = _storage.read<bool>(_regs.pc, value); pushUint8(_stack, (uint8_t)value); } break; case OP_CPTR: { //Serial.print("cptr "); PROGPTR value; _regs.pc = _storage.read<PROGPTR>(_regs.pc, value); pushProgPtr(_stack, value); } break; #ifdef SUPPORT_STRING case OP_STRING: { //Serial.print("string: \""); // ***KLUDGE WARNING*** // Borrowing unused (hopefully) stack space as a buffer! // (To avoid having to allocate another buffer. uint8_t* psz = (uint8_t*)getTopAddress(_stack); uint8_t nextChar; int16_t i = -1; do { i++; _regs.pc = _storage.readByte(_regs.pc, nextChar); psz[i] = nextChar; } while (nextChar); //Serial.print((char *)psz); //Serial.print("\" "); // Logically this is wrong because I'm apparently // pushing a string to a location that it already // occupies. However, the stack implementation // pushes strings onto a separate stack, then // pushes the location onto the main stack. So // the string doesn't get copied over itself, and // is already copied before the first characters are // overwritten by pushing the said location onto the // main stack. //STACKSTATE state; //getStackState(_stack, &state); //Serial.print("[("); Serial.print(state.top); Serial.print(","); Serial.print(state.stringTop);Serial.print(") -> ("); pushString(_stack, psz); //getStackState(_stack, &state); //Serial.print(state.top); Serial.print(","); Serial.print(state.stringTop);Serial.println(")]"); } break; case OP_ASCII: { uint8_t* psz; topString(_stack, &psz); uint8_t ascii = psz[0]; popString(_stack); pushUint8(_stack, ascii); } break; case OP_STRLEN: { uint8_t* psz; topString(_stack, &psz); uint8_t len = strlen((char*)psz); popString(_stack); pushUint8(_stack, len); } break; #endif case OP_BEEP: //Serial.println("---beep---"); beep(); break; case OP_LEDON: //Serial.println("---LED on---"); userLed(true); // set the correct bit break; case OP_LEDOFF: //Serial.println("---LED off---"); userLed(false); break; case OP_WITHINT8: case OP_WITHUINT8: case OP_WITHINT16: case OP_WITHUINT16: case OP_WITHBOOL: case OP_WITHPTR: #ifdef SUPPORT_32BIT case OP_WITHINT32: case OP_WITHUINT32: #endif #ifdef SUPPORT_FLOAT case OP_WITHFLOAT: #endif #ifdef SUPPORT_DOUBLE case OP_WITHDOUBLE: #endif #ifdef SUPPORT_STRING case OP_WITHSTRING: #endif _regs.withCode = _regs.opCode; break; case OP_LOCAL: { //Serial.print("local: local frame ("); //Serial.print(_regs.localFrame); //Serial.print(") - "); STACKPTR varOffset; _regs.pc = _storage.read<uint16_t>(_regs.pc, (uint16_t&)varOffset); pushStackPtr(_stack, (STACKPTR)_regs.localFrame.top + varOffset); //Serial.print(varOffset); //Serial.print(" = global "); //Serial.println(_regs.localFrame + varOffset); } break; case OP_PARAM: { //Serial.print("param: "); STACKPTR varOffset; _regs.pc = _storage.read<uint16_t>(_regs.pc, (uint16_t&)varOffset); // We have an index into the parameters, which were put on // the stack in reverse order before the function call. // Calculate the absolute stack offset using the local // stack frame offset. // Also, the total size of the arguments was pushed last, // so we need to step past that too. // TODO: Check against the total argument size. pushStackPtr(_stack, getArgsLocation() - sizeof(uint8_t) // Number of args - varOffset // Offset to the required param ); } break; case OP_BLOCK: { //Serial.print("block "); descendBlock(); // Shift the flag to the next block bit //char psz[10]; //utoa(_regs.blockDepthMask, psz, 2); //Serial.println(psz); uint16_t blockLength; // Push address of next instruction (following the block // length data) pushProgPtr(_stack, (PROGPTR)_regs.pc + sizeof(uint16_t)); _storage.read<uint16_t>(_regs.pc, blockLength); // Step past the block (tests there will bring execution back) _regs.pc.increment(blockLength); } break; case OP_EOB: //Serial.println("--eob--"); setBlockExecuted(); // Set the bit to indicate that this block has executed break; case OP_DO: { //Serial.println("---do---"); // OP_DO is like OP_BLOCK except that execution falls through to // the top of the block of code unconditionally rather than jump // to the end where some condition is tested. // Need to: // - Push the address that the following OP_BLOCK would push // - Step past the: // - The OP_BLOCK code (uint8_t) // - The block size (uint16_t) // After going through the code block it should jump back to // the beginning of the OP_BLOCK and loop as usual. descendBlock(); // Shift the flag to the next block bit (normally done by OP_BLOCK) PROGPTR startOfBlock = (PROGPTR)_regs.pc + sizeof(uint8_t) +sizeof(uint16_t); pushProgPtr(_stack, startOfBlock); _regs.pc.set(startOfBlock); } break; case OP_WHILE: { //Serial.print("while "); bool condition; PROGPTR blockAddr; popUint8(_stack, (uint8_t*)&condition); //Serial.println(condition ? "true" : "false"); //_stack.pop(blockAddr); if (condition) // if true then go to the block start address { topProgPtr(_stack, &blockAddr); _regs.pc = blockAddr; } else { popProgPtr(_stack, &blockAddr); // Throw it away ascendBlock(); // Finished with this block now } } break; case OP_REPEAT: { //Serial.print("repeat "); PROGPTR blockAddr; uint16_t max; popProgPtr(_stack, &blockAddr); popUint16(_stack, &max); uint16_t repcount; if (!hasBlockExecuted()) // First time around? { repcount = 1; pushUint16(_stack, repcount); // point to the counter we just pushed STACKPTR slot = getTop(_stack); // Save outer loop's repcount pointer pushStackPtr(_stack, _regs.repcountLocation); // Set it to ours _regs.repcountLocation = slot; } else { getUint16(_stack, _regs.repcountLocation, &repcount); // Get counter value repcount++; } //Serial.println(repcount); if (repcount <= max) { setUint16(_stack, _regs.repcountLocation, repcount); pushUint16(_stack, max); pushProgPtr(_stack, blockAddr); _regs.pc = blockAddr; } else { // Restore the outer loop's repcount pointer popStackPtr(_stack, &_regs.repcountLocation); popUint16(_stack, &repcount); // Dispose of counter ascendBlock(); // Finished with this block now } } break; case OP_REPCOUNT: { uint16_t repcount; getUint16(_stack, _regs.repcountLocation, &repcount); pushUint16(_stack, repcount); } break; case OP_FOR: { //Serial.println("for "); // The counter variable has already been set to the from // value, so the from value isn't on the stack. PROGPTR blockAddr; int16_t step, to, from; STACKPTR counterOff; int16_t counterVal; popProgPtr(_stack, &blockAddr); popUint16(_stack, (uint16_t*)&step); popUint16(_stack, (uint16_t*)&to); popUint16(_stack, (uint16_t*)&from); popStackPtr(_stack, &counterOff); getUint16(_stack, counterOff, (uint16_t*)&counterVal); //Serial.print(counterVal); //Serial.print(" "); //Serial.print(to); //Serial.print(" "); //Serial.println(step); bool keepGoing; // See if this is the first time around if (!hasBlockExecuted()) { counterVal = from; keepGoing = true; } else { // If step > 0 then assume from < to otherwise assume from > to keepGoing = (step > 0) ? (counterVal < to) : (counterVal > to); counterVal += step; } if (keepGoing) { setUint16(_stack, counterOff, (uint16_t)counterVal); _regs.pc = blockAddr; // reiterate pushStackPtr(_stack, counterOff); // Var offset pushUint16(_stack, (uint16_t)from); // to pushUint16(_stack, (uint16_t)to); // to pushUint16(_stack, (uint16_t)step); // step pushProgPtr(_stack, blockAddr); } else { ascendBlock(); } } break; case OP_IF: { //Serial.print("if "); // If it's the first time through then check the // condition if (!hasBlockExecuted()) { PROGPTR blockAddr; bool condition; popProgPtr(_stack, &blockAddr); // Block initial address popUint8(_stack, (uint8_t*)&condition); // argument to test //Serial.println(condition ? "true" : "false"); if (condition) { _regs.pc = blockAddr; } else { ascendBlock(); } } else { ascendBlock(); } } break; // IFELSE starts with address of THEN and ELSE lists (and // CONDITIONAL) on the stack. CONDITIONAL is tested and // appropriate list is run. case OP_IFELSE: { //Serial.print("ifelse "); PROGPTR elseBlock; popProgPtr(_stack, &elseBlock); // ELSE block start // Note that descendBlock() will have been called twice // the first time around (once for each block). ascendBlock(); // Remove the else block... // ...and use the then block flag for both purposes if (!hasBlockExecuted()) { PROGPTR thenBlock; bool condition; popProgPtr(_stack, &thenBlock); // THEN block start popUint8(_stack, (uint8_t*)&condition); // argument to test if (condition) { //Serial.println("(then)"); _regs.pc = thenBlock; // The ELSE address will get pushed again when // execution falls into the ELSE block after // exiting the THEN block. // Another else block will be descended into // as well, and ascended away again above. // The eob code will be encountered at the end // of the then block, and that will set the // executed flag. } else { //Serial.println("(else)"); _regs.pc = elseBlock; // the "ELSE" list pushProgPtr(_stack, (PROGPTR)0); // Push fake ELSE to balance // Borrow the then block flag and set it now as // executed since it won't actually be set // otherwise. setBlockExecuted(); // Descend the else block now, as // this also won't be done in the block's code. descendBlock(); } } else { //popProgPtr(_stack, &elseBlock); // dispose of unrequired address ascendBlock(); // ie. the then block } } break; case OP_PUSH: { //Serial.print("push "); uint8_t amount; popUint8(_stack, &amount); pushn(_stack, (STACKPTR)amount); } break; case OP_POP: { //Serial.print("pop "); uint8_t amount; popUint8(_stack, &amount); popn(_stack, (STACKPTR)amount); } break; case OP_CHKPOINT: getStackState(_stack, &_regs.checkPoint); break; case OP_ROLLBACK: setStackState(_stack, &_regs.checkPoint); break; case OP_CALL: { //Serial.println("call"); PROGPTR procAddr; popProgPtr(_stack, &procAddr); // Get the function location // Save the args location used by the calling function, and // set it to what was the stack top before it was pushed. /* _regs.argsLoc = _stack.push(_regs.argsLoc); //Serial.print("args location: "); //Serial.println(_regs.argsLoc); */ pushProgPtr(_stack, (PROGPTR)_regs.pc); // Save the current code location for the return _regs.pc.set(procAddr); // Now jump to the function } break; case OP_BEGIN: //Serial.println("begin"); pushRegisters(); // Save state of the caller _regs.blockDepthMask = 0; _regs.blocksExecuted = 0; getStackState(_stack, &_regs.localFrame); // = getTop(_stack); //Serial.println(_regs.localFrame); break; case OP_RETURN: { //Serial.print("return "); //Unwind the stack to the beginning of the local frame setStackState(_stack, &_regs.localFrame); popRegisters(); PROGPTR returnAddr; popProgPtr(_stack, &returnAddr); // Get the return address //_stack.pop(_regs.argsLoc); // Restore the param location for the calling function _regs.pc.set(returnAddr); } break; case OP_EXIT: reset(); //Serial.println("---exit---"); break; case OP_LOOP: { //Serial.println("---loop---"); PROGPTR blockAddr; topProgPtr(_stack, &blockAddr); _regs.pc.set(blockAddr); } break; case OP_WAIT: { //Serial.println("---wait---"); uint16_t tenths; popUint16(_stack, &tenths); delay(100 * tenths); } break; case OP_TIMER: //Serial.print("timer "); pushUint16(_stack, _timerCount); // TODO: implement timer!! break; case OP_RESETT: //Serial.println("---resett---"); _timerCount = 0; break; case OP_RANDOM: //Serial.print("random "); pushUint16(_stack, (uint16_t)random(0, 32767)); break; case OP_RANDOMXY: { //Serial.print("randomxy "); int16_t x; int16_t y; popUint16(_stack, (uint16_t*)&y); popUint16(_stack, (uint16_t*)&x); pushUint16(_stack, (uint16_t)random(x, y)); } break; case OP_MOTORS: { //Serial.print("motors "); uint8_t selected; popUint8(_stack, &selected); _selectedMotors = (Motors::Selected)selected; } break; case OP_THISWAY: //Serial.print("---thisway---"); _motors.setDirection(_selectedMotors, MotorBase::THIS_WAY); break; case OP_THATWAY: //Serial.print("---thatway---"); _motors.setDirection(_selectedMotors, MotorBase::THAT_WAY); break; case OP_RD: //Serial.print("---rd---"); _motors.reverseDirection(_selectedMotors); break; case OP_SETPOWER: { //Serial.print("setpower "); uint8_t power; popUint8(_stack, &power); if (power > 7) power = 7; _motors.setPower(_selectedMotors, power); } break; case OP_BRAKE: //Serial.println("---brake---"); _motors.setBrake(_selectedMotors, MotorBase::BRAKE_ON); break; case OP_ON: //Serial.println("---on---"); _motors.on(_selectedMotors); break; case OP_ONFOR: { //Serial.print("onfor"); uint16_t tenths; popUint16(_stack, &tenths); _motors.on(_selectedMotors); delay(100 * tenths); _motors.off(_selectedMotors); } break; case OP_OFF: //Serial.println("---off---"); _motors.off(_selectedMotors); break; case OP_SENSOR1: case OP_SENSOR2: case OP_SENSOR3: case OP_SENSOR4: case OP_SENSOR5: case OP_SENSOR6: case OP_SENSOR7: case OP_SENSOR8: //Serial.print("sensor "); //Serial.print(_regs.opCode - OP_SENSOR1); //Serial.print(" "); pushUint16(_stack, (uint16_t)readAnalog(_regs.opCode - OP_SENSOR1)); break; case OP_AIN: { //Serial.print("ain "); uint8_t input; popUint8(_stack, &input); pushUint16(_stack, (uint16_t)readAnalog(input)); } break; case OP_AOUT: { //Serial.print("aout "); uint8_t output; uint8_t value; popUint8(_stack, &output); popUint8(_stack, &value); writeAnalog(output, value); } break; case OP_SWITCH1: case OP_SWITCH2: case OP_SWITCH3: case OP_SWITCH4: case OP_SWITCH5: case OP_SWITCH6: case OP_SWITCH7: case OP_SWITCH8: { //Serial.print("switch "); //Serial.print(_regs.opCode - OP_SWITCH1); //Serial.print(" "); int16_t val = readAnalog(_regs.opCode - OP_SWITCH1); if (val < 0) pushUint8(_stack, (uint8_t)false); else pushUint8(_stack, (uint8_t)!!(val >> 7)); } break; case OP_NOT: break; case OP_AND: break; case OP_OR: break; case OP_XOR: break; case OP_DIN: { //Serial.print("din "); uint8_t input; popUint8(_stack, &input); pushUint8(_stack, (uint8_t)readDigital(input)); } break; case OP_DOUT: { //Serial.print("dout "); uint8_t output; bool value; popUint8(_stack, &output); popUint8(_stack, (uint8_t*)&value); writeDigital(output, value); } break; case OP_BTOS: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushUint16(_stack,(uint16_t)value); } break; case OP_UBTOS: { uint8_t value; popUint8(_stack, &value); pushUint16(_stack,(uint16_t)value); } break; case OP_STOB: // and OP_USTOB { //Serial.print("stob: "); uint16_t value; popUint16(_stack, (uint16_t*)&value); //Serial.println(value); pushUint8(_stack, (uint8_t)value); } break; #ifdef SUPPORT_32BIT case OP_BTOI: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushUint32(_stack,(uint32_t)value); } break; case OP_UBTOI: { uint8_t value; popUint8(_stack, &value); pushUint32(_stack,(uint32_t)value); } break; case OP_STOI: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushUint32(_stack,(uint32_t)value); } break; case OP_USTOI: { uint16_t value; popUint16(_stack, &value); pushUint32(_stack,(uint32_t)value); } break; case OP_ITOB: // and OP_UITOB { int32_t value; popUint32(_stack, (uint32_t*)&value); pushUint8(_stack, (uint8_t)value); } break; case OP_ITOS: //and OP_UITOS { int32_t value; popUint32(_stack, (uint32_t*)&value); pushUint16(_stack, (uint16_t)value); } break; #endif #ifdef SUPPORT_FLOAT case OP_BTOF: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushFloat(_stack, (float)value); } break; case OP_UBTOF: { uint8_t value; popUint8(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_STOF: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushFloat(_stack, (float)value); } break; case OP_USTOF: { uint16_t value; popUint16(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_FTOB: { float value; popFloat(_stack, &value); pushUint8(_stack, (uint8_t)value); } break; case OP_FTOS: { float value; popFloat(_stack, &value); pushUint16(_stack, (uint16_t)value); } break; #endif #ifdef SUPPORT_DOUBLE case OP_BTOD: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushDouble(_stack, (double)value); } break; case OP_UBTOD: { uint8_t value; popUint8(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_STOD: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushDouble(_stack, (double)value); } break; case OP_USTOD: { uint16_t value; popUint8(_stack, (uint8_t*)&value); pushDouble(_stack, (double)value); } break; case OP_DTOB: { double value; popDouble(_stack, &value); pushUint8(_stack, (uint8_t)value); } break; case OP_DTOS: { double value; popDouble(_stack, &value); pushUint16(_stack, (uint16_t)value); } break; #endif #if defined(SUPPORT_DOUBLE) && defined(SUPPORT_32BIT) case OP_ITOD: { int32_t value; popUint32(_stack, (uint32_t*)&value); pushDouble(_stack, (double)value); } break; case OP_UITOD: { uint32_t value; popUint32(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_DTOI: { double value; popDouble(_stack, &value); pushUint32(_stack, (uint32_t)value); } break; #endif #if defined(SUPPORT_DOUBLE) && defined(SUPPORT_FLOAT) case OP_FTOD: { float value; popFloat(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_DTOF: { double value; popDouble(_stack, &value); pushFloat(_stack, (float)value); } break; #endif #if defined(SUPPORT_FLOAT) && defined(SUPPORT_32BIT) case OP_ITOF: { int32_t value; popUint32(_stack, (uint32_t*)&value); pushFloat(_stack, (float)value); } break; case OP_UITOF: { uint32_t value; popUint32(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_FTOI: { float value; popFloat(_stack, &value); pushUint32(_stack, (uint32_t)value); } break; #endif case OP_I2CSTART: i2cStart(); break; case OP_I2CSTOP: i2cStop(); break; case OP_I2CTXRX: { uint16_t i2cAddr; uint16_t txBuffOffset; uint8_t txBuffLen; uint16_t rxBuffOffset; uint8_t rxBuffLen; uint16_t timeout; popUint16(_stack, &i2cAddr); popUint16(_stack, &txBuffOffset); popUint8(_stack, &txBuffLen); popUint16(_stack, &rxBuffOffset); popUint8(_stack, &rxBuffLen); popUint16(_stack, &timeout); i2cTxRx(i2cAddr, (uint8_t*)getStackAddress(_stack, txBuffOffset), txBuffLen, (uint8_t*)getStackAddress(_stack, rxBuffOffset), rxBuffLen, timeout); } break; case OP_I2CRX: { uint16_t addr; uint16_t rxBuffOffset; uint8_t rxBuffLen; uint16_t timeout; popUint16(_stack, &addr); popUint16(_stack, &rxBuffOffset); popUint8(_stack, &rxBuffLen); popUint16(_stack, &timeout); i2cRx(addr, (uint8_t*)getStackAddress(_stack, rxBuffOffset), rxBuffLen, timeout); } break; #ifdef SUPPORT_32BIT case OP_I2CERR: { //Serial.println("---i2cerr---"); uint32_t errors = i2cErrors(); pushUint32(_stack, errors); } break; #endif case OP_WAITUNTIL: case OP_RECORD: case OP_RECALL: case OP_RESETDP: case OP_SETDP: case OP_ERASE: case OP_SETSVH: case OP_SVR: case OP_SVL: // TODO!!! break; default: // All of the type specific codes are dealt with here if (!withCurrentType()) { //beep(); // Just an indication for now. Serial.print("unrecognised opcode: "); Serial.println(_regs.opCode); } break; } } }