xa 51, work in progress
[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 int cl_xa::get_reg(int word_flag, unsigned int index)
39 {
40   //if (index < 3) { /* banked */
41   //  if (word_flag)
42   //    return get_word_direct(0x400+index);
43   //  else
44   //    return mem_direct[0x400+index];
45   //} else { /* non-banked */
46     if (word_flag)
47       return get_word_direct(index);
48     else
49       return mem_direct[index];
50   //}
51 }
52
53 bool cl_xa::get_bit(int bit) {
54   short offset=0;
55   if (bit>=0x200) {
56     // in sfr space
57     bit-=0x200;
58     offset=0x400;
59   }
60   return mem_direct[offset + (bit/8)] & (1 << (bit%8));
61 }
62
63 void cl_xa::set_bit(int bit, int value) {
64   short offset=0;
65   if (bit>=0x200) {
66     // in sfr space
67     bit-=0x200;
68     offset=0x400;
69   }
70   if (value) {
71     mem_direct[offset + (bit/8)] |= (1 << (bit%8));
72   } else {
73     mem_direct[offset + (bit/8)] &= ~(1 << (bit%8));
74   }
75 }
76
77 #define RI_F0 ((code >> 4) & 0xf)
78 #define RI_70 ((code >> 4) & 0x7)
79 #define RI_0F (code & 0xf)
80 #define RI_07 (code & 0x7)
81
82 int cl_xa::inst_ADD(uint code, int operands)
83 {
84 #undef FUNC1
85 #define FUNC1 add1
86 #undef FUNC2
87 #define FUNC2 add2
88 #include "inst_gen.cc"
89
90   return(resGO);
91 }
92
93 int cl_xa::inst_ADDC(uint code, int operands)
94 {
95 #undef FUNC1
96 #define FUNC1 addc1
97 #undef FUNC2
98 #define FUNC2 addc2
99 #include "inst_gen.cc"
100
101   return(resGO);
102 }
103
104 int cl_xa::inst_ADDS(uint code, int operands)
105 {
106   return(resGO);
107 }
108
109 int cl_xa::inst_AND(uint code, int operands)
110 {
111 #undef FUNC1
112 #define FUNC1 and1
113 #undef FUNC2
114 #define FUNC2 and2
115 #include "inst_gen.cc"
116   return(resGO);
117 }
118
119 int cl_xa::inst_ANL(uint code, int operands)
120 {
121   return(resGO);
122 }
123
124 int cl_xa::inst_ASL(uint code, int operands)
125 {
126   return(resGO);
127 }
128
129 int cl_xa::inst_ASR(uint code, int operands)
130 {
131   return(resGO);
132 }
133
134 int cl_xa::inst_BCC(uint code, int operands)
135 {
136   return(resGO);
137 }
138
139 int cl_xa::inst_BCS(uint code, int operands)
140 {
141   return(resGO);
142 }
143
144 int cl_xa::inst_BEQ(uint code, int operands)
145 {
146   short jmpAddr = fetch1()*2;
147   if (get_psw() & BIT_Z) {
148     PC=(PC+jmpAddr)&0xfffffffe;
149   }
150   return(resGO);
151 }
152
153 int cl_xa::inst_BG(uint code, int operands)
154 {
155   return(resGO);
156 }
157 int cl_xa::inst_BGE(uint code, int operands)
158 {
159   return(resGO);
160 }
161 int cl_xa::inst_BGT(uint code, int operands)
162 {
163   return(resGO);
164 }
165 int cl_xa::inst_BKPT(uint code, int operands)
166 {
167   return(resGO);
168 }
169 int cl_xa::inst_BL(uint code, int operands)
170 {
171   return(resGO);
172 }
173 int cl_xa::inst_BLE(uint code, int operands)
174 {
175   return(resGO);
176 }
177 int cl_xa::inst_BLT(uint code, int operands)
178 {
179   return(resGO);
180 }
181 int cl_xa::inst_BMI(uint code, int operands)
182 {
183   return(resGO);
184 }
185 int cl_xa::inst_BNE(uint code, int operands)
186 {
187   return(resGO);
188 }
189 int cl_xa::inst_BNV(uint code, int operands)
190 {
191   return(resGO);
192 }
193 int cl_xa::inst_BOV(uint code, int operands)
194 {
195   return(resGO);
196 }
197 int cl_xa::inst_BPL(uint code, int operands)
198 {
199   return(resGO);
200 }
201
202 int cl_xa::inst_BR(uint code, int operands)
203 {
204   short jmpAddr = fetch1()*2;
205   PC=(PC+jmpAddr)&0xfffffffe;
206   return(resGO);
207 }
208
209 int cl_xa::inst_CALL(uint code, int operands)
210 {
211   int jmpaddr;
212   unsigned int sp;
213   bool pageZero=get_scr()&1;
214
215   switch(operands) {
216     case REL16:
217     {
218       jmpaddr = (signed short)fetch2();
219       sp = get_sp() - (pageZero ? 2 : 4);
220       set_sp(sp);
221       store2(sp, PC&0xffff);
222       if (!pageZero) {
223         store2(sp+2, (PC>>16)&0xff);
224       }
225       jmpaddr *= 2;
226       PC = (PC + jmpaddr) & 0xfffffe;
227     }
228     break;
229     case IREG:
230     {
231       sp = get_sp() - (pageZero ? 2 : 4);
232       set_sp(sp);
233       store2(sp, PC&0xffff);
234       if (!pageZero) {
235         store2(sp+2, (PC>>16)&0xff);
236       }
237       jmpaddr = reg2(RI_07);
238       jmpaddr *= 2;
239       PC = (PC + jmpaddr) & 0xfffffe;
240     }
241     break;
242   }
243   return(resGO);
244 }
245
246 int cl_xa::inst_CJNE(uint code, int operands)
247 {
248   switch(operands) {
249     case REG_DIRECT_REL8:
250     {
251        // update C,N,Z
252        if (code & 0x800) {  // word op
253          int result;
254          int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
255          int addr = (fetch1() * 2);
256          int dst = reg2(RI_F0);
257          unsigned char flags;
258          flags = get_psw();
259          flags &= ~BIT_ALL; /* clear these bits */
260          result = dst - src;
261          if (result == 0) flags |= BIT_Z;
262          if (result > 0xffff) flags |= BIT_C;
263          if (dst < src) flags |= BIT_N;
264          set_psw(flags);
265          if (flags & BIT_Z)
266            PC += addr;
267        } else {
268          int result;
269          int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
270          int addr = (fetch1() * 2);
271          int dst = reg1(RI_F0);
272          unsigned char flags;
273          flags = get_psw();
274          flags &= ~BIT_ALL; /* clear these bits */
275          result = dst - src;
276          if (result == 0) flags |= BIT_Z;
277          if (result > 0xff) flags |= BIT_C;
278          if (dst < src) flags |= BIT_N;
279          set_psw(flags);
280          if (flags & BIT_Z)
281            PC += addr;
282        }
283     }
284     break;
285
286     case DIRECT_REL8:
287     {
288        int daddr = ((code & 0x7) << 8) | fetch();
289        int addr = fetch() * 2;
290
291        if (code & 0x800) {  // word op
292          unsigned short tmp = get_word_direct(daddr)-1;
293          set_word_direct(daddr, tmp);
294          if (tmp != 0)
295            PC += addr;
296        } else {
297          unsigned char tmp = get_word_direct(daddr)-1;
298          set_byte_direct(daddr, tmp);
299          if (tmp != 0)
300            PC += addr;
301        }
302     }
303     break;
304   }
305   return(resGO);
306 }
307
308 int cl_xa::inst_CLR(uint code, int operands)
309 {
310   unsigned short bitAddr = (code&0x03 << 8) + fetch();
311   // fixme: implement
312   bitAddr=bitAddr;
313   return(resGO);
314 }
315
316 int cl_xa::inst_CMP(uint code, int operands)
317 {
318 #undef FUNC1
319 #define FUNC1 cmp1
320 #undef FUNC2
321 #define FUNC2 cmp2
322 #include "inst_gen.cc"
323   return(resGO);
324 }
325 int cl_xa::inst_CPL(uint code, int operands)
326 {
327   return(resGO);
328 }
329 int cl_xa::inst_DA(uint code, int operands)
330 {
331   return(resGO);
332 }
333 int cl_xa::inst_DIV(uint code, int operands)
334 {
335   return(resGO);
336 }
337
338 int cl_xa::inst_DJNZ(uint code, int operands)
339 {
340   // update N Z flags.
341   switch(operands) {
342     case REG_REL8:
343     {
344        int addr = ( ((char)fetch1()) * 2);
345        if (code & 0x800) {  // word op
346          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
347          set_reg2(RI_F0, tmp);
348          if (tmp != 0)
349            PC = (PC + addr) & 0xfffffffe;
350        } else {
351          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
352          set_reg1(RI_F0, tmp);
353          if (tmp != 0)
354            PC = (PC + addr) & 0xfffffffe;
355        }
356     }
357     break;
358
359     case DIRECT_REL8:
360     {
361        int daddr = ((code & 0x7) << 8) | fetch();
362        int addr = fetch() * 2;
363
364        if (code & 0x800) {  // word op
365          unsigned short tmp = get_word_direct(daddr)-1;
366          set_word_direct(daddr, tmp);
367          if (tmp != 0)
368            PC += addr;
369        } else {
370          unsigned char tmp = get_word_direct(daddr)-1;
371          set_byte_direct(daddr, tmp);
372          if (tmp != 0)
373            PC += addr;
374        }
375     }
376     break;
377   }
378
379   return(resGO);
380 }
381
382 int cl_xa::inst_FCALL(uint code, int operands)
383 {
384   return(resGO);
385 }
386
387 int cl_xa::inst_FJMP(uint code, int operands)
388 {
389   return(resGO);
390 }
391
392 int cl_xa::inst_JB(uint code, int operands)
393 {
394   short bitAddr=((code&0x3)<<8) + fetch1();
395   short jmpAddr = (fetch1() * 2);
396   if (get_bit(bitAddr)) {
397     PC = (PC+jmpAddr)&0xfffffe;
398   }
399   return(resGO);
400 }
401 int cl_xa::inst_JBC(uint code, int operands)
402 {
403   return(resGO);
404 }
405 int cl_xa::inst_JNB(uint code, int operands)
406 {
407   short bitAddr=((code&0x3)<<8) + fetch1();
408   short jmpAddr = (fetch1() * 2);
409   if (!get_bit(bitAddr)) {
410     PC = (PC+jmpAddr)&0xfffffe;
411   }
412   return(resGO);
413   return(resGO);
414 }
415 int cl_xa::inst_JMP(uint code, int operands)
416 {
417   int jmpAddr;
418
419   switch(operands) {
420     case REL16:
421     {
422       jmpAddr = (signed short)fetch2()*2;
423       PC = (PC + jmpAddr) & 0xfffffffe;
424     }
425     break;
426     case IREG:
427       PC &= 0xff0000;
428       PC |= (reg2(RI_07) & 0xfffe);  /* word aligned */
429     break;
430     /* fixme 2 more... */
431   }
432   return(resGO);
433 }
434 int cl_xa::inst_JNZ(uint code, int operands)
435 {
436   short saddr = (fetch1() * 2);
437   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
438   if (reg1(8)!=0) {
439     PC = (PC + saddr) & 0xfffffe;
440   }
441   return(resGO);
442 }
443 int cl_xa::inst_JZ(uint code, int operands)
444 {
445   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
446   short saddr = (fetch1() * 2);
447   if (reg1(8)==0) {
448       PC += saddr;
449   }
450   return(resGO);
451 }
452 int cl_xa::inst_LEA(uint code, int operands)
453 {
454   return(resGO);
455 }
456 int cl_xa::inst_LSR(uint code, int operands)
457 {
458   return(resGO);
459 }
460 int cl_xa::inst_MOV(uint code, int operands)
461 {
462 #undef FUNC1
463 #define FUNC1 mov1
464 #undef FUNC2
465 #define FUNC2 mov2
466 #include "inst_gen.cc"
467   return(resGO);
468 }
469 int cl_xa::inst_MOVC(uint code, int operands)
470 {
471   switch (operands) {
472     case REG_IREGINC:
473     {
474       short srcreg = reg2(RI_07);
475       if (code & 0x0800) {  /* word op */
476         set_reg2( RI_F0,
477                   mov2( reg2(RI_F0),
478                         getcode2(srcreg)
479                       )
480                 );
481       } else {
482         set_reg1( RI_F0,
483                   mov1( reg1(RI_F0),
484                         getcode1(srcreg)
485                       )
486                 );
487       }
488       if (operands == REG_IREGINC) {
489         set_reg2(RI_07,  srcreg+1);
490       }
491     }
492     break;
493     // fixme, 2 more
494   }
495   return(resGO);
496 }
497 int cl_xa::inst_MOVS(uint code, int operands)
498 {
499   return(resGO);
500 }
501 int cl_xa::inst_MOVX(uint code, int operands)
502 {
503   return(resGO);
504 }
505 int cl_xa::inst_MUL(uint code, int operands)
506 {
507   return(resGO);
508 }
509 int cl_xa::inst_NEG(uint code, int operands)
510 {
511   return(resGO);
512 }
513 int cl_xa::inst_NOP(uint code, int operands)
514 {
515   return(resGO);
516 }
517 int cl_xa::inst_NORM(uint code, int operands)
518 {
519   return(resGO);
520 }
521 int cl_xa::inst_OR(uint code, int operands)
522 {
523 #undef FUNC1
524 #define FUNC1 or1
525 #undef FUNC2
526 #define FUNC2 or2
527 #include "inst_gen.cc"
528   return(resGO);
529 }
530
531 int cl_xa::inst_ORL(uint code, int operands)
532 {
533   return(resGO);
534 }
535
536 int cl_xa::inst_POP(uint code, int operands)
537 {
538   switch(operands) {
539     case DIRECT:
540     {
541       unsigned short sp;
542       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
543
544       sp = get_sp();
545       if (code & 0x0800) {  /* word op */
546         set_word_direct(direct_addr, get2(sp) );
547       } else {
548         set_byte_direct(direct_addr, get2(sp) & 0xff );
549       }
550       set_sp(sp+2);
551     }
552     break;
553
554     case RLIST:
555       // fixme: implement
556       unsigned char rlist = fetch();
557       rlist = rlist; //shutup compiler
558     break;
559   }
560   return(resGO);
561 }
562
563 int cl_xa::inst_PUSH(uint code, int operands)
564 {
565   switch(operands) {
566     case DIRECT:
567     {
568       unsigned short sp;
569       unsigned short direct_addr = ((operands & 0x7) << 8) | fetch();
570
571       sp = get_sp()-2;
572       set_sp(sp);
573       if (code & 0x0800) {  /* word op */
574         store2( sp, get_word_direct(direct_addr));
575       } else {
576         store2( sp, get_byte_direct(direct_addr));
577       }
578     }
579     break;
580
581     case RLIST:
582       // fixme: implement
583       unsigned char rlist = fetch();
584       rlist = rlist; //shutup compiler
585     break;
586   }
587   
588   return(resGO);
589 }
590 int cl_xa::inst_RESET(uint code, int operands)
591 {
592   return(resGO);
593 }
594 int cl_xa::inst_RET(uint code, int operands)
595 {
596   unsigned int retaddr;
597   unsigned short sp;
598   bool pageZero=get_scr()&1;
599
600   sp = get_sp();
601   retaddr = get2(sp);
602   if (!pageZero) {
603     retaddr |= get2(sp+2) << 16;
604     set_sp(sp+4);
605   } else {
606     set_sp(sp+2);
607   }
608   PC = retaddr;
609   return(resGO);
610 }
611 int cl_xa::inst_RETI(uint code, int operands)
612 {
613   unsigned int retaddr;
614   unsigned short sp;
615   bool pageZero=get_scr()&1;
616
617   sp = get_sp();
618   set_psw(get2(sp));
619   retaddr = get2(sp+2);
620   if (!pageZero) {
621     retaddr |= get2(sp+4) << 16;
622     set_sp(sp+6);
623   } else {
624     set_sp(sp+4);
625   }
626   PC = retaddr;
627   return(resGO);
628 }
629 int cl_xa::inst_RL(uint code, int operands)
630 {
631   return(resGO);
632 }
633 int cl_xa::inst_RLC(uint code, int operands)
634 {
635   return(resGO);
636 }
637 int cl_xa::inst_RR(uint code, int operands)
638 {
639   return(resGO);
640 }
641 int cl_xa::inst_RRC(uint code, int operands)
642 {
643   return(resGO);
644 }
645 int cl_xa::inst_SETB(uint code, int operands)
646 {
647   unsigned short bitAddr = (code&0x03 << 8) + fetch();
648   // fixme: implement
649   bitAddr=bitAddr;
650   return(resGO);
651 }
652
653 int cl_xa::inst_SEXT(uint code, int operands)
654 {
655   return(resGO);
656 }
657
658 int cl_xa::inst_SUB(uint code, int operands)
659 {
660 #undef FUNC1
661 #define FUNC1 sub1
662 #undef FUNC2
663 #define FUNC2 sub2
664 #include "inst_gen.cc"
665   return(resGO);
666 }
667
668 int cl_xa::inst_SUBB(uint code, int operands)
669 {
670 #undef FUNC1
671 #define FUNC1 subb1
672 #undef FUNC2
673 #define FUNC2 subb2
674 #include "inst_gen.cc"
675   return(resGO);
676 }
677 int cl_xa::inst_TRAP(uint code, int operands)
678 {
679   return(resGO);
680 }
681 int cl_xa::inst_XCH(uint code, int operands)
682 {
683   return(resGO);
684 }
685 int cl_xa::inst_XOR(uint code, int operands)
686 {
687 #undef FUNC1
688 #define FUNC1 xor1
689 #undef FUNC2
690 #define FUNC2 xor2
691 #include "inst_gen.cc"
692   return(resGO);
693 }
694
695 /* End of xa.src/inst.cc */