Fixed problem in SDCCalloc.h & fixed problem allocation
[fw/sdcc] / sim / ucsim / avr.src / move_inst.cc
1 /*
2  * Simulator of microcontrollers (move_inst.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 #include "avrcl.h"
29 #include "regsavr.h"
30
31
32 /*
33  * Load Program Memory
34  * LPM
35  * 1001 0101 110X 1000
36  *____________________________________________________________________________
37  */
38
39 int
40 cl_avr::lpm(t_mem code)
41 {
42   t_addr addr;
43   t_mem data;
44
45   addr= ram->get(ZH)*256 + ram->get(ZL);
46   data= rom->read(addr);
47   if (addr & 1)
48     ram->/*write*/set(0, (data>>8)&0xff);
49   else
50     ram->/*write*/set(0, data&0xff);
51   tick(2);
52   return(resGO);
53 }
54
55
56 int
57 cl_avr::elpm(t_mem code)
58 {
59   return(resGO);
60 }
61
62
63 int
64 cl_avr::spm(t_mem code)
65 {
66   return(resGO);
67 }
68
69
70 int
71 cl_avr::espm(t_mem code)
72 {
73   return(resGO);
74 }
75
76
77 /*
78  * Load Immediate
79  * LDI Rd,K 16<=d<=31 0<=K<=255
80  * 1110 KKKK dddd KKKK
81  *____________________________________________________________________________
82  */
83
84 int
85 cl_avr::ldi_Rd_K(t_mem code)
86 {
87   t_addr d;
88   t_mem K;
89
90   d= (code&0xf0)>>4;
91   K= ((code&0xf00)>>4)|(code&0xf);
92   ram->write(d+16, &K);
93   return(resGO);
94 }
95
96
97 int
98 cl_avr::movw_Rd_Rr(t_mem code)
99 {
100   return(resGO);
101 }
102
103
104 /*
105  * Load Indirect From SRAM to Register using Index Z
106  * LDD Rd,Z+q 0<=d<=31, 0<=q<=63
107  * 10q0 qq0d dddd 0qqq
108  *____________________________________________________________________________
109  */
110
111 int
112 cl_avr::ldd_Rd_Z_q(t_mem code)
113 {
114   int d, q;
115   t_addr z;
116
117   d= (code&0x1f0)>>4;
118   q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7);
119   z= ram->get(ZH)*256 + ram->get(ZL);
120   t_mem data= ram->read(z+q);
121   ram->write(d, &data);
122   tick(1);
123   return(resGO);
124 }
125
126
127 /*
128  * Load Indirect From SRAM to Register using Index Y
129  * LDD Rd,Y+q 0<=d<=31, 0<=q<=63
130  * 10q0 qq0d dddd 1qqq
131  *____________________________________________________________________________
132  */
133
134 int
135 cl_avr::ldd_Rd_Y_q(t_mem code)
136 {
137   int d, q;
138   t_addr y;
139
140   d= (code&0x1f0)>>4;
141   q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7);
142   y= ram->get(YH)*256 + ram->get(YL);
143   t_mem data= ram->read(y+q);
144   ram->write(d, &data);
145   tick(1);
146   return(resGO);
147 }
148
149
150 /*
151  * Store Indirect From Register to SRAM using Index Z
152  * ST Z+q,Rr 0<=r<=31, 0<=q<=63
153  * 10q0 qq1r rrrr 0qqq
154  *____________________________________________________________________________
155  */
156
157 int
158 cl_avr::std_Z_q_Rr(t_mem code)
159 {
160   int r, q;
161   t_addr z;
162
163   r= (code&0x1f0)>>4;
164   q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7);
165   z= ram->get(ZH)*256 + ram->get(ZL);
166   t_mem data= ram->read(r);
167   ram->write(z+q, &data);
168   tick(1);
169   return(resGO);
170 }
171
172
173 /*
174  * Store Indirect From Register to SRAM using Index Y
175  * ST Y+q,Rr 0<=r<=31, 0<=q<=63
176  * 10q0 qq1r rrrr 1qqq
177  *____________________________________________________________________________
178  */
179
180 int
181 cl_avr::std_Y_q_Rr(t_mem code)
182 {
183   int r, q;
184   t_addr y;
185
186   r= (code&0x1f0)>>4;
187   q= ((code&0x2000)>>8)|((code&0xc00)>>7)|(code&0x7);
188   y= ram->get(YH)*256 + ram->get(YL);
189   t_mem data= ram->read(r);
190   ram->write(y+q, &data);
191   tick(1);
192   return(resGO);
193 }
194
195
196 /*
197  * Load Direct from SRAM
198  * LDS Rd,k 0<=d<=31, 0<=k<=65535
199  * 1001 000d dddd 0000
200  * kkkk kkkk kkkk kkkk
201  *____________________________________________________________________________
202  */
203
204 int
205 cl_avr::lds_Rd_k(t_mem code)
206 {
207   t_addr d, k;
208
209   d= (code&0x1f0)>>4;
210   k= fetch();
211   t_mem data= ram->read(k);
212   ram->write(d, &data);
213   tick(2);
214   return(resGO);
215 }
216
217
218 /*
219  * Load Indirect From SRAM to register using Index Z
220  * LD Rd,Z+ 0<=d<=31
221  * 1001 000d dddd 0001
222  *____________________________________________________________________________
223  */
224
225 int
226 cl_avr::ld_Rd_Z$(t_mem code)
227 {
228   t_addr z, d;
229
230   d= (code&0x1f0)>>4;
231   z= ram->get(ZH)*256 + ram->get(ZL);
232   t_mem data= ram->read(z);
233   ram->write(d, &data);
234   ram->set(ZL, data= (ram->get(ZL)+1)&0xff);
235   if (!data)
236     ram->set(ZH, (ram->get(ZH)+1)&0xff);
237   tick(1);
238   return(resGO);
239 }
240
241
242 /*
243  * Load Indirect From SRAM to register using Index Z
244  * LD Rd,-Z 0<=d<=31
245  * 1001 000d dddd 0010
246  *____________________________________________________________________________
247  */
248
249 int
250 cl_avr::ld_Rd_$Z(t_mem code)
251 {
252   t_addr z, d;
253   t_mem data;
254
255   d= (code&0x1f0)>>4;
256   ram->set(ZL, z= (ram->get(ZL)-1)&0xff);
257   if (z == 0xff)
258     ram->set(ZH, (ram->get(ZH)-1)&0xff);
259   z= ram->get(ZH)*256 + z;
260   data= ram->read(z);
261   ram->write(d, &data);
262   tick(1);
263   return(resGO);
264 }
265
266
267 int
268 cl_avr::lpm_Rd_Z(t_mem code)
269 {
270   return(resGO);
271 }
272
273
274 int
275 cl_avr::lpm_Rd_Z$(t_mem code)
276 {
277   return(resGO);
278 }
279
280
281 int
282 cl_avr::elpm_Rd_Z(t_mem code)
283 {
284   return(resGO);
285 }
286
287
288 int
289 cl_avr::elpm_Rd_Z$(t_mem code)
290 {
291   return(resGO);
292 }
293
294
295 /*
296  * Load Indirect From SRAM to register using Index Y
297  * LD Rd,Y+ 0<=d<=31
298  * 1001 000d dddd 1001
299  *____________________________________________________________________________
300  */
301
302 int
303 cl_avr::ld_Rd_Y$(t_mem code)
304 {
305   t_addr y, d;
306
307   d= (code&0x1f0)>>4;
308   y= ram->get(YH)*256 + ram->get(YL);
309   t_mem data= ram->read(y);
310   ram->write(d, &data);
311   ram->set(YL, data= (ram->get(YL)+1)&0xff);
312   if (!data)
313     ram->set(YH, (ram->get(YH)+1)&0xff);
314   tick(1);
315   return(resGO);
316 }
317
318
319 /*
320  * Load Indirect From SRAM to register using Index Y
321  * LD Rd,-Y 0<=d<=31
322  * 1001 000d dddd 1010
323  *____________________________________________________________________________
324  */
325
326 int
327 cl_avr::ld_Rd_$Y(t_mem code)
328 {
329   t_addr y, d;
330   t_mem data;
331
332   d= (code&0x1f0)>>4;
333   ram->set(YL, y= (ram->get(YL)-1)&0xff);
334   if (y == 0xff)
335     ram->set(YH, (ram->get(YH)-1)&0xff);
336   y= ram->get(YH)*256 + y;
337   data= ram->read(y);
338   ram->write(d, &data);
339   tick(1);
340   return(resGO);
341 }
342
343
344 /*
345  * Load Indirect From SRAM to register using Index X
346  * LD Rd,X 0<=d<=31
347  * 1001 000d dddd 1100
348  *____________________________________________________________________________
349  */
350
351 int
352 cl_avr::ld_Rd_X(t_mem code)
353 {
354   t_addr x, d;
355
356   d= (code&0x1f0)>>4;
357   x= ram->get(XH)*256 + ram->get(XL);
358   t_mem data= ram->read(x);
359   ram->write(d, &data);
360   tick(1);
361   return(resGO);
362 }
363
364
365 /*
366  * Load Indirect From SRAM to register using Index X
367  * LD Rd,X+ 0<=d<=31
368  * 1001 000d dddd 1101
369  *____________________________________________________________________________
370  */
371
372 int
373 cl_avr::ld_Rd_X$(t_mem code)
374 {
375   t_addr x, d;
376
377   d= (code&0x1f0)>>4;
378   x= ram->get(XH)*256 + ram->get(XL);
379   t_mem data= ram->read(x);
380   ram->write(d, &data);
381   ram->set(XL, data= (ram->get(XL)+1)&0xff);
382   if (!data)
383     ram->set(XH, (ram->get(XH)+1)&0xff);
384   tick(1);
385   return(resGO);
386 }
387
388
389 /*
390  * Load Indirect From SRAM to register using Index X
391  * LD Rd,-X 0<=d<=31
392  * 1001 000d dddd 1110
393  *____________________________________________________________________________
394  */
395
396 int
397 cl_avr::ld_Rd_$X(t_mem code)
398 {
399   t_addr x, d;
400   t_mem data;
401
402   d= (code&0x1f0)>>4;
403   ram->set(XL, x= (ram->get(XL)-1)&0xff);
404   if (x == 0xff)
405     ram->set(XH, (ram->get(XH)-1)&0xff);
406   x= ram->get(XH)*256 + x;
407   data= ram->read(x);
408   ram->write(d, &data);
409   tick(1);
410   return(resGO);
411 }
412
413
414 int
415 cl_avr::pop_Rd(t_mem code)
416 {
417   return(resGO);
418 }
419
420
421 /*
422  * Store Direct to SRAM
423  * STS k,Rr 0<=r<=31, 0<=k<=65535
424  * 1001 001r rrrr 0000
425  * kkkk kkkk kkkk kkkk
426  *____________________________________________________________________________
427  */
428
429 int
430 cl_avr::sts_k_Rr(t_mem code)
431 {
432   t_addr r, k;
433
434   r= (code&0x1f0)>>4;
435   k= fetch();
436   t_mem data= ram->read(r);
437   ram->write(k, &data);
438   tick(2);
439   return(resGO);
440 }
441
442
443 /*
444  * Store Indirect From Register to SRAM using Index Z
445  * ST Z+,Rr 0<=r<=63
446  * 1001 001r rrrr 0001
447  *____________________________________________________________________________
448  */
449
450 int
451 cl_avr::st_Z$_Rr(t_mem code)
452
453   t_addr z, r;
454
455   r= (code&0x1f0)>>4;
456   z= ram->get(ZH)*256 + ram->get(ZL);
457   t_mem data= ram->read(r);
458   ram->write(z, &data);
459   ram->set(ZL, data= (ram->get(ZL)+1)&0xff);
460   if (!data)
461     ram->set(ZH, (ram->get(ZH)+1)&0xff);
462   tick(1);
463   return(resGO);
464 }
465
466
467 /*
468  * Store Indirect From Register to SRAM using Index Z
469  * ST -Z,Rr 0<=r<=63
470  * 1001 001r rrrr 0010
471  *____________________________________________________________________________
472  */
473
474 int
475 cl_avr::st_$Z_Rr(t_mem code)
476 {
477   t_addr z, r;
478   t_mem data;
479
480   r= (code&0x1f0)>>4;
481   ram->set(ZL, z= (ram->get(ZL)-1)&0xff);
482   if (z == 0xff)
483     ram->set(ZH, (ram->get(ZH)-1)&0xff);
484   z= ram->get(ZH)*256 + z;
485   data= ram->read(r);
486   ram->write(z, &data);
487   tick(1);
488   return(resGO);
489 }
490
491
492 /*
493  * Store Indirect From Register to SRAM using Index Y
494  * ST Y+,Rr 0<=r<=63
495  * 1001 001r rrrr 1001
496  *____________________________________________________________________________
497  */
498
499 int
500 cl_avr::st_Y$_Rr(t_mem code)
501 {
502   t_addr y, r;
503
504   r= (code&0x1f0)>>4;
505   y= ram->get(YH)*256 + ram->get(YL);
506   t_mem data= ram->read(r);
507   ram->write(y, &data);
508   ram->set(YL, data= (ram->get(YL)+1)&0xff);
509   if (!data)
510     ram->set(YH, (ram->get(YH)+1)&0xff);
511   tick(1);
512   return(resGO);
513 }
514
515
516 /*
517  * Store Indirect From Register to SRAM using Index Y
518  * ST -Y,Rr 0<=r<=63
519  * 1001 001r rrrr 1010
520  *____________________________________________________________________________
521  */
522
523 int
524 cl_avr::st_$Y_Rr(t_mem code)
525 {
526   t_addr y, r;
527   t_mem data;
528
529   r= (code&0x1f0)>>4;
530   ram->set(YL, y= (ram->get(YL)-1)&0xff);
531   if (y == 0xff)
532     ram->set(YH, (ram->get(YH)-1)&0xff);
533   y= ram->get(YH)*256 + y;
534   data= ram->read(r);
535   ram->write(y, &data);
536   tick(1);
537   return(resGO);
538 }
539
540
541 /*
542  * Store Indirect From Register to SRAM using Index X
543  * ST X,Rr 0<=r<=31
544  * 1001 001r rrrr 1100
545  *____________________________________________________________________________
546  */
547
548 int
549 cl_avr::st_X_Rr(t_mem code)
550 {
551   int r;
552   t_addr x;
553
554   r= (code&0x1f0)>>4;
555   x= ram->get(XH)*256 + ram->get(XL);
556   t_mem data= ram->read(r);
557   ram->write(x, &data);
558   tick(1);
559   return(resGO);
560 }
561
562
563 /*
564  * Store Indirect From Register to SRAM using Index X
565  * ST X+,Rr 0<=r<=63
566  * 1001 001r rrrr 1101
567  *____________________________________________________________________________
568  */
569
570 int
571 cl_avr::st_X$_Rr(t_mem code)
572 {
573   t_addr x, r;
574
575   r= (code&0x1f0)>>4;
576   x= ram->get(XH)*256 + ram->get(XL);
577   t_mem data= ram->read(r);
578   ram->write(x, &data);
579   ram->set(XL, data= (ram->get(XL)+1)&0xff);
580   if (!data)
581     ram->set(XH, (ram->get(XH)+1)&0xff);
582   tick(1);
583   return(resGO);
584 }
585
586
587 /*
588  * Store Indirect From Register to SRAM using Index X
589  * ST -X,Rr 0<=r<=63
590  * 1001 001r rrrr 1110
591  *____________________________________________________________________________
592  */
593
594 int
595 cl_avr::st_$X_Rr(t_mem code)
596 {
597   t_addr x, r;
598   t_mem data;
599
600   r= (code&0x1f0)>>4;
601   ram->set(XL, x= (ram->get(XL)-1)&0xff);
602   if (x == 0xff)
603     ram->set(XH, (ram->get(XH)-1)&0xff);
604   x= ram->get(XH)*256 + x;
605   data= ram->read(r);
606   ram->write(x, &data);
607   tick(1);
608   return(resGO);
609 }
610
611
612 int
613 cl_avr::push_Rr(t_mem code)
614 {
615   return(resGO);
616 }
617
618
619 /*
620  * Swap Nibbles
621  * SWAP Rd 0<=d<=31
622  * 1001 010d dddd 0010
623  *____________________________________________________________________________
624  */
625
626 int
627 cl_avr::swap_Rd(t_mem code)
628 {
629   t_addr d;
630   t_mem data, temp;
631
632   d= (code&0x1f0)>>4;
633   data= ram->read(d);
634   temp= (data>>4)&0xf;
635   data= (data<<4)|temp;
636   ram->write(d, &data);
637   return(resGO);
638 }
639
640
641 /*
642  * Load an I/O Port to Register
643  * IN Rd,P 0<=d<=31 0<=P<=63
644  * 1011 0PPd dddd PPPP
645  *____________________________________________________________________________
646  */
647
648 int
649 cl_avr::in_Rd_A(t_mem code)
650 {
651   t_mem P, data;
652   t_addr d;
653   
654   P= ((code&0x600)>>5)|(code&0xf);
655   d= (code&0x1f0)>>4;
656   data= ram->read(P+0x20);
657   ram->write(d, &data);
658   return(resGO);
659 }
660
661
662 /*
663  * Store Register to I/O Port
664  * OUT P,Rr 0<=r<=31 0<=P<=63
665  * 1011 1PPr rrrr PPPP
666  *____________________________________________________________________________
667  */
668
669 int
670 cl_avr::out_A_Rr(t_mem code)
671 {
672   t_mem P, data;
673   t_addr r;
674   
675   P= ((code&0x600)>>5)|(code&0xf);
676   r= (code&0x1f0)>>4;
677   data= ram->read(r);
678   ram->write(P+0x20, &data);
679   return(resGO);
680 }
681
682
683 /*
684  * Copy Register
685  * MOV Rd,Rr 0<=d<=31 0<=r<=31
686  * 0010 11rd dddd rrrr
687  *____________________________________________________________________________
688  */
689
690 int
691 cl_avr::mov_Rd_Rr(t_mem code)
692 {
693   t_addr d, r;
694   
695   d= (code&0x1f0)>>4;
696   r= ((code&0x200)>>5)|(code&0xf);
697   t_mem data= ram->read(r);
698   ram->write(d, &data);
699   return(resGO);
700 }
701
702
703 /* End of avr.src/move_inst.cc */