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