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
40 *____________________________________________________________________________
45 cl_51core::inst_rr(uchar code)
51 acc->write((ac >> 1) | 0x80);
60 *____________________________________________________________________________
65 cl_51core::inst_rrc(uchar code)
71 SFR_SET_C((ac= acc->read()) & 0x01);
82 *____________________________________________________________________________
87 cl_51core::inst_rl(uchar code)
93 acc->write((ac << 1 ) | 0x01);
101 * 0x24 2 12 ADD A,#data
102 *____________________________________________________________________________
107 cl_51core::inst_add_a_Sdata(uchar code)
114 newC= (((uint)ac+(uint)(data)) > 255)?0x80:0;
115 newA= ((ac&0x0f)+(data&0x0f)) & 0xf0;
116 c6 = ((ac&0x7f)+(data&0x7f)) & 0x80;
119 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
120 SFR_SET_BIT(newA, PSW, bmAC);
126 * 0x25 2 12 ADD A,addr
127 *____________________________________________________________________________
132 cl_51core::inst_add_a_addr(uchar code)
136 class cl_memory_cell *cell;
139 cell= get_direct(a= fetch());
142 newC= (((uint)ac+(uint)(data)) > 255)?0x80:0;
143 newA= ((ac&0x0f)+(data&0x0f)) & 0xf0;
144 c6 = ((ac&0x7f)+(data&0x7f)) & 0x80;
147 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
148 SFR_SET_BIT(newA, PSW, bmAC);
154 * 0x26-0x27 1 12 ADD A,@Ri
155 *____________________________________________________________________________
160 cl_51core::inst_add_a_Sri(uchar code)
164 class cl_memory_cell *cell;
166 cell= iram->get_cell(get_reg(code & 0x01)->read());
169 newC= (((uint)ac+(uint)data) > 255)?0x80:0;
170 newA= ((ac&0x0f)+(data&0x0f)) & 0xf0;
171 c6 = ((ac&0x7f)+(data&0x7f)) & 0x80;
174 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
175 SFR_SET_BIT(newA, PSW, bmAC);
181 * 0x28-0x2f 1 12 ADD A,Rn
182 *____________________________________________________________________________
187 cl_51core::inst_add_a_rn(uchar code)
192 data= get_reg(code & 0x07)->read();
194 newC= (((uint)ac+(uint)data) > 255)?0x80:0;
195 newA= ((ac&0x0f)+(data&0x0f)) & 0xf0;
196 c6 = ((ac&0x7f)+(data&0x7f)) & 0x80;
199 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
200 SFR_SET_BIT(newA, PSW, bmAC);
207 *____________________________________________________________________________
212 cl_51core::inst_rlc(uchar code)
218 SFR_SET_C((ac= acc->get()) & 0x80);
228 * 0x34 2 12 ADDC A,#data
229 *____________________________________________________________________________
234 cl_51core::inst_addc_a_Sdata(uchar code)
237 bool orgC, newC, newA, c6;
241 newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
242 newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
243 c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
244 acc->write(ac + data + (orgC?1:0));
246 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
247 SFR_SET_BIT(newA, PSW, bmAC);
253 * 0x35 2 12 ADDC A,addr
254 *____________________________________________________________________________
259 cl_51core::inst_addc_a_addr(uchar code)
262 bool orgC, newC, newA, c6;
263 class cl_memory_cell *cell;
266 cell= get_direct(a= fetch());
269 newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
270 newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
271 c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
272 acc->write(ac + data + (orgC?1:0));
274 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
275 SFR_SET_BIT(newA, PSW, bmAC);
281 * 0x36-0x37 1 12 ADDC A,@Ri
282 *____________________________________________________________________________
287 cl_51core::inst_addc_a_Sri(uchar code)
290 bool orgC, newC, newA, c6;
291 class cl_memory_cell *cell;
293 cell= iram->get_cell(get_reg(code & 0x01)->read());
296 newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
297 newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
298 c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
299 acc->write(ac + data + (orgC?1:0));
301 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
302 SFR_SET_BIT(newA, PSW, bmAC);
308 * 0x38-0x3f 1 12 ADDC A,Rn
309 *____________________________________________________________________________
314 cl_51core::inst_addc_a_rn(uchar code)
317 bool orgC, newC, newA, c6;
319 data= get_reg(code & 0x07)->read();
321 newC= (((uint)ac+(uint)data+((orgC= SFR_GET_C)?1:0)) > 255)?0x80:0;
322 newA= ((ac&0x0f)+(data&0x0f)+(orgC?1:0)) & 0xf0;
323 c6 = ((ac&0x7f)+(data&0x7f)+(orgC?1:0)) & 0x80;
324 acc->write(ac + data + (orgC?1:0));
326 SFR_SET_BIT(newC ^ c6, PSW, bmOV);
327 SFR_SET_BIT(newA, PSW, bmAC);
334 *____________________________________________________________________________
339 cl_51core::inst_div_ab(uchar code)
341 uchar temp, pw, b, ac;
345 if (!(b= sfr->get(B)))
350 temp= (ac= acc->get()) / b;
351 sfr->write(B, ac % b);
361 * 0x94 2 12 SUBB A,#data
362 *____________________________________________________________________________
367 cl_51core::inst_subb_a_Sdata(uchar code)
369 uchar data, ac, result, pw, c;
375 if ((c= (pw & bmCY)?1:0))
378 psw->write((pw & ~(bmCY|bmOV|bmAC)) |
379 (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) |
380 (((ac<0x80 && data>0x7f && result>0x7f) ||
381 (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) |
382 (((ac&0x0f) < ((data+c)&0x0f) ||
383 (c && ((data&0x0f)==0x0f)))?bmAC:0));
389 * 0x95 2 12 SUBB A,addr
390 *____________________________________________________________________________
395 cl_51core::inst_subb_a_addr(uchar code)
397 uchar data, ac, result, pw, c;
398 class cl_memory_cell *cell;
400 cell= get_direct(fetch());
405 if ((c= (pw & bmCY)?1:0))
408 psw->set((pw & ~(bmCY|bmOV|bmAC)) |
409 (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) |
410 (((ac<0x80 && data>0x7f && result>0x7f) ||
411 (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) |
412 (((ac&0x0f) < ((data+c)&0x0f) ||
413 (c && ((data&0x0f)==0x0f)))?bmAC:0));
419 * 0x96-0x97 1 12 SUBB A,@Ri
420 *____________________________________________________________________________
425 cl_51core::inst_subb_a_Sri(uchar code)
427 uchar data, ac, result, pw, c;
428 class cl_memory_cell *cell;
430 cell= iram->get_cell(get_reg(code & 0x01)->read());
435 if ((c= (pw & bmCY)?1:0))
438 psw->write((pw & ~(bmCY|bmOV|bmAC)) |
439 (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) |
440 (((ac<0x80 && data>0x7f && result>0x7f) ||
441 (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) |
442 (((ac&0x0f) < ((data+c)&0x0f) ||
443 (c && ((data&0x0f)==0x0f)))?bmAC:0));
449 * 0x98-0x9f 1 12 SUBB A,Rn
450 *____________________________________________________________________________
455 cl_51core::inst_subb_a_rn(uchar code)
457 uchar data, ac, result, pw, c;
459 data= get_reg(code & 0x07)->read();
463 if ((c= (pw & bmCY)?1:0))
466 psw->write((pw & ~(bmCY|bmOV|bmAC)) |
467 (((unsigned int)ac < (unsigned int)(data+c))?bmCY:0) |
468 (((ac<0x80 && data>0x7f && result>0x7f) ||
469 (ac>0x7f && data<0x80 && result<0x80))?bmOV:0) |
470 (((ac&0x0f) < ((data+c)&0x0f) ||
471 (c && ((data&0x0f)==0x0f)))?bmAC:0));
478 *____________________________________________________________________________
483 cl_51core::inst_mul_ab(uchar code)
485 uint temp, pw, ac, b, x;
489 temp= (ac= acc->read()) * (b= sfr->get(B));
490 acc->write(temp & 0xff);
491 x= sfr->write(B, (temp >> 8) & 0xff);
492 SFR_SET_BIT(x/*sfr->get(B)*/, PSW, bmOV);
493 SFR_SET_BIT(0, PSW, bmCY);
501 *____________________________________________________________________________
506 cl_51core::inst_da_a(uchar code)
512 if ((ac & 0x0f) > 9 ||
515 if (((uint)ac+(uint)0x06) > 255)
519 if ((ac & 0xf0) > 0x90 ||
522 if (((uint)ac+(uint)0x60) > 255)
532 /* End of s51.src/arith.cc */