ec737aa83bd2d38e10cd059eed8574e881502c4f
[fw/sdcc] / sim / ucsim / xa.src / inst.cc
1 /*
2  * Simulator of microcontrollers (inst.cc)
3  *
4  * Copyright (C) 1999,2002 Drotos Daniel, Talker Bt.
5  *
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  * Other contributors include:
8  *   Karl Bongers karl@turbobit.com,
9  *   Johan Knol 
10  *
11  */
12
13 /* This file is part of microcontroller simulator: ucsim.
14
15 UCSIM is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 UCSIM is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with UCSIM; see the file COPYING.  If not, write to the Free
27 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 02111-1307, USA. */
29 /*@1@*/
30
31 #include "ddconfig.h"
32
33 // local
34 #include "glob.h"
35 #include "xacl.h"
36 #include "regsxa.h"
37
38
39 void cl_xa::store1(t_addr addr, unsigned char val)
40 {
41   if (addr < 0x2000) {
42     set_idata1(addr, val);
43   } else {
44     set_xdata1(addr, val);
45   }
46 }
47
48 void cl_xa::store2(t_addr addr, unsigned char val)
49 {
50   if (addr < 0x2000) {
51     set_idata2(addr, val);
52   } else {
53     set_xdata2(addr, val);
54   }
55 }
56
57 unsigned char cl_xa::get1(t_addr addr)
58 {
59   if (addr < 0x2000) {
60     return get_idata1(addr);
61   } else {
62     return get_xdata1(addr);
63   }
64 }
65
66 unsigned short cl_xa::get2(t_addr addr)
67 {
68   if (addr < 0x2000) {
69     return get_idata2(addr);
70   } else {
71     return get_xdata2(addr);
72   }
73 }
74
75 int cl_xa::get_reg(int word_flag, unsigned int index)
76 {
77   int result;
78
79   if (word_flag) {
80     result = get_word_direct(index);
81   }
82   else {
83     result = get_byte_direct(index);
84   }
85   return result;
86 }
87
88 bool cl_xa::get_bit(int bit) {
89   short offset=0;
90   unsigned char result;
91
92   if (bit>=0x200) {
93     // in sfr space
94     bit-=0x200;
95     offset=0x400;
96   }
97   result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
98   return result;
99   //return mem_direct[offset + (bit/8)] & (1 << (bit%8));
100 }
101
102 void cl_xa::set_bit(int bit, int value) {
103   int i;
104   short offset=0;
105   if (bit>=0x200) {
106     // in sfr space
107     bit-=0x200;
108     offset=0x400;
109   }
110
111   i = get_byte_direct(offset + (bit/8));
112   if (value) {
113     set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
114     //mem_direct[offset + (bit/8)] |= (1 << (bit%8));
115   } else {
116     set_byte_direct(offset + (bit/8), i & ~(1 << (bit%8)) );
117     //mem_direct[offset + (bit/8)] &= ~(1 << (bit%8));
118   }
119 }
120
121 #define RI_F0 ((code >> 4) & 0xf)
122 #define RI_70 ((code >> 4) & 0x7)
123 #define RI_0F (code & 0xf)
124 #define RI_07 (code & 0x7)
125
126 int cl_xa::inst_ADD(uint code, int operands)
127 {
128 #undef FUNC1
129 #define FUNC1 add1
130 #undef FUNC2
131 #define FUNC2 add2
132 #include "inst_gen.cc"
133
134   return(resGO);
135 }
136
137 int cl_xa::inst_ADDC(uint code, int operands)
138 {
139 #undef FUNC1
140 #define FUNC1 addc1
141 #undef FUNC2
142 #define FUNC2 addc2
143 #include "inst_gen.cc"
144
145   return(resGO);
146 }
147
148 int cl_xa::inst_ADDS(uint code, int operands)
149 {
150   return(resGO);
151 }
152
153 int cl_xa::inst_AND(uint code, int operands)
154 {
155 #undef FUNC1
156 #define FUNC1 and1
157 #undef FUNC2
158 #define FUNC2 and2
159 #include "inst_gen.cc"
160   return(resGO);
161 }
162
163 int cl_xa::inst_ANL(uint code, int operands)
164 {
165   return(resGO);
166 }
167
168 int cl_xa::inst_ASL(uint code, int operands)
169 {
170   return(resGO);
171 }
172
173 int cl_xa::inst_ASR(uint code, int operands)
174 {
175   return(resGO);
176 }
177
178 int cl_xa::inst_BCC(uint code, int operands)
179 {
180   return(resGO);
181 }
182
183 int cl_xa::inst_BCS(uint code, int operands)
184 {
185   return(resGO);
186 }
187
188 int cl_xa::inst_BEQ(uint code, int operands)
189 {
190   short jmpAddr = fetch1()*2;
191   if (get_psw() & BIT_Z) {
192     PC=(PC+jmpAddr)&0xfffffffe;
193   }
194   return(resGO);
195 }
196
197 int cl_xa::inst_BG(uint code, int operands)
198 {
199   return(resGO);
200 }
201 int cl_xa::inst_BGE(uint code, int operands)
202 {
203   return(resGO);
204 }
205 int cl_xa::inst_BGT(uint code, int operands)
206 {
207   return(resGO);
208 }
209 int cl_xa::inst_BKPT(uint code, int operands)
210 {
211   return(resGO);
212 }
213 int cl_xa::inst_BL(uint code, int operands)
214 {
215   return(resGO);
216 }
217 int cl_xa::inst_BLE(uint code, int operands)
218 {
219   return(resGO);
220 }
221 int cl_xa::inst_BLT(uint code, int operands)
222 {
223   return(resGO);
224 }
225 int cl_xa::inst_BMI(uint code, int operands)
226 {
227   return(resGO);
228 }
229 int cl_xa::inst_BNE(uint code, int operands)
230 {
231   return(resGO);
232 }
233 int cl_xa::inst_BNV(uint code, int operands)
234 {
235   return(resGO);
236 }
237 int cl_xa::inst_BOV(uint code, int operands)
238 {
239   return(resGO);
240 }
241 int cl_xa::inst_BPL(uint code, int operands)
242 {
243   return(resGO);
244 }
245
246 int cl_xa::inst_BR(uint code, int operands)
247 {
248   short jmpAddr = fetch1()*2;
249   PC=(PC+jmpAddr)&0xfffffe;
250   return(resGO);
251 }
252
253 int cl_xa::inst_CALL(uint code, int operands)
254 {
255   int jmpaddr;
256   unsigned int sp;
257   bool pageZero=get_scr()&1;
258
259   switch(operands) {
260     case REL16:
261     {
262       jmpaddr = (signed short)fetch2();
263       sp = get_sp() - (pageZero ? 2 : 4);
264       set_sp(sp);
265       store2(sp, PC&0xffff);
266       if (!pageZero) {
267         store2(sp+2, (PC>>16)&0xff);
268       }
269       jmpaddr *= 2;
270       PC = (PC + jmpaddr) & 0xfffffe;
271     }
272     break;
273     case IREG:
274     {
275       sp = get_sp() - (pageZero ? 2 : 4);
276       set_sp(sp);
277       store2(sp, PC&0xffff);
278       if (!pageZero) {
279         store2(sp+2, (PC>>16)&0xff);
280       }
281       jmpaddr = reg2(RI_07);
282       jmpaddr *= 2;
283       PC = (PC + jmpaddr) & 0xfffffe;
284     }
285     break;
286   }
287   return(resGO);
288 }
289
290 int cl_xa::inst_CJNE(uint code, int operands)
291 {
292   switch(operands) {
293     case REG_DIRECT_REL8:
294     {
295        // update C,N,Z
296        if (code & 0x800) {  // word op
297          int result;
298          int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
299          int addr = (fetch1() * 2);
300          int dst = reg2(RI_F0);
301          unsigned char flags;
302          flags = get_psw();
303          flags &= ~BIT_ALL; /* clear these bits */
304          result = dst - src;
305          if (result == 0) flags |= BIT_Z;
306          if (result > 0xffff) flags |= BIT_C;
307          if (dst < src) flags |= BIT_N;
308          set_psw(flags);
309          if (flags & BIT_Z)
310            PC += addr;
311        } else {
312          int result;
313          int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
314          int addr = (fetch1() * 2);
315          int dst = reg1(RI_F0);
316          unsigned char flags;
317          flags = get_psw();
318          flags &= ~BIT_ALL; /* clear these bits */
319          result = dst - src;
320          if (result == 0) flags |= BIT_Z;
321          if (result > 0xff) flags |= BIT_C;
322          if (dst < src) flags |= BIT_N;
323          set_psw(flags);
324          if (flags & BIT_Z)
325            PC += addr;
326        }
327     }
328     break;
329
330     case DIRECT_REL8:
331     {
332        int daddr = ((code & 0x7) << 8) | fetch();
333        int addr = fetch() * 2;
334
335        if (code & 0x800) {  // word op
336          unsigned short tmp = get_word_direct(daddr)-1;
337          set_word_direct(daddr, tmp);
338          if (tmp != 0)
339            PC += addr;
340        } else {
341          unsigned char tmp = get_word_direct(daddr)-1;
342          set_byte_direct(daddr, tmp);
343          if (tmp != 0)
344            PC += addr;
345        }
346     }
347     break;
348   }
349   return(resGO);
350 }
351
352 int cl_xa::inst_CLR(uint code, int operands)
353 {
354   unsigned short bitAddr = (code&0x03 << 8) + fetch();
355   // fixme: implement
356   bitAddr=bitAddr;
357   return(resGO);
358 }
359
360 int cl_xa::inst_CMP(uint code, int operands)
361 {
362 #undef FUNC1
363 #define FUNC1 cmp1
364 #undef FUNC2
365 #define FUNC2 cmp2
366 #include "inst_gen.cc"
367   return(resGO);
368 }
369 int cl_xa::inst_CPL(uint code, int operands)
370 {
371   return(resGO);
372 }
373 int cl_xa::inst_DA(uint code, int operands)
374 {
375   return(resGO);
376 }
377 int cl_xa::inst_DIV(uint code, int operands)
378 {
379   return(resGO);
380 }
381
382 int cl_xa::inst_DJNZ(uint code, int operands)
383 {
384   // update N Z flags.
385   switch(operands) {
386     case REG_REL8:
387     {
388        int addr = ( ((char)fetch1()) * 2);
389        if (code & 0x800) {  // word op
390          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
391          set_reg2(RI_F0, tmp);
392          if (tmp != 0)
393            PC = (PC + addr) & 0xfffffe;
394        } else {
395          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
396          set_reg1(RI_F0, tmp);
397          if (tmp != 0)
398            PC = (PC + addr) & 0xfffffe;
399        }
400     }
401     break;
402
403     case DIRECT_REL8:
404     {
405        int daddr = ((code & 0x7) << 8) | fetch();
406        int addr = fetch() * 2;
407
408        if (code & 0x800) {  // word op
409          unsigned short tmp = get_word_direct(daddr)-1;
410          set_word_direct(daddr, tmp);
411          if (tmp != 0)
412            PC += addr;
413        } else {
414          unsigned char tmp = get_word_direct(daddr)-1;
415          set_byte_direct(daddr, tmp);
416          if (tmp != 0)
417            PC += addr;
418        }
419     }
420     break;
421   }
422
423   return(resGO);
424 }
425
426 int cl_xa::inst_FCALL(uint code, int operands)
427 {
428   return(resGO);
429 }
430
431 int cl_xa::inst_FJMP(uint code, int operands)
432 {
433   return(resGO);
434 }
435
436 int cl_xa::inst_JB(uint code, int operands)
437 {
438   short bitAddr=((code&0x3)<<8) + fetch1();
439   short jmpAddr = (fetch1() * 2);
440   if (get_bit(bitAddr)) {
441     PC = (PC+jmpAddr)&0xfffffe;
442   }
443   return(resGO);
444 }
445 int cl_xa::inst_JBC(uint code, int operands)
446 {
447   return(resGO);
448 }
449 int cl_xa::inst_JNB(uint code, int operands)
450 {
451   short bitAddr=((code&0x3)<<8) + fetch1();
452   short jmpAddr = (fetch1() * 2);
453   if (!get_bit(bitAddr)) {
454     PC = (PC+jmpAddr)&0xfffffe;
455   }
456   return(resGO);
457   return(resGO);
458 }
459 int cl_xa::inst_JMP(uint code, int operands)
460 {
461   int jmpAddr;
462
463   switch(operands) {
464     case REL16:
465     {
466       jmpAddr = (signed short)fetch2()*2;
467       PC = (PC + jmpAddr) & 0xfffffe;
468     }
469     break;
470     case IREG:
471       PC &= 0xff0000;
472       PC |= (reg2(RI_07) & 0xfffe);  /* word aligned */
473     break;
474     /* fixme 2 more... */
475   }
476   return(resGO);
477 }
478 int cl_xa::inst_JNZ(uint code, int operands)
479 {
480   short saddr = (fetch1() * 2);
481   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
482   if (reg1(8)!=0) {
483     PC = (PC + saddr) & 0xfffffe;
484   }
485   return(resGO);
486 }
487 int cl_xa::inst_JZ(uint code, int operands)
488 {
489   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
490   short saddr = (fetch1() * 2);
491   if (reg1(8)==0) {
492       PC += saddr;
493   }
494   return(resGO);
495 }
496 int cl_xa::inst_LEA(uint code, int operands)
497 {
498   return(resGO);
499 }
500 int cl_xa::inst_LSR(uint code, int operands)
501 {
502   return(resGO);
503 }
504 int cl_xa::inst_MOV(uint code, int operands)
505 {
506 #undef FUNC1
507 #define FUNC1 mov1
508 #undef FUNC2
509 #define FUNC2 mov2
510 #include "inst_gen.cc"
511   return(resGO);
512 }
513 int cl_xa::inst_MOVC(uint code, int operands)
514 {
515   switch (operands) {
516     case REG_IREGINC:
517     {
518       short srcreg = reg2(RI_07);
519       if (code & 0x0800) {  /* word op */
520         set_reg2( RI_F0,
521                   mov2( reg2(RI_F0),
522                         getcode2(srcreg)
523                       )
524                 );
525       } else {
526         set_reg1( RI_F0,
527                   mov1( reg1(RI_F0),
528                         getcode1(srcreg)
529                       )
530                 );
531       }
532       if (operands == REG_IREGINC) {
533         set_reg2(RI_07,  srcreg+1);
534       }
535     }
536     break;
537     case A_APLUSDPTR:
538     {  /* R4l=ACC, R6=DPTR */
539       unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
540       unsigned short result;
541       unsigned char flags;
542       flags = get_psw();
543
544       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
545       result = getcode1(addr);
546       set_reg1( 4, result);
547       if (result == 0) flags |= BIT_Z;
548       if (result & 0x80) flags |= BIT_N;
549       set_psw(flags);
550     }
551     break;
552     case A_APLUSPC:
553     {  /* R4l=ACC, R6=DPTR */
554       unsigned int addr = (PC + reg1(4));
555       unsigned short result;
556       unsigned char flags;
557       flags = get_psw();
558
559       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
560       result = getcode1(addr);
561       set_reg1( 4, result);
562       if (result == 0) flags |= BIT_Z;
563       if (result & 0x80) flags |= BIT_N;
564       set_psw(flags);
565     }
566     break;
567   }
568   return(resGO);
569 }
570 int cl_xa::inst_MOVS(uint code, int operands)
571 {
572   return(resGO);
573 }
574 int cl_xa::inst_MOVX(uint code, int operands)
575 {
576   return(resGO);
577 }
578 int cl_xa::inst_MUL(uint code, int operands)
579 {
580   return(resGO);
581 }
582 int cl_xa::inst_NEG(uint code, int operands)
583 {
584   return(resGO);
585 }
586 int cl_xa::inst_NOP(uint code, int operands)
587 {
588   return(resGO);
589 }
590 int cl_xa::inst_NORM(uint code, int operands)
591 {
592   return(resGO);
593 }
594 int cl_xa::inst_OR(uint code, int operands)
595 {
596 #undef FUNC1
597 #define FUNC1 or1
598 #undef FUNC2
599 #define FUNC2 or2
600 #include "inst_gen.cc"
601   return(resGO);
602 }
603
604 int cl_xa::inst_ORL(uint code, int operands)
605 {
606   return(resGO);
607 }
608
609 int cl_xa::inst_POP(uint code, int operands)
610 {
611   switch(operands) {
612     case DIRECT:
613     {
614       unsigned short sp;
615       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
616
617       sp = get_sp();
618       if (code & 0x0800) {  /* word op */
619         set_word_direct(direct_addr, get2(sp) );
620       } else {
621         set_byte_direct(direct_addr, get2(sp) & 0xff );
622       }
623       set_sp(sp+2);
624     }
625     break;
626
627     case RLIST:
628       // fixme: implement
629       unsigned char rlist = fetch();
630       rlist = rlist; //shutup compiler
631     break;
632   }
633   return(resGO);
634 }
635
636 int cl_xa::inst_PUSH(uint code, int operands)
637 {
638   switch(operands) {
639     case DIRECT:
640     {
641       unsigned short sp;
642       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
643
644       sp = get_sp()-2;
645       set_sp(sp);
646       if (code & 0x0800) {  /* word op */
647         store2( sp, get_word_direct(direct_addr));
648       } else {
649         store2( sp, get_byte_direct(direct_addr));
650       }
651     }
652     break;
653
654     case RLIST:
655       // fixme: implement
656       unsigned char rlist = fetch();
657       rlist = rlist; //shutup compiler
658     break;
659   }
660   
661   return(resGO);
662 }
663 int cl_xa::inst_RESET(uint code, int operands)
664 {
665   return(resGO);
666 }
667 int cl_xa::inst_RET(uint code, int operands)
668 {
669   unsigned int retaddr;
670   unsigned short sp;
671   bool pageZero=get_scr()&1;
672
673   sp = get_sp();
674   retaddr = get2(sp);
675   if (!pageZero) {
676     retaddr |= get2(sp+2) << 16;
677     set_sp(sp+4);
678   } else {
679     set_sp(sp+2);
680   }
681   PC = retaddr;
682   return(resGO);
683 }
684 int cl_xa::inst_RETI(uint code, int operands)
685 {
686   unsigned int retaddr;
687   unsigned short sp;
688   bool pageZero=get_scr()&1;
689
690   sp = get_sp();
691   set_psw(get2(sp));
692   retaddr = get2(sp+2);
693   if (!pageZero) {
694     retaddr |= get2(sp+4) << 16;
695     set_sp(sp+6);
696   } else {
697     set_sp(sp+4);
698   }
699   PC = retaddr;
700   return(resGO);
701 }
702 int cl_xa::inst_RL(uint code, int operands)
703 {
704   return(resGO);
705 }
706 int cl_xa::inst_RLC(uint code, int operands)
707 {
708   return(resGO);
709 }
710 int cl_xa::inst_RR(uint code, int operands)
711 {
712   return(resGO);
713 }
714 int cl_xa::inst_RRC(uint code, int operands)
715 {
716   return(resGO);
717 }
718 int cl_xa::inst_SETB(uint code, int operands)
719 {
720   unsigned short bitAddr = (code&0x03 << 8) + fetch();
721   // fixme: implement
722   bitAddr=bitAddr;
723   return(resGO);
724 }
725
726 int cl_xa::inst_SEXT(uint code, int operands)
727 {
728   return(resGO);
729 }
730
731 int cl_xa::inst_SUB(uint code, int operands)
732 {
733 #undef FUNC1
734 #define FUNC1 sub1
735 #undef FUNC2
736 #define FUNC2 sub2
737 #include "inst_gen.cc"
738   return(resGO);
739 }
740
741 int cl_xa::inst_SUBB(uint code, int operands)
742 {
743 #undef FUNC1
744 #define FUNC1 subb1
745 #undef FUNC2
746 #define FUNC2 subb2
747 #include "inst_gen.cc"
748   return(resGO);
749 }
750 int cl_xa::inst_TRAP(uint code, int operands)
751 {
752   return(resGO);
753 }
754 int cl_xa::inst_XCH(uint code, int operands)
755 {
756   return(resGO);
757 }
758 int cl_xa::inst_XOR(uint code, int operands)
759 {
760 #undef FUNC1
761 #define FUNC1 xor1
762 #undef FUNC2
763 #define FUNC2 xor2
764 #include "inst_gen.cc"
765   return(resGO);
766 }
767
768 /* End of xa.src/inst.cc */