From fbdee38492cf86a89334965e7c8721b506df9b36 Mon Sep 17 00:00:00 2001 From: holub Date: Sat, 2 Sep 2023 13:09:52 -0400 Subject: cpu/z80/z80.cpp: Improved flags, and removed timing tables. (#11522) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improved emulation of undocumented flags. [Manuel Sainz de Baranda y Goñi, Peter Helcmanovsky, Patrik Rak] * Removed instruction timing tables and helpers for systems with simple wait states. [smf, hap, Lord Nightmare] --- src/devices/cpu/z80/kc82.cpp | 22 +- src/devices/cpu/z80/kc82.h | 9 +- src/devices/cpu/z80/z80.cpp | 1118 ++++++++++++++++++--------------------- src/devices/cpu/z80/z80.h | 199 +++---- src/mame/amstrad/amstrad.cpp | 78 ++- src/mame/amstrad/amstrad.h | 4 +- src/mame/amstrad/amstrad_m.cpp | 241 +++------ src/mame/chess/cking_master.cpp | 8 +- src/mame/msx/msx.cpp | 100 +--- 9 files changed, 714 insertions(+), 1065 deletions(-) diff --git a/src/devices/cpu/z80/kc82.cpp b/src/devices/cpu/z80/kc82.cpp index 440a4498c0a..6dc575139de 100644 --- a/src/devices/cpu/z80/kc82.cpp +++ b/src/devices/cpu/z80/kc82.cpp @@ -206,7 +206,7 @@ bool kc82_device::memory_translate(int spacenum, int intention, offs_t &address, // rm - read one byte from memory //------------------------------------------------- -u8 kc82_device::rm(u16 addr) +u8 kc82_device::data_read(u16 addr) { return m_data.read_byte(addr + m_mmu_base[addr >> 10]); } @@ -216,7 +216,7 @@ u8 kc82_device::rm(u16 addr) // wm - write one byte to memory //------------------------------------------------- -void kc82_device::wm(u16 addr, u8 value) +void kc82_device::data_write(u16 addr, u8 value) { m_data.write_byte(addr + m_mmu_base[addr >> 10], value); } @@ -226,10 +226,9 @@ void kc82_device::wm(u16 addr, u8 value) // rop - read opcode //------------------------------------------------- -u8 kc82_device::rop() +u8 kc82_device::opcode_read() { u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2]; - m_pc.w.l++; // no refresh return m_opcodes.read_byte(pc); } @@ -239,21 +238,8 @@ u8 kc82_device::rop() // arg - read 8-bit argument //------------------------------------------------- -u8 kc82_device::arg() +u8 kc82_device::arg_read() { u32 pc = m_pc.w.l + m_mmu_base[m_pc.b.h >> 2]; - m_pc.w.l++; return m_args.read_byte(pc); } - - -//------------------------------------------------- -// arg16 - read 16-bit argument -//------------------------------------------------- - -u16 kc82_device::arg16() -{ - u16 d16 = arg(); - d16 |= u16(arg()) << 8; - return d16; -} diff --git a/src/devices/cpu/z80/kc82.h b/src/devices/cpu/z80/kc82.h index 1d0a0965870..3c7f05cd70d 100644 --- a/src/devices/cpu/z80/kc82.h +++ b/src/devices/cpu/z80/kc82.h @@ -41,11 +41,10 @@ protected: virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override; // z80_device overrides - virtual u8 rm(u16 addr) override; - virtual void wm(u16 addr, u8 value) override; - virtual u8 rop() override; - virtual u8 arg() override; - virtual u16 arg16() override; + virtual u8 data_read(u16 addr) override; + virtual void data_write(u16 addr, u8 value) override; + virtual u8 opcode_read() override; + virtual u8 arg_read() override; // MMU access u8 mmu_r(offs_t offset); diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index 16988b788c8..fca99ae0eba 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -16,24 +16,14 @@ * - LD A,I/R P/V flag reset glitch is fixed on CMOS Z80 * - OUT (C),0 outputs 0 on NMOS Z80, $FF on CMOS Z80 * - SCF/CCF X/Y flags is ((flags | A) & 0x28) on SGS/SHARP/ZiLOG NMOS Z80, - * (flags & A & 0x28) on NEC NMOS Z80, other models unknown. + * (flags & A & 0x28). * However, recent findings say that SCF/CCF X/Y results depend on whether - * or not the previous instruction touched the flag register. And the exact - * behaviour on NEC Z80 is still unknown. + * or not the previous instruction touched the flag register. * This Z80 emulator assumes a ZiLOG NMOS model. * * Changes in 0.243: - * Fundation for M cycles emulation. Currently we preserve cc_* tables with total timings. + * Foundation for M cycles emulation. Currently we preserve cc_* tables with total timings. * execute_run() behavior (simplified) ... - * Before: - * + fetch opcode - * + call EXEC() - * + adjust icount base on cc_* (all T are used after M1 == wrong) - * + execute instruction - * Now: - * + fetch opcode - * + call EXEC() - * + execute instruction adjusting icount per each Read (arg(), recursive rop()) and Write * Changes in 3.9: * - Fixed cycle counts for LD IYL/IXL/IYH/IXH,n [Marshmellow] * - Fixed X/Y flags in CCF/SCF/BIT, ZEXALL is happy now [hap] @@ -109,7 +99,7 @@ * now also adjust the r register depending on the skipped opcodes. * Changes in 2.2: * - Fixed bugs in CPL, SCF and CCF instructions flag handling. - * - Changed variable ea and arg16() function to uint32_t; this + * - Changed variable ea and arg16() function to u32; this * produces slightly more efficient code. * - The DD/FD XY CB opcodes where XY is 40-7F and Y is not 6/E * are changed to calls to the X6/XE opcodes to reduce object size. @@ -124,21 +114,27 @@ #include "z80.h" #include "z80dasm.h" -#define VERBOSE 0 +#define LOG_UNDOC (1U << 1) +#define LOG_INT (1U << 2) +#define LOG_TIME (1U << 3) + +#define VERBOSE ( LOG_UNDOC /*| LOG_INT*/ ) +#include "logmacro.h" + +#define LOGUNDOC(...) LOGMASKED(LOG_UNDOC, __VA_ARGS__) +#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__) + /* On an NMOS Z80, if LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2 was set before this instruction. This issue was fixed on the CMOS Z80, so until knowing (most) Z80 types on hardware, it's disabled */ -#define HAS_LDAIR_QUIRK 0 - -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) +#define HAS_LDAIR_QUIRK 0 -/****************************************************************************/ -/* The Z80 registers. halt is set to 1 when the CPU is halted, the refresh */ -/* register is calculated as follows: refresh=(r&127)|(r2&128) */ -/****************************************************************************/ - +/**************************************************************************** + * The Z80 registers. halt is set to 1 when the CPU is halted, the refresh + * register is calculated as follows: refresh = (r & 127) | (r2 & 128) + ****************************************************************************/ #define CF 0x01 #define NF 0x02 #define PF 0x04 @@ -152,7 +148,7 @@ #define INT_IRQ 0x01 #define NMI_IRQ 0x02 -#define PRVPC m_prvpc.d /* previous program counter */ +#define PRVPC m_prvpc.d // previous program counter #define PCD m_pc.d #define PC m_pc.w.l @@ -164,6 +160,7 @@ #define AF m_af.w.l #define A m_af.b.h #define F m_af.b.l +#define Q m_q #define BCD m_bc.d #define BC m_bc.w.l @@ -196,133 +193,15 @@ static bool tables_initialised = false; -static uint8_t SZ[256]; /* zero and sign flags */ -static uint8_t SZ_BIT[256]; /* zero, sign and parity/overflow (=zero) flags for BIT opcode */ -static uint8_t SZP[256]; /* zero, sign and parity flags */ -static uint8_t SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */ -static uint8_t SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */ - -static uint8_t SZHVC_add[2*256*256]; -static uint8_t SZHVC_sub[2*256*256]; - -static const uint8_t cc_op[0x100] = { - 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, - 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, - 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, - 7,10,13, 6,11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 7, 7, 7, 7, 7, 7, 4, 7, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, - 5,10,10,10,10,11, 7,11, 5,10,10, 4,10,17, 7,11, /* cb -> cc_cb */ - 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 4, 7,11, /* dd -> cc_xy */ - 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 4, 7,11, /* ed -> cc_ed */ - 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 4, 7,11 /* fd -> cc_xy */ -}; - -static const u8 cc_cb[0x100] = { - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4, - 4, 4, 4, 4, 4, 4,11, 4, 4, 4, 4, 4, 4, 4,11, 4 -}; - -static const uint8_t cc_ed[0x100] = { - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 8, 8,11,16, 4,10, 4, 5, 8, 8,11,16, 4,10, 4, 5, - 8, 8,11,16, 4,10, 4, 5, 8, 8,11,16, 4,10, 4, 5, - 8, 8,11,16, 4,10, 4,14, 8, 8,11,16, 4,10, 4,14, - 8, 8,11,16, 4,10, 4, 4, 8, 8,11,16, 4,10, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 12,12,12,12,4, 4, 4, 4,12,12,12,12, 4, 4, 4, 4, - 12,12,12,12,4, 4, 4, 4,12,12,12,12, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -}; - -/* ix/iy: with the exception of (i+offset) opcodes, for total add t-states from main_opcode_table[DD/FD] == 4 */ -static const uint8_t cc_xy[0x100] = { - 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, - 8,10, 7, 6, 4, 4, 7, 4,12,11, 7, 6, 4, 4, 7, 4, - 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, - 7,10,13, 6,19,19,15, 4, 7,11,13, 6, 4, 4, 7, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 15,15,15,15,15,15, 4,15, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 4, 4, 4, 4, 4, 4,15, 4, 4, 4, 4, 4, 4, 4,15, 4, - 5,10,10,10,10,11, 7,11, 5,10,10, 7,10,17, 7,11, /* cb -> cc_xycb */ - 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 4, 7,11, /* dd -> cc_xy again */ - 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 4, 7,11, /* ed -> cc_ed */ - 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 4, 7,11 /* fd -> cc_xy again */ -}; - -static const uint8_t cc_xycb[0x100] = { - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12 -}; - -/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */ -static const uint8_t cc_ex[0x100] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */ - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */ - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */ - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2 -}; - -#define m_cc_dd m_cc_xy -#define m_cc_fd m_cc_xy +static u8 SZ[256]; // zero and sign flags +static u8 SZ_BIT[256]; // zero, sign and parity/overflow (=zero) flags for BIT opcode +static u8 SZP[256]; // zero, sign and parity flags +static u8 SZHV_inc[256]; // zero, sign, half carry and overflow flags INC r8 +static u8 SZHV_dec[256]; // zero, sign, half carry and overflow flags DEC r8 + +static u8 SZHVC_add[2*256*256]; +static u8 SZHVC_sub[2*256*256]; + /*************************************************************** * define an opcode function @@ -332,19 +211,10 @@ static const uint8_t cc_ex[0x100] = { /*************************************************************** * adjust cycle count by n T-states ***************************************************************/ -#define CC(prefix,opcode) do { m_icount_executing += m_cc_##prefix == nullptr ? 0 : m_cc_##prefix[opcode]; } while (0) - -#define T(icount) do { \ - m_icount -= icount; \ - m_icount_executing -= icount; \ -} while (0) - -// T Memory Address -#define MTM (m_mtm_cycles) +#define T(icount) execute_cycles(icount) #define EXEC(prefix,opcode) do { \ unsigned op = opcode; \ - CC(prefix,op); \ switch(op) \ { \ case 0x00:prefix##_##00();break; case 0x01:prefix##_##01();break; case 0x02:prefix##_##02();break; case 0x03:prefix##_##03();break; \ @@ -412,7 +282,6 @@ static const uint8_t cc_ex[0x100] = { case 0xf8:prefix##_##f8();break; case 0xf9:prefix##_##f9();break; case 0xfa:prefix##_##fa();break; case 0xfb:prefix##_##fb();break; \ case 0xfc:prefix##_##fc();break; case 0xfd:prefix##_##fd();break; case 0xfe:prefix##_##fe();break; case 0xff:prefix##_##ff();break; \ } \ - if(m_icount_executing > 0) T(m_icount_executing); else m_icount_executing = 0; \ } while (0) /*************************************************************** @@ -442,33 +311,38 @@ inline void z80_device::leave_halt() /*************************************************************** * Input a byte from given I/O port ***************************************************************/ -inline uint8_t z80_device::in(uint16_t port) +inline u8 z80_device::in(u16 port) { u8 res = m_io.read_byte(port); - T(4); + T(m_iorq_cycles); return res; } /*************************************************************** * Output a byte to given I/O port ***************************************************************/ -inline void z80_device::out(uint16_t port, uint8_t value) +inline void z80_device::out(u16 port, u8 value) { m_io.write_byte(port, value); - T(4); + T(m_iorq_cycles); } /*************************************************************** * Read a byte from given memory location ***************************************************************/ -uint8_t z80_device::rm(uint16_t addr) +inline u8 z80_device::data_read(u16 addr) +{ + return m_data.read_byte(translate_memory_address(addr)); +} + +u8 z80_device::rm(u16 addr) { - u8 res = m_data.read_byte(translate_memory_address(addr)); - T(MTM); + u8 res = data_read(addr); + T(m_memrq_cycles); return res; } -uint8_t z80_device::rm_reg(uint16_t addr) +u8 z80_device::rm_reg(u16 addr) { u8 res = rm(addr); nomreq_addr(addr, 1); @@ -478,43 +352,45 @@ uint8_t z80_device::rm_reg(uint16_t addr) /*************************************************************** * Read a word from given memory location ***************************************************************/ -inline void z80_device::rm16(uint16_t addr, PAIR &r) +inline void z80_device::rm16(u16 addr, PAIR &r) { - r.b.l = rm(addr); - r.b.h = rm(addr+1); + r.b.l = data_read(addr); + T(m_memrq_cycles); + r.b.h = data_read(addr + 1); + T(m_memrq_cycles); } /*************************************************************** * Write a byte to given memory location ***************************************************************/ -void z80_device::wm(uint16_t addr, uint8_t value) +inline void z80_device::data_write(u16 addr, u8 value) { - // As we don't count changes between read and write, simply adjust to the end of requested. - if(m_icount_executing != MTM) T(m_icount_executing - MTM); - m_data.write_byte(translate_memory_address(addr), value); - T(MTM); + m_data.write_byte(translate_memory_address((u32)addr), value); +} + +inline void z80_device::wm(u16 addr, u8 value) +{ + data_write(addr, value); + T(m_memrq_cycles); } /*************************************************************** * Write a word to given memory location ***************************************************************/ -inline void z80_device::wm16(uint16_t addr, PAIR &r) +inline void z80_device::wm16(u16 addr, PAIR &r) { - m_icount_executing -= MTM; wm(addr, r.b.l); - m_icount_executing += MTM; - wm(addr+1, r.b.h); + wm(addr + 1, r.b.h); } /*************************************************************** * Write a word to (SP) + * in: TDAT ***************************************************************/ inline void z80_device::wm16_sp(PAIR &r) { SP--; - m_icount_executing -= MTM; wm(SPD, r.b.h); - m_icount_executing += MTM; SP--; wm(SPD, r.b.l); } @@ -524,16 +400,21 @@ inline void z80_device::wm16_sp(PAIR &r) * reading opcodes. In case of system with memory mapped I/O, * this function can be used to greatly speed up emulation ***************************************************************/ -uint8_t z80_device::rop() +inline u8 z80_device::opcode_read() +{ + return m_opcodes.read_byte(translate_memory_address(PCD)); +} + +u8 z80_device::rop() { - // Use leftovers from previous instruction. Mainly to support recursive EXEC(.., rop()) - if(m_icount_executing) T(m_icount_executing); - uint8_t res = m_opcodes.read_byte(translate_memory_address(PCD)); - T(execute_min_cycles()); + u8 res = m_opcodes.read_byte(translate_memory_address(PCD)); + T(m_m1_cycles - 2); m_refresh_cb((m_i << 8) | (m_r2 & 0x80) | (m_r & 0x7f), 0x00, 0xff); - T(execute_min_cycles()); + T(2); PC++; m_r++; + Q = m_qtemp; + m_qtemp = YF | XF; return res; } @@ -543,17 +424,23 @@ uint8_t z80_device::rop() * for reading opcode arguments. This difference can be used to * support systems that use different encoding mechanisms for * opcodes and opcode arguments + * out: TDAT8 ***************************************************************/ -uint8_t z80_device::arg() +inline u8 z80_device::arg_read() { - u8 res = m_args.read_byte(translate_memory_address(PCD)); - T(MTM); + return m_args.read_byte(translate_memory_address(PCD)); +} + +u8 z80_device::arg() +{ + u8 res = arg_read(); + T(m_memrq_cycles); PC++; return res; } -uint16_t z80_device::arg16() +u16 z80_device::arg16() { u8 const res = arg(); @@ -566,13 +453,13 @@ uint16_t z80_device::arg16() ***************************************************************/ inline void z80_device::eax() { - m_ea = (uint32_t)(uint16_t)(IX + (int8_t)arg()); + m_ea = (u32)(u16)(IX + (s8)arg()); WZ = m_ea; } inline void z80_device::eay() { - m_ea = (uint32_t)(uint16_t)(IY + (int8_t)arg()); + m_ea = (u32)(u16)(IY + (s8)arg()); WZ = m_ea; } @@ -614,7 +501,7 @@ inline void z80_device::jp_cond(bool cond) WZ = PCD; } else - WZ = arg16(); /* implicit do PC += 2 */ + WZ = arg16(); // implicit do PC += 2 } /*************************************************************** @@ -622,27 +509,26 @@ inline void z80_device::jp_cond(bool cond) ***************************************************************/ inline void z80_device::jr() { - int8_t a = (int8_t)arg(); /* arg() also increments PC */ - nomreq_addr(PCD-1, 5); - PC += a; /* so don't do PC += arg() */ + s8 a = (s8)arg(); // arg() also increments PC + nomreq_addr(PCD - 1, 5); + PC += a; // so don't do PC += arg() WZ = PC; } /*************************************************************** * JR_COND ***************************************************************/ -inline void z80_device::jr_cond(bool cond, uint8_t opcode) +inline void z80_device::jr_cond(bool cond, u8 opcode) { if (cond) { - CC(ex, opcode); jr(); } else { arg(); - //nomreq_addr(PCD, 3); - //PC++; + // nomreq_addr(PCD, 3); + // PC++; } } @@ -652,7 +538,7 @@ inline void z80_device::jr_cond(bool cond, uint8_t opcode) inline void z80_device::call() { m_ea = arg16(); - nomreq_addr(PCD-1, 1); + nomreq_addr(PCD - 1, 1); WZ = m_ea; wm16_sp(m_pc); PCD = m_ea; @@ -661,30 +547,28 @@ inline void z80_device::call() /*************************************************************** * CALL_COND ***************************************************************/ -inline void z80_device::call_cond(bool cond, uint8_t opcode) +inline void z80_device::call_cond(bool cond, u8 opcode) { if (cond) { - CC(ex, opcode); m_ea = arg16(); - nomreq_addr(PCD-1, 1); + nomreq_addr(PCD - 1, 1); WZ = m_ea; wm16_sp(m_pc); PCD = m_ea; } else - WZ = arg16(); /* implicit call PC+=2; */ + WZ = arg16(); // implicit call PC+=2; } /*************************************************************** * RET_COND ***************************************************************/ -inline void z80_device::ret_cond(bool cond, uint8_t opcode) +inline void z80_device::ret_cond(bool cond, u8 opcode) { nomreq_ir(1); if (cond) { - CC(ex, opcode); pop(m_pc); WZ = PC; } @@ -695,7 +579,7 @@ inline void z80_device::ret_cond(bool cond, uint8_t opcode) ***************************************************************/ inline void z80_device::retn() { - LOG(("Z80 RETN m_iff1:%d m_iff2:%d\n", m_iff1, m_iff2)); + LOGINT("RETN m_iff1:%d m_iff2:%d\n", m_iff1, m_iff2); pop(m_pc); WZ = PC; m_iff1 = m_iff2; @@ -719,7 +603,7 @@ inline void z80_device::ld_r_a() { nomreq_ir(1); m_r = A; - m_r2 = A & 0x80; /* keep bit 7 of r */ + m_r2 = A & 0x80; // keep bit 7 of r } /*************************************************************** @@ -729,7 +613,7 @@ inline void z80_device::ld_a_r() { nomreq_ir(1); A = (m_r & 0x7f) | m_r2; - F = (F & CF) | SZ[A] | (m_iff2 << 2); + set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; } @@ -749,16 +633,15 @@ inline void z80_device::ld_a_i() { nomreq_ir(1); A = m_i; - F = (F & CF) | SZ[A] | (m_iff2 << 2); + set_f((F & CF) | SZ[A] | (m_iff2 << 2)); m_after_ldair = true; } /*************************************************************** * RST ***************************************************************/ -inline void z80_device::rst(uint16_t addr) +inline void z80_device::rst(u16 addr) { - //nomreq_ir(1); push(m_pc); PCD = addr; WZ = PC; @@ -767,20 +650,20 @@ inline void z80_device::rst(uint16_t addr) /*************************************************************** * INC r8 ***************************************************************/ -inline uint8_t z80_device::inc(uint8_t value) +inline u8 z80_device::inc(u8 value) { - uint8_t res = value + 1; - F = (F & CF) | SZHV_inc[res]; - return (uint8_t)res; + u8 res = value + 1; + set_f((F & CF) | SZHV_inc[res]); + return (u8)res; } /*************************************************************** * DEC r8 ***************************************************************/ -inline uint8_t z80_device::dec(uint8_t value) +inline u8 z80_device::dec(u8 value) { - uint8_t res = value - 1; - F = (F & CF) | SZHV_dec[res]; + u8 res = value - 1; + set_f((F & CF) | SZHV_dec[res]); return res; } @@ -790,7 +673,7 @@ inline uint8_t z80_device::dec(uint8_t value) inline void z80_device::rlca() { A = (A << 1) | (A >> 7); - F = (F & (SF | ZF | PF)) | (A & (YF | XF | CF)); + set_f((F & (SF | ZF | PF)) | (A & (YF | XF | CF))); } /*************************************************************** @@ -798,7 +681,7 @@ inline void z80_device::rlca() ***************************************************************/ inline void z80_device::rrca() { - F = (F & (SF | ZF | PF)) | (A & CF); + set_f((F & (SF | ZF | PF)) | (A & CF)); A = (A >> 1) | (A << 7); F |= (A & (YF | XF)); } @@ -808,9 +691,9 @@ inline void z80_device::rrca() ***************************************************************/ inline void z80_device::rla() { - uint8_t res = (A << 1) | (F & CF); - uint8_t c = (A & 0x80) ? CF : 0; - F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); + u8 res = (A << 1) | (F & CF); + u8 c = (A & 0x80) ? CF : 0; + set_f((F & (SF | ZF | PF)) | c | (res & (YF | XF))); A = res; } @@ -819,9 +702,9 @@ inline void z80_device::rla() ***************************************************************/ inline void z80_device::rra() { - uint8_t res = (A >> 1) | (F << 7); - uint8_t c = (A & 0x01) ? CF : 0; - F = (F & (SF | ZF | PF)) | c | (res & (YF | XF)); + u8 res = (A >> 1) | (F << 7); + u8 c = (A & 0x01) ? CF : 0; + set_f((F & (SF | ZF | PF)) | c | (res & (YF | XF))); A = res; } @@ -830,12 +713,12 @@ inline void z80_device::rra() ***************************************************************/ inline void z80_device::rrd() { - uint8_t n = rm(HL); - WZ = HL+1; + u8 n = rm(HL); + WZ = HL + 1; nomreq_addr(HL, 4); wm(HL, (n >> 4) | (A << 4)); A = (A & 0xf0) | (n & 0x0f); - F = (F & CF) | SZP[A]; + set_f((F & CF) | SZP[A]); } /*************************************************************** @@ -843,55 +726,55 @@ inline void z80_device::rrd() ***************************************************************/ inline void z80_device::rld() { - uint8_t n = rm(HL); - WZ = HL+1; + u8 n = rm(HL); + WZ = HL + 1; nomreq_addr(HL, 4); wm(HL, (n << 4) | (A & 0x0f)); A = (A & 0xf0) | (n >> 4); - F = (F & CF) | SZP[A]; + set_f((F & CF) | SZP[A]); } /*************************************************************** * ADD A,n ***************************************************************/ -inline void z80_device::add_a(uint8_t value) +inline void z80_device::add_a(u8 value) { - uint32_t ah = AFD & 0xff00; - uint32_t res = (uint8_t)((ah >> 8) + value); - F = SZHVC_add[ah | res]; + u32 ah = AFD & 0xff00; + u32 res = (u8)((ah >> 8) + value); + set_f(SZHVC_add[ah | res]); A = res; } /*************************************************************** * ADC A,n ***************************************************************/ -inline void z80_device::adc_a(uint8_t value) +inline void z80_device::adc_a(u8 value) { - uint32_t ah = AFD & 0xff00, c = AFD & 1; - uint32_t res = (uint8_t)((ah >> 8) + value + c); - F = SZHVC_add[(c << 16) | ah | res]; + u32 ah = AFD & 0xff00, c = AFD & 1; + u32 res = (u8)((ah >> 8) + value + c); + set_f(SZHVC_add[(c << 16) | ah | res]); A = res; } /*************************************************************** * SUB n ***************************************************************/ -inline void z80_device::sub(uint8_t value) +inline void z80_device::sub(u8 value) { - uint32_t ah = AFD & 0xff00; - uint32_t res = (uint8_t)((ah >> 8) - value); - F = SZHVC_sub[ah | res]; + u32 ah = AFD & 0xff00; + u32 res = (u8)((ah >> 8) - value); + set_f(SZHVC_sub[ah | res]); A = res; } /*************************************************************** * SBC A,n ***************************************************************/ -inline void z80_device::sbc_a(uint8_t value) +inline void z80_device::sbc_a(u8 value) { - uint32_t ah = AFD & 0xff00, c = AFD & 1; - uint32_t res = (uint8_t)((ah >> 8) - value - c); - F = SZHVC_sub[(c<<16) | ah | res]; + u32 ah = AFD & 0xff00, c = AFD & 1; + u32 res = (u8)((ah >> 8) - value - c); + set_f(SZHVC_sub[(c << 16) | ah | res]); A = res; } @@ -900,7 +783,7 @@ inline void z80_device::sbc_a(uint8_t value) ***************************************************************/ inline void z80_device::neg() { - uint8_t value = A; + u8 value = A; A = 0; sub(value); } @@ -910,77 +793,62 @@ inline void z80_device::neg() ***************************************************************/ inline void z80_device::daa() { - uint8_t a = A; + u8 a = A; if (F & NF) { - if ((F&HF) | ((A&0xf)>9)) a-=6; - if ((F&CF) | (A>0x99)) a-=0x60; + if ((F & HF) | ((A & 0xf) > 9)) + a -= 6; + if ((F & CF) | (A > 0x99)) + a -= 0x60; } else { - if ((F&HF) | ((A&0xf)>9)) a+=6; - if ((F&CF) | (A>0x99)) a+=0x60; + if ((F & HF) | ((A & 0xf) > 9)) + a += 6; + if ((F & CF) | (A > 0x99)) + a += 0x60; } - F = (F&(CF|NF)) | (A>0x99) | ((A^a)&HF) | SZP[a]; + set_f((F & (CF | NF)) | (A > 0x99) | ((A ^ a) & HF) | SZP[a]); A = a; } /*************************************************************** * AND n ***************************************************************/ -inline void z80_device::and_a(uint8_t value) +inline void z80_device::and_a(u8 value) { A &= value; - F = SZP[A] | HF; + set_f(SZP[A] | HF); } /*************************************************************** * OR n ***************************************************************/ -inline void z80_device::or_a(uint8_t value) +inline void z80_device::or_a(u8 value) { A |= value; - F = SZP[A]; + set_f(SZP[A]); } /*************************************************************** * XOR n ***************************************************************/ -inline void z80_device::xor_a(uint8_t value) +inline void z80_device::xor_a(u8 value) { A ^= value; - F = SZP[A]; + set_f(SZP[A]); } /*************************************************************** * CP n ***************************************************************/ -inline void z80_device::cp(uint8_t value) +inline void z80_device::cp(u8 value) { unsigned val = value; - uint32_t ah = AFD & 0xff00; - uint32_t res = (uint8_t)((ah >> 8) - val); - F = (SZHVC_sub[ah | res] & ~(YF | XF)) | - (val & (YF | XF)); -} - -/*************************************************************** - * EX AF,AF' - ***************************************************************/ -inline void z80_device::ex_af() -{ - PAIR tmp; - tmp = m_af; m_af = m_af2; m_af2 = tmp; -} - -/*************************************************************** - * EX DE,HL - ***************************************************************/ -inline void z80_device::ex_de_hl() -{ - PAIR tmp; - tmp = m_de; m_de = m_hl; m_hl = tmp; + u32 ah = AFD & 0xff00; + u32 res = (u8)((ah >> 8) - val); + set_f((SZHVC_sub[ah | res] & ~(YF | XF)) | (val & (YF | XF))); } /*************************************************************** @@ -988,23 +856,22 @@ inline void z80_device::ex_de_hl() ***************************************************************/ inline void z80_device::exx() { - PAIR tmp; - tmp = m_bc; m_bc = m_bc2; m_bc2 = tmp; - tmp = m_de; m_de = m_de2; m_de2 = tmp; - tmp = m_hl; m_hl = m_hl2; m_hl2 = tmp; + using std::swap; + swap(m_bc, m_bc2); + swap(m_de, m_de2); + swap(m_hl, m_hl2); } /*************************************************************** * EX (SP),r16 + * in: TDAT ***************************************************************/ inline void z80_device::ex_sp(PAIR &r) { - PAIR tmp = { { 0, 0, 0, 0 } }; + PAIR tmp = {{0, 0, 0, 0}}; pop(tmp); nomreq_addr(SPD - 1, 1); - m_icount_executing -= 2; wm16_sp(r); - m_icount_executing += 2; nomreq_addr(SPD, 2); r = tmp; WZ = r.d; @@ -1016,12 +883,12 @@ inline void z80_device::ex_sp(PAIR &r) inline void z80_device::add16(PAIR &dr, PAIR &sr) { nomreq_ir(7); - uint32_t res = dr.d + sr.d; + u32 res = dr.d + sr.d; WZ = dr.d + 1; - F = (F & (SF | ZF | VF)) | - (((dr.d ^ res ^ sr.d) >> 8) & HF) | - ((res >> 16) & CF) | ((res >> 8) & (YF | XF)); - dr.w.l = (uint16_t)res; + set_f((F & (SF | ZF | VF)) | + (((dr.d ^ res ^ sr.d) >> 8) & HF) | + ((res >> 16) & CF) | ((res >> 8) & (YF | XF))); + dr.w.l = (u16)res; } /*************************************************************** @@ -1030,14 +897,14 @@ inline void z80_device::add16(PAIR &dr, PAIR &sr) inline void z80_device::adc_hl(PAIR &r) { nomreq_ir(7); - uint32_t res = HLD + r.d + (F & CF); + u32 res = HLD + r.d + (F & CF); WZ = HL + 1; - F = (((HLD ^ res ^ r.d) >> 8) & HF) | - ((res >> 16) & CF) | - ((res >> 8) & (SF | YF | XF)) | - ((res & 0xffff) ? 0 : ZF) | - (((r.d ^ HLD ^ 0x8000) & (r.d ^ res) & 0x8000) >> 13); - HL = (uint16_t)res; + set_f((((HLD ^ res ^ r.d) >> 8) & HF) | + ((res >> 16) & CF) | + ((res >> 8) & (SF | YF | XF)) | + ((res & 0xffff) ? 0 : ZF) | + (((r.d ^ HLD ^ 0x8000) & (r.d ^ res) & 0x8000) >> 13)); + HL = (u16)res; } /*************************************************************** @@ -1046,150 +913,150 @@ inline void z80_device::adc_hl(PAIR &r) inline void z80_device::sbc_hl(PAIR &r) { nomreq_ir(7); - uint32_t res = HLD - r.d - (F & CF); + u32 res = HLD - r.d - (F & CF); WZ = HL + 1; - F = (((HLD ^ res ^ r.d) >> 8) & HF) | NF | - ((res >> 16) & CF) | - ((res >> 8) & (SF | YF | XF)) | - ((res & 0xffff) ? 0 : ZF) | - (((r.d ^ HLD) & (HLD ^ res) &0x8000) >> 13); - HL = (uint16_t)res; + set_f((((HLD ^ res ^ r.d) >> 8) & HF) | NF | + ((res >> 16) & CF) | + ((res >> 8) & (SF | YF | XF)) | + ((res & 0xffff) ? 0 : ZF) | + (((r.d ^ HLD) & (HLD ^ res) & 0x8000) >> 13)); + HL = (u16)res; } /*************************************************************** * RLC r8 ***************************************************************/ -inline uint8_t z80_device::rlc(uint8_t value) +inline u8 z80_device::rlc(u8 value) { unsigned res = value; unsigned c = (res & 0x80) ? CF : 0; res = ((res << 1) | (res >> 7)) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * RRC r8 ***************************************************************/ -inline uint8_t z80_device::rrc(uint8_t value) +inline u8 z80_device::rrc(u8 value) { unsigned res = value; unsigned c = (res & 0x01) ? CF : 0; res = ((res >> 1) | (res << 7)) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * RL r8 ***************************************************************/ -inline uint8_t z80_device::rl(uint8_t value) +inline u8 z80_device::rl(u8 value) { unsigned res = value; unsigned c = (res & 0x80) ? CF : 0; res = ((res << 1) | (F & CF)) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * RR r8 ***************************************************************/ -inline uint8_t z80_device::rr(uint8_t value) +inline u8 z80_device::rr(u8 value) { unsigned res = value; unsigned c = (res & 0x01) ? CF : 0; res = ((res >> 1) | (F << 7)) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * SLA r8 ***************************************************************/ -inline uint8_t z80_device::sla(uint8_t value) +inline u8 z80_device::sla(u8 value) { unsigned res = value; unsigned c = (res & 0x80) ? CF : 0; res = (res << 1) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * SRA r8 ***************************************************************/ -inline uint8_t z80_device::sra(uint8_t value) +inline u8 z80_device::sra(u8 value) { unsigned res = value; unsigned c = (res & 0x01) ? CF : 0; res = ((res >> 1) | (res & 0x80)) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * SLL r8 ***************************************************************/ -inline uint8_t z80_device::sll(uint8_t value) +inline u8 z80_device::sll(u8 value) { unsigned res = value; unsigned c = (res & 0x80) ? CF : 0; res = ((res << 1) | 0x01) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * SRL r8 ***************************************************************/ -inline uint8_t z80_device::srl(uint8_t value) +inline u8 z80_device::srl(u8 value) { unsigned res = value; unsigned c = (res & 0x01) ? CF : 0; res = (res >> 1) & 0xff; - F = SZP[res] | c; + set_f(SZP[res] | c); return res; } /*************************************************************** * BIT bit,r8 ***************************************************************/ -inline void z80_device::bit(int bit, uint8_t value) +inline void z80_device::bit(int bit, u8 value) { - F = (F & CF) | HF | (SZ_BIT[value & (1<>8) & (YF|XF)); + set_f((F & CF) | HF | (SZ_BIT[value & (1 << bit)] & ~(YF | XF)) | ((m_ea >> 8) & (YF | XF))); } /*************************************************************** * RES bit,r8 ***************************************************************/ -inline uint8_t z80_device::res(int bit, uint8_t value) +inline u8 z80_device::res(int bit, u8 value) { - return value & ~(1< flag 5 */ - if ((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ - HL++; DE++; BC--; - if(BC) F |= VF; + set_f(F & (SF | ZF | CF)); + if ((A + io) & 0x02) + F |= YF; // bit 1 -> flag 5 + if ((A + io) & 0x08) + F |= XF; // bit 3 -> flag 3 + HL++; + DE++; + BC--; + if (BC) + F |= VF; } /*************************************************************** @@ -1214,54 +1084,65 @@ inline void z80_device::ldi() ***************************************************************/ inline void z80_device::cpi() { - uint8_t val = rm(HL); + u8 val = rm(HL); nomreq_addr(HL, 5); - uint8_t res = A - val; + u8 res = A - val; WZ++; - HL++; BC--; - F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF; - if (F & HF) res -= 1; - if (res & 0x02) F |= YF; /* bit 1 -> flag 5 */ - if (res & 0x08) F |= XF; /* bit 3 -> flag 3 */ - if (BC) F |= VF; + HL++; + BC--; + set_f((F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF); + if (F & HF) + res -= 1; + if (res & 0x02) + F |= YF; // bit 1 -> flag 5 + if (res & 0x08) + F |= XF; // bit 3 -> flag 3 + if (BC) + F |= VF; } /*************************************************************** * INI ***************************************************************/ -inline void z80_device::ini() +inline u8 z80_device::ini() { nomreq_ir(1); - unsigned t; - uint8_t io = in(BC); + const u8 io = in(BC); WZ = BC + 1; B--; wm(HL, io); HL++; - F = SZ[B]; - t = (unsigned)((C + 1) & 0xff) + (unsigned)io; - if (io & SF) F |= NF; - if (t & 0x100) F |= HF | CF; - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; + set_f(SZ[B]); + unsigned t = (unsigned)((C + 1) & 0xff) + (unsigned)io; + if (io & SF) + F |= NF; + if (t & 0x100) + F |= HF | CF; + F |= SZP[(u8)(t & 0x07) ^ B] & PF; + + return io; } /*************************************************************** * OUTI ***************************************************************/ -inline void z80_device::outi() +inline u8 z80_device::outi() { nomreq_ir(1); - unsigned t; - uint8_t io = rm(HL); + const u8 io = rm(HL); B--; WZ = BC + 1; out(BC, io); HL++; - F = SZ[B]; - t = (unsigned)L + (unsigned)io; - if (io & SF) F |= NF; - if (t & 0x100) F |= HF | CF; - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; + set_f(SZ[B]); + unsigned t = (unsigned)L + (unsigned)io; + if (io & SF) + F |= NF; + if (t & 0x100) + F |= HF | CF; + F |= SZP[(u8)(t & 0x07) ^ B] & PF; + + return io; } /*************************************************************** @@ -1269,16 +1150,19 @@ inline void z80_device::outi() ***************************************************************/ inline void z80_device::ldd() { - uint8_t io = rm(HL); - m_icount_executing -= 2; + const u8 io = rm(HL); wm(DE, io); - m_icount_executing += 2; nomreq_addr(DE, 2); - F &= SF | ZF | CF; - if ((A + io) & 0x02) F |= YF; /* bit 1 -> flag 5 */ - if ((A + io) & 0x08) F |= XF; /* bit 3 -> flag 3 */ - HL--; DE--; BC--; - if (BC) F |= VF; + set_f(F & (SF | ZF | CF)); + if ((A + io) & 0x02) + F |= YF; // bit 1 -> flag 5 + if ((A + io) & 0x08) + F |= XF; // bit 3 -> flag 3 + HL--; + DE--; + BC--; + if (BC) + F |= VF; } /*************************************************************** @@ -1286,54 +1170,65 @@ inline void z80_device::ldd() ***************************************************************/ inline void z80_device::cpd() { - uint8_t val = rm(HL); + u8 val = rm(HL); nomreq_addr(HL, 5); - uint8_t res = A - val; + u8 res = A - val; WZ--; - HL--; BC--; - F = (F & CF) | (SZ[res]&~(YF|XF)) | ((A^val^res)&HF) | NF; - if (F & HF) res -= 1; - if (res & 0x02) F |= YF; /* bit 1 -> flag 5 */ - if (res & 0x08) F |= XF; /* bit 3 -> flag 3 */ - if (BC) F |= VF; + HL--; + BC--; + set_f((F & CF) | (SZ[res] & ~(YF | XF)) | ((A ^ val ^ res) & HF) | NF); + if (F & HF) + res -= 1; + if (res & 0x02) + F |= YF; // bit 1 -> flag 5 + if (res & 0x08) + F |= XF; // bit 3 -> flag 3 + if (BC) + F |= VF; } /*************************************************************** * IND ***************************************************************/ -inline void z80_device::ind() +inline u8 z80_device::ind() { nomreq_ir(1); - unsigned t; - uint8_t io = in(BC); + const u8 io = in(BC); WZ = BC - 1; B--; wm(HL, io); HL--; - F = SZ[B]; - t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; - if (io & SF) F |= NF; - if (t & 0x100) F |= HF | CF; - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; + set_f(SZ[B]); + unsigned t = ((unsigned)(C - 1) & 0xff) + (unsigned)io; + if (io & SF) + F |= NF; + if (t & 0x100) + F |= HF | CF; + F |= SZP[(u8)(t & 0x07) ^ B] & PF; + + return io; } /*************************************************************** * OUTD ***************************************************************/ -inline void z80_device::outd() +inline u8 z80_device::outd() { nomreq_ir(1); - unsigned t; - uint8_t io = rm(HL); + const u8 io = rm(HL); B--; WZ = BC - 1; out(BC, io); HL--; - F = SZ[B]; - t = (unsigned)L + (unsigned)io; - if (io & SF) F |= NF; - if (t & 0x100) F |= HF | CF; - F |= SZP[(uint8_t)(t & 0x07) ^ B] & PF; + set_f(SZ[B]); + unsigned t = (unsigned)L + (unsigned)io; + if (io & SF) + F |= NF; + if (t & 0x100) + F |= HF | CF; + F |= SZP[(u8)(t & 0x07) ^ B] & PF; + + return io; } /*************************************************************** @@ -1344,10 +1239,11 @@ inline void z80_device::ldir() ldi(); if (BC != 0) { - CC(ex, 0xb0); nomreq_addr(DE, 5); PC -= 2; WZ = PC + 1; + F &= ~(YF | XF); + F |= (PC >> 8) & (YF | XF); } } @@ -1359,10 +1255,37 @@ inline void z80_device::cpir() cpi(); if (BC != 0 && !(F & ZF)) { - CC(ex, 0xb1); nomreq_addr(HL, 5); PC -= 2; WZ = PC + 1; + F &= ~(YF | XF); + F |= (PC >> 8) & (YF | XF); + } +} + +inline void z80_device::block_io_interrupted_flags(u8 data) +{ + F &= ~(YF | XF); + F |= (PC >> 8) & (YF | XF); + if (F & CF) + { + F &= ~HF; + if (data & 0x80) + { + F ^= (SZP[(B - 1) & 0x07] ^ PF) & PF; + if ((B & 0x0f) == 0x00) + F |= HF; + } + else + { + F ^= (SZP[(B + 1) & 0x07] ^ PF) & PF; + if ((B & 0x0f) == 0x0f) + F |= HF; + } + } + else + { + F ^= (SZP[B & 0x07] ^ PF) & PF; } } @@ -1371,12 +1294,12 @@ inline void z80_device::cpir() ***************************************************************/ inline void z80_device::inir() { - ini(); + const u8 data = ini(); if (B != 0) { - CC(ex, 0xb2); nomreq_addr(HL, 5); PC -= 2; + block_io_interrupted_flags(data); } } @@ -1385,12 +1308,12 @@ inline void z80_device::inir() ***************************************************************/ inline void z80_device::otir() { - outi(); + const u8 data = outi(); if (B != 0) { - CC(ex, 0xb3); nomreq_addr(BC, 5); PC -= 2; + block_io_interrupted_flags(data); } } @@ -1402,10 +1325,11 @@ inline void z80_device::lddr() ldd(); if (BC != 0) { - CC(ex, 0xb8); nomreq_addr(DE, 5); PC -= 2; WZ = PC + 1; + F &= ~(YF | XF); + F |= (PC >> 8) & (YF | XF); } } @@ -1417,10 +1341,11 @@ inline void z80_device::cpdr() cpd(); if (BC != 0 && !(F & ZF)) { - CC(ex, 0xb9); nomreq_addr(HL, 5); PC -= 2; WZ = PC + 1; + F &= ~(YF | XF); + F |= (PC >> 8) & (YF | XF); } } @@ -1429,12 +1354,12 @@ inline void z80_device::cpdr() ***************************************************************/ inline void z80_device::indr() { - ind(); + const u8 data = ind(); if (B != 0) { - CC(ex, 0xba); nomreq_addr(HL, 5); PC -= 2; + block_io_interrupted_flags(data); } } @@ -1443,12 +1368,12 @@ inline void z80_device::indr() ***************************************************************/ inline void z80_device::otdr() { - outd(); + const u8 data = outd(); if (B != 0) { - CC(ex, 0xbb); nomreq_addr(BC, 5); PC -= 2; + block_io_interrupted_flags(data); } } @@ -1461,6 +1386,24 @@ inline void z80_device::ei() m_after_ei = true; } +inline void z80_device::set_f(u8 f) +{ + m_qtemp = 0; + F = f; +} + +inline void z80_device::illegal_1() +{ + LOGUNDOC("ill. opcode $%02x $%02x ($%04x)\n", + m_opcodes.read_byte(translate_memory_address((PCD - 1) & 0xffff)), m_opcodes.read_byte(translate_memory_address(PCD)), PCD - 1); +} + +inline void z80_device::illegal_2() +{ + LOGUNDOC("ill. opcode $ed $%02x\n", + m_opcodes.read_byte(translate_memory_address((PCD - 1) & 0xffff))); +} + /********************************************************** * opcodes with CB prefix * rotate, shift and bit operations @@ -1489,7 +1432,7 @@ OP(cb,12) { D = rl(D); } /* RL D */ OP(cb,13) { E = rl(E); } /* RL E */ OP(cb,14) { H = rl(H); } /* RL H */ OP(cb,15) { L = rl(L); } /* RL L */ -OP(cb,16) { wm(HL, rl(rm_reg(HL))); } /* RL (HL) */ +OP(cb,16) { wm(HL, rl(rm_reg(HL))); } /* RL (HL) */ OP(cb,17) { A = rl(A); } /* RL A */ OP(cb,18) { B = rr(B); } /* RR B */ @@ -1498,7 +1441,7 @@ OP(cb,1a) { D = rr(D); } /* RR D */ OP(cb,1b) { E = rr(E); } /* RR E */ OP(cb,1c) { H = rr(H); } /* RR H */ OP(cb,1d) { L = rr(L); } /* RR L */ -OP(cb,1e) { wm(HL, rr(rm_reg(HL))); } /* RR (HL) */ +OP(cb,1e) { wm(HL, rr(rm_reg(HL))); } /* RR (HL) */ OP(cb,1f) { A = rr(A); } /* RR A */ OP(cb,20) { B = sla(B); } /* SLA B */ @@ -1543,7 +1486,7 @@ OP(cb,42) { bit(0, D); } /* BIT 0,D */ OP(cb,43) { bit(0, E); } /* BIT 0,E */ OP(cb,44) { bit(0, H); } /* BIT 0,H */ OP(cb,45) { bit(0, L); } /* BIT 0,L */ -OP(cb,46) { bit_hl(0, rm_reg(HL)); } /* BIT 0,(HL) */ +OP(cb,46) { bit_hl(0, rm_reg(HL)); } /* BIT 0,(HL) */ OP(cb,47) { bit(0, A); } /* BIT 0,A */ OP(cb,48) { bit(1, B); } /* BIT 1,B */ @@ -1552,7 +1495,7 @@ OP(cb,4a) { bit(1, D); } /* BIT 1,D */ OP(cb,4b) { bit(1, E); } /* BIT 1,E */ OP(cb,4c) { bit(1, H); } /* BIT 1,H */ OP(cb,4d) { bit(1, L); } /* BIT 1,L */ -OP(cb,4e) { bit_hl(1, rm_reg(HL)); } /* BIT 1,(HL) */ +OP(cb,4e) { bit_hl(1, rm_reg(HL)); } /* BIT 1,(HL) */ OP(cb,4f) { bit(1, A); } /* BIT 1,A */ OP(cb,50) { bit(2, B); } /* BIT 2,B */ @@ -1561,7 +1504,7 @@ OP(cb,52) { bit(2, D); } /* BIT 2,D */ OP(cb,53) { bit(2, E); } /* BIT 2,E */ OP(cb,54) { bit(2, H); } /* BIT 2,H */ OP(cb,55) { bit(2, L); } /* BIT 2,L */ -OP(cb,56) { bit_hl(2, rm_reg(HL)); } /* BIT 2,(HL) */ +OP(cb,56) { bit_hl(2, rm_reg(HL)); } /* BIT 2,(HL) */ OP(cb,57) { bit(2, A); } /* BIT 2,A */ OP(cb,58) { bit(3, B); } /* BIT 3,B */ @@ -1570,7 +1513,7 @@ OP(cb,5a) { bit(3, D); } /* BIT 3,D */ OP(cb,5b) { bit(3, E); } /* BIT 3,E */ OP(cb,5c) { bit(3, H); } /* BIT 3,H */ OP(cb,5d) { bit(3, L); } /* BIT 3,L */ -OP(cb,5e) { bit_hl(3, rm_reg(HL)); } /* BIT 3,(HL) */ +OP(cb,5e) { bit_hl(3, rm_reg(HL)); } /* BIT 3,(HL) */ OP(cb,5f) { bit(3, A); } /* BIT 3,A */ OP(cb,60) { bit(4, B); } /* BIT 4,B */ @@ -1579,7 +1522,7 @@ OP(cb,62) { bit(4, D); } /* BIT 4,D */ OP(cb,63) { bit(4, E); } /* BIT 4,E */ OP(cb,64) { bit(4, H); } /* BIT 4,H */ OP(cb,65) { bit(4, L); } /* BIT 4,L */ -OP(cb,66) { bit_hl(4, rm_reg(HL)); } /* BIT 4,(HL) */ +OP(cb,66) { bit_hl(4, rm_reg(HL)); } /* BIT 4,(HL) */ OP(cb,67) { bit(4, A); } /* BIT 4,A */ OP(cb,68) { bit(5, B); } /* BIT 5,B */ @@ -1588,7 +1531,7 @@ OP(cb,6a) { bit(5, D); } /* BIT 5,D */ OP(cb,6b) { bit(5, E); } /* BIT 5,E */ OP(cb,6c) { bit(5, H); } /* BIT 5,H */ OP(cb,6d) { bit(5, L); } /* BIT 5,L */ -OP(cb,6e) { bit_hl(5, rm_reg(HL)); } /* BIT 5,(HL) */ +OP(cb,6e) { bit_hl(5, rm_reg(HL)); } /* BIT 5,(HL) */ OP(cb,6f) { bit(5, A); } /* BIT 5,A */ OP(cb,70) { bit(6, B); } /* BIT 6,B */ @@ -1597,7 +1540,7 @@ OP(cb,72) { bit(6, D); } /* BIT 6,D */ OP(cb,73) { bit(6, E); } /* BIT 6,E */ OP(cb,74) { bit(6, H); } /* BIT 6,H */ OP(cb,75) { bit(6, L); } /* BIT 6,L */ -OP(cb,76) { bit_hl(6, rm_reg(HL)); } /* BIT 6,(HL) */ +OP(cb,76) { bit_hl(6, rm_reg(HL)); } /* BIT 6,(HL) */ OP(cb,77) { bit(6, A); } /* BIT 6,A */ OP(cb,78) { bit(7, B); } /* BIT 7,B */ @@ -1606,7 +1549,7 @@ OP(cb,7a) { bit(7, D); } /* BIT 7,D */ OP(cb,7b) { bit(7, E); } /* BIT 7,E */ OP(cb,7c) { bit(7, H); } /* BIT 7,H */ OP(cb,7d) { bit(7, L); } /* BIT 7,L */ -OP(cb,7e) { bit_hl(7, rm_reg(HL)); } /* BIT 7,(HL) */ +OP(cb,7e) { bit_hl(7, rm_reg(HL)); } /* BIT 7,(HL) */ OP(cb,7f) { bit(7, A); } /* BIT 7,A */ OP(cb,80) { B = res(0, B); } /* RES 0,B */ @@ -2046,10 +1989,6 @@ OP(xycb,fd) { L = set(7, rm_reg(m_ea)); wm(m_ea, L); } /* SET 7,L=(XY+o) */ OP(xycb,fe) { wm(m_ea, set(7, rm_reg(m_ea))); } /* SET 7,(XY+o) */ OP(xycb,ff) { A = set(7, rm_reg(m_ea)); wm(m_ea, A); } /* SET 7,A=(XY+o) */ -OP(illegal,1) { - logerror("Z80 ill. opcode $%02x $%02x ($%04x)\n", - m_opcodes.read_byte(translate_memory_address((PCD-1)&0xffff)), m_opcodes.read_byte(translate_memory_address(PCD)), PCD-1); -} /********************************************************** * IX register related opcodes (DD prefix) @@ -2114,7 +2053,7 @@ OP(dd,32) { illegal_1(); op_32(); } /* DB DD OP(dd,33) { illegal_1(); op_33(); } /* DB DD */ OP(dd,34) { eax(); nomreq_addr(PCD-1, 5); wm(m_ea, inc(rm_reg(m_ea))); } /* INC (IX+o) */ OP(dd,35) { eax(); nomreq_addr(PCD-1, 5); wm(m_ea, dec(rm_reg(m_ea))); } /* DEC (IX+o) */ -OP(dd,36) { eax(); u8 a = arg(); nomreq_addr(PCD-1, 2); wm(m_ea, a); } /* LD (IX+o),n */ +OP(dd,36) { eax(); u8 a = arg(); nomreq_addr(PCD-1, 2); wm(m_ea, a); } /* LD (IX+o),n */ OP(dd,37) { illegal_1(); op_37(); } /* DB DD */ OP(dd,38) { illegal_1(); op_38(); } /* DB DD */ @@ -2405,7 +2344,7 @@ OP(fd,32) { illegal_1(); op_32(); } /* DB FD OP(fd,33) { illegal_1(); op_33(); } /* DB FD */ OP(fd,34) { eay(); nomreq_addr(PCD-1, 5); wm(m_ea, inc(rm_reg(m_ea))); } /* INC (IY+o) */ OP(fd,35) { eay(); nomreq_addr(PCD-1, 5); wm(m_ea, dec(rm_reg(m_ea))); } /* DEC (IY+o) */ -OP(fd,36) { eay(); u8 a = arg(); nomreq_addr(PCD-1, 2); wm(m_ea, a); } /* LD (IY+o),n */ +OP(fd,36) { eay(); u8 a = arg(); nomreq_addr(PCD-1, 2); wm(m_ea, a); } /* LD (IY+o),n */ OP(fd,37) { illegal_1(); op_37(); } /* DB FD */ OP(fd,38) { illegal_1(); op_38(); } /* DB FD */ @@ -2633,11 +2572,6 @@ OP(fd,fd) { illegal_1(); op_fd(); } /* DB FD OP(fd,fe) { illegal_1(); op_fe(); } /* DB FD */ OP(fd,ff) { illegal_1(); op_ff(); } /* DB FD */ -OP(illegal,2) -{ - logerror("Z80 ill. opcode $ed $%02x\n", - m_opcodes.read_byte(translate_memory_address((PCD-1)&0xffff))); -} /********************************************************** * special opcodes (ED prefix) @@ -2714,7 +2648,7 @@ OP(ed,3d) { illegal_2(); } /* DB ED OP(ed,3e) { illegal_2(); } /* DB ED */ OP(ed,3f) { illegal_2(); } /* DB ED */ -OP(ed,40) { B = in(BC); F = (F & CF) | SZP[B]; WZ = BC + 1; } /* IN B,(C) */ +OP(ed,40) { B = in(BC); set_f((F & CF) | SZP[B]); WZ = BC + 1; } /* IN B,(C) */ OP(ed,41) { out(BC, B); WZ = BC + 1; } /* OUT (C),B */ OP(ed,42) { sbc_hl(m_bc); } /* SBC HL,BC */ OP(ed,43) { m_ea = arg16(); wm16(m_ea, m_bc); WZ = m_ea + 1; } /* LD (w),BC */ @@ -2723,7 +2657,7 @@ OP(ed,45) { retn(); } /* RETN OP(ed,46) { m_im = 0; } /* IM 0 */ OP(ed,47) { ld_i_a(); } /* LD i,A */ -OP(ed,48) { C = in(BC); F = (F & CF) | SZP[C]; WZ = BC + 1; } /* IN C,(C) */ +OP(ed,48) { C = in(BC); set_f((F & CF) | SZP[C]); WZ = BC + 1; } /* IN C,(C) */ OP(ed,49) { out(BC, C); WZ = BC + 1; } /* OUT (C),C */ OP(ed,4a) { adc_hl(m_bc); } /* ADC HL,BC */ OP(ed,4b) { m_ea = arg16(); rm16(m_ea, m_bc); WZ = m_ea + 1; } /* LD BC,(w) */ @@ -2732,7 +2666,7 @@ OP(ed,4d) { reti(); } /* RETI OP(ed,4e) { m_im = 0; } /* IM 0 */ OP(ed,4f) { ld_r_a(); } /* LD r,A */ -OP(ed,50) { D = in(BC); F = (F & CF) | SZP[D]; WZ = BC + 1; } /* IN D,(C) */ +OP(ed,50) { D = in(BC); set_f((F & CF) | SZP[D]); WZ = BC + 1; } /* IN D,(C) */ OP(ed,51) { out(BC, D); WZ = BC + 1; } /* OUT (C),D */ OP(ed,52) { sbc_hl(m_de); } /* SBC HL,DE */ OP(ed,53) { m_ea = arg16(); wm16(m_ea, m_de); WZ = m_ea + 1; } /* LD (w),DE */ @@ -2741,7 +2675,7 @@ OP(ed,55) { retn(); } /* RETN OP(ed,56) { m_im = 1; } /* IM 1 */ OP(ed,57) { ld_a_i(); } /* LD A,i */ -OP(ed,58) { E = in(BC); F = (F & CF) | SZP[E]; WZ = BC + 1; } /* IN E,(C) */ +OP(ed,58) { E = in(BC); set_f((F & CF) | SZP[E]); WZ = BC + 1; } /* IN E,(C) */ OP(ed,59) { out(BC, E); WZ = BC + 1; } /* OUT (C),E */ OP(ed,5a) { adc_hl(m_de); } /* ADC HL,DE */ OP(ed,5b) { m_ea = arg16(); rm16(m_ea, m_de); WZ = m_ea + 1; } /* LD DE,(w) */ @@ -2750,7 +2684,7 @@ OP(ed,5d) { reti(); } /* RETI OP(ed,5e) { m_im = 2; } /* IM 2 */ OP(ed,5f) { ld_a_r(); } /* LD A,r */ -OP(ed,60) { H = in(BC); F = (F & CF) | SZP[H]; WZ = BC + 1; } /* IN H,(C) */ +OP(ed,60) { H = in(BC); set_f((F & CF) | SZP[H]); WZ = BC + 1; } /* IN H,(C) */ OP(ed,61) { out(BC, H); WZ = BC + 1; } /* OUT (C),H */ OP(ed,62) { sbc_hl(m_hl); } /* SBC HL,HL */ OP(ed,63) { m_ea = arg16(); wm16(m_ea, m_hl); WZ = m_ea + 1; } /* LD (w),HL */ @@ -2759,7 +2693,7 @@ OP(ed,65) { retn(); } /* RETN OP(ed,66) { m_im = 0; } /* IM 0 */ OP(ed,67) { rrd(); } /* RRD (HL) */ -OP(ed,68) { L = in(BC); F = (F & CF) | SZP[L]; WZ = BC + 1; } /* IN L,(C) */ +OP(ed,68) { L = in(BC); set_f((F & CF) | SZP[L]); WZ = BC + 1; } /* IN L,(C) */ OP(ed,69) { out(BC, L); WZ = BC + 1; } /* OUT (C),L */ OP(ed,6a) { adc_hl(m_hl); } /* ADC HL,HL */ OP(ed,6b) { m_ea = arg16(); rm16(m_ea, m_hl); WZ = m_ea + 1; } /* LD HL,(w) */ @@ -2768,7 +2702,7 @@ OP(ed,6d) { reti(); } /* RETI OP(ed,6e) { m_im = 0; } /* IM 0 */ OP(ed,6f) { rld(); } /* RLD (HL) */ -OP(ed,70) { u8 res = in(BC); F = (F & CF) | SZP[res]; WZ = BC + 1; } /* IN 0,(C) */ +OP(ed,70) { u8 res = in(BC); set_f((F & CF) | SZP[res]); WZ = BC + 1; } /* IN 0,(C) */ OP(ed,71) { out(BC, 0); WZ = BC + 1; } /* OUT (C),0 */ OP(ed,72) { sbc_hl(m_sp); } /* SBC HL,SP */ OP(ed,73) { m_ea = arg16(); wm16(m_ea, m_sp); WZ = m_ea + 1; } /* LD (w),SP */ @@ -2777,7 +2711,7 @@ OP(ed,75) { retn(); } /* RETN OP(ed,76) { m_im = 1; } /* IM 1 */ OP(ed,77) { illegal_2(); } /* DB ED,77 */ -OP(ed,78) { A = in(BC); F = (F & CF) | SZP[A]; WZ = BC + 1; } /* IN A,(C) */ +OP(ed,78) { A = in(BC); set_f((F & CF) | SZP[A]); WZ = BC + 1; } /* IN A,(C) */ OP(ed,79) { out(BC, A); WZ = BC + 1; } /* OUT (C),A */ OP(ed,7a) { adc_hl(m_sp); } /* ADC HL,SP */ OP(ed,7b) { m_ea = arg16(); rm16(m_ea, m_sp); WZ = m_ea + 1; } /* LD SP,(w) */ @@ -2943,8 +2877,8 @@ OP(op,05) { B = dec(B); OP(op,06) { B = arg(); } /* LD B,n */ OP(op,07) { rlca(); } /* RLCA */ -OP(op,08) { ex_af(); } /* EX AF,AF' */ -OP(op,09) { add16(m_hl, m_bc); } /* ADD HL,BC */ +OP(op,08) { using std::swap; swap(m_af, m_af2); } /* EX AF,AF' */ +OP(op,09) { add16(m_hl, m_bc); } /* ADD HL,BC */ OP(op,0a) { A = rm(BC); WZ=BC+1; } /* LD A,(BC) */ OP(op,0b) { nomreq_ir(2); BC--; } /* DEC BC */ OP(op,0c) { C = inc(C); } /* INC C */ @@ -2962,7 +2896,7 @@ OP(op,16) { D = arg(); OP(op,17) { rla(); } /* RLA */ OP(op,18) { jr(); } /* JR o */ -OP(op,19) { add16(m_hl, m_de); } /* ADD HL,DE */ +OP(op,19) { add16(m_hl, m_de); } /* ADD HL,DE */ OP(op,1a) { A = rm(DE); WZ = DE + 1; } /* LD A,(DE) */ OP(op,1b) { nomreq_ir(2); DE--; } /* DEC DE */ OP(op,1c) { E = inc(E); } /* INC E */ @@ -2980,13 +2914,13 @@ OP(op,26) { H = arg(); OP(op,27) { daa(); } /* DAA */ OP(op,28) { jr_cond(F & ZF, 0x28); } /* JR Z,o */ -OP(op,29) { add16(m_hl, m_hl); } /* ADD HL,HL */ +OP(op,29) { add16(m_hl, m_hl); } /* ADD HL,HL */ OP(op,2a) { m_ea = arg16(); rm16(m_ea, m_hl); WZ = m_ea + 1; } /* LD HL,(w) */ OP(op,2b) { nomreq_ir(2); HL--; } /* DEC HL */ OP(op,2c) { L = inc(L); } /* INC L */ OP(op,2d) { L = dec(L); } /* DEC L */ OP(op,2e) { L = arg(); } /* LD L,n */ -OP(op,2f) { A ^= 0xff; F = (F & (SF | ZF | PF | CF)) | HF | NF | (A & (YF | XF)); } /* CPL */ +OP(op,2f) { A ^= 0xff; set_f((F & (SF | ZF | PF | CF)) | HF | NF | (A & (YF | XF))); } /* CPL */ OP(op,30) { jr_cond(!(F & CF), 0x30); } /* JR NC,o */ OP(op,31) { SP = arg16(); } /* LD SP,w */ @@ -2995,7 +2929,7 @@ OP(op,33) { nomreq_ir(2); SP++; OP(op,34) { wm(HL, inc(rm_reg(HL))); } /* INC (HL) */ OP(op,35) { wm(HL, dec(rm_reg(HL))); } /* DEC (HL) */ OP(op,36) { wm(HL, arg()); } /* LD (HL),n */ -OP(op,37) { F = (F & (SF | ZF | YF | XF | PF)) | CF | (A & (YF | XF)); } /* SCF */ +OP(op,37) { set_f((F & (SF | ZF | PF)) | CF | (((F & Q) | A) & (YF | XF))); } /* SCF */ OP(op,38) { jr_cond(F & CF, 0x38); } /* JR C,o */ OP(op,39) { add16(m_hl, m_sp); } /* ADD HL,SP */ @@ -3004,7 +2938,7 @@ OP(op,3b) { nomreq_ir(2); SP--; OP(op,3c) { A = inc(A); } /* INC A */ OP(op,3d) { A = dec(A); } /* DEC A */ OP(op,3e) { A = arg(); } /* LD A,n */ -OP(op,3f) { F = ((F&(SF|ZF|YF|XF|PF|CF))|((F&CF)<<4)|(A&(YF|XF)))^CF; } /* CCF */ +OP(op,3f) { set_f(((F & (SF | ZF | PF | CF)) ^ CF) | ((F & CF) << 4) | (((F & Q) | A) & (YF | XF))); } /* CCF */ OP(op,40) { } /* LD B,B */ OP(op,41) { B = C; } /* LD B,C */ @@ -3171,7 +3105,7 @@ OP(op,cf) { rst(0x08); OP(op,d0) { ret_cond(!(F & CF), 0xd0); } /* RET NC */ OP(op,d1) { pop(m_de); } /* POP DE */ OP(op,d2) { jp_cond(!(F & CF)); } /* JP NC,a */ -OP(op,d3) { unsigned n = arg() | (A << 8); out(n, A); WZ_L = ((n & 0xff) + 1) & 0xff; WZ_H = A; } /* OUT (n),A */ +OP(op,d3) { unsigned n = arg() | (A << 8); out(n, A); WZ_L = ((n & 0xff) + 1) & 0xff; WZ_H = A; } /* OUT (n),A */ OP(op,d4) { call_cond(!(F & CF), 0xd4); } /* CALL NC,a */ OP(op,d5) { push(m_de); } /* PUSH DE */ OP(op,d6) { sub(arg()); } /* SUB n */ @@ -3198,7 +3132,7 @@ OP(op,e7) { rst(0x20); OP(op,e8) { ret_cond(F & PF, 0xe8); } /* RET PE */ OP(op,e9) { PC = HL; } /* JP (HL) */ OP(op,ea) { jp_cond(F & PF); } /* JP PE,a */ -OP(op,eb) { ex_de_hl(); } /* EX DE,HL */ +OP(op,eb) { using std::swap; swap(DE, HL); } /* EX DE,HL */ OP(op,ec) { call_cond(F & PF, 0xec); } /* CALL PE,a */ OP(op,ed) { EXEC(ed, rop()); } /* **** ED xx */ OP(op,ee) { xor_a(arg()); } /* XOR n */ @@ -3225,22 +3159,21 @@ OP(op,ff) { rst(0x38); void z80_device::take_nmi() { - /* Check if processor was halted */ + // Check if processor was halted leave_halt(); #if HAS_LDAIR_QUIRK - /* reset parity flag after LD A,I or LD A,R */ + // reset parity flag after LD A,I or LD A,R if (m_after_ldair) F &= ~PF; #endif m_iff1 = 0; m_r++; - m_icount_executing = 11; - T(m_icount_executing - MTM * 2); + T(5); wm16_sp(m_pc); PCD = 0x0066; - WZ=PCD; + WZ = PCD; m_nmi_pending = false; } @@ -3260,91 +3193,81 @@ void z80_device::take_interrupt() // fetch the IRQ vector device_z80daisy_interface *intf = daisy_get_irq_device(); int irq_vector = (intf != nullptr) ? intf->z80daisy_irq_ack() : standard_irq_callback(0, m_pc.w.l); - LOG(("Z80 single int. irq_vector $%02x\n", irq_vector)); + LOGINT("single INT irq_vector $%02x\n", irq_vector); - /* 'interrupt latency' cycles */ - m_icount_executing = 0; - CC(ex, 0xff); // 2 - T(m_icount_executing); + // 'interrupt latency' cycles + T(2); - /* Interrupt mode 2. Call [i:databyte] */ - if( m_im == 2 ) + // Interrupt mode 2. Call [i:databyte] + if (m_im == 2) { // Zilog's datasheet claims that "the least-significant bit must be a zero." // However, experiments have confirmed that IM 2 vectors do not have to be // even, and all 8 bits will be used; even $FF is handled normally. - /* CALL opcode timing */ - CC(op, 0xcd); // 17+2=19 - T(m_icount_executing - MTM * 4); - m_icount_executing -= MTM * 2; // save for rm16 + // CALL opcode timing + T(5); wm16_sp(m_pc); - m_icount_executing += MTM * 2; irq_vector = (irq_vector & 0xff) | (m_i << 8); rm16(irq_vector, m_pc); - LOG(("Z80 IM2 [$%04x] = $%04x\n", irq_vector, PCD)); + LOGINT("IM2 [$%04x] = $%04x\n", irq_vector, PCD); } else - /* Interrupt mode 1. RST 38h */ - if( m_im == 1 ) - { - LOG(("Z80 '%s' IM1 $0038\n", tag())); - /* RST $38 */ - CC(op, 0xff); // 11+2=13 - T(m_icount_executing - MTM * 2); - wm16_sp(m_pc); - PCD = 0x0038; - } - else - { - /* Interrupt mode 0. We check for CALL and JP instructions, */ - /* if neither of these were found we assume a 1 byte opcode */ - /* was placed on the databus */ - LOG(("Z80 IM0 $%04x\n", irq_vector)); - - /* check for nop */ - if (irq_vector != 0x00) + // Interrupt mode 1. RST 38h + if (m_im == 1) { - switch (irq_vector & 0xff0000) + LOGINT("'%s' IM1 $0038\n", tag()); + // RST $38 + T(5); + wm16_sp(m_pc); + PCD = 0x0038; + } + else + { + /* Interrupt mode 0. We check for CALL and JP instructions, + if neither of these were found we assume a 1 byte opcode + was placed on the databus */ + LOGINT("IM0 $%04x\n", irq_vector); + + // check for nop + if (irq_vector != 0x00) { - case 0xcd0000: /* call */ - /* CALL $xxxx cycles */ - CC(op, 0xcd); - T(m_icount_executing - MTM * 2); + switch (irq_vector & 0xff0000) + { + case 0xcd0000: // call + // CALL $xxxx cycles + T(11); wm16_sp(m_pc); PCD = irq_vector & 0xffff; break; - case 0xc30000: /* jump */ - /* JP $xxxx cycles */ - CC(op, 0xc3); - T(m_icount_executing); + case 0xc30000: // jump + // JP $xxxx cycles + T(10); PCD = irq_vector & 0xffff; break; - default: /* rst (or other opcodes?) */ + default: // rst (or other opcodes?) if (irq_vector == 0xfb) { // EI - CC(op, 0xfb); - T(m_icount_executing); + T(4); ei(); } else if ((irq_vector & 0xc7) == 0xc7) { - /* RST $xx cycles */ - CC(op, 0xff); - T(m_icount_executing - MTM * 2); + // RST $xx cycles + T(5); wm16_sp(m_pc); PCD = irq_vector & 0x0038; } else logerror("take_interrupt: unexpected opcode in im0 mode: 0x%02x\n", irq_vector); break; + } } } - } - WZ=PCD; + WZ = PCD; #if HAS_LDAIR_QUIRK - /* reset parity flag after LD A,I or LD A,R */ + // reset parity flag after LD A,I or LD A,R if (m_after_ldair) F &= ~PF; #endif } @@ -3356,7 +3279,7 @@ void z80_device::nomreq_ir(s8 cycles) void z80_device::nomreq_addr(u16 addr, s8 cycles) { - for (; cycles; cycles--) + while (cycles--) { m_nomreq_cb(addr, 0x00, 0xff); T(1); @@ -3365,18 +3288,14 @@ void z80_device::nomreq_addr(u16 addr, s8 cycles) void nsc800_device::take_interrupt_nsc800() { - /* Check if processor was halted */ + // Check if processor was halted leave_halt(); - /* Clear both interrupt flip flops */ + // Clear both interrupt flip flops m_iff1 = m_iff2 = 0; - /* 'interrupt latency' cycles */ - m_icount_executing = 0; - CC(op, 0xff); - CC(ex, 0xff); //2 - - T(m_icount_executing - MTM * 2); + // 'interrupt latency' cycles + T(7); if (m_nsc800_irq_state[NSC800_RSTA]) { wm16_sp(m_pc); @@ -3392,12 +3311,15 @@ void nsc800_device::take_interrupt_nsc800() wm16_sp(m_pc); PCD = 0x002c; } - T(m_icount_executing); + else + { + T(2 * m_memrq_cycles); + } - WZ=PCD; + WZ = PCD; #if HAS_LDAIR_QUIRK - /* reset parity flag after LD A,I or LD A,R */ + // reset parity flag after LD A,I or LD A,R if (m_after_ldair) F &= ~PF; #endif } @@ -3407,44 +3329,44 @@ void nsc800_device::take_interrupt_nsc800() ****************************************************************************/ void z80_device::device_start() { - if( !tables_initialised ) + if (!tables_initialised) { - uint8_t *padd = &SZHVC_add[ 0*256]; - uint8_t *padc = &SZHVC_add[256*256]; - uint8_t *psub = &SZHVC_sub[ 0*256]; - uint8_t *psbc = &SZHVC_sub[256*256]; + 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 */ + // 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 */ + *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 */ + // adc with carry set val = newval - oldval - 1; *padc = (newval) ? ((newval & 0x80) ? SF : 0) : ZF; - *padc |= (newval & (YF | XF)); /* undocumented flag bits 5+3 */ + *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 */ + // 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 */ + *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 */ + // 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 */ @@ -3467,9 +3389,9 @@ void z80_device::device_start() if( i&0x40 ) ++p; if( i&0x80 ) ++p; SZ[i] = i ? i & SF : ZF; - SZ[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZ[i] |= (i & (YF | XF)); // undocumented flag bits 5+3 SZ_BIT[i] = i ? i & SF : ZF | PF; - SZ_BIT[i] |= (i & (YF | XF)); /* undocumented flag bits 5+3 */ + SZ_BIT[i] |= (i & (YF | XF)); // undocumented flag bits 5+3 SZP[i] = SZ[i] | ((p & 1) ? 0 : PF); SZHV_inc[i] = SZ[i]; if( i == 0x80 ) SZHV_inc[i] |= VF; @@ -3498,6 +3420,8 @@ void z80_device::device_start() save_item(NAME(m_hl2.w.l)); save_item(NAME(m_r)); save_item(NAME(m_r2)); + save_item(NAME(m_q)); + save_item(NAME(m_qtemp)); save_item(NAME(m_iff1)); save_item(NAME(m_iff2)); save_item(NAME(m_halt)); @@ -3511,7 +3435,7 @@ void z80_device::device_start() save_item(NAME(m_after_ei)); save_item(NAME(m_after_ldair)); - /* Reset registers to their initial values */ + // Reset registers to their initial values PRVPC = 0; PCD = 0; SPD = 0; @@ -3547,10 +3471,10 @@ void z80_device::device_start() space(AS_PROGRAM).specific(m_data); space(AS_IO).specific(m_io); - IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */ - F = ZF; /* Zero flag is set */ + IX = IY = 0xffff; // IX and IY are FFFF after a reset! + set_f(ZF); // Zero flag is set - /* set up the state table */ + // set up the state table state_add(STATE_GENPC, "PC", m_pc.w.l).callimport(); state_add(STATE_GENPCBASE, "CURPC", m_prvpc.w.l).callimport().noshow(); state_add(Z80_SP, "SP", SP); @@ -3582,15 +3506,6 @@ void z80_device::device_start() // set our instruction counter set_icountptr(m_icount); - m_icount_executing = 0; - - /* setup cycle tables */ - m_cc_op = cc_op; - m_cc_cb = cc_cb; - m_cc_ed = cc_ed; - m_cc_xy = cc_xy; - m_cc_xycb = cc_xycb; - m_cc_ex = cc_ex; } void nsc800_device::device_start() @@ -3617,7 +3532,7 @@ void z80_device::device_reset() m_iff1 = 0; m_iff2 = 0; - WZ=PCD; + WZ = PCD; } void nsc800_device::device_reset() @@ -3626,10 +3541,14 @@ void nsc800_device::device_reset() memset(m_nsc800_irq_state, 0, sizeof(m_nsc800_irq_state)); } +inline void z80_device::execute_cycles(u8 icount) +{ + m_icount -= icount; +} + /**************************************************************************** * Execute 'cycles' T-states. ****************************************************************************/ - void z80_device::execute_run() { do @@ -3643,7 +3562,6 @@ void z80_device::execute_run() // check for interrupts before each instruction check_interrupts(); - m_icount_executing = 0; m_after_ei = false; m_after_ldair = false; @@ -3651,7 +3569,7 @@ void z80_device::execute_run() PRVPC = PCD; debugger_instruction_hook(PCD); - uint8_t opcode = rop(); + u8 opcode = rop(); // when in HALT state, the fetched opcode is not dispatched (aka a NOP) if (m_halt) @@ -3659,7 +3577,7 @@ void z80_device::execute_run() PC--; opcode = 0; } - EXEC(op,opcode); + EXEC(op, opcode); } while (m_icount > 0); } @@ -3680,19 +3598,19 @@ void z80_device::execute_set_input(int inputnum, int state) break; case INPUT_LINE_NMI: - /* mark an NMI pending on the rising edge */ + // mark an NMI pending on the rising edge if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE) m_nmi_pending = true; m_nmi_state = state; break; case INPUT_LINE_IRQ0: - /* update the IRQ state via the daisy chain */ + // update the IRQ state via the daisy chain m_irq_state = state; if (daisy_chain_present()) - m_irq_state = (daisy_update_irq_state() == ASSERT_LINE ) ? ASSERT_LINE : m_irq_state; + m_irq_state = (daisy_update_irq_state() == ASSERT_LINE) ? ASSERT_LINE : m_irq_state; - /* the main execute loop will take the interrupt */ + // the main execute loop will take the interrupt break; case Z80_INPUT_LINE_WAIT: @@ -3736,45 +3654,41 @@ void nsc800_device::execute_set_input(int inputnum, int state) } } - - /************************************************************************** * STATE IMPORT/EXPORT **************************************************************************/ - -void z80_device::state_import( const device_state_entry &entry ) +void z80_device::state_import(const device_state_entry &entry) { switch (entry.index()) { - case STATE_GENPC: - m_prvpc = m_pc; - break; + case STATE_GENPC: + m_prvpc = m_pc; + break; - case STATE_GENPCBASE: - m_pc = m_prvpc; - break; + case STATE_GENPCBASE: + m_pc = m_prvpc; + break; - case Z80_R: - m_r = m_rtemp & 0x7f; - m_r2 = m_rtemp & 0x80; - break; + case Z80_R: + m_r = m_rtemp & 0x7f; + m_r2 = m_rtemp & 0x80; + break; - default: - fatalerror("CPU_IMPORT_STATE() called for unexpected value\n"); + default: + fatalerror("CPU_IMPORT_STATE() called for unexpected value\n"); } } - -void z80_device::state_export( const device_state_entry &entry ) +void z80_device::state_export(const device_state_entry &entry) { switch (entry.index()) { - case Z80_R: - m_rtemp = (m_r & 0x7f) | (m_r2 & 0x80); - break; + case Z80_R: + m_rtemp = (m_r & 0x7f) | (m_r2 & 0x80); + break; - default: - fatalerror("CPU_EXPORT_STATE() called for unexpected value\n"); + default: + fatalerror("CPU_EXPORT_STATE() called for unexpected value\n"); } } @@ -3796,44 +3710,19 @@ void z80_device::state_string_export(const device_state_entry &entry, std::strin } } -//------------------------------------------------- -// disassemble - call the disassembly -// helper function -//------------------------------------------------- - -std::unique_ptr z80_device::create_disassembler() -{ - return std::make_unique(); -} - - /************************************************************************** - * Generic set_info + * disassemble - call the disassembly helper function **************************************************************************/ - -void z80_device::z80_set_cycle_tables(const uint8_t *op, const uint8_t *cb, const uint8_t *ed, const uint8_t *xy, const uint8_t *xycb, const uint8_t *ex) -{ - m_cc_op = (op != nullptr) ? op : cc_op; - m_cc_cb = (cb != nullptr) ? cb : cc_cb; - m_cc_ed = (ed != nullptr) ? ed : cc_ed; - m_cc_xy = (xy != nullptr) ? xy : cc_xy; - m_cc_xycb = (xycb != nullptr) ? xycb : cc_xycb; - m_cc_ex = (ex != nullptr) ? ex : cc_ex; -} - - -void z80_device::set_mtm_cycles(uint8_t mtm_cycles) +std::unique_ptr z80_device::create_disassembler() { - m_mtm_cycles = mtm_cycles; + return std::make_unique(); } - -z80_device::z80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - z80_device(mconfig, Z80, tag, owner, clock) +z80_device::z80_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : z80_device(mconfig, Z80, tag, owner, clock) { } -z80_device::z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : +z80_device::z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : cpu_device(mconfig, type, tag, owner, clock), z80_daisy_chain_interface(mconfig, *this), m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0), @@ -3842,8 +3731,7 @@ z80_device::z80_device(const machine_config &mconfig, device_type type, const ch m_irqack_cb(*this), m_refresh_cb(*this), m_nomreq_cb(*this), - m_halt_cb(*this), - m_mtm_cycles(3) + m_halt_cb(*this) { } @@ -3864,7 +3752,7 @@ device_memory_interface::space_config_vector z80_device::memory_space_config() c DEFINE_DEVICE_TYPE(Z80, z80_device, "z80", "Zilog Z80") -nsc800_device::nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +nsc800_device::nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : z80_device(mconfig, NSC800, tag, owner, clock) { } diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index 3b91032f710..41ba7c8a968 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -13,7 +13,7 @@ enum NSC800_RSTB, NSC800_RSTC, Z80_INPUT_LINE_WAIT, - Z80_INPUT_LINE_BOGUSWAIT, /* WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT */ + Z80_INPUT_LINE_BOGUSWAIT, // WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT Z80_INPUT_LINE_BUSRQ }; @@ -30,10 +30,11 @@ enum class z80_device : public cpu_device, public z80_daisy_chain_interface { public: - z80_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + z80_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void z80_set_cycle_tables(const uint8_t *op, const uint8_t *cb, const uint8_t *ed, const uint8_t *xy, const uint8_t *xycb, const uint8_t *ex); - void set_mtm_cycles(uint8_t mtm_cycles); + void z80_set_m1_cycles(u8 m1_cycles) { m_m1_cycles = m1_cycles; } + void z80_set_memrq_cycles(u8 memrq_cycles) { m_memrq_cycles = memrq_cycles; } + void z80_set_iorq_cycles(u8 iorq_cycles) { m_iorq_cycles = iorq_cycles; } template void set_memory_map(T &&... args) { set_addrmap(AS_PROGRAM, std::forward(args)...); } template void set_m1_map(T &&... args) { set_addrmap(AS_OPCODES, std::forward(args)...); } template void set_io_map(T &&... args) { set_addrmap(AS_IO, std::forward(args)...); } @@ -43,17 +44,17 @@ public: auto halt_cb() { return m_halt_cb.bind(); } protected: - z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + z80_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_start() override; virtual void device_reset() override; // device_execute_interface overrides - virtual uint32_t execute_min_cycles() const noexcept override { return 2; } - virtual uint32_t execute_max_cycles() const noexcept override { return 16; } - virtual uint32_t execute_input_lines() const noexcept override { return 4; } - virtual uint32_t execute_default_irq_vector(int inputnum) const noexcept override { return 0xff; } + virtual u32 execute_min_cycles() const noexcept override { return 2; } + virtual u32 execute_max_cycles() const noexcept override { return 16; } + virtual u32 execute_input_lines() const noexcept override { return 4; } + virtual u32 execute_default_irq_vector(int inputnum) const noexcept override { return 0xff; } virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return inputnum == INPUT_LINE_NMI; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; @@ -137,9 +138,6 @@ protected: void prefix##_f8(); void prefix##_f9(); void prefix##_fa(); void prefix##_fb(); \ void prefix##_fc(); void prefix##_fd(); void prefix##_fe(); void prefix##_ff(); - void illegal_1(); - void illegal_2(); - PROTOTYPES(op) PROTOTYPES(cb) PROTOTYPES(dd) @@ -147,19 +145,22 @@ protected: PROTOTYPES(fd) PROTOTYPES(xycb) + void illegal_1(); + void illegal_2(); + void halt(); void leave_halt(); - uint8_t in(uint16_t port); - void out(uint16_t port, uint8_t value); - virtual uint8_t rm(uint16_t addr); - uint8_t rm_reg(uint16_t addr); - void rm16(uint16_t addr, PAIR &r); - virtual void wm(uint16_t addr, uint8_t value); - void wm16(uint16_t addr, PAIR &r); + u8 in(u16 port); + void out(u16 port, u8 value); + u8 rm(u16 addr); + u8 rm_reg(u16 addr); + void rm16(u16 addr, PAIR &r); + void wm(u16 addr, u8 value); + void wm16(u16 addr, PAIR &r); void wm16_sp(PAIR &r); - virtual uint8_t rop(); - virtual uint8_t arg(); - virtual uint16_t arg16(); + u8 rop(); + u8 arg(); + u16 arg16(); void eax(); void eay(); void pop(PAIR &r); @@ -167,63 +168,61 @@ protected: void jp(void); void jp_cond(bool cond); void jr(); - void jr_cond(bool cond, uint8_t opcode); + void jr_cond(bool cond, u8 opcode); void call(); - void call_cond(bool cond, uint8_t opcode); - void ret_cond(bool cond, uint8_t opcode); + void call_cond(bool cond, u8 opcode); + void ret_cond(bool cond, u8 opcode); void retn(); void reti(); void ld_r_a(); void ld_a_r(); void ld_i_a(); void ld_a_i(); - void rst(uint16_t addr); - uint8_t inc(uint8_t value); - uint8_t dec(uint8_t value); + void rst(u16 addr); + u8 inc(u8 value); + u8 dec(u8 value); void rlca(); void rrca(); void rla(); void rra(); void rrd(); void rld(); - void add_a(uint8_t value); - void adc_a(uint8_t value); - void sub(uint8_t value); - void sbc_a(uint8_t value); + void add_a(u8 value); + void adc_a(u8 value); + void sub(u8 value); + void sbc_a(u8 value); void neg(); void daa(); - void and_a(uint8_t value); - void or_a(uint8_t value); - void xor_a(uint8_t value); - void cp(uint8_t value); - void ex_af(); - void ex_de_hl(); + void and_a(u8 value); + void or_a(u8 value); + void xor_a(u8 value); + void cp(u8 value); void exx(); void ex_sp(PAIR &r); void add16(PAIR &dr, PAIR &sr); void adc_hl(PAIR &r); void sbc_hl(PAIR &r); - uint8_t rlc(uint8_t value); - uint8_t rrc(uint8_t value); - uint8_t rl(uint8_t value); - uint8_t rr(uint8_t value); - uint8_t sla(uint8_t value); - uint8_t sra(uint8_t value); - uint8_t sll(uint8_t value); - uint8_t srl(uint8_t value); - void bit(int bit, uint8_t value); - void bit_hl(int bit, uint8_t value); - void bit_xy(int bit, uint8_t value); - uint8_t res(int bit, uint8_t value); - uint8_t set(int bit, uint8_t value); + u8 rlc(u8 value); + u8 rrc(u8 value); + u8 rl(u8 value); + u8 rr(u8 value); + u8 sla(u8 value); + u8 sra(u8 value); + u8 sll(u8 value); + u8 srl(u8 value); + void bit(int bit, u8 value); + void bit_hl(int bit, u8 value); + void bit_xy(int bit, u8 value); + u8 res(int bit, u8 value); + u8 set(int bit, u8 value); void ldi(); void cpi(); - void ini(); - void outi(); + u8 ini(); + u8 outi(); void ldd(); void cpd(); - void ind(); - void outd(); + u8 ind(); + u8 outd(); void ldir(); void cpir(); void inir(); @@ -233,13 +232,21 @@ protected: void indr(); void otdr(); void ei(); + void set_f(u8 f); + void block_io_interrupted_flags(u8 data); + void execute_cycles(u8 icount); virtual void check_interrupts(); void take_interrupt(); void take_nmi(); void nomreq_ir(s8 cycles); void nomreq_addr(u16 addr, s8 cycles); + virtual u8 data_read(u16 addr); + virtual void data_write(u16 addr, u8 value); + virtual u8 opcode_read(); + virtual u8 arg_read(); + // address spaces const address_space_config m_program_config; const address_space_config m_opcodes_config; @@ -254,46 +261,44 @@ protected: devcb_write8 m_nomreq_cb; devcb_write_line m_halt_cb; - PAIR m_prvpc; - PAIR m_pc; - PAIR m_sp; - PAIR m_af; - PAIR m_bc; - PAIR m_de; - PAIR m_hl; - PAIR m_ix; - PAIR m_iy; - PAIR m_wz; - PAIR m_af2; - PAIR m_bc2; - PAIR m_de2; - PAIR m_hl2; - uint8_t m_r; - uint8_t m_r2; - uint8_t m_iff1; - uint8_t m_iff2; - uint8_t m_halt; - uint8_t m_im; - uint8_t m_i; - uint8_t m_nmi_state; /* nmi line state */ - uint8_t m_nmi_pending; /* nmi pending */ - uint8_t m_irq_state; /* irq line state */ - int m_wait_state; // wait line state - int m_busrq_state; // bus request line state - uint8_t m_after_ei; /* are we in the EI shadow? */ - uint8_t m_after_ldair; /* same, but for LD A,I or LD A,R */ - uint32_t m_ea; + PAIR m_prvpc; + PAIR m_pc; + PAIR m_sp; + PAIR m_af; + PAIR m_bc; + PAIR m_de; + PAIR m_hl; + PAIR m_ix; + PAIR m_iy; + PAIR m_wz; + PAIR m_af2; + PAIR m_bc2; + PAIR m_de2; + PAIR m_hl2; + u8 m_qtemp; + u8 m_q; + u8 m_r; + u8 m_r2; + u8 m_iff1; + u8 m_iff2; + u8 m_halt; + u8 m_im; + u8 m_i; + u8 m_nmi_state; // nmi line state + u8 m_nmi_pending; // nmi pending + u8 m_irq_state; // irq line state + int m_wait_state; // wait line state + int m_busrq_state; // bus request line state + u8 m_after_ei; // are we in the EI shadow? + u8 m_after_ldair; // same, but for LD A,I or LD A,R + u32 m_ea; + + int m_icount; + u8 m_rtemp; - int m_icount; - int m_icount_executing; - uint8_t m_rtemp; - const uint8_t * m_cc_op; - const uint8_t * m_cc_cb; - const uint8_t * m_cc_ed; - const uint8_t * m_cc_xy; - const uint8_t * m_cc_xycb; - const uint8_t * m_cc_ex; - uint8_t m_mtm_cycles; + u8 m_m1_cycles = 4; + u8 m_memrq_cycles = 3; + u8 m_iorq_cycles = 4; }; DECLARE_DEVICE_TYPE(Z80, z80_device) @@ -301,7 +306,7 @@ DECLARE_DEVICE_TYPE(Z80, z80_device) class nsc800_device : public z80_device { public: - nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nsc800_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides @@ -309,12 +314,12 @@ protected: virtual void device_reset() override; // device_execute_interface overrides - virtual uint32_t execute_input_lines() const noexcept override { return 7; } + virtual u32 execute_input_lines() const noexcept override { return 7; } virtual void execute_set_input(int inputnum, int state) override; virtual void check_interrupts() override; void take_interrupt_nsc800(); - uint8_t m_nsc800_irq_state[4]; /* state of NSC800 restart interrupts A, B, C */ + u8 m_nsc800_irq_state[4]; // state of NSC800 restart interrupts A, B, C }; DECLARE_DEVICE_TYPE(NSC800, nsc800_device) diff --git a/src/mame/amstrad/amstrad.cpp b/src/mame/amstrad/amstrad.cpp index 68cae48764c..ebb38ad7b2a 100644 --- a/src/mame/amstrad/amstrad.cpp +++ b/src/mame/amstrad/amstrad.cpp @@ -93,12 +93,12 @@ Some bugs left : #include "amstrad.h" /* Components */ -#include "machine/i8255.h" /* for 8255 ppi */ -#include "cpu/z80/z80.h" /* for cycle tables */ -#include "video/mc6845.h" /* CRTC */ -#include "machine/upd765.h" /* for floppy disc controller */ +#include "machine/i8255.h" // for 8255 ppi +#include "cpu/z80/z80.h" // for cycle tables +#include "video/mc6845.h" // CRTC +#include "machine/upd765.h" // for floppy disc controller #include "sound/ay8910.h" -#include "machine/mc146818.h" /* Aleste RTC */ +#include "machine/mc146818.h" // Aleste RTC #include "bus/centronics/ctronics.h" /* Devices */ @@ -121,19 +121,11 @@ Some bugs left : #define SYSTEM_GX4000 2 -/* Memory is banked in 16k blocks. However, the multiface -pages the memory in 8k blocks! The ROM can -be paged into bank 0 and bank 3. */ +/* Memory is banked in 16k blocks. However, the multiface pages the memory in 8k blocks! + The ROM can be paged into bank 0 and bank 3. */ void amstrad_state::amstrad_mem(address_map &map) { - map(0x00000, 0x01fff).bankr("bank1").bankw("bank9"); - map(0x02000, 0x03fff).bankr("bank2").bankw("bank10"); - map(0x04000, 0x05fff).bankr("bank3").bankw("bank11"); - map(0x06000, 0x07fff).bankr("bank4").bankw("bank12"); - map(0x08000, 0x09fff).bankr("bank5").bankw("bank13"); - map(0x0a000, 0x0bfff).bankr("bank6").bankw("bank14"); - map(0x0c000, 0x0dfff).bankr("bank7").bankw("bank15"); - map(0x0e000, 0x0ffff).bankr("bank8").bankw("bank16"); + map(0x0000, 0xffff).rw(FUNC(amstrad_state::amstrad_cpc_mem_r), FUNC(amstrad_state::amstrad_cpc_mem_w)); } /* I've handled the I/O ports in this way, because the ports @@ -153,9 +145,9 @@ void amstrad_state::amstrad_io(address_map &map) static INPUT_PORTS_START( amstrad_keyboard ) PORT_START("kbrow.0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) @@ -163,7 +155,7 @@ static INPUT_PORTS_START( amstrad_keyboard ) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) PORT_START("kbrow.1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Copy") PORT_CODE(KEYCODE_END) PORT_CHAR(UCHAR_MAMEKEY(END)) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) @@ -343,8 +335,8 @@ static INPUT_PORTS_START( amx_mouse ) PORT_BIT(0xff , 0, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) PORT_START("mouse_input3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3) PORT_CONDITION("controller_type", 0x02, EQUALS, 0x02) PORT_START("controller_type") @@ -1197,13 +1189,12 @@ void amstrad_state::aleste(machine_config &config) * *************************************/ -/* cpc6128.rom contains OS in first 16k, BASIC in second 16k */ -/* cpcados.rom contains Amstrad DOS */ +// cpc6128.rom contains OS in first 16k, BASIC in second 16k +// cpcados.rom contains Amstrad DOS -/* I am loading the roms outside of the Z80 memory area, because they -are banked. */ +// I am loading the roms outside of the Z80 memory area, because they are banked. ROM_START( cpc6128 ) - /* this defines the total memory size - 64k ram, 16k OS, 16k BASIC, 16k DOS */ + // this defines the total memory size - 64k ram, 16k OS, 16k BASIC, 16k DOS ROM_REGION(0x020000, "maincpu", 0) /* load the os to offset 0x01000 from memory base */ ROM_LOAD("cpc6128.rom", 0x10000, 0x8000, CRC(9e827fe1) SHA1(5977adbad3f7c1e0e082cd02fe76a700d9860c30)) @@ -1212,17 +1203,17 @@ ROM_END ROM_START( cpc6128f ) - /* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/ + // this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k ROM_REGION(0x020000, "maincpu", 0) - /* load the os to offset 0x01000 from memory base */ + // load the os to offset 0x01000 from memory base ROM_LOAD("cpc6128f.rom", 0x10000, 0x8000, CRC(1574923b) SHA1(200d59076dfef36db061d6d7d21d80021cab1237)) ROM_LOAD("cpcados.rom", 0x18000, 0x4000, CRC(1fe22ecd) SHA1(39102c8e9cb55fcc0b9b62098780ed4a3cb6a4bb)) ROM_END ROM_START( cpc6128s ) - /* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/ + // this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k ROM_REGION(0x020000, "maincpu", 0) /* load the os to offset 0x01000 from memory base */ @@ -1231,7 +1222,7 @@ ROM_START( cpc6128s ) ROM_END ROM_START( cpc6128sp ) - /* this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k*/ + // this defines the total memory size (128kb))- 64k ram, 16k OS, 16k BASIC, 16k DOS +16k ROM_REGION(0x020000, "maincpu", 0) /* load the os to offset 0x01000 from memory base */ @@ -1309,15 +1300,16 @@ ROM_END * *************************************/ -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1984, cpc464, 0, 0, cpc464, cpc464, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464", 0 ) -COMP( 1985, cpc664, cpc464, 0, cpc664, cpc664, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC664", 0 ) -COMP( 1985, cpc6128, cpc464, 0, cpc6128, cpc6128, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128", 0 ) -COMP( 1985, cpc6128f, cpc464, 0, cpc6128, cpc6128f, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (France, AZERTY Keyboard)", 0 ) -COMP( 1985, cpc6128s, cpc464, 0, cpc6128, cpc6128s, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Sweden/Finland)", 0 ) -COMP( 1985, cpc6128sp, cpc464, 0, cpc6128, cpc6128sp, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Spain)", 0 ) -COMP( 1990, cpc464p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464+", 0 ) -COMP( 1990, cpc6128p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128+", 0 ) -CONS( 1990, gx4000, 0, 0, gx4000, gx4000, amstrad_state, empty_init, "Amstrad plc", "Amstrad GX4000", 0 ) -COMP( 1989, kccomp, cpc464, 0, kccomp, kccomp, amstrad_state, empty_init, u8"VEB Mikroelektronik \"Wilhelm Pieck\" Mühlhausen", "KC Compact", 0 ) -COMP( 1993, al520ex, cpc464, 0, aleste, aleste, amstrad_state, empty_init, "Patisonic", "Aleste 520EX", MACHINE_IMPERFECT_SOUND ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1984, cpc464, 0, 0, cpc464, cpc464, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464", 0 ) +COMP( 1985, cpc664, cpc464, 0, cpc664, cpc664, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC664", 0 ) +COMP( 1985, cpc6128, cpc464, 0, cpc6128, cpc6128, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128", 0 ) +COMP( 1985, cpc6128f, cpc464, 0, cpc6128, cpc6128f, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (France, AZERTY Keyboard)", 0 ) +COMP( 1985, cpc6128s, cpc464, 0, cpc6128, cpc6128s, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Sweden/Finland)", 0 ) +COMP( 1985, cpc6128sp, cpc464, 0, cpc6128, cpc6128sp, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128 (Spain)", 0 ) +COMP( 1990, cpc464p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC464+", 0 ) +COMP( 1990, cpc6128p, 0, 0, cpcplus, plus, amstrad_state, empty_init, "Amstrad plc", "Amstrad CPC6128+", 0 ) +CONS( 1990, gx4000, 0, 0, gx4000, gx4000, amstrad_state, empty_init, "Amstrad plc", "Amstrad GX4000", 0 ) +COMP( 1989, kccomp, cpc464, 0, kccomp, kccomp, amstrad_state, empty_init, u8"VEB Mikroelektronik \"Wilhelm Pieck\" M?hlhausen", + "KC Compact", 0 ) +COMP( 1993, al520ex, cpc464, 0, aleste, aleste, amstrad_state, empty_init, "Patisonic", "Aleste 520EX", MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/amstrad/amstrad.h b/src/mame/amstrad/amstrad.h index b14b98b3800..bf1a986b774 100644 --- a/src/mame/amstrad/amstrad.h +++ b/src/mame/amstrad/amstrad.h @@ -211,6 +211,8 @@ private: void aleste_msx_mapper(offs_t offset, uint8_t data); uint8_t amstrad_cpc_io_r(offs_t offset); void amstrad_cpc_io_w(offs_t offset, uint8_t data); + uint8_t amstrad_cpc_mem_r(offs_t offset); + void amstrad_cpc_mem_w(offs_t offset, uint8_t data); uint8_t amstrad_psg_porta_read(); void amstrad_plus_seqcheck(int data); DECLARE_MACHINE_START(amstrad); @@ -266,7 +268,7 @@ private: required_memory_region m_region_maincpu; optional_memory_region m_region_user1; - required_memory_bank_array<16> m_banks; + memory_bank_array_creator<16> m_banks; optional_ioport_array<11> m_io_kbrow; optional_ioport_array<4> m_io_analog; optional_ioport_array<3> m_io_mouse; diff --git a/src/mame/amstrad/amstrad_m.cpp b/src/mame/amstrad/amstrad_m.cpp index 4d0aa81f3e4..74b49904245 100644 --- a/src/mame/amstrad/amstrad_m.cpp +++ b/src/mame/amstrad/amstrad_m.cpp @@ -31,8 +31,14 @@ the name I give to the time taken for one NOP command to execute. This happens to be 1us. -From measurement, there are 64 NOPs per line, with 312 lines per screen. -This gives a total of 19968 NOPs per frame. + +Timings: + From measurement, there are 64 NOPs per line, with 312 lines per screen. This +gives a total of 19968 NOPs per frame. + + The Amstrad hardware issues a HALT for each memory fetch. This has the effect +of stretching the timing for Z80 opcodes, so that they are all multiple of 4 T +states long. All opcode timings are a multiple of 1us in length. ***************************************************************************/ @@ -97,14 +103,14 @@ static const uint8_t asic_unlock_seq[15] = The following tables show the possible ram configurations :*/ static const int RamConfigurations[8 * 4] = { - 0, 1, 2, 3, /* config 0 */ - 0, 1, 2, 7, /* config 1 */ - 4, 5, 6, 7, /* config 2 */ - 0, 3, 2, 7, /* config 3 */ - 0, 4, 2, 3, /* config 4 */ - 0, 5, 2, 3, /* config 5 */ - 0, 6, 2, 3, /* config 6 */ - 0, 7, 2, 3 /* config 7 */ + 0, 1, 2, 3, // config 0 + 0, 1, 2, 7, // config 1 + 4, 5, 6, 7, // config 2 + 0, 3, 2, 7, // config 3 + 0, 4, 2, 3, // config 4 + 0, 5, 2, 3, // config 5 + 0, 6, 2, 3, // config 6 + 0, 7, 2, 3 // config 7 }; @@ -161,38 +167,38 @@ static const rgb_t amstrad_palette[32] = /* the green brightness is equal to the firmware colour index */ static const rgb_t amstrad_green_palette[32] = { - rgb_t(0x000, 0x07F, 0x000), /*13*/ - rgb_t(0x000, 0x07F, 0x000), /*13*/ - rgb_t(0x000, 0x0BA, 0x000), /*19*/ - rgb_t(0x000, 0x0F5, 0x000), /*25*/ - rgb_t(0x000, 0x009, 0x000), /*1*/ - rgb_t(0x000, 0x044, 0x000), /*7*/ - rgb_t(0x000, 0x062, 0x000), /*10*/ - rgb_t(0x000, 0x09C, 0x000), /*16*/ - rgb_t(0x000, 0x044, 0x000), /*7*/ - rgb_t(0x000, 0x0F5, 0x000), /*25*/ - rgb_t(0x000, 0x0EB, 0x000), /*24*/ - rgb_t(0x000, 0x0FF, 0x000), /*26*/ - rgb_t(0x000, 0x03A, 0x000), /*6*/ - rgb_t(0x000, 0x04E, 0x000), /*8*/ - rgb_t(0x000, 0x093, 0x000), /*15*/ - rgb_t(0x000, 0x0A6, 0x000), /*17*/ - rgb_t(0x000, 0x009, 0x000), /*1*/ - rgb_t(0x000, 0x0BA, 0x000), /*19*/ - rgb_t(0x000, 0x0B0, 0x000), /*18*/ - rgb_t(0x000, 0x0C4, 0x000), /*20*/ - rgb_t(0x000, 0x000, 0x000), /*0*/ - rgb_t(0x000, 0x013, 0x000), /*2*/ - rgb_t(0x000, 0x058, 0x000), /*9*/ - rgb_t(0x000, 0x06B, 0x000), /*11*/ - rgb_t(0x000, 0x027, 0x000), /*4*/ - rgb_t(0x000, 0x0D7, 0x000), /*22*/ - rgb_t(0x000, 0x0CD, 0x000), /*21*/ - rgb_t(0x000, 0x0E1, 0x000), /*23*/ - rgb_t(0x000, 0x01D, 0x000), /*3*/ - rgb_t(0x000, 0x031, 0x000), /*5*/ - rgb_t(0x000, 0x075, 0x000), /*12*/ - rgb_t(0x000, 0x089, 0x000) /*14*/ + rgb_t(0x000, 0x07F, 0x000), // 13 + rgb_t(0x000, 0x07F, 0x000), // 13 + rgb_t(0x000, 0x0BA, 0x000), // 19 + rgb_t(0x000, 0x0F5, 0x000), // 25 + rgb_t(0x000, 0x009, 0x000), // 1 + rgb_t(0x000, 0x044, 0x000), // 7 + rgb_t(0x000, 0x062, 0x000), // 10 + rgb_t(0x000, 0x09C, 0x000), // 16 + rgb_t(0x000, 0x044, 0x000), // 7 + rgb_t(0x000, 0x0F5, 0x000), // 25 + rgb_t(0x000, 0x0EB, 0x000), // 24 + rgb_t(0x000, 0x0FF, 0x000), // 26 + rgb_t(0x000, 0x03A, 0x000), // 6 + rgb_t(0x000, 0x04E, 0x000), // 8 + rgb_t(0x000, 0x093, 0x000), // 15 + rgb_t(0x000, 0x0A6, 0x000), // 17 + rgb_t(0x000, 0x009, 0x000), // 1 + rgb_t(0x000, 0x0BA, 0x000), // 19 + rgb_t(0x000, 0x0B0, 0x000), // 18 + rgb_t(0x000, 0x0C4, 0x000), // 20 + rgb_t(0x000, 0x000, 0x000), // 0 + rgb_t(0x000, 0x013, 0x000), // 2 + rgb_t(0x000, 0x058, 0x000), // 9 + rgb_t(0x000, 0x06B, 0x000), // 11 + rgb_t(0x000, 0x027, 0x000), // 4 + rgb_t(0x000, 0x0D7, 0x000), // 22 + rgb_t(0x000, 0x0CD, 0x000), // 21 + rgb_t(0x000, 0x0E1, 0x000), // 23 + rgb_t(0x000, 0x01D, 0x000), // 3 + rgb_t(0x000, 0x031, 0x000), // 5 + rgb_t(0x000, 0x075, 0x000), // 12 + rgb_t(0x000, 0x089, 0x000) // 14 }; @@ -2174,6 +2180,18 @@ The exception is the case where none of b7-b0 are reset (i.e. port &FBFF), which } } +uint8_t amstrad_state::amstrad_cpc_mem_r(offs_t offset) +{ + if (!machine().side_effects_disabled()) + m_maincpu->adjust_icount(-((4 - m_maincpu->total_cycles() % 4) % 4)); + return ((uint8_t*)m_banks[(offset >> 13)]->base())[offset & 0x1fff]; +} + +void amstrad_state::amstrad_cpc_mem_w(offs_t offset, uint8_t data) +{ + m_maincpu->adjust_icount(-((4 - m_maincpu->total_cycles() % 4) % 4)); + ((uint8_t*)m_banks[(offset >> 13) + 8]->base())[offset & 0x1fff] = data; +} /* load CPCEMU style snapshots */ void amstrad_state::amstrad_handle_snapshot(unsigned char *pSnapshot) @@ -2766,125 +2784,6 @@ IRQ_CALLBACK_MEMBER(amstrad_state::amstrad_cpu_acknowledge_int) } -/* the following timings have been measured! */ -static const uint8_t amstrad_cycle_table_op[256] = { - 4, 12, 8, 8, 4, 4, 8, 4, 4, 12, 8, 8, 4, 4, 8, 4, - 12, 12, 8, 8, 4, 4, 8, 4, 12, 12, 8, 8, 4, 4, 8, 4, - 8, 12, 20, 8, 4, 4, 8, 4, 8, 12, 20, 8, 4, 4, 8, 4, - 8, 12, 16, 8, 12, 12, 12, 4, 8, 12, 16, 8, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 8, 8, 8, 8, 8, 8, 4, 8, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 8, 12, 12, 12, 12, 16, 8, 16, 8, 12, 12, 4, 12, 20, 8, 16, - 8, 12, 12, 12, 12, 16, 8, 16, 8, 4, 12, 12, 12, 4, 8, 16, - 8, 12, 12, 24, 12, 16, 8, 16, 8, 4, 12, 4, 12, 4, 8, 16, - 8, 12, 12, 4, 12, 16, 8, 16, 8, 8, 12, 4, 12, 4, 8, 16 -}; - -static const uint8_t amstrad_cycle_table_cb[256]= -{ - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 8, 4, 4, 4, 4, 4, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4, - 4, 4, 4, 4, 4, 4, 12, 4, 4, 4, 4, 4, 4, 4, 12, 4 -}; - -static const uint8_t amstrad_cycle_table_ed[256]= -{ - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 12, 12, 12, 20, 4, 12, 4, 8, 12, 12, 12, 20, 4, 12, 4, 8, - 12, 12, 12, 20, 4, 12, 4, 8, 12, 12, 12, 20, 4, 12, 4, 8, - 12, 12, 12, 20, 4, 12, 4, 16, 12, 12, 12, 20, 4, 12, 4, 16, - 12, 12, 12, 20, 4, 12, 4, 4, 12, 12, 12, 20, 4, 12, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 16, 12, 16, 16, 4, 4, 4, 4, 16, 12, 16, 16, 4, 4, 4, 4, - 16, 12, 16, 16, 4, 4, 4, 4, 16, 12, 16, 16, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -}; - -static const uint8_t amstrad_cycle_table_xy[256]= -{ - 4, 12, 8, 8, 4, 4, 8, 4, 4, 12, 8, 8, 4, 4, 8, 4, - 12, 12, 8, 8, 4, 4, 8, 4, 12, 12, 8, 8, 4, 4, 8, 4, - 8, 12, 20, 8, 4, 4, 8, 4, 8, 12, 20, 8, 4, 4, 8, 4, - 8, 12, 16, 8, 20, 20, 20, 4, 8, 12, 16, 8, 4, 4, 8, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 16, 16, 16, 16, 16, 16, 4, 16, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 4, 4, 4, 4, 4, 4, 16, 4, 4, 4, 4, 4, 4, 4, 16, 4, - 8, 12, 12, 12, 12, 16, 8, 16, 8, 12, 12, 8, 12, 20, 8, 16, - 8, 12, 12, 12, 12, 16, 8, 16, 8, 4, 12, 12, 12, 4, 8, 16, - 8, 12, 12, 24, 12, 16, 8, 16, 8, 4, 12, 4, 12, 4, 8, 16, - 8, 12, 12, 4, 12, 16, 8, 16, 8, 8, 12, 4, 12, 4, 8, 16 -}; - -static const uint8_t amstrad_cycle_table_xycb[0x100] = { - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, - 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 -}; - -static const uint8_t amstrad_cycle_table_ex[256]= -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 8, 4, 4, 0, 0, 0, 0, 4, 8, 4, 4, 0, 0, 0, 0, - 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, - 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, - 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, - 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 8, 0, 0, 0 -}; - #define NEXT_ROM_SLOT m_rom_count++; \ if(slot3 && m_rom_count == 3) m_rom_count++; \ if(slot7 && m_rom_count == 7) m_rom_count++; @@ -3036,26 +2935,6 @@ void amstrad_state::amstrad_common_init() m_maincpu->set_input_line_vector(0, 0xff); // Z80 else m_maincpu->set_input_line_vector(0, 0x00); // Z80 - - /* The opcode timing in the Amstrad is different to the opcode - timing in the core for the Z80 CPU. - - The Amstrad hardware issues a HALT for each memory fetch. - This has the effect of stretching the timing for Z80 opcodes, - so that they are all multiple of 4 T states long. All opcode - timings are a multiple of 1us in length. */ - - /* Using the cool code Juergen has provided, I will override - the timing tables with the values for the amstrad */ - m_maincpu->z80_set_cycle_tables( - (const uint8_t*)amstrad_cycle_table_op, - (const uint8_t*)amstrad_cycle_table_cb, - (const uint8_t*)amstrad_cycle_table_ed, - (const uint8_t*)amstrad_cycle_table_xy, - (const uint8_t*)amstrad_cycle_table_xycb, - (const uint8_t*)amstrad_cycle_table_ex); - - /* Juergen is a cool dude! */ } TIMER_CALLBACK_MEMBER(amstrad_state::cb_set_resolution) diff --git a/src/mame/chess/cking_master.cpp b/src/mame/chess/cking_master.cpp index a16fe428745..20e1040833f 100644 --- a/src/mame/chess/cking_master.cpp +++ b/src/mame/chess/cking_master.cpp @@ -12,11 +12,6 @@ Hardware notes: - simple I/O via 2*74373 and a 74145 - 8*8 chessboard buttons, 32+1 border leds, piezo -TODO: -- 1 WAIT CLK per M1, workaround with z80_set_cycle_tables is possible - (wait state is similar to MSX) but I can't be bothered, better solution - is to add M1 pin to the z80 core. Until then, it'll run ~20% too fast. - *******************************************************************************/ #include "emu.h" @@ -59,7 +54,7 @@ protected: private: // devices/pointers - required_device m_maincpu; + required_device m_maincpu; required_device m_display; required_device m_board; required_device m_dac; @@ -221,6 +216,7 @@ void master_state::master(machine_config &config) { // basic machine hardware Z80(config, m_maincpu, 8_MHz_XTAL/2); + m_maincpu->z80_set_m1_cycles(5); // 1 WAIT CLK per M1 m_maincpu->set_addrmap(AS_PROGRAM, &master_state::main_trampoline); ADDRESS_MAP_BANK(config, "mainmap").set_map(&master_state::main_map).set_options(ENDIANNESS_LITTLE, 8, 16); diff --git a/src/mame/msx/msx.cpp b/src/mame/msx/msx.cpp index b28ec33b865..a37199a7141 100644 --- a/src/mame/msx/msx.cpp +++ b/src/mame/msx/msx.cpp @@ -314,108 +314,10 @@ void msx_state::machine_start() m_port_c_old = 0xff; } -// Update instruction timings to add 1 wait cycle for each M1 opcode fetch. -static const u8 cc_op[0x100] = { - 4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 7+1,10+1,13+1, 6+1,11+1,11+1,10+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 7+1, 7+1, 7+1, 7+1, 7+1, 7+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 7+1, 4+1, - 5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 4+1,10+1,17+1, 7+1,11+1, - 5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 4+1, 7+1,11+1, - 5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 4+1, 7+1,11+1, - 5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 4+1, 7+1,11+1 -}; - -static const u8 cc_cb[0x100] = { - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 8+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,11+1, 4+1 -}; - -static const u8 cc_ed[0x100] = { - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, - 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 5+1, - 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1,14+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1,14+1, - 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 4+1, 8+1, 8+1,15+2,16+1, 4+1,14+2, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1, - 12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1,12+1,12+1,12+1,12+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1 -}; - -static const u8 cc_xy[0x100] = { - 4+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, 4+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 8+1,10+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1,12+1,11+1, 7+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 7+1,10+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, 7+1,11+1,16+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 7+1,10+1,13+1, 6+1,19+1,19+1,15+1, 4+1, 7+1,11+1,13+1, 6+1, 4+1, 4+1, 7+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 15+1,15+1,15+1,15+1,15+1,15+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1, 4+1,15+1, 4+1, - 5+1,10+1,10+1,10+1,10+1,11+1, 7+1,11+1, 5+1,10+1,10+1, 7+1,10+1,17+1, 7+1,11+1, - 5+1,10+1,10+1,11+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1,11+1,10+1, 4+1, 7+1,11+1, - 5+1,10+1,10+1,19+1,10+1,11+1, 7+1,11+1, 5+1, 4+1,10+1, 4+1,10+1, 4+1, 7+1,11+1, - 5+1,10+1,10+1, 4+1,10+1,11+1, 7+1,11+1, 5+1, 6+1,10+1, 4+1,10+1, 4+1, 7+1,11+1 -}; - -/* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */ -static const u8 cc_ex[0x100] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* DJNZ */ - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NZ/JR Z */ - 5, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, /* JR NC/JR C */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, /* LDIR/CPIR/INIR/OTIR LDDR/CPDR/INDR/OTDR */ - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2, - 6, 0, 0, 0, 7, 0, 0, 2, 6, 0, 0, 0, 7, 0, 0, 2+1 -}; - void msx_state::driver_start() { m_maincpu->set_input_line_vector(0, 0xff); // Z80 - - m_maincpu->z80_set_cycle_tables(cc_op, cc_cb, cc_ed, cc_xy, nullptr, cc_ex); + m_maincpu->z80_set_m1_cycles(5); save_item(NAME(m_psg_b)); save_item(NAME(m_kanji_latch)); -- cgit v1.2.3