|
|
|
/***************************************************************************
|
|
|
|
* 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 <tqstring.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
|
|
|
|
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<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 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
|