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