cpu/z80/z80.cpp Update core generator to support r800 [holub, Wilbert Pol] (#12445)

This commit is contained in:
holub 2024-06-05 16:03:05 -04:00 committed by GitHub
parent a57e4cebde
commit ccad8c4c2f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 75 additions and 56 deletions

View File

@ -2978,14 +2978,12 @@ if (CPUS["Z80"]~=null or CPUS["KC80"]~=null) then
dependency { dependency {
{ MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80.hxx" },
{ MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80_rop.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80_ncs800.hxx" },
{ MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80_ncs800rop.hxx" },
} }
custombuildtask { custombuildtask {
{ MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 source file...", PYTHON .. " $(1) $(<) $(@)" } }, { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 source file...", PYTHON .. " $(1) $(<) $(@)" } },
{ MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80_rop.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 \\(rop\\) source file...", PYTHON .. " $(1) rop $(<) $(@)" } }, { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80_ncs800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating NSC800 source file...", PYTHON .. " $(1) ncs800 $(<) $(@)" } },
{ MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80_ncs800rop.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating NSC800 \\(rop\\) source file...", PYTHON .. " $(1) ncs800rop $(<) $(@)" } },
} }
end end

View File

@ -206,14 +206,14 @@
#define TDAT8 m_shared_data.b.l // Typically represents values from D0..8 pins. 8bit input or output in steps. #define TDAT8 m_shared_data.b.l // Typically represents values from D0..8 pins. 8bit input or output in steps.
static bool tables_initialised = false; static bool tables_initialised = false;
static u8 SZ[256]; // zero and sign flags std::unique_ptr<u8[]> z80_device::SZ = std::make_unique<u8[]>(0x100); // zero and sign flags
static u8 SZ_BIT[256]; // zero, sign and parity/overflow (=zero) flags for BIT opcode std::unique_ptr<u8[]> z80_device::SZ_BIT = std::make_unique<u8[]>(0x100); // zero, sign and parity/overflow (=zero) flags for BIT opcode
static u8 SZP[256]; // zero, sign and parity flags std::unique_ptr<u8[]> z80_device::SZP = std::make_unique<u8[]>(0x100); // zero, sign and parity flags
static u8 SZHV_inc[256]; // zero, sign, half carry and overflow flags INC r8 std::unique_ptr<u8[]> z80_device::SZHV_inc = std::make_unique<u8[]>(0x100); // zero, sign, half carry and overflow flags INC r8
static u8 SZHV_dec[256]; // zero, sign, half carry and overflow flags DEC r8 std::unique_ptr<u8[]> z80_device::SZHV_dec = std::make_unique<u8[]>(0x100); // zero, sign, half carry and overflow flags DEC r8
static u8 SZHVC_add[2*256*256]; std::unique_ptr<u8[]> z80_device::SZHVC_add = std::make_unique<u8[]>(2 * 0x100 * 0x100);
static u8 SZHVC_sub[2*256*256]; std::unique_ptr<u8[]> z80_device::SZHVC_sub = std::make_unique<u8[]>(2 * 0x100 * 0x100);
/*************************************************************** /***************************************************************
@ -905,20 +905,24 @@ bool z80_device::check_icount(u8 to_step, int icount_saved, bool redonable)
return false; return false;
} }
void z80_device::do_rop()
{
#include "cpu/z80/z80_rop.hxx"
}
void z80_device::do_op() void z80_device::do_op()
{ {
const bool is_rop = m_ref >= 0xffff00;
#include "cpu/z80/z80.hxx" #include "cpu/z80/z80.hxx"
m_ref = 0xffff00; if (!is_rop)
{
m_ref = 0xffff00;
}
} }
void nsc800_device::do_rop() void nsc800_device::do_op()
{ {
#include "cpu/z80/z80_ncs800rop.hxx" const bool is_rop = m_ref >= 0xffff00;
#include "cpu/z80/z80_ncs800.hxx"
if (!is_rop)
{
m_ref = 0xffff00;
}
} }
/**************************************************************************** /****************************************************************************
@ -935,25 +939,7 @@ void z80_device::execute_run()
m_redone = false; m_redone = false;
while (m_icount > 0 && !m_redone) while (m_icount > 0 && !m_redone)
{ {
if (m_ref >= 0xffff00) do_op();
{
do_rop();
if (m_icount > 0 && !m_redone)
{
if (m_halt)
{
PC--;
m_ref = 0xffff00;
} else {
m_ref = (0x00 << 16) | (TDAT8 << 8);
do_op();
}
}
}
else
{
do_op();
}
} }
} }

View File

@ -113,7 +113,6 @@ protected:
void set_f(u8 f); void set_f(u8 f);
void block_io_interrupted_flags(); void block_io_interrupted_flags();
virtual void do_rop();
virtual void do_op(); virtual void do_op();
bool check_icount(u8 to_step, int icount_saved, bool redonable); bool check_icount(u8 to_step, int icount_saved, bool redonable);
@ -180,6 +179,15 @@ protected:
u8 m_m1_cycles; u8 m_m1_cycles;
u8 m_memrq_cycles; u8 m_memrq_cycles;
u8 m_iorq_cycles; u8 m_iorq_cycles;
static std::unique_ptr<u8[]> SZ; // zero and sign flags
static std::unique_ptr<u8[]> SZ_BIT; // zero, sign and parity/overflow (=zero) flags for BIT opcode
static std::unique_ptr<u8[]> SZP; // zero, sign and parity flags
static std::unique_ptr<u8[]> SZHV_inc; // zero, sign, half carry and overflow flags INC r8
static std::unique_ptr<u8[]> SZHV_dec; // zero, sign, half carry and overflow flags DEC r8
static std::unique_ptr<u8[]> SZHVC_add;
static std::unique_ptr<u8[]> SZHVC_sub;
}; };
DECLARE_DEVICE_TYPE(Z80, z80_device) DECLARE_DEVICE_TYPE(Z80, z80_device)
@ -198,7 +206,7 @@ protected:
virtual u32 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 execute_set_input(int inputnum, int state) override;
virtual void do_rop() override; virtual void do_op() override;
u8 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
}; };

View File

@ -461,7 +461,7 @@ macro nsc800_take_interrupt
if (m_after_ldair) F &= ~PF; if (m_after_ldair) F &= ~PF;
#endif #endif
macro ncs800_check_interrupts macro ncs800:check_interrupts
if (m_nmi_pending) { if (m_nmi_pending) {
call take_nmi call take_nmi
} else if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei) { } else if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei) {
@ -474,21 +474,20 @@ macro ncs800_check_interrupts
########################################################## ##########################################################
# ROP # ROP
########################################################## ##########################################################
rop:ffff ffff
call check_interrupts call check_interrupts
m_after_ei = false; m_after_ei = false;
m_after_ldair = false; m_after_ldair = false;
PRVPC = PCD; PRVPC = PCD;
debugger_instruction_hook(PCD); debugger_instruction_hook(PCD);
call rop call rop
if (m_halt)
ncs800rop:ffff {
call ncs800_check_interrupts PC--;
m_after_ei = false; m_ref = 0xffff00;
m_after_ldair = false; } else {
PRVPC = PCD; m_ref = (0x00 << 16) | (TDAT8 << 8);
debugger_instruction_hook(PCD); }
call rop
########################################################## ##########################################################

View File

@ -139,24 +139,52 @@ class OpcodeList:
# New opcode # New opcode
tokens = line.split() tokens = line.split()
if tokens[0] == "macro": if tokens[0] == "macro":
name = tokens[1]
arg_name = None arg_name = None
if len(tokens) > 2: if len(tokens) > 2:
arg_name = tokens[2] arg_name = tokens[2]
inf = Macro(name, arg_name) nnames = tokens[1].split(":")
if name in self.macros: if len(nnames) == 2:
sys.stderr.write("Replacing macro: %s\n" % name) inf = Macro(nnames[1], arg_name)
self.macros[name] = inf if nnames[0] == self.gen:
self.macros[nnames[1]] = inf
else:
inf = Macro(nnames[0], arg_name)
if None == self.gen:
if nnames[0] in self.macros:
sys.stderr.write("Replacing macro: %s\n" % nnames[0])
self.macros[nnames[0]] = inf
else:
if not nnames[0] in self.macros:
self.macros[nnames[0]] = inf
else: else:
ntokens = tokens[0].split(":") ntokens = tokens[0].split(":")
if len(ntokens) == 2: if len(ntokens) == 2:
inf = Opcode(ntokens[1]) inf = Opcode(ntokens[1])
if ntokens[0] == self.gen: if ntokens[0] == self.gen:
self.opcode_info.append(inf) # Replace in list when already present, otherwise append
found = False
found_index = 0
for i in range(len(self.opcode_info)):
if self.opcode_info[i].code == inf.code:
found = True
found_index = i
if found:
self.opcode_info[found_index] = inf
else:
self.opcode_info.append(inf)
else: else:
inf = Opcode(ntokens[0]) inf = Opcode(ntokens[0])
if None == self.gen: if None == self.gen:
self.opcode_info.append(inf) self.opcode_info.append(inf)
else:
# Only place in list when not already present
found = False
for i in range(len(self.opcode_info)):
if self.opcode_info[i].code == inf.code:
found = True
if not found:
self.opcode_info.append(inf)
def pre_process(self, iline): def pre_process(self, iline):
out = [] out = []