* src/hc08/gen.c (genPlusIncr, genUminus, genMinusDec, genCmp,
[fw/sdcc] / sim / ucsim / hc08.src / inst.cc
1 /*
2  * Simulator of microcontrollers (inst.cc)
3  *
4  * hc08 code base from Erik Petrich  epetrich@users.sourceforge.net
5  *
6  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
7  * 
8  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
9  *
10  */
11
12 /* This file is part of microcontroller simulator: ucsim.
13
14 UCSIM is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
18
19 UCSIM is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with UCSIM; see the file COPYING.  If not, write to the Free
26 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 02111-1307, USA. */
28 /*@1@*/
29
30 #include "ddconfig.h"
31 #include "stdio.h"
32 #include <stdlib.h>
33
34 // local
35 #include "hc08cl.h"
36 #include "regshc08.h"
37 #include "hc08mac.h"
38
39
40
41 void
42 cl_hc08::incx(void)
43 {
44   int hx = (regs.H << 8) | (regs.X);
45   hx++;
46   regs.H = (hx >> 8) & 0xff;
47   regs.X = hx & 0xff;
48 }
49
50 int
51 cl_hc08::fetchea(t_mem code, bool prefix)
52 {
53   switch ((code >> 4) & 0x0f) {
54     case 0x0: 
55     case 0x1:
56     case 0x3:
57     case 0xb:
58       return fetch(); // Direct
59     case 0x7:
60     case 0xf:
61       return (regs.H << 8) | regs.X;  // IX
62     case 0x6:
63     case 0xe:
64       if (!prefix)
65         return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1
66       else
67         return ((unsigned char)fetch())+regs.SP; // SP1
68     case 0xd:
69       if (!prefix)
70         return fetch2()+((regs.H << 8) | regs.X); // IX2
71       else
72         return fetch2()+regs.SP; // SP2
73     case 0xc:
74       return fetch2();
75     default:
76       return(resHALT);
77   }
78 }
79
80
81 int
82 cl_hc08::inst_nop(t_mem code, bool prefix)
83 {
84   return(resGO);
85 }
86
87
88 int
89 cl_hc08::inst_transfer(t_mem code, bool prefix)
90 {
91   int hx;
92   
93   switch (code) {
94     case 0x84: // TAP
95       regs.P = regs.A | 0x60;
96       break;
97     case 0x85: // TPA
98       regs.A = regs.P | 0x60;
99       break;
100     case 0x97: // TAX
101       regs.X = regs.A;
102       break;
103     case 0x9f: // TXA
104       regs.A = regs.X;
105       break;
106     case 0x94: // TXS
107       hx = (regs.H << 8) | regs.X;
108       regs.SP = (hx - 1) & 0xffff;
109       break;
110     case 0x95: // TSX
111       hx = regs.SP +1;
112       regs.H = (hx >> 8) & 0xff;
113       regs.X = hx & 0xff;
114       break;
115     default:
116       return(resHALT);
117   }
118   return(resGO);
119 }
120
121
122 int
123 cl_hc08::inst_setclearflags(t_mem code, bool prefix)
124 {
125   switch (code) {
126     case 0x98:
127       regs.P &= ~BIT_C;
128       break;
129     case 0x99:
130       regs.P |= BIT_C;
131       break;
132     case 0x9a:
133       regs.P &= ~BIT_I;
134       break;
135     case 0x9b:
136       regs.P |= BIT_I;
137       break;
138     default:
139       return(resHALT);
140   }
141   return(resGO);
142 }
143
144
145 int
146 cl_hc08::inst_rsp(t_mem code, bool prefix)
147 {
148   regs.SP = 0x00ff;
149   return(resGO);
150 }
151
152
153 int
154 cl_hc08::inst_nsa(t_mem code, bool prefix)
155 {
156   regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4);
157   return(resGO);
158 }
159
160
161
162 int
163 cl_hc08::inst_lda(t_mem code, bool prefix)
164 {
165   regs.A = OPERAND(code, prefix);
166   FLAG_CLEAR(BIT_V);
167   FLAG_NZ(regs.A);
168   return(resGO);
169 }
170
171 int
172 cl_hc08::inst_ldx(t_mem code, bool prefix)
173 {
174   regs.X = OPERAND(code, prefix);
175   FLAG_CLEAR(BIT_V);
176   FLAG_NZ(regs.X);
177   return(resGO);
178 }
179
180 int
181 cl_hc08::inst_sta(t_mem code, bool prefix)
182 {
183   int ea = fetchea(code, prefix);
184
185   //fprintf (stdout, "ea = 0x%04x\n", ea);
186     
187   FLAG_CLEAR(BIT_V);
188   FLAG_NZ(regs.A);
189   store1(ea, regs.A);
190   return(resGO);
191 }
192
193 int
194 cl_hc08::inst_stx(t_mem code, bool prefix)
195 {
196   int ea = fetchea(code, prefix);
197
198   FLAG_CLEAR(BIT_V);
199   FLAG_NZ(regs.X);
200   store1(ea, regs.X);
201   return(resGO);
202 }
203
204 int
205 cl_hc08::inst_add(t_mem code, bool prefix)
206 {
207   int result, operand1, operand2;
208
209   operand1 = regs.A;
210   operand2 = OPERAND(code, prefix);
211   result = operand1 + operand2;
212   FLAG_NZ (result);
213   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
214   FLAG_ASSIGN (BIT_C, 0x100 & result);
215   FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
216   
217   regs.A = result & 0xff;
218   return(resGO);
219 }
220
221 int
222 cl_hc08::inst_adc(t_mem code, bool prefix)
223 {
224   int result, operand1, operand2;
225   int carryin = (regs.P & BIT_C)!=0;
226
227   operand1 = regs.A;
228   operand2 = OPERAND(code, prefix);
229   result = operand1 + operand2 + carryin;
230   FLAG_NZ (result);
231   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
232   FLAG_ASSIGN (BIT_C, 0x100 & result);
233   FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result));
234
235   regs.A = result & 0xff;
236   return(resGO);
237 }
238
239 int
240 cl_hc08::inst_sub(t_mem code, bool prefix)
241 {
242   int result, operand1, operand2;
243
244   operand1 = regs.A;
245   operand2 = OPERAND(code, prefix);
246   result = operand1 - operand2;
247   FLAG_NZ (result);
248   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
249   FLAG_ASSIGN (BIT_C, 0x100 & result);
250
251   regs.A = result & 0xff;
252   return(resGO);
253 }
254
255 int
256 cl_hc08::inst_sbc(t_mem code, bool prefix)
257 {
258   int result, operand1, operand2;
259   int carryin = (regs.P & BIT_C)!=0;
260
261   operand1 = regs.A;
262   operand2 = OPERAND(code, prefix);
263   result = operand1 - operand2 - carryin;
264   FLAG_NZ (result);
265   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
266   FLAG_ASSIGN (BIT_C, 0x100 & result);
267
268   regs.A = result & 0xff;
269   return(resGO);
270 }
271
272 int
273 cl_hc08::inst_cmp(t_mem code, bool prefix)
274 {
275   int result, operand1, operand2;
276
277   operand1 = regs.A;
278   operand2 = OPERAND(code, prefix);
279   result = operand1 - operand2;
280   FLAG_NZ (result);
281   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
282   FLAG_ASSIGN (BIT_C, 0x100 & result);
283
284   return(resGO);
285 }
286
287 int
288 cl_hc08::inst_cpx(t_mem code, bool prefix)
289 {
290   int result, operand1, operand2;
291
292   operand1 = regs.X;
293   operand2 = OPERAND(code, prefix);
294   result = operand1 - operand2;
295   FLAG_NZ (result);
296   FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
297   FLAG_ASSIGN (BIT_C, 0x100 & result);
298
299   return(resGO);
300 }
301
302 int
303 cl_hc08::inst_jmp(t_mem code, bool prefix)
304 {
305   PC = fetchea(code, prefix);
306
307   return(resGO);
308 }
309
310 int
311 cl_hc08::inst_jsr(t_mem code, bool prefix)
312 {
313   int newPC = fetchea(code, prefix);
314   
315   push2(PC);
316   PC = newPC;
317
318   return(resGO);
319 }
320
321 int
322 cl_hc08::inst_bsr(t_mem code, bool prefix)
323 {
324   signed char ofs = fetch();
325   
326   push2(PC);
327   PC += ofs;
328
329   return(resGO);
330 }
331
332 int
333 cl_hc08::inst_ais(t_mem code, bool prefix)
334 {
335   regs.SP = regs.SP + (signed char)fetch();
336   return(resGO);
337 }
338
339 int
340 cl_hc08::inst_aix(t_mem code, bool prefix)
341 {
342   int hx = (regs.H << 8) | (regs.X);
343   hx += (signed char)fetch();
344   regs.H = (hx >> 8) & 0xff;
345   regs.X = hx & 0xff;
346   return(resGO);
347 }
348
349 int
350 cl_hc08::inst_and(t_mem code, bool prefix)
351 {
352   regs.A = regs.A & OPERAND(code, prefix);
353   FLAG_CLEAR(BIT_V);
354   FLAG_NZ(regs.A);
355   return(resGO);
356 }
357
358 int
359 cl_hc08::inst_bit(t_mem code, bool prefix)
360 {
361   uchar operand = regs.A & OPERAND(code, prefix);
362   FLAG_CLEAR(BIT_V);
363   FLAG_NZ(operand);
364   return(resGO);
365 }
366
367 int
368 cl_hc08::inst_ora(t_mem code, bool prefix)
369 {
370   regs.A = regs.A | OPERAND(code, prefix);
371   FLAG_CLEAR(BIT_V);
372   FLAG_NZ(regs.A);
373   return(resGO);
374 }
375
376 int
377 cl_hc08::inst_eor(t_mem code, bool prefix)
378 {
379   regs.A = regs.A ^ OPERAND(code, prefix);
380   FLAG_CLEAR(BIT_V);
381   FLAG_NZ(regs.A);
382   return(resGO);
383 }
384
385 int
386 cl_hc08::inst_asr(t_mem code, bool prefix)
387 {
388   int ea = 0xffff;
389   uchar operand;
390   
391   if ((code & 0xf0) == 0x40)
392     operand = regs.A;
393   else if ((code & 0xf0) == 0x50)
394     operand = regs.X;
395   else {
396     ea = fetchea(code,prefix);
397     operand = get1(ea);
398   }
399
400   FLAG_ASSIGN (BIT_C, operand & 1);
401   operand = (operand >> 1) | (operand & 0x80);
402   FLAG_NZ (operand);
403   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
404
405   if ((code & 0xf0) == 0x40)
406     regs.A = operand;
407   else if ((code & 0xf0) == 0x50)
408     regs.X = operand;
409   else {
410     store1(ea, operand);
411   }
412
413   return(resGO);
414 }
415
416
417 int
418 cl_hc08::inst_lsr(t_mem code, bool prefix)
419 {
420   int ea = 0xffff;
421   uchar operand;
422   
423   if ((code & 0xf0) == 0x40)
424     operand = regs.A;
425   else if ((code & 0xf0) == 0x50)
426     operand = regs.X;
427   else {
428     ea = fetchea(code,prefix);
429     operand = get1(ea);
430   }
431
432   FLAG_ASSIGN (BIT_C, operand & 1);
433   operand = (operand >> 1) & 0x7f;
434   FLAG_NZ (operand);
435   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
436
437   if ((code & 0xf0) == 0x40)
438     regs.A = operand;
439   else if ((code & 0xf0) == 0x50)
440     regs.X = operand;
441   else {
442     store1(ea, operand);
443   }
444   return(resGO);
445 }
446
447
448 int
449 cl_hc08::inst_lsl(t_mem code, bool prefix)
450 {
451   int ea = 0xffff;
452   uchar operand;
453   
454   if ((code & 0xf0) == 0x40)
455     operand = regs.A;
456   else if ((code & 0xf0) == 0x50)
457     operand = regs.X;
458   else {
459     ea = fetchea(code,prefix);
460     operand = get1(ea);
461   }
462
463   FLAG_ASSIGN (BIT_C, operand & 0x80);
464   operand = (operand << 1);
465   FLAG_NZ (operand);
466   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
467
468   if ((code & 0xf0) == 0x40)
469     regs.A = operand;
470   else if ((code & 0xf0) == 0x50)
471     regs.X = operand;
472   else {
473     store1(ea, operand);
474   }
475   return(resGO);
476 }
477
478
479 int
480 cl_hc08::inst_rol(t_mem code, bool prefix)
481 {
482   uchar c = (regs.P & BIT_C)!=0;
483   int ea = 0xffff;
484   uchar operand;
485   
486   if ((code & 0xf0) == 0x40)
487     operand = regs.A;
488   else if ((code & 0xf0) == 0x50)
489     operand = regs.X;
490   else {
491     ea = fetchea(code,prefix);
492     operand = get1(ea);
493   }
494
495   FLAG_ASSIGN (BIT_C, operand & 0x80);
496   operand = (operand << 1) | c;
497   FLAG_NZ (operand);
498   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
499
500   if ((code & 0xf0) == 0x40)
501     regs.A = operand;
502   else if ((code & 0xf0) == 0x50)
503     regs.X = operand;
504   else {
505     store1(ea, operand);
506   }
507   return(resGO);
508 }
509
510
511 int
512 cl_hc08::inst_ror(t_mem code, bool prefix)
513 {
514   uchar c = (regs.P & BIT_C)!=0;
515   int ea = 0xffff;
516   uchar operand;
517   
518   if ((code & 0xf0) == 0x40)
519     operand = regs.A;
520   else if ((code & 0xf0) == 0x50)
521     operand = regs.X;
522   else {
523     ea = fetchea(code,prefix);
524     operand = get1(ea);
525   }
526
527   FLAG_ASSIGN (BIT_C, operand & 1);
528   operand = (operand >> 1) | (c << 7);
529   FLAG_NZ (operand);
530   FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
531
532   if ((code & 0xf0) == 0x40)
533     regs.A = operand;
534   else if ((code & 0xf0) == 0x50)
535     regs.X = operand;
536   else {
537     store1(ea, operand);
538   }
539   return(resGO);
540 }
541
542
543 int
544 cl_hc08::inst_inc(t_mem code, bool prefix)
545 {
546   int ea = 0xffff;
547   uchar operand;
548   
549   if ((code & 0xf0) == 0x40)
550     operand = regs.A;
551   else if ((code & 0xf0) == 0x50)
552     operand = regs.X;
553   else {
554     ea = fetchea(code,prefix);
555     operand = get1(ea);
556   }
557
558   operand++;
559   FLAG_NZ (operand);
560   FLAG_ASSIGN (BIT_V, operand == 0x80);
561
562   if ((code & 0xf0) == 0x40)
563     regs.A = operand;
564   else if ((code & 0xf0) == 0x50)
565     regs.X = operand;
566   else {
567     store1(ea, operand);
568   }
569   return(resGO);
570 }
571
572
573 int
574 cl_hc08::inst_dec(t_mem code, bool prefix)
575 {
576   int ea = 0xffff;
577   uchar operand;
578   
579   if ((code & 0xf0) == 0x40)
580     operand = regs.A;
581   else if ((code & 0xf0) == 0x50)
582     operand = regs.X;
583   else {
584     ea = fetchea(code,prefix);
585     operand = get1(ea);
586   }
587
588   operand--;
589   FLAG_NZ (operand);
590   FLAG_ASSIGN (BIT_V, operand == 0x7f);
591
592   if ((code & 0xf0) == 0x40)
593     regs.A = operand;
594   else if ((code & 0xf0) == 0x50)
595     regs.X = operand;
596   else {
597     store1(ea, operand);
598   }
599   return(resGO);
600 }
601
602 int
603 cl_hc08::inst_dbnz(t_mem code, bool prefix)
604 {
605   int ea = 0xffff;
606   uchar operand;
607   signed char ofs;
608   
609   if ((code & 0xf0) == 0x40)
610     operand = regs.A;
611   else if ((code & 0xf0) == 0x50)
612     operand = regs.X;
613   else {
614     ea = fetchea(code,prefix);
615     operand = get1(ea);
616   }
617
618   operand--;
619   FLAG_NZ (operand);
620   FLAG_ASSIGN (BIT_V, operand == 0x7f);
621
622   if ((code & 0xf0) == 0x40)
623     regs.A = operand;
624   else if ((code & 0xf0) == 0x50)
625     regs.X = operand;
626   else {
627     store1(ea, operand);
628   }
629
630   ofs = fetch();
631   if (operand)
632     PC += ofs;
633
634   return(resGO);
635 }
636
637
638 int
639 cl_hc08::inst_tst(t_mem code, bool prefix)
640 {
641   int ea = 0xffff;
642   uchar operand;
643   
644   if ((code & 0xf0) == 0x40)
645     operand = regs.A;
646   else if ((code & 0xf0) == 0x50)
647     operand = regs.X;
648   else {
649     ea = fetchea(code,prefix);
650     operand = get1(ea);
651   }
652
653   FLAG_NZ (operand);
654   FLAG_CLEAR (BIT_V);
655
656   return(resGO);
657 }
658
659
660 int
661 cl_hc08::inst_clr(t_mem code, bool prefix)
662 {
663   int ea = 0xffff;
664   uchar operand;
665   
666   operand = 0;
667   FLAG_CLEAR (BIT_V);
668   FLAG_CLEAR (BIT_N);
669   FLAG_SET (BIT_Z);
670
671   if ((code & 0xf0) == 0x40)
672     regs.A = operand;
673   else if ((code & 0xf0) == 0x50)
674     regs.X = operand;
675   else {
676     ea = fetchea(code,prefix);
677     store1(ea, operand);
678   }
679   return(resGO);
680 }
681
682
683 int
684 cl_hc08::inst_clrh(t_mem code, bool prefix)
685 {
686   FLAG_CLEAR (BIT_V);
687   FLAG_CLEAR (BIT_N);
688   FLAG_SET (BIT_Z);
689   regs.H = 0;
690   return(resGO);
691 }
692
693
694 int
695 cl_hc08::inst_com(t_mem code, bool prefix)
696 {
697   int ea = 0xffff;
698   uchar operand;
699   
700   if ((code & 0xf0) == 0x40)
701     operand = regs.A;
702   else if ((code & 0xf0) == 0x50)
703     operand = regs.X;
704   else {
705     ea = fetchea(code,prefix);
706     operand = get1(ea);
707   }
708
709   operand = ~operand;
710   FLAG_SET (BIT_C);
711   FLAG_NZ (operand);
712   FLAG_CLEAR (BIT_V);
713
714   if ((code & 0xf0) == 0x40)
715     regs.A = operand;
716   else if ((code & 0xf0) == 0x50)
717     regs.X = operand;
718   else {
719     store1(ea, operand);
720   }
721   return(resGO);
722 }
723
724
725 int
726 cl_hc08::inst_neg(t_mem code, bool prefix)
727 {
728   int ea = 0xffff;
729   uchar operand;
730   
731   if ((code & 0xf0) == 0x40)
732     operand = regs.A;
733   else if ((code & 0xf0) == 0x50)
734     operand = regs.X;
735   else {
736     ea = fetchea(code,prefix);
737     operand = get1(ea);
738   }
739
740   FLAG_ASSIGN (BIT_V, operand==0x80);
741   FLAG_ASSIGN (BIT_C, operand!=0x00);
742   operand = -operand;
743   FLAG_NZ (operand);
744
745   if ((code & 0xf0) == 0x40)
746     regs.A = operand;
747   else if ((code & 0xf0) == 0x50)
748     regs.X = operand;
749   else {
750     store1(ea, operand);
751   }
752   return(resGO);
753 }
754
755
756
757 int
758 cl_hc08::inst_pushpull(t_mem code, bool prefix)
759 {
760   switch (code) {
761     case 0x86:
762       pop1(regs.A);
763       break;
764     case 0x87:
765       push1(regs.A);
766       break;
767     case 0x88:
768       pop1(regs.X);
769       break;
770     case 0x89:
771       push1(regs.X);
772       break;
773     case 0x8a:
774       pop1(regs.H);
775       break;
776     case 0x8b:
777       push1(regs.H);
778       break;
779     default:
780       return(resHALT);
781   }
782   return(resGO);
783 }
784
785
786
787
788 int
789 cl_hc08::inst_stop(t_mem code, bool prefix)
790 {
791   FLAG_CLEAR (BIT_I);
792   return(resGO);
793 }
794
795
796 int
797 cl_hc08::inst_wait(t_mem code, bool prefix)
798 {
799   FLAG_CLEAR (BIT_I);
800   return(resGO);
801 }
802
803
804 int
805 cl_hc08::inst_daa(t_mem code, bool prefix)
806 {
807   uchar lsn, msn;
808
809   lsn = regs.A & 0xf;
810   msn = (regs.A >> 4) & 0xf;
811   if (regs.P & BIT_H) {
812     lsn += 16;
813     msn = (msn-1) & 0xf;
814   }
815   if (regs.P & BIT_C)
816     msn += 16;
817
818   FLAG_CLEAR (BIT_C);
819   while (lsn>9) {
820     lsn -= 10;
821     msn++;
822   }
823   if (msn>9) {
824     msn = msn % 10;
825     FLAG_SET (BIT_C);
826   }
827
828   return(resGO);
829 }
830
831 int
832 cl_hc08::inst_mul(t_mem code, bool prefix)
833 {
834   int result = regs.A * regs.X;
835   regs.A = result & 0xff;
836   regs.X = (result >> 8) & 0xff;
837   FLAG_CLEAR (BIT_C);
838   FLAG_CLEAR (BIT_H);
839   return(resGO);
840 }
841
842 int
843 cl_hc08::inst_div(t_mem code, bool prefix)
844 {
845   unsigned int dividend = (regs.H << 8) | regs.A;
846   unsigned int quotient;
847
848   if (regs.X) {
849     quotient = dividend / (unsigned int)regs.X;
850     if (quotient<=0xff) {
851       regs.A = quotient;
852       regs.H = dividend % regs.X;
853       FLAG_CLEAR (BIT_C);
854       FLAG_ASSIGN (BIT_Z, quotient==0);
855     }
856     else
857       FLAG_SET (BIT_C);  // overflow
858   } else
859     FLAG_SET (BIT_C);    // division by zero
860
861   return(resGO);
862 }
863
864
865 int
866 cl_hc08::inst_condbranch(t_mem code, bool prefix)
867 {
868   bool taken;
869   signed char ofs;
870   
871   if ((code & 0xf0)==0x20) {
872     switch ((code>>1) & 7) {
873       case 0: // BRA
874         taken = 1;
875         break;
876       case 1: // BHI
877         taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
878         break;
879       case 2: // BCC
880         taken = !(regs.P & BIT_C);
881         break;
882       case 3: // BNE
883         taken = !(regs.P & BIT_Z);
884         break;
885       case 4: // BHCC
886         taken = !(regs.P & BIT_H);
887         break;
888       case 5: // BPL
889         taken = !(regs.P & BIT_N);
890         break;
891       case 6: // BMC
892         taken = !(regs.P & BIT_I);
893         break;
894       case 7: // BIL
895         taken = 0; // TODO: should read simulated IRQ# pin
896       default:
897         return(resHALT);
898     } 
899   }
900   else if ((code & 0xf0)==0x90) {
901     switch ((code>>1) & 7) {
902       case 0: // BGE
903         taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
904         break;
905       case 1: // BLT
906         taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
907                 || (regs.P & BIT_Z);
908         break;
909       default:
910         return(resHALT);
911     }
912   }
913   else
914     return(resHALT);
915   
916   if (code & 1)
917     taken = ! taken;
918   
919   ofs = fetch();
920   if (taken)
921     PC += ofs;
922
923   return(resGO);
924 }
925
926 int
927 cl_hc08::inst_bitsetclear(t_mem code, bool prefix)
928 {
929   uchar bit = (code >> 1) & 7;
930   int ea = fetchea(code, prefix);
931   uchar operand = get1(ea);
932
933   if (code & 1)
934     operand &= ~(1 << bit);
935   else
936     operand |= (1 << bit);
937   store1(ea, operand);
938   return(resGO);
939 }
940
941 int
942 cl_hc08::inst_bittestsetclear(t_mem code, bool prefix)
943 {
944   uchar bit = (code >> 1) & 7;
945   int ea = fetchea(code, prefix);
946   uchar operand = get1(ea);
947   signed char ofs;
948   bool taken;
949   
950   if (code & 1)
951     taken = operand & (1 << bit);
952   else
953     taken = !(operand & (1 << bit));
954
955   ofs = fetch();
956   if (taken)
957     PC += ofs;
958
959   FLAG_ASSIGN (BIT_C, operand & (1 << bit));
960   return(resGO);
961 }
962
963 int
964 cl_hc08::inst_cbeq(t_mem code, bool prefix)
965 {
966   int ea;
967   uchar operand1, operand2;
968   signed char ofs;
969     
970   if ((code & 0xf0) == 0x40) {
971     operand1 = regs.A;
972     operand2 = fetch();
973   }
974   else if ((code & 0xf0) == 0x50) {
975     operand1 = regs.X;
976     operand2 = fetch();
977   }
978   else {
979     ea = fetchea(code,prefix);
980     operand1 = get1(ea);
981     operand2 = regs.A;
982   }
983
984   ofs = fetch();
985   if (operand1==operand2)
986     PC += ofs;  
987
988   if (code==0x71)
989     incx();
990     
991   return(resGO);
992 }
993
994 int
995 cl_hc08::inst_rti(t_mem code, bool prefix)
996 {
997   pop1(regs.P);
998   regs.P |= 0x60;
999   pop1(regs.A);
1000   pop1(regs.X);
1001   pop2(PC);
1002   
1003   return(resGO);
1004 }
1005
1006 int
1007 cl_hc08::inst_rts(t_mem code, bool prefix)
1008 {
1009   pop2(PC);
1010   
1011   return(resGO);
1012 }
1013
1014
1015 int
1016 cl_hc08::inst_mov(t_mem code, bool prefix)
1017 {
1018   int ea;
1019   uchar operand;
1020   bool aix;
1021   int hx = (regs.H << 8) | (regs.X);
1022   
1023   switch (code) {
1024     case 0x4e:  //mov opr8a,opr8a
1025       operand = get1(fetch());
1026       ea = fetch();
1027       aix = 0;
1028       break;
1029     case 0x5e:  //mov opr8a,x+
1030       operand = get1(fetch());
1031       ea = hx;
1032       aix = 1;
1033       break;
1034     case 0x6e:  //mov #opr8i,opr8a
1035       operand = fetch();
1036       ea = fetch();
1037       aix = 0;
1038       break;
1039     case 0x7e:  //mov x+,opr8a
1040       operand = get1(hx);
1041       ea = fetch();
1042       aix = 1;
1043       break;
1044     default:
1045       return(resHALT);
1046   }
1047   
1048   store1(ea, operand);
1049   if (aix)
1050     incx();
1051
1052   FLAG_NZ(operand);
1053   FLAG_CLEAR(BIT_V);
1054     
1055   return(resGO);
1056 }
1057
1058
1059 int
1060 cl_hc08::inst_sthx(t_mem code, bool prefix)
1061 {
1062   int ea = fetch1();
1063   
1064   store1(ea, regs.H);
1065   store1((ea+1) & 0xffff, regs.X);
1066
1067   FLAG_CLEAR(BIT_V);
1068   FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1069   FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1070   return(resGO);
1071 }
1072
1073 int
1074 cl_hc08::inst_ldhx(t_mem code, bool prefix)
1075 {
1076   int ea;
1077   
1078   if (code == 0x45) {
1079     regs.H = fetch();
1080     regs.X = fetch();
1081   }
1082   else if (code == 0x55) {
1083     ea = fetch();
1084     regs.H = get1(ea);
1085     regs.X = get1(ea+1);
1086   }
1087   else
1088     return(resHALT);
1089   
1090   FLAG_CLEAR(BIT_V);
1091   FLAG_ASSIGN(BIT_N, regs.H & 0x80);
1092   FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
1093   return(resGO);
1094 }
1095
1096
1097 int
1098 cl_hc08::inst_cphx(t_mem code, bool prefix)
1099 {
1100   int ea;
1101   int hx;
1102   int operand;
1103   int result;
1104   
1105   if (code == 0x65) {
1106     operand = fetch2();
1107   }
1108   else if (code == 0x75) {
1109     ea = fetch();
1110     operand = (get1(ea) << 8) | get1(ea+1);
1111   }
1112   else
1113     return(resHALT);
1114
1115   hx = (regs.H << 8) | regs.X;
1116   result = hx-operand;
1117
1118   FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1)));
1119   FLAG_ASSIGN (BIT_C, 0x10000 & result);
1120   FLAG_ASSIGN(BIT_N, result & 0x8000);
1121   FLAG_ASSIGN(BIT_Z, !(result & 0xffff));
1122                               
1123   return(resGO);
1124 }
1125
1126 int
1127 cl_hc08::inst_swi(t_mem code, bool prefix)
1128 {
1129   push2(PC);
1130   push1(regs.X);
1131   push1(regs.A);
1132   push1(regs.P);
1133   FLAG_CLEAR(BIT_I);
1134   
1135   PC = get2(0xfffc);
1136
1137   return(resGO);
1138 }
1139
1140
1141 /* End of hc08.src/inst.cc */