summaryrefslogtreecommitdiffstats
path: root/microbe/pic14.h
blob: 5fd5a40095c2dd532db9789dfcfafaa7e1218f8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
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