int
cl_hc08::inst_add(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
- operand = OPERAND(code, prefix);
- result = (regs.A + operand) & 0xff;
+ operand1 = regs.A;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 + operand2;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
- | (~regs.A & ~operand & result)));
- FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
- | (operand & ~result)
- | (~result & regs.A)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
- | (operand & ~result)
- | (~result & regs.A)));
- regs.A = 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);
}
int
cl_hc08::inst_adc(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
+ int carryin = (regs.P & BIT_C)!=0;
- operand = OPERAND(code, prefix);
- result = (regs.A + operand + ((regs.P & BIT_C)!=0)) & 0xff;
+ operand1 = regs.A;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 + operand2 + carryin;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & operand & ~result)
- | (~regs.A & ~operand & result)));
- FLAG_ASSIGN (BIT_H, 0x10 & ((regs.A & operand)
- | (operand & ~result)
- | (~result & regs.A)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((regs.A & operand)
- | (operand & ~result)
- | (~result & regs.A)));
- regs.A = 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);
}
int
cl_hc08::inst_sub(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
- operand = OPERAND(code, prefix);
- result = (regs.A - operand) & 0xff;
+ operand1 = regs.A;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 - operand2;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
- | (~regs.A & operand & result)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
- | (operand & result)
- | (result & ~regs.A)));
- regs.A = result;
+ FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+ FLAG_ASSIGN (BIT_C, 0x100 & result);
+
+ regs.A = result & 0xff;
return(resGO);
}
int
cl_hc08::inst_sbc(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
+ int carryin = (regs.P & BIT_C)!=0;
- operand = OPERAND(code, prefix);
- result = (regs.A - operand - ((regs.P & BIT_C)!=0) ) & 0xff;
+ operand1 = regs.A;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 - operand2 - carryin;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
- | (~regs.A & operand & result)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
- | (operand & result)
- | (result & ~regs.A)));
- regs.A = result;
+ FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+ FLAG_ASSIGN (BIT_C, 0x100 & result);
+
+ regs.A = result & 0xff;
return(resGO);
}
int
cl_hc08::inst_cmp(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
- operand = OPERAND(code, prefix);
- result = (regs.A - operand) & 0xff;
+ operand1 = regs.A;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 - operand2;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.A & ~operand & ~result)
- | (~regs.A & operand & result)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.A & operand)
- | (operand & result)
- | (result & ~regs.A)));
+ FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+ FLAG_ASSIGN (BIT_C, 0x100 & result);
+
return(resGO);
}
int
cl_hc08::inst_cpx(t_mem code, bool prefix)
{
- int result;
- uchar operand;
+ int result, operand1, operand2;
- operand = OPERAND(code, prefix);
- result = (regs.X - operand) & 0xff;
+ operand1 = regs.X;
+ operand2 = OPERAND(code, prefix);
+ result = operand1 - operand2;
FLAG_NZ (result);
- FLAG_ASSIGN (BIT_V, 0x80 & ((regs.X & ~operand & ~result)
- | (~regs.X & operand & result)));
- FLAG_ASSIGN (BIT_C, 0x80 & ((~regs.X & operand)
- | (operand & result)
- | (result & ~regs.X)));
+ FLAG_ASSIGN (BIT_V, 0x80 & (operand1 ^ operand2 ^ result ^ (result >>1)));
+ FLAG_ASSIGN (BIT_C, 0x100 & result);
+
return(resGO);
}
int
cl_hc08::inst_aix(t_mem code, bool prefix)
{
- regs.X = regs.X + (signed char)fetch();
+ int hx = (regs.H << 8) | (regs.X);
+ hx += (signed char)fetch();
+ regs.H = (hx >> 8) & 0xff;
+ regs.X = hx & 0xff;
return(resGO);
}
else if ((code & 0xf0) == 0x50)
regs.X = operand;
else {
+ ea = fetchea(code,prefix);
store1(ea, operand);
}
return(resGO);
int
cl_hc08::inst_div(t_mem code, bool prefix)
{
- int dividend = (regs.H << 8) | regs.A;
- int quotient;
+ unsigned int dividend = (regs.H << 8) | regs.A;
+ unsigned int quotient;
if (regs.X) {
- quotient = dividend / regs.X;
+ quotient = dividend / (unsigned int)regs.X;
if (quotient<=0xff) {
regs.A = quotient;
regs.H = dividend % regs.X;
{
bool taken;
signed char ofs;
+ unsigned char maskedP;
if ((code & 0xf0)==0x20) {
switch ((code>>1) & 7) {
taken = 1;
break;
case 1: // BHI
- taken = (regs.P & BIT_C) || !(regs.P & BIT_Z);
+ taken = !(regs.P & (BIT_C | BIT_Z));
break;
case 2: // BCC
taken = !(regs.P & BIT_C);
else if ((code & 0xf0)==0x90) {
switch ((code>>1) & 7) {
case 0: // BGE
- taken = !(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0));
+ maskedP = regs.P & (BIT_N | BIT_V);
+ taken = !maskedP || (maskedP == (BIT_N | BIT_V));
break;
- case 1: // BLT
- taken = (!(((regs.P & BIT_N)!=0) ^ ((regs.P & BIT_V)!=0)))
- || (regs.P & BIT_Z);
+ case 1: // BGT
+ maskedP = regs.P & (BIT_N | BIT_V | BIT_Z);
+ taken = !maskedP || (maskedP == (BIT_N | BIT_V));
break;
default:
return(resHALT);
int ea;
uchar operand;
bool aix;
+ int hx = (regs.H << 8) | (regs.X);
switch (code) {
- case 0x4e:
+ case 0x4e: //mov opr8a,opr8a
operand = get1(fetch());
ea = fetch();
aix = 0;
break;
- case 0x5e:
+ case 0x5e: //mov opr8a,x+
operand = get1(fetch());
- ea = regs.X;
+ ea = hx;
aix = 1;
break;
- case 0x6e:
+ case 0x6e: //mov #opr8i,opr8a
operand = fetch();
ea = fetch();
aix = 0;
break;
- case 0x7e:
- operand = get1(regs.X);
+ case 0x7e: //mov x+,opr8a
+ operand = get1(hx);
ea = fetch();
aix = 1;
break;
store1((ea+1) & 0xffff, regs.X);
FLAG_CLEAR(BIT_V);
- FLAG_ASSIGN(BIT_N, regs.X & 0x80);
- FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
+ FLAG_ASSIGN(BIT_N, regs.H & 0x80);
+ FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
return(resGO);
}
return(resHALT);
FLAG_CLEAR(BIT_V);
- FLAG_ASSIGN(BIT_N, regs.X & 0x80);
- FLAG_ASSIGN(BIT_Z, !regs.X && !regs.A);
+ FLAG_ASSIGN(BIT_N, regs.H & 0x80);
+ FLAG_ASSIGN(BIT_Z, !regs.X && !regs.H);
return(resGO);
}
return(resHALT);
hx = (regs.H << 8) | regs.X;
+ result = hx-operand;
- result = (hx-operand) & 0xffff;
-
- FLAG_ASSIGN (BIT_V, 0x8000 & ((hx & ~operand & ~result)
- | (~hx & operand & result)));
- FLAG_ASSIGN (BIT_C, 0x8000 & ((~hx & operand)
- | (operand & result)
- | (result & ~hx)));
+ FLAG_ASSIGN (BIT_V, 0x8000 & (hx ^ operand ^ result ^ (result>>1)));
+ FLAG_ASSIGN (BIT_C, 0x10000 & result);
FLAG_ASSIGN(BIT_N, result & 0x8000);
- FLAG_ASSIGN(BIT_Z, !result);
+ FLAG_ASSIGN(BIT_Z, !(result & 0xffff));
return(resGO);
}