C.1.4 Board code

The header file and c++ code file with comments are listed in the next two subsections. This files control the behavior of board in simulator.

board_x.h

board_x.h online file.

board_x.h online doxygen version.

1/* ######################################################################## 
2 
3            PICsimLab - PIC laboratory simulator 
4 
5            ######################################################################## 
6 
7            Copyright (c) : 2015-2021  Luis Claudio Gambôa Lopes 
8 
9            This program is free software; you can redistribute it and/or modify 
10            it under the terms of the GNU General Public License as published by 
11            the Free Software Foundation; either version 2, or (at your option) 
12            any later version. 
13 
14            This program is distributed in the hope that it will be useful, 
15            but WITHOUT ANY WARRANTY; without even the implied warranty of 
16            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
17            GNU General Public License for more details. 
18 
19            You should have received a copy of the GNU General Public License 
20            along with this program; if not, write to the Free Software 
21            Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
22 
23            For e-mail suggestions :  lcgamboa@yahoo.com 
24            ######################################################################## */ 
25 
26#ifndef BOARD_x_H 
27#define        BOARD_x_H 
28 
29#include<lxrad.h> 
30 
31#include "bsim_picsim.h" 
32 
33#define        BOARD_x_Name "X" 
34 
35//new board class must be derived from board class defined in board.h 
36class cboard_x:public bsim_picsim 
37{ 
38        private: 
39                   unsigned char p_BT1;           //first board push button in RD0 
40                   unsigned char p_BT2;           //second board switch in RD1   
41                    
42                   //value of potentiometer 
43                   unsigned char pot1; 
44                   //flag to control if potentiometer is active 
45                   unsigned char active; 
46                    
47                   //controls to be added in simulator window  
48                   CGauge *gauge1;   //gauge to show mean value of RB0 
49                   CGauge *gauge2;   //gauge to show mean value of RB1 
50                   CLabel *label2;   //label of gauge RB0 
51                   CLabel *label3;   //label of gauge RB1 
52                    
53                   //Register controls for remote interface called once on board creation  
54                   void RegisterRemoteControl(void);   
55                    
56                   lxColor color1;//LEDs color 1 
57                   lxColor color2;//LEDs color 2    
58                   lxFont font; 
59            public: 
60                       //Constructor called once on board creation  
61                       cboard_x(void); 
62                       //Destructor called once on board destruction  
63                       ~cboard_x(void);  
64                       //Return the board name 
65                       lxString GetName(void) {return lxT(BOARD_x_Name); };  
66                       //Return the about info of board 
67                       lxString GetAboutInfo(void){return lxT("L.C. Gamboa \n <lcgamboa@yahoo.com>");}; 
68                       //Called ever 100ms to draw board 
69                       void Draw(CDraw *draw); 
70                       void Run_CPU(void); 
71                       //Return a list of board supported microcontrollers 
72                       lxString GetSupportedDevices(void){return lxT("PIC16F877A,PIC18F4550,PIC18F4620,");}; 
73                       //Reset board status 
74                       void Reset(void); 
75                       //Event on the board 
76                       void EvMouseButtonPress(uint button, uint x, uint y,uint state); 
77                       //Event on the board 
78                       void EvMouseButtonRelease(uint button, uint x, uint y,uint state); 
79                       //Event on the board 
80                       void EvMouseMove(uint button, uint x, uint y, uint state); 
81                       //Event on the board 
82                       void EvKeyPress(uint key,uint mask); 
83                       //Event on the board 
84                       void EvKeyRelease(uint key,uint mask); 
85                       //Called ever 1s to refresh status 
86                       void RefreshStatus(void); 
87                       //Called to save board preferences in configuration file 
88                       void WritePreferences(void); 
89                       //Called whe configuration file load  preferences  
90                       void ReadPreferences(char *name,char *value); 
91                       //return the input ids numbers of names used in input map 
92                       unsigned short get_in_id(char * name); 
93                       //return the output ids numbers of names used in output map 
94                       unsigned short get_out_id(char * name); 
95}; 
96 
97#endif        /* BOARD_x_H */ 
98

