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->cmd->debug("%g sec (%d tick): Watchdog timer enabled/reset"
115 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)
373 fprintf(stderr,"WDT=%d\n",WDT);
376 sim->cmd->debug("%g sec (%d ticks): "
377 "Watchdog timer resets the CPU, PC= 0x%06x\n",
378 get_rtime(), ticks->ticks, PC);
388 * 0xe0 1 24 MOVX A,@DPTR
389 *____________________________________________________________________________
394 t_uc51r::inst_movx_a_$dptr(uchar code)
396 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
397 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
398 /*MEM(MEM_SFR)[event_at.ws= ACC]= read_mem(MEM_XRAM,
400 MEM(MEM_SFR)[DPH]*256+
401 MEM(MEM_SFR)[DPL]);*/
402 sfr->set(event_at.ws= ACC, read_mem(MEM_XRAM,
404 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256+
405 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)));
407 //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= MEM(MEM_SFR)[DPL]];
408 sfr->set(event_at.ws= ACC, ERAM[event_at.rx=
409 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]);
416 * 0xe2-0xe3 1 24 MOVX A,@Ri
417 *____________________________________________________________________________
422 t_uc51r::inst_movx_a_$ri(uchar code)
427 addr= get_indirect(*(get_reg(code & 0x01)), &res);
428 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
429 /*MEM(MEM_SFR)[event_at.ws= ACC]=
431 event_at.rx= (MEM(MEM_SFR)[P2]&port_pins[2])*256+*addr);*/
432 sfr->set(event_at.ws= ACC,
435 (/*MEM(MEM_SFR)[P2]*/sfr->get(P2)&port_pins[2])*256+*addr));
437 //MEM(MEM_SFR)[event_at.ws= ACC]= ERAM[event_at.rx= *addr];
438 sfr->set(event_at.ws= ACC, ERAM[event_at.rx= *addr]);
445 * 0xf0 1 24 MOVX @DPTR,A
446 *____________________________________________________________________________
451 t_uc51r::inst_movx_$dptr_a(uchar code)
453 if ((get_mem(MEM_SFR, AUXR) & bmEXTRAM) ||
454 /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH))
456 event_at.wx= /*MEM(MEM_SFR)[DPH]*/sfr->get(DPH)*256 +
457 /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL),
458 /*MEM(MEM_SFR)[event_at.rs= ACC]*/sfr->get(event_at.rs= ACC));
460 ERAM[event_at.wx= /*MEM(MEM_SFR)[DPL]*/sfr->get(DPL)]=
461 /*MEM(MEM_SFR)[*/sfr->get(event_at.rs= ACC)/*]*/;
467 * 0xf2-0xf3 1 24 MOVX @Ri,A
468 *____________________________________________________________________________
473 t_uc51r::inst_movx_$ri_a(uchar code)
478 addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
479 if (get_mem(MEM_SFR, AUXR) & bmEXTRAM)
482 (/*MEM(MEM_SFR)[P2]*/sfr->get(P2) & port_pins[2])*256 + *addr,
483 /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC));
485 ERAM[event_at.wx= *addr]= /*MEM(MEM_SFR)[ACC]*/sfr->get(ACC);
491 /* End of s51.src/uc51r.cc */