2 * Simulator of microcontrollers (inst.cc)
4 * hc08 code base from Erik Petrich epetrich@users.sourceforge.net
6 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
8 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
12 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
44 int hx = (regs.H << 8) | (regs.X);
46 regs.H = (hx >> 8) & 0xff;
51 cl_hc08::fetchea(t_mem code, bool prefix)
53 switch ((code >> 4) & 0x0f) {
58 return fetch(); // Direct
61 return (regs.H << 8) | regs.X; // IX
65 return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1
67 return ((unsigned char)fetch())+regs.SP; // SP1
70 return fetch2()+((regs.H << 8) | regs.X); // IX2
72 return fetch2()+regs.SP; // SP2
82 cl_hc08::inst_nop(t_mem code, bool prefix)
89 cl_hc08::inst_transfer(t_mem code, bool prefix)
95 regs.P = regs.A | 0x60;
98 regs.A = regs.P | 0x60;
107 hx = (regs.H << 8) | regs.X;
108 regs.SP = (hx - 1) & 0xffff;
112 regs.H = (hx >> 8) & 0xff;
123 cl_hc08::inst_setclearflags(t_mem code, bool prefix)
146 cl_hc08::inst_rsp(t_mem code, bool prefix)
154 cl_hc08::inst_nsa(t_mem code, bool prefix)
156 regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4);
163 cl_hc08::inst_lda(t_mem code, bool prefix)
165 regs.A = OPERAND(code, prefix);
172 cl_hc08::inst_ldx(t_mem code, bool prefix)
174 regs.X = OPERAND(code, prefix);
181 cl_hc08::inst_sta(t_mem code, bool prefix)
183 int ea = fetchea(code, prefix);
185 //fprintf (stdout, "ea = 0x%04x\n", ea);
194 cl_hc08::inst_stx(t_mem code, bool prefix)
196 int ea = fetchea(code, prefix);
205 cl_hc08::inst_add(t_mem code, bool prefix)
210 operand = OPERAND(code, prefix);
211 result = (regs.A + operand) & 0xff;
213 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
214 | (~regs.A & ~operand & result)));
215 FLAG_ASSIGN (BIT_H, 0x08 & ((regs.A & operand)
216 | (operand & ~result)
217 | (~result & regs.A)));
218 FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
219 | (operand & ~result)
220 | (~result & regs.A)));
223 fprintf (stdout, "add 0x%02x + 0x%02x = 0x%02x ",regs.A, operand, result & 0xff);
224 fprintf (stdout, "(V=%d, H=%d, C=%d, N=%d, Z=%d), ",
229 (regs.P & BIT_Z)!=0);
237 cl_hc08::inst_adc(t_mem code, bool prefix)
242 uchar carryin = (regs.P & BIT_C)!=0;
244 operand = OPERAND(code, prefix);
245 result = regs.A + operand + carryin;
246 sresult = (signed char)regs.A + (signed char)operand + ((regs.P & BIT_C)!=0);
247 FLAG_NZ (result & 0xff);
248 FLAG_ASSIGN (BIT_V, (sresult<-128) || (sresult>127));
249 /* 0x80 & ((regs.A & operand & ~result)
250 | (~regs.A & ~operand & result))); */
251 FLAG_ASSIGN (BIT_H, (result & 0xf) < (regs.A & 0xf));
252 /* 0x10 & ((regs.A & operand)
253 | (operand & ~result)
254 | (~result & regs.A))); */
255 FLAG_ASSIGN (BIT_C, result & 0x100);
256 /* 0x80 & ((regs.A & operand)
257 | (operand & ~result)
258 | (~result & regs.A))); */
261 fprintf (stdout, "adc 0x%02x + 0x%02x + %d = 0x%02x ",
262 regs.A, operand, carryin, result & 0xff);
263 fprintf (stdout, "(V=%d, H=%d, C=%d, N=%d, Z=%d), ",
268 (regs.P & BIT_Z)!=0);
271 regs.A = result & 0xff;
276 cl_hc08::inst_sub(t_mem code, bool prefix)
281 operand = OPERAND(code, prefix);
282 result = (regs.A - operand) & 0xff;
284 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
285 | (~regs.A & operand & result)));
286 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
288 | (result & ~regs.A)));
290 fprintf (stdout, "sub 0x%02x - 0x%02x = 0x%02x ",regs.A, operand, result & 0xff);
291 fprintf (stdout, "(V=%d, H=%d, C=%d, N=%d, Z=%d), ",
296 (regs.P & BIT_Z)!=0);
303 cl_hc08::inst_sbc(t_mem code, bool prefix)
307 uchar carryin = (regs.P & BIT_C)!=0;
309 operand = OPERAND(code, prefix);
310 result = (regs.A - operand - carryin) & 0xff;
312 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
313 | (~regs.A & operand & result)));
314 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
316 | (result & ~regs.A)));
318 fprintf (stdout, "sbc 0x%02x - 0x%02x - %d = 0x%02x ",
319 regs.A, operand, carryin, result & 0xff);
320 fprintf (stdout, "(V=%d, H=%d, C=%d, N=%d, Z=%d), ",
325 (regs.P & BIT_Z)!=0);
332 cl_hc08::inst_cmp(t_mem code, bool prefix)
337 operand = OPERAND(code, prefix);
338 result = (regs.A - operand) & 0xff;
340 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
341 | (~regs.A & operand & result)));
342 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
344 | (result & ~regs.A)));
349 cl_hc08::inst_cpx(t_mem code, bool prefix)
354 operand = OPERAND(code, prefix);
355 result = (regs.X - operand) & 0xff;
357 FLAG_ASSIGN (BIT_V, 0x80 & ((regs.X & ~operand & ~result)
358 | (~regs.X & operand & result)));
359 FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.X & operand)
361 | (result & ~regs.X)));
366 cl_hc08::inst_jmp(t_mem code, bool prefix)
368 PC = fetchea(code, prefix);
374 cl_hc08::inst_jsr(t_mem code, bool prefix)
376 int newPC = fetchea(code, prefix);
385 cl_hc08::inst_bsr(t_mem code, bool prefix)
387 signed char ofs = fetch();
396 cl_hc08::inst_ais(t_mem code, bool prefix)
398 regs.SP = regs.SP + (signed char)fetch();
403 cl_hc08::inst_aix(t_mem code, bool prefix)
405 regs.X = regs.X + (signed char)fetch();
410 cl_hc08::inst_and(t_mem code, bool prefix)
412 regs.A = regs.A & OPERAND(code, prefix);
419 cl_hc08::inst_bit(t_mem code, bool prefix)
421 uchar operand = regs.A & OPERAND(code, prefix);
428 cl_hc08::inst_ora(t_mem code, bool prefix)
430 regs.A = regs.A | OPERAND(code, prefix);
437 cl_hc08::inst_eor(t_mem code, bool prefix)
439 regs.A = regs.A ^ OPERAND(code, prefix);
446 cl_hc08::inst_asr(t_mem code, bool prefix)
451 if ((code & 0xf0) == 0x40)
453 else if ((code & 0xf0) == 0x50)
456 ea = fetchea(code,prefix);
460 FLAG_ASSIGN (BIT_C, operand & 1);
461 operand = (operand >> 1) | (operand & 0x80);
463 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
465 if ((code & 0xf0) == 0x40)
467 else if ((code & 0xf0) == 0x50)
478 cl_hc08::inst_lsr(t_mem code, bool prefix)
483 if ((code & 0xf0) == 0x40)
485 else if ((code & 0xf0) == 0x50)
488 ea = fetchea(code,prefix);
492 FLAG_ASSIGN (BIT_C, operand & 1);
493 operand = (operand >> 1) & 0x7f;
495 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
497 if ((code & 0xf0) == 0x40)
499 else if ((code & 0xf0) == 0x50)
509 cl_hc08::inst_lsl(t_mem code, bool prefix)
514 if ((code & 0xf0) == 0x40)
516 else if ((code & 0xf0) == 0x50)
519 ea = fetchea(code,prefix);
523 FLAG_ASSIGN (BIT_C, operand & 0x80);
524 operand = (operand << 1);
526 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
528 if ((code & 0xf0) == 0x40)
530 else if ((code & 0xf0) == 0x50)
540 cl_hc08::inst_rol(t_mem code, bool prefix)
542 uchar c = (regs.P & BIT_C)!=0;
546 if ((code & 0xf0) == 0x40)
548 else if ((code & 0xf0) == 0x50)
551 ea = fetchea(code,prefix);
555 FLAG_ASSIGN (BIT_C, operand & 0x80);
556 operand = (operand << 1) | c;
558 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
560 if ((code & 0xf0) == 0x40)
562 else if ((code & 0xf0) == 0x50)
572 cl_hc08::inst_ror(t_mem code, bool prefix)
574 uchar c = (regs.P & BIT_C)!=0;
578 if ((code & 0xf0) == 0x40)
580 else if ((code & 0xf0) == 0x50)
583 ea = fetchea(code,prefix);
587 FLAG_ASSIGN (BIT_C, operand & 1);
588 operand = (operand >> 1) | (c << 7);
590 FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0));
592 if ((code & 0xf0) == 0x40)
594 else if ((code & 0xf0) == 0x50)
604 cl_hc08::inst_inc(t_mem code, bool prefix)
609 if ((code & 0xf0) == 0x40)
611 else if ((code & 0xf0) == 0x50)
614 ea = fetchea(code,prefix);
620 FLAG_ASSIGN (BIT_V, operand == 0x80);
622 if ((code & 0xf0) == 0x40)
624 else if ((code & 0xf0) == 0x50)
634 cl_hc08::inst_dec(t_mem code, bool prefix)
639 if ((code & 0xf0) == 0x40)
641 else if ((code & 0xf0) == 0x50)
644 ea = fetchea(code,prefix);
650 FLAG_ASSIGN (BIT_V, operand == 0x7f);
652 if ((code & 0xf0) == 0x40)
654 else if ((code & 0xf0) == 0x50)
663 cl_hc08::inst_dbnz(t_mem code, bool prefix)
669 if ((code & 0xf0) == 0x40)
671 else if ((code & 0xf0) == 0x50)
674 ea = fetchea(code,prefix);
680 FLAG_ASSIGN (BIT_V, operand == 0x7f);
682 if ((code & 0xf0) == 0x40)
684 else if ((code & 0xf0) == 0x50)
699 cl_hc08::inst_tst(t_mem code, bool prefix)
704 if ((code & 0xf0) == 0x40)
706 else if ((code & 0xf0) == 0x50)
709 ea = fetchea(code,prefix);
721 cl_hc08::inst_clr(t_mem code, bool prefix)
731 if ((code & 0xf0) == 0x40)
733 else if ((code & 0xf0) == 0x50)
743 cl_hc08::inst_clrh(t_mem code, bool prefix)
754 cl_hc08::inst_com(t_mem code, bool prefix)
759 if ((code & 0xf0) == 0x40)
761 else if ((code & 0xf0) == 0x50)
764 ea = fetchea(code,prefix);
773 if ((code & 0xf0) == 0x40)
775 else if ((code & 0xf0) == 0x50)
785 cl_hc08::inst_neg(t_mem code, bool prefix)
790 if ((code & 0xf0) == 0x40)
792 else if ((code & 0xf0) == 0x50)
795 ea = fetchea(code,prefix);
799 FLAG_ASSIGN (BIT_V, operand==0x80);
800 FLAG_ASSIGN (BIT_C, operand!=0x00);
804 if ((code & 0xf0) == 0x40)
806 else if ((code & 0xf0) == 0x50)
817 cl_hc08::inst_pushpull(t_mem code, bool prefix)
848 cl_hc08::inst_stop(t_mem code, bool prefix)
856 cl_hc08::inst_wait(t_mem code, bool prefix)
864 cl_hc08::inst_daa(t_mem code, bool prefix)
869 msn = (regs.A >> 4) & 0xf;
870 if (regs.P & BIT_H) {
891 cl_hc08::inst_mul(t_mem code, bool prefix)
893 int result = regs.A * regs.X;
894 regs.A = result & 0xff;
895 regs.X = (result >> 8) & 0xff;
902 cl_hc08::inst_div(t_mem code, bool prefix)
904 int dividend = (regs.H << 8) | regs.A;
908 quotient = dividend / regs.X;
909 if (quotient<=0xff) {
911 regs.H = dividend % regs.X;
913 FLAG_ASSIGN (BIT_Z, quotient==0);
916 FLAG_SET (BIT_C); // overflow
918 FLAG_SET (BIT_C); // division by zero
925 cl_hc08::inst_condbranch(t_mem code, bool prefix)
930 if ((code & 0xf0)==0x20) {
931 switch ((code>>1) & 7) {
936 taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
939 taken = !(regs.P & BIT_C);
942 taken = !(regs.P & BIT_Z);
945 taken = !(regs.P & BIT_H);
948 taken = !(regs.P & BIT_N);
951 taken = !(regs.P & BIT_I);
954 taken = 0; // TODO: should read simulated IRQ# pin
959 else if ((code & 0xf0)==0x90) {
960 switch ((code>>1) & 7) {
962 taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
965 taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
986 cl_hc08::inst_bitsetclear(t_mem code, bool prefix)
988 uchar bit = (code >> 1) & 7;
989 int ea = fetchea(code, prefix);
990 uchar operand = get1(ea);
993 operand &= ~(1 << bit);
995 operand |= (1 << bit);
1001 cl_hc08::inst_bittestsetclear(t_mem code, bool prefix)
1003 uchar bit = (code >> 1) & 7;
1004 int ea = fetchea(code, prefix);
1005 uchar operand = get1(ea);
1010 taken = operand & (1 << bit);
1012 taken = !(operand & (1 << bit));
1018 FLAG_ASSIGN (BIT_C, operand & (1 << bit));
1023 cl_hc08::inst_cbeq(t_mem code, bool prefix)
1026 uchar operand1, operand2;
1029 if ((code & 0xf0) == 0x40) {
1033 else if ((code & 0xf0) == 0x50) {
1038 ea = fetchea(code,prefix);
1039 operand1 = get1(ea);
1044 if (operand1==operand2)
1054 cl_hc08::inst_rti(t_mem code, bool prefix)
1066 cl_hc08::inst_rts(t_mem code, bool prefix)
1075 cl_hc08::inst_mov(t_mem code, bool prefix)
1080 int hx = (regs.H << 8) | (regs.X);
1083 case 0x4e: //mov opr8a,opr8a
1084 operand = get1(fetch());
1088 case 0x5e: //mov opr8a,x+
1089 operand = get1(fetch());
1093 case 0x6e: //mov #opr8i,opr8a
1098 case 0x7e: //mov x+,opr8a
1107 store1(ea, operand);
1119 cl_hc08::inst_sthx(t_mem code, bool prefix)
1124 store1((ea+1) & 0xffff, regs.X);
1127 FLAG_ASSIGN(BIT_N, regs.X & 0x80);
1128 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
1133 cl_hc08::inst_ldhx(t_mem code, bool prefix)
1141 else if (code == 0x55) {
1144 regs.X = get1(ea+1);
1150 FLAG_ASSIGN(BIT_N, regs.X & 0x80);
1151 FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
1157 cl_hc08::inst_cphx(t_mem code, bool prefix)
1167 else if (code == 0x75) {
1169 operand = (get1(ea) << 8) | get1(ea+1);
1174 hx = (regs.H << 8) | regs.X;
1176 result = (hx-operand) & 0xffff;
1178 FLAG_ASSIGN (BIT_V, 0x8000 & ((hx & ~operand & ~result)
1179 | (~hx & operand & result)));
1180 FLAG_ASSIGN (BIT_C, 0x8000 & ((~hx & operand)
1181 | (operand & result)
1183 FLAG_ASSIGN(BIT_N, result & 0x8000);
1184 FLAG_ASSIGN(BIT_Z, !result);
1190 cl_hc08::inst_swi(t_mem code, bool prefix)
1204 /* End of hc08.src/inst.cc */