summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/z80/z80.cpp110
-rw-r--r--src/devices/cpu/z80/z80.h6
-rw-r--r--src/devices/cpu/z80/z80.lst30
3 files changed, 60 insertions, 86 deletions
diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp
index 9b85d3cfee4..ab4d79d5120 100644
--- a/src/devices/cpu/z80/z80.cpp
+++ b/src/devices/cpu/z80/z80.cpp
@@ -40,8 +40,6 @@ u8 z80_device::SZ_BIT[] = {}; // zero, sign and parity/overflow (=zero) flags
u8 z80_device::SZP[] = {}; // zero, sign and parity flags
u8 z80_device::SZHV_inc[] = {}; // zero, sign, half carry and overflow flags INC r8
u8 z80_device::SZHV_dec[] = {}; // zero, sign, half carry and overflow flags DEC r8
-u8 z80_device::SZHVC_add[] = {};
-u8 z80_device::SZHVC_sub[] = {};
/***************************************************************
@@ -170,9 +168,11 @@ void z80_device::rra()
***************************************************************/
void z80_device::add_a(u8 value)
{
- u32 ah = AF & 0xff00;
- u32 res = (u8)((ah >> 8) + value);
- set_f(SZHVC_add[ah | res]);
+ const u16 res = A + value;
+ u8 f = (((A ^ res) & (value ^ res)) >> 5) & VF;
+ f |= flags_szyxc(res);
+ f |= ((A & 0x0f) + (value & 0x0f)) & HF;
+ set_f(f);
A = res;
}
@@ -181,20 +181,27 @@ void z80_device::add_a(u8 value)
***************************************************************/
void z80_device::adc_a(u8 value)
{
- u32 ah = AF & 0xff00, c = AF & 1;
- u32 res = (u8)((ah >> 8) + value + c);
- set_f(SZHVC_add[(c << 16) | ah | res]);
+ const int c = F & CF;
+ const u16 res = A + value + c;
+ u8 f = (((A ^ res) & (value ^ res)) >> 5) & VF;
+ f |= flags_szyxc(res);
+ f |= ((A & 0x0f) + (value & 0x0f) + c) & HF;
+
+ set_f(f);
A = res;
}
/***************************************************************
- * SUB n
+ * SUB A,n
***************************************************************/
-void z80_device::sub(u8 value)
+void z80_device::sub_a(u8 value)
{
- u32 ah = AF & 0xff00;
- u32 res = (u8)((ah >> 8) - value);
- set_f(SZHVC_sub[ah | res]);
+ const u16 res = A - value;
+ u8 f = (((A ^ value) & (A ^ res)) >> 5) & VF;
+ f |= NF | flags_szyxc(res);
+ f |= ((A & 0x0f) - (value & 0x0f)) & HF;
+
+ set_f(f);
A = res;
}
@@ -203,9 +210,13 @@ void z80_device::sub(u8 value)
***************************************************************/
void z80_device::sbc_a(u8 value)
{
- u32 ah = AF & 0xff00, c = AF & 1;
- u32 res = (u8)((ah >> 8) - value - c);
- set_f(SZHVC_sub[(c << 16) | ah | res]);
+ const int c = F & CF;
+ const u16 res = A - value - c;
+ u8 f = (((A ^ value) & (A ^ res)) >> 5) & VF;
+ f |= NF | flags_szyxc(res);
+ f |= ((A & 0x0f) - (value & 0x0f) - c) & HF;
+
+ set_f(f);
A = res;
}
@@ -216,7 +227,7 @@ void z80_device::neg()
{
u8 value = A;
A = 0;
- sub(value);
+ sub_a(value);
}
/***************************************************************
@@ -272,10 +283,12 @@ void z80_device::xor_a(u8 value)
***************************************************************/
void z80_device::cp(u8 value)
{
- unsigned val = value;
- u32 ah = AF & 0xff00;
- u32 res = (u8)((ah >> 8) - val);
- set_f((SZHVC_sub[ah | res] & ~(YF | XF)) | (val & (YF | XF)));
+ const u16 res = A - value;
+ u8 f = (((A ^ value) & (A ^ res)) >> 5) & VF;
+ f |= NF | flags_szyxc(res);
+ f |= ((A & 0x0f) - (value & 0x0f)) & HF;
+
+ set_f((f & ~(YF | XF)) | (value & (YF | XF)));
}
/***************************************************************
@@ -476,6 +489,15 @@ void z80_device::illegal_2()
m_opcodes.read_byte((PC - 1) & 0xffff));
}
+u8 z80_device::flags_szyxc(u16 value)
+{
+ u8 f = value & (SF | YF | XF); // SF + undocumented flag bits 5+3
+ f |= u8(value) ? 0 : ZF;
+ f |= (value >> 8) & CF;
+ return f;
+}
+
+
/****************************************************************************
* Processor initialization
****************************************************************************/
@@ -495,52 +517,6 @@ void z80_device::device_start()
{
if (!tables_initialised)
{
- u8 *padd = &SZHVC_add[ 0*256];
- u8 *padc = &SZHVC_add[256*256];
- u8 *psub = &SZHVC_sub[ 0*256];
- u8 *psbc = &SZHVC_sub[256*256];
- for (int oldval = 0; oldval < 256; oldval++)
- {
- for (int newval = 0; newval < 256; newval++)
- {
- // add or adc w/o carry set
- int val = newval - oldval;
- *padd = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
- *padd |= (newval & (YF | XF)); // undocumented flag bits 5+3
- if ((newval & 0x0f) < (oldval & 0x0f)) *padd |= HF;
- if (newval < oldval) *padd |= CF;
- if ((val^oldval^0x80) & (val^newval) & 0x80) *padd |= VF;
- padd++;
-
- // adc with carry set
- val = newval - oldval - 1;
- *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF;
- *padc |= (newval & (YF | XF)); // undocumented flag bits 5+3
- if ((newval & 0x0f) <= (oldval & 0x0f)) *padc |= HF;
- if (newval <= oldval) *padc |= CF;
- if ((val^oldval^0x80) & (val^newval) & 0x80) *padc |= VF;
- padc++;
-
- // cp, sub or sbc w/o carry set
- val = oldval - newval;
- *psub = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
- *psub |= (newval & (YF | XF)); // undocumented flag bits 5+3
- if ((newval & 0x0f) > (oldval & 0x0f)) *psub |= HF;
- if (newval > oldval) *psub |= CF;
- if ((val^oldval) & (oldval^newval) & 0x80) *psub |= VF;
- psub++;
-
- // sbc with carry set
- val = oldval - newval - 1;
- *psbc = NF | ((newval) ? ((newval & 0x80) ? SF : 0) : ZF);
- *psbc |= (newval & (YF | XF)); // undocumented flag bits 5+3
- if ((newval & 0x0f) >= (oldval & 0x0f)) *psbc |= HF;
- if (newval >= oldval) *psbc |= CF;
- if ((val^oldval) & (oldval^newval) & 0x80) *psbc |= VF;
- psbc++;
- }
- }
-
for (int i = 0; i < 256; i++)
{
int p = 0;
diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h
index 0978b03cbbe..ec111c3cd32 100644
--- a/src/devices/cpu/z80/z80.h
+++ b/src/devices/cpu/z80/z80.h
@@ -77,6 +77,7 @@ protected:
void illegal_1();
void illegal_2();
+ u8 flags_szyxc(u16 value);
void halt();
void leave_halt();
@@ -88,7 +89,7 @@ protected:
void rra();
void add_a(u8 value);
void adc_a(u8 value);
- void sub(u8 value);
+ void sub_a(u8 value);
void sbc_a(u8 value);
void neg();
void daa();
@@ -187,9 +188,6 @@ protected:
static u8 SZP[0x100]; // zero, sign and parity flags
static u8 SZHV_inc[0x100]; // zero, sign, half carry and overflow flags INC r8
static u8 SZHV_dec[0x100]; // zero, sign, half carry and overflow flags DEC r8
-
- static u8 SZHVC_add[2 * 0x100 * 0x100];
- static u8 SZHVC_sub[2 * 0x100 * 0x100];
};
DECLARE_DEVICE_TYPE(Z80, z80_device)
diff --git a/src/devices/cpu/z80/z80.lst b/src/devices/cpu/z80/z80.lst
index 202776169f6..e666dc6444a 100644
--- a/src/devices/cpu/z80/z80.lst
+++ b/src/devices/cpu/z80/z80.lst
@@ -3605,10 +3605,10 @@ dd93 # DB DD
call jump 0093
dd94 # SUB HX
- sub(HX);
+ sub_a(HX);
dd95 # SUB LX
- sub(LX);
+ sub_a(LX);
dd96 # SUB (IX+o)
call eax
@@ -3616,7 +3616,7 @@ dd96 # SUB (IX+o)
5 * call nomreq_addr
TADR = m_ea;
call rm
- sub(TDAT8);
+ sub_a(TDAT8);
dd97 # DB DD
illegal_1();
@@ -4693,10 +4693,10 @@ fd93 # DB FD
call jump 0093
fd94 # SUB HY
- sub(HY);
+ sub_a(HY);
fd95 # SUB LY
- sub(LY);
+ sub_a(LY);
fd96 # SUB (IY+o)
call eay
@@ -4704,7 +4704,7 @@ fd96 # SUB (IY+o)
5 * call nomreq_addr
TADR = m_ea;
call rm
- sub(TDAT8);
+ sub_a(TDAT8);
fd97 # DB FD
illegal_1();
@@ -6490,30 +6490,30 @@ edff # DB ED
adc_a(A);
0090 # SUB B
- sub(B);
+ sub_a(B);
0091 # SUB C
- sub(C);
+ sub_a(C);
0092 # SUB D
- sub(D);
+ sub_a(D);
0093 # SUB E
- sub(E);
+ sub_a(E);
0094 # SUB H
- sub(H);
+ sub_a(H);
0095 # SUB L
- sub(L);
+ sub_a(L);
0096 # SUB (HL)
TADR = HL;
call rm
- sub(TDAT8);
+ sub_a(TDAT8);
0097 # SUB A
- sub(A);
+ sub_a(A);
0098 # SBC A,B
sbc_a(B);
@@ -6733,7 +6733,7 @@ edff # DB ED
00d6 # SUB n
call arg
- sub(TDAT8);
+ sub_a(TDAT8);
00d7 # RST 2
call rst 0x10