bool Babuino::withInt32() { STACKPTR location, index; int32_t rhs, lhs; switch (_regs.opCode) { case OP_ASHIFT: case OP_LSHIFT: { int8_t shift; popUint8(_stack, (uint8_t*)&shift); popUint32(_stack, (uint32_t*)&lhs); if (shift >= 0) pushUint32(_stack, (uint32_t)(lhs << shift)); else pushUint32(_stack, (uint32_t)(lhs >> -shift)); return true; } case OP_SET: //Serial.println("---set---"); popStackPtr(_stack, &location); popUint32(_stack, (uint32_t*)&rhs); setUint32(_stack, location, (uint32_t)rhs); return true; case OP_GET: //Serial.println("---get---"); popStackPtr(_stack, &location); getUint32(_stack, location, (uint32_t*)&rhs); pushUint32(_stack, (uint32_t)rhs); return true; case OP_ASET: //Serial.println("---aset---"); popStackPtr(_stack, &location); popStackPtr(_stack, &index); popUint32(_stack, (uint32_t*)&rhs); setUint32(_stack, location + index * sizeof(int32_t), (uint32_t)rhs); return true; case OP_AGET: //Serial.println("---aget---"); popStackPtr(_stack, &location); popStackPtr(_stack, &index); getUint32(_stack, location + index * sizeof(int32_t), (uint32_t*)&rhs); pushUint32(_stack, (uint32_t)rhs); return true; case OP_OUTPUT: { //Serial.print("output "); popUint32(_stack, (uint32_t*)&rhs); // The return value // point to where the arguments size is on the stack. location = getArgsLocation(); uint8_t argsSize; getUint8(_stack, location - sizeof(uint8_t), &argsSize); // Get size of args. // If the size > 0 then step over the size location too. // Otherwise keep pointing to the same place because the return // value should overwrite where the arguments size would be. if (argsSize > 0) argsSize += sizeof(uint8_t); setUint32(_stack, location - (STACKPTR)argsSize - sizeof(int32_t), (uint32_t)rhs); } return true; case OP_SEND: { //Serial.println("---send---"); popUint32(_stack, (uint32_t*)&rhs); uint8_t buf[sizeof(int32_t)]; hton(rhs, buf); //_defaultStream->write(nbuf, sizeof(int32_t)); // Replaced for debugging _defaultStream->print(rhs); } return true; case OP_SENDN: { //Serial.println("---sendn---"); uint8_t items; uint8_t port; STACKPTR bufLoc; popUint8(_stack, &items); popUint8(_stack, &port); popStackPtr(_stack, &bufLoc); int32_t* buf = (int32_t*)getStackAddress(_stack, bufLoc); uint8_t nbuf[sizeof(int32_t)]; for (int i = 0; i < items; i++) { rhs = *buf; hton(rhs, nbuf); //_defaultStream->write(nbuf, sizeof(int32_t)); // Replaced for debugging _defaultStream->print(rhs); buf++; } } return true; #ifdef SUPPORT_STRING case OP_TOSTR: { //Serial.println("---tostr---"); popUint32(_stack, (uint32_t*)&rhs); // ***KLUDGE WARNING*** // Borrowing unused (hopefully) stack space as a buffer! // just to avoid having to allocate another buffer. char* psz = (char *)getTopAddress(_stack); itoa((int) rhs, psz, 10); // 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. pushString(_stack, (uint8_t*)psz); } return true; #endif case OP_FOREACH: { //Serial.print("foreach "); PROGPTR blockAddr; popProgPtr(_stack, &blockAddr); // Block address popStackPtr(_stack, &location); // Iterator variable location (Variable contains a 'pointer') uint8_t itemsRemaining; popUint8(_stack, &itemsRemaining); // Number of items remaining // If we've gone through the block then we need to pop the // previous list item off the stack if (hasBlockExecuted()) { uint32_t tmpUint32; popUint32(_stack, &tmpUint32); } if (itemsRemaining > 0) // Any items remaining { // Set the value of the variable to the location on the // stack of the next list item (ie the top) setStackPtr(_stack, location, getTop(_stack) - sizeof(int32_t)); _regs.pc = blockAddr; // Point to the top of the block for the next iteration itemsRemaining--; // Decrement the number of items remaining pushUint8(_stack, itemsRemaining); // Save number of items remaining for next time pushStackPtr(_stack, location); // Save iterator variable location for next time pushProgPtr(_stack, blockAddr); // Save block address for next time } else { ascendBlock(); // Leaving. Pop the block. } } return true; } popUint32(_stack, (uint32_t*)&rhs); switch (_regs.opCode) { case OP_BITNOT: pushUint32(_stack, (uint32_t)~rhs); return true; case OP_ABS: pushUint32(_stack, (uint32_t)abs(rhs)); return true; case OP_NEG: pushUint32(_stack, (uint32_t)-rhs); return true; } popUint32(_stack, (uint32_t*)&lhs); switch (_regs.opCode) { case OP_ADD: pushUint32(_stack, (uint32_t)(lhs + rhs)); return true; case OP_SUB: pushUint32(_stack, (uint32_t)(lhs - rhs)); return true; case OP_MUL: pushUint32(_stack, (uint32_t)(lhs * rhs)); return true; case OP_DIV: pushUint32(_stack, (uint32_t)(lhs / rhs)); return true; case OP_MOD: pushUint32(_stack, (uint32_t)(lhs % rhs)); return true; case OP_EQ: pushUint8(_stack, (uint8_t)(lhs == rhs)); return true; case OP_GT: pushUint8(_stack, (uint8_t)(lhs > rhs)); return true; case OP_LT: pushUint8(_stack, (uint8_t)(lhs < rhs)); return true; case OP_LE: pushUint8(_stack, (uint8_t)(lhs <= rhs)); return true; case OP_GE: pushUint8(_stack, (uint8_t)(lhs >= rhs)); return true; case OP_NE: pushUint8(_stack, (uint8_t)(lhs != rhs)); return true; case OP_BITAND: pushUint32(_stack, (uint32_t)(lhs & rhs)); return true; case OP_BITOR: pushUint32(_stack, (uint32_t)(lhs | rhs)); return true; case OP_BITXOR: pushUint32(_stack, (uint32_t)(lhs ^ rhs)); return true; case OP_MIN: pushUint32(_stack, (uint32_t)min(lhs, rhs)); return true; case OP_MAX: pushUint32(_stack, (uint32_t)max(lhs, rhs)); return true; } return false; }
//------------------------------------------------------------------------------ // 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; } } }
v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engine) { quint32 header = popUint32(data); Type type = headertype(header); switch (type) { case WorkerUndefined: return v8::Undefined(); case WorkerNull: return v8::Null(); case WorkerTrue: return v8::True(); case WorkerFalse: return v8::False(); case WorkerString: { quint32 size = headersize(header); v8::Local<v8::String> string = v8::String::New((uint16_t*)data, size - 1); data += ALIGN(size * sizeof(uint16_t)); return string; } case WorkerFunction: Q_ASSERT(!"Unreachable"); break; case WorkerArray: { quint32 size = headersize(header); v8::Local<v8::Array> array = v8::Array::New(size); for (quint32 ii = 0; ii < size; ++ii) { array->Set(ii, deserialize(data, engine)); } return array; } case WorkerObject: { quint32 size = headersize(header); v8::Local<v8::Object> o = v8::Object::New(); for (quint32 ii = 0; ii < size; ++ii) { v8::Handle<v8::Value> name = deserialize(data, engine); v8::Handle<v8::Value> value = deserialize(data, engine); o->Set(name, value); } return o; } case WorkerInt32: return v8::Integer::New((qint32)popUint32(data)); case WorkerUint32: return v8::Integer::NewFromUnsigned(popUint32(data)); case WorkerNumber: return v8::Number::New(popDouble(data)); case WorkerDate: return v8::Date::New(popDouble(data)); case WorkerRegexp: { quint32 flags = headersize(header); quint32 length = popUint32(data); v8::Local<v8::String> source = v8::String::New((uint16_t*)data, length - 1); data += ALIGN(length * sizeof(uint16_t)); return v8::RegExp::New(source, (v8::RegExp::Flags)flags); } case WorkerListModel: { void *ptr = popPtr(data); QDeclarativeListModelWorkerAgent *agent = (QDeclarativeListModelWorkerAgent *)ptr; v8::Handle<v8::Value> rv = engine->newQObject(agent); if (rv->IsObject()) { QDeclarativeListModelWorkerAgent::VariantRef ref(agent); QVariant var = qVariantFromValue(ref); rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var)); } agent->release(); agent->setV8Engine(engine); return rv; } } Q_ASSERT(!"Unreachable"); return v8::Undefined(); }
void Babuino::configSerial() { union { uint8_t paramsByte; _SerialParams params; }; uint32_t baud; uint8_t port; popUint8(_stack, ¶msByte); #ifdef SUPPORT_32BIT popUint32(_stack, &baud); #else uint16_t baudBits; popUint16(_stack, &baudBits); // Low 16 bits baud = (uint32_t)baudBits; popUint16(_stack, &baudBits); // High 16 bits baud |= (baudBits << 16); #endif popUint8(_stack, &port); // Use a knowledge of the defines in HardwareSerial.h // to build the same numbers with our parameters. //uint8_t databits = (params >> 4) & 0x0F; //uint8_t parity = (params >> 2) & 0x03; //uint8_t stopbits = params & 0x03; uint8_t config = 0; // PARITY_NONE if (params.parity == PARITY_EVEN) config = 0x20; else if (params.parity == PARITY_ODD) config = 0x30; // Databits config += (params.databits - 5) << 1; //Stopbits if (params.stopbits == 2) config += 8; /* Serial.print("Baud: "); Serial.println(baud); Serial.print("Params as byte: "); Serial.println(paramsByte); Serial.print("Databits: "); Serial.println(params.databits); Serial.print("Parity: "); Serial.println(params.parity); Serial.print("Stopbits: "); Serial.println(params.stopbits); Serial.print("Params: "); Serial.println(config); */ if (port == 4) #ifdef Serial3 Serial3.begin(baud, config); #else beep(); #endif if (port == 3) #ifdef Serial2 Serial2.begin(baud, config); #else beep(); #endif if (port == 2) #ifdef Serial1 Serial1.begin(baud, config); #else beep(); #endif if (port == 1) #ifdef Serial Serial.begin(baud, config); #else beep(); #endif }