void allocLocal(TypePtr typePtr) { if(typePtr == IntegerTypePtr) pushInteger(0); else if(typePtr == RealTypePtr) pushReal((float)0.0); else if(typePtr == BooleanTypePtr) pushByte(0); else if(typePtr == CharTypePtr) pushByte(0); else switch(typePtr->form) { case FRM_ENUM: pushInteger(0); break; // NOTE: We currently are not supporting sub ranges, until // we really want 'em... // case FRM_SUBRANGE: // allocLocal(typePtr->info.subrange.rangeTypePtr); // break; case FRM_ARRAY: PSTR ptr = (PSTR)ABLStackMallocCallback(typePtr->size); if(!ptr) ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc local array "); pushAddress((Address)ptr); break; } }
// Arbitrary-size push function unsigned int pushToBuffer(buffer_t *b, void *d, unsigned int l) { unsigned int elementIndex, byteIndex; // Loop through all elements for (elementIndex = 0; elementIndex < l; elementIndex++) { // Loop through all bytes of each element for (byteIndex = 0; byteIndex < b->width; byteIndex++) { // Only push to buffer if it is not full or overwriting is allowed if ( (!isBufferFull(b)) || (b->behavior.bits.overwrite) ) { pushByte(b, *( (unsigned char*)(d + elementIndex * (b->width) + byteIndex) )); } // If buffer is full, return a count of those elments not pushed else { // Pop all bytes of incomplete elements // -This should never run, but added just in case unsigned int failedbytes; for (failedbytes = byteIndex; failedbytes > 0; failedbytes--) { // If it is a queue pop comes from tail, so decrement head decrement(b, &(b->head)); } // Return a count of failed push operations // -Include partial pushes in count return l - elementIndex; } } } return 0; }
void LCD4Bit_mod::commandWrite(byte value) { digitalWrite(RS, LOW); if (USING_RW) { digitalWrite(RW, LOW); } pushByte(value); //TODO: perhaps better to add a delay after EVERY command, here. many need a delay, apparently. }
//print the given character at the current cursor position. overwrites, doesn't insert. void LCD4Bit_mod::print(int value) { //set the RS and RW pins to show we're writing data digitalWrite(RS, HIGH); if (USING_RW) { digitalWrite(RW, LOW); } //let pushByte worry about the intricacies of Enable, nibble order. pushByte(value); }
static void dataWrite(int value) { digitalWrite(RS_PORT, RS_BIT, 1); #if USING_RW != 0 if (USING_RW) { digitalWrite(RW_PORT, RW_BIT, 0); } #endif pushByte(value); }
void LCD4Bit_mod::home(){ clrbits(CONTROL_PORT, CONTROL_RS); #ifdef USING_RW clrbits(CONTROL_PORT, CONTROL_RW); #endif pushByte(CMD_HOME); delayMicroseconds(1640); // 1.64ms }
void LCD4Bit_mod::commandWrite(uint8_t value) { clrbits(CONTROL_PORT, CONTROL_RS); #ifdef USING_RW clrbits(CONTROL_PORT, CONTROL_RW); #endif pushByte(value); delayMicroseconds(40); // commands need > 37us to settle }
static void commandWrite(int value) { digitalWrite(RS_PORT, RS_BIT, 0); #if USING_RW != 0 if (USING_RW) { digitalWrite(RW_PORT, RW_BIT, 0); } #endif pushByte(value); //Remark: some commands needs additional delay! }
//print the given character at the current cursor position. overwrites, doesn't insert. void LCD4Bit_mod::print(uint8_t value) { //set the RS and RW pins to show we're writing data setbits(CONTROL_PORT, CONTROL_RS);//digitalWrite(RS, HIGH); #ifdef USING_RW clrbits(CONTROL_PORT, CONTROL_RW);//digitalWrite(RW, LOW); #endif //let pushByte worry about the intricacies of Enable, nibble order. pushByte(value); delayMicroseconds(40); // commands need > 37us to settle }
//print the given character at the current cursor position. overwrites, doesn't insert. size_t LCD4Bit_mod::write(uint8_t c) { //set the RS and RW pins to show we're writing data digitalWrite(RS, HIGH); if (USING_RW) { digitalWrite(RW, LOW); } //let pushByte worry about the intricacies of Enable, nibble order. pushByte(c); return 1; }
//print the given string to the LCD at the current cursor position. overwrites, doesn't insert. //While I don't understand why this was named printIn (PRINT IN?) in the original LiquidCrystal library, I've preserved it here to maintain the interchangeability of the two libraries. void LCD4Bit_mod::printIn(const char* msg) { setbits(CONTROL_PORT, CONTROL_RS);//digitalWrite(RS, HIGH); #ifdef USING_RW clrbits(CONTROL_PORT, CONTROL_RW);//digitalWrite(RW, LOW); #endif uint8_t i; //fancy int. avoids compiler warning when comparing i with strlen()'s uint8_t uint8_t len = strlen(msg); for (i=0;i < len ;i++){ //let pushByte worry about the intricacies of Enable, nibble order. pushByte(msg[i]); delayMicroseconds(40); // commands need > 37us to settle } }
void interpretLoad(Instruction* ins) { switch(ins->argSize) { case 1: pushByte(readByte(popDword())); break; case 2: pushWord(readWord(popDword())); break; case 4: pushDword(readDword(popDword())); break; case 8: pushQword(readQword(popDword())); break; } }
void interpretConv(Instruction* ins) { switch(ins->opcode) { case CONVB_D: pushDword((uint32_t)popByte()); break; case CONVD_B: pushByte((uint8_t)popDword()); break; case CONVD_W: pushWord((uint16_t)popDword()); break; case CONVQ_D: pushQword((uint64_t)popDword()); break; case CONVD_Q: pushDword((uint32_t)popQword()); break; } }
// Arbitrary-size pop function unsigned int popFromBuffer(buffer_t *b, void *d, unsigned int l){ unsigned int elementIndex, byteIndex; for (elementIndex = 0; elementIndex < l; elementIndex++) { for (byteIndex = 0; byteIndex < b->width; byteIndex++) { if (!isBufferEmpty(b)){ // Stacks swap bytes of multi-byte elements, so swap back // on pop operation if (b->behavior.bits.stack){ *( (unsigned char*)(d + ((elementIndex + 1) * b->width) - 1 - byteIndex) ) = popByte(b); } // Queue does not swap bytes, so no need to swap on pop else { *( (unsigned char*)(d + (elementIndex * b->width) + byteIndex) ) = popByte(b); } } else { // Push any bytes back to buffer that form an incomplete element // -Ideally this should never run, but added just in case unsigned int failedbytes; for (failedbytes=byteIndex; failedbytes > 0; failedbytes--){ // Careful not to swap bytes here... pushByte(b, *( (unsigned char*)(d + elementIndex * b->width + failedbytes ) )); } // Return a count of failed pop operations // -Include partial pops in counter return l - elementIndex; } } } return 0; }
static void dataWrite(int value) { digitalWrite(RS_PORT, RS_BIT, 1); pushByte(value); }
static void commandWrite(int value) { digitalWrite(RS_PORT, RS_BIT, 0); pushByte(value); //Remark: some commands needs additional delay! }
TypePtr execFactor(void) { TypePtr resultTypePtr = nullptr; switch (codeToken) { case TKN_IDENTIFIER: { SymTableNodePtr idPtr = getCodeSymTableNodePtr(); if (idPtr->defn.key == DFN_FUNCTION) { SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr; resultTypePtr = execRoutineCall(idPtr, false); CurRoutineIdPtr = thisRoutineIdPtr; } else if (idPtr->defn.key == DFN_CONST) resultTypePtr = execConstant(idPtr); else resultTypePtr = execVariable(idPtr, USE_EXPR); } break; case TKN_NUMBER: { SymTableNodePtr numberPtr = getCodeSymTableNodePtr(); if (numberPtr->typePtr == IntegerTypePtr) { pushInteger(numberPtr->defn.info.constant.value.integer); resultTypePtr = IntegerTypePtr; } else { pushReal(numberPtr->defn.info.constant.value.real); resultTypePtr = RealTypePtr; } getCodeToken(); } break; case TKN_STRING: { SymTableNodePtr nodePtr = getCodeSymTableNodePtr(); int32_t length = strlen(nodePtr->name); if (length > 1) { //----------------------------------------------------------------------- // Remember, the double quotes are on the back and front of the // string... pushAddress(nodePtr->info); resultTypePtr = nodePtr->typePtr; } else { //---------------------------------------------- // Just push the one character in this string... pushByte(nodePtr->name[0]); resultTypePtr = CharTypePtr; } getCodeToken(); } break; case TKN_NOT: getCodeToken(); resultTypePtr = execFactor(); //-------------------------------------- // Following flips 1 to 0, and 0 to 1... tos->integer = 1 - tos->integer; break; case TKN_LPAREN: getCodeToken(); resultTypePtr = execExpression(); getCodeToken(); break; } return (resultTypePtr); }