2 * Simulator of microcontrollers (pca.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
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
39 cl_pca::cl_pca(class cl_uc *auc, int aid):
40 cl_hw(auc, HW_PCA, aid, "pca")
42 t0_overflows= ECI_edge= 0;
44 for (i= 0; i < 5; cex_pos[i]= cex_neg[i]= DD_FALSE, i++) ;
50 sfr= uc->address_space(MEM_SFR_ID);
51 //t_addr CCAPL[5]= {CCAPL[0], CCAPL[1], CCAPL[2], CCAPL[3], CCAPL[4]};
52 //t_addr CCAPH[5]= {CCAPH[0], CCAPH[1], CCAPH[2], CCAPH[3], CCAPH[4]};
53 //t_addr CCAPM[5]= {CCAPM[0], CCAPM[1], CCAPM[2], CCAPM[3], CCAPM[4]};
54 t_addr CCAPL[5]= {CCAP0L, CCAP1L, CCAP2L, CCAP3L, CCAP4L};
55 t_addr CCAPH[5]= {CCAP0H, CCAP1H, CCAP2H, CCAP3H, CCAP4H};
56 t_addr CCAPM[5]= {CCAPM0, CCAPM1, CCAPM2, CCAPM3, CCAPM4};
61 fprintf(stderr, "No SFR to register PCA[%d] into\n", id);
63 register_cell(sfr, CMOD, &cell_cmod, wtd_restore_write);
64 register_cell(sfr, CCON, &cell_ccon, wtd_restore_write);
65 for (i= 0; i < 5; i++)
67 use_cell(sfr, CCAPL[i], &cell_ccapl[i], wtd_restore);
68 use_cell(sfr, CCAPH[i], &cell_ccaph[i], wtd_restore);
69 register_cell(sfr, CCAPM[i], &cell_ccapm[i], wtd_restore_write);
71 use_cell(sfr, CL, &cell_cl, wtd_restore);
72 use_cell(sfr, CH, &cell_ch, wtd_restore);
77 cl_pca::added_to_uc(void)
79 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF4, 0x0033, false,
81 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF3, 0x0033, false,
83 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF2, 0x0033, false,
85 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF1, 0x0033, false,
87 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCCF0, 0x0033, false,
89 uc->it_sources->add_at(4, new cl_it_src(bmEC, CCON, bmCF, 0x0033, false,
94 cl_pca::write(class cl_memory_cell *cell, t_mem *val)
96 //uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4};
97 //uchar bmCCF[5]= {bmCCF0, bmCCF1, bmCCF2, bmCCF3, bmCCF4};
99 if (cell == cell_cmod)
101 bit_CIDL= *val & bmCIDL;
102 bit_WDTE= *val & bmWDTE;
103 bit_ECF = *val & bmECF;
105 if ((clk_source= *val & (bmCPS1|bmCPS0)) != o)
106 t0_overflows= ECI_edge= 0;
108 else if (cell == cell_ccon)
115 for (i= 0; i < 5; i++)
117 if (cell == cell_ccapm[i])
120 ccapm[i]= *val & 0xff;
122 cex_neg[i]= cex_pos[i]= DD_FALSE;
126 if (ccapm[i] & (bmMAT|bmTOG))
128 if (cell == cell_ccapl[i])
130 cell_ccapm[i]->set_bit0(bmECOM);
131 ccapm[i]= cell_ccapm[i]->get();
133 else if (cell == cell_ccaph[i])
135 cell_ccapm[i]->set_bit1(bmECOM);
136 ccapm[i]= cell_ccapm[i]->get();
145 cl_pca::mem_cell_changed(class cl_m *mem, t_addr addr)
147 class cl_m *sfr= uc->mem(MEM_SFR);
149 if (mem && sfr && mem == sfr)
151 if (addr == addr_ccapXl)
152 ccapXl= sfr->get_cell(addr_ccapXl);
153 else if (addr == addr_ccapXh)
154 ccapXh= sfr->get_cell(addr_ccapXh);
155 else if (addr == addr_ccapmX)
156 ccapmX= sfr->get_cell(addr_ccapmX);
161 cl_pca::tick(int cycles)
167 if (uc->state == stIDLE &&
174 do_pca_counter(cycles);
177 do_pca_counter(cycles*3);
180 do_pca_counter(t0_overflows);
183 case (bmCPS0|bmCPS1):
184 do_pca_counter(ECI_edge);
192 cl_pca::do_pca_counter(int cycles)
194 //class cl_m *sfr= uc->mem(MEM_SFR);
198 if (cell_cl->add(1) == 0)
201 for (i= 0; i < 5; i++)
202 if (ccapm[i] & bmPWM)
203 cell_ccapl[i]->set(cell_ccaph[i]->get());
204 if (cell_ch->add(1) == 0)
207 cell_ccon->set_bit1(bmCF);
219 cl_pca::do_pca_module(int nr)
221 uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4};
222 uchar bmCCF[5]= {bmCCF0, bmCCF1, bmCCF2, bmCCF3, bmCCF4};
223 //uint p1= sfr->get(P1);
225 bool capture= DD_FALSE;
226 if ((ccapm[nr] & bmCAPP) &&
230 cex_pos[nr]= DD_FALSE;
232 if ((ccapm[nr] & bmCAPN) &&
236 cex_pos[nr]= DD_FALSE;
241 cell_ccapl[nr]->set(cell_cl->get());
242 cell_ccaph[nr]->set(cell_ch->get());
243 cell_ccon->set_bit1(bmCCF[nr]);
246 if (ccapm[nr] & bmECOM)
248 // Comparator enabled
249 if (cell_cl->get() == cell_ccapl[nr]->get() &&
250 cell_ch->get() == cell_ccaph[nr]->get())
259 cell_ccon->set_bit1(bmCCF[nr]);
260 if (ccapm[nr] & bmTOG)
263 sfr->set(P1, sfr->get(P1) ^ bmCEX[nr]);
266 if (ccapm[nr] & bmPWM)
269 /*if (cell_cl->get() == 0)
270 cell_ccapl[nr]->set(cell_ccaph[nr]->get());*/
271 if (cell_cl->get() < cell_ccapl[nr]->get())
272 //sfr->set(P1, sfr->get(P1) & ~(bmCEX[nr]));
273 sfr->set_bit1(P1, bmCEX[nr]);
275 sfr->set_bit1(P1, bmCEX[nr]);
283 t0_overflows= ECI_edge= 0;
285 for (i= 0; i < 5; cex_pos[i]= cex_neg[i]= DD_FALSE, i++) ;
289 cl_pca::happen(class cl_hw *where, enum hw_event he, void *params)
291 struct ev_port_changed *ep= (struct ev_port_changed *)params;
292 uchar bmCEX[5]= {bmCEX0, bmCEX1, bmCEX2, bmCEX3, bmCEX4};
294 if (where->cathegory == HW_PORT &&
295 he == EV_PORT_CHANGED &&
298 t_mem p1n= ep->new_pins & ep->new_value;
299 t_mem p1o= ep->pins & ep->prev_value;
300 if (!(p1n & bmECI) &&
304 for (i= 0; i < 5; i++)
306 if (!(p1n & bmCEX[i]) &&
309 else if ((p1n & bmCEX[i]) &&
314 else if (where->cathegory == HW_TIMER &&
324 cl_pca::print_info(class cl_console *con)
326 con->dd_printf("%s[%d] FIXME\n", id_string, id);
330 /* End of s51.src/pca.cc */