*** empty log message ***
[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 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 // 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 short 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   short jmpAddr = fetch1()*2;
181   if (!(get_psw() & BIT_C)) {
182     PC=(PC+jmpAddr)&0xfffffe;
183   }
184   return(resGO);
185 }
186
187 int cl_xa::inst_BCS(uint code, int operands)
188 {
189   short jmpAddr = fetch1()*2;
190   if (get_psw() & BIT_C) {
191     PC=(PC+jmpAddr)&0xfffffe;
192   }
193   return(resGO);
194 }
195
196 int cl_xa::inst_BEQ(uint code, int operands)
197 {
198   short jmpAddr = fetch1()*2;
199   if (get_psw() & BIT_Z) {
200     PC=(PC+jmpAddr)&0xfffffe;
201   }
202   return(resGO);
203 }
204
205 int cl_xa::inst_BG(uint code, int operands)
206 {
207   short jmpAddr = fetch1()*2;
208   short flags=get_psw();
209   bool Z=flags&BIT_Z, C=flags&BIT_C;
210   if (!(Z|C)) {
211     PC=(PC+jmpAddr)&0xfffffe;
212   }
213   return(resGO);
214 }
215 int cl_xa::inst_BGE(uint code, int operands)
216 {
217   short jmpAddr = fetch1()*2;
218   short flags=get_psw();
219   bool N=flags&BIT_N, V=flags&BIT_V;
220   if (!(N^V)) {
221     PC=(PC+jmpAddr)&0xfffffe;
222   }
223   return(resGO);
224 }
225 int cl_xa::inst_BGT(uint code, int operands)
226 {
227   short jmpAddr = fetch1()*2;
228   short flags=get_psw();
229   bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
230   if (!((Z|N)^V)) {
231     PC=(PC+jmpAddr)&0xfffffe;
232   }
233   return(resGO);
234 }
235 int cl_xa::inst_BKPT(uint code, int operands)
236 {
237   return(resGO);
238 }
239 int cl_xa::inst_BL(uint code, int operands)
240 {
241   short jmpAddr = fetch1()*2;
242   short flags=get_psw();
243   bool Z=flags&BIT_Z, C=flags&BIT_C;
244   if (Z|C) {
245     PC=(PC+jmpAddr)&0xfffffe;
246   }
247   return(resGO);
248 }
249 int cl_xa::inst_BLE(uint code, int operands)
250 {
251   short jmpAddr = fetch1()*2;
252   short flags=get_psw();
253   bool Z=flags&BIT_Z, N=flags&BIT_N, V=flags&BIT_V;
254   if ((Z|N)^V) {
255     PC=(PC+jmpAddr)&0xfffffe;
256   }
257   return(resGO);
258 }
259 int cl_xa::inst_BLT(uint code, int operands)
260 {
261   short jmpAddr = fetch1()*2;
262   short flags=get_psw();
263   bool N=flags&BIT_N, V=flags&BIT_V;
264   if (N^V) {
265     PC=(PC+jmpAddr)&0xfffffe;
266   }
267   return(resGO);
268 }
269 int cl_xa::inst_BMI(uint code, int operands)
270 {
271   short jmpAddr = fetch1()*2;
272   if (get_psw()&BIT_N) {
273     PC=(PC+jmpAddr)&0xfffffe;
274   }
275   return(resGO);
276 }
277 int cl_xa::inst_BNE(uint code, int operands)
278 {
279   short jmpAddr = fetch1()*2;
280   if (!(get_psw()&BIT_Z)) {
281     PC=(PC+jmpAddr)&0xfffffe;
282   }
283   return(resGO);
284 }
285 int cl_xa::inst_BNV(uint code, int operands)
286 {
287   short jmpAddr = fetch1()*2;
288   if (!(get_psw()&BIT_V)) {
289     PC=(PC+jmpAddr)&0xfffffe;
290   }
291   return(resGO);
292 }
293 int cl_xa::inst_BOV(uint code, int operands)
294 {
295   short jmpAddr = fetch1()*2;
296   if (get_psw()&BIT_V) {
297     PC=(PC+jmpAddr)&0xfffffe;
298   }
299   return(resGO);
300 }
301 int cl_xa::inst_BPL(uint code, int operands)
302 {
303   short jmpAddr = fetch1()*2;
304   if (!(get_psw()&BIT_N)) {
305     PC=(PC+jmpAddr)&0xfffffe;
306   }
307   return(resGO);
308 }
309
310 int cl_xa::inst_BR(uint code, int operands)
311 {
312   short jmpAddr = fetch1()*2;
313   PC=(PC+jmpAddr)&0xfffffe;
314   return(resGO);
315 }
316
317 int cl_xa::inst_CALL(uint code, int operands)
318 {
319   int jmpaddr;
320   unsigned int sp;
321   bool pageZero=get_scr()&1;
322
323   switch(operands) {
324     case REL16:
325     {
326       jmpaddr = (signed short)fetch2();
327       sp = get_sp() - (pageZero ? 2 : 4);
328       set_sp(sp);
329       store2(sp, PC&0xffff);
330       if (!pageZero) {
331         store2(sp+2, (PC>>16)&0xff);
332       }
333       jmpaddr *= 2;
334       PC = (PC + jmpaddr) & 0xfffffe;
335     }
336     break;
337     case IREG:
338     {
339       sp = get_sp() - (pageZero ? 2 : 4);
340       set_sp(sp);
341       store2(sp, PC&0xffff);
342       if (!pageZero) {
343         store2(sp+2, (PC>>16)&0xff);
344       }
345       jmpaddr = reg2(RI_07);
346       jmpaddr *= 2;
347       PC = (PC + jmpaddr) & 0xfffffe;
348     }
349     break;
350   }
351   return(resGO);
352 }
353
354 int cl_xa::inst_CJNE(uint code, int operands)
355 {
356   switch(operands) {
357     case REG_DIRECT_REL8:
358     {
359        // update C,N,Z
360        if (code & 0x800) {  // word op
361          int result;
362          int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
363          int addr = (fetch1() * 2);
364          int dst = reg2(RI_F0);
365          unsigned char flags;
366          flags = get_psw();
367          flags &= ~BIT_ALL; /* clear these bits */
368          result = dst - src;
369          if (result == 0) flags |= BIT_Z;
370          if (result > 0xffff) flags |= BIT_C;
371          if (dst < src) flags |= BIT_N;
372          set_psw(flags);
373          if (flags & BIT_Z)
374            PC += addr;
375        } else {
376          int result;
377          int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
378          int addr = (fetch1() * 2);
379          int dst = reg1(RI_F0);
380          unsigned char flags;
381          flags = get_psw();
382          flags &= ~BIT_ALL; /* clear these bits */
383          result = dst - src;
384          if (result == 0) flags |= BIT_Z;
385          if (result > 0xff) flags |= BIT_C;
386          if (dst < src) flags |= BIT_N;
387          set_psw(flags);
388          if (flags & BIT_Z)
389            PC += addr;
390        }
391     }
392     break;
393
394     case DIRECT_REL8:
395     {
396        int daddr = ((code & 0x7) << 8) | fetch();
397        int addr = fetch() * 2;
398
399        if (code & 0x800) {  // word op
400          unsigned short tmp = get_word_direct(daddr)-1;
401          set_word_direct(daddr, tmp);
402          if (tmp != 0)
403            PC += addr;
404        } else {
405          unsigned char tmp = get_word_direct(daddr)-1;
406          set_byte_direct(daddr, tmp);
407          if (tmp != 0)
408            PC += addr;
409        }
410     }
411     break;
412   }
413   return(resGO);
414 }
415
416 int cl_xa::inst_CLR(uint code, int operands)
417 {
418   unsigned short bitAddr = (code&0x03 << 8) + fetch();
419   set_bit (bitAddr, 0);
420   return(resGO);
421 }
422
423 int cl_xa::inst_CMP(uint code, int operands)
424 {
425 #undef FUNC1
426 #define FUNC1 cmp1
427 #undef FUNC2
428 #define FUNC2 cmp2
429 #include "inst_gen.cc"
430   return(resGO);
431 }
432 int cl_xa::inst_CPL(uint code, int operands)
433 {
434   return(resGO);
435 }
436 int cl_xa::inst_DA(uint code, int operands)
437 {
438   return(resGO);
439 }
440 int cl_xa::inst_DIV(uint code, int operands)
441 {
442   return(resGO);
443 }
444
445 int cl_xa::inst_DJNZ(uint code, int operands)
446 {
447   // update N Z flags.
448   switch(operands) {
449     case REG_REL8:
450     {
451        int addr = ( ((char)fetch1()) * 2);
452        if (code & 0x800) {  // word op
453          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
454          set_reg2(RI_F0, tmp);
455          if (tmp != 0)
456            PC = (PC + addr) & 0xfffffe;
457        } else {
458          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
459          set_reg1(RI_F0, tmp);
460          if (tmp != 0)
461            PC = (PC + addr) & 0xfffffe;
462        }
463     }
464     break;
465
466     case DIRECT_REL8:
467     {
468        int daddr = ((code & 0x7) << 8) | fetch();
469        int addr = fetch() * 2;
470
471        if (code & 0x800) {  // word op
472          unsigned short tmp = get_word_direct(daddr)-1;
473          set_word_direct(daddr, tmp);
474          if (tmp != 0)
475            PC += addr;
476        } else {
477          unsigned char tmp = get_word_direct(daddr)-1;
478          set_byte_direct(daddr, tmp);
479          if (tmp != 0)
480            PC += addr;
481        }
482     }
483     break;
484   }
485
486   return(resGO);
487 }
488
489 int cl_xa::inst_FCALL(uint code, int operands)
490 {
491   return(resGO);
492 }
493
494 int cl_xa::inst_FJMP(uint code, int operands)
495 {
496   return(resGO);
497 }
498
499 int cl_xa::inst_JB(uint code, int operands)
500 {
501   short bitAddr=((code&0x3)<<8) + fetch1();
502   short jmpAddr = (fetch1() * 2);
503   if (get_bit(bitAddr)) {
504     PC = (PC+jmpAddr)&0xfffffe;
505   }
506   return(resGO);
507 }
508 int cl_xa::inst_JBC(uint code, int operands)
509 {
510   return(resGO);
511 }
512 int cl_xa::inst_JNB(uint code, int operands)
513 {
514   short bitAddr=((code&0x3)<<8) + fetch1();
515   short jmpAddr = (fetch1() * 2);
516   if (!get_bit(bitAddr)) {
517     PC = (PC+jmpAddr)&0xfffffe;
518   }
519   return(resGO);
520   return(resGO);
521 }
522 int cl_xa::inst_JMP(uint code, int operands)
523 {
524   int jmpAddr;
525
526   switch(operands) {
527     case REL16:
528     {
529       jmpAddr = (signed short)fetch2()*2;
530       PC = (PC + jmpAddr) & 0xfffffe;
531     }
532     break;
533     case IREG:
534       PC &= 0xff0000;
535       PC |= (reg2(RI_07) & 0xfffe);  /* word aligned */
536     break;
537     /* fixme 2 more... */
538   }
539   return(resGO);
540 }
541 int cl_xa::inst_JNZ(uint code, int operands)
542 {
543   short saddr = (fetch1() * 2);
544   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
545   if (reg1(8)!=0) {
546     PC = (PC + saddr) & 0xfffffe;
547   }
548   return(resGO);
549 }
550 int cl_xa::inst_JZ(uint code, int operands)
551 {
552   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
553   short saddr = (fetch1() * 2);
554   if (reg1(8)==0) {
555       PC += saddr;
556   }
557   return(resGO);
558 }
559 int cl_xa::inst_LEA(uint code, int operands)
560 {
561   return(resGO);
562 }
563 int cl_xa::inst_LSR(uint code, int operands)
564 {
565   return(resGO);
566 }
567 int cl_xa::inst_MOV(uint code, int operands)
568 {
569 #undef FUNC1
570 #define FUNC1 mov1
571 #undef FUNC2
572 #define FUNC2 mov2
573 #include "inst_gen.cc"
574   return(resGO);
575 }
576 int cl_xa::inst_MOVC(uint code, int operands)
577 {
578   switch (operands) {
579     case REG_IREGINC:
580     {
581       short srcreg = reg2(RI_07);
582       if (code & 0x0800) {  /* word op */
583         set_reg2( RI_F0,
584                   mov2( reg2(RI_F0),
585                         getcode2(srcreg)
586                       )
587                 );
588       } else {
589         set_reg1( RI_F0,
590                   mov1( reg1(RI_F0),
591                         getcode1(srcreg)
592                       )
593                 );
594       }
595       if (operands == REG_IREGINC) {
596         set_reg2(RI_07,  srcreg+1);
597       }
598     }
599     break;
600     case A_APLUSDPTR:
601     {  /* R4l=ACC, R6=DPTR */
602       unsigned int addr = (PC & 0xff0000) | (reg1(4) + reg2(6));
603       unsigned short result;
604       unsigned char flags;
605       flags = get_psw();
606
607       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
608       result = getcode1(addr);
609       set_reg1( 4, result);
610       if (result == 0) flags |= BIT_Z;
611       if (result & 0x80) flags |= BIT_N;
612       set_psw(flags);
613     }
614     break;
615     case A_APLUSPC:
616     {  /* R4l=ACC, R6=DPTR */
617       unsigned int addr = (PC + reg1(4));
618       unsigned short result;
619       unsigned char flags;
620       flags = get_psw();
621
622       flags &= ~(BIT_Z | BIT_N); /* clear these bits */
623       result = getcode1(addr);
624       set_reg1( 4, result);
625       if (result == 0) flags |= BIT_Z;
626       if (result & 0x80) flags |= BIT_N;
627       set_psw(flags);
628     }
629     break;
630   }
631   return(resGO);
632 }
633 int cl_xa::inst_MOVS(uint code, int operands)
634 {
635   return(resGO);
636 }
637 int cl_xa::inst_MOVX(uint code, int operands)
638 {
639   return(resGO);
640 }
641 int cl_xa::inst_MUL(uint code, int operands)
642 {
643   return(resGO);
644 }
645 int cl_xa::inst_NEG(uint code, int operands)
646 {
647   return(resGO);
648 }
649 int cl_xa::inst_NOP(uint code, int operands)
650 {
651   return(resGO);
652 }
653 int cl_xa::inst_NORM(uint code, int operands)
654 {
655   return(resGO);
656 }
657 int cl_xa::inst_OR(uint code, int operands)
658 {
659 #undef FUNC1
660 #define FUNC1 or1
661 #undef FUNC2
662 #define FUNC2 or2
663 #include "inst_gen.cc"
664   return(resGO);
665 }
666
667 int cl_xa::inst_ORL(uint code, int operands)
668 {
669   return(resGO);
670 }
671
672 int cl_xa::inst_POP(uint code, int operands)
673 {
674   unsigned short sp=get_sp();
675   switch(operands) {
676     case DIRECT:
677     {
678       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
679
680       if (code & 0x0800) {  /* word op */
681         set_word_direct(direct_addr, get2(sp) );
682       } else {
683         set_byte_direct(direct_addr, get2(sp) & 0xff );
684       }
685       set_sp(sp+2);
686     }
687     break;
688
689     case RLIST:
690     {
691       unsigned char rlist = fetch();
692       if (code & 0x0800) { // word op
693         if (code & 0x4000) { // R8-R15
694           if (rlist&0x01) { set_reg2(8, get2(sp)); sp+=2; }
695           if (rlist&0x02) { set_reg2(9, get2(sp)); sp+=2; }
696           if (rlist&0x04) { set_reg2(10, get2(sp)); sp+=2; }
697           if (rlist&0x08) { set_reg2(11, get2(sp)); sp+=2; }
698           if (rlist&0x10) { set_reg2(12, get2(sp)); sp+=2; }
699           if (rlist&0x20) { set_reg2(13, get2(sp)); sp+=2; }
700           if (rlist&0x40) { set_reg2(14, get2(sp)); sp+=2; }
701           if (rlist&0x80) { set_reg2(15, get2(sp)); sp+=2; }
702         } else { // R0-R7
703           if (rlist&0x01) { set_reg2(0, get2(sp)); sp+=2; }
704           if (rlist&0x02) { set_reg2(1, get2(sp)); sp+=2; }
705           if (rlist&0x04) { set_reg2(2, get2(sp)); sp+=2; }
706           if (rlist&0x08) { set_reg2(3, get2(sp)); sp+=2; }
707           if (rlist&0x10) { set_reg2(4, get2(sp)); sp+=2; }
708           if (rlist&0x20) { set_reg2(5, get2(sp)); sp+=2; }
709           if (rlist&0x40) { set_reg2(6, get2(sp)); sp+=2; }
710           if (rlist&0x80) { set_reg2(7, get2(sp)); sp+=2; }
711         }
712       } else { // byte op
713         if (code & 0x4000) { // R4l-R7h
714           if (rlist&0x01) { set_reg1(8, get1(sp)); sp+=2; }
715           if (rlist&0x02) { set_reg1(9, get1(sp)); sp+=2; }
716           if (rlist&0x04) { set_reg1(10, get1(sp)); sp+=2; }
717           if (rlist&0x08) { set_reg1(11, get1(sp)); sp+=2; }
718           if (rlist&0x10) { set_reg1(12, get1(sp)); sp+=2; }
719           if (rlist&0x20) { set_reg1(13, get1(sp)); sp+=2; }
720           if (rlist&0x40) { set_reg1(14, get1(sp)); sp+=2; }
721           if (rlist&0x80) { set_reg1(15, get1(sp)); sp+=2; }
722         } else { // R0l-R3h
723           if (rlist&0x01) { set_reg1(0, get1(sp)); sp+=2; }
724           if (rlist&0x02) { set_reg1(1, get1(sp)); sp+=2; }
725           if (rlist&0x04) { set_reg1(2, get1(sp)); sp+=2; }
726           if (rlist&0x08) { set_reg1(3, get1(sp)); sp+=2; }
727           if (rlist&0x10) { set_reg1(4, get1(sp)); sp+=2; }
728           if (rlist&0x20) { set_reg1(5, get1(sp)); sp+=2; }
729           if (rlist&0x40) { set_reg1(6, get1(sp)); sp+=2; }
730           if (rlist&0x80) { set_reg1(7, get1(sp)); sp+=2; }
731         }
732       }
733     }
734     break;
735   }
736   return(resGO);
737 }
738
739 int cl_xa::inst_PUSH(uint code, int operands)
740 {
741   switch(operands) {
742     case DIRECT:
743     {
744       unsigned short sp;
745       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
746
747       sp = get_sp()-2;
748       set_sp(sp);
749       if (code & 0x0800) {  /* word op */
750         store2( sp, get_word_direct(direct_addr));
751       } else {
752         store2( sp, get_byte_direct(direct_addr));
753       }
754     }
755     break;
756
757     case RLIST:
758     {
759       unsigned short sp=get_sp();
760       unsigned char rlist = fetch();
761       if (code & 0x0800) { // word op
762         if (code & 0x4000) { // R15-R8
763           if (rlist&0x80) { sp-=2; store2(sp, reg2(15)); }
764           if (rlist&0x40) { sp-=2; store2(sp, reg2(14)); }
765           if (rlist&0x20) { sp-=2; store2(sp, reg2(13)); }
766           if (rlist&0x10) { sp-=2; store2(sp, reg2(12)); }
767           if (rlist&0x08) { sp-=2; store2(sp, reg2(11)); }
768           if (rlist&0x04) { sp-=2; store2(sp, reg2(10)); }
769           if (rlist&0x02) { sp-=2; store2(sp, reg2(9)); }
770           if (rlist&0x01) { sp-=2; store2(sp, reg2(8)); }
771         } else { // R7-R0
772           if (rlist&0x80) { sp-=2; store2(sp, reg2(7)); }
773           if (rlist&0x40) { sp-=2; store2(sp, reg2(6)); }
774           if (rlist&0x20) { sp-=2; store2(sp, reg2(5)); }
775           if (rlist&0x10) { sp-=2; store2(sp, reg2(4)); }
776           if (rlist&0x08) { sp-=2; store2(sp, reg2(3)); }
777           if (rlist&0x04) { sp-=2; store2(sp, reg2(2)); }
778           if (rlist&0x02) { sp-=2; store2(sp, reg2(1)); }
779           if (rlist&0x01) { sp-=2; store2(sp, reg2(0)); }
780         }
781       } else { // byte op
782         if (code & 0x4000) { // R7h-R4l
783           if (rlist&0x80) { sp-=2; store2(sp, reg1(15)); }
784           if (rlist&0x40) { sp-=2; store2(sp, reg1(14)); }
785           if (rlist&0x20) { sp-=2; store2(sp, reg1(13)); }
786           if (rlist&0x10) { sp-=2; store2(sp, reg1(12)); }
787           if (rlist&0x08) { sp-=2; store2(sp, reg1(11)); }
788           if (rlist&0x04) { sp-=2; store2(sp, reg1(10)); }
789           if (rlist&0x02) { sp-=2; store2(sp, reg1(9)); }
790           if (rlist&0x01) { sp-=2; store2(sp, reg1(8)); }
791         } else { // R3h-R0l
792           if (rlist&0x80) { sp-=2; store2(sp, reg1(7)); }
793           if (rlist&0x40) { sp-=2; store2(sp, reg1(6)); }
794           if (rlist&0x20) { sp-=2; store2(sp, reg1(5)); }
795           if (rlist&0x10) { sp-=2; store2(sp, reg1(4)); }
796           if (rlist&0x08) { sp-=2; store2(sp, reg1(3)); }
797           if (rlist&0x04) { sp-=2; store2(sp, reg1(2)); }
798           if (rlist&0x02) { sp-=2; store2(sp, reg1(1)); }
799           if (rlist&0x01) { sp-=2; store2(sp, reg1(0)); }
800         }
801       }
802       set_sp(sp);
803     }
804     break;
805   }
806   return(resGO);
807 }
808 int cl_xa::inst_RESET(uint code, int operands)
809 {
810   return(resGO);
811 }
812 int cl_xa::inst_RET(uint code, int operands)
813 {
814   unsigned int retaddr;
815   unsigned short sp;
816   bool pageZero=get_scr()&1;
817
818   sp = get_sp();
819   retaddr = get2(sp);
820   if (!pageZero) {
821     retaddr |= get2(sp+2) << 16;
822     set_sp(sp+4);
823   } else {
824     set_sp(sp+2);
825   }
826   PC = retaddr;
827   return(resGO);
828 }
829 int cl_xa::inst_RETI(uint code, int operands)
830 {
831   unsigned int retaddr;
832   unsigned short sp;
833   bool pageZero=get_scr()&1;
834
835   sp = get_sp();
836   set_psw(get2(sp));
837   retaddr = get2(sp+2);
838   if (!pageZero) {
839     retaddr |= get2(sp+4) << 16;
840     set_sp(sp+6);
841   } else {
842     set_sp(sp+4);
843   }
844   PC = retaddr;
845   return(resGO);
846 }
847 int cl_xa::inst_RL(uint code, int operands)
848 {
849   return(resGO);
850 }
851 int cl_xa::inst_RLC(uint code, int operands)
852 {
853   return(resGO);
854 }
855 int cl_xa::inst_RR(uint code, int operands)
856 {
857   return(resGO);
858 }
859 int cl_xa::inst_RRC(uint code, int operands)
860 {
861   return(resGO);
862 }
863 int cl_xa::inst_SETB(uint code, int operands)
864 {
865   unsigned short bitAddr = (code&0x03 << 8) + fetch();
866   set_bit (bitAddr, 1);
867   return(resGO);
868 }
869
870 int cl_xa::inst_SEXT(uint code, int operands)
871 {
872   bool neg=get_psw()&BIT_N;
873   if (code & 0x0800) { // word op
874     set_reg2(RI_F0, neg ? 0xffff : 0);
875   } else {
876     set_reg1(RI_F0, neg ? 0xff : 0);
877   }
878   return(resGO);
879 }
880
881 int cl_xa::inst_SUB(uint code, int operands)
882 {
883 #undef FUNC1
884 #define FUNC1 sub1
885 #undef FUNC2
886 #define FUNC2 sub2
887 #include "inst_gen.cc"
888   return(resGO);
889 }
890
891 int cl_xa::inst_SUBB(uint code, int operands)
892 {
893 #undef FUNC1
894 #define FUNC1 subb1
895 #undef FUNC2
896 #define FUNC2 subb2
897 #include "inst_gen.cc"
898   return(resGO);
899 }
900
901 int cl_xa::inst_TRAP(uint code, int operands)
902 {
903   // steal a few opcodes for simulator only putchar() and exit()
904   // functions.  Used in SDCC regression testing.
905   switch (code & 0x0f) {
906     case 0xe:
907       // implement a simulator putchar() routine
908       //printf("PUTCHAR-----> %xH\n", reg1(0));
909       putchar(reg1(0));
910       fflush(stdout);
911     break;
912
913     case 0xf:
914       ::exit(0);
915     break;
916   }
917   return(resGO);
918 }
919
920 int cl_xa::inst_XCH(uint code, int operands)
921 {
922   return(resGO);
923 }
924 int cl_xa::inst_XOR(uint code, int operands)
925 {
926 #undef FUNC1
927 #define FUNC1 xor1
928 #undef FUNC2
929 #define FUNC2 xor2
930 #include "inst_gen.cc"
931   return(resGO);
932 }
933
934 /* End of xa.src/inst.cc */