2 * Simulator of microcontrollers (timer0.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
33 cl_timer0::cl_timer0(class cl_uc *auc, int aid, char *aid_string):
34 cl_hw(auc, HW_TIMER, aid, aid_string)
36 cell_tmod= cell_tcon= 0;
71 mask_M0= mask_M1= mask_GATE= mask_INT= 0;
74 make_partner(HW_PCA, 0);
75 make_partner(HW_PCA, 1);
76 make_partner(HW_PCA, 2);
77 make_partner(HW_PCA, 3);
78 make_partner(HW_PCA, 4);
84 class cl_mem *sfr= uc->mem(MEM_SFR);
89 if (id == 0 || id == 1)
91 //cell_tmod= sfr->register_hw(TMOD, this, 0);
92 register_cell(sfr, TMOD, &cell_tmod, wtd_restore_write);
93 //d= cell_tmod->get(); write(cell_tmod, &d);
94 //cell_tcon= sfr->register_hw(TCON, this, 0);
95 register_cell(sfr, TCON, &cell_tcon, wtd_restore_write);
96 //d= cell_tcon->get(); write(cell_tcon, &d);
97 INT= sfr->read(P3) & mask_INT;
102 //cell_tcon= sfr->register_hw(T2CON, this, 0);
103 register_cell(sfr, T2CON, &cell_tcon, wtd_restore_write);
104 //d= cell_tcon->get(); write(cell_tcon, &d);
106 //cell_tl= sfr->get_cell(addr_tl);
107 //cell_th= sfr->get_cell(addr_th);
108 use_cell(sfr, addr_tl, &cell_tl, wtd_restore);
109 use_cell(sfr, addr_th, &cell_th, wtd_restore);
115 cl_timer0::added_to_uc(void)
118 uc->it_sources->add(new cl_it_src(bmET0, TCON, bmTF0, 0x000b, true,
121 uc->it_sources->add(new cl_it_src(bmET1, TCON, bmTF1, 0x001b, true,
126 cl_timer0::read(class cl_cell *cell)
132 cl_timer0::write(class cl_cell *cell, t_mem *val)
134 if (cell == cell_tmod)
136 t_mem md= *val & (mask_M0|mask_M1);
139 else if (md == mask_M1)
141 else if (md == (mask_M0|mask_M1))
145 GATE= *val & mask_GATE;
146 C_T = *val & mask_C_T;
149 else if (cell == cell_tcon)
157 cl_timer0::mem_cell_changed(class cl_mem *mem, t_addr addr)
159 //class cl_mem *sfr= uc->mem(MEM_SFR);
162 cl_hw::mem_cell_changed(mem, addr);
164 //d= cell_tmod->get();
165 //write(cell_tmod, &d);
166 //d= cell_tcon->get();
167 //write(cell_tcon, &d);
168 //if (addr == addr_tl) cell_tl= sfr->get_cell(addr_tl);
169 //if (addr == addr_th) cell_th= sfr->get_cell(addr_th);
173 cl_timer0::tick(int cycles)
177 case 0: do_mode0(cycles); break;
178 case 1: do_mode1(cycles); break;
179 case 2: do_mode2(cycles); break;
180 case 3: do_mode3(cycles); break;
186 cl_timer0::do_mode0(int cycles)
191 //t_mem p3= uc->mem(MEM_SFR)->get(P3);
194 if ((/*p3 & mask_*/INT) == 0)
201 if ((uc51->prev_p3 & mask_T) &&
202 !(p3 & uc51->port_pins[3] & mask_T))
209 // mod 0, TH= 8 bit t/c, TL= 5 bit precounter
210 t_mem tl= cell_tl->add(1);
211 if ((tl & 0x1f) == 0)
214 if (!cell_th->add(1))
216 cell_tcon->set_bit1(mask_TF);
226 cl_timer0::do_mode1(int cycles)
231 //t_mem p3= uc->mem(MEM_SFR)->get(P3);
234 if ((/*p3 & mask_*/INT) == 0)
241 if ((uc51->prev_p3 & mask_T) &&
242 !(p3 & uc51->port_pins[3] & mask_T))
250 // mod 1 TH+TL= 16 bit t/c
251 if (!cell_tl->add(1))
253 if (!cell_th->add(1))
255 cell_tcon->set_bit1(mask_TF);
265 cl_timer0::do_mode2(int cycles)
270 //t_mem p3= uc->mem(MEM_SFR)->get(P3);
273 if ((/*p3 & mask_*/INT) == 0)
280 if ((uc51->prev_p3 & mask_T) &&
281 !(p3 & uc51->port_pins[3] & mask_T))
287 //unsigned long startt= uc->ticks->ticks-(cycles*12);int i=0;
290 // mod 2 TL= 8 bit t/c auto reload from TH
291 if (!cell_tl->add(1))
293 cell_tl->set(cell_th->get());
294 cell_tcon->set_bit1(mask_TF);
295 //printf("timer%d overflow %d (%d) %d\n",id,uc->ticks->ticks,i,startt+(i*12));
304 cl_timer0::do_mode3(int cycles)
307 //t_mem p3= uc->mem(MEM_SFR)->get(P3);
314 if ((/*p3 & mask_*/INT) == 0)
321 if ((uc51->prev_p3 & mask_T) &&
322 !(p3 & uc51->port_pins[3] & mask_T))
330 if (!cell_tl->add(1))
332 cell_tcon->set_bit1(mask_TF);
338 if ((cell_tcon->get() & bmTR1) != 0)
341 if (!cell_th->add(1))
342 cell_tcon->set_bit1(bmTF1);
348 cl_timer0::overflow(void)
350 inform_partners(EV_OVERFLOW, 0);
354 cl_timer0::happen(class cl_hw *where, enum hw_event he, void *params)
356 struct ev_port_changed *ep= (struct ev_port_changed *)params;
358 if (where->cathegory == HW_PORT &&
359 he == EV_PORT_CHANGED &&
362 t_mem p3n= ep->new_pins & ep->new_value;
363 t_mem p3o= ep->pins & ep->prev_value;
364 if ((p3n & mask_T) &&
368 //printf("timer%d p%dchanged (%02x,%02x->%02x,%02x) INT=%d(%02x) edge=%d(%02x)\n",id,where->id,ep->prev_value,ep->pins,ep->new_value,ep->new_pins,INT,mask_INT,T_edge,mask_T);
373 cl_timer0::print_info(class cl_console *con)
375 char *modes[]= { "13 bit", "16 bit", "8 bit autoreload", "2x8 bit" };
376 //t_mem tmod= cell_tmod->get();
379 con->dd_printf("%s[%d] 0x%04x", id_string, id,
380 256*cell_th->get()+cell_tl->get());
381 //int mode= tmod & (bmM00|bmM10);
382 con->dd_printf(" %s", modes[mode]);
383 con->dd_printf(" %s", (/*tmod&bm*/C_T/*0*/)?"counter":"timer");
384 if (/*tmod&bm*/GATE/*0*/)
386 con->dd_printf(" gated");
387 on= /*uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & mask_*/INT/*bm_INT0*/;
390 on= TR/*cell_tcon->get(TCON) & mask_TR*/;
391 con->dd_printf(" %s", on?"ON":"OFF");
392 con->dd_printf(" irq=%c", (cell_tcon->get()&mask_TF)?'1':'0');
393 con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET0)?"en":"dis");
394 con->dd_printf(" prio=%d", uc->it_priority(bmPT0));
395 con->dd_printf("\n");
399 /* End of s51.src/timer0.cc */