This commit is contained in:
redcode
2015-11-09 14:27:37 +01:00
parent 4f23d6bbbd
commit 7100dbdb24

View File

@@ -185,24 +185,24 @@ static zuint8 const pf_parity_table[256] = {
#define PF_PARITY(value) pf_parity_table[value]
#define VF(function, operand) \
Z_INLINE zuint8 pf_overflow_##function##8(zint8 a, zint8 b) \
{ \
zint16 total = a operand b; \
\
return total < -128 || total > 127 ? PF : 0; \
#define VF(function, operand) \
Z_INLINE zuint8 pf_overflow_##function##8(zint8 a, zint8 b) \
{ \
zint16 total = a operand b; \
\
return total < -128 || total > 127 ? PF : 0; \
}
VF(add, +)
VF(sub, -)
#undef VF
#define VF(function, bits, total_bits, operand, minimum, maximum) \
Z_INLINE zuint8 pf_overflow_##function##bits(zint##bits a, zint##bits b, zuint8 carry) \
{ \
zint##total_bits total = a operand b operand carry; \
\
return total < minimum || total > maximum ? PF : 0; \
#define VF(function, bits, total_bits, operand, minimum, maximum) \
Z_INLINE zuint8 pf_overflow_##function##bits(zint##bits a, zint##bits b, zuint8 carry) \
{ \
zint##total_bits total = a operand b operand carry; \
\
return total < minimum || total > maximum ? PF : 0; \
}
VF(adc, 8, 16, +, -128, 127)
@@ -247,8 +247,8 @@ static zuint8 const j_k_p_q_table[8] = {
O(state.Z_Z80_STATE_MEMBER_A)
};
#define R_8(name, table, offset, mask, shift) \
Z_INLINE zuint8 *name(Z80 *object) \
#define R_8(name, table, offset, mask, shift) \
Z_INLINE zuint8 *name(Z80 *object) \
{return ((zuint8 *)object) + table[(BYTE(offset) & mask) shift];}
R_8(__xxx___0, x_y_table, 0, 56, >> 3)
@@ -292,8 +292,8 @@ static zuint8 const w_table[4] = {
O(state.Z_Z80_STATE_MEMBER_SP)
};
#define R_16(name, table, offset) \
Z_INLINE zuint16 *name(Z80 *object) \
#define R_16(name, table, offset) \
Z_INLINE zuint16 *name(Z80 *object) \
{return ((void *)object) + table[(BYTE(offset) & 48) >> 4];}
R_16(__ss____0, s_table, 0)
@@ -363,10 +363,10 @@ static void __uuu___(Z80 *object, zuint8 offset, zuint8 value)
case 0: /* ADD */
t = A + value;
F = (A + value > 255) /* CF = Carry */
| pf_overflow_add8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF); /* HF = Half-carry */
A = t; /* NF = 0 */
F = (A + value > 255) /* CF = Carry */
| pf_overflow_add8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF); /* HF = Half-carry */
A = t; /* NF = 0 */
break;
case 1: /* ADC */
@@ -382,10 +382,10 @@ static void __uuu___(Z80 *object, zuint8 offset, zuint8 value)
case 2: /* SUB */
t = A - value;
F = (A < value) /* CF = Borrow */
| NF /* NF = 1 */
| pf_overflow_sub8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF); /* HF = Half-Borrow */
F = (A < value) /* CF = Borrow */
| NF /* NF = 1 */
| pf_overflow_sub8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF); /* HF = Half-Borrow */
A = t;
break;
@@ -402,35 +402,35 @@ static void __uuu___(Z80 *object, zuint8 offset, zuint8 value)
case 4: /* AND */
A &= value;
F = HF | PF_PARITY(A); /* HF = 1; PF = Parity */
break; /* NF, CF = 0 */
F = HF | PF_PARITY(A); /* HF = 1; PF = Parity */
break; /* NF, CF = 0 */
case 5: /* XOR */
A ^= value;
F = PF_PARITY(A); /* PF = Parity */
break; /* HF, NF, CF = 0 */
F = PF_PARITY(A); /* PF = Parity */
break; /* HF, NF, CF = 0 */
case 6: /* OR */
A |= value;
F = PF_PARITY(A); /* PF = Parity */
break; /* HF, NF, CF = 0 */
F = PF_PARITY(A); /* PF = Parity */
break; /* HF, NF, CF = 0 */
case 7: /* CP */
t = A - value;
F = (A < value) /* CF = Borrow */
| NF /* NF = 1 */
| pf_overflow_sub8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF) /* HF = Half-Borrow */
| (value & YXF) /* YF = v.5, XF = v.3 */
| ZF_ZERO(t) /* ZF = !(A - v) */
| (t & SF); /* SF = (A - v).7 */
F = (A < value) /* CF = Borrow */
| NF /* NF = 1 */
| pf_overflow_sub8(A, value) /* PF = Overflow */
| ((A ^ value ^ t) & HF) /* HF = Half-Borrow */
| (value & YXF) /* YF = v.5, XF = v.3 */
| ZF_ZERO(t) /* ZF = !(A - v) */
| (t & SF); /* SF = (A - v).7 */
return;
}
F = (F & (HF | PF | NF | CF)) /* CF, NF, PF and HF already changed */
| A_SYX /* SF = A.7; YF = A.5; XF = A.3 */
| ZF_ZERO(A); /* ZF = !A */
F = (F & (HF | PF | NF | CF)) /* CF, NF, PF and HF already changed */
| A_SYX /* SF = A.7; YF = A.5; XF = A.3 */
| ZF_ZERO(A); /* ZF = !A */
}
@@ -440,22 +440,22 @@ static zuint8 _____vvv(Z80 *object, zuint8 offset, zuint8 value)
/* DEC */
if (object->data.array_uint8[offset] & 1)
{ /* PF = Overflow */
pn = value == 128 ? PNF : NF; /* NF = 1 */
{ /* PF = Overflow */
pn = value == 128 ? PNF : NF; /* NF = 1 */
t = value - 1;
}
/* INC */
else { /* PF = Overflow */
pn = value == 127 ? PF : 0; /* NF = 0 */
else { /* PF = Overflow */
pn = value == 127 ? PF : 0; /* NF = 0 */
t = value + 1;
}
F = (F & CF) /* CF unchanged */
| pn /* PF and NF already calculated */
| (t & SYXF) /* SF = v.7; YF = v.5; XF = v.3 */
| ((value ^ 1 ^ t) & HF) /* HF = Half-Borrow */
| ZF_ZERO(t); /* ZF = !v */
F = (F & CF) /* CF unchanged */
| pn /* PF and NF already calculated */
| (t & SYXF) /* SF = v.7; YF = v.5; XF = v.3 */
| ((value ^ 1 ^ t) & HF) /* HF = Half-Borrow */
| ZF_ZERO(t); /* ZF = !v */
return t;
}
@@ -552,7 +552,7 @@ static zuint8 __ggg___(Z80 *object, zuint8 offset, zuint8 value)
value >>= 1;
break;
/* Uncoment to Avoid compiler warning */
/* Uncoment to Avoid a compiler warning */
/*default: c = 0; break;*/
}
@@ -611,65 +611,65 @@ Z_INLINE zuint8 _m______(Z80 *object, zuint8 offset, zuint8 value)
/* MARK: - Reusable Code */
#define INSTRUCTION(name) static zuint8 name(Z80 *object)
#define CYCLES(cycles) return cycles;
#define EXIT_HALT if (HALT) {PC++; HALT = FALSE; CLEAR_HALT;}
#define PUSH(value) WRITE_16(SP -= 2, value)
#define INSTRUCTION(name) static zuint8 name(Z80 *object)
#define CYCLES(cycles) return cycles;
#define EXIT_HALT if (HALT) {PC++; HALT = FALSE; CLEAR_HALT;}
#define PUSH(value) WRITE_16(SP -= 2, value)
#define LD_A_I_LD_A_R /* HF = 0 / NF = 0 */ \
F = A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
| ZF_ZERO(A) /* ZF = !A */ \
| (IFF2 << 2) /* PF = IFF2 */ \
| F_C; /* CF unchanged */
#define LD_A_I_LD_A_R /* HF = 0 / NF = 0 */ \
F = A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
| ZF_ZERO(A) /* ZF = !A */ \
| (IFF2 << 2) /* PF = IFF2 */ \
| F_C; /* CF unchanged */
#define EX(a, b) t = a; a = b; b = t;
#define EX_VSP_X(register) \
zuint16 tmp = READ_16(SP); \
WRITE_16(SP, register); \
#define EX_VSP_X(register) \
zuint16 tmp = READ_16(SP); \
WRITE_16(SP, register); \
register = tmp;
#define LDX(sign) \
zuint8 n = READ_8(HL sign); \
WRITE_8(DE sign, n); \
n += A; \
/* HF = 0, NF = 0 */ \
F = (F & (SF | ZF | CF)) /* SF, ZF, CF unchanged */ \
| ((n & 2) << 4) /* YF = ([HL] + A).1 */ \
| (n & XF) /* XF = ([HL] + A).3 */ \
| (!!(--BC) << 2); /* PF = 1 if BC != 0, else PF = 0 */
#define LDX(sign) \
zuint8 n = READ_8(HL sign); \
WRITE_8(DE sign, n); \
n += A; \
/* HF = 0, NF = 0 */ \
F = (F & (SF | ZF | CF)) /* SF, ZF, CF unchanged */ \
| ((n & 2) << 4) /* YF = ([HL] + A).1 */ \
| (n & XF) /* XF = ([HL] + A).3 */ \
| (!!(--BC) << 2); /* PF = 1 if BC != 0, else PF = 0 */
#define LDXR(sign) \
LDX(sign) \
if (!BC) return 16; \
PC -= 2; \
#define LDXR(sign) \
LDX(sign) \
if (!BC) return 16; \
PC -= 2; \
return 21;
#define CPX(sign) \
zuint8 v = READ_8(HL sign); \
zuint8 n0 = A - v; \
zuint8 n1 = n0 - !!F_H; \
\
F = (n0 & SF) /* SF = (A - [HL]).7 */ \
| ZF_ZERO(n0) /* ZF = !(A - [HL]) */ \
| ((A ^ v ^ n0) & HF) /* HF = borrow from bit 5 */ \
| ((n1 & 2) << 4) /* YF = (A - [HL] - HF).1 */ \
| (n1 & XF) /* XF = (A - [HL] - HF).3 */ \
| (!!(--BC) << 2) /* PF = !!BC */ \
| NF /* NF = 1 */ \
| F_C; /* CF unchanged */
#define CPX(sign) \
zuint8 v = READ_8(HL sign); \
zuint8 n0 = A - v; \
zuint8 n1 = n0 - !!F_H; \
\
F = (n0 & SF) /* SF = (A - [HL]).7 */ \
| ZF_ZERO(n0) /* ZF = !(A - [HL]) */ \
| ((A ^ v ^ n0) & HF) /* HF = borrow from bit 5 */ \
| ((n1 & 2) << 4) /* YF = (A - [HL] - HF).1 */ \
| (n1 & XF) /* XF = (A - [HL] - HF).3 */ \
| (!!(--BC) << 2) /* PF = !!BC */ \
| NF /* NF = 1 */ \
| F_C; /* CF unchanged */
#define CPXR(sign) \
CPX(sign) \
if (!BC || !n0) return 16; \
PC -= 2; \
#define CPXR(sign) \
CPX(sign) \
if (!BC || !n0) return 16; \
PC -= 2; \
return 21;
@@ -677,11 +677,11 @@ Z_INLINE void add_RR_NN(Z80 *object, zuint16 *r, zuint16 v)
{
zuint16 t = *r + v;
F = F_SZP /* SF, ZF, PF unchanged */
| ((t >> 8) & YXF) /* YF = RR.13; XF = RR.11 */
| (((*r ^ v ^ t) >> 8) & HF) /* HF = RRh half-carry */
| (*r + v > 65535); /* CF = Carry */
*r = t; /* NF = 0 */
F = F_SZP /* SF, ZF, PF unchanged */
| ((t >> 8) & YXF) /* YF = RR.13; XF = RR.11 */
| (((*r ^ v ^ t) >> 8) & HF) /* HF = RRh half-carry */
| (*r + v > 65535); /* CF = Carry */
*r = t; /* NF = 0 */
}
@@ -689,100 +689,100 @@ Z_INLINE void add_RR_NN(Z80 *object, zuint16 *r, zuint16 v)
add_RR_NN(object, (zuint16 *)&register, value);
#define ADC_SBC_HL_SS(function, sign, cf_test, set_nf) \
zuint8 c = F_C; \
zuint16 v = SS1, t = HL sign v sign c; \
\
F = ((t >> 8) & SYXF) /* SF = HL.15; YF = HL.13; XF = HL.11 */ \
| ZF_ZERO(t) /* ZF = !HL */ \
| ((((HL & 0xFFF) sign (v & 0xFFF) sign c) >> 8) & HF) /* HF = Half-carry of H */ \
| pf_overflow_##function##16(HL, v, c) /* PF = Overflow */ \
| (cf_test) /* CF = Carry */ \
set_nf; /* ADC: NF = 0; SBC: NF = 1 */ \
\
HL = t; \
#define ADC_SBC_HL_SS(function, sign, cf_test, set_nf) \
zuint8 c = F_C; \
zuint16 v = SS1, t = HL sign v sign c; \
\
F = ((t >> 8) & SYXF) /* SF = HL.15; YF = HL.13; XF = HL.11 */ \
| ZF_ZERO(t) /* ZF = !HL */ \
| ((((HL & 0xFFF) sign (v & 0xFFF) sign c) >> 8) & HF) /* HF = Half-carry of H */ \
| pf_overflow_##function##16(HL, v, c) /* PF = Overflow */ \
| (cf_test) /* CF = Carry */ \
set_nf; /* ADC: NF = 0; SBC: NF = 1 */ \
\
HL = t; \
CYCLES(15);
#define RXA \
F = F_SZP /* SF, ZF, PF unchanged */ \
| A_YX /* YF = A.5; XF = A.3 */ \
| c; /* CF = pA.7 (rla) / pA.0 (rra) */
#define RXA \
F = F_SZP /* SF, ZF, PF unchanged */ \
| A_YX /* YF = A.5; XF = A.3 */ \
| c; /* CF = pA.7 (rla) / pA.0 (rra) */
#define RXD(a, b, c) \
zuint8 t = READ_8(HL); \
\
WRITE_8(HL, (t a 4) | (A b)); \
A = (A & 0xF0) | (t c); \
\
F = A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
| ZF_ZERO(A) /* ZF = !A */ \
| PF_PARITY(A) /* PF = Parity of A */ \
| F_C; /* CF unchanged */ \
/* HF = 0, NF = 0; */
#define RXD(a, b, c) \
zuint8 t = READ_8(HL); \
\
WRITE_8(HL, (t a 4) | (A b)); \
A = (A & 0xF0) | (t c); \
\
F = A_SYX /* SF = A.7; YF = A.5; XF = A.3 */ \
| ZF_ZERO(A) /* ZF = !A */ \
| PF_PARITY(A) /* PF = Parity of A */ \
| F_C; /* CF unchanged */ \
/* HF = 0, NF = 0; */
#define BIT_N_VALUE(value) \
zuint8 n = value & (1 << N(1)); /* SF = value.N && N == 7 */ \
/* ZF, PF = !value.N */ \
F = (n ? n & SYXF : ZPF) /* YF = value.N && N == 5 */ \
| HF /* HF = 1; NF = 0; CF unchanged */ \
#define BIT_N_VALUE(value) \
zuint8 n = value & (1 << N(1)); /* SF = value.N && N == 7 */ \
/* ZF, PF = !value.N */ \
F = (n ? n & SYXF : ZPF) /* YF = value.N && N == 5 */ \
| HF /* HF = 1; NF = 0; CF unchanged */ \
| F_C; /* XF = value.N && N == 3 */
#define BIT_N_VADDRESS(address) \
Z16Bit a; \
zuint8 n = READ_8(a.value_uint16 = address) & (1 << N(3)); \
\
F = (n ? (n & SF) : ZPF) \
| (a.values_uint8.index1 & YXF) \
| HF \
#define BIT_N_VADDRESS(address) \
Z16Bit a; \
zuint8 n = READ_8(a.value_uint16 = address) & (1 << N(3)); \
\
F = (n ? (n & SF) : ZPF) \
| (a.values_uint8.index1 & YXF) \
| HF \
| F_C;
#define IN_VC \
zuint8 t = IN(BC); \
\
F = (t & SYXF) \
| ZF_ZERO(t) \
| PF_PARITY(t) \
#define IN_VC \
zuint8 t = IN(BC); \
\
F = (t & SYXF) \
| ZF_ZERO(t) \
| PF_PARITY(t) \
| F_C;
#define INX(sign) \
zuint8 v = IN(BC); \
zuint16 t = v + ((C + 1) & 255); \
\
WRITE_8(HL, v); \
HL sign; \
B--; \
\
F = (B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
| PF_PARITY((t & 7) ^ B) /* */ \
| (v & 128); /* NF = IN(BC).7 */ \
\
#define INX(sign) \
zuint8 v = IN(BC); \
zuint16 t = v + ((C + 1) & 255); \
\
WRITE_8(HL, v); \
HL sign; \
B--; \
\
F = (B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
| PF_PARITY((t & 7) ^ B) /* */ \
| (v & 128); /* NF = IN(BC).7 */ \
\
if (t > 255) F |= HCF;
#define INXR(sign) INX(sign); if (!B) return 16; PC -= 2; return 21;
#define OUTX(sign) \
zuint8 t = READ_8(HL); \
\
OUT(BC, t); \
HL sign; \
B--; \
\
F = (B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
| PF_PARITY(((L + t) & 7) ^ B) /* PF = Parity of ((L + (HL)) and 7) xor B */ \
| (t & 128); /* NF = IN(BC).7 */ \
/* */ \
if (L + t > 255) F |= HCF; /* if (L + (HL) > 255) HF = 1; else HF = 0 */ \
/* if (L + (HL) > 255) CF = 1; else CF = 0 */
#define OUTX(sign) \
zuint8 t = READ_8(HL); \
\
OUT(BC, t); \
HL sign; \
B--; \
\
F = (B & SYXF) /* SF = (B - 1).7; YF = (B - 1).5; XF = (B - 1).3 */ \
| ZF_ZERO(B) /* ZF = !(B - 1) */ \
| PF_PARITY(((L + t) & 7) ^ B) /* PF = Parity of ((L + (HL)) and 7) xor B */ \
| (t & 128); /* NF = IN(BC).7 */ \
/* */ \
if (L + t > 255) F |= HCF; /* if (L + (HL) > 255) HF = 1; else HF = 0 */ \
/* if (L + (HL) > 255) CF = 1; else CF = 0 */
#define OTXR(sign) OUTX(sign); if (!B) return 16; PC -= 2; return 21;
@@ -1023,10 +1023,10 @@ INSTRUCTION(cpl)
{
PC++; A = ~A;
F = (F & (SF | ZF | PF | CF)) /* SF, ZF, PF, CF unchanged */
| HF /* HF = 1 */
| NF /* NF = 1 */
| A_YX; /* YF = A.5; XF = A.3 */
F = (F & (SF | ZF | PF | CF)) /* SF, ZF, PF, CF unchanged */
| HF /* HF = 1 */
| NF /* NF = 1 */
| A_YX; /* YF = A.5; XF = A.3 */
CYCLES(4);
}
@@ -1036,12 +1036,12 @@ INSTRUCTION(neg)
{
zuint8 t = -A; PC += 2;
F = (t & SYXF) /* SF = -A.7; YF = -A.5; XF = -A.3 */
| ZF_ZERO(t) /* ZF = !-A */
| ((0 ^ A ^ t) & HF) /* HF = Half-borrow */
| ((t == 128) << 2) /* PF = Overflow */
| NF /* NF = 1 */
| !!A; /* CF = !!A */
F = (t & SYXF) /* SF = -A.7; YF = -A.5; XF = -A.3 */
| ZF_ZERO(t) /* ZF = !-A */
| ((0 ^ A ^ t) & HF) /* HF = Half-borrow */
| ((t == 128) << 2) /* PF = Overflow */
| NF /* NF = 1 */
| !!A; /* CF = !!A */
A = t;
CYCLES(8);
@@ -1052,11 +1052,11 @@ INSTRUCTION(ccf)
{
PC++;
F = F_SZP /* SF, ZF, PF unchanged */
| A_YX /* YF = A.5; XF = A.3 */
| (F_C << 4) /* HF = CF */
| (~F & CF); /* CF = ~CF */
/* NF = 0 */
F = F_SZP /* SF, ZF, PF unchanged */
| A_YX /* YF = A.5; XF = A.3 */
| (F_C << 4) /* HF = CF */
| (~F & CF); /* CF = ~CF */
/* NF = 0 */
CYCLES(4);
}
@@ -1065,10 +1065,10 @@ INSTRUCTION(scf)
{
PC++;
F = F_SZP /* SF, ZF, PF unchanged */
| A_YX /* YF = A.5; XF = A.3 */
| CF; /* CF = 1 */
/* HF = 0; NF = 0 */
F = F_SZP /* SF, ZF, PF unchanged */
| A_YX /* YF = A.5; XF = A.3 */
| CF; /* CF = 1 */
/* HF = 0; NF = 0 */
CYCLES(4);
}
@@ -1365,13 +1365,13 @@ static Instruction const instruction_table_ED[256] = {
/* MARK: - Prefixed Instruction Set Selection and Execution */
#define DD_FD(register) \
zuint8 tiks; \
\
XY = register; \
R++; \
tiks = instruction_table_XY[BYTE1 = READ_8(PC + 1)](object); \
register = XY; \
#define DD_FD(register) \
zuint8 tiks; \
\
XY = register; \
R++; \
tiks = instruction_table_XY[BYTE1 = READ_8(PC + 1)](object); \
register = XY; \
return tiks;