512da92b093e0c93c6a6c9c2c561a5c07ada829e
[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_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 t_uc51::inst_mov_addr_Sdata(uchar code)
67 {
68   class cl_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 t_uc51::inst_mov_Sri_Sdata(uchar code)
85 {
86   class cl_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 t_uc51::inst_mov_rn_Sdata(uchar code)
103 {
104   class cl_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 t_uc51::inst_movc_a_Sa_pc(uchar code)
120 {
121   acc->write(mem(MEM_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 t_uc51::inst_mov_addr_addr(uchar code)
135 {
136   class cl_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 t_uc51::inst_mov_addr_Sri(uchar code)
155 {
156   class cl_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 t_uc51::inst_mov_addr_rn(uchar code)
174 {
175   class cl_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 t_uc51::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 t_uc51::inst_movc_a_Sa_dptr(uchar code)
208 {
209   acc->write(get_mem(MEM_ROM,
210                      sfr->read(DPH)*256+sfr->read(DPL) +
211                      acc->read()));
212   tick(1);
213   return(resGO);
214 }
215
216
217 /*
218  * 0xa6-0xa7 2 24 MOV @Ri,addr
219  *____________________________________________________________________________
220  *
221  */
222
223 int
224 t_uc51::inst_mov_Sri_addr(uchar code)
225 {
226   class cl_cell *d, *s;
227
228   d= iram->get_cell(get_reg(code & 0x01)->read());
229   s= get_direct(fetch());
230   d->write(s->read());
231   tick(1);
232   return(resGO);
233 }
234
235
236 /*
237  * 0xa8-0xaf 2 24 MOV Rn,addr
238  *____________________________________________________________________________
239  *
240  */
241
242 int
243 t_uc51::inst_mov_rn_addr(uchar code)
244 {
245   class cl_cell *reg, *cell;
246
247   reg = get_reg(code & 0x07);
248   cell= get_direct(fetch());
249   reg->write(cell->read());
250   tick(1);
251   return(resGO);
252 }
253
254
255 /*
256  * 0xc0 2 24 PUSH addr
257  *____________________________________________________________________________
258  *
259  */
260
261 int
262 t_uc51::inst_push(uchar code)
263 {
264   t_addr sp;
265   class cl_cell *stck, *cell;
266
267   cell= get_direct(fetch());
268   sp= sfr->wadd(SP, 1);
269   stck= iram->get_cell(sp);
270   stck->write(cell->read());
271   tick(1);
272   return(resGO);
273 }
274
275
276 /*
277  * 0xc5 2 12 XCH A,addr
278  *____________________________________________________________________________
279  *
280  */
281
282 int
283 t_uc51::inst_xch_a_addr(uchar code)
284 {
285   t_mem temp;
286   class cl_cell *cell;
287
288   cell= get_direct(fetch());
289   temp= acc->read();
290   acc->write(cell->read());
291   cell->write(temp);
292   return(resGO);
293 }
294
295
296 /*
297  * 0xc6-0xc7 1 12 XCH A,@Ri
298  *____________________________________________________________________________
299  *
300  */
301
302 int
303 t_uc51::inst_xch_a_Sri(uchar code)
304 {
305   t_mem temp;
306   class cl_cell *cell;
307
308   cell= iram->get_cell(get_reg(code & 0x01)->read());
309   temp= acc->read();
310   acc->write(cell->read());
311   cell->write(temp);
312   return(resGO);
313 }
314
315
316 /*
317  * 0xc8-0xcf 1 12 XCH A,Rn
318  *____________________________________________________________________________
319  *
320  */
321
322 int
323 t_uc51::inst_xch_a_rn(uchar code)
324 {
325   t_mem temp;
326   class cl_cell *reg;
327
328   reg = get_reg(code & 0x07);
329   temp= acc->read();
330   acc->write(reg->read());
331   reg->write(temp);
332   return(resGO);
333 }
334
335
336 /*
337  * 0xd0 2 24 POP addr
338  *____________________________________________________________________________
339  *
340  */
341
342 int
343 t_uc51::inst_pop(uchar code)
344 {
345   t_addr sp;
346   class cl_cell *cell, *stck;
347
348   cell= get_direct(fetch());
349   stck= iram->get_cell(sfr->get(SP));
350   cell->write(stck->read());
351   sp= sfr->wadd(SP, -1);
352   tick(1);
353   return(resGO);
354 }
355
356
357 /*
358  * 0xd6-0xd7 1 12 XCHD A,@Ri
359  *____________________________________________________________________________
360  *
361  */
362
363 int
364 t_uc51::inst_xchd_a_Sri(uchar code)
365 {
366   t_mem temp, d;
367   class cl_cell *cell;
368
369   cell= iram->get_cell(get_reg(code & 0x01)->read());
370   temp= (d= cell->read()) & 0x0f;
371   cell->write((d & 0xf0) | (acc->read() & 0x0f));
372   acc->write((acc->get() & 0xf0) | temp);
373   return(resGO);
374 }
375
376
377 /*
378  * 0xe0 1 24 MOVX A,@DPTR
379  *____________________________________________________________________________
380  *
381  */
382
383 int
384 t_uc51::inst_movx_a_Sdptr(uchar code)
385 {
386   acc->write(read_mem(MEM_XRAM,
387                       sfr->read(DPH)*256 + sfr->read(DPL)));
388   tick(1);
389   return(resGO);
390 }
391
392
393 /*
394  * 0xe2-0xe3 1 24 MOVX A,@Ri
395  *____________________________________________________________________________
396  *
397  */
398
399 int
400 t_uc51::inst_movx_a_Sri(uchar code)
401 {
402   t_mem d;
403
404   d= get_reg(code & 0x01)->read();
405   acc->write(read_mem(MEM_XRAM, sfr->read(P2)*256 + d));
406   tick(1);
407   return(resGO);
408 }
409
410
411 /*
412  * 0xe5 2 12 MOV A,addr
413  *____________________________________________________________________________
414  *
415  */
416
417 int
418 t_uc51::inst_mov_a_addr(uchar code)
419 {
420   class cl_cell *cell;
421   int address = fetch();
422
423   /* If this is ACC, it is an invalid instruction */
424   if (address == ACC)
425     {
426       sim->app->get_commander()->
427         debug ("Invalid Instruction : E5 E0  MOV A,ACC  at  %06x\n", PC);
428
429       return(resHALT);
430     }
431   else
432     {
433       cell= get_direct(address);
434       acc->write(cell->read());
435       return(resGO);
436     }
437   
438 }
439
440
441 /*
442  * 0xe6-0xe7 1 12 MOV A,@Ri
443  *____________________________________________________________________________
444  *
445  */
446
447 int
448 t_uc51::inst_mov_a_Sri(uchar code)
449 {
450   class cl_cell *cell;
451
452   cell= iram->get_cell(get_reg(code & 0x01)->read());
453   acc->write(cell->read());
454   return(resGO);
455 }
456
457
458 /*
459  * 0xe8-0xef 1 12 MOV A,Rn
460  *____________________________________________________________________________
461  *
462  */
463
464 int
465 t_uc51::inst_mov_a_rn(uchar code)
466 {
467   acc->write(get_reg(code & 0x07)->read());
468   return(resGO);
469 }
470
471
472 /*
473  * 0xf0 1 24 MOVX @DPTR,A
474  *____________________________________________________________________________
475  *
476  */
477
478 int
479 t_uc51::inst_movx_Sdptr_a(uchar code)
480 {
481   write_mem(MEM_XRAM, sfr->read(DPH)*256 + sfr->read(DPL), acc->read());
482   tick(1);
483   return(resGO);
484 }
485
486
487 /*
488  * 0xf2-0xf3 1 24 MOVX @Ri,A
489  *____________________________________________________________________________
490  *
491  */
492
493 int
494 t_uc51::inst_movx_Sri_a(uchar code)
495 {
496   t_mem d;
497
498   d= get_reg(code & 0x01)->read();
499   write_mem(MEM_XRAM, sfr->read(P2)*256 + d, acc->read());
500   tick(1);
501   return(resGO);
502 }
503
504
505 /*
506  * 0xf5 2 12 MOV addr,A
507  *____________________________________________________________________________
508  *
509  */
510
511 int
512 t_uc51::inst_mov_addr_a(uchar code)
513 {
514   class cl_cell *cell;
515   
516   cell= get_direct(fetch());
517   cell->write(acc->read());
518   return(resGO);
519 }
520
521
522 /*
523  * 0xf6-0xf7 1 12 MOV @Ri,A
524  *____________________________________________________________________________
525  *
526  */
527
528 int
529 t_uc51::inst_mov_Sri_a(uchar code)
530 {
531   class cl_cell *cell;
532
533   cell= iram->get_cell(get_reg(code & 0x01)->read());
534   cell->write(acc->read());
535   return(resGO);
536 }
537
538
539 /*
540  * 0xf8-0xff 1 12 MOV Rn,A
541  *____________________________________________________________________________
542  *
543  */
544
545 int
546 t_uc51::inst_mov_rn_a(uchar code)
547 {
548   class cl_cell *reg;
549
550   reg= get_reg(code &0x07);
551   reg->write(acc->read());
552   return(resGO);
553 }
554
555
556 /* End of s51.src/mov.cc */