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
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   int jmpAddr;
386
387   switch(operands) {
388     case REL16:
389     {
390       jmpAddr = (signed short)fetch2()*2;
391       PC = (PC + jmpAddr) & 0xfffffffe;
392     }
393     break;
394     case IREG:
395       PC &= 0xff0000;
396       PC |= (reg2(RI_07) & 0xfffe);  /* word aligned */
397     break;
398     /* fixme 2 more... */
399   }
400   return(resGO);
401 }
402 int
403 cl_xa::inst_CALL(uint code, int operands)
404 {
405   int jmpaddr;
406   unsigned int sp;
407
408   switch(operands) {
409     case REL16:
410     {
411       jmpaddr = (signed short)fetch2();
412       sp = get_sp() - 4;
413       set_sp(sp);
414       store2(sp, PC);
415       store2(sp+2, 0);  /* segment(not sure about ordering...) */
416       jmpaddr *= 2;
417       PC = (PC + jmpaddr) & 0xfffffffe;
418     }
419     break;
420     case IREG:
421     {
422       sp = get_sp() - 2;
423       set_sp(sp);
424       store2(sp, PC);
425 #if 0 // only in huge model
426       store2(sp+2, ...
427 #endif
428       jmpaddr = reg2(RI_07);
429       jmpaddr *= 2;
430       PC = (PC + jmpaddr) & 0xfffffffe;
431     }
432     break;
433     /* fixme 2 more... */ /* johan: which ones? */
434   }
435   return(resGO);
436 }
437 int
438 cl_xa::inst_RET(uint code, int operands)
439 {
440   unsigned int retaddr;
441   unsigned short sp;
442   sp = get_sp();
443   retaddr = get2(sp);
444 #if 0 // only in huge model
445   retaddr |= get2(sp+2) << 16;
446 #endif
447   set_sp(sp+2);
448   PC = retaddr;
449   return(resGO);
450 }
451 int
452 cl_xa::inst_Bcc(uint code, int operands)
453 {
454   return(resGO);
455 }
456 int
457 cl_xa::inst_JB(uint code, int operands)
458 {
459   short bitAddr=((code&0x3)<<8) + fetch1();
460   short jmpAddr = (fetch1() * 2);
461   if (get_bit(bitAddr)) {
462     PC = (PC+jmpAddr)&0xfffffe;
463   }
464   return(resGO);
465 }
466 int
467 cl_xa::inst_JNB(uint code, int operands)
468 {
469   short bitAddr=((code&0x3)<<8) + fetch1();
470   short jmpAddr = (fetch1() * 2);
471   if (!get_bit(bitAddr)) {
472     PC = (PC+jmpAddr)&0xfffffe;
473   }
474   return(resGO);
475   return(resGO);
476 }
477 int
478 cl_xa::inst_CJNE(uint code, int operands)
479 {
480   switch(operands) {
481     case REG_DIRECT_REL8:
482     {
483        // update C,N,Z
484        if (code & 0x800) {  // word op
485          int result;
486          int src = get_word_direct( ((code & 0x7)<<4) | fetch1());
487          int addr = (fetch1() * 2);
488          int dst = reg2(RI_F0);
489          unsigned char flags;
490          flags = get_psw();
491          flags &= ~BIT_ALL; /* clear these bits */
492          result = dst - src;
493          if (result == 0) flags |= BIT_Z;
494          if (result > 0xffff) flags |= BIT_C;
495          if (dst < src) flags |= BIT_N;
496          set_psw(flags);
497          if (flags & BIT_Z)
498            PC += addr;
499        } else {
500          int result;
501          int src = get_byte_direct( ((code & 0x7)<<4) | fetch1());
502          int addr = (fetch1() * 2);
503          int dst = reg1(RI_F0);
504          unsigned char flags;
505          flags = get_psw();
506          flags &= ~BIT_ALL; /* clear these bits */
507          result = dst - src;
508          if (result == 0) flags |= BIT_Z;
509          if (result > 0xff) flags |= BIT_C;
510          if (dst < src) flags |= BIT_N;
511          set_psw(flags);
512          if (flags & BIT_Z)
513            PC += addr;
514        }
515     }
516     break;
517
518     case DIRECT_REL8:
519     {
520        int daddr = ((code & 0x7) << 8) | fetch();
521        int addr = fetch() * 2;
522
523        if (code & 0x800) {  // word op
524          unsigned short tmp = get_word_direct(daddr)-1;
525          set_word_direct(daddr, tmp);
526          if (tmp != 0)
527            PC += addr;
528        } else {
529          unsigned char tmp = get_word_direct(daddr)-1;
530          set_byte_direct(daddr, tmp);
531          if (tmp != 0)
532            PC += addr;
533        }
534     }
535     break;
536   }
537   return(resGO);
538 }
539 int
540 cl_xa::inst_DJNZ(uint code, int operands)
541 {
542   switch(operands) {
543     case REG_REL8:
544     {
545        int addr = (fetch1() * 2);
546        if (code & 0x800) {  // word op
547          unsigned short tmp = mov2(0, reg2(RI_F0)-1);
548          set_reg2(RI_F0, tmp);
549          if (tmp != 0)
550            PC += addr;
551        } else {
552          unsigned char tmp = mov1(0, reg1(RI_F0)-1);
553          set_reg1(RI_F0, tmp);
554          if (tmp != 0)
555            PC += addr;
556        }
557     }
558     break;
559
560     case DIRECT_REL8:
561     {
562        int daddr = ((code & 0x7) << 8) | fetch();
563        int addr = fetch() * 2;
564
565        if (code & 0x800) {  // word op
566          unsigned short tmp = get_word_direct(daddr)-1;
567          set_word_direct(daddr, tmp);
568          if (tmp != 0)
569            PC += addr;
570        } else {
571          unsigned char tmp = get_word_direct(daddr)-1;
572          set_byte_direct(daddr, tmp);
573          if (tmp != 0)
574            PC += addr;
575        }
576     }
577     break;
578   }
579
580   return(resGO);
581 }
582 int
583 cl_xa::inst_JZ(uint code, int operands)
584 {
585   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
586   short saddr = (fetch1() * 2);
587   if (reg1(8)==0) {
588       PC += saddr;
589   }
590   return(resGO);
591 }
592 int
593 cl_xa::inst_JNZ(uint code, int operands)
594 {
595   short saddr = (fetch1() * 2);
596   /* reg1(8) = R4L, is ACC for MCS51 compatiblility */
597   if (reg1(8)!=0) {
598     PC = (PC + saddr) & 0xfffffe;
599   }
600   return(resGO);
601 }
602 int
603 cl_xa::inst_BKPT(uint code, int operands)
604 {
605   return(resGO);
606 }
607 int
608 cl_xa::inst_TRAP(uint code, int operands)
609 {
610   return(resGO);
611 }
612 int
613 cl_xa::inst_RESET(uint code, int operands)
614 {
615   return(resGO);
616 }
617
618
619 /* End of xa.src/inst.cc */