1 /*
2 Copyright (C) 1998 T. Scott Dattalo
3
4 This file is part of the libgpsim library of gpsim
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 */
20
21 #include <stdio.h>
22 #ifdef _WIN32
23 #include "uxtime.h"
24 #include "unistd.h"
25 #else
26 #include <unistd.h>
27 #endif
28 #ifndef _MSC_VER
29 #include <sys/time.h>
30 #endif
31 #include <time.h>
32 #include <iostream>
33 #include <iomanip>
34 #include <string>
35 #include <utility>
36
37 #include "../config.h"
38
39 #include "exports.h"
40 #include "pic-processor.h"
41 #include "pic-registers.h"
42 #include "gpsim_interface.h"
43 #include "gpsim_time.h"
44 #include "interface.h"
45 #include "ioports.h"
46 #include "modules.h"
47 #include "p16x5x.h"
48 #include "p16f62x.h"
49 #include "p16f8x.h"
50 #include "p16f88x.h"
51 #include "p16x8x.h"
52 #include "p16f87x.h"
53 #include "p16x6x.h"
54 #include "p16x7x.h"
55 #include "p16f91x.h"
56 #include "p12x.h"
57 #include "p12f6xx.h"
58 #include "p1xf1xxx.h"
59 #ifdef P17C7XX // code no longer works
60 #include "p17c75x.h"
61 #endif
62 #include "p18x.h"
63 #include "p18fk.h"
64 #include "icd.h"
65
66 #include "pic-ioports.h"
67 #include "program_files.h"
68 #include "stimuli.h"
69 #include "trace.h"
70 #include "ui.h"
71
72 guint64 simulation_start_cycle;
73
74 #include "cod.h"
75
76
77 #include "clock_phase.h"
78
79
80
81 //================================================================================
82 //
83 // pic_processor
84 //
85 // This file contains all (most?) of the code that simulates those features
86 // common to all pic microcontrollers.
87 //
88 //
89
90 ProcessorConstructor pP10F200(P10F200::construct,
91 "__10F200", "pic10f200", "p10f200", "10f200");
92 ProcessorConstructor pP10F202(P10F202::construct,
93 "__10F202", "pic10f202", "p10f202", "10f202");
94 ProcessorConstructor pP10F204(P10F204::construct,
95 "__10F204", "pic10f204", "p10f204", "10f204");
96 ProcessorConstructor pP10F220(P10F220::construct,
97 "__10F220", "pic10f220", "p10f220", "10f220");
98 ProcessorConstructor pP10F222(P10F222::construct,
99 "__10F222", "pic10f222", "p10f222", "10f222");
100 ProcessorConstructor pP10F320(P10F320::construct,
101 "__10F320", "pic10f320", "p10f320", "10f320");
102 ProcessorConstructor pP10LF320(P10LF320::construct,
103 "__10LF320", "pic10lf320", "p10lf320", "10lf320");
104 ProcessorConstructor pP10F322(P10F322::construct,
105 "__10F322", "pic10f322", "p10f322", "10f322");
106 ProcessorConstructor pP10LF322(P10LF322::construct,
107 "__10LF322", "pic10lf322", "p10lf322", "10lf322");
108 ProcessorConstructor pP12C508(P12C508::construct,
109 "__12C508", "pic12c508", "p12c508", "12c508");
110 ProcessorConstructor pP12C509(P12C509::construct,
111 "__12C509", "pic12c509", "p12c509", "12c509");
112 ProcessorConstructor pP12CE518(P12CE518::construct,
113 "__12ce518", "pic12ce518", "p12ce518", "12ce518");
114 ProcessorConstructor pP12CE519(P12CE519::construct,
115 "__12ce519", "pic12ce519", "p12ce519", "12ce519");
116 ProcessorConstructor pP12F508(P12F508::construct,
117 "__12F508", "pic12f508", "p12f508", "12f508");
118 ProcessorConstructor pP12F509(P12F509::construct,
119 "__12F509", "pic12f509", "p12f509", "12f509");
120 ProcessorConstructor pP12F510(P12F510::construct,
121 "__12F510", "pic12f510", "p12f510", "12f510");
122 ProcessorConstructor pP12F629(P12F629::construct,
123 "__12F629", "pic12f629", "p12f629", "12f629");
124 ProcessorConstructor pP12F675(P12F675::construct,
125 "__12F675", "pic12f675", "p12f675", "12f675");
126 ProcessorConstructor pP12F683(P12F683::construct,
127 "__12F683", "pic12f683", "p12f683", "12f683");
128 ProcessorConstructor pP12F1822(P12F1822::construct,
129 "__12F1822", "pic12f1822", "p12f1822", "12f1822");
130 ProcessorConstructor pP12LF1822(P12LF1822::construct,
131 "__12LF1822", "pic12lf1822", "p12lf1822", "12lf1822");
132 ProcessorConstructor pP12F1840(P12F1840::construct,
133 "__12F1840", "pic12f1840", "p12f1840", "12f1840");
134 ProcessorConstructor pP12LF1840(P12LF1840::construct,
135 "__12LF1840", "pic12lf1840", "p12lf1840", "12lf1840");
136 ProcessorConstructor pP16C54(P16C54::construct,
137 "__16C54", "pic16c54", "p16c54", "16c54");
138 ProcessorConstructor pP16C55(P16C55::construct,
139 "__16C55", "pic16c55", "p16c55", "16c55");
140 ProcessorConstructor pP16C56(P16C56::construct,
141 "__16C56", "pic16c56", "p16c56", "16c56");
142 ProcessorConstructor pP16C61(P16C61::construct,
143 "__16C61", "pic16c61", "p16c61", "16c61");
144 ProcessorConstructor pP16C62(P16C62::construct,
145 "__16C62", "pic16c62", "p16c62", "16c62");
146 ProcessorConstructor pP16C62A(P16C62::construct,
147 "__16C62A", "pic16c62a", "p16c62a", "16c62a");
148 ProcessorConstructor pP16CR62(P16C62::construct,
149 "__16CR62", "pic16cr62", "p16cr62", "16cr62");
150 ProcessorConstructor pP16C63(P16C63::construct,
151 "__16C63", "pic16c63", "p16c63", "16c63");
152 ProcessorConstructor pP16C64(P16C64::construct,
153 "__16C64", "pic16c64", "p16c64", "16c64");
154 ProcessorConstructor pP16C65(P16C65::construct,
155 "__16C65", "pic16c65", "p16c65", "16c65");
156 ProcessorConstructor pP16C65A(P16C65::construct,
157 "__16C65A", "pic16c65a", "p16c65a", "16c65a");
158 ProcessorConstructor pP16C71(P16C71::construct,
159 "__16C71", "pic16c71", "p16c71", "16c71");
160 ProcessorConstructor pP16C712(P16C712::construct,
161 "__16C712", "pic16c712", "p16c712", "16c712");
162 ProcessorConstructor pP16C716(P16C716::construct,
163 "__16C716", "pic16c716", "p16c716", "16c716");
164 ProcessorConstructor pP16C72(P16C72::construct,
165 "__16C72", "pic16c72", "p16c72", "16c72");
166 ProcessorConstructor pP16C73(P16C73::construct,
167 "__16C73", "pic16c73", "p16c73", "16c73");
168 ProcessorConstructor pP16C74(P16C74::construct,
169 "__16C74", "pic16c74", "p16c74", "16c74");
170 ProcessorConstructor pP16C84(P16C84::construct,
171 "__16C84", "pic16c84", "p16c84", "16c84");
172 ProcessorConstructor pP16CR83(P16CR83::construct,
173 "__16CR83", "pic16cr83", "p16cr83", "16cr83");
174 ProcessorConstructor pP16CR84(P16CR84::construct,
175 "__16CR84", "pic16cr84", "p16cr84", "16cr84");
176 ProcessorConstructor pP16F505(P16F505::construct,
177 "__16F505", "pic16f505", "p16f505", "16f505");
178 ProcessorConstructor pP16F73(P16F73::construct,
179 "__16F73", "pic16f73", "p16f73", "16f73");
180 ProcessorConstructor pP16F74(P16F74::construct,
181 "__16F74", "pic16f74", "p16f74", "16f74");
182 ProcessorConstructor pP16F716(P16F716::construct,
183 "__16F716", "pic16f716", "p16f716", "16f716");
184 ProcessorConstructor pP16F83(P16F83::construct,
185 "__16F83", "pic16f83", "p16f83", "16f83");
186 ProcessorConstructor pP16F84(P16F84::construct,
187 "__16F84", "pic16f84", "p16f84", "16f84");
188 ProcessorConstructor pP16F87(P16F87::construct,
189 "__16F87", "pic16f87", "p16f87", "16f87");
190 ProcessorConstructor pP16F88(P16F88::construct,
191 "__16F88", "pic16f88", "p16f88", "16f88");
192 ProcessorConstructor pP16F882(P16F882::construct,
193 "__16F882", "pic16f882", "p16f882", "16f882");
194 ProcessorConstructor pP16F883(P16F883::construct,
195 "__16F883", "pic16f883", "p16f883", "16f883");
196 ProcessorConstructor pP16F884(P16F884::construct,
197 "__16F884", "pic16f884", "p16f884", "16f884");
198 ProcessorConstructor pP16F886(P16F886::construct,
199 "__16F886", "pic16f886", "p16f886", "16f886");
200 ProcessorConstructor pP16F887(P16F887::construct,
201 "__16F887", "pic16f887", "p16f887", "16f887");
202 ProcessorConstructor pP16F627(P16F627::construct,
203 "__16F627", "pic16f627", "p16f627", "16f627");
204 ProcessorConstructor pP16F627A(P16F627::construct,
205 "__16F627A", "pic16f627a", "p16f627a", "16f627a");
206 ProcessorConstructor pP16F628(P16F628::construct,
207 "__16F628", "pic16f628", "p16f628", "16f628");
208 ProcessorConstructor pP16F628A(P16F628::construct,
209 "__16F628A", "pic16f628a", "p16f628a", "16f628a");
210 ProcessorConstructor pP16F630(P16F630::construct,
211 "__16F630", "pic16f630", "p16f630", "16f630");
212 ProcessorConstructor pP16F631(P16F631::construct,
213 "__16F631", "pic16f631", "p16f631", "16f631");
214 ProcessorConstructor pP16F648(P16F648::construct,
215 "__16F648", "pic16f648", "p16f648", "16f648");
216 ProcessorConstructor pP16F648A(P16F648::construct,
217 "__16F648A", "pic16f648a", "p16f648a", "16f648a");
218 ProcessorConstructor pP16F676(P16F676::construct,
219 "__16F676", "pic16f676", "p16f676", "16f676");
220 ProcessorConstructor pP16F677(P16F677::construct,
221 "__16F677", "pic16f677", "p16f677", "16f677");
222 ProcessorConstructor pP16F684(P16F684::construct,
223 "__16F684", "pic16f684", "p16f684", "16f684");
224 ProcessorConstructor pP16F685(P16F685::construct,
225 "__16F685", "pic16f685", "p16f685", "16f685");
226 ProcessorConstructor pP16F687(P16F687::construct,
227 "__16F687", "pic16f687", "p16f687", "16f687");
228 ProcessorConstructor pP16F689(P16F689::construct,
229 "__16F689", "pic16f689", "p16f689", "16f689");
230 ProcessorConstructor pP16F690(P16F690::construct,
231 "__16F690", "pic16f690", "p16f690", "16f690");
232 ProcessorConstructor pP16F818(P16F818::construct,
233 "__16F818", "pic16f818", "p16f818", "16f818");
234 ProcessorConstructor pP16F819(P16F819::construct,
235 "__16F819", "pic16f819", "p16f819", "16f819");
236 ProcessorConstructor pP16F871(P16F871::construct,
237 "__16F871", "pic16f871", "p16f871", "16f871");
238 ProcessorConstructor pP16F873(P16F873::construct,
239 "__16F873", "pic16f873", "p16f873", "16f873");
240 ProcessorConstructor pP16F874(P16F874::construct,
241 "__16F874", "pic16f874", "p16f874", "16f874");
242 ProcessorConstructor pP16F876(P16F876::construct,
243 "__16F876", "pic16f876", "p16f876", "16f876");
244 ProcessorConstructor pP16F877(P16F877::construct,
245 "__16F877", "pic16f877", "p16f877", "16f877");
246 ProcessorConstructor pP16F873A(P16F873A::construct,
247 "__16F873a", "pic16f873a", "p16f873a", "16f873a");
248 ProcessorConstructor pP16F874A(P16F874A::construct,
249 "__16F874a", "pic16f874a", "p16f874a", "16f874a");
250 ProcessorConstructor pP16F876A(P16F876A::construct,
251 "__16F876a", "pic16f876a", "p16f876a", "16f876a");
252 ProcessorConstructor pP16F877A(P16F877A::construct,
253 "__16F877a", "pic16f877a", "p16f877a", "16f877a");
254 ProcessorConstructor pP16F913(P16F913::construct,
255 "__16F913", "pic16f913", "p16f913", "16f913");
256 ProcessorConstructor pP16F914(P16F914::construct,
257 "__16F914", "pic16f914", "p16f914", "16f914");
258 ProcessorConstructor pP16F916(P16F916::construct,
259 "__16F916", "pic16f916", "p16f916", "16f916");
260 ProcessorConstructor pP16F917(P16F917::construct,
261 "__16F917", "pic16f917", "p16f917", "16f917");
262 ProcessorConstructor pP16F1503(P16F1503::construct,
263 "__16F1503", "pic16f1503", "p16f1503", "16f1503");
264 ProcessorConstructor pP16LF1503(P16LF1503::construct,
265 "__16LF1503", "pic16lf1503", "p16lf1503", "16lf1503");
266 ProcessorConstructor pP16F1705(P16F1705::construct,
267 "__16F1705", "pic16f1705", "p16f1705", "16f1705");
268 ProcessorConstructor pP16LF1705(P16LF1705::construct,
269 "__16LF1705", "pic16lf1705", "p16lf1705", "16lf1705");
270 ProcessorConstructor pP16F1709(P16F1709::construct,
271 "__16F1709", "pic16f1709", "p16f1709", "16f1709");
272 ProcessorConstructor pP16LF1709(P16LF1709::construct,
273 "__16LF1709", "pic16lf1709", "p16lf1709", "16lf1709");
274 ProcessorConstructor pP16F1788(P16F1788::construct,
275 "__16F1788", "pic16f1788", "p16f1788", "16f1788");
276 ProcessorConstructor pP16LF1788(P16LF1788::construct,
277 "__16LF1788", "pic16lf1788", "p16lf1788", "16lf1788");
278 ProcessorConstructor pP16F1823(P16F1823::construct,
279 "__16F1823", "pic16f1823", "p16f1823", "16f1823");
280 ProcessorConstructor pP16LF1823(P16LF1823::construct,
281 "__16LF1823", "pic16lf1823", "p16lf1823", "16lf1823");
282 ProcessorConstructor pP16F1825(P16F1825::construct,
283 "__16F1825", "pic16f1825", "p16f1825", "16f1825");
284 ProcessorConstructor pP16LF1825(P16F1825::construct,
285 "__16LF1825", "pic16lf1825", "p16lf1825", "16lf1825");
286 #ifdef P17C7XX // code no longer works
287 ProcessorConstructor pP17C7xx(P17C7xx::construct,
288 "__17C7xx", "pic17c7xx", "p17c7xx", "17c7xx");
289 ProcessorConstructor pP17C75x(P17C75x::construct,
290 "__17C75x", "pic17c75x", "p17c75x", "17c75x");
291 ProcessorConstructor pP17C752(P17C752::construct,
292 "__17C752", "pic17c752", "p17c752", "17c752");
293 ProcessorConstructor pP17C756(P17C756::construct,
294 "__17C756", "pic17c756", "p17c756", "17c756");
295 ProcessorConstructor pP17C756A(P17C756A::construct,
296 "__17C756A", "pic17c756a", "p17c756a", "17c756a");
297 ProcessorConstructor pP17C762(P17C762::construct,
298 "__17C762", "pic17c762", "p17c762", "17c762");
299 ProcessorConstructor pP17C766(P17C766::construct,
300 "__17C766", "pic17c766", "p17c766", "17c766");
301 #endif // P17C7XX
302 ProcessorConstructor pP18C242(P18C242::construct,
303 "__18C242", "pic18c242", "p18c242", "18c242");
304 ProcessorConstructor pP18C252(P18C252::construct,
305 "__18C252", "pic18c252", "p18c252", "18c252");
306 ProcessorConstructor pP18C442(P18C442::construct,
307 "__18C442", "pic18c442", "p18c442", "18c442");
308 ProcessorConstructor pP18C452(P18C452::construct,
309 "__18C452", "pic18c452", "p18c452", "18c452");
310 ProcessorConstructor pP18F242(P18F242::construct,
311 "__18F242", "pic18f242", "p18f242", "18f242");
312 ProcessorConstructor pP18F248(P18F248::construct,
313 "__18F248", "pic18f248", "p18f248", "18f248");
314 ProcessorConstructor pP18F258(P18F258::construct,
315 "__18F258", "pic18f258", "p18f258", "18f258");
316 ProcessorConstructor pP18F252(P18F252::construct,
317 "__18F252", "pic18f252", "p18f252", "18f252");
318 ProcessorConstructor pP18F442(P18F442::construct,
319 "__18F442", "pic18f442", "p18f442", "18f442");
320 ProcessorConstructor pP18F448(P18F448::construct,
321 "__18F448", "pic18f448", "p18f448", "18f448");
322 ProcessorConstructor pP18F458(P18F458::construct,
323 "__18F458", "pic18f458", "p18f458", "18f458");
324 ProcessorConstructor pP18F452(P18F452::construct,
325 "__18F452", "pic18f452", "p18f452", "18f452");
326 ProcessorConstructor pP18F1220(P18F1220::construct,
327 "__18F1220", "pic18f1220", "p18f1220", "18f1220");
328 ProcessorConstructor pP18F1320(P18F1320::construct,
329 "__18F1320", "pic18f1320", "p18f1320", "18f1320");
330 ProcessorConstructor pP18F14K22(P18F14K22::construct,
331 "__18F14K22", "pic18f14k22", "p18f14k22", "18f14k22");
332 ProcessorConstructor pP18F2221(P18F2221::construct,
333 "__18F2221", "pic18f2221", "p18f2221", "18f2221");
334 ProcessorConstructor pP18F2321(P18F2321::construct,
335 "__18F2321", "pic18f2321", "p18f2321", "18f2321");
336 ProcessorConstructor pP18F2420(P18F2420::construct,
337 "__18F2420", "pic18f2420", "p18f2420", "18f2420");
338 ProcessorConstructor pP18F2455(P18F2455::construct,
339 "__18F2455", "pic18f2455", "p18f2455", "18f2455");
340 ProcessorConstructor pP18F2520(P18F2520::construct,
341 "__18F2520", "pic18f2520", "p18f2520", "18f2520");
342 ProcessorConstructor pP18F2525(P18F2525::construct,
343 "__18F2525", "pic18f2525", "p18f2525", "18f2525");
344 ProcessorConstructor pP18F2550(P18F2550::construct,
345 "__18F2550", "pic18f2550", "p18f2550", "18f2550");
346 ProcessorConstructor pP18F2620(P18F2620::construct,
347 "__18F2620", "pic18f2620", "p18f2620", "18f2620");
348 ProcessorConstructor pP18F26K22(P18F26K22::construct,
349 "__18F26K22", "pic18f26k22", "p18f26k22", "18f26k22");
350 ProcessorConstructor pP18F4221(P18F4221::construct,
351 "__18F4221", "pic18f4221", "p18f4221", "18f4221");
352 ProcessorConstructor pP18F4321(P18F4321::construct,
353 "__18F4321", "pic18f4321", "p18f4321", "18f4321");
354 ProcessorConstructor pP18F4420(P18F4420::construct,
355 "__18F4420", "pic18f4420", "p18f4420", "18f4420");
356 ProcessorConstructor pP18F4520(P18F4520::construct,
357 "__18F4520", "pic18f4520", "p18f4520", "18f4520");
358 ProcessorConstructor pP18F4550(P18F4550::construct,
359 "__18F4550", "pic18f4550", "p18f4550", "18f4550");
360 ProcessorConstructor pP18F4455(P18F4455::construct,
361 "__18F4455", "pic18f4455", "p18f4455", "18f4455");
362 ProcessorConstructor pP18F4620(P18F4620::construct,
363 "__18F4620", "pic18f4620", "p18f4620", "18f4620");
364 ProcessorConstructor pP18F6520(P18F6520::construct,
365 "__18F6520", "pic18f6520", "p18f6520", "18f6520");
366
367
368 //========================================================================
369 // Trace Type for Resets
370
371 class InterruptTraceObject : public ProcessorTraceObject
372 {
373 public:
374 explicit InterruptTraceObject(Processor *_cpu);
375 virtual void print(FILE *fp);
376 };
377
378
379 class InterruptTraceType : public ProcessorTraceType
380 {
381 public:
382 explicit InterruptTraceType(Processor *_cpu);
383 TraceObject *decode(unsigned int tbi);
384 void record();
385 int dump_raw(Trace *pTrace, unsigned int tbi, char *buf, int bufsize);
386
387 unsigned int m_uiTT;
388 };
389
390
391 //------------------------------------------------------------
InterruptTraceObject(Processor * _cpu)392 InterruptTraceObject::InterruptTraceObject(Processor *_cpu)
393 : ProcessorTraceObject(_cpu)
394 {
395 }
396
397
print(FILE * fp)398 void InterruptTraceObject::print(FILE *fp)
399 {
400 fprintf(fp, " %s *** Interrupt ***\n",
401 (cpu ? cpu->name().c_str() : ""));
402 }
403
404
405 //------------------------------------------------------------
InterruptTraceType(Processor * _cpu)406 InterruptTraceType::InterruptTraceType(Processor *_cpu)
407 : ProcessorTraceType(_cpu, 1, "Interrupt")
408 {
409 m_uiTT = trace.allocateTraceType(this);
410 }
411
412
decode(unsigned int)413 TraceObject *InterruptTraceType::decode(unsigned int /* tbi */ )
414 {
415 //unsigned int tv = trace.get(tbi);
416 return new InterruptTraceObject(cpu);
417 }
418
419
record()420 void InterruptTraceType::record()
421 {
422 trace.raw(m_uiTT);
423 }
424
425
dump_raw(Trace * pTrace,unsigned int tbi,char * buf,int bufsize)426 int InterruptTraceType::dump_raw(Trace *pTrace, unsigned int tbi, char *buf, int bufsize)
427 {
428 if (!pTrace)
429 {
430 return 0;
431 }
432
433 int n = TraceType::dump_raw(pTrace, tbi, buf, bufsize);
434 buf += n;
435 bufsize -= n;
436 int m = snprintf(buf, bufsize,
437 " %s *** Interrupt ***",
438 (cpu ? cpu->name().c_str() : ""));
439 return m > 0 ? (m + n) : n;
440 }
441
442
443 //-------------------------------------------------------------------
set_eeprom(EEPROM * e)444 void pic_processor::set_eeprom(EEPROM *e)
445 {
446 eeprom = e;
447
448 if (e)
449 {
450 ema.set_Registers(e->rom, e->rom_size);
451 }
452 }
453
454
455 //-------------------------------------------------------------------
BP_set_interrupt()456 void pic_processor::BP_set_interrupt()
457 {
458 m_pInterruptTT->record();
459 mCaptureInterrupt->firstHalf();
460 }
461
462
463 //-------------------------------------------------------------------
464 //
465 // sleep - Begin sleeping and stay asleep until something causes a wake
466 //
467
sleep()468 void pic_processor::sleep()
469 {
470 }
471
472
473 //-------------------------------------------------------------------
474 //
475 // enter_sleep - The processor is about to go to sleep, so update
476 // the status register.
477
enter_sleep()478 void pic_processor::enter_sleep()
479 {
480 status->put_TO(1);
481 status->put_PD(0);
482 sleep_time = get_cycles().get();
483 wdt.update();
484 pc->increment();
485 save_pNextPhase = mCurrentPhase->getNextPhase();
486 save_CurrentPhase = mCurrentPhase;
487 mCurrentPhase->setNextPhase(mIdle);
488 mCurrentPhase = mIdle;
489 mCurrentPhase->setNextPhase(mIdle);
490 m_ActivityState = ePASleeping;
491 }
492
493
494 //-------------------------------------------------------------------
495 //
496 // exit_sleep
497
exit_sleep()498 void pic_processor::exit_sleep()
499 {
500 // If enter and exit sleep at same clock cycle, restore execute state
501 if (get_cycles().get() == sleep_time)
502 {
503 mCurrentPhase = save_CurrentPhase;
504 mCurrentPhase->setNextPhase(save_pNextPhase);
505
506 }
507 else
508 {
509 mCurrentPhase->setNextPhase(mExecute1Cycle);
510 }
511
512 m_ActivityState = ePAActive;
513 }
514
515
516 //-------------------------------------------------------------------
517 //
518 // is_sleeping
519
is_sleeping()520 bool pic_processor::is_sleeping()
521 {
522 return m_ActivityState == ePASleeping;
523 }
524
525
526 //-------------------------------------------------------------------
527 //
528 // pm_write - program memory write
529 //
530
pm_write()531 void pic_processor::pm_write()
532 {
533 m_ActivityState = ePAPMWrite;
534
535 do
536 {
537 get_cycles().increment(); // burn cycles until we're through writing
538 }
539 while (bp.have_pm_write());
540
541 simulation_mode = eSM_RUNNING;
542 }
543
544
545 static bool realtime_mode = false;
546 static bool realtime_mode_with_gui = false;
547
548
EnableRealTimeMode(bool bEnable)549 void EnableRealTimeMode(bool bEnable)
550 {
551 realtime_mode = bEnable;
552 }
553
554
EnableRealTimeModeWithGui(bool bEnable)555 void EnableRealTimeModeWithGui(bool bEnable)
556 {
557 realtime_mode_with_gui = bEnable;
558 }
559
560
561 extern void update_gui();
562
563 class RealTimeBreakPoint : public TriggerObject
564 {
565 public:
566 Processor *cpu;
567 struct timeval tv_start;
568 guint64 cycle_start;
569 guint64 future_cycle;
570 int warntimer;
571 guint64 period; // callback period in us
572
573 //#define REALTIME_DEBUG
574 guint64 diffmax;
575 guint64 diffsum;
576 int diffsumct;
577 struct timeval stat_start;
578
RealTimeBreakPoint()579 RealTimeBreakPoint()
580 {
581 cpu = nullptr;
582 warntimer = 1;
583 period = 1;
584 future_cycle = 0;
585 diffsum = 0;
586 diffsumct = 0;
587 diffmax = 0;
588 }
589
start(Processor * active_cpu)590 void start(Processor *active_cpu)
591 {
592 if (!active_cpu)
593 {
594 return;
595 }
596
597 diffsum = 0;
598 diffsumct = 0;
599 diffmax = 0;
600 // Grab the system time and record the simulated pic's time.
601 // We'll then set a break point a short time in the future
602 // and compare how the two track.
603 cpu = active_cpu;
604 gettimeofday(&tv_start, 0);
605 stat_start = tv_start;
606 cycle_start = get_cycles().get();
607 guint64 fc = cycle_start + 100;
608
609 //cout << "real time start : " << cycle_start << '\n';
610
611 if (future_cycle)
612 {
613 get_cycles().reassign_break(future_cycle, fc, this);
614
615 }
616 else
617 {
618 get_cycles().set_break(fc, this);
619 }
620
621 future_cycle = fc;
622 }
623
stop()624 void stop()
625 {
626 //cout << "real time stop : " << future_cycle << '\n';
627 #ifdef REALTIME_DEBUG
628 dump_stats();
629 #endif
630
631 // Clear any pending break point.
632 if (future_cycle)
633 {
634 std::cout << " real time clearing\n";
635 get_cycles().clear_break(this);
636 future_cycle = 0;
637
638 if (realtime_mode_with_gui)
639 {
640 update_gui();
641 }
642 }
643 }
644
645 #ifdef REALTIME_DEBUG
dump_stats()646 void dump_stats()
647 {
648 struct timeval tv;
649 gettimeofday(&tv, 0);
650 double simulation_time = (tv.tv_sec - stat_start.tv_sec) + (tv.tv_usec - stat_start.tv_usec) / 1000000.0; // in seconds
651
652 if (diffsumct > 0 && simulation_time > 0)
653 {
654 std::cout << std::dec << "Average realtime error: " << diffsum / diffsumct << " microseconds. Max: " << diffmax << '\n';
655
656 if (realtime_mode_with_gui)
657 {
658 std::cout << "Number of realtime callbacks (gui refreshes) per second:";
659
660 }
661 else
662 {
663 std::cout << "Number of realtime callbacks per second:";
664 }
665
666 std::cout << diffsumct / (double)simulation_time << '\n';
667 }
668
669 stat_start = tv;
670 diffsum = 0;
671 diffsumct = 0;
672 diffmax = 0;
673 }
674 #endif
675
callback()676 void callback()
677 {
678 guint64 system_time; // wall clock time since datum in micro seconds
679 guint64 simulation_time; // simulation time since datum in micro seconds
680 guint64 diff_us;
681 struct timeval tv;
682 // We just hit the break point. A few moments ago we
683 // grabbed a snap shot of the system time and the simulated
684 // pic's time. Now we're going to compare the two deltas and
685 // see how well they've tracked.
686 //
687 // If the host is running faster than the PIC, we'll put the
688 // host to sleep briefly.
689 //
690 // If the host is running slower than the PIC, lengthen the
691 // time between GUI updates.
692 gettimeofday(&tv, 0);
693 system_time = (tv.tv_sec - tv_start.tv_sec) * 1000000ULL + (tv.tv_usec - tv_start.tv_usec); // in micro-seconds
694 simulation_time = ((get_cycles().get() - cycle_start) * 4.0e6 * cpu->get_OSCperiod());
695
696 if (simulation_time > system_time)
697 {
698 // we are simulating too fast
699 diff_us = simulation_time - system_time;
700
701 if (period > diff_us)
702 {
703 period -= diff_us;
704
705 }
706 else
707 {
708 period = 1;
709 }
710
711 usleep((unsigned int)diff_us);
712
713 }
714 else
715 {
716 diff_us = system_time - simulation_time;
717 period += diff_us;
718
719 if (period > 1000000)
720 {
721 period = 1000000; // limit to a one second callback period
722 }
723
724 if (diff_us > 1000000)
725 {
726 // we are simulating too slow
727 if (warntimer < 10)
728 {
729 warntimer++;
730
731 }
732 else
733 {
734 warntimer = 0;
735 puts("Processor is too slow for realtime mode!");
736 }
737
738 }
739 else
740 {
741 warntimer = 0;
742 }
743 }
744
745 guint64 delta_cycles = (guint64)(period * cpu->get_frequency() / 4000000);
746
747 if (delta_cycles < 1)
748 {
749 delta_cycles = 1;
750 }
751
752 // Look at realtime_mode_with_gui and update the gui if true
753 if (realtime_mode_with_gui)
754 {
755 update_gui();
756 }
757
758 #ifdef REALTIME_DEBUG
759
760 if (tv.tv_sec < stat_start.tv_sec + 10)
761 {
762 diffsum += diff_us;
763 diffsumct++;
764
765 }
766 else
767 {
768 dump_stats();
769 }
770
771 if (diff_us > diffmax)
772 {
773 diffmax = diff_us;
774 }
775
776 static guint64 oldtime = 0;
777 //cout<<dec<<"dt="<<(system_time-oldtime)/1000 << "\tdiff_us="<<diff_us<<"\tdelta_cycles="<<delta_cycles<<"\tperiod="<<period<<endl;
778 oldtime = system_time;
779 #endif
780 guint64 fc = get_cycles().get() + delta_cycles;
781
782 if (future_cycle)
783 {
784 get_cycles().reassign_break(future_cycle, fc, this);
785
786 }
787 else
788 {
789 get_cycles().set_break(fc, this);
790 }
791
792 future_cycle = fc;
793 }
794
795 };
796
797
798 RealTimeBreakPoint realtime_cbp;
799
800 //-------------------------------------------------------------------
save_state()801 void pic_processor::save_state()
802 {
803 Processor::save_state();
804
805 if (Wreg)
806 {
807 Wreg->put_trace_state(Wreg->value);
808 }
809
810 if (eeprom)
811 {
812 eeprom->save_state();
813 }
814 }
815
816
817 //-------------------------------------------------------------------
818 //
819 // run -- Begin simulating and don't stop until there is a break.
820 //
821
822
run(bool)823 void pic_processor::run(bool /* refresh */ )
824 {
825 if (simulation_mode != eSM_STOPPED)
826 {
827 if (verbose)
828 {
829 std::cout << "Ignoring run request because simulation is not stopped\n";
830 }
831
832 return;
833 }
834
835 simulation_mode = eSM_RUNNING;
836
837 // If the first instruction we're simulating is a break point,
838 // then ignore it.
839
840 if (realtime_mode)
841 {
842 realtime_cbp.start(this);
843 }
844
845 simulation_start_cycle = get_cycles().get();
846 bp.clear_global();
847 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle;
848
849 do
850 {
851 mCurrentPhase = mCurrentPhase->advance();
852 }
853 while (!bp.global_break);
854
855 if (realtime_mode)
856 {
857 realtime_cbp.stop();
858 }
859
860 bp.clear_global();
861 trace.cycle_counter(get_cycles().get());
862 simulation_mode = eSM_STOPPED;
863 }
864
865
866 //-------------------------------------------------------------------
867 //
868 // step - Simulate one (or more) instructions. If a breakpoint is set
869 // at the current PC-> 'step' will go right through it. (That's supposed
870 // to be a feature.)
871 //
872
step(unsigned int steps,bool refresh)873 void pic_processor::step(unsigned int steps, bool refresh)
874 {
875 if (!steps)
876 {
877 return;
878 }
879
880 if (get_use_icd())
881 {
882 if (steps != 1)
883 {
884 std::cout << "Can only step one step in ICD mode\n";
885 }
886
887 icd_step();
888 pc->get_value();
889 disassemble((signed int)pc->value, (signed int)pc->value); // FIXME, don't want this in HLL ICD mode.
890
891 if (refresh)
892 {
893 gi.simulation_has_stopped();
894 }
895
896 return;
897 }
898
899 if (simulation_mode != eSM_STOPPED)
900 {
901 if (verbose)
902 {
903 std::cout << "Ignoring step request because simulation is not stopped\n";
904 }
905
906 return;
907 }
908
909 simulation_mode = eSM_SINGLE_STEPPING;
910 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle;
911
912 do
913 {
914 mCurrentPhase = mCurrentPhase->advance();
915 }
916 while (!bp.have_halt() && --steps > 0);
917
918 // complete the step if this is a multi-cycle instruction.
919
920 if (mCurrentPhase == mExecute2ndHalf)
921 while (mCurrentPhase != mExecute1Cycle)
922 {
923 mCurrentPhase = mCurrentPhase->advance();
924 }
925
926 get_trace().cycle_counter(get_cycles().get());
927
928 if (refresh)
929 {
930 trace_dump(0, 1);
931 }
932
933 bp.clear_halt();
934 simulation_mode = eSM_STOPPED;
935
936 if (refresh)
937 {
938 get_interface().simulation_has_stopped();
939 }
940 }
941
942
943 //-------------------------------------------------------------------
step_cycle()944 void pic_processor::step_cycle()
945 {
946 mCurrentPhase = mCurrentPhase->advance();
947 }
948
949
950 //
951 //-------------------------------------------------------------------
952 //
953 // step_over - In most cases, step_over will simulate just one instruction.
954 // However, if the next instruction is a branching one (e.g. goto, call,
955 // return, etc.) then a break point will be set after it and gpsim will
956 // begin 'running'. This is useful for stepping over time-consuming calls.
957 //
958
step_over(bool refresh)959 void pic_processor::step_over(bool refresh)
960 {
961 bool skip = false;
962
963 if (simulation_mode != eSM_STOPPED)
964 {
965 if (verbose)
966 {
967 std::cout << "Ignoring step-over request because simulation is not stopped\n";
968 }
969
970 return;
971 }
972
973 unsigned int saved_pc = pma->get_PC();
974 instruction *nextInstruction = pma->getFromAddress(saved_pc);
975
976 if (!nextInstruction)
977 {
978 // this is really fatal...
979 return;
980 }
981
982 // If break set, get actual instruction
983 if (typeid(*nextInstruction) == typeid(Breakpoint_Instruction))
984 {
985 Breakpoint_Instruction *x = (Breakpoint_Instruction *)nextInstruction;
986 nextInstruction = x->getReplaced();
987 }
988 // skip over calls of various types
989 if (nextInstruction->name() == "call" ||
990 nextInstruction->name() == "rcall" ||
991 nextInstruction->name() == "callw"
992 )
993 {
994 skip = true;
995 }
996
997 unsigned int nextExpected_pc =
998 saved_pc + map_pm_index2address(nextInstruction->instruction_size());
999 step(1, false); // Try one step -- without refresh
1000 // if the pc did not advance just one instruction, then some kind of branch occurred.
1001 unsigned int current_pc = pma->get_PC();
1002
1003 if (skip && !(current_pc >= saved_pc && current_pc <= nextExpected_pc))
1004 {
1005 // If the branch is not a skip instruction then we'll set a break point and run.
1006 // (note, the test that's performed will treat a goto $+2 as a skip.
1007 instruction *nextNextInstruction = pma->getFromAddress(nextExpected_pc);
1008 unsigned int nextNextExpected_pc = nextExpected_pc +
1009 (nextNextInstruction ? map_pm_index2address(nextNextInstruction->instruction_size()) : 0);
1010
1011 if (!(current_pc >= saved_pc && current_pc <= nextNextExpected_pc))
1012 {
1013 unsigned int bp_num = pma->set_break_at_address(nextExpected_pc);
1014
1015 if (bp_num != INVALID_VALUE)
1016 {
1017 run();
1018 bp.clear(bp_num);
1019 }
1020 }
1021 }
1022
1023 // note that we don't need to tell the gui to update its windows since
1024 // that is already done by step() or run().
1025
1026 if (refresh)
1027 {
1028 get_interface().simulation_has_stopped();
1029 }
1030 }
1031
1032
1033 //-------------------------------------------------------------------
1034 //
1035 // finish
1036 //
1037 // this method really only applies to processors with stacks.
1038
finish()1039 void pic_processor::finish()
1040 {
1041 if (!stack)
1042 {
1043 return;
1044 }
1045
1046 run_to_address(stack->contents[(stack->pointer - 1) & stack->stack_mask]);
1047 get_interface().simulation_has_stopped();
1048 }
1049
1050
1051 //-------------------------------------------------------------------
1052 //
1053 // reset - reset the pic based on the desired reset type.
1054 //
1055
reset(RESET_TYPE r)1056 void pic_processor::reset(RESET_TYPE r)
1057 {
1058 bool bHaltSimulation = getBreakOnReset();
1059
1060 if (get_use_icd())
1061 {
1062 puts("RESET");
1063 icd_reset();
1064 disassemble((signed int)pc->get_value(), (signed int)pc->get_value());
1065 gi.simulation_has_stopped();
1066 return;
1067 }
1068
1069 m_pResetTT->record(r);
1070 rma.reset(r);
1071 stack->reset(r);
1072 wdt.reset(r);
1073 pc->reset();
1074 bp.clear_global();
1075
1076 switch (r)
1077 {
1078 case POR_RESET:
1079 if (verbose)
1080 {
1081 std::cout << "POR\n";
1082
1083 if (config_modes)
1084 {
1085 config_modes->print();
1086 }
1087 }
1088
1089 bHaltSimulation = false;
1090 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle;
1091 m_ActivityState = ePAActive;
1092 break;
1093
1094 case SOFT_RESET:
1095 std::cout << "Reset due to Software reset instruction\n";
1096 mCurrentPhase = mExecute1Cycle;
1097 mCurrentPhase->setNextPhase(mExecute1Cycle);
1098 m_ActivityState = ePAActive;
1099 break;
1100
1101 case MCLR_RESET:
1102 std::cout << "MCLR reset\n";
1103 mCurrentPhase = mIdle;
1104 mCurrentPhase->setNextPhase(mIdle);
1105 m_ActivityState = ePAIdle;
1106 break;
1107
1108 case IO_RESET:
1109 mCurrentPhase = mExecute1Cycle;
1110 mCurrentPhase->setNextPhase(mExecute1Cycle);
1111 m_ActivityState = ePAActive;
1112 break;
1113
1114 case WDT_RESET:
1115 std::cout << "Reset on Watch Dog Timer expire\n";
1116 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle;
1117 mCurrentPhase->setNextPhase(mExecute1Cycle);
1118 m_ActivityState = ePAActive;
1119 break;
1120
1121 case EXIT_RESET: // MCLR reset has cleared
1122 std::cout << "MCLR low, resume execution\n";
1123 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mExecute1Cycle;
1124 mCurrentPhase->setNextPhase(mExecute1Cycle);
1125 m_ActivityState = ePAActive;
1126 return;
1127 break;
1128
1129 case STKOVF_RESET:
1130 std::cout << "Reset on Stack overflow\n";
1131 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mIdle;
1132 mCurrentPhase->setNextPhase(mIdle);
1133 m_ActivityState = ePAActive;
1134 // mCurrentPhase->setNextPhase(mExecute1Cycle);
1135 // m_ActivityState = ePAActive;
1136 break;
1137
1138 case STKUNF_RESET:
1139 std::cout << "Reset on Stack undeflow\n";
1140 mCurrentPhase = mCurrentPhase ? mCurrentPhase : mIdle;
1141 mCurrentPhase->setNextPhase(mIdle);
1142 m_ActivityState = ePAActive;
1143 break;
1144
1145 default:
1146 printf("pic_processor::reset unknow reset type %d\n", r);
1147 m_ActivityState = ePAActive;
1148 break;
1149 }
1150
1151 if (bHaltSimulation || getBreakOnReset())
1152 {
1153 bp.halt();
1154 gi.simulation_has_stopped();
1155 }
1156 }
1157
1158
1159 //-------------------------------------------------------------------
1160 //
1161 // pic_processor -- constructor
1162 //
1163
pic_processor(const char * _name,const char * _desc)1164 pic_processor::pic_processor(const char *_name, const char *_desc)
1165 : Processor(_name, _desc),
1166 wdt(this, 18.0e-3),
1167 tmr0(this, "tmr0", "Timer 0")
1168 {
1169 mExecute1Cycle = new phaseExecute1Cycle(this);
1170 mExecute2ndHalf = new phaseExecute2ndHalf(this);
1171 mCaptureInterrupt = new phaseCaptureInterrupt(this);
1172 mIdle = new phaseIdle(this);
1173 mCurrentPhase = mExecute1Cycle;
1174 std::fill_n(m_osc_Monitor, 4, nullptr);
1175 m_Capabilities = eSTACK | eWATCHDOGTIMER;
1176
1177 if (verbose)
1178 {
1179 std::cout << "pic_processor constructor\n";
1180 }
1181
1182 config_modes = create_ConfigMode();
1183 Integer::setDefaultBitmask(0xff);
1184 // Test code for logging to disk:
1185 GetTraceLog().switch_cpus(this);
1186 m_pResetTT = new ResetTraceType(this);
1187 m_pInterruptTT = new InterruptTraceType(this);
1188
1189 for (int i = 0; i < 4; i++)
1190 {
1191 osc_pin_Number[i] = 254;
1192 }
1193 }
1194
1195
1196 //-------------------------------------------------------------------
~pic_processor()1197 pic_processor::~pic_processor()
1198 {
1199 if (pma)
1200 {
1201 while (!rma.SpecialRegisters.empty())
1202 {
1203 rma.SpecialRegisters.pop_back();
1204 }
1205
1206 while (!pma->SpecialRegisters.empty())
1207 {
1208 pma->SpecialRegisters.pop_back();
1209 }
1210 }
1211
1212 delete m_pResetTT;
1213 delete m_pInterruptTT;
1214 delete_sfr_register(Wreg);
1215 delete_sfr_register(pcl);
1216 delete_sfr_register(pclath);
1217 delete_sfr_register(status);
1218 delete_sfr_register(indf);
1219 delete m_PCHelper;
1220 delete stack;
1221 delete mExecute1Cycle;
1222 delete mExecute2ndHalf;
1223 delete mCaptureInterrupt;
1224 delete mIdle;
1225 delete config_modes;
1226 delete m_configMemory;
1227
1228 if (m_MCLR)
1229 {
1230 m_MCLR->setMonitor(nullptr);
1231 }
1232
1233 if (m_MCLR_Save)
1234 {
1235 m_MCLR_Save->setMonitor(nullptr);
1236 }
1237
1238 delete m_MCLRMonitor;
1239 delete clksource;
1240 delete clkcontrol;
1241 }
1242
1243
1244 //-------------------------------------------------------------------
1245 //
1246 //
1247 // create
1248 //
1249 // The purpose of this member function is to 'create' a pic processor.
1250 // Since this is a base class member function, only those things that
1251 // are common to all pics are created.
1252
create()1253 void pic_processor::create()
1254 {
1255 init_program_memory(program_memory_size());
1256 init_register_memory(register_memory_size());
1257 // Now, initialize the core stuff:
1258 pc->set_cpu(this);
1259 Wreg = new WREG(this, "W", "Working Register");
1260 pcl = new PCL(this, "pcl", "Program Counter Low");
1261 pclath = new PCLATH(this, "pclath", "Program Counter Latch High");
1262 status = new Status_register(this, "status", "Processor status");
1263 indf = new INDF(this, "indf", "Indirect register");
1264 register_bank = ®isters[0]; // Define the active register bank
1265
1266 if (pma)
1267 {
1268 m_PCHelper = new PCHelper(this, pma);
1269 rma.SpecialRegisters.push_back(m_PCHelper);
1270 rma.SpecialRegisters.push_back(status);
1271 rma.SpecialRegisters.push_back(Wreg);
1272 pma->SpecialRegisters.push_back(m_PCHelper);
1273 pma->SpecialRegisters.push_back(status);
1274 pma->SpecialRegisters.push_back(Wreg);
1275 }
1276
1277 create_config_memory();
1278 }
1279
1280
1281 //-------------------------------------------------------------------
1282 //
1283 // add_sfr_register
1284 //
1285 // The purpose of this routine is to add one special function register
1286 // to the file registers. If the sfr has a physical address (like the
1287 // status or tmr0 registers) then a pointer to that register will be
1288 // placed in the file register map.
1289
1290 // FIXME It doesn't make any sense to initialize the por_value here!
1291 // FIXME The preferred way is to initialize all member data in their
1292 // FIXME parent's constructor.
1293
add_sfr_register(Register * reg,unsigned int addr,RegisterValue por_value,const char * new_name,bool warn_dup)1294 void pic_processor::add_sfr_register(Register *reg, unsigned int addr,
1295 RegisterValue por_value,
1296 const char *new_name,
1297 bool warn_dup)
1298 {
1299 reg->set_cpu(this);
1300
1301 if (addr < register_memory_size())
1302 {
1303 if (registers[addr])
1304 {
1305 if (registers[addr]->isa() == Register::INVALID_REGISTER)
1306 {
1307 delete registers[addr];
1308 registers[addr] = reg;
1309
1310 }
1311 else if (warn_dup)
1312 {
1313 printf("%s %s 0x%x Already register %s\n", __FUNCTION__, name().c_str(), addr, registers[addr]->name().c_str());
1314 }
1315
1316 }
1317 else
1318 {
1319 registers[addr] = reg;
1320 }
1321
1322 reg->address = addr;
1323 reg->alias_mask = 0;
1324
1325 if (new_name)
1326 {
1327 reg->new_name(new_name);
1328 }
1329
1330 RegisterValue rv = getWriteTT(addr);
1331 reg->set_write_trace(rv);
1332 rv = getReadTT(addr);
1333 reg->set_read_trace(rv);
1334 }
1335
1336 reg->value = por_value;
1337 reg->por_value = por_value; /// FIXME why are we doing this?
1338 reg->initialize();
1339 }
1340
1341
1342 // Use this function when register is initialized on WDT reset to
1343 // same value as a POR.
add_sfr_registerR(sfr_register * reg,unsigned int addr,RegisterValue por_value,const char * new_name,bool warn_dup)1344 void pic_processor::add_sfr_registerR(sfr_register *reg, unsigned int addr,
1345 RegisterValue por_value,
1346 const char *new_name,
1347 bool warn_dup)
1348 {
1349 add_sfr_register(reg, addr, por_value, new_name, warn_dup);
1350 reg->wdtr_value = por_value;
1351 }
1352
1353
1354 //-------------------------------------------------------------------
1355 //
1356 // delete_sfr_register
1357 // This both deletes the register from the registers array,
1358 // but also deletes the register class.
1359 //
delete_sfr_register(Register * pReg)1360 void pic_processor::delete_sfr_register(Register *pReg)
1361 {
1362 if (pReg)
1363 {
1364 unsigned int a = pReg->getAddress();
1365
1366 if (0)
1367 std::cout << __FUNCTION__ << " addr = 0x" << std::hex << a
1368 << " reg " << pReg->name() << '\n';
1369
1370 if (a < rma.get_size() && registers[a] == pReg)
1371 {
1372 delete_file_registers(a, a);
1373
1374 }
1375 else
1376 {
1377 delete pReg;
1378 }
1379 }
1380 }
1381
1382
1383 //-------------------------------------------------------------------
1384 //
1385 // remove_sfr_register
1386 // This is the inverse of add_sfr_register and does not delete the register.
1387 //
remove_sfr_register(Register * ppReg)1388 void pic_processor::remove_sfr_register(Register *ppReg)
1389 {
1390 if (ppReg)
1391 {
1392 unsigned int a = ppReg->getAddress();
1393
1394 if (a == AN_INVALID_ADDRESS)
1395 {
1396 return;
1397 }
1398
1399 if (registers[a] == ppReg)
1400 {
1401 delete_file_registers(a, a, true);
1402 }
1403 }
1404 }
1405
1406
1407 //-------------------------------------------------------------------
1408 //
1409 // init_program_memory
1410 //
1411 // The purpose of this member function is to allocate memory for the
1412 // pic's code space. The 'memory_size' parameter tells how much memory
1413 // is to be allocated AND it should be an integer of the form of 2^n.
1414 // If the memory size is not of the form of 2^n, then this routine will
1415 // round up to the next integer that is of the form 2^n.
1416 // Once the memory has been allocated, this routine will initialize
1417 // it with the 'bad_instruction'. The bad_instruction is an instantiation
1418 // of the instruction class that chokes gpsim if it is executed. Note that
1419 // each processor owns its own 'bad_instruction' object.
1420
init_program_memory(unsigned int memory_size)1421 void pic_processor::init_program_memory(unsigned int memory_size)
1422 {
1423 if (verbose)
1424 {
1425 std::cout << "Initializing program memory: 0x" << memory_size << " words\n";
1426 }
1427
1428 // The memory_size_mask is used by the branching instructions
1429 pc->memory_size = memory_size;
1430 Processor::init_program_memory(memory_size);
1431 }
1432
1433
create_symbols()1434 void pic_processor::create_symbols()
1435 {
1436 if (verbose)
1437 {
1438 std::cout << __FUNCTION__ << " register memory size = " << register_memory_size() << '\n';
1439 }
1440
1441 for (unsigned int i = 0; i < register_memory_size(); i++)
1442 {
1443 switch (registers[i]->isa())
1444 {
1445 case Register::SFR_REGISTER:
1446 //if(!symbol_table.find((char *)registers[i]->name().c_str()))
1447 // symbol_table.add_register(registers[i]);
1448 //
1449 addSymbol(registers[i]);
1450 break;
1451
1452 default:
1453 break;
1454 }
1455 }
1456
1457 pc->set_description("Program Counter"); // Fixme put this in the pc constructor.
1458 addSymbol(pc);
1459 addSymbol(&wdt);
1460 }
1461
1462
1463 //-------------------------------------------------------------------
1464
1465
set_config_word(unsigned int address,unsigned int cfg_word)1466 bool pic_processor::set_config_word(unsigned int address, unsigned int cfg_word)
1467 {
1468 int i = get_config_index(address);
1469
1470 if (i >= 0)
1471 {
1472 m_configMemory->getConfigWord(i)->set((int)cfg_word);
1473
1474 if (i == 0 && config_modes)
1475 {
1476 config_word = cfg_word;
1477 config_modes->config_mode = (config_modes->config_mode & ~7) |
1478 (cfg_word & 7);
1479 }
1480
1481 return true;
1482 }
1483
1484 return false;
1485 }
1486
1487
get_config_word(unsigned int address)1488 unsigned int pic_processor::get_config_word(unsigned int address)
1489 {
1490 int i;
1491
1492 if ((i = get_config_index(address)) >= 0)
1493 {
1494 return m_configMemory->getConfigWord(i)->getVal();
1495 }
1496
1497 return 0xffffffff;
1498 }
1499
1500
get_config_index(unsigned int address)1501 int pic_processor::get_config_index(unsigned int address)
1502 {
1503 if (m_configMemory)
1504 {
1505 for (int i = 0; i < m_configMemory->getnConfigWords(); i++)
1506 {
1507 if (m_configMemory->getConfigWord(i))
1508 {
1509 if (m_configMemory->getConfigWord(i)->ConfigWordAdd() == address)
1510 {
1511 return i;
1512 }
1513 }
1514 }
1515 }
1516
1517 return -1;
1518 }
1519
1520
1521
1522 //-------------------------------------------------------------------
1523 //
1524 // load_hex
1525 //
1526
LoadProgramFile(const char * pFilename,FILE * pFile,const char * pProcessorName)1527 bool pic_processor::LoadProgramFile(const char *pFilename, FILE *pFile,
1528 const char *pProcessorName)
1529 {
1530 Processor * pProcessor = this;
1531 // Tries the file type based on the file extension first.
1532 // If it fails tries the other type. This code will need
1533 // to change if pic_processor is moved to its own module
1534 // because then we cannot garrentee that these file types
1535 // will be the first two in the list.
1536 ProgramFileType * aFileTypes[] =
1537 {
1538 ProgramFileTypeList::GetList()[0], // IntelHexProgramFileType
1539 ProgramFileTypeList::GetList()[1] // PicCodProgramFileType
1540 };
1541
1542 if (IsFileExtension(pFilename, "cod"))
1543 {
1544 // If 'cod' file extension, try PicCodProgramFileType first
1545 std::swap(aFileTypes[0], aFileTypes[1]);
1546 }
1547
1548 int iReturn = aFileTypes[0]->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName);
1549
1550 if (iReturn != ProgramFileType::SUCCESS)
1551 {
1552 fseek(pFile, 0, SEEK_SET);
1553 iReturn = aFileTypes[1]->LoadProgramFile(&pProcessor, pFilename, pFile, pProcessorName);
1554 }
1555
1556 std::cout << "Leaving pic_processor::LoadProgramFile\n";
1557 return iReturn == ProgramFileType::SUCCESS;
1558 }
1559
1560
1561 //-------------------------------------------------------------------
1562 //-------------------------------------------------------------------
1563 // ConfigMode
1564 //
print()1565 void ConfigMode::print()
1566 {
1567 if (config_mode & CM_FOSC1x)
1568 {
1569 // Internal Oscillator type processor
1570 switch (config_mode & (CM_FOSC0 | CM_FOSC1)) // Lower two bits are the clock type
1571 {
1572 case 0:
1573 std::cout << "LP";
1574 break;
1575
1576 case CM_FOSC0:
1577 std::cout << "XT";
1578 break;
1579
1580 case CM_FOSC1:
1581 std::cout << "Internal RC";
1582 break;
1583
1584 case (CM_FOSC0|CM_FOSC1):
1585 std::cout << "External RC";
1586 break;
1587 }
1588
1589 }
1590 else
1591 {
1592 switch (config_mode & (CM_FOSC0 | CM_FOSC1)) // Lower two bits are the clock type
1593 {
1594 case 0:
1595 std::cout << "LP";
1596 break;
1597
1598 case CM_FOSC0:
1599 std::cout << "XT";
1600 break;
1601
1602 case CM_FOSC1:
1603 std::cout << "HS";
1604 break;
1605
1606 case (CM_FOSC0|CM_FOSC1):
1607 std::cout << "RC";
1608 break;
1609 }
1610 }
1611
1612 std::cout << " oscillator\n";
1613
1614 if (valid_bits & CM_WDTE)
1615 {
1616 std::cout << " WDT is " << (get_wdt() ? "enabled\n" : "disabled\n");
1617 }
1618
1619 if (valid_bits & CM_MCLRE)
1620 {
1621 std::cout << "MCLR is " << (get_mclre() ? "enabled\n" : "disabled\n");
1622 }
1623
1624 if (valid_bits & CM_CP0)
1625 {
1626 if (valid_bits & CM_CP1)
1627 {
1628 std::cout << "CP0 is " << (get_cp0() ? "high\n" : "low\n");
1629 std::cout << "CP1 is " << (get_cp1() ? "high\n" : "low\n");
1630
1631 }
1632 else
1633 {
1634 std::cout << "code protection is " << (get_cp0() ? "enabled\n" : "disabled\n");
1635 }
1636 }
1637 }
1638
1639
1640 //-------------------------------------------------------------------
1641 //-------------------------------------------------------------------
callback()1642 void ProgramMemoryAccess::callback()
1643 {
1644 if (_state)
1645 {
1646 _state = 0;
1647 //cout << __FUNCTION__ << " address= " << address << ", opcode= " << opcode << '\n';
1648 //cpu->program_memory[address]->opcode = opcode;
1649 put_opcode(_address, _opcode);
1650 // FIXME trace.opcode_write(_address,_opcode);
1651 bp.clear_pm_write();
1652 }
1653 }
1654
1655
1656 //--------------------------------------------------
WDT(pic_processor * p_cpu,double _timeout)1657 WDT::WDT(pic_processor *p_cpu, double _timeout)
1658 : gpsimObject("WDT", "Watch Dog Timer"),
1659 cpu(p_cpu), prescale(1), postscale(128), timeout(_timeout)
1660 {
1661 }
1662
1663
1664 //--------------------------------------------------
update()1665 void WDT::update()
1666 {
1667 if (wdte)
1668 {
1669 // FIXME - the WDT should not be tied to the instruction counter...
1670 guint64 delta_cycles;
1671
1672 if (!use_t0_prescale)
1673 {
1674 postscale = 1;
1675 }
1676
1677 delta_cycles = (guint64)(postscale * prescale * timeout / get_cycles().seconds_per_cycle());
1678
1679 if (verbose)
1680 {
1681 std::cout << "WDT::update timeout in " << (postscale * prescale * timeout);
1682 std::cout << " seconds (" << std::dec << delta_cycles << " cycles), ";
1683 std::cout << "CPU frequency " << (cpu->get_frequency()) << '\n';
1684 }
1685
1686 guint64 fc = get_cycles().get() + delta_cycles ;
1687
1688 if (future_cycle)
1689 {
1690 if (verbose)
1691 {
1692 std::cout << "WDT::update: moving break from " << future_cycle << " to " << fc << '\n';
1693 }
1694
1695 get_cycles().reassign_break(future_cycle, fc, this);
1696
1697 }
1698 else
1699 {
1700 get_cycles().set_break(fc, this);
1701 }
1702
1703 future_cycle = fc;
1704 }
1705 }
1706
1707
1708 //--------------------------------------------------
1709 // WDT::put - shouldn't be called?
1710 //
1711
put(unsigned int)1712 void WDT::put(unsigned int /* new_value */ )
1713 {
1714 std::cout << "WDT::put should not be called\n";
1715 }
1716
1717
set_timeout(double _timeout)1718 void WDT::set_timeout(double _timeout)
1719 {
1720 timeout = _timeout;
1721 update();
1722 }
1723
1724
1725 // TMR0 prescale is WDT postscale
set_postscale(unsigned int newPostscale)1726 void WDT::set_postscale(unsigned int newPostscale)
1727 {
1728 unsigned int value = 1 << newPostscale;
1729
1730 if (verbose)
1731 {
1732 std::cout << "WDT::set_postscale postscale = " << std::dec << value << '\n';
1733 }
1734
1735 if (value != postscale)
1736 {
1737 postscale = value;
1738 update();
1739 }
1740 }
1741
1742
swdten(bool enable)1743 void WDT::swdten(bool enable)
1744 {
1745 if (cfgw_enable)
1746 {
1747 return;
1748 }
1749
1750 if (wdte != enable)
1751 {
1752 wdte = enable;
1753 warned = false;
1754
1755 if (verbose)
1756 std::cout << " WDT swdten "
1757 << ((enable) ? "enabling\n" : ", but disabling WDT\n");
1758
1759 if (wdte)
1760 {
1761 update();
1762
1763 }
1764 else
1765 {
1766 if (future_cycle)
1767 {
1768 if (verbose)
1769 {
1770 std::cout << "Disabling WDT\n";
1771 }
1772
1773 get_cycles().clear_break(this);
1774 future_cycle = 0;
1775 }
1776 }
1777 }
1778 }
1779
1780
1781 // For WDT period select 0-11
set_prescale(unsigned int newPrescale)1782 void WDT::set_prescale(unsigned int newPrescale)
1783 {
1784 unsigned int value = 1 << (5 + newPrescale);
1785
1786 if (verbose)
1787 {
1788 std::cout << "WDT::set_prescale prescale = " << std::dec << value << '\n';
1789 }
1790
1791 if (value != prescale)
1792 {
1793 prescale = value;
1794 update();
1795 }
1796 }
1797
1798
initialize(bool enable,bool _use_t0_prescale)1799 void WDT::initialize(bool enable, bool _use_t0_prescale)
1800 {
1801 wdte = enable;
1802 cfgw_enable = enable;
1803 use_t0_prescale = _use_t0_prescale;
1804 warned = false;
1805
1806 if (verbose)
1807 {
1808 std::cout << " WDT init called " << ((enable) ? "enabling\n" : ", but disabling WDT\n");
1809 }
1810
1811 if (wdte)
1812 {
1813 update();
1814
1815 }
1816 else
1817 {
1818 if (future_cycle)
1819 {
1820 std::cout << "Disabling WDT\n";
1821 get_cycles().clear_break(this);
1822 future_cycle = 0;
1823 }
1824 }
1825 }
1826
1827
reset(RESET_TYPE r)1828 void WDT::reset(RESET_TYPE r)
1829 {
1830 switch (r)
1831 {
1832 case POR_RESET:
1833 case EXIT_RESET:
1834 update();
1835 break;
1836
1837 case MCLR_RESET:
1838 if (future_cycle)
1839 {
1840 get_cycles().clear_break(this);
1841 }
1842
1843 future_cycle = 0;
1844 break;
1845
1846 default:
1847 ;
1848 }
1849 }
1850
1851
set_breakpoint(unsigned int bpn)1852 void WDT::set_breakpoint(unsigned int bpn)
1853 {
1854 breakpoint = bpn;
1855 }
1856
1857
callback()1858 void WDT::callback()
1859 {
1860 if (wdte)
1861 {
1862 if (verbose)
1863 {
1864 std::cout << "WDT timeout: " << std::hex << get_cycles().get() << '\n';
1865 }
1866
1867 if (breakpoint)
1868 {
1869 bp.halt();
1870
1871 }
1872 else if (cpu->is_sleeping() && cpu->exit_wdt_sleep())
1873 {
1874 std::cout << "WDT expired during sleep\n";
1875 update();
1876 cpu->exit_sleep();
1877 cpu->status->put_TO(0);
1878
1879 }
1880 else
1881 {
1882 // The TO bit gets cleared when the WDT times out.
1883 std::cout << "WDT expired reset\n";
1884 update();
1885 cpu->status->put_TO(0);
1886 cpu->reset(WDT_RESET);
1887 }
1888 }
1889 }
1890
1891
clear()1892 void WDT::clear()
1893 {
1894 if (wdte)
1895 {
1896 update();
1897
1898 }
1899 else if (!warned)
1900 {
1901 warned = 1;
1902 std::cout << "The WDT is not enabled - clrwdt has no effect!\n";
1903 }
1904 }
1905
1906
callback_print()1907 void WDT::callback_print()
1908 {
1909 std::cout << name() << " has callback, ID = " << CallBackID << '\n';
1910 // cout << "WDT\n";
1911 }
1912
1913
1914 //------------------------------------------------------------------------
1915 // ConfigMemory - Base class
ConfigWord(const char * _name,unsigned int default_val,const char * desc,pic_processor * pCpu,unsigned int addr,bool EEw)1916 ConfigWord::ConfigWord(const char *_name, unsigned int default_val, const char *desc,
1917 pic_processor *pCpu, unsigned int addr, bool EEw)
1918 : Integer(_name, default_val, desc), m_pCpu(pCpu), m_addr(addr),
1919 EEWritable(EEw)
1920 {
1921 /*
1922 if (m_pCpu)
1923 m_pCpu->addSymbol(this);
1924 */
1925 }
1926
1927
1928 // this get controls the display format in the symbols window
get(char * buffer,int buf_size)1929 void ConfigWord::get(char *buffer, int buf_size)
1930 {
1931 if (buffer)
1932 {
1933 gint64 i;
1934 get(i);
1935 long long int j = i;
1936 snprintf(buffer, buf_size, "0x%" PRINTF_INT64_MODIFIER "x", j);
1937 }
1938 }
1939
1940
get(gint64 & i)1941 void ConfigWord::get(gint64 &i)
1942 {
1943 Integer::get(i);
1944 }
1945
1946
1947 //------------------------------------------------------------------------
ConfigMemory(pic_processor * pCpu,unsigned int nWords)1948 ConfigMemory::ConfigMemory(pic_processor *pCpu, unsigned int nWords)
1949 : m_pCpu(pCpu), m_nConfigWords(nWords)
1950 {
1951 if (nWords > 0 && nWords < 100)
1952 {
1953 m_ConfigWords = new ConfigWord *[nWords];
1954
1955 for (unsigned int i = 0; i < nWords; i++)
1956 {
1957 m_ConfigWords[i] = nullptr;
1958 }
1959 }
1960 }
1961
1962
~ConfigMemory()1963 ConfigMemory::~ConfigMemory()
1964 {
1965 for (unsigned int i = 0; i < m_nConfigWords; i++)
1966 if (m_ConfigWords[i])
1967 {
1968 m_pCpu->deleteSymbol(m_ConfigWords[i]);
1969 }
1970
1971 delete [] m_ConfigWords;
1972 }
1973
1974
addConfigWord(unsigned int addr,ConfigWord * pConfigWord)1975 int ConfigMemory::addConfigWord(unsigned int addr, ConfigWord *pConfigWord)
1976 {
1977 if (addr < m_nConfigWords)
1978 {
1979 if (m_ConfigWords[addr])
1980 {
1981 m_pCpu->deleteSymbol(m_ConfigWords[addr]);
1982 }
1983
1984 m_ConfigWords[addr] = pConfigWord;
1985 m_pCpu->addSymbol(pConfigWord);
1986 return 1;
1987 }
1988
1989 delete pConfigWord;
1990 return 0;
1991 }
1992
1993
getConfigWord(unsigned int addr)1994 ConfigWord *ConfigMemory::getConfigWord(unsigned int addr)
1995 {
1996 return addr < m_nConfigWords ? m_ConfigWords[addr] : nullptr;
1997 }
1998
1999
2000 //-------------------------------------------------------------------
2001 class MCLRPinMonitor : public PinMonitor
2002 {
2003 public:
2004 explicit MCLRPinMonitor(pic_processor *pCpu);
~MCLRPinMonitor()2005 ~MCLRPinMonitor() {}
2006
2007 virtual void setDrivenState(char);
setDrivingState(char)2008 virtual void setDrivingState(char) {}
set_nodeVoltage(double)2009 virtual void set_nodeVoltage(double) {}
putState(char)2010 virtual void putState(char) {}
setDirection()2011 virtual void setDirection() {}
2012
2013 private:
2014 pic_processor *m_pCpu;
2015 char m_cLastResetState;
2016 };
2017
2018
MCLRPinMonitor(pic_processor * pCpu)2019 MCLRPinMonitor::MCLRPinMonitor(pic_processor *pCpu)
2020 : m_pCpu(pCpu),
2021 m_cLastResetState('I') // I is not a valid state. It's used here for 'I'nitialization
2022 {
2023 }
2024
2025
setDrivenState(char newState)2026 void MCLRPinMonitor::setDrivenState(char newState)
2027 {
2028 if (newState == '0' || newState == 'w')
2029 {
2030 m_cLastResetState = '0';
2031 m_pCpu->reset(MCLR_RESET);
2032 }
2033
2034 if (newState == '1' || newState == 'W')
2035 {
2036 if (m_cLastResetState == '0')
2037 {
2038 m_pCpu->reset(EXIT_RESET);
2039 }
2040
2041 m_cLastResetState = '1';
2042 }
2043 }
2044
2045
2046 //-------------------------------------------------------------------
createMCLRPin(int pkgPinNumber)2047 void pic_processor::createMCLRPin(int pkgPinNumber)
2048 {
2049 if (m_MCLR)
2050 {
2051 std::cout << "BUG?: assigning multiple MCLR pins: " __FILE__ << std::dec << " " << __LINE__ << '\n';
2052 }
2053
2054 if (package)
2055 {
2056 m_MCLR = new IO_open_collector("MCLR");
2057 package->assign_pin(pkgPinNumber, m_MCLR);
2058 addSymbol(m_MCLR);
2059 m_MCLRMonitor = new MCLRPinMonitor(this);
2060 m_MCLR->setMonitor(m_MCLRMonitor);
2061 }
2062 }
2063
2064
2065 //-------------------------------------------------------------------
2066 // This function is called instead of createMCLRPin where the pin
2067 // is already defined, but the configuration word has set the function
2068 // to MCLR
2069
2070
assignMCLRPin(int pkgPinNumber)2071 void pic_processor::assignMCLRPin(int pkgPinNumber)
2072 {
2073 if (package)
2074 {
2075 if (m_MCLR == nullptr)
2076 {
2077 m_MCLR_pin = pkgPinNumber;
2078 m_MCLR = new IO_open_collector("MCLR");
2079 addSymbol(m_MCLR);
2080 m_MCLR_Save = package->get_pin(pkgPinNumber);
2081 package->assign_pin(pkgPinNumber, m_MCLR, false);
2082 m_MCLRMonitor = new MCLRPinMonitor(this);
2083 m_MCLR->setMonitor(m_MCLRMonitor);
2084 m_MCLR->newGUIname("MCLR");
2085
2086 }
2087 else if (m_MCLR != package->get_pin(pkgPinNumber))
2088 {
2089 std::cout << "BUG?: assigning multiple MCLR pins: "
2090 << std::dec << pkgPinNumber << " " __FILE__ " "
2091 << __LINE__ << '\n';
2092 }
2093 }
2094 }
2095
2096
2097 //-------------------------------------------------------------------
2098 // This function sets the pin currently set as MCLR back to its original function
unassignMCLRPin()2099 void pic_processor::unassignMCLRPin()
2100 {
2101 if (package && m_MCLR_Save)
2102 {
2103 size_t l = m_MCLR_Save->name().find_first_of('.');
2104 package->assign_pin(m_MCLR_pin, m_MCLR_Save, false);
2105
2106 if (l == std::string::npos)
2107 {
2108 m_MCLR_Save->newGUIname(m_MCLR_Save->name().c_str());
2109
2110 }
2111 else
2112 {
2113 m_MCLR_Save->newGUIname(m_MCLR_Save->name().substr(l + 1).c_str());
2114 }
2115
2116 if (m_MCLR)
2117 {
2118 m_MCLR->setMonitor(nullptr);
2119 deleteSymbol(m_MCLR);
2120 m_MCLR = nullptr;
2121
2122 delete m_MCLRMonitor;
2123 m_MCLRMonitor = nullptr;
2124 }
2125 }
2126 }
2127
2128
2129 //--------------------------------------------------
2130 //
2131 class IO_SignalControl : public SignalControl
2132 {
2133 public:
IO_SignalControl(char _dir)2134 explicit IO_SignalControl(char _dir)
2135 : direction(_dir)
2136 {
2137 }
~IO_SignalControl()2138 ~IO_SignalControl() {}
getState()2139 virtual char getState()
2140 {
2141 return direction;
2142 }
release()2143 virtual void release() {}
setState(char _dir)2144 void setState(char _dir)
2145 {
2146 direction = _dir;
2147 }
2148
2149 private:
2150 char direction;
2151 };
2152
2153
2154 // This function sets a label on a pin and if PinMod is defined
2155 // removes its control from it's port register
2156 //
set_clk_pin(unsigned int pkg_Pin_Number,PinModule * PinMod,const char * name,bool in,PicPortRegister * m_port,PicTrisRegister * m_tris,PicLatchRegister * m_lat)2157 void pic_processor::set_clk_pin(unsigned int pkg_Pin_Number,
2158 PinModule *PinMod,
2159 const char * name,
2160 bool in,
2161 PicPortRegister *m_port,
2162 PicTrisRegister *m_tris,
2163 PicLatchRegister *m_lat)
2164 {
2165 IOPIN *m_pin = package->get_pin(pkg_Pin_Number);
2166
2167 if (name)
2168 {
2169 m_pin->newGUIname(name);
2170
2171 }
2172 else
2173 {
2174 m_pin->newGUIname(package->get_pin_name(pkg_Pin_Number).c_str());
2175 }
2176
2177 if (PinMod)
2178 {
2179 if (m_port)
2180 {
2181 unsigned int mask = m_port->getEnableMask();
2182 mask &= ~(1 << PinMod->getPinNumber());
2183 m_port->setEnableMask(mask);
2184
2185 if (m_tris)
2186 {
2187 m_tris->setEnableMask(mask);
2188 }
2189
2190 if (m_lat)
2191 {
2192 m_lat->setEnableMask(mask);
2193 }
2194 }
2195
2196 if (!clksource)
2197 {
2198 clksource = new PeripheralSignalSource(PinMod);
2199 clkcontrol = new IO_SignalControl(in ? '1' : '0');
2200 }
2201
2202 PinMod->setSource(clksource);
2203 PinMod->setControl(clkcontrol);
2204 PinMod->updatePinModule();
2205 }
2206 }
2207
2208
2209 // This function reverses the effects of the previous function
clr_clk_pin(unsigned int pkg_Pin_Number,PinModule * PinMod,PicPortRegister * m_port,PicTrisRegister * m_tris,PicLatchRegister * m_lat)2210 void pic_processor::clr_clk_pin(unsigned int pkg_Pin_Number,
2211 PinModule *PinMod,
2212 PicPortRegister *m_port,
2213 PicTrisRegister *m_tris,
2214 PicLatchRegister *m_lat)
2215 {
2216 IOPIN *m_pin = package->get_pin(pkg_Pin_Number);
2217 m_pin->newGUIname(package->get_pin_name(pkg_Pin_Number).c_str());
2218
2219 if (PinMod)
2220 {
2221 if (m_port)
2222 {
2223 unsigned int mask = m_port->getEnableMask();
2224 mask |= (1 << PinMod->getPinNumber());
2225 m_port->setEnableMask(mask);
2226
2227 if (m_tris)
2228 {
2229 m_tris->setEnableMask(mask);
2230 }
2231
2232 if (m_lat)
2233 {
2234 m_lat->setEnableMask(mask);
2235 }
2236 }
2237
2238 PinMod->setSource(nullptr);
2239 PinMod->setControl(nullptr);
2240 PinMod->updatePinModule();
2241 }
2242 }
2243
2244
osc_mode(unsigned int value)2245 void pic_processor::osc_mode(unsigned int value)
2246 {
2247 IOPIN *m_pin;
2248 unsigned int pin_Number = get_osc_pin_Number(0);
2249
2250 if (pin_Number < 253)
2251 {
2252 m_pin = package->get_pin(pin_Number);
2253 }
2254
2255 if ((pin_Number = get_osc_pin_Number(1)) < 253 &&
2256 (m_pin = package->get_pin(pin_Number)))
2257 {
2258 pll_factor = 0;
2259
2260 if (value < 5)
2261 {
2262 set_clk_pin(pin_Number, m_osc_Monitor[1], "OSC2", true);
2263
2264 }
2265 else if (value == 6)
2266 {
2267 pll_factor = 2;
2268 set_clk_pin(pin_Number, m_osc_Monitor[1], "CLKO", false);
2269
2270 }
2271 else
2272 {
2273 clr_clk_pin(pin_Number, m_osc_Monitor[1]);
2274 }
2275 }
2276 }
2277
2278
Wput(unsigned int value)2279 void pic_processor::Wput(unsigned int value)
2280 {
2281 Wreg->put(value);
2282 }
2283
2284
Wget()2285 unsigned int pic_processor::Wget()
2286 {
2287 return Wreg->get();
2288 }
2289