board_x.cc

board_x.cc online file.

board_x.cc online doxygen version.

1/* ######################################################################## 
2 
3            PICsimLab - PIC laboratory simulator 
4 
5            ######################################################################## 
6 
7            Copyright (c) : 2015-2021  Luis Claudio Gambôa Lopes 
8 
9            This program is free software; you can redistribute it and/or modify 
10            it under the terms of the GNU General Public License as published by 
11            the Free Software Foundation; either version 2, or (at your option) 
12            any later version. 
13 
14            This program is distributed in the hope that it will be useful, 
15            but WITHOUT ANY WARRANTY; without even the implied warranty of 
16            MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
17            GNU General Public License for more details. 
18 
19            You should have received a copy of the GNU General Public License 
20            along with this program; if not, write to the Free Software 
21            Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
22 
23            For e-mail suggestions :  lcgamboa@yahoo.com 
24            ######################################################################## */ 
25 
26//include files 
27#include"../picsimlab1.h" 
28#include"../picsimlab4.h" //Oscilloscope 
29#include"../picsimlab5.h" //Spare Parts 
30#include"board_x.h" 
31 
32/* ids of inputs of input map*/ 
33enum 
34{ 
35    I_POT1, //potentiometer    
36    I_ICSP, //ICSP connector 
37    I_PWR, //Power button 
38    I_RST, //Reset button 
39    I_BD0, //RD0 push button 
40    I_SD1 //RD1 switch 
41}; 
42 
43/* ids of outputs of output map*/ 
44enum 
45{ 
46    O_POT1, //potentiometer   
47    O_RST, //Reset button 
48    O_SD1, //switch position (On/Off) 
49    O_LD0, //LED on RD0 push button 
50    O_LD1, //LED on RD1 switch 
51    O_LPWR, //Power LED 
52    O_RB0, //LED on RB0 output 
53    O_RB1, //LED on RB1 output 
54    O_BD0, //RD1 switch      
55    O_CPU //CPU name 
56}; 
57 
58//return the input ids numbers of names used in input map 
59 
60unsigned short 
61cboard_x::get_in_id(char * name) 
62{ 
63    if (strcmp (name, "PG_ICSP") == 0)return I_ICSP; 
64    if (strcmp (name, "SW_PWR") == 0)return I_PWR; 
65    if (strcmp (name, "PB_RST") == 0)return I_RST; 
66    if (strcmp (name, "PB_D0") == 0)return I_BD0; 
67    if (strcmp (name, "SW_D1") == 0)return I_SD1; 
68    if (strcmp (name, "PO_1") == 0)return I_POT1; 
69 
70    printf ("Error input '%s' don't have a valid id! \n", name); 
71    return -1; 
72} 
73 
74//return the output ids numbers of names used in output map 
75 
76unsigned short 
77cboard_x::get_out_id(char * name) 
78{ 
79 
80    if (strcmp (name, "SW_D1") == 0)return O_SD1; 
81    if (strcmp (name, "LD_LD0") == 0)return O_LD0; 
82    if (strcmp (name, "LD_LD1") == 0)return O_LD1; 
83    if (strcmp (name, "LD_LPWR") == 0)return O_LPWR; 
84    if (strcmp (name, "LD_RB1") == 0)return O_RB1; 
85    if (strcmp (name, "LD_RB0") == 0)return O_RB0; 
86    if (strcmp (name, "PB_D0") == 0)return O_BD0; 
87    if (strcmp (name, "PO_1") == 0)return O_POT1; 
88    if (strcmp (name, "PB_RST") == 0)return O_RST; 
89    if (strcmp (name, "IC_CPU") == 0)return O_CPU; 
90 
91    printf ("Error output '%s' don't have a valid id! \n", name); 
92    return 1; 
93} 
94 
95//Constructor called once on board creation  
96 
97cboard_x::cboard_x(void) : 
98font(10, lxFONTFAMILY_TELETYPE, lxFONTSTYLE_NORMAL, lxFONTWEIGHT_BOLD) 
99{ 
100    Proc = "PIC18F4550"; //default microcontroller if none defined in preferences 
101    ReadMaps (); //Read input and output board maps 
102 
103    pot1 = 100; 
104 
105    active = 0; 
106 
107    //controls properties and creation 
108    //gauge1 
109    gauge1 = new CGauge (); 
110    gauge1->SetFOwner (&Window1); 
111    gauge1->SetName (lxT ("gauge1_px")); 
112    gauge1->SetX (13); 
113    gauge1->SetY (382 - 160); 
114    gauge1->SetWidth (140); 
115    gauge1->SetHeight (20); 
116    gauge1->SetEnable (1); 
117    gauge1->SetVisible (1); 
118    gauge1->SetRange (100); 
119    gauge1->SetValue (0); 
120    gauge1->SetType (4); 
121    Window1.CreateChild (gauge1); 
122    //gauge2 
123    gauge2 = new CGauge (); 
124    gauge2->SetFOwner (&Window1); 
125    gauge2->SetName (lxT ("gauge2_px")); 
126    gauge2->SetX (12); 
127    gauge2->SetY (330 - 160); 
128    gauge2->SetWidth (140); 
129    gauge2->SetHeight (20); 
130    gauge2->SetEnable (1); 
131    gauge2->SetVisible (1); 
132    gauge2->SetRange (100); 
133    gauge2->SetValue (0); 
134    gauge2->SetType (4); 
135    Window1.CreateChild (gauge2); 
136    //label2 
137    label2 = new CLabel (); 
138    label2->SetFOwner (&Window1); 
139    label2->SetName (lxT ("label2_px")); 
140    label2->SetX (12); 
141    label2->SetY (306 - 160); 
142    label2->SetWidth (60); 
143    label2->SetHeight (20); 
144    label2->SetEnable (1); 
145    label2->SetVisible (1); 
146    label2->SetText (lxT ("RB0")); 
147    label2->SetAlign (1); 
148    Window1.CreateChild (label2); 
149    //label3 
150    label3 = new CLabel (); 
151    label3->SetFOwner (&Window1); 
152    label3->SetName (lxT ("label3_px")); 
153    label3->SetX (13); 
154    label3->SetY (357 - 160); 
155    label3->SetWidth (60); 
156    label3->SetHeight (20); 
157    label3->SetEnable (1); 
158    label3->SetVisible (1); 
159    label3->SetText (lxT ("RB1")); 
160    label3->SetAlign (1); 
161    Window1.CreateChild (label3); 
162} 
163 
164//Destructor called once on board destruction  
165 
166cboard_x::~cboard_x(void) 
167{ 
168    //controls destruction  
169    Window1.DestroyChild (gauge1); 
170    Window1.DestroyChild (gauge2); 
171    Window1.DestroyChild (label2); 
172    Window1.DestroyChild (label3); 
173} 
174 
175//Reset board status 
176 
177void 
178cboard_x::Reset(void) 
179{ 
180    pic_reset (1); 
181 
182    p_BT1 = 1; //set push button  in default state (high)  
183 
184    //write button state to pic pin 19 (RD0) 
185    pic_set_pin (19, p_BT1); 
186    //write switch state to pic pin 20 (RD1) 
187    pic_set_pin (20, p_BT2); 
188 
189 
190    //verify serial port state and refresh status bar   
191#ifndef _WIN_ 
192    if (pic.serial[0].serialfd > 0) 
193#else 
194    if (pic.serial[0].serialfd != INVALID_HANDLE_VALUE) 
195#endif 
196        Window1.statusbar1.SetField (2, lxT ("Serial: ") + 
197                                                                                                                       lxString::FromAscii (SERIALDEVICE) + lxT (":") + itoa (pic.serial[0].serialbaud) + lxT ("(") + 
198                                                                                                                       lxString ().Format ("%4.1f", fabs ((100.0 * pic.serial[0].serialexbaud - 100.0 * 
199                                                                                                                                                                                                                                                                 pic.serial[0].serialbaud) / pic.serial[0].serialexbaud)) + lxT ("%)")); 
200    else 
201        Window1.statusbar1.SetField (2, lxT ("Serial: ") + 
202                                                                                                                       lxString::FromAscii (SERIALDEVICE) + lxT (" (ERROR)")); 
203 
204    if (use_spare)Window5.Reset (); 
205 
206    RegisterRemoteControl (); 
207} 
208 
209//Register variables to be controled by remote control 
210 
211void 
212cboard_x::RegisterRemoteControl(void) 
213{ 
214    //register inputa 
215    input_ids[I_BD0]->status = &p_BT1; 
216    input_ids[I_SD1]->status = &p_BT2; 
217    input_ids[I_POT1]->status = &pot1; 
218     
219    //register output to be updated on input change 
220    input_ids[I_BD0]->update = &output_ids[O_BD0]->update; 
221    input_ids[I_SD1]->update = &output_ids[O_SD1]->update; 
222    input_ids[I_POT1]->update = &output_ids[O_POT1]->update; 
223     
224    //register outputa 
225    output_ids[O_RB0]->status = &pic.pins[32].oavalue; 
226    output_ids[O_RB1]->status = &pic.pins[33].oavalue; 
227    output_ids[O_LD0]->status = &pic.pins[18].oavalue; 
228    output_ids[O_LD1]->status = &pic.pins[19].oavalue; 
229} 
230 
231//Called ever 1s to refresh status 
232 
233void 
234cboard_x::RefreshStatus(void) 
235{ 
236    //verify serial port state and refresh status bar    
237#ifndef _WIN_ 
238    if (pic.serial[0].serialfd > 0) 
239#else 
240    if (pic.serial[0].serialfd != INVALID_HANDLE_VALUE) 
241#endif 
242        Window1.statusbar1.SetField (2, lxT ("Serial: ") + 
243                                                                                                                       lxString::FromAscii (SERIALDEVICE) + lxT (":") + itoa (pic.serial[0].serialbaud) + lxT ("(") + 
244                                                                                                                       lxString ().Format ("%4.1f", fabs ((100.0 * pic.serial[0].serialexbaud - 100.0 * 
245 pic.serial[0].serialbaud) / pic.serial[0].serialexbaud)) + lxT ("%)")); 
246 else 
247 Window1.statusbar1.SetField (2, lxT ("Serial: ") + 
248 lxString::FromAscii (SERIALDEVICE) + lxT (" (ERROR)")); 
249 
250} 
251 
252//Called to save board preferences in configuration file 
253 
254void 
255cboard_x::WritePreferences(void) 
256{ 
257 //write selected microcontroller of board_x to preferences 
258 Window1.saveprefs (lxT ("X_proc"), Proc); 
259 //write switch state of board_x to preferences  
260 Window1.saveprefs (lxT ("X_bt2"), lxString ().Format ("%i", p_BT2)); 
261 //write microcontroller clock to preferences 
262 Window1.saveprefs (lxT ("X_clock"), lxString ().Format ("%2.1f", Window1.GetClock ())); 
263 //write potentiometer position to preferences 
264 Window1.saveprefs (lxT ("X_pot1"), lxString ().Format ("%i", pot1)); 
265} 
266 
267//Called whe configuration file load preferences  
268 
269void 
270cboard_x::ReadPreferences(char *name, char *value) 
271{ 
272 //read switch state of board_x of preferences  
273 if (!strcmp (name, "X_bt2")) 
274 { 
275 if (value[0] == '0') 
276 p_BT2 = 0; 
277 else 
278 p_BT2 = 1; 
279 } 
280 //read microcontroller of preferences 
281 if (!strcmp (name, "X_proc")) 
282 { 
283 Proc = value; 
284 } 
285 //read microcontroller clock 
286 if (!strcmp (name, "X_clock")) 
287 { 
288 Window1.SetClock (atof (value)); 
289 } 
290 
291 //read potentiometer position 
292 if (!strcmp (name, "X_pot1")) 
293 { 
294 pot1 = atoi (value); 
295 } 
296} 
297 
298 
299//Event on the board 
300 
301void 
302cboard_x::EvKeyPress(uint key, uint mask) 
303{ 
304 //if keyboard key 1 is pressed then activate button (state=0)  
305 if (key == '1') 
306 { 
307 p_BT1 = 0; 
308 output_ids[O_BD0]- >update = 1; 
309 } 
310 
311 //if keyboard key 2 is pressed then toggle switch state  
312 if (key == '2') 
313 { 
314 p_BT2 ^= 1; 
315 output_ids[O_SD1]- >update = 1; 
316 } 
317 
318} 
319 
320//Event on the board 
321 
322void 
323cboard_x::EvKeyRelease(uint key, uint mask) 
324{ 
325 //if keyboard key 1 is pressed then deactivate button (state=1)  
326 if (key == '1') 
327 { 
328 p_BT1 = 1; 
329 output_ids[O_BD0]- >update = 1; 
330 } 
331 
332} 
333 
334//Event on the board 
335 
336void 
337cboard_x::EvMouseButtonPress(uint button, uint x, uint y, uint state) 
338{ 
339 
340 int i; 
341 
342 //search for the input area which owner the event  
343 for (i = 0; i < inputc; i++) 
344 { 
345 if (((input[i].x1 <= x)&&(input[i].x2 >= x))&&((input[i].y1 <= y)&& 
346 (input[i].y2 >= y))) 
347 { 
348 
349 switch (input[i].id) 
350 { 
351 //if event is over I_ISCP area then load hex file  
352 case I_ICSP: 
353 Window1.menu1_File_LoadHex_EvMenuActive (NULL); 
354 break; 
355 //if event is over I_PWR area then toggle board on/off 
356 case I_PWR: 
357 if (Window1.Get_mcupwr ()) //if on turn off 
358 { 
359 Window1.Set_mcurun (0); 
360 Window1.Set_mcupwr (0); 
361 Reset (); 
362 p_BT1 = 1; 
363 Window1.statusbar1.SetField (0, lxT ("Stoped")); 
364 } 
365 else //if off turn on 
366 { 
367 Window1.Set_mcupwr (1); 
368 Window1.Set_mcurun (1); 
369 Reset (); 
370 Window1.statusbar1.SetField (0, lxT ("Running...")); 
371 } 
372 output_ids[O_LPWR]- >update = 1; 
373 break; 
374 //if event is over I_RST area then turn off and reset 
375 case I_RST: 
376 if (Window1.Get_mcupwr () && pic_reset (- 1))//if powered 
377 { 
378 Window1.Set_mcupwr (0); 
379 Window1.Set_mcurst (1); 
380 } 
381 p_RST = 0; 
382 output_ids[O_RST]- >update = 1; 
383 break; 
384 //if event is over I_D0 area then activate button (state=0)  
385 case I_BD0: 
386 p_BT1 = 0; 
387 output_ids[O_BD0]- >update = 1; 
388 break; 
389 //if event is over I_D1 area then toggle switch state  
390 case I_SD1: 
391 p_BT2 ^= 1; 
392 output_ids[O_SD1]- >update = 1; 
393 break; 
394 case I_POT1: 
395 { 
396 active = 1; 
397 pot1 = (x -  input[i].x1)*2.77; 
398 if (pot1 > 199)pot1 = 199; 
399 output_ids[O_POT1]- >update = 1; 
400 } 
401 break; 
402 } 
403 } 
404 } 
405 
406} 
407 
408//Event on the board 
409 
410void 
411cboard_x::EvMouseMove(uint button, uint x, uint y, uint state) 
412{ 
413 int i; 
414 
415 for (i = 0; i < inputc; i++) 
416 { 
417 switch (input[i].id) 
418 { 
419 case I_POT1: 
420 if (((input[i].x1 <= x)&&(input[i].x2 >= x))&&((input[i].y1 <= y)&&(input[i].y2 >= y))) 
421 { 
422 if (active) 
423 { 
424 pot1 = (x -  input[i].x1)*2.77; 
425 if (pot1 > 199)pot1 = 199; 
426 output_ids[O_POT1]- >update = 1; 
427 } 
428 } 
429 break; 
430 } 
431 } 
432} 
433 
434//Event on the board 
435 
436void 
437cboard_x::EvMouseButtonRelease(uint button, uint x, uint y, uint state) 
438{ 
439 int i; 
440 
441 //search for the input area which owner the event  
442 for (i = 0; i < inputc; i++) 
443 { 
444 if (((input[i].x1 <= x)&&(input[i].x2 >= x))&&((input[i].y1 <= y)&& 
445 (input[i].y2 >= y))) 
446 { 
447 switch (input[i].id) 
448 { 
449 //if event is over I_RST area then turn on  
450 case I_RST: 
451 if (Window1.Get_mcurst ())//if powered 
452 { 
453 Window1.Set_mcupwr (1); 
454 Window1.Set_mcurst (0); 
455 
456 if (pic_reset (- 1)) 
457 { 
458 Reset (); 
459 } 
460 } 
461 p_RST = 1; 
462 output_ids[O_RST]- >update = 1; 
463 break; 
464 //if event is over I_D0 area then deactivate button (state=1)  
465 case I_BD0: 
466 p_BT1 = 1; 
467 output_ids[O_BD0]- >update = 1; 
468 break; 
469 case I_POT1: 
470 { 
471 active = 0; 
472 output_ids[O_POT1]- >update = 1; 
473 } 
474 break; 
475 } 
476 } 
477 } 
478 
479} 
480 
481 
482//Called ever 100ms to draw board 
483//This is the critical code for simulator running speed 
484 
485void 
486cboard_x::Draw(CDraw *draw) 
487{ 
488 int update = 0; //verifiy if updated is needed 
489 int i; 
490 
491 
492 //board_x draw  
493 for (i = 0; i < outputc; i++) //run over all outputs 
494 { 
495 if (output[i].update)//only if need update 
496 { 
497 output[i].update = 0; 
498 
499 if (!update) 
500 { 
501 draw- >Canvas.Init (Scale, Scale); 
502 } 
503 update++; //set to update buffer 
504 
505 if (!output[i].r)//if output shape is a rectangle 
506 { 
507 if (output[i].id == O_SD1)//if output is switch 
508 { 
509 //draw a background white rectangle  
510 draw- >Canvas.SetBgColor (255, 255, 255); 
511 draw- >Canvas.Rectangle (1, output[i].x1, output[i].y1, 
512 output[i].x2 -  output[i].x1, output[i].y2 -  output[i].y1); 
513 
514 if (!p_BT2) //draw switch off 
515 { 
516 //draw a grey rectangle  
517 draw- >Canvas.SetBgColor (70, 70, 70); 
518 draw- >Canvas.Rectangle (1, output[i].x1, output[i].y1 + 
519 ((int) ((output[i].y2 -  output[i].y1)*0.35)), output[i].x2 -  output[i].x1, 
520 (int) ((output[i].y2 -  output[i].y1)*0.65)); 
521 } 
522 else //draw switch on 
523 { 
524 //draw a grey rectangle  
525 draw- >Canvas.SetBgColor (70, 70, 70); 
526 draw- >Canvas.Rectangle (1, output[i].x1, 
527 output[i].y1, output[i].x2 -  output[i].x1, 
528 (int) ((output[i].y2 -  output[i].y1)*0.65)); 
529 } 
530 } 
531 else if (output[i].id == O_BD0) 
532 { 
533 draw- >Canvas.SetColor (102, 102, 102); 
534 draw- >Canvas.Circle (1, output[i].cx, output[i].cy, 10); 
535 if (p_BT1) 
536 { 
537 draw- >Canvas.SetColor (15, 15, 15); 
538 } 
539 else 
540 { 
541 draw- >Canvas.SetColor (55, 55, 55); 
542 } 
543 draw- >Canvas.Circle (1, output[i].cx, output[i].cy, 8); 
544 } 
545 else if (output[i].id == O_RST) 
546 { 
547 draw- >Canvas.SetColor (102, 102, 102); 
548 draw- >Canvas.Circle (1, output[i].cx, output[i].cy, 10); 
549 
550 if (p_RST) 
551 { 
552 draw- >Canvas.SetColor (15, 15, 15); 
553 } 
554 else 
555 { 
556 draw- >Canvas.SetColor (55, 55, 55); 
557 } 
558 draw- >Canvas.Circle (1, output[i].cx, output[i].cy, 8); 
559 } 
560 else if (output[i].id == O_POT1) 
561 { 
562 draw- >Canvas.SetColor (0, 50, 215); 
563 draw- >Canvas.Rectangle (1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, output[i].y2 -  output[i].y1); 
564 draw- >Canvas.SetColor (250, 250, 250); 
565 draw- >Canvas.Rectangle (1, output[i].x1 + pot1 / 2.77, output[i].y1 + 2, 10, 15); 
566 } 
567 else if (output[i].id == O_CPU) 
568 { 
569 draw- >Canvas.SetFont (font); 
570 int x, y, w, h; 
571 draw- >Canvas.SetColor (26, 26, 26); 
572 draw- >Canvas.Rectangle (1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, output[i].y2 -  output[i].y1); 
573 
574 draw- >Canvas.SetColor (230, 230, 230); 
575 w = output[i].x2 -  output[i].x1; 
576 h = output[i].y2 -  output[i].y2; 
577 x = output[i].x1 + (w / 2) + 7; 
578 y = output[i].y1 + (h / 2) + (Proc.length ()); 
579 draw- >Canvas.RotatedText (Proc, x, y, 270); 
580 } 
581 } 
582 else //if output shape is a circle 
583 { 
584 draw- >Canvas.SetFgColor (0, 0, 0); //black 
585 
586 switch (output[i].id)//search for color of output 
587 { 
588 case O_LD0: //White using pin 19 mean value (RD0) 
589 draw- >Canvas.SetBgColor (pic.pins[18].oavalue, pic.pins[18].oavalue, pic.pins[18].oavalue); 
590 break; 
591 case O_LD1: //Yelllow using pin 20 mean value (RD1) 
592 draw- >Canvas.SetBgColor (pic.pins[19].oavalue, pic.pins[19].oavalue, 0); 
593 break; 
594 case O_LPWR: //Blue using mcupwr value 
595 draw- >Canvas.SetBgColor (0, 0, 200 * Window1.Get_mcupwr () + 55); 
596 break; 
597 case O_RB0: //Green using pin 33 mean value (RB0) 
598 draw- >Canvas.SetBgColor (0, pic.pins[32].oavalue, 0); 
599 break; 
600 case O_RB1: //Red using pin 34 mean value (RB1) 
601 draw- >Canvas.SetBgColor (pic.pins[33].oavalue, 0, 0); 
602 break; 
603 } 
604 
605 //draw a LED 
606 color1 = draw- >Canvas.GetBgColor (); 
607 int r = color1.Red () -  120; 
608 int g = color1.Green () -  120; 
609 int b = color1.Blue () -  120; 
610 if (r < 0)r = 0; 
611 if (g < 0)g = 0; 
612 if (b < 0)b = 0; 
613 color2.Set (r, g, b); 
614 draw- >Canvas.SetBgColor (color2); 
615 draw- >Canvas.Circle (1, output[i].x1, output[i].y1, output[i].r + 1); 
616 draw- >Canvas.SetBgColor (color1); 
617 draw- >Canvas.Circle (1, output[i].x1, output[i].y1, output[i].r -  2); 
618 } 
619 } 
620 } 
621 //end draw 
622 
623 if (update) 
624 { 
625 draw- >Canvas.End (); 
626 draw- >Update (); 
627 } 
628 
629 //RB0 mean value to gauge1 
630 gauge1- >SetValue ((pic.pins[33].oavalue -  55) / 2); 
631 //RB1 mean value to gauge2 
632 gauge2- >SetValue ((pic.pins[32].oavalue -  55) / 2); 
633 
634} 
635 
636void 
637cboard_x::Run_CPU(void) 
638{ 
639 int i; 
640 int j; 
641 unsigned char pi; 
642 const picpin * pins; 
643 unsigned int alm[40]; 
644 
645 int JUMPSTEPS = Window1.GetJUMPSTEPS (); //number of steps skipped 
646 long int NSTEP = Window1.GetNSTEP () / MGetPinCount (); //number of steps in 100ms 
647 
648 
649 //reset pins mean value 
650 memset (alm, 0, 40 * sizeof (unsigned int)); 
651 
652 //read pic.pins to a local variable to speed up  
653 pins = pic.pins; 
654 
655 //Spare parts window pre process 
656 if (use_spare)Window5.PreProcess (); 
657 
658 j = JUMPSTEPS; //step counter 
659 if (Window1.Get_mcupwr ()) //if powered 
660 for (i = 0; i < Window1.GetNSTEP (); i++) //repeat for number of steps in 100ms 
661 { 
662 
663 if (j >= JUMPSTEPS)//if number of step is bigger than steps to skip  
664 { 
665 pic_set_pin (pic.mclr, p_RST); 
666 pic_set_pin (19, p_BT1); //Set pin 19 (RD0) with button state  
667 pic_set_pin (20, p_BT2); //Set pin 20 (RD1) with switch state  
668 } 
669 
670 //verify if a breakpoint is reached if not run one instruction  
671 if (!mplabxd_testbp ())pic_step (); 
672 //Oscilloscope window process 
673 if (use_oscope)Window4.SetSample (); 
674 //Spare parts window process 
675 if (use_spare)Window5.Process (); 
676 
677 //increment mean value counter if pin is high 
678 alm[i % pic.PINCOUNT] += pins[i % pic.PINCOUNT].value; 
679 
680 if (j >= JUMPSTEPS)//if number of step is bigger than steps to skip  
681 { 
682 
683 //set analog pin 2 (AN0) with value from scroll  
684 pic_set_apin (2, (5.0 * pot1 / 199)); 
685 
686 j = - 1; //reset counter 
687 } 
688 j++; //counter increment 
689 } 
690 
691 //calculate mean value 
692 for (pi = 0; pi < pic.PINCOUNT; pi++) 
693 { 
694 pic.pins[pi].oavalue = (int) (((200.0 * alm[pi]) / NSTEP) + 55); 
695 } 
696 
697 //Spare parts window pre post process 
698 if (use_spare)Window5.PostProcess (); 
699 
700 //verifiy if LEDS need update  
701 if (output_ids[O_LD0]- >value != pic.pins[18].oavalue) 
702 { 
703 output_ids[O_LD0]- >value = pic.pins[18].oavalue; 
704 output_ids[O_LD0]- >update = 1; 
705 } 
706 if (output_ids[O_LD1]- >value != pic.pins[19].oavalue) 
707 { 
708 output_ids[O_LD1]- >value = pic.pins[19].oavalue; 
709 output_ids[O_LD1]- >update = 1; 
710 } 
711 if (output_ids[O_RB0]- >value != pic.pins[32].oavalue) 
712 { 
713 output_ids[O_RB0]- >value = pic.pins[32].oavalue; 
714 output_ids[O_RB0]- >update = 1; 
715 } 
716 if (output_ids[O_RB1]- >value != pic.pins[33].oavalue) 
717 { 
718 output_ids[O_RB1]- >value = pic.pins[33].oavalue; 
719 output_ids[O_RB1]- >update = 1; 
720 } 
721 
722} 
723 
724 
725//Register the board in PICSimLab 
726board_init(BOARD_x_Name, cboard_x); 
727