Imported Upstream version 2.9.0
[debian/cc1111] / 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 johan.knol@iduna.nl
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 #include <stdlib.h>
34
35 // local
36 #include "glob.h"
37 #include "xacl.h"
38 #include "regsxa.h"
39
40 #define NOTDONE_ASSERT { printf("**********Instr not done at %d!\n", __LINE__); }
41
42 void cl_xa::store1(t_addr addr, unsigned char val)
43 {
44   if (addr < 0x2000) {
45     set_idata1(addr, val);
46   } else {
47     set_xdata1(addr, val);
48   }
49 }
50
51 void cl_xa::store2(t_addr addr, unsigned short val)
52 {
53   if (addr < 0x2000) {
54     set_idata2(addr, val);
55   } else {
56     set_xdata2(addr, val);
57   }
58 }
59
60 unsigned char cl_xa::get1(t_addr addr)
61 {
62   if (addr < 0x2000) {
63     return get_idata1(addr);
64   } else {
65     return get_xdata1(addr);
66   }
67 }
68
69 unsigned short cl_xa::get2(t_addr addr)
70 {
71   if (addr < 0x2000) {
72     return get_idata2(addr);
73   } else {
74     return get_xdata2(addr);
75   }
76 }
77
78 int cl_xa::get_reg(int word_flag, unsigned int index)
79 {
80   int result;
81
82   if (word_flag) {
83     result = get_word_direct(index);
84   }
85   else {
86     result = get_byte_direct(index);
87   }
88   return result;
89 }
90
91 bool cl_xa::get_bit(int bit) {
92   short offset=0;
93   unsigned char result;
94
95   if (bit>=0x200) {
96     // in sfr space
97     bit-=0x200;
98     offset=0x400;
99   }
100   result = get_byte_direct(offset + (bit/8)) & (1 << (bit%8));
101   return result;
102 }
103
104 void cl_xa::set_bit(int bit, int value) {
105   int i;
106   short offset=0;
107   if (bit>=0x200) {
108     // in sfr space
109     bit-=0x200;
110     offset=0x400;
111   }
112
113   i = get_byte_direct(offset + (bit/8));
114   if (value) {
115     set_byte_direct(offset + (bit/8), i | (1 << (bit%8)) );
116   } else {
117     set_byte_direct(offset + (bit/8), i & ~(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   NOTDONE_ASSERT;
151   return(resGO);
152 }
153
154 int cl_xa::inst_AND(uint code, int operands)
155 {
156 #undef FUNC1
157 #define FUNC1 and1
158 #undef FUNC2
159 #define FUNC2 and2
160 #include "inst_gen.cc"
161   return(resGO);
162 }
163
164 /* logical AND bit with Carry flag */
165 int cl_xa::inst_ANL(uint code, int operands)
166 {
167  unsigned char flags;
168  unsigned short bitAddr = (code&0x03 << 8) + fetch();
169  flags = get_psw();
170
171   if (flags & BIT_C) {
172     /* have work to do */
173     switch(operands) {
174       case CY_BIT :
175         if (!get_bit(bitAddr)) {
176           set_psw(flags & ~BIT_C);
177         }
178       break;
179
180       case CY_NOTBIT :
181         if (get_bit(bitAddr)) {
182           set_psw(flags & ~BIT_C);
183         }
184       break;
185     }
186   }
187
188   return(resGO);
189 }
190
191 /* arithmetic shift left */
192 int cl_xa::inst_ASL(uint code, int operands)
193 {
194   unsigned int dst, cnt;
195   unsigned char flags;
196
197   /* ASL, dest, count
198     while (count != 0)
199       C = dest.80H; dest <<= 1; if sign chg then set V=1
200       this is a confusing one...
201   */
202
203   flags = get_psw();
204   flags &= ~BIT_ALL; /* clear these bits */
205
206   switch(operands) {
207     //{0,0xc150,0xf300,' ',2,ASL, REG_REG         }, //  ASL Rd, Rs                 1 1 0 0 S S 0 1  d d d d s s s s
208     case REG_REG :
209       cnt = reg1(RI_0F) & 0x1f;
210       switch (code & 0xc00) {
211         case 0: // byte
212           dst = reg1(RI_F0);
213           dst <<= cnt;
214           set_reg1(RI_F0,dst);
215           if (dst & 0x100)
216             flags |= BIT_C;
217           if ((dst & 0xff) == 0)
218             flags |= BIT_Z;
219         break;
220         case 1: // word
221           dst = reg2(RI_F0);
222           dst <<= cnt;
223           set_reg2(RI_F0,dst);
224           if (dst & 0x10000)
225             flags |= BIT_C;
226           if ((dst & 0xffff) == 0)
227             flags |= BIT_Z;
228         break;
229         case 2: // ?
230           // not really sure about the encoding here..
231           NOTDONE_ASSERT;
232         break;
233         case 3:  // dword
234           //dst = reg4(RI_F0);
235           dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
236           if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {
237             flags |= BIT_C;
238           }
239           dst <<= cnt;
240           set_reg2(RI_F0,dst & 0xffff);
241           set_reg2(RI_F0+2, (dst>>16) & 0xffff);
242           if (dst == 0)
243             flags |= BIT_Z;
244         break;
245       }
246     break;
247
248     case REG_DATA4 :
249     case REG_DATA5 :
250       switch (code & 0xc00) {
251         case 0: // byte
252           dst = reg1(RI_F0);
253           cnt = operands & 0x0f;
254           dst <<= cnt;
255           set_reg1(RI_F0,dst);
256           if (dst & 0x100)
257             flags |= BIT_C;
258           if ((dst & 0xff) == 0)
259             flags |= BIT_Z;
260         break;
261         case 1: // word
262           dst = reg2(RI_F0);
263           cnt = operands & 0x0f;
264           dst <<= cnt;
265           set_reg2(RI_F0,dst);
266           if (dst & 0x10000)
267             flags |= BIT_C;
268           if ((dst & 0xffff) == 0)
269             flags |= BIT_Z;
270         break;
271         case 2: // ?
272           // not really sure about the encoding here..
273           NOTDONE_ASSERT;
274         break;
275         case 3:  // dword
276           dst = reg1(RI_F0 & 0xe);
277           cnt = operands & 0x1f;
278           if ((cnt != 0) && (dst & (0x80000000 >> (cnt-1)))) {
279             flags |= BIT_C;
280           }
281           dst <<= cnt;
282           set_reg2(RI_F0,dst & 0xffff);
283           set_reg2(RI_F0+2, (dst>>16) & 0xffff);
284           if (dst == 0)
285             flags |= BIT_Z;
286         break;
287       }
288     break;
289   }
290   set_psw(flags);
291
292   return(resGO);
293 }
294
295 /* arithmetic shift right */
296 int cl_xa::inst_ASR(uint code, int operands)
297 {
298   unsigned int dst, cnt;
299   unsigned char flags;
300
301   /* ASR, dest, count
302     while (count != 0)
303       C = dest.0; dest >>= 1;
304       this is a confusing one...
305   */
306
307   flags = get_psw();
308   flags &= ~BIT_ALL; /* clear these bits */
309
310   switch(operands) {
311     case REG_REG :
312       cnt = reg1(RI_0F) & 0x1f;
313       switch (code & 0xc00) {
314         case 0: // byte
315           dst = reg1(RI_F0);
316           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
317             flags |= BIT_C;
318           if (dst & 0x01)
319             flags |= BIT_C;
320           dst >>= cnt;
321           set_reg1(RI_F0,dst);
322           if ((dst & 0xff) == 0)
323             flags |= BIT_Z;
324         break;
325         case 1: // word
326           dst = reg2(RI_F0);
327           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
328             flags |= BIT_C;
329           dst >>= cnt;
330           set_reg2(RI_F0,dst);
331           if ((dst & 0xffff) == 0)
332             flags |= BIT_Z;
333         break;
334         case 2: // ?
335           // not really sure about the encoding here..
336           NOTDONE_ASSERT;
337         break;
338         case 3:  // dword
339           dst = reg2(RI_F0) | (reg2(RI_F0 + 2) << 16);
340           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
341             flags |= BIT_C;
342           dst >>= cnt;
343           set_reg2(RI_F0,dst & 0xffff);
344           set_reg2(RI_F0+2, (dst>>16) & 0xffff);
345           if (dst == 0)
346             flags |= BIT_Z;
347         break;
348       }
349     break;
350
351     case REG_DATA4 :
352     case REG_DATA5 :
353       switch (code & 0xc00) {
354         case 0: // byte
355           dst = reg1(RI_F0);
356           cnt = operands & 0x0f;
357           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
358             flags |= BIT_C;
359           dst >>= cnt;
360           set_reg1(RI_F0,dst);
361           if ((dst & 0xff) == 0)
362             flags |= BIT_Z;
363         break;
364         case 1: // word
365           dst = reg2(RI_F0);
366           cnt = operands & 0x0f;
367           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
368             flags |= BIT_C;
369           dst >>= cnt;
370           set_reg2(RI_F0,dst);
371           if ((dst & 0xffff) == 0)
372             flags |= BIT_Z;
373         break;
374         case 2: // ?
375           // not really sure about the encoding here..
376           NOTDONE_ASSERT;
377         break;
378         case 3:  // dword
379           dst = reg1(RI_F0 & 0xe);
380           cnt = operands & 0x1f;
381           if ((cnt != 0) && (dst & (0x00000001 << (cnt-1))))
382             flags |= BIT_C;
383           dst >>= cnt;
384           set_reg2(RI_F0,dst & 0xffff);
385           set_reg2(RI_F0+2, (dst>>16) & 0xffff);
386           if (dst == 0)
387             flags |= BIT_Z;
388         break;
389       }
390     break;
391   }
392   set_psw(flags);
393
394   return(resGO);
395 }
396
397 int cl_xa::inst_BCC(uint code, int operands)
398 {
399   short jmpAddr = fetch1()*2;
400   if (!(get_psw() & BIT_C)) {
401     PC=(PC+jmpAddr)&0xfffffe;
402   }
403   return(resGO);
404 }
405
406 int cl_xa::inst_BCS(uint code, int operands)
407 {
408   short jmpAddr = fetch1()*2;
409   if (get_psw() & BIT_C) {
410     PC=(PC+jmpAddr)&0xfffffe;
411   }
412   return(resGO);
413 }
414
415 int cl_xa::inst_BEQ(uint code, int operands)
416 {
417   short jmpAddr = fetch1()*2;
418   if (get_psw() & BIT_Z) {
419     PC=(PC+jmpAddr)&0xfffffe;
420   }
421   return(resGO);
422 }
423
424 int cl_xa::inst_BG(uint code, int operands)
425 {
426   short jmpAddr = fetch1()*2;
427   short flags=get_psw();
428   bool Z=flags&BIT_Z, C=flags&BIT_C;
429   if (!(Z|C)) {
430     PC=(PC+jmpAddr)&0xfffffe;
431   }
432   return(resGO);
433 }
434 int cl_xa::inst_BGE(uint code, int operands)
435 {
436   short jmpAddr = fetch1()*2;
437   short flags=get_psw();
438   bool N=flags&BIT_N, V=flags&BIT_V;
439   if (!(N^V)) {
440     PC=(PC+jmpAddr)&0xfffffe;
441   }
442   return(resGO);
443 }
444 int cl_xa::inst_BGT(uint code, int operands)
445 {
446   short jmpAddr = fetch1()*2;
447   short flags=get_psw();
448   bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
449   if (!((Z|N)^V)) {
450     PC=(PC+jmpAddr)&0xfffffe;
451   }
452   return(resGO);
453 }
454 int cl_xa::inst_BKPT(uint code, int operands)
455 {
456   NOTDONE_ASSERT;
457   return(resGO);
458 }
459 int cl_xa::inst_BL(uint code, int operands)
460 {
461   short jmpAddr = fetch1()*2;
462   short flags=get_psw();
463   bool Z=flags&BIT_Z, C=flags&BIT_C;
464   if (Z|C) {
465     PC=(PC+jmpAddr)&0xfffffe;
466   }
467   return(resGO);
468 }
469 int cl_xa::inst_BLE(uint code, int operands)
470 {
471   short jmpAddr = fetch1()*2;
472   short flags=get_psw();
473   bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
474   if ((Z|N)^V) {
475     PC=(PC+jmpAddr)&0xfffffe;
476   }
477   return(resGO);
478 }
479 int cl_xa::inst_BLT(uint code, int operands)
480 {
481   short jmpAddr = fetch1()*2;
482   short flags=get_psw();
483   bool N=flags&BIT_N, V=flags&BIT_V;
484   if (N^V) {
485     PC=(PC+jmpAddr)&0xfffffe;
486   }
487   return(resGO);
488 }
489 int cl_xa::inst_BMI(uint code, int operands)
490 {
491   short jmpAddr = fetch1()*2;
492   if (get_psw()&BIT_N) {
493     PC=(PC+jmpAddr)&0xfffffe;
494   }
495   return(resGO);
496 }
497 int cl_xa::inst_BNE(uint code, int operands)
498 {
499   short jmpAddr = fetch1()*2;
500   if (!(get_psw()&BIT_Z)) {
501     PC=(PC+jmpAddr)&0xfffffe;
502   }
503   return(resGO);
504 }
505 int cl_xa::inst_BNV(uint code, int operands)
506 {
507   short jmpAddr = fetch1()*2;
508   if (!(get_psw()&BIT_V)) {
509     PC=(PC+jmpAddr)&0xfffffe;
510   }
511   return(resGO);
512 }
513 int cl_xa::inst_BOV(uint code, int operands)
514 {
515   short jmpAddr = fetch1()*2;
516   if (get_psw()&BIT_V) {
517     PC=(PC+jmpAddr)&0xfffffe;
518   }
519   return(resGO);
520 }
521 int cl_xa::inst_BPL(uint code, int operands)
522 {
523   short jmpAddr = fetch1()*2;
524   if (!(get_psw()&BIT_N)) {
525     PC=(PC+jmpAddr)&0xfffffe;
526   }
527   return(resGO);
528 }
529
530 int cl_xa::inst_BR(uint code, int operands)
531 {
532   short jmpAddr = fetch1()*2;
533   PC=(PC+jmpAddr)&0xfffffe;
534   return(resGO);
535 }
536
537 int cl_xa::inst_CALL(uint code, int operands)
538 {
539   int jmpaddr;
540   unsigned int sp;
541   bool pageZero=get_scr()&1;
542
543   switch(operands) {
544     case REL16:
545     {
546       jmpaddr = (signed short)fetch2();
547       sp = get_sp() - (pageZero ? 2 : 4);
548       set_sp(sp);
549       store2(sp, PC&0xffff);
550       if (!pageZero) {
551         store2(sp+2, (PC>>16)&0xff);
552       }
553       jmpaddr *= 2;
554       PC = (PC + jmpaddr) & 0xfffffe;
555     }
556     break;
557     case IREG:
558     {
559       sp = get_sp() - (pageZero ? 2 : 4);
560       set_sp(sp);
561       store2(sp, PC&0xffff);
562       if (!pageZero) {
563         store2(sp+2, (PC>>16)&0xff);
564       }
565       jmpaddr = reg2(RI_07);
566       jmpaddr *= 2;
567       PC = (PC + jmpaddr) & 0xfffffe;
568     }
569     break;
570   }
571   return(resGO);
572 }
573
574 int cl_xa::inst_CJNE(uint code, int operands)
575 {
576   switch(operands) {
577     case REG_DIRECT_REL8:
578     {
579        // update C,N,Z
580        if (code & 0x800) {  // word op
581          int result;
582          int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
583          int addr = (fetch1() * 2);
584          int dst = reg2(RI_F0);
585          unsigned char flags;
586          flags = get_psw();
587          flags &= ~BIT_ALL; /* clear these bits */
588          result = dst - src;
589          if (result == 0) flags |= BIT_Z;
590          if (result > 0xffff) flags |= BIT_C;
591          if (dst < src) flags |= BIT_N;
592          set_psw(flags);
593          if (flags & BIT_Z)
594            PC += addr;
595        } else {
596          int result;
597          int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
598          int addr = (fetch1() * 2);
599          int dst = reg1(RI_F0);
600          unsigned char flags;
601          flags = get_psw();
602          flags &= ~BIT_ALL; /* clear these bits */
603          result = dst - src;
604          if (result == 0) flags |= BIT_Z;
605          if (result > 0xff) flags |= BIT_C;
606          if (dst < src) flags |= BIT_N;
607          set_psw(flags);
608          if (flags & BIT_Z)
609            PC += addr;
610        }
611     }
612     break;
613
614     case DIRECT_REL8:
615     {
616        int daddr = ((code & 0x7) << 8) | fetch();
617        int addr = fetch() * 2;
618
619        if (code & 0x800) {  // word op
620          unsigned short tmp = get_word_direct(daddr)-1;
621          set_word_direct(daddr, tmp);
622          if (tmp != 0)
623            PC += addr;
624        } else {
625          unsigned char tmp = get_word_direct(daddr)-1;
626          set_byte_direct(daddr, tmp);
627          if (tmp != 0)
628            PC += addr;
629        }
630     }
631     break;
632   }
633   return(resGO);
634 }
635
636 int cl_xa::inst_CLR(uint code, int operands)
637 {
638   unsigned short bitAddr = (code&0x03 << 8) + fetch();
639   set_bit (bitAddr, 0);
640   return(resGO);
641 }
642
643 int cl_xa::inst_CMP(uint code, int operands)
644 {
645 #undef FUNC1
646 #define FUNC1 cmp1
647 #undef FUNC2
648 #define FUNC2 cmp2
649 #include "inst_gen.cc"
650   return(resGO);
651 }
652 int cl_xa::inst_CPL(uint code, int operands)
653 {
654   NOTDONE_ASSERT;
655   return(resGO);
656 }
657 int cl_xa::inst_DA(uint code, int operands)
658 {
659   NOTDONE_ASSERT;
660   return(resGO);
661 }
662 int cl_xa::inst_DIV(uint code, int operands)
663 {
664   NOTDONE_ASSERT;
665   return(resGO);
666 }
667
668 int cl_xa::inst_DJNZ(uint code, int operands)
669 {
670   // update N Z flags.
671   switch(operands) {
672     case REG_REL8:
673     {
674        int addr = ( ((char)fetch1()) * 2);
675        if (code & 0x800) {  // word op
676          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
677          set_reg2(RI_F0, tmp);
678          if (tmp != 0)
679            PC = (PC + addr) & 0xfffffe;
680        } else {
681          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
682          set_reg1(RI_F0, tmp);
683          if (tmp != 0)
684            PC = (PC + addr) & 0xfffffe;
685        }
686     }
687     break;
688
689     case DIRECT_REL8:
690     {
691        int daddr = ((code & 0x7) << 8) | fetch();
692        int addr = fetch() * 2;
693
694        if (code & 0x800) {  // word op
695          unsigned short tmp = get_word_direct(daddr)-1;
696          set_word_direct(daddr, tmp);
697          if (tmp != 0)
698            PC += addr;
699        } else {
700          unsigned char tmp = get_word_direct(daddr)-1;
701          set_byte_direct(daddr, tmp);
702          if (tmp != 0)
703            PC += addr;
704        }
705     }
706     break;
707   }
708
709   return(resGO);
710 }
711
712 int cl_xa::inst_FCALL(uint code, int operands)
713 {
714   NOTDONE_ASSERT;
715   return(resGO);
716 }
717
718 int cl_xa::inst_FJMP(uint code, int operands)
719 {
720   NOTDONE_ASSERT;
721   return(resGO);
722 }
723
724 int cl_xa::inst_JB(uint code, int operands)
725 {
726   short bitAddr=((code&0x3)<<8) + fetch1();
727   short jmpAddr = (fetch1() * 2);
728   if (get_bit(bitAddr)) {
729     PC = (PC+jmpAddr)&0xfffffe;
730   }
731   return(resGO);
732 }
733 int cl_xa::inst_JBC(uint code, int operands)
734 {
735   short bitAddr=((code&0x3)<<8) + fetch1();
736   short jmpAddr = (fetch1() * 2);
737   if (get_bit(bitAddr)) {
738     PC = (PC+jmpAddr)&0xfffffe;
739   }
740   set_bit(bitAddr,0);
741   return(resGO);
742 }
743 int cl_xa::inst_JNB(uint code, int operands)
744 {
745   short bitAddr=((code&0x3)<<8) + fetch1();
746   short jmpAddr = (fetch1() * 2);
747   if (!get_bit(bitAddr)) {
748     PC = (PC+jmpAddr)&0xfffffe;
749   }
750   return(resGO);
751 }
752 int cl_xa::inst_JMP(uint code, int operands)
753 {
754   int jmpAddr;
755
756   switch(operands) {
757     case REL16:
758     {
759       jmpAddr = (signed short)fetch2()*2;
760       PC = (PC + jmpAddr) & 0xfffffe;
761     }
762     break;
763     case IREG:
764       PC &= 0xff0000;
765       PC |= (reg2(RI_07) & 0xfffe);  /* word aligned */
766     break;
767     /* fixme 2 more... */
768   }
769   return(resGO);
770 }
771 int cl_xa::inst_JNZ(uint code, int operands)
772 {
773   short saddr = (fetch1() * 2);
774   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
775   if (reg1(8)!=0) {
776     PC = (PC + saddr) & 0xfffffe;
777   }
778   return(resGO);
779 }
780 int cl_xa::inst_JZ(uint code, int operands)
781 {
782   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
783   short saddr = (fetch1() * 2);
784   if (reg1(8)==0) {
785       PC += saddr;
786   }
787   return(resGO);
788 }
789 int cl_xa::inst_LEA(uint code, int operands)
790 {
791   switch (operands) {
792     case REG_REGOFF8:
793       {
794         char offset=fetch1();
795         set_reg2(RI_70, reg2(RI_07)+offset);
796         break;
797       }
798     case REG_REGOFF16:
799       {
800         short offset=fetch2();
801         set_reg2(RI_70, reg2(RI_07)+offset);
802         break;
803       }
804   }
805   return(resGO);
806 }
807 int cl_xa::inst_LSR(uint code, int operands)
808 {
809   NOTDONE_ASSERT;
810   return(resGO);
811 }
812 int cl_xa::inst_MOV(uint code, int operands)
813 {
814 #undef FUNC1
815 #define FUNC1 mov1
816 #undef FUNC2
817 #define FUNC2 mov2
818 #include "inst_gen.cc"
819   return(resGO);
820 }
821 int cl_xa::inst_MOVC(uint code, int operands)
822 {
823   switch (operands) {
824     case REG_IREGINC:
825     {
826       short srcreg = reg2(RI_07);
827       if (code & 0x0800) {  /* word op */
828         set_reg2( RI_F0,
829                   mov2( reg2(RI_F0),
830                         getcode2(srcreg)
831                       )
832                 );
833       } else {
834         set_reg1( RI_F0,
835                   mov1( reg1(RI_F0),
836                         getcode1(srcreg)
837                       )
838                 );
839       }
840       if (operands == REG_IREGINC) {
841         set_reg2(RI_07,  srcreg+1);
842       }
843     }
844     break;
845     case A_APLUSDPTR:
846     {  /* R4l=ACC, R6=DPTR */
847       unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
848       unsigned short result;
849       unsigned char flags;
850       flags = get_psw();
851
852       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
853       result = getcode1(addr);
854       set_reg1( 4, result);
855       if (result == 0) flags |= BIT_Z;
856       if (result & 0x80) flags |= BIT_N;
857       set_psw(flags);
858     }
859     break;
860     case A_APLUSPC:
861     {  /* R4l=ACC, R6=DPTR */
862       unsigned int addr = (PC + reg1(4));
863       unsigned short result;
864       unsigned char flags;
865       flags = get_psw();
866
867       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
868       result = getcode1(addr);
869       set_reg1( 4, result);
870       if (result == 0) flags |= BIT_Z;
871       if (result & 0x80) flags |= BIT_N;
872       set_psw(flags);
873     }
874     break;
875   }
876   return(resGO);
877 }
878 int cl_xa::inst_MOVS(uint code, int operands)
879 {
880   NOTDONE_ASSERT;
881   return(resGO);
882 }
883 int cl_xa::inst_MOVX(uint code, int operands)
884 {
885   NOTDONE_ASSERT;
886   return(resGO);
887 }
888 int cl_xa::inst_MUL(uint code, int operands)
889 {
890   NOTDONE_ASSERT;
891   return(resGO);
892 }
893 int cl_xa::inst_NEG(uint code, int operands)
894 {
895   NOTDONE_ASSERT;
896   return(resGO);
897 }
898 int cl_xa::inst_NOP(uint code, int operands)
899 {
900   return(resGO);
901 }
902 int cl_xa::inst_NORM(uint code, int operands)
903 {
904   NOTDONE_ASSERT;
905   return(resGO);
906 }
907 int cl_xa::inst_OR(uint code, int operands)
908 {
909 #undef FUNC1
910 #define FUNC1 or1
911 #undef FUNC2
912 #define FUNC2 or2
913 #include "inst_gen.cc"
914   return(resGO);
915 }
916
917 int cl_xa::inst_ORL(uint code, int operands)
918 {
919   NOTDONE_ASSERT;
920   return(resGO);
921 }
922
923 int cl_xa::inst_POP(uint code, int operands)
924 {
925   unsigned short sp=get_sp();
926   switch(operands) {
927     case DIRECT:
928     {
929       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
930
931       if (code & 0x0800) {  /* word op */
932         set_word_direct(direct_addr, get2(sp) );
933       } else {
934         set_byte_direct(direct_addr, get2(sp) & 0xff );
935       }
936       set_sp(sp+2);
937     }
938     break;
939
940     case RLIST:
941     {
942       unsigned char rlist = fetch();
943       if (code & 0x0800) { // word op
944         if (code & 0x4000) { // R8-R15
945           if (rlist&0x01) { set_reg2(8, get2(sp)); sp+=2; }
946           if (rlist&0x02) { set_reg2(9, get2(sp)); sp+=2; }
947           if (rlist&0x04) { set_reg2(10, get2(sp)); sp+=2; }
948           if (rlist&0x08) { set_reg2(11, get2(sp)); sp+=2; }
949           if (rlist&0x10) { set_reg2(12, get2(sp)); sp+=2; }
950           if (rlist&0x20) { set_reg2(13, get2(sp)); sp+=2; }
951           if (rlist&0x40) { set_reg2(14, get2(sp)); sp+=2; }
952           if (rlist&0x80) { set_reg2(15, get2(sp)); sp+=2; }
953         } else { // R0-R7
954           if (rlist&0x01) { set_reg2(0, get2(sp)); sp+=2; }
955           if (rlist&0x02) { set_reg2(1, get2(sp)); sp+=2; }
956           if (rlist&0x04) { set_reg2(2, get2(sp)); sp+=2; }
957           if (rlist&0x08) { set_reg2(3, get2(sp)); sp+=2; }
958           if (rlist&0x10) { set_reg2(4, get2(sp)); sp+=2; }
959           if (rlist&0x20) { set_reg2(5, get2(sp)); sp+=2; }
960           if (rlist&0x40) { set_reg2(6, get2(sp)); sp+=2; }
961           if (rlist&0x80) { set_reg2(7, get2(sp)); sp+=2; }
962         }
963       } else { // byte op
964         if (code & 0x4000) { // R4l-R7h
965           if (rlist&0x01) { set_reg1(8, get1(sp)); sp+=2; }
966           if (rlist&0x02) { set_reg1(9, get1(sp)); sp+=2; }
967           if (rlist&0x04) { set_reg1(10, get1(sp)); sp+=2; }
968           if (rlist&0x08) { set_reg1(11, get1(sp)); sp+=2; }
969           if (rlist&0x10) { set_reg1(12, get1(sp)); sp+=2; }
970           if (rlist&0x20) { set_reg1(13, get1(sp)); sp+=2; }
971           if (rlist&0x40) { set_reg1(14, get1(sp)); sp+=2; }
972           if (rlist&0x80) { set_reg1(15, get1(sp)); sp+=2; }
973         } else { // R0l-R3h
974           if (rlist&0x01) { set_reg1(0, get1(sp)); sp+=2; }
975           if (rlist&0x02) { set_reg1(1, get1(sp)); sp+=2; }
976           if (rlist&0x04) { set_reg1(2, get1(sp)); sp+=2; }
977           if (rlist&0x08) { set_reg1(3, get1(sp)); sp+=2; }
978           if (rlist&0x10) { set_reg1(4, get1(sp)); sp+=2; }
979           if (rlist&0x20) { set_reg1(5, get1(sp)); sp+=2; }
980           if (rlist&0x40) { set_reg1(6, get1(sp)); sp+=2; }
981           if (rlist&0x80) { set_reg1(7, get1(sp)); sp+=2; }
982         }
983       }
984     }
985     break;
986   }
987   return(resGO);
988 }
989
990 int cl_xa::inst_PUSH(uint code, int operands)
991 {
992   switch(operands) {
993     case DIRECT:
994     {
995       unsigned short sp;
996       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
997
998       sp = get_sp()-2;
999       set_sp(sp);
1000       if (code & 0x0800) {  /* word op */
1001         store2( sp, get_word_direct(direct_addr));
1002       } else {
1003         store2( sp, get_byte_direct(direct_addr));
1004       }
1005     }
1006     break;
1007
1008     case RLIST:
1009     {
1010       unsigned short sp=get_sp();
1011       unsigned char rlist = fetch();
1012       if (code & 0x0800) { // word op
1013         if (code & 0x4000) { // R15-R8
1014           if (rlist&0x80) { sp-=2; store2(sp, reg2(15)); }
1015           if (rlist&0x40) { sp-=2; store2(sp, reg2(14)); }
1016           if (rlist&0x20) { sp-=2; store2(sp, reg2(13)); }
1017           if (rlist&0x10) { sp-=2; store2(sp, reg2(12)); }
1018           if (rlist&0x08) { sp-=2; store2(sp, reg2(11)); }
1019           if (rlist&0x04) { sp-=2; store2(sp, reg2(10)); }
1020           if (rlist&0x02) { sp-=2; store2(sp, reg2(9)); }
1021           if (rlist&0x01) { sp-=2; store2(sp, reg2(8)); }
1022         } else { // R7-R0
1023           if (rlist&0x80) { sp-=2; store2(sp, reg2(7)); }
1024           if (rlist&0x40) { sp-=2; store2(sp, reg2(6)); }
1025           if (rlist&0x20) { sp-=2; store2(sp, reg2(5)); }
1026           if (rlist&0x10) { sp-=2; store2(sp, reg2(4)); }
1027           if (rlist&0x08) { sp-=2; store2(sp, reg2(3)); }
1028           if (rlist&0x04) { sp-=2; store2(sp, reg2(2)); }
1029           if (rlist&0x02) { sp-=2; store2(sp, reg2(1)); }
1030           if (rlist&0x01) { sp-=2; store2(sp, reg2(0)); }
1031         }
1032       } else { // byte op
1033         if (code & 0x4000) { // R7h-R4l
1034           if (rlist&0x80) { sp-=2; store2(sp, reg1(15)); }
1035           if (rlist&0x40) { sp-=2; store2(sp, reg1(14)); }
1036           if (rlist&0x20) { sp-=2; store2(sp, reg1(13)); }
1037           if (rlist&0x10) { sp-=2; store2(sp, reg1(12)); }
1038           if (rlist&0x08) { sp-=2; store2(sp, reg1(11)); }
1039           if (rlist&0x04) { sp-=2; store2(sp, reg1(10)); }
1040           if (rlist&0x02) { sp-=2; store2(sp, reg1(9)); }
1041           if (rlist&0x01) { sp-=2; store2(sp, reg1(8)); }
1042         } else { // R3h-R0l
1043           if (rlist&0x80) { sp-=2; store2(sp, reg1(7)); }
1044           if (rlist&0x40) { sp-=2; store2(sp, reg1(6)); }
1045           if (rlist&0x20) { sp-=2; store2(sp, reg1(5)); }
1046           if (rlist&0x10) { sp-=2; store2(sp, reg1(4)); }
1047           if (rlist&0x08) { sp-=2; store2(sp, reg1(3)); }
1048           if (rlist&0x04) { sp-=2; store2(sp, reg1(2)); }
1049           if (rlist&0x02) { sp-=2; store2(sp, reg1(1)); }
1050           if (rlist&0x01) { sp-=2; store2(sp, reg1(0)); }
1051         }
1052       }
1053       set_sp(sp);
1054     }
1055     break;
1056   }
1057   return(resGO);
1058 }
1059 int cl_xa::inst_RESET(uint code, int operands)
1060 {
1061   NOTDONE_ASSERT;
1062   return(resGO);
1063 }
1064 int cl_xa::inst_RET(uint code, int operands)
1065 {
1066   unsigned int retaddr;
1067   unsigned short sp;
1068   bool pageZero=get_scr()&1;
1069
1070   sp = get_sp();
1071   retaddr = get2(sp);
1072   if (!pageZero) {
1073     retaddr |= get2(sp+2) << 16;
1074     set_sp(sp+4);
1075   } else {
1076     set_sp(sp+2);
1077   }
1078   PC = retaddr;
1079   return(resGO);
1080 }
1081 int cl_xa::inst_RETI(uint code, int operands)
1082 {
1083   unsigned int retaddr;
1084   unsigned short sp;
1085   bool pageZero=get_scr()&1;
1086
1087   sp = get_sp();
1088   set_psw(get2(sp));
1089   retaddr = get2(sp+2);
1090   if (!pageZero) {
1091     retaddr |= get2(sp+4) << 16;
1092     set_sp(sp+6);
1093   } else {
1094     set_sp(sp+4);
1095   }
1096   PC = retaddr;
1097   return(resGO);
1098 }
1099 int cl_xa::inst_RL(uint code, int operands)
1100 {
1101   NOTDONE_ASSERT;
1102   return(resGO);
1103 }
1104 int cl_xa::inst_RLC(uint code, int operands)
1105 {
1106   NOTDONE_ASSERT;
1107   return(resGO);
1108 }
1109 int cl_xa::inst_RR(uint code, int operands)
1110 {
1111   NOTDONE_ASSERT;
1112   return(resGO);
1113 }
1114 int cl_xa::inst_RRC(uint code, int operands)
1115 {
1116   NOTDONE_ASSERT;
1117   return(resGO);
1118 }
1119 int cl_xa::inst_SETB(uint code, int operands)
1120 {
1121   unsigned short bitAddr = (code&0x03 << 8) + fetch();
1122   set_bit (bitAddr, 1);
1123   return(resGO);
1124 }
1125
1126 int cl_xa::inst_SEXT(uint code, int operands)
1127 {
1128   bool neg=get_psw()&BIT_N;
1129   if (code & 0x0800) { // word op
1130     set_reg2(RI_F0, neg ? 0xffff : 0);
1131   } else {
1132     set_reg1(RI_F0, neg ? 0xff : 0);
1133   }
1134   return(resGO);
1135 }
1136
1137 int cl_xa::inst_SUB(uint code, int operands)
1138 {
1139 #undef FUNC1
1140 #define FUNC1 sub1
1141 #undef FUNC2
1142 #define FUNC2 sub2
1143 #include "inst_gen.cc"
1144   return(resGO);
1145 }
1146
1147 int cl_xa::inst_SUBB(uint code, int operands)
1148 {
1149 #undef FUNC1
1150 #define FUNC1 subb1
1151 #undef FUNC2
1152 #define FUNC2 subb2
1153 #include "inst_gen.cc"
1154   return(resGO);
1155 }
1156
1157 int cl_xa::inst_TRAP(uint code, int operands)
1158 {
1159   // steal a few opcodes for simulator only putchar() and exit()
1160   // functions.  Used in SDCC regression testing.
1161   switch (code & 0x0f) {
1162     case 0xe:
1163       // implement a simulator putchar() routine
1164       //printf("PUTCHAR-----> %xH\n", reg1(0));
1165       putchar(reg1(0));
1166       fflush(stdout);
1167     break;
1168
1169     case 0xf:
1170       ::exit(0);
1171     break;
1172   }
1173   return(resGO);
1174 }
1175
1176 int cl_xa::inst_XCH(uint code, int operands)
1177 {
1178   NOTDONE_ASSERT;
1179   return(resGO);
1180 }
1181 int cl_xa::inst_XOR(uint code, int operands)
1182 {
1183 #undef FUNC1
1184 #define FUNC1 xor1
1185 #undef FUNC2
1186 #define FUNC2 xor2
1187 #include "inst_gen.cc"
1188   return(resGO);
1189 }
1190
1191 /* End of xa.src/inst.cc */