📄 inst.cc
字号:
/* * Simulator of microcontrollers (inst.cc) * * hc08 code base from Erik Petrich epetrich@users.sourceforge.net * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * *//* This file is part of microcontroller simulator: ucsim.UCSIM is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.UCSIM is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING. If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. *//*@1@*/#include "ddconfig.h"#include "stdio.h"#include <stdlib.h>// local#include "hc08cl.h"#include "regshc08.h"#include "hc08mac.h"voidcl_hc08::incx(void){ int hx = (regs.H << 8) | (regs.X); hx++; regs.H = (hx >> 8) & 0xff; regs.X = hx & 0xff;}intcl_hc08::fetchea(t_mem code, bool prefix){ switch ((code >> 4) & 0x0f) { case 0x0: case 0x1: case 0x3: case 0xb: return fetch(); // Direct case 0x7: case 0xf: return (regs.H << 8) | regs.X; // IX case 0x6: case 0xe: if (!prefix) return ((unsigned char)fetch())+((regs.H << 8) | regs.X); // IX1 else return ((unsigned char)fetch())+regs.SP; // SP1 case 0xd: if (!prefix) return fetch2()+((regs.H << 8) | regs.X); // IX2 else return fetch2()+regs.SP; // SP2 case 0xc: return fetch2(); default: return(resHALT); }}intcl_hc08::inst_nop(t_mem code, bool prefix){ return(resGO);}intcl_hc08::inst_transfer(t_mem code, bool prefix){ int hx; switch (code) { case 0x84: // TAP regs.P = regs.A | 0x60; break; case 0x85: // TPA regs.A = regs.P | 0x60; break; case 0x97: // TAX regs.X = regs.A; break; case 0x9f: // TXA regs.A = regs.X; break; case 0x94: // TXS hx = (regs.H << 8) | regs.X; regs.SP = (hx - 1) & 0xffff; break; case 0x95: // TSX hx = regs.SP +1; regs.H = (hx >> 8) & 0xff; regs.X = hx & 0xff; break; default: return(resHALT); } return(resGO);}intcl_hc08::inst_setclearflags(t_mem code, bool prefix){ switch (code) { case 0x98: regs.P &= ~BIT_C; break; case 0x99: regs.P |= BIT_C; break; case 0x9a: regs.P &= ~BIT_I; break; case 0x9b: regs.P |= BIT_I; break; default: return(resHALT); } return(resGO);}intcl_hc08::inst_rsp(t_mem code, bool prefix){ regs.SP = 0x00ff; return(resGO);}intcl_hc08::inst_nsa(t_mem code, bool prefix){ regs.A = ((regs.A & 0xf0)>>4) | ((regs.A & 0x0f)<<4); return(resGO);}intcl_hc08::inst_lda(t_mem code, bool prefix){ regs.A = OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.A); return(resGO);}intcl_hc08::inst_ldx(t_mem code, bool prefix){ regs.X = OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.X); return(resGO);}intcl_hc08::inst_sta(t_mem code, bool prefix){ int ea = fetchea(code, prefix); //fprintf (stdout, "ea = 0x%04x\n", ea); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.A); store1(ea, regs.A); return(resGO);}intcl_hc08::inst_stx(t_mem code, bool prefix){ int ea = fetchea(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.X); store1(ea, regs.X); return(resGO);}intcl_hc08::inst_add(t_mem code, bool prefix){ int result, operand1, operand2; operand1 = regs.A; operand2 = OPERAND(code, prefix); result = operand1 + operand2; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result)); regs.A = result & 0xff; return(resGO);}intcl_hc08::inst_adc(t_mem code, bool prefix){ int result, operand1, operand2; int carryin = (regs.P & BIT_C)!=0; operand1 = regs.A; operand2 = OPERAND(code, prefix); result = operand1 + operand2 + carryin; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); FLAG_ASSIGN (BIT_H, 0x10 & (operand1 ^ operand2 ^ result)); regs.A = result & 0xff; return(resGO);}intcl_hc08::inst_sub(t_mem code, bool prefix){ int result, operand1, operand2; operand1 = regs.A; operand2 = OPERAND(code, prefix); result = operand1 - operand2; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); regs.A = result & 0xff; return(resGO);}intcl_hc08::inst_sbc(t_mem code, bool prefix){ int result, operand1, operand2; int carryin = (regs.P & BIT_C)!=0; operand1 = regs.A; operand2 = OPERAND(code, prefix); result = operand1 - operand2 - carryin; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); regs.A = result & 0xff; return(resGO);}intcl_hc08::inst_cmp(t_mem code, bool prefix){ int result, operand1, operand2; operand1 = regs.A; operand2 = OPERAND(code, prefix); result = operand1 - operand2; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); return(resGO);}intcl_hc08::inst_cpx(t_mem code, bool prefix){ int result, operand1, operand2; operand1 = regs.X; operand2 = OPERAND(code, prefix); result = operand1 - operand2; FLAG_NZ (result); FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1))); FLAG_ASSIGN (BIT_C, 0x100 & result); return(resGO);}intcl_hc08::inst_jmp(t_mem code, bool prefix){ PC = fetchea(code, prefix); return(resGO);}intcl_hc08::inst_jsr(t_mem code, bool prefix){ int newPC = fetchea(code, prefix); push2(PC); PC = newPC; return(resGO);}intcl_hc08::inst_bsr(t_mem code, bool prefix){ signed char ofs = fetch(); push2(PC); PC += ofs; return(resGO);}intcl_hc08::inst_ais(t_mem code, bool prefix){ regs.SP = regs.SP + (signed char)fetch(); return(resGO);}intcl_hc08::inst_aix(t_mem code, bool prefix){ int hx = (regs.H << 8) | (regs.X); hx += (signed char)fetch(); regs.H = (hx >> 8) & 0xff; regs.X = hx & 0xff; return(resGO);}intcl_hc08::inst_and(t_mem code, bool prefix){ regs.A = regs.A & OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.A); return(resGO);}intcl_hc08::inst_bit(t_mem code, bool prefix){ uchar operand = regs.A & OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(operand); return(resGO);}intcl_hc08::inst_ora(t_mem code, bool prefix){ regs.A = regs.A | OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.A); return(resGO);}intcl_hc08::inst_eor(t_mem code, bool prefix){ regs.A = regs.A ^ OPERAND(code, prefix); FLAG_CLEAR(BIT_V); FLAG_NZ(regs.A); return(resGO);}intcl_hc08::inst_asr(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_C, operand & 1); operand = (operand >> 1) | (operand & 0x80); FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_lsr(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_C, operand & 1); operand = (operand >> 1) & 0x7f; FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_lsl(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_C, operand & 0x80); operand = (operand << 1); FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_rol(t_mem code, bool prefix){ uchar c = (regs.P & BIT_C)!=0; int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_C, operand & 0x80); operand = (operand << 1) | c; FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_ror(t_mem code, bool prefix){ uchar c = (regs.P & BIT_C)!=0; int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } FLAG_ASSIGN (BIT_C, operand & 1); operand = (operand >> 1) | (c << 7); FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, ((regs.P & BIT_C)!=0) ^ ((regs.P & BIT_N)!=0)); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}intcl_hc08::inst_inc(t_mem code, bool prefix){ int ea = 0xffff; uchar operand; if ((code & 0xf0) == 0x40) operand = regs.A; else if ((code & 0xf0) == 0x50) operand = regs.X; else { ea = fetchea(code,prefix); operand = get1(ea); } operand++; FLAG_NZ (operand); FLAG_ASSIGN (BIT_V, operand == 0x80); if ((code & 0xf0) == 0x40) regs.A = operand; else if ((code & 0xf0) == 0x50) regs.X = operand; else { store1(ea, operand); } return(resGO);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -