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;
69 * Copying ERAM to XRAM and vice versa
71 * This two methods are used by command interpreter to make ERAM and
72 * beginning of XRAM to be equivalent.
76 t_uc51r::eram2xram(void)
80 for (i= 0; i < ERAM_SIZE; i++)
81 set_mem(MEM_XRAM, i, ERAM[i]);
85 t_uc51r::xram2eram(void)
89 for (i= 0; i < ERAM_SIZE; i++)
90 ERAM[i]= get_mem(MEM_XRAM, i);
95 * Processing write operation of SFR
97 * Inherited method is extended with WDT handling.
101 t_uc51r::proc_write(uchar *addr)
103 t_uc52::proc_write(addr);
105 if (addr == &(MEM(MEM_SFR)[WDTRST]))
107 if ((wdtrst == 0x1e) &&
111 sim->cmd->debug("%g sec (%d tick): Watchdog timer enabled/reset"
113 get_rtime(), ticks->ticks, PC);
123 * Calling inherited method to simulate timer #0 and #1 and then
124 * simulating timer #2.
128 t_uc51r::do_timers(int cycles)
132 if ((res= t_uc51::do_timers(cycles)) != resGO)
134 return(do_timer2(cycles));
141 * It is something wrong: T2MOD is not implemented in 52?!
145 t_uc51r::do_timer2(int cycles)
148 uint t2mod= get_mem(MEM_SFR, T2MOD);
149 uint t2con= get_mem(MEM_SFR, T2CON);
150 uint p1= get_mem(MEM_SFR, P1);
153 if (!(t2con & bmTR2))
158 return(do_t2_clockout(cycles));
160 if (t2con & (bmRCLK | bmTCLK))
161 return(do_t2_baud(cycles));
163 /* Determining nr of input clocks */
164 if (!(t2con & bmTR2))
165 nocount= TRUE; // Timer OFF
169 // Counter mode, falling edge on P1.0 (T2)
170 if ((prev_p1 & bmT2) &&
171 !(p1 & port_pins[1] & bmT2))
179 if (t2con & bmCP_RL2)
180 do_t2_capture(&cycles, nocount);
185 /* Auto-Relode mode */
189 exf2it->deactivate();
194 if (p1 & port_pins[1] & bmT2EX)
197 if (!++(MEM(MEM_SFR)[TL2]))
198 if (!++(MEM(MEM_SFR)[TH2]))
201 MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
202 MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
203 mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
210 if (MEM(MEM_SFR)[TL2] == 0xff)
212 if (MEM(MEM_SFR)[TH2] == MEM(MEM_SFR)[RCAP2H] &&
213 MEM(MEM_SFR)[TL2] == MEM(MEM_SFR)[RCAP2L])
216 MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[TL2]= 0xff;
217 mem(MEM_SFR)->set_bit1(T2CON, bmTF2);
221 MEM(MEM_SFR)[P1]^= bmEXF2;
226 do_t2_reload(&cycles, nocount);
235 * Clock out mode of Timer #2
239 t_uc51r::do_t2_clockout(int cycles)
241 uint t2con= get_mem(MEM_SFR, T2CON);
242 uint p1= get_mem(MEM_SFR, P1);
244 /* Programmable Clock Out Mode */
245 if ((prev_p1 & bmT2EX) &&
246 !(p1 & port_pins[1] & bmT2EX) &&
248 mem(MEM_SFR)->set_bit1(T2CON, bmEXF2);
249 if (t2con & bmCP_RL2)
253 if ((prev_p1 & bmT2) &&
254 !(p1 & port_pins[1] & bmT2))
264 if (!++(MEM(MEM_SFR)[TL2]))
265 if (!++(MEM(MEM_SFR)[TH2]))
267 MEM(MEM_SFR)[TH2]= MEM(MEM_SFR)[RCAP2H];
268 MEM(MEM_SFR)[TL2]= MEM(MEM_SFR)[RCAP2L];
270 if (!(t2con & bmC_T2))
272 SET_BIT((clock_out&1), P1, bmT2);
281 * Handling serial line
285 t_uc51r::serial_bit_cnt(int mode)
288 int *tr_src= 0, *rec_src= 0;
295 rec_src= &s_rec_tick;
299 divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
300 tr_src = (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_tr_t2):(&s_tr_t1);
301 rec_src= (get_mem(MEM_SFR, T2CON)&bmTCLK)?(&s_rec_t2):(&s_rec_t1);
304 divby = (get_mem(MEM_SFR, PCON)&bmSMOD)?16:32;
306 rec_src= &s_rec_tick;
311 while (*tr_src >= divby)
319 while (*rec_src >= divby)
329 t_uc51r::received(int c)
331 uint br= get_mem(MEM_SFR, SADDR) | get_mem(MEM_SFR, SADEN);
332 int scon= get_mem(MEM_SFR, SCON);
334 if ((0 < scon >> 6) &&
338 /* Check for individual address */
339 ((get_mem(MEM_SFR, SADDR) & get_mem(MEM_SFR, SADEN)) ==
340 (c & get_mem(MEM_SFR, SADEN)))
342 /* Check for broadcast address */
345 mem(MEM_SFR)->set_bit1(SCON, bmRI);
348 mem(MEM_SFR)->set_bit1(SCON, bmRI);
357 t_uc51r::do_wdt(int cycles)
362 fprintf(stderr,"WDT=%d\n",WDT);
365 sim->cmd->debug("%g sec (%d ticks): "
366 "Watchdog timer resets the CPU, PC= 0x%06x\n",
367 get_rtime(), ticks->ticks, PC);
377 * 0xe0 1 24 MOVX A,@DPTR
378 *____________________________________________________________________________
383 t_uc51r::inst_movx_a_$dptr(uchar code)
385 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
387 MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM,
389 MEM(MEM_SFR)[DPH]*256+
392 MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]];
399 * 0xe2-0xe3 1 24 MOVX A,@Ri
400 *____________________________________________________________________________
405 t_uc51r::inst_movx_a_$ri(uchar code)
410 addr= get_indirect(*(get_reg(code & 0x01)), &res);
411 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
412 MEM(MEM_SFR)[event_at.ws= ACC]=
414 event_at.rx= (MEM(MEM_SFR)[P2]&port_pins[2])*256+*addr);
416 MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr];
423 * 0xf0 1 24 MOVX @DPTR,A
424 *____________________________________________________________________________
429 t_uc51r::inst_movx_$dptr_a(uchar code)
431 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
434 event_at.wx= MEM(MEM_SFR)[DPH]*256+MEM(MEM_SFR)[DPL],
435 MEM(MEM_SFR)[event_at.rs= ACC]);
437 ERAM[event_at.wx= MEM(MEM_SFR)[DPL]]= MEM(MEM_SFR)[event_at.rs= ACC];
443 * 0xf2-0xf3 1 24 MOVX @Ri,A
444 *____________________________________________________________________________
449 t_uc51r::inst_movx_$ri_a(uchar code)
454 addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
455 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
457 event_at.wx= (MEM(MEM_SFR)[P2] & port_pins[2])*256 + *addr,
460 ERAM[event_at.wx= *addr]= MEM(MEM_SFR)[ACC];
466 /* End of s51.src/uc51r.cc */