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