diff options
Diffstat (limited to 'src/devices/cpu/z80/z80.cpp')
-rw-r--r-- | src/devices/cpu/z80/z80.cpp | 110 |
1 files changed, 43 insertions, 67 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; |