version 0.2.39: fix of arith insts and start of re-structure
[fw/sdcc] / sim / ucsim / s51.src / mov.cc
1 /*
2  * Simulator of microcontrollers (mov.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
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.
16
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.
21
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
25 02111-1307, USA. */
26 /*@1@*/
27
28 /* Bugs fixed by Sandeep Dutta:
29  *      source<->dest bug in "mov direct,direct"
30  *      get register in "mov @ri,address"
31  */
32  
33 #include "ddconfig.h"
34
35 #include <stdio.h>
36
37 // sim
38 #include "memcl.h"
39
40 // local
41 #include "uc51cl.h"
42 #include "regs51.h"
43
44
45 /*
46  * 0x74 2 12 MOV A,#data
47  *____________________________________________________________________________
48  *
49  */
50
51 int
52 t_uc51::inst_mov_a_$data(uchar code)
53 {
54   sfr->set(event_at.ws= ACC, fetch());
55   return(resGO);
56 }
57
58
59 /*
60  * 0x75 3 24 MOV addr,#data
61  *____________________________________________________________________________
62  *
63  */
64
65 int
66 t_uc51::inst_mov_addr_$data(uchar code)
67 {
68   uchar *addr;
69
70   addr= get_direct(fetch(), &event_at.wi, &event_at.ws);
71   (*addr)= fetch();
72   proc_write(addr);
73   tick(1);
74   return(resGO);
75 }
76
77
78 /*
79  * 0x76-0x77 2 12 MOV @Ri,#data
80  *____________________________________________________________________________
81  *
82  */
83
84 int
85 t_uc51::inst_mov_$ri_$data(uchar code)
86 {
87   uchar *addr;
88   int res;
89
90   addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
91   (*addr)= fetch();
92   proc_write(addr);
93   return(res);
94 }
95
96
97 /*
98  * 0x78-0x7f 2 12 MOV Rn,#data
99  *____________________________________________________________________________
100  *
101  */
102
103 int
104 t_uc51::inst_mov_rn_$data(uchar code)
105 {
106   uchar *reg;
107
108   reg= get_reg(code & 0x07, &event_at.wi);
109   (*reg)= fetch();
110   return(resGO);
111 }
112
113
114 /*
115  * 0x93 1 24 MOVC A,@A+DPTR
116  *____________________________________________________________________________
117  *
118  */
119
120 int
121 t_uc51::inst_movc_a_$a_pc(uchar code)
122 {
123   //SFR[ACC]= EROM[event_at.rc= (PC + SFR[ACC]) & (EROM_SIZE - 1)];
124   sfr->set(ACC,
125            mem(MEM_ROM)->get(event_at.rc=
126                              (PC + sfr->get(ACC)))&(EROM_SIZE - 1));
127   tick(1);
128   return(resGO);
129 }
130
131
132 /*
133  * 0x85 3 24 MOV addr,addr
134  *____________________________________________________________________________
135  *
136  */
137
138 int
139 t_uc51::inst_mov_addr_addr(uchar code)
140 {
141   uchar *d, *s;
142
143   /* SD reversed s & d here */
144   s= get_direct(fetch(), &event_at.ri, &event_at.rs);
145   d= get_direct(fetch(), &event_at.wi, &event_at.ws);
146   (*d)= read(s);
147   proc_write(d);
148   tick(1);
149   return(resGO);
150 }
151
152
153 /*
154  * 0x86-0x87 2 24 MOV addr,@Ri
155  *____________________________________________________________________________
156  *
157  */
158
159 int
160 t_uc51::inst_mov_addr_$ri(uchar code)
161 {
162   uchar *d, *s;
163   int res;
164
165   d= get_direct(fetch(), &event_at.wi, &event_at.ws);
166   s= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
167   *d= *s;
168   proc_write(d);
169   tick(1);
170   return(res);
171 }
172
173
174 /*
175  * 0x88-0x8f 2 24 MOV addr,Rn
176  *____________________________________________________________________________
177  *
178  */
179
180 int
181 t_uc51::inst_mov_addr_rn(uchar code)
182 {
183   uchar *addr;
184
185   addr= get_direct(fetch(), &event_at.wi, &event_at.ws);
186   (*addr)= *(get_reg(code & 0x07, &event_at.ri));
187   proc_write(addr);
188   tick(1);
189   return(resGO);
190 }
191
192
193 /*
194  * 0x90 3 24 MOV DPTR,#data
195  *____________________________________________________________________________
196  *
197  */
198
199 int
200 t_uc51::inst_mov_dptr_$data(uchar code)
201 {
202   sfr->set(event_at.ws= DPH, fetch());
203   sfr->set(DPL, fetch());
204   tick(1);
205   return(resGO);
206 }
207
208
209 /*
210  * 0x93 1 24 MOVC A,@A+DPTR
211  *____________________________________________________________________________
212  *
213  */
214
215 int
216 t_uc51::inst_movc_a_$a_dptr(uchar code)
217 {
218   //SFR[ACC]= EROM[event_at.rc= (SFR[DPH]*256+SFR[DPL]+SFR[ACC])&(EROM_SIZE-1)];
219   sfr->set(ACC, get_mem(MEM_ROM, event_at.rc=
220                         (sfr->get(DPH)*256+sfr->get(DPL) +
221                          sfr->get(ACC)) & (EROM_SIZE-1)));
222   tick(1);
223   return(resGO);
224 }
225
226
227 /*
228  * 0xa6-0xa7 2 24 MOV @Ri,addr
229  *____________________________________________________________________________
230  *
231  */
232
233 int
234 t_uc51::inst_mov_$ri_addr(uchar code)
235 {
236   uchar *d, *s;
237   int res;
238
239   d= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
240   s= get_direct(fetch(), &event_at.ri, &event_at.rs);
241   (*d)= read(s);
242   tick(1);
243   return(res);
244 }
245
246
247 /*
248  * 0xa8-0xaf 2 24 MOV Rn,addr
249  *____________________________________________________________________________
250  *
251  */
252
253 int
254 t_uc51::inst_mov_rn_addr(uchar code)
255 {
256   uchar *reg, *addr;
257
258   reg = get_reg(code & 0x07, &event_at.wi);
259   addr= get_direct(fetch(), &event_at.ri, &event_at.rs);
260   (*reg)= read(addr);
261   tick(1);
262   return(resGO);
263 }
264
265
266 /*
267  * 0xc0 2 24 PUSH addr
268  *____________________________________________________________________________
269  *
270  */
271
272 int
273 t_uc51::inst_push(uchar code)
274 {
275   uchar *addr, *sp;
276   int res;
277
278   addr= get_direct(fetch(), &event_at.ri, &event_at.rs);
279   sfr->add(SP, 1);
280   sp= get_indirect(sfr->get(SP), &res);
281   if (res != resGO)
282     res= resSTACK_OV;
283   (*sp)= read(addr);
284   tick(1);
285   return(res);
286 }
287
288
289 /*
290  * 0xc5 2 12 XCH A,addr
291  *____________________________________________________________________________
292  *
293  */
294
295 int
296 t_uc51::inst_xch_a_addr(uchar code)
297 {
298   uchar temp, *addr;
299
300   addr= get_direct(fetch(), &event_at.ri, &event_at.rs);
301   temp= sfr->get(ACC);
302   sfr->set(event_at.ws= ACC, read(addr));
303   (*addr)= temp;
304   proc_write(addr);
305   return(resGO);
306 }
307
308
309 /*
310  * 0xc6-0xc7 1 12 XCH A,@Ri
311  *____________________________________________________________________________
312  *
313  */
314
315 int
316 t_uc51::inst_xch_a_$ri(uchar code)
317 {
318   uchar temp, *addr;
319   int res;
320
321   addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
322   temp= sfr->get(ACC);
323   sfr->set(event_at.ws= ACC, *addr);
324   (*addr)= temp;
325   return(res);
326 }
327
328
329 /*
330  * 0xc8-0xcf 1 12 XCH A,Rn
331  *____________________________________________________________________________
332  *
333  */
334
335 int
336 t_uc51::inst_xch_a_rn(uchar code)
337 {
338   uchar temp, *reg;
339
340   reg = get_reg(code & 0x07, &event_at.ri);
341   temp= sfr->get(ACC);
342   sfr->set(event_at.wi= ACC, *reg);
343   (*reg)= temp;
344   return(resGO);
345 }
346
347
348 /*
349  * 0xd0 2 24 POP addr
350  *____________________________________________________________________________
351  *
352  */
353
354 int
355 t_uc51::inst_pop(uchar code)
356 {
357   uchar *addr, *sp;
358   int res;
359
360   addr= get_direct(fetch(), &event_at.wi, &event_at.ws);
361   sp= get_indirect(get_mem(MEM_SFR, SP), &res);
362   if (res != resGO)
363     res= resSTACK_OV;
364   sfr->add(SP, -1);
365   (*addr)= *sp;
366   proc_write(addr);
367   tick(1);
368   return(res);
369 }
370
371
372 /*
373  * 0xd6-0xd7 1 12 XCHD A,@Ri
374  *____________________________________________________________________________
375  *
376  */
377
378 int
379 t_uc51::inst_xchd_a_$ri(uchar code)
380 {
381   uchar *addr, temp;
382   int res;
383
384   addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
385   temp= *addr & 0x0f;
386   (*addr) = (*addr & 0xf0) | (sfr->get(ACC) & 0x0f);
387   sfr->set(event_at.ws= ACC, (sfr->get(ACC) & 0xf0) | temp);
388   return(res);
389 }
390
391
392 /*
393  * 0xe0 1 24 MOVX A,@DPTR
394  *____________________________________________________________________________
395  *
396  */
397
398 int
399 t_uc51::inst_movx_a_$dptr(uchar code)
400 {
401   sfr->set(event_at.ws= ACC,
402            get_mem(MEM_XRAM, event_at.rx=sfr->get(DPH)*256+sfr->get(DPL)));
403   tick(1);
404   return(resGO);
405 }
406
407
408 /*
409  * 0xe2-0xe3 1 24 MOVX A,@Ri
410  *____________________________________________________________________________
411  *
412  */
413
414 int
415 t_uc51::inst_movx_a_$ri(uchar code)
416 {
417   uchar *addr;
418
419   addr= get_reg(code & 0x01);
420   sfr->set(event_at.ws= ACC,
421            read_mem(MEM_XRAM,
422                     event_at.rx= (sfr->get(P2)&port_pins[2])*256+*addr));
423   tick(1);
424   return(resGO);
425 }
426
427
428 /*
429  * 0xe5 2 12 MOV A,addr
430  *____________________________________________________________________________
431  *
432  */
433
434 int
435 t_uc51::inst_mov_a_addr(uchar code)
436 {
437   uchar *addr;
438
439   addr= get_direct(fetch(), &event_at.ri, &event_at.rs);
440   sfr->set(event_at.ws= ACC, read(addr));
441   return(resGO);
442 }
443
444
445 /*
446  * 0xe6-0xe7 1 12 MOV A,@Ri
447  *____________________________________________________________________________
448  *
449  */
450
451 int
452 t_uc51::inst_mov_a_$ri(uchar code)
453 {
454   uchar *addr;
455   int res;
456
457   addr= get_indirect(event_at.ri= *(get_reg(code & 0x01)), &res);
458   sfr->set(event_at.ws= ACC, *addr);
459   return(res);
460 }
461
462
463 /*
464  * 0xe8-0xef 1 12 MOV A,Rn
465  *____________________________________________________________________________
466  *
467  */
468
469 int
470 t_uc51::inst_mov_a_rn(uchar code)
471 {
472   sfr->set(event_at.ws= ACC, *(get_reg(code & 0x07, &event_at.ri)));
473   return(resGO);
474 }
475
476
477 /*
478  * 0xf0 1 24 MOVX @DPTR,A
479  *____________________________________________________________________________
480  *
481  */
482
483 int
484 t_uc51::inst_movx_$dptr_a(uchar code)
485 {
486   set_mem(MEM_XRAM, event_at.wx= sfr->get(DPH)*256+sfr->get(DPL),
487           sfr->get(event_at.rs= ACC));
488   tick(1);
489   return(resGO);
490 }
491
492
493 /*
494  * 0xf2-0xf3 1 24 MOVX @Ri,A
495  *____________________________________________________________________________
496  *
497  */
498
499 int
500 t_uc51::inst_movx_$ri_a(uchar code)
501 {
502   uchar *addr;
503
504   addr= get_reg(code & 0x01);
505   set_mem(MEM_XRAM,
506           event_at.wx= (sfr->get(P2) & port_pins[2])*256 + *addr,
507           sfr->get(ACC));
508   tick(1);
509   return(resGO);
510 }
511
512
513 /*
514  * 0xf5 2 12 MOV addr,A
515  *____________________________________________________________________________
516  *
517  */
518
519 int
520 t_uc51::inst_mov_addr_a(uchar code)
521 {
522   uchar *addr;
523
524   addr= get_direct(fetch(), &event_at.wi, &event_at.ws);
525   (*addr)= sfr->get(event_at.rs= ACC);
526   proc_write(addr);
527   return(resGO);
528 }
529
530
531 /*
532  * 0xf6-0xf7 1 12 MOV @Ri,A
533  *____________________________________________________________________________
534  *
535  */
536
537 int
538 t_uc51::inst_mov_$ri_a(uchar code)
539 {
540   uchar *addr;
541   int res;
542
543   addr= get_indirect(event_at.wi= *(get_reg(code & 0x01)), &res);
544   (*addr)= sfr->get(event_at.rs= ACC);
545   return(res);
546 }
547
548
549 /*
550  * 0xf8-0xff 1 12 MOV Rn,A
551  *____________________________________________________________________________
552  *
553  */
554
555 int
556 t_uc51::inst_mov_rn_a(uchar code)
557 {
558   uchar *reg;
559
560   reg= get_reg(code &0x07, &event_at.wi);
561   (*reg)= sfr->get(event_at.rs= ACC);
562   return(resGO);
563 }
564
565
566 /* End of s51.src/mov.cc */