[ucsim-p1516] Implement timer and 2 btn reset
[sdcc.git] / sdcc / sim / ucsim / src / sims / p1516.src / fpga.cc
bloba9d328ddd623539171a2663e62db661725380cb1
1 /*
2 * Simulator of microcontrollers (fpga.cc)
4 * Copyright (C) 2020 Drotos Daniel
5 *
6 * To contact author send email to dr.dkdb@gmail.com
8 */
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
28 #include "globals.h"
30 #include "p1516cl.h"
32 #include "fpgacl.h"
36 LED
37 -------------------------------------------------------------------------
40 cl_led::cl_led(class cl_fpga *the_fpga, int ax, int ay, u32_t amask):
41 cl_base()
43 fpga= the_fpga;
44 x= ax;
45 y= ay;
46 mask= amask;
47 last= 0;
50 void
51 cl_led::refresh(bool force)
53 class cl_hw_io *io= fpga->get_io();
54 u32_t a= fpga->pb->get() & mask;
55 u32_t l= last & mask;
56 if (force || (a != l))
58 io->tu_go(x, y);
59 if (a)
61 io->dd_cprintf("led_on", "@");
62 last|= mask;
64 else
66 io->dd_cprintf("led_off", ".");
67 last&= ~mask;
74 RGB LED
75 -------------------------------------------------------------------------
78 cl_rgb::cl_rgb(class cl_fpga *the_fpga, int ax, int ay, u32_t amask):
79 cl_led(the_fpga, ax, ay, amask)
81 last= 0;
84 void
85 cl_rgb::refresh(bool force)
87 u32_t gm= mask, rm= mask<<8, bm= mask<<16;
88 u32_t m= gm|rm|bm;
89 class cl_hw_io *io= fpga->get_io();
90 u32_t a= fpga->pb->get() & m;
91 u32_t l= last & m;
92 if (force || (a != l))
94 int c= 0;
95 io->tu_go(x, y);
96 if (a&gm) c|= 2;
97 if (a&rm) c|= 1;
98 if (a&bm) c|= 4;
99 if (a)
101 io->tu_fgcolor(c);
102 io->dd_printf("\033[1m");
104 else
105 io->dd_color("answer");
106 io->dd_printf("%c", a?'@':'.');
107 last&= ~m;
108 last|= a;
109 if (a) io->dd_color("answer");
115 7 SEGMENT DISPLAY
116 -------------------------------------------------------------------------
119 cl_seg::cl_seg(class cl_fpga *the_fpga, int ax, int ay, int adigit):
120 cl_led(the_fpga, ax, ay, 0)
122 digit= adigit;
125 static const char *dsp[3]= {
126 // 1 2 3 4
127 //1234567890123456789012345678901234567890123456789
128 " _ _ _ _ _ _ _ _ _ _ _ _ ",
129 "| | | _| _| |_| |_ |_ | |_| |_| |_| |_ | _| |_ |_ ",
130 "|_| | |_ _| | _| |_| | |_| _| | | |_| |_ |_| |_ | "
133 void
134 cl_seg::refresh(bool force)
136 class cl_hw_io *io= fpga->get_io();
137 u32_t sw= fpga->pj->read(), act, act_what;
138 u32_t l, mask, a, lw;
139 class cl_p1516 *uc= (class cl_p1516 *)(fpga->uc);
140 chars w= "non ";
141 bool direct= false;
142 int c= -digit + fpga->d2c_b;
143 u32_t b_c= fpga->bc->read(), ctr;
144 ctr= (b_c&1)?b_c:sw;
145 if (last_ctrl != ctr)
146 force= true;
147 last_ctrl= ctr;
148 switch ((ctr>>4)&0xf)
150 case 0: act= fpga->pa->get(); w="PA= "; break;
151 case 1: act= fpga->pb->get(); w="PB= "; break;
152 case 2: act= fpga->pc->get(); w="PC= "; break;
153 case 3: act= fpga->pd->get(); w="PD= "; break;
154 case 9:
155 act= uc->R[sw&0xf];
156 if ((sw&0xf)>9)
157 w.format("R%d=", sw&0xf);
158 else
159 w.format("R%d= ", sw&0xf);
160 break;
161 case 10:
163 t_addr a;
164 //act= (digit<=3)?(fpga->pd->get()):(fpga->pc->get());
165 a= 0xff02; // ODR of PC
166 a+= c/4;
167 act= fpga->uc->rom->read(a);
168 w="CD->";
169 direct= true;
170 break;
172 default: act= 0;
174 act_what= sw & 0xff;
175 if (force || (act_what != last_what))
177 io->tu_go(1,y+2);
178 io->dd_cprintf("ui_label", "%s", w.c_str());
180 if (!direct)
182 mask= 0xf << (digit*4);
183 act&= mask;
184 l= last & mask;
185 if (force || (act != l) || (act_what != last_what))
187 a= act >> (digit*4);
188 a&= 0xf;
189 int s= a*5;
190 io->tu_fgcolor(1); io->dd_printf("\033[1m");
191 io->tu_go(x, y);
192 io->dd_printf("%c%c%c", dsp[0][s], dsp[0][s+1], dsp[0][s+2]);
193 io->tu_go(x, y+1);
194 io->dd_printf("%c%c%c", dsp[1][s], dsp[1][s+1], dsp[1][s+2]);
195 io->tu_go(x, y+2);
196 io->dd_printf("%c%c%c", dsp[2][s], dsp[2][s+1], dsp[2][s+2]);
197 io->dd_printf("\033[0m");
198 io->dd_color("answer");
199 last= (last & ~mask) | act;
200 last_what= act_what;
203 else
205 // direct
206 int sby= 0;
207 switch (c % 4)
209 case 3: mask= 0xff000000; sby= 3*8; break;
210 case 2: mask= 0x00ff0000; sby= 2*8; break;
211 case 1: mask= 0x0000ff00; sby= 1*8; break;
212 default: mask= 0x000000ff; sby= 0*8; break;
214 act&= mask;
215 l= last & mask;
216 if (force || (act != l) || (act_what != last_what))
218 int bits= (act >> sby) & 0xff;
219 io->tu_fgcolor(1); io->dd_printf("\033[1m");
220 io->tu_go(x, y);
221 io->dd_printf(" %c ", (bits&1)?'_':' ');
222 io->tu_go(x, y+1);
223 io->dd_printf("%c%c%c", (bits&0x20)?'|':' ', (bits&0x40)?'_':' ', (bits&2)?'|':' ');
224 io->tu_go(x, y+2);
225 io->dd_printf("%c%c%c", (bits&0x10)?'|':' ', (bits&8)?'_':' ', (bits&4)?'|':' ');
226 io->dd_printf("\033[0m");
227 io->dd_color("answer");
228 last= (last & ~mask) | act;
229 last_what= act_what;
234 void
235 cl_seg::draw(void)
237 class cl_hw_io *io= fpga->get_io();
238 io->tu_go(x+1,y+4);
239 io->dd_cprintf("ui_label", "%d", digit);
244 Input bit
245 -------------------------------------------------------------------------
248 cl_ibit::cl_ibit(class cl_fpga *the_fpga, int ax, int ay, int amask, char akey):
249 cl_base()
251 fpga= the_fpga;
252 x= ax;
253 y= ay;
254 mask= amask;
255 key= akey;
260 Switch
261 -------------------------------------------------------------------------
264 cl_sw::cl_sw(class cl_fpga *the_fpga, int ax, int ay, int amask, char akey):
265 cl_ibit(the_fpga, ax, ay, amask, akey)
269 void
270 cl_sw::refresh(bool force)
272 char c= ' ';
273 u32_t v= 0, act, a, l;
274 class cl_hw_io *io= fpga->get_io();
275 if (!io) return;
276 class cl_memory_cell *p= fpga->pjp;
277 if (!p)
279 c= '?';
280 act= 0;
282 else
284 v= p->R();
285 act= v;
286 v&= mask;
287 c= '#';
289 a= act & mask;
290 l= last & mask;
291 if (force || (a != l))
293 const char *d0= "_ #";
294 const char *d1= "_#_";
295 const char *p= v?d1:d0;
296 if (!p) io->dd_color("answer");
297 else io->dd_color(v?"sw_on":"sw_off");
298 io->tu_go(x,y+0); io->dd_printf("%c", p[0]);
299 io->tu_go(x,y+1); io->dd_printf("%c", p[1]);
300 io->tu_go(x,y+2); io->dd_printf("%c", p[2]);
301 io->dd_color("answer");
302 last= act;
306 void
307 cl_sw::draw(void)
309 class cl_hw_io *io= fpga->get_io();
310 if (!io) return;
311 io->tu_go(x,y+3);
312 io->dd_cprintf("ui_mkey", "%c", key);
315 bool
316 cl_sw::handle_input(int c)
318 cl_memory_cell *p= fpga->pjp;
319 if ((c == key) || ((key=='y')&&(c=='z')))
321 if (p)
323 t_mem v= p->R();
324 v^= mask;
325 p->W(v);
327 return true;
329 return false;
334 Push button
335 -------------------------------------------------------------------------
338 cl_btn::cl_btn(class cl_fpga *the_fpga, int ax, int ay, int amask, char akey):
339 cl_ibit(the_fpga, ax, ay, amask, akey)
343 void
344 cl_btn::refresh(bool force)
346 char c= ' ';
347 u32_t act, a, l, v= 0;
348 class cl_hw_io *io= fpga->get_io();
349 if (!io) return;
350 class cl_memory_cell *p= fpga->pip;
351 if (!p)
353 c= '?';
354 act= last;
356 else
358 v= p->R();
359 act= v;
360 v&= mask;
361 c= v?'-':'T';
363 a= act&mask;
364 l= last&mask;
365 if (force || (a != l))
367 if (!p) io->dd_color("answer");
368 else io->dd_color(v?"btn_on":"btn_off");
369 io->tu_go(x,y);
370 io->dd_printf("_%c_", c);
371 io->dd_color("answer");
372 last= act;
376 void
377 cl_btn::draw(void)
379 class cl_hw_io *io= fpga->get_io();
380 if (!io) return;
381 io->tu_go(x+1,y+1);
382 io->dd_cprintf("ui_mkey", "%c", key);
385 bool
386 cl_btn::handle_input(int c)
388 cl_memory_cell *p= fpga->pip;
389 if (c == key)
391 if (p)
393 class cl_p1516 *u= (class cl_p1516 *)(fpga->uc);
394 t_mem v= p->R();
395 v^= mask;
396 p->W(v);
397 if (mask==1)
398 u->btn_edge(0, v&mask);
399 if (mask==2)
400 u->btn_edge(1, v&mask);
402 return true;
404 return false;
409 FPGA
410 -------------------------------------------------------------------------
413 cl_fpga::cl_fpga(class cl_uc *auc, int aid, chars aid_string):
414 cl_hw(auc, HW_DUMMY, aid, aid_string)
416 int i;
417 for (i= 0; i<16; i++)
418 leds[i]= NULL;
419 for (i= 0; i<8; i++)
420 segs[i]= NULL;
421 for (i= 0; i<16; i++)
422 sws[i]= NULL;
423 for (i= 0; i<8; i++)
424 btns[i]= NULL;
425 pa= (class cl_cell32 *)register_cell(uc->rom, 0xff00);
426 pb= (class cl_cell32 *)register_cell(uc->rom, 0xff01);
427 pc= (class cl_cell32 *)register_cell(uc->rom, 0xff02);
428 pd= (class cl_cell32 *)register_cell(uc->rom, 0xff03);
429 pi= (class cl_cell32 *)register_cell(uc->rom, 0xff20);
430 pj= (class cl_cell32 *)register_cell(uc->rom, 0xff10);
431 bc= (class cl_cell32 *)register_cell(uc->rom, 0xfff0);
432 if ((uc->symbol2cell((char*)"pi_pins", &pip)))
434 register_cell(pip);
436 if ((uc->symbol2cell((char*)"pj_pins", &pjp)))
438 register_cell(pjp);
440 basey= 13; // row of leds
441 d2c_b= 7;
446 cl_fpga::init(void)
448 cl_hw::init();
449 mk_leds();
450 mk_segs();
451 mk_sws();
452 mk_btns();
453 return 0;
457 void
458 cl_fpga::make_io()
460 if (!io)
462 io= new cl_hw_io(this);
463 io->init();
464 application->get_commander()->add_console(io);
469 void
470 cl_fpga::new_io(class cl_f *f_in, class cl_f *f_out)
472 cl_hw::new_io(f_in, f_out);
473 io->tu_mouse_on();
474 io->dd_printf("\033[2 q");
475 if (f_in)
476 f_in->set_escape(true);
480 bool
481 cl_fpga::handle_input(int c)
483 int i;
484 int ret;
485 for (i=0; i<8; i++)
486 if (btns[i])
487 if (btns[i]->handle_input(c))
488 return true;
489 for (i=0; i<16; i++)
490 if (sws[i])
491 if (sws[i]->handle_input(c))
492 return true;
493 if (pjp)
495 u32_t sw= pjp->R();
496 u32_t rx= sw&0xf;
497 //printf("c=%8x\n",c);
498 switch (c)
500 case 'A': sw&= ~0xf0; sw|= 0x00; pjp->W(sw); break;
501 case 'B': sw&= ~0xf0; sw|= 0x10; pjp->W(sw); break;
502 case 'C': sw&= ~0xf0; sw|= 0x20; pjp->W(sw); break;
503 case 'D': sw&= ~0xf0; sw|= 0x30; pjp->W(sw); break;
504 case 'R': sw&= ~0xf0; sw|= 0x90; pjp->W(sw); break;
505 case 'S': sw&= ~0xf0; sw|= 0xa0; pjp->W(sw); break;
506 case TU_UP : sw&= ~0xf; sw|= ((rx+1)&0xf); pjp->W(sw); break;
507 case TU_DOWN: sw&= ~0xf; sw|= ((rx-1)&0xf); pjp->W(sw); break;
511 ret= cl_hw::handle_input(c); // handle default keys
512 return ret;
516 void
517 cl_fpga::refresh_leds(bool force)
519 int i;
520 if (!io) return;
521 for (i=0; i<16; i++)
523 if (leds[i])
524 leds[i]->refresh(force);
529 void
530 cl_fpga::refresh_segs(bool force)
532 int i;
533 if (!io) return;
534 for (i=0; i<8; i++)
536 if (segs[i])
537 segs[i]->refresh(force);
542 void
543 cl_fpga::refresh_sws(bool force)
545 int i;
546 if (!io) return;
547 for (i=0; i<16; i++)
549 if (sws[i])
550 sws[i]->refresh(force);
555 void
556 cl_fpga::refresh_btns(bool force)
558 int i;
559 if (!io) return;
560 for (i=0; i<8; i++)
562 if (btns[i])
563 btns[i]->refresh(force);
568 void
569 cl_fpga::refresh_display(bool force)
571 int i;
573 if (!io) return;
574 //io->tu_hide();
575 refresh_leds(force);
576 refresh_segs(force);
577 refresh_sws(force);
578 refresh_btns(force);
582 void
583 cl_fpga::draw_display(void)
585 int i;
586 if (!io) return;
587 io->tu_hide();
588 io->dd_color("led_on");
589 io->tu_cls();
590 cl_hw::draw_display();
591 draw_fpga(); // board specific
592 for (i=0; i<16; i++)
593 if (leds[i])
594 leds[i]->draw();
595 for (i=0; i<8; i++)
596 if (segs[i])
597 segs[i]->draw();
598 for (i=0; i<16; i++)
599 if (sws[i])
600 sws[i]->draw();
601 for (i=0; i<8; i++)
602 if (btns[i])
603 btns[i]->draw();
604 io->tu_go(2+8*5-9-7+3-16-6,basey-7);
605 io->dd_cprintf("ui_mkey" , "[S]");
606 io->dd_cprintf("ui_mitem", "eg ");
607 io->dd_cprintf("ui_mkey" , "[ABCD] ");
608 io->dd_cprintf("ui_mitem", "PX ");
609 io->dd_cprintf("ui_mkey" , "[R] ");
610 io->dd_cprintf("ui_mitem", "RX ");
611 io->dd_cprintf("ui_mkey" , "[up] ");
612 io->dd_cprintf("ui_mitem", "R+ ");
613 io->dd_cprintf("ui_mkey" , "[dn] ");
614 io->dd_cprintf("ui_mitem", "R- ");
615 refresh_display(true);
619 t_mem
620 cl_fpga::read(class cl_memory_cell *cell)
622 if (cell == pi)
625 conf(cell, NULL);
626 return cell->get();
629 void
630 cl_fpga::write(class cl_memory_cell *cell, t_mem *val)
632 if (conf(cell, val))
633 return;
635 if (cell == pa)
638 else if (cell == pb)
640 refresh_leds(false);
643 cell->set(*val);
648 Nexys4 DDR
649 -------------------------------------------------------------------------
652 cl_n4::cl_n4(class cl_uc *auc, int aid, chars aid_string):
653 cl_fpga(auc, aid, aid_string)
655 board= "Nexys4DDR";
659 void
660 cl_n4::mk_leds(void)
662 int i, m;
663 for (i=0, m=1; i<16; i++, m<<=1)
664 leds[i]= new cl_led(this, 2+16*3-i*3,basey, m);
667 void
668 cl_n4::mk_segs(void)
670 int i, d;
671 for (i=0, d=0; i<8; i++, d++)
672 segs[i]= new cl_seg(this, 2+8*5-i*5,basey-6, d);
675 void
676 cl_n4::mk_btns(void)
678 int d;
679 // btnc
680 btns[0]= new cl_btn(this, 2+16*3+5+5,basey-5, 1, '0');
681 // btnd
682 btns[1]= new cl_btn(this, 2+16*3+5+5,basey-2, 2, '1');
683 // btnu
684 btns[2]= new cl_btn(this, 2+16*3+5+5,basey-8, 4, '2');
685 // btnr
686 btns[3]= new cl_btn(this, 2+16*3+5+5+5,basey-5, 8, '3');
687 // btnl
688 btns[4]= new cl_btn(this, 2+16*3+5,basey-5, 16, '4');
691 void
692 cl_n4::mk_sws(void)
694 const char *k= "asdfghjkqwertyui";
695 int i, m;
696 for (i=0, m=1; i<16; i++, m<<=1)
697 sws[i]= new cl_sw(this, 2+16*3-i*3,basey+2, m, k[15-i]);
700 void
701 cl_n4::draw_fpga(void)
703 int i;
704 if (!io) return;
705 io->tu_go(1,basey);
706 io->dd_cprintf("ui_label", "PB=");
707 io->tu_go(1,4);
708 io->dd_printf("%s", board.c_str());
709 for (i=0; i<16; i++)
711 io->tu_go(2+16*3-i*3-1,basey+1);
712 io->dd_cprintf("ui_label", "%2d", i);
718 Boolean
719 -------------------------------------------------------------------------
722 cl_bool::cl_bool(class cl_uc *auc, int aid, chars aid_string):
723 cl_n4(auc, aid, aid_string)
725 board= "Boolean";
729 void
730 cl_bool::draw_fpga(void)
732 cl_n4::draw_fpga();
736 void
737 cl_bool::mk_btns(void)
739 int d;
744 btns[0]= new cl_btn(this, 2+16*3+5+5 ,basey-5, 1, '0');
745 btns[1]= new cl_btn(this, 2+16*3+5+5+5,basey-5, 2, '1');
746 btns[2]= new cl_btn(this, 2+16*3+5+5 ,basey-2, 4, '2');
747 btns[3]= new cl_btn(this, 2+16*3+5+5+5,basey-2, 8, '3');
752 LogSys
753 -------------------------------------------------------------------------
756 cl_logsys::cl_logsys(class cl_uc *auc, int aid, chars aid_string):
757 cl_fpga(auc, aid, aid_string)
759 board= "LogSys";
760 d2c_b= 3;
763 void
764 cl_logsys::mk_leds(void)
766 int i, m;
767 for (i=0, m=1; i<8; i++, m<<=1)
768 leds[i]= new cl_rgb(this, 2+16*3-i*3,basey+7, m);
771 void
772 cl_logsys::mk_segs(void)
774 int i, d;
775 for (i=0, d=0; i<4; i++, d++)
776 segs[i]= new cl_seg(this, 2+8*5-i*5,basey-6, d);
779 void
780 cl_logsys::draw_fpga(void)
782 int i;
783 if (!io) return;
784 io->tu_go(2+16*3-8*3-1,basey+7);
785 io->dd_cprintf("ui_label", "PB=");
786 io->tu_go(1,4);
787 io->dd_printf("%s", board.c_str());
788 for (i=0; i<8; i++)
790 io->tu_go(2+16*3-i*3-1,basey+1);
791 io->dd_cprintf("ui_label", "%2d", i);
795 void
796 cl_logsys::mk_btns(void)
798 int d;
800 3 2 1 0
802 btns[0]= new cl_btn(this, 2+16*3-3-9*3-0*5,basey+3, 1, '0');
803 btns[1]= new cl_btn(this, 2+16*3-3-9*3-1*5,basey+3, 2, '1');
804 btns[2]= new cl_btn(this, 2+16*3-3-9*3-2*5,basey+3, 4, '2');
805 btns[3]= new cl_btn(this, 2+16*3-3-9*3-3*5,basey+3, 8, '3');
809 void
810 cl_logsys::mk_sws(void)
812 const char *k= "qwertyui";
813 int i, m;
814 for (i=0, m=1; i<8; i++, m<<=1)
815 sws[i]= new cl_sw(this, 2+16*3-i*3,basey+2, m, k[7-i]);
818 /* End of p1516.src/fpga.cc */