diff options
Diffstat (limited to 'src/devices/cpu')
-rw-r--r-- | src/devices/cpu/z80/z80.cpp | 110 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.h | 6 | ||||
-rw-r--r-- | src/devices/cpu/z80/z80.lst | 30 |
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 |