2 * Simulator of microcontrollers (arith.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 *____________________________________________________________________________
44 t_uc51::inst_rr(uchar code)
48 acc= sfr->read(event_at.ws= event_at.rs= ACC);
50 sfr->set(ACC, (acc >> 1) | 0x80);
52 sfr->set(ACC, acc >> 1);
59 *____________________________________________________________________________
64 t_uc51::inst_rrc(uchar code)
70 SET_C((acc= sfr->read(ACC)) & 0x01);
71 event_at.ws= event_at.rs= ACC;
82 *____________________________________________________________________________
87 t_uc51::inst_rl(uchar code)
91 acc= sfr->read(event_at.ws= event_at.rs= ACC);
93 sfr->set(ACC, (acc << 1 ) | 0x01);
95 sfr->set(ACC, acc << 1);
101 * 0x24 2 12 ADD A,#data
102 *____________________________________________________________________________
107 t_uc51::inst_add_a_$data(uchar code)
114 newC= (((uint)acc+(uint)(data)) > 255)?0x80:0;
115 newA= ((acc&0x0f)+(data&0x0f)) & 0xf0;
116 c6 = ((acc&0x7f)+(data&0x7f)) & 0x80;
118 sfr->set(ACC, acc+data);
120 SET_BIT(newC ^ c6, PSW, bmOV);
121 SET_BIT(newA, PSW, bmAC);
127 * 0x25 2 12 ADD A,addr
128 *____________________________________________________________________________
133 t_uc51::inst_add_a_addr(uchar code)
138 data= read(get_direct(fetch(), &event_at.ri, &event_at.rs));
140 newC= (((uint)acc+(uint)(data)) > 255)?0x80:0;
141 newA= ((acc&0x0f)+(data&0x0f)) & 0xf0;
142 c6 = ((acc&0x7f)+(data&0x7f)) & 0x80;
144 sfr->set(ACC, acc+data);
146 SET_BIT(newC ^ c6, PSW, bmOV);
147 SET_BIT(newA, PSW, bmAC);
153 * 0x26-0x27 1 12 ADD A,@Ri
154 *____________________________________________________________________________
159 t_uc51::inst_add_a_$ri(uchar code)
161 uchar data, *addr, acc;
165 addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
168 newC= (((uint)acc+(uint)data) > 255)?0x80:0;
169 newA= ((acc&0x0f)+(data&0x0f)) & 0xf0;
170 c6 = ((acc&0x7f)+(data&0x7f)) & 0x80;
172 sfr->set(ACC, acc+data);
174 SET_BIT(newC ^ c6, PSW, bmOV);
175 SET_BIT(newA, PSW, bmAC);
181 * 0x28-0x2f 1 12 ADD A,Rn
182 *____________________________________________________________________________
187 t_uc51::inst_add_a_rn(uchar code)
192 data= *(get_reg(code & 0x07, &event_at.ri));
194 newC= (((uint)acc+(uint)data) > 255)?0x80:0;
195 newA= ((acc&0x0f)+(data&0x0f)) & 0xf0;
196 c6 = ((acc&0x7f)+(data&0x7f)) & 0x80;
198 sfr->set(ACC, acc+data);
200 SET_BIT(newC ^ c6, PSW, bmOV);
201 SET_BIT(newA, PSW, bmAC);
208 *____________________________________________________________________________
213 t_uc51::inst_rlc(uchar code)
219 SET_C((acc= sfr->get(event_at.rs= ACC)) & 0x80);
223 sfr->set(event_at.ws= ACC, acc);
229 * 0x34 2 12 ADDC A,#data
230 *____________________________________________________________________________
235 t_uc51::inst_addc_a_$data(uchar code)
238 bool orgC, newC, newA, c6;
242 newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
243 newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
244 c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
245 sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0));
247 SET_BIT(newC ^ c6, PSW, bmOV);
248 SET_BIT(newA, PSW, bmAC);
254 * 0x35 2 12 ADDC A,addr
255 *____________________________________________________________________________
260 t_uc51::inst_addc_a_addr(uchar code)
263 bool orgC, newC, newA, c6;
265 data= read(get_direct(fetch(), &event_at.ri, &event_at.rs));
267 newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
268 newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
269 c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
270 sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0));
272 SET_BIT(newC ^ c6, PSW, bmOV);
273 SET_BIT(newA, PSW, bmAC);
279 * 0x36-0x37 1 12 ADDC A,@Ri
280 *____________________________________________________________________________
285 t_uc51::inst_addc_a_$ri(uchar code)
287 uchar data, *addr, acc;
288 bool orgC, newC, newA, c6;
291 addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
294 newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
295 newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
296 c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
297 sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0));
299 SET_BIT(newC ^ c6, PSW, bmOV);
300 SET_BIT(newA, PSW, bmAC);
306 * 0x38-0x3f 1 12 ADDC A,Rn
307 *____________________________________________________________________________
312 t_uc51::inst_addc_a_rn(uchar code)
315 bool orgC, newC, newA, c6;
317 data= *(get_reg(code & 0x07, &event_at.ri));
319 newC= (((uint)acc+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
320 newA= ((acc&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
321 c6 = ((acc&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
322 sfr->set(event_at.ws= ACC, acc + data + (orgC?1:0));
324 SET_BIT(newC ^ c6, PSW, bmOV);
325 SET_BIT(newA, PSW, bmAC);
332 *____________________________________________________________________________
337 t_uc51::inst_div_ab(uchar code)
339 uchar temp, psw, b, acc;
343 if (!(b= sfr->get(event_at.rs= B)))
348 temp= (acc= sfr->get(ACC)) / b;
349 sfr->set(B, acc % b);
350 sfr->set(event_at.ws= ACC, temp);
359 * 0x94 2 12 SUBB A,#data
360 *____________________________________________________________________________
365 t_uc51::inst_subb_a_$data(uchar code)
367 uchar data, acc, result, psw, c;
373 if ((c= (psw & bmCY)?1:0))
375 sfr->set(event_at.ws= ACC, result);
377 (psw & ~(bmCY|bmOV|bmAC)) |
378 (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) |
379 (((acc<0x80 && data>0x7f && result>0x7f) ||
380 (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) |
381 (((acc&0x0f) < ((data+c)&0x0f) ||
382 (c && ((data&0x0f)==0x0f)))?bmAC:0));
388 * 0x95 2 12 SUBB A,addr
389 *____________________________________________________________________________
394 t_uc51::inst_subb_a_addr(uchar code)
396 uchar *addr, data, acc, result, psw,c ;
398 addr= get_direct(fetch(), &event_at.ri, &event_at.rs);
403 if ((c= (psw & bmCY)?1:0))
405 sfr->set(event_at.ws= ACC, result);
407 (psw & ~(bmCY|bmOV|bmAC)) |
408 (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) |
409 (((acc<0x80 && data>0x7f && result>0x7f) ||
410 (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) |
411 (((acc&0x0f) < ((data+c)&0x0f) ||
412 (c && ((data&0x0f)==0x0f)))?bmAC:0));
418 * 0x96-0x97 1 12 SUBB A,@Ri
419 *____________________________________________________________________________
424 t_uc51::inst_subb_a_$ri(uchar code)
426 uchar data, acc, result, psw, c;
429 data= *(get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res));
433 if ((c= (psw & bmCY)?1:0))
435 sfr->set(event_at.ws= ACC, result);
437 (psw & ~(bmCY|bmOV|bmAC)) |
438 (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) |
439 (((acc<0x80 && data>0x7f && result>0x7f) ||
440 (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) |
441 (((acc&0x0f) < ((data+c)&0x0f) ||
442 (c && ((data&0x0f)==0x0f)))?bmAC:0));
448 * 0x98-0x9f 1 12 SUBB A,Rn
449 *____________________________________________________________________________
454 t_uc51::inst_subb_a_rn(uchar code)
456 uchar data, acc, result, psw, c;
458 data= *(get_reg(code & 0x07, &event_at.ri));
462 if ((c= (psw & bmCY)?1:0))
464 sfr->set(event_at.ws= ACC, result);
466 (psw & ~(bmCY|bmOV|bmAC)) |
467 (((unsigned int)acc < (unsigned int)(data+c))?bmCY:0) |
468 (((acc<0x80 && data>0x7f && result>0x7f) ||
469 (acc>0x7f && data<0x80 && result<0x80))?bmOV:0) |
470 (((acc&0x0f) < ((data+c)&0x0f) ||
471 (c && ((data&0x0f)==0x0f)))?bmAC:0));
478 *____________________________________________________________________________
483 t_uc51::inst_mul_ab(uchar code)
485 uint temp, psw, acc, b;
489 temp= (acc= sfr->get(ACC)) * (b= sfr->get(B));
490 sfr->set(event_at.ws= ACC, temp & 0xff);
491 sfr->set(event_at.rs= B, (temp >> 8) & 0xff);
492 SET_BIT(sfr->get(B), PSW, bmOV);
493 SET_BIT(0, PSW, bmCY);
501 *____________________________________________________________________________
506 t_uc51::inst_da_a(uchar code)
513 if ((acc & 0x0f) > 9 ||
516 if (((uint)acc+(uint)0x06) > 255)
520 if ((acc & 0xf0) > 0x90 ||
523 if (((uint)acc+(uint)0x60) > 255)
533 /* End of s51.src/arith.cc */