diff options
Diffstat (limited to 'microbe/pic14.h')
-rw-r--r-- | microbe/pic14.h | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/microbe/pic14.h b/microbe/pic14.h new file mode 100644 index 0000000..5fd5a40 --- /dev/null +++ b/microbe/pic14.h @@ -0,0 +1,253 @@ +/*************************************************************************** + * Copyright (C) 2004-2005 by Daniel Clarke * + * [email protected] * + * * + * 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 <qstring.h> +#include <qstringlist.h> +#include <qvaluelist.h> + +class Code; +class Microbe; +class Parser; + +/** +@author David Saxton + */ +class PortPin +{ + public: + PortPin( const QString & port, int pin ); + /** + * Creates an invalid PortPin ( pin() will return -1). + */ + PortPin(); + /** + * Returns port (uppercase). + */ + QString 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: + QString m_port; + int m_pin; +}; +typedef QValueList<PortPin> 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 QString & text ); + /** + * @return the PIC type. + */ + Type type() const { return m_type; } + /** + * @return the Type as a string without the P at the front. + */ + QString 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 QString & 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 QStringList &interrupts ); + + /** + * @returns whether or not the port is valid. + * @see isValidPortPin + */ + bool isValidPort( const QString & 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 QString & trisName ) const; + bool isValidInterrupt( const QString & interruptName ) const; + + void Sgoto(const QString &label); + void Slabel(const QString &label); + void Send(); + void Ssubroutine(const QString &procName, Code * compiledProcCode); + void Sinterrupt(const QString & procName, Code * compiledProcCode); + void Scall(const QString &name); + + void Ssetlh( const PortPin & portPin, bool high); + + void add( QString val1, QString val2, LocationType val1Type, LocationType val2Type ); + void subtract( const QString & val1, const QString & val2, LocationType val1Type, LocationType val2Type ); + void mul( QString val1, QString val2, LocationType val1Type, LocationType val2Type); + void div( const QString & val1, const QString & val2, LocationType val1Type, LocationType val2Type); + + void assignNum(const QString & val); + void assignVar(const QString & val); + + void saveToReg(const QString &dest); + /** + * Move the contents of the working register to the register with the given + * name. + */ + void saveResultToVar( const QString & var ); + /** Code for "==" */ + void equal( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + /** Code for "!=" */ + void notEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + /** Code for ">" */ + void greaterThan( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + /** Code for "<" */ + void lessThan( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + /** Code for ">=" */ + void greaterOrEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + /** Code for "<=" */ + void lessOrEqual( const QString &val1, const QString &val2, LocationType val1Type, LocationType val2Type ); + + void bitwise( Expression::Operation op, const QString &val1, const QString &val2, bool val1IsNum, bool val2IsNum ); + + void Swhile( Code * whileCode, const QString &expression); + void Srepeat( Code * repeatCode, const QString &expression); + void Sif( Code * ifCode, Code * elseCode, const QString &expression); + void Sfor( Code * forCode, Code * initCode, const QString &expression, const QString &variable, const QString &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 QString &var ); + void SdecVar( const QString &var ); + void SrotlVar( const QString &var ); + void SrotrVar( const QString &var ); + + void Stristate( const QString &port ); + + void Sasm(const QString &raw); + + protected: + void multiply(); + void divide(); + + /** @see Microbe::m_picType */ + Type m_type; + + Parser * m_parser; + Microbe * mb; + Code * m_pCode; + + void ifInitCode( const QString &val1, const QString &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( QString * val1, QString * val2, LocationType * val1Type, LocationType * val2Type); + + /** + * @param flag True means give flag bit, false means give enable bit instead + */ + int interruptNameToBit(const QString &name, bool flag); +}; + +#endif |