/*************************************************************************** * Copyright (C) 2004-2005 by Daniel Clarke * * daniel.jc@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #ifndef PIC14_H #define PIC14_H #include "expression.h" #include "microbe.h" #include #include #include class Code; class Microbe; class Parser; /** @author David Saxton */ class PortPin { public: PortPin( const TQString & port, int pin ); /** * Creates an invalid PortPin ( pin() will return -1). */ PortPin(); /** * Returns port (uppercase). */ TQString port() const { return m_port; } /** * Returns the port position (e.g. "PORTA" is 0, "PORTB" is 1, etc). */ int portPosition() const; /** * Returns the pin (-1 == invalid PortPin). */ int pin() const { return m_pin; } protected: TQString m_port; int m_pin; }; typedef TQValueList PortPinList; /** @author Daniel Clarke @author David Saxton */ class PIC14 { public: enum Type { P16C84, P16F84, P16F627, P16F628, unknown, }; enum LocationType { num = 1, work = 2, var = 3, }; /** * Used in determining which delay subroutine should be created. */ enum DelaySubroutine { Delay_None = 0, Delay_3uS = 1, Delay_768uS = 2, Delay_200mS = 3, Delay_50S = 4, }; PIC14( Microbe * master, Type type ); ~PIC14(); /** * Tries to convert the string to a PIC type, returning unknown if * unsuccessful. */ static Type toType( const TQString & text ); /** * @return the PIC type. */ Type type() const { return m_type; } /** * @return the Type as a string without the P at the front. */ TQString minimalTypeString() const; /** * Translates the portPinString (e.g. "PORTA.2") into a PortPin if the port * and pin combination is valid (otherwise returns an invalid PortPin with * a pin of -1. */ PortPin toPortPin( const TQString & portPinString ); /** * Returns the address that the General Purpose Registers starts at. */ uchar gprStart() const; void setParser(Parser *parser) { m_parser = parser; } void setCode( Code * code ) { m_pCode = code; } void mergeCode( Code * code ); void setConditionalCode( Code * ifCode, Code * elseCode ); Code * ifCode(); Code * elseCode(); Code * m_ifCode; Code * m_elseCode; void postCompileConstruct( const TQStringList &interrupts ); /** * @returns whether or not the port is valid. * @see isValidPortPin */ bool isValidPort( const TQString & portName ) const; /** * @returns whether or not the port and pin is a valid combination. * @see isValidPort */ bool isValidPortPin( const PortPin & portPin ) const; bool isValidTris( const TQString & trisName ) const; bool isValidInterrupt( const TQString & interruptName ) const; void Sgoto(const TQString &label); void Slabel(const TQString &label); void Send(); void Ssubroutine(const TQString &procName, Code * compiledProcCode); void Sinterrupt(const TQString & procName, Code * compiledProcCode); void Scall(const TQString &name); void Ssetlh( const PortPin & portPin, bool high); void add( TQString val1, TQString val2, LocationType val1Type, LocationType val2Type ); void subtract( const TQString & val1, const TQString & val2, LocationType val1Type, LocationType val2Type ); void mul( TQString val1, TQString val2, LocationType val1Type, LocationType val2Type); void div( const TQString & val1, const TQString & val2, LocationType val1Type, LocationType val2Type); void assignNum(const TQString & val); void assignVar(const TQString & val); void saveToReg(const TQString &dest); /** * Move the contents of the working register to the register with the given * name. */ void saveResultToVar( const TQString & var ); /** Code for "==" */ void equal( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** Code for "!=" */ void notEqual( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** Code for ">" */ void greaterThan( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** Code for "<" */ void lessThan( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** Code for ">=" */ void greaterOrEqual( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** Code for "<=" */ void lessOrEqual( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); void bitwise( Expression::Operation op, const TQString &val1, const TQString &val2, bool val1IsNum, bool val2IsNum ); void Swhile( Code * whileCode, const TQString &expression); void Srepeat( Code * repeatCode, const TQString &expression); void Sif( Code * ifCode, Code * elseCode, const TQString &expression); void Sfor( Code * forCode, Code * initCode, const TQString &expression, const TQString &variable, const TQString &step, bool stepPositive); void Spin( const PortPin & portPin, bool NOT); void addCommonFunctions( DelaySubroutine delay ); //BEGIN "Special Functionality" functions /** * Delay the program execution, for the given period of length_us (unit: * microseconds). * @param pos the position to add the code for calling the delay subroutine. */ void Sdelay( unsigned length_us, Code::InstructionPosition pos = Code::Middle ); /** * Output the working register to the given seven segment. * @param name The variable giving the pin configuration of the seven * segment. */ void SsevenSegment( const Variable & pinMap ); /** * Read the value of the keypad to the working register. * @param name The variable giving the pin configuration of the keypad. */ void Skeypad( const Variable & pinMap ); //END "Special Functionality" functions void SincVar( const TQString &var ); void SdecVar( const TQString &var ); void SrotlVar( const TQString &var ); void SrotrVar( const TQString &var ); void Stristate( const TQString &port ); void Sasm(const TQString &raw); protected: void multiply(); void divide(); /** @see Microbe::m_picType */ Type m_type; Parser * m_parser; Microbe * mb; Code * m_pCode; void ifInitCode( const TQString &val1, const TQString &val2, LocationType val1Type, LocationType val2Type ); /** * The function makes sure that val1 always contains a working register * variable, if one has been passed, this is done by swapping val1 and val2 when * neccessary */ void rearrangeOpArguments( TQString * val1, TQString * val2, LocationType * val1Type, LocationType * val2Type); /** * @param flag True means give flag bit, false means give enable bit instead */ int interruptNameToBit(const TQString &name, bool flag); }; #endif