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 = &registers[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