2 * Simulator of microcontrollers (uc51r.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
38 * Making an 8051r CPU object
41 t_uc51r::t_uc51r(int Itype, int Itech, class cl_sim *asim):
42 t_uc52(Itype, Itech, asim)
46 for (i= 0; i < ERAM_SIZE; i++)
53 * Resetting of the microcontroller
55 * Original method is extended with handling of WDT.
62 WDT= -1; // Disable WDT
64 //MEM(MEM_SFR)[SADDR]= MEM(MEM_SFR)[SADEN]= 0;
71 * Copying ERAM to XRAM and vice versa
73 * This two methods are used by command interpreter to make ERAM and
74 * beginning of XRAM to be equivalent.
78 t_uc51r::eram2xram(void)
82 for (i= 0; i < ERAM_SIZE; i++)
83 set_mem(MEM_XRAM, i, ERAM[i]);
87 t_uc51r::xram2eram(void)
91 for (i= 0; i < ERAM_SIZE; i++)
92 ERAM[i]= get_mem(MEM_XRAM, i);
97 * Processing write operation of SFR
99 * Inherited method is extended with WDT handling.
103 t_uc51r::proc_write(uchar *addr)
105 t_uc52::proc_write(addr);
107 if (addr == &(/*MEM(MEM_SFR)*/sfr->umem8[WDTRST]))
109 if ((wdtrst == 0x1e) &&
113 sim->app->get_commander()->
114 debug("%g sec (%d tick): Watchdog timer enabled/reset PC= 0x%06x"
115 "\n", get_rtime(), ticks->ticks, PC);
125 * Calling inherited method to simulate timer #0 and #1 and then
126 * simulating timer #2.
130 t_uc51r::do_timers(int cycles)
134 if ((res= t_uc51::do_timers(cycles)) != resGO)
136 return(do_timer2(cycles));
143 * It is something wrong: T2MOD is not implemented in 52?!
147 t_uc51r::do_timer2(int cycles)
149 bool nocount= DD_FALSE;
150 uint t2mod= get_mem(MEM_SFR, T2MOD);
151 uint t2con= get_mem(MEM_SFR, T2CON);
152 uint p1= get_mem(MEM_SFR, P1);
155 if (!(t2con & bmTR2))
160 return(do_t2_clockout(cycles));
162 if (t2con & (bmRCLK | bmTCLK))
163 return(do_t2_baud(cycles));
165 /* Determining nr of input clocks */
166 if (!(t2con & bmTR2))
167 nocount= DD_TRUE; // Timer OFF
171 // Counter mode, falling edge on P1.0 (T2)
172 if ((prev_p1 & bmT2) &&
173 !(p1 & port_pins[1] & bmT2))
181 if (t2con & bmCP_RL2)
182 do_t2_capture(&cycles, nocount);
187 /* Auto-Relode mode */
191 exf2it->deactivate();
196 if (p1 & port_pins[1] & bmT2EX)
199 if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1))
200 if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1))
203 //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
204 sfr->set(TH2, sfr->get(RCAP2H));
205 //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
206 sfr->set(TL2, sfr->get(RCAP2L));
207 mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
213 //MEM(MEM_SFR)[TL2]--;
214 if (/*MEM(MEM_SFR)[TL2]*/sfr->add(TL2, -1) == 0xff)
215 /*MEM(MEM_SFR)[TH2]--*/sfr->add(TH2, -1);
216 /*if (MEM(MEM_SFR)[TH2] == MEM(MEM_SFR)[RCAP2H] &&
217 MEM(MEM_SFR)[TL2] == MEM(MEM_SFR)[RCAP2L])*/
218 if (sfr->get(TH2) == sfr->get(RCAP2H) &&
219 sfr->get(TL2) == sfr->get(RCAP2L))
222 //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[TL2]= 0xff;
225 mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
229 //MEM(MEM_SFR)[P1]^= bmEXF2;
230 sfr->set(P1, sfr->get(P1) ^ bmEXF2);
235 do_t2_reload(&cycles, nocount);
244 * Clock out mode of Timer #2
248 t_uc51r::do_t2_clockout(int cycles)
250 uint t2con= get_mem(MEM_SFR, T2CON);
251 uint p1= get_mem(MEM_SFR, P1);
253 /* Programmable Clock Out Mode */
254 if ((prev_p1 & bmT2EX) &&
255 !(p1 & port_pins[1] & bmT2EX) &&
257 mem(MEM_SFR)->set_bit1(T2CON, bmEXF2);
258 if (t2con & bmCP_RL2)
262 if ((prev_p1 & bmT2) &&
263 !(p1 & port_pins[1] & bmT2))
273 if (!/*++(MEM(MEM_SFR)[TL2])*/sfr->add(TL2, 1))
274 if (!/*++(MEM(MEM_SFR)[TH2])*/sfr->add(TH2, 1))
276 //MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
277 sfr->set(TH2, sfr->get(RCAP2H));
278 //MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
279 sfr->set(TL2, sfr->get(RCAP2L));
281 if (!(t2con & bmC_T2))
283 SET_BIT((clock_out&1), P1, bmT2);
292 * Handling serial line
296 t_uc51r::serial_bit_cnt(int mode)
299 int *tr_src= 0, *rec_src= 0;
306 rec_src= &s_rec_tick;
310 divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
311 tr_src = (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_tr_t2):(&s_tr_t1);
312 rec_src= (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_rec_t2):(&s_rec_t1);
315 divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
317 rec_src= &s_rec_tick;
322 while (*tr_src >= divby)
330 while (*rec_src >= divby)
340 t_uc51r::received(int c)
342 uint br= get_mem(MEM_SFR, SADDR) | get_mem(MEM_SFR, SADEN);
343 int scon= get_mem(MEM_SFR, SCON);
345 if ((0 < scon >> 6) &&
349 /* Check for individual address */
350 ((get_mem(MEM_SFR, SADDR) & get_mem(MEM_SFR, SADEN)) ==
351 (c & get_mem(MEM_SFR, SADEN)))
353 /* Check for broadcast address */
356 mem(MEM_SFR)->set_bit1(SCON, bmRI);
359 mem(MEM_SFR)->set_bit1(SCON, bmRI);
368 t_uc51r::do_wdt(int cycles)
375 sim->app->get_commander()->
376 debug("%g sec (%d ticks): Watchdog timer resets the CPU, "
377 "PC= 0x%06x\n", get_rtime(), ticks->ticks, PC);
387 * 0xe0 1 24 MOVX A,@DPTR
388 *____________________________________________________________________________
393 t_uc51r::inst_movx_a_$dptr(uchar code)
395 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
396 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
397 /*MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM,
399 MEM(MEM_SFR)[DPH]*256+
400 MEM(MEM_SFR)[DPL]);*/
401 sfr->set(event_at.ws= ACC, read_mem(MEM_XRAM,
403 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256+
404 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)));
406 //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]];
407 sfr->set(event_at.ws= ACC, ERAM[event_at.rx=
408 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]);
415 * 0xe2-0xe3 1 24 MOVX A,@Ri
416 *____________________________________________________________________________
421 t_uc51r::inst_movx_a_$ri(uchar code)
426 addr= get_indirect(*(get_reg(code & 0x01)), &res);
427 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
428 /*MEM(MEM_SFR)[event_at.ws= ACC]=
430 event_at.rx= (MEM(MEM_SFR)[P2]&port_pins[2])*256+*addr);*/
431 sfr->set(event_at.ws= ACC,
434 (/*MEM(MEM_SFR)[P2]*/sfr->get(P2)&port_pins[2])*256+*addr));
436 //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr];
437 sfr->set(event_at.ws= ACC, ERAM[event_at.rx= *addr]);
444 * 0xf0 1 24 MOVX @DPTR,A
445 *____________________________________________________________________________
450 t_uc51r::inst_movx_$dptr_a(uchar code)
452 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
453 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
455 event_at.wx= /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256 +
456 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL),
457 /*MEM(MEM_SFR)[event_at.rs= ACC]*/sfr->get(event_at.rs= ACC));
459 ERAM[event_at.wx= /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]=
460 /*MEM(MEM_SFR)[*/sfr->get(event_at.rs= ACC)/*]*/;
466 * 0xf2-0xf3 1 24 MOVX @Ri,A
467 *____________________________________________________________________________
472 t_uc51r::inst_movx_$ri_a(uchar code)
477 addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
478 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
481 (/*MEM(MEM_SFR)[P2]*/sfr->get(P2) & port_pins[2])*256 + *addr,
482 /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC));
484 ERAM[event_at.wx= *addr]= /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC);
490 /* End of s51.src/uc51r.cc */