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 - Programmable IC Simulator Laboratory 
4 
5   ######################################################################## 
6 
7   Copyright (c) : 2015-2025  Luis Claudio Gambôa Lopes <lcgamboa@yahoo.com> 
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 "../devices/swbounce.h" 
30#include "../sim_backend/bsim_picsim.h" 
31 
32#define BOARD_x_Name "X" 
33 
34// new board class must be derived from board class defined in board.h 
35class cboard_x : public bsim_picsim { 
36private: 
37    unsigned char p_BT1;  // first board push button in RD0 
38    unsigned char p_BT2;  // second board switch in RD1 
39 
40    // value of potentiometer 
41    unsigned char pot1; 
42    // flag to control if potentiometer is active 
43    unsigned char active; 
44 
45    // Register controls for remote interface called once on board creation 
46    void RegisterRemoteControl(void) override; 
47 
48    SWBounce_t bounce; 
49 
50public: 
51    // Constructor called once on board creation 
52    cboard_x(void); 
53    // Destructor called once on board destruction 
54    ~cboard_x(void); 
55    // Return the board name 
56    std::string GetName(void) override { return BOARD_x_Name; }; 
57    // Return the about info of board 
58    std::string GetAboutInfo(void) override { return "L.C. Gamboa \n <lcgamboa@yahoo.com>"; }; 
59    // Called ever 100ms to draw board 
60    void Draw(void) override; 
61    void Run_CPU(void) override; 
62    // Return a list of board supported microcontrollers 
63    std::string GetSupportedDevices(void) override { return "PIC16F877A,PIC18F4550,PIC18F4620,"; }; 
64    // Reset board status 
65    void Reset(void) override; 
66    // Event on the board 
67    void EvMouseButtonPress(unsigned int button, unsigned int x, unsigned int y, unsigned int state) override; 
68    // Event on the board 
69    void EvMouseButtonRelease(unsigned int button, unsigned int x, unsigned int y, unsigned int state) override; 
70    // Event on the board 
71    void EvMouseMove(unsigned int button, unsigned int x, unsigned int y, unsigned int state) override; 
72    // Event on the board 
73    void EvKeyPress(unsigned int key, unsigned int mask) override; 
74    // Event on the board 
75    void EvKeyRelease(unsigned int key, unsigned int mask) override; 
76    // Called ever 1s to refresh status 
77    void RefreshStatus(void) override; 
78    // Called to save board preferences in configuration file 
79    void WritePreferences(void) override; 
80    // Called whe configuration file load  preferences 
81    void ReadPreferences(char* name, char* value) override; 
82    // return the input ids numbers of names used in input map 
83    unsigned short GetInputId(char* name) override; 
84    // return the output ids numbers of names used in output map 
85    unsigned short GetOutputId(char* name) override; 
86}; 
87 
88#endif /* BOARD_x_H */
board_x.cc

board_x.cc online file.

board_x.cc online doxygen version.

1/* ######################################################################## 
2 
3   PICSimLab - Programmable IC Simulator Laboratory 
4 
5   ######################################################################## 
6 
7   Copyright (c) : 2015-2025  Luis Claudio Gambôa Lopes <lcgamboa@yahoo.com> 
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 "board_x.h" 
28#include <math.h> 
29#include "../lib/oscilloscope.h" 
30#include "../lib/picsimlab.h" 
31#include "../lib/spareparts.h" 
32 
33/* ids of inputs of input map*/ 
34enum { 
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    O_POT1,  // potentiometer 
46    O_RST,   // Reset button 
47    O_SD1,   // switch position (On/Off) 
48    O_LD0,   // LED on RD0 push button 
49    O_LD1,   // LED on RD1 switch 
50    O_LPWR,  // Power LED 
51    O_RB0,   // LED on RB0 output 
52    O_RB1,   // LED on RB1 output 
53    O_BD0,   // RD1 switch 
54    O_CPU    // CPU name 
55}; 
56 
57enum { PWM0 = 1, PWM1 }; 
58 
59// return the input ids numbers of names used in input map 
60 
61unsigned short cboard_x::GetInputId(char* name) { 
62    if (strcmp(name, "PG_ICSP") == 0) 
63        return I_ICSP; 
64    if (strcmp(name, "SW_PWR") == 0) 
65        return I_PWR; 
66    if (strcmp(name, "PB_RST") == 0) 
67        return I_RST; 
68    if (strcmp(name, "PB_D0") == 0) 
69        return I_BD0; 
70    if (strcmp(name, "SW_D1") == 0) 
71        return I_SD1; 
72    if (strcmp(name, "PO_1") == 0) 
73        return I_POT1; 
74 
75    printf("Error input '%s' don't have a valid id! \n", name); 
76    return INVALID_ID; 
77} 
78 
79// return the output ids numbers of names used in output map 
80 
81unsigned short cboard_x::GetOutputId(char* name) { 
82    if (strcmp(name, "SW_D1") == 0) 
83        return O_SD1; 
84    if (strcmp(name, "LD_LD0") == 0) 
85        return O_LD0; 
86    if (strcmp(name, "LD_LD1") == 0) 
87        return O_LD1; 
88    if (strcmp(name, "LD_LPWR") == 0) 
89        return O_LPWR; 
90    if (strcmp(name, "LD_RB1") == 0) 
91        return O_RB1; 
92    if (strcmp(name, "LD_RB0") == 0) 
93        return O_RB0; 
94    if (strcmp(name, "PB_D0") == 0) 
95        return O_BD0; 
96    if (strcmp(name, "PO_1") == 0) 
97        return O_POT1; 
98    if (strcmp(name, "PB_RST") == 0) 
99        return O_RST; 
100    if (strcmp(name, "IC_CPU") == 0) 
101        return O_CPU; 
102 
103    printf("Error output '%s' don't have a valid id! \n", name); 
104    return INVALID_ID; 
105} 
106 
107// Constructor called once on board creation 
108 
109cboard_x::cboard_x(void) { 
110    Proc = "PIC18F4550";  // default microcontroller if none defined in preferences 
111    ReadMaps();           // Read input and output board maps 
112 
113    pot1 = 100; 
114 
115    active = 0; 
116 
117    PICSimLab.UpdateGUI(PWM0, GT_GAUGE, GA_ADD, (void*)"*RB0"); 
118    PICSimLab.UpdateGUI(PWM1, GT_GAUGE, GA_ADD, (void*)"*RB1"); 
119 
120    SWBounce_init(&bounce, 2); 
121} 
122 
123// Destructor called once on board destruction 
124 
125cboard_x::~cboard_x(void) { 
126    PICSimLab.UpdateGUI(PWM0, GT_GAUGE, GA_DEL, NULL); 
127    PICSimLab.UpdateGUI(PWM1, GT_GAUGE, GA_DEL, NULL); 
128    SWBounce_end(&bounce); 
129} 
130 
131// Reset board status 
132 
133void cboard_x::Reset(void) { 
134    MReset(1); 
135 
136    p_BT1 = 1;  // set push button  in default state (high) 
137 
138    // write button state to pin 19 (RD0) 
139    MSetPin(19, p_BT1); 
140    // write switch state to pin 20 (RD1) 
141    MSetPin(20, p_BT2); 
142 
143    // verify serial port state and refresh status bar 
144    PICSimLab.UpdateStatus(PS_SERIAL, GetUARTStrStatus(0)); 
145 
146    if (use_spare) 
147        SpareParts.Reset(); 
148 
149    RegisterRemoteControl(); 
150} 
151 
152// Register variables to be controled by remote control 
153 
154void cboard_x::RegisterRemoteControl(void) { 
155    // register inputa 
156    input_ids[I_BD0]->status = &p_BT1; 
157    input_ids[I_SD1]->status = &p_BT2; 
158    input_ids[I_POT1]->status = &pot1; 
159 
160    // register output to be updated on input change 
161    input_ids[I_BD0]->update = &output_ids[O_BD0]->update; 
162    input_ids[I_SD1]->update = &output_ids[O_SD1]->update; 
163    input_ids[I_POT1]->update = &output_ids[O_POT1]->update; 
164 
165    // register outputa 
166    output_ids[O_RB0]->status = MGetPinOAVPtr(33); 
167    output_ids[O_RB1]->status = MGetPinOAVPtr(34); 
168    output_ids[O_LD0]->status = MGetPinOAVPtr(19); 
169    output_ids[O_LD1]->status = MGetPinOAVPtr(20); 
170} 
171 
172// Called ever 1s to refresh status 
173 
174void cboard_x::RefreshStatus(void) { 
175    // verify serial port state and refresh status bar 
176    PICSimLab.UpdateStatus(PS_SERIAL, GetUARTStrStatus(0)); 
177} 
178 
179// Called to save board preferences in configuration file 
180 
181void cboard_x::WritePreferences(void) { 
182    // write selected microcontroller of board_x to preferences 
183    PICSimLab.SavePrefs("X_proc", Proc); 
184    // write switch state of board_x to preferences 
185    PICSimLab.SavePrefs("X_bt2", std::to_string(p_BT2)); 
186    // write microcontroller clock to preferences 
187    PICSimLab.SavePrefs("X_clock", FloatStrFormat("%2.1f", PICSimLab.GetClock())); 
188    // write potentiometer position to preferences 
189    PICSimLab.SavePrefs("X_pot1", std::to_string(pot1)); 
190} 
191 
192// Called whe configuration file load  preferences 
193 
194void cboard_x::ReadPreferences(char* name, char* value) { 
195    // read switch state of board_x of preferences 
196    if (!strcmp(name, "X_bt2")) { 
197        if (value[0] == '0') 
198            p_BT2 = 0; 
199        else 
200            p_BT2 = 1; 
201    } 
202    // read microcontroller of preferences 
203    if (!strcmp(name, "X_proc")) { 
204        Proc = value; 
205    } 
206    // read microcontroller clock 
207    if (!strcmp(name, "X_clock")) { 
208        PICSimLab.SetClock(atof(value)); 
209    } 
210 
211    // read potentiometer position 
212    if (!strcmp(name, "X_pot1")) { 
213        pot1 = atoi(value); 
214    } 
215} 
216 
217// Event on the board 
218 
219void cboard_x::EvKeyPress(unsigned int key, unsigned int mask) { 
220    // if keyboard key 1 is pressed then activate button (state=0) 
221    if (key == '1') { 
222        p_BT1 = 0; 
223        output_ids[O_BD0]->update = 1; 
224    } 
225 
226    // if keyboard key 2 is pressed then toggle switch state 
227    if (key == '2') { 
228        p_BT2 ^= 1; 
229        output_ids[O_SD1]->update = 1; 
230    } 
231} 
232 
233// Event on the board 
234 
235void cboard_x::EvKeyRelease(unsigned int key, unsigned int mask) { 
236    // if keyboard key 1 is pressed then deactivate button (state=1) 
237    if (key == '1') { 
238        p_BT1 = 1; 
239        output_ids[O_BD0]->update = 1; 
240    } 
241} 
242 
243// Event on the board 
244 
245void cboard_x::EvMouseButtonPress(unsigned int button, unsigned int x, unsigned int y, unsigned int state) { 
246    int i; 
247 
248    // search for the input area which owner the event 
249    for (i = 0; i < inputc; i++) { 
250        if (((input[i].x1 <= x) && (input[i].x2 >= x)) && ((input[i].y1 <= y) && (input[i].y2 >= y))) { 
251            switch (input[i].id) { 
252                    // if event is over I_ISCP area then load hex file 
253                case I_ICSP: 
254                    PICSimLab.OpenLoadHexFileDialog(); 
255                    ; 
256                    break; 
257                    // if event is over I_PWR area then toggle board on/off 
258                case I_PWR: 
259                    if (PICSimLab.GetMcuPwr())  // if on turn off 
260                    { 
261                        PICSimLab.SetMcuPwr(0); 
262                        Reset(); 
263                        p_BT1 = 1; 
264                    } else  // if off turn on 
265                    { 
266                        PICSimLab.SetMcuPwr(1); 
267                        Reset(); 
268                    } 
269                    output_ids[O_LPWR]->update = 1; 
270                    break; 
271                    // if event is over I_RST area then turn off and reset 
272                case I_RST: 
273                    if (PICSimLab.GetMcuPwr() && MReset(- 1))  // if powered 
274                    { 
275                        PICSimLab.SetMcuPwr(0); 
276                        PICSimLab.SetMcuRst(1); 
277                    } 
278                    p_RST = 0; 
279                    output_ids[O_RST]- >update = 1; 
280                    break; 
281                    // if event is over I_D0 area then activate button (state=0) 
282                case I_BD0: 
283                    p_BT1 = 0; 
284                    output_ids[O_BD0]- >update = 1; 
285                    break; 
286                    // if event is over I_D1 area then toggle switch state 
287                case I_SD1: 
288                    p_BT2 ^= 1; 
289                    output_ids[O_SD1]- >update = 1; 
290                    break; 
291                case I_POT1: { 
292                    active = 1; 
293                    pot1 = (x -  input[i].x1) * 2.77; 
294                    if (pot1 > 199) 
295                        pot1 = 199; 
296                    output_ids[O_POT1]- >update = 1; 
297                } break; 
298            } 
299        } 
300    } 
301} 
302 
303// Event on the board 
304 
305void cboard_x::EvMouseMove(unsigned int button, unsigned int x, unsigned int y, unsigned int state) { 
306    int i; 
307 
308    for (i = 0; i < inputc; i++) { 
309        switch (input[i].id) { 
310            case I_POT1: 
311                if (((input[i].x1 <= x) && (input[i].x2 >= x)) && ((input[i].y1 <= y) && (input[i].y2 >= y))) { 
312                    if (active) { 
313                        pot1 = (x -  input[i].x1) * 2.77; 
314                        if (pot1 > 199) 
315                            pot1 = 199; 
316                        output_ids[O_POT1]- >update = 1; 
317                    } 
318                } else { 
319                    active = 0; 
320                } 
321                break; 
322        } 
323    } 
324} 
325 
326// Event on the board 
327 
328void cboard_x::EvMouseButtonRelease(unsigned int button, unsigned int x, unsigned int y, unsigned int state) { 
329    int i; 
330 
331    // search for the input area which owner the event 
332    for (i = 0; i < inputc; i++) { 
333        if (((input[i].x1 <= x) && (input[i].x2 >= x)) && ((input[i].y1 <= y) && (input[i].y2 >= y))) { 
334            switch (input[i].id) { 
335                    // if event is over I_RST area then turn on 
336                case I_RST: 
337                    if (PICSimLab.GetMcuRst())  // if powered 
338                    { 
339                        PICSimLab.SetMcuPwr(1); 
340                        PICSimLab.SetMcuRst(0); 
341 
342                        if (MReset(- 1)) { 
343                            Reset(); 
344                        } 
345                    } 
346                    p_RST = 1; 
347                    output_ids[O_RST]- >update = 1; 
348                    break; 
349                    // if event is over I_D0 area then deactivate button (state=1) 
350                case I_BD0: 
351                    p_BT1 = 1; 
352                    output_ids[O_BD0]- >update = 1; 
353                    break; 
354                case I_POT1: { 
355                    active = 0; 
356                    output_ids[O_POT1]- >update = 1; 
357                } break; 
358            } 
359        } 
360    } 
361} 
362 
363// Called ever 100ms to draw board 
364// This is the critical code for simulator running speed 
365 
366void cboard_x::Draw(void) { 
367    int update = 0;  // verifiy if updated is needed 
368    int i; 
369    const picpin* pins = MGetPinsValues(); 
370 
371    // board_x draw 
372    for (i = 0; i < outputc; i++)  // run over all outputs 
373    { 
374        if (output[i].update)  // only if need update 
375        { 
376            output[i].update = 0; 
377 
378            if (!update) { 
379                PICSimLab.CanvasCmd({.cmd = CC_INIT, .Init{Scale, Scale, 0}}); 
380                PICSimLab.CanvasCmd({.cmd = CC_SETFONTWEIGHT, .SetFontWeight{CC_FONTWEIGHT_BOLD}}); 
381            } 
382            update++;  // set to update buffer 
383 
384            if (!output[i].r)  // if output shape is a rectangle 
385            { 
386                if (output[i].id == O_SD1)  // if output is switch 
387                { 
388                    // draw a background white rectangle 
389                    PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, .SetBgColor{255, 255, 255}}); 
390                    PICSimLab.CanvasCmd({.cmd = CC_RECTANGLE, 
391                                         .Rectangle{1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, 
392                                                    output[i].y2 -  output[i].y1}}); 
393 
394                    if (!p_BT2)  // draw switch off 
395                    { 
396                        // draw a grey rectangle 
397                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, .SetBgColor{70, 70, 70}}); 
398                        PICSimLab.CanvasCmd( 
399                            {.cmd = CC_RECTANGLE, 
400                             .Rectangle{1, output[i].x1, output[i].y1 + ((int)((output[i].y2 -  output[i].y1) * 0.35)), 
401                                        output[i].x2 -  output[i].x1, ((output[i].y2 -  output[i].y1) * 0.65f)}}); 
402                    } else  // draw switch on 
403                    { 
404                        // draw a grey rectangle 
405                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, .SetBgColor{70, 70, 70}}); 
406                        PICSimLab.CanvasCmd({.cmd = CC_RECTANGLE, 
407                                             .Rectangle{1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, 
408                                                        ((output[i].y2 -  output[i].y1) * 0.65f)}}); 
409                    } 
410                } else if (output[i].id == O_BD0) { 
411                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{102, 102, 102}}); 
412                    PICSimLab.CanvasCmd({.cmd = CC_CIRCLE, .Circle{1, output[i].cx, output[i].cy, 10}}); 
413                    if (p_BT1) { 
414                        PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{15, 15, 15}}); 
415                    } else { 
416                        PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{55, 55, 55}}); 
417                    } 
418                    PICSimLab.CanvasCmd({.cmd = CC_CIRCLE, .Circle{1, output[i].cx, output[i].cy, 8}}); 
419                } else if (output[i].id == O_RST) { 
420                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{102, 102, 102}}); 
421                    PICSimLab.CanvasCmd({.cmd = CC_CIRCLE, .Circle{1, output[i].cx, output[i].cy, 10}}); 
422 
423                    if (p_RST) { 
424                        PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{15, 15, 15}}); 
425                    } else { 
426                        PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{55, 55, 55}}); 
427                    } 
428                    PICSimLab.CanvasCmd({.cmd = CC_CIRCLE, .Circle{1, output[i].cx, output[i].cy, 8}}); 
429                } else if (output[i].id == O_POT1) { 
430                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{0, 50, 215}}); 
431                    PICSimLab.CanvasCmd({.cmd = CC_RECTANGLE, 
432                                         .Rectangle{1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, 
433                                                    output[i].y2 -  output[i].y1}}); 
434                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{250, 250, 250}}); 
435                    PICSimLab.CanvasCmd( 
436                        {.cmd = CC_RECTANGLE, .Rectangle{1, output[i].x1 + pot1 / 2.77f, output[i].y1 + 2, 10, 15}}); 
437                } else if (output[i].id == O_CPU) { 
438                    PICSimLab.CanvasCmd({.cmd = CC_SETFONTSIZE, .SetFontSize{10}}); 
439                    float x, y; 
440                    int w, h; 
441                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{26, 26, 26}}); 
442                    PICSimLab.CanvasCmd({.cmd = CC_RECTANGLE, 
443                                         .Rectangle{1, output[i].x1, output[i].y1, output[i].x2 -  output[i].x1, 
444                                                    output[i].y2 -  output[i].y1}}); 
445 
446                    PICSimLab.CanvasCmd({.cmd = CC_SETCOLOR, .SetColor{230, 230, 230}}); 
447                    w = output[i].x2 -  output[i].x1; 
448                    h = output[i].y2 -  output[i].y2; 
449                    x = output[i].x1 + (w / 2) + 7; 
450                    y = output[i].y1 + (h / 2) + (Proc.length()); 
451                    PICSimLab.CanvasCmd({.cmd = CC_ROTATEDTEXT, .RotatedText{Proc.c_str(), x, y, 270}}); 
452                } 
453            } else  // if output shape is a circle 
454            { 
455                PICSimLab.CanvasCmd({.cmd = CC_SETFGCOLOR, .SetFgColor{0, 0, 0}});  // black 
456 
457                switch (output[i].id)  // search for color of output 
458                { 
459                    case O_LD0:  // White using pin 19 mean value (RD0) 
460                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, 
461                                             .SetBgColor{(unsigned int)pins[18].oavalue, (unsigned int)pins[18].oavalue, 
462                                                         (unsigned int)pins[18].oavalue}}); 
463                        break; 
464                    case O_LD1:  // Yelllow using pin 20 mean value (RD1) 
465                        PICSimLab.CanvasCmd( 
466                            {.cmd = CC_SETBGCOLOR, 
467                             .SetBgColor{(unsigned int)pins[19].oavalue, (unsigned int)pins[19].oavalue, 0}}); 
468                        break; 
469                    case O_LPWR:  // Blue using mcupwr value 
470                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, 
471                                             .SetBgColor{0, 0, (unsigned int)(200 * PICSimLab.GetMcuPwr() + 55)}}); 
472                        break; 
473                    case O_RB0:  // Green using pin 33 mean value (RB0) 
474                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, .SetBgColor{0, (unsigned int)pins[32].oavalue, 0}}); 
475                        break; 
476                    case O_RB1:  // Red using pin 34 mean value (RB1) 
477                        PICSimLab.CanvasCmd({.cmd = CC_SETBGCOLOR, .SetBgColor{(unsigned int)pins[33].oavalue, 0, 0}}); 
478                        break; 
479                } 
480 
481                DrawLED(PICSimLab.CanvasCmd, &output[i]); 
482            } 
483        } 
484    } 
485    // end draw 
486 
487    if (update) { 
488        PICSimLab.CanvasCmd({.cmd = CC_END}); 
489    } 
490 
491    int value = (pins[33].oavalue -  55) / 2;  // RB0 mean value 
492    PICSimLab.UpdateGUI(PWM0, GT_GAUGE, GA_SET, (void*)&value); 
493    value = (pins[32].oavalue -  55) / 2;  // RB1 mean value 
494    PICSimLab.UpdateGUI(PWM1, GT_GAUGE, GA_SET, (void*)&value); 
495} 
496 
497void cboard_x::Run_CPU(void) { 
498    int i; 
499    int j; 
500    unsigned char pi; 
501    const picpin* pins; 
502    unsigned int alm[40]; 
503    int bret; 
504 
505    const int JUMPSTEPS = PICSimLab.GetJUMPSTEPS();  // number of steps skipped 
506    const long int NSTEP = PICSimLab.GetNSTEP();     // number of steps in 100ms 
507    const float RNSTEP = 200.0 * MGetPinCount() / NSTEP; 
508 
509    // reset pins mean value 
510    memset(alm, 0, 40 * sizeof(unsigned int)); 
511 
512    // read pins to a local variable to speed up 
513    pins = MGetPinsValues(); 
514 
515    // Spare parts window pre process 
516    if (use_spare) 
517        SpareParts.PreProcess(); 
518 
519    SWBounce_prepare(&bounce, PICSimLab.GetBoard()- >MGetInstClockFreq()); 
520 
521    unsigned char p_BT1_ = p_BT1; 
522    unsigned char p_BT2_ = p_BT2; 
523 
524    if ((pins[19 -  1].dir == PD_IN) && (pins[19 -  1].value != p_BT1_)) { 
525        SWBounce_bounce(&bounce, 0); 
526    } 
527    if ((pins[20 -  1].dir == PD_IN) && (pins[20 -  1].value != p_BT2_)) { 
528        SWBounce_bounce(&bounce, 1); 
529    } 
530 
531    j = JUMPSTEPS;  // step counter 
532    pi = 0; 
533    if (PICSimLab.GetMcuPwr())       // if powered 
534        for (i = 0; i < NSTEP; i++)  // repeat for number of steps in 100ms 
535        { 
536            if (j >= JUMPSTEPS)  // if number of step is bigger than step to skip 
537            { 
538                MSetPin(MGetResetPin(), p_RST); 
539                if (!bounce.do_bounce) { 
540                    MSetPin(19, p_BT1_);  // Set pin 19 (RD0) with button state 
541                    MSetPin(20, p_BT2_);  // Set pin 20 (RD1) with switch state 
542                } 
543            } 
544 
545            if (bounce.do_bounce) { 
546                bret = SWBounce_process(&bounce); 
547                if (bret) { 
548                    if (bounce.bounce[0]) { 
549                        if (bret == 1) { 
550                            MSetPin(19, !pins[19 -  1].value); 
551                        } else { 
552                            MSetPin(19, p_BT1_); 
553                        } 
554                    } 
555                    if (bounce.bounce[1]) { 
556                        if (bret == 1) { 
557                            MSetPin(20, !pins[20 -  1].value); 
558                        } else { 
559                            MSetPin(20, p_BT2_); 
560                        } 
561                    } 
562                } 
563            } 
564 
565            // verify if a breakpoint is reached if not run one instruction 
566            if (!mplabxd_testbp()) 
567                MStep(); 
568            ioupdated = MGetIOUpdated(); 
569            InstCounterInc(); 
570            // Oscilloscope window process 
571            if (use_oscope) 
572                Oscilloscope.SetSample(); 
573            // Spare parts window process 
574            if (use_spare) 
575                SpareParts.Process(); 
576 
577            // increment mean value counter if pin is high 
578            alm[pi] += pins[pi].value; 
579            pi++; 
580            if (pi == MGetPinCount()) 
581                pi = 0; 
582 
583            if (j >= JUMPSTEPS)  // if number of step is bigger than steps to skip 
584            { 
585                // set analog pin 2 (AN0) with value from scroll 
586                MSetAPin(2, (5.0 * pot1 / 199)); 
587 
588                j = - 1;  // reset counter 
589            } 
590            j++;  // counter increment 
591            MClearIOUpdated(); 
592        } 
593 
594    // calculate mean value 
595    for (pi = 0; pi < MGetPinCount(); pi++) { 
596        MSetPinOAV(pi + 1, (alm[pi] * RNSTEP) + 55); 
597    } 
598 
599    // Spare parts window pre post process 
600    if (use_spare) 
601        SpareParts.PostProcess(); 
602 
603    // verifiy if LEDS need update 
604    if (output_ids[O_LD0]- >value != pins[18].oavalue) { 
605        output_ids[O_LD0]- >value = pins[18].oavalue; 
606        output_ids[O_LD0]- >update = 1; 
607    } 
608    if (output_ids[O_LD1]- >value != pins[19].oavalue) { 
609        output_ids[O_LD1]- >value = pins[19].oavalue; 
610        output_ids[O_LD1]- >update = 1; 
611    } 
612    if (output_ids[O_RB0]- >value != pins[32].oavalue) { 
613        output_ids[O_RB0]- >value = pins[32].oavalue; 
614        output_ids[O_RB0]- >update = 1; 
615    } 
616    if (output_ids[O_RB1]- >value != pins[33].oavalue) { 
617        output_ids[O_RB1]- >value = pins[33].oavalue; 
618        output_ids[O_RB1]- >update = 1; 
619    } 
620} 
621 
622// Register the board in PICSimLab 
623board_init(BOARD_x_Name, cboard_x);