version 0.5.2
[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 cl_51core::inst_mov_a_Sdata(uchar code)
53 {
54   acc->write(fetch());
55   return(resGO);
56 }
57
58
59 /*
60  * 0x75 3 24 MOV addr,#data
61  *____________________________________________________________________________
62  *
63  */
64
65 int
66 cl_51core::inst_mov_addr_Sdata(uchar code)
67 {
68   class cl_memory_cell *cell;
69
70   cell= get_direct(fetch());
71   cell->write(fetch());
72   tick(1);
73   return(resGO);
74 }
75
76
77 /*
78  * 0x76-0x77 2 12 MOV @Ri,#data
79  *____________________________________________________________________________
80  *
81  */
82
83 int
84 cl_51core::inst_mov_Sri_Sdata(uchar code)
85 {
86   class cl_memory_cell *cell;
87   
88   cell= iram->get_cell(get_reg(code & 0x01)->read());
89   t_mem d= fetch();
90   cell->write(d);
91   return(resGO);
92 }
93
94
95 /*
96  * 0x78-0x7f 2 12 MOV Rn,#data
97  *____________________________________________________________________________
98  *
99  */
100
101 int
102 cl_51core::inst_mov_rn_Sdata(uchar code)
103 {
104   class cl_memory_cell *reg;
105
106   reg= get_reg(code & 0x07);
107   reg->write(fetch());
108   return(resGO);
109 }
110
111
112 /*
113  * 0x93 1 24 MOVC A,@A+DPTR
114  *____________________________________________________________________________
115  *
116  */
117
118 int
119 cl_51core::inst_movc_a_Sa_pc(uchar code)
120 {
121   acc->write(rom->read(PC + acc->read()));
122   tick(1);
123   return(resGO);
124 }
125
126
127 /*
128  * 0x85 3 24 MOV addr,addr
129  *____________________________________________________________________________
130  *
131  */
132
133 int
134 cl_51core::inst_mov_addr_addr(uchar code)
135 {
136   class cl_memory_cell *d, *s;
137
138   /* SD reversed s & d here */
139   s= get_direct(fetch());
140   d= get_direct(fetch());
141   d->write(s->read());
142   tick(1);
143   return(resGO);
144 }
145
146
147 /*
148  * 0x86-0x87 2 24 MOV addr,@Ri
149  *____________________________________________________________________________
150  *
151  */
152
153 int
154 cl_51core::inst_mov_addr_Sri(uchar code)
155 {
156   class cl_memory_cell *d, *s;
157
158   d= get_direct(fetch());
159   s= iram->get_cell(get_reg(code & 0x01)->read());
160   d->write(s->read());
161   tick(1);
162   return(resGO);
163 }
164
165
166 /*
167  * 0x88-0x8f 2 24 MOV addr,Rn
168  *____________________________________________________________________________
169  *
170  */
171
172 int
173 cl_51core::inst_mov_addr_rn(uchar code)
174 {
175   class cl_memory_cell *cell;
176
177   cell= get_direct(fetch());
178   cell->write(get_reg(code & 0x07)->read());
179   tick(1);
180   return(resGO);
181 }
182
183
184 /*
185  * 0x90 3 24 MOV DPTR,#data
186  *____________________________________________________________________________
187  *
188  */
189
190 int
191 cl_51core::inst_mov_dptr_Sdata(uchar code)
192 {
193   sfr->write(DPH, fetch());
194   sfr->write(DPL, fetch());
195   tick(1);
196   return(resGO);
197 }
198
199
200 /*
201  * 0x93 1 24 MOVC A,@A+DPTR
202  *____________________________________________________________________________
203  *
204  */
205
206 int
207 cl_51core::inst_movc_a_Sa_dptr(uchar code)
208 {
209   acc->write(rom->read(sfr->read(DPH)*256+sfr->read(DPL) +  acc->read()));
210   tick(1);
211   return(resGO);
212 }
213
214
215 /*
216  * 0xa6-0xa7 2 24 MOV @Ri,addr
217  *____________________________________________________________________________
218  *
219  */
220
221 int
222 cl_51core::inst_mov_Sri_addr(uchar code)
223 {
224   class cl_memory_cell *d, *s;
225
226   d= iram->get_cell(get_reg(code & 0x01)->read());
227   s= get_direct(fetch());
228   d->write(s->read());
229   tick(1);
230   return(resGO);
231 }
232
233
234 /*
235  * 0xa8-0xaf 2 24 MOV Rn,addr
236  *____________________________________________________________________________
237  *
238  */
239
240 int
241 cl_51core::inst_mov_rn_addr(uchar code)
242 {
243   class cl_memory_cell *reg, *cell;
244
245   reg = get_reg(code & 0x07);
246   cell= get_direct(fetch());
247   reg->write(cell->read());
248   tick(1);
249   return(resGO);
250 }
251
252
253 /*
254  * 0xc0 2 24 PUSH addr
255  *____________________________________________________________________________
256  *
257  */
258
259 int
260 cl_51core::inst_push(uchar code)
261 {
262   t_addr sp, sp_before/*, sp_after*/;
263   t_mem data;
264   class cl_memory_cell *stck, *cell;
265
266   cell= get_direct(fetch());
267   sp_before= sfr->get(SP);
268   sp= /*sp_after= */sfr->wadd(SP, 1);
269   stck= iram->get_cell(sp);
270   stck->write(data= cell->read());
271   class cl_stack_op *so=
272     new cl_stack_push(instPC, data, sp_before, sp/*_after*/);
273   so->init();
274   stack_write(so);
275   tick(1);
276   return(resGO);
277 }
278
279
280 /*
281  * 0xc5 2 12 XCH A,addr
282  *____________________________________________________________________________
283  *
284  */
285
286 int
287 cl_51core::inst_xch_a_addr(uchar code)
288 {
289   t_mem temp;
290   class cl_memory_cell *cell;
291
292   cell= get_direct(fetch());
293   temp= acc->read();
294   acc->write(cell->read());
295   cell->write(temp);
296   return(resGO);
297 }
298
299
300 /*
301  * 0xc6-0xc7 1 12 XCH A,@Ri
302  *____________________________________________________________________________
303  *
304  */
305
306 int
307 cl_51core::inst_xch_a_Sri(uchar code)
308 {
309   t_mem temp;
310   class cl_memory_cell *cell;
311
312   cell= iram->get_cell(get_reg(code & 0x01)->read());
313   temp= acc->read();
314   acc->write(cell->read());
315   cell->write(temp);
316   return(resGO);
317 }
318
319
320 /*
321  * 0xc8-0xcf 1 12 XCH A,Rn
322  *____________________________________________________________________________
323  *
324  */
325
326 int
327 cl_51core::inst_xch_a_rn(uchar code)
328 {
329   t_mem temp;
330   class cl_memory_cell *reg;
331
332   reg = get_reg(code & 0x07);
333   temp= acc->read();
334   acc->write(reg->read());
335   reg->write(temp);
336   return(resGO);
337 }
338
339
340 /*
341  * 0xd0 2 24 POP addr
342  *____________________________________________________________________________
343  *
344  */
345
346 int
347 cl_51core::inst_pop(uchar code)
348 {
349   t_addr sp, sp_before/*, sp_after*/;
350   t_mem data;
351   class cl_memory_cell *cell, *stck;
352
353   sp_before= sfr->get(SP);
354   cell= get_direct(fetch());
355   stck= iram->get_cell(sfr->get(SP));
356   cell->write(data= stck->read());
357   sp= /*sp_after= */sfr->wadd(SP, -1);
358   tick(1);
359   class cl_stack_op *so=
360     new cl_stack_pop(instPC, data, sp_before, sp/*_after*/);
361   so->init();
362   stack_read(so);
363   return(resGO);
364 }
365
366
367 /*
368  * 0xd6-0xd7 1 12 XCHD A,@Ri
369  *____________________________________________________________________________
370  *
371  */
372
373 int
374 cl_51core::inst_xchd_a_Sri(uchar code)
375 {
376   t_mem temp, d;
377   class cl_memory_cell *cell;
378
379   cell= iram->get_cell(get_reg(code & 0x01)->read());
380   temp= (d= cell->read()) & 0x0f;
381   cell->write((d & 0xf0) | (acc->read() & 0x0f));
382   acc->write((acc->get() & 0xf0) | temp);
383   return(resGO);
384 }
385
386
387 /*
388  * 0xe0 1 24 MOVX A,@DPTR
389  *____________________________________________________________________________
390  *
391  */
392
393 int
394 cl_51core::inst_movx_a_Sdptr(uchar code)
395 {
396   acc->write(xram->read(sfr->read(DPH)*256 + sfr->read(DPL)));
397   tick(1);
398   return(resGO);
399 }
400
401
402 /*
403  * 0xe2-0xe3 1 24 MOVX A,@Ri
404  *____________________________________________________________________________
405  *
406  */
407
408 int
409 cl_51core::inst_movx_a_Sri(uchar code)
410 {
411   t_mem d;
412
413   d= get_reg(code & 0x01)->read();
414   acc->write(xram->read(sfr->read(P2)*256 + d));
415   tick(1);
416   return(resGO);
417 }
418
419
420 /*
421  * 0xe5 2 12 MOV A,addr
422  *____________________________________________________________________________
423  *
424  */
425
426 int
427 cl_51core::inst_mov_a_addr(uchar code)
428 {
429   class cl_memory_cell *cell;
430   t_addr address= fetch();
431   
432   /* If this is ACC, it is an invalid instruction */
433   if (address == ACC)
434     {
435       //sim->app->get_commander()->
436       //debug("Invalid Instruction : E5 E0  MOV A,ACC  at  %06x\n", PC);
437       inst_unknown();
438     }
439   else
440     {
441       cell= get_direct(address);
442       acc->write(cell->read());
443     }
444   return(resGO);
445 }
446
447
448 /*
449  * 0xe6-0xe7 1 12 MOV A,@Ri
450  *____________________________________________________________________________
451  *
452  */
453
454 int
455 cl_51core::inst_mov_a_Sri(uchar code)
456 {
457   class cl_memory_cell *cell;
458
459   cell= iram->get_cell(get_reg(code & 0x01)->read());
460   acc->write(cell->read());
461   return(resGO);
462 }
463
464
465 /*
466  * 0xe8-0xef 1 12 MOV A,Rn
467  *____________________________________________________________________________
468  *
469  */
470
471 int
472 cl_51core::inst_mov_a_rn(uchar code)
473 {
474   acc->write(get_reg(code & 0x07)->read());
475   return(resGO);
476 }
477
478
479 /*
480  * 0xf0 1 24 MOVX @DPTR,A
481  *____________________________________________________________________________
482  *
483  */
484
485 int
486 cl_51core::inst_movx_Sdptr_a(uchar code)
487 {
488   xram->write(sfr->read(DPH)*256 + sfr->read(DPL), acc->read());
489   tick(1);
490   return(resGO);
491 }
492
493
494 /*
495  * 0xf2-0xf3 1 24 MOVX @Ri,A
496  *____________________________________________________________________________
497  *
498  */
499
500 int
501 cl_51core::inst_movx_Sri_a(uchar code)
502 {
503   t_mem d;
504
505   d= get_reg(code & 0x01)->read();
506   xram->write(sfr->read(P2)*256 + d, acc->read());
507   tick(1);
508   return(resGO);
509 }
510
511
512 /*
513  * 0xf5 2 12 MOV addr,A
514  *____________________________________________________________________________
515  *
516  */
517
518 int
519 cl_51core::inst_mov_addr_a(uchar code)
520 {
521   class cl_memory_cell *cell;
522   
523   cell= get_direct(fetch());
524   cell->write(acc->read());
525   return(resGO);
526 }
527
528
529 /*
530  * 0xf6-0xf7 1 12 MOV @Ri,A
531  *____________________________________________________________________________
532  *
533  */
534
535 int
536 cl_51core::inst_mov_Sri_a(uchar code)
537 {
538   class cl_memory_cell *cell;
539
540   cell= iram->get_cell(get_reg(code & 0x01)->read());
541   cell->write(acc->read());
542   return(resGO);
543 }
544
545
546 /*
547  * 0xf8-0xff 1 12 MOV Rn,A
548  *____________________________________________________________________________
549  *
550  */
551
552 int
553 cl_51core::inst_mov_rn_a(uchar code)
554 {
555   class cl_memory_cell *reg;
556
557   reg= get_reg(code &0x07);
558   reg->write(acc->read());
559   return(resGO);
560 }
561
562
563 /* End of s51.src/mov.cc */