summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z8
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/z8')
-rw-r--r--src/devices/cpu/z8/z8.cpp104
-rw-r--r--src/devices/cpu/z8/z8.h55
-rw-r--r--src/devices/cpu/z8/z8dasm.cpp35
-rw-r--r--src/devices/cpu/z8/z8ops.hxx40
4 files changed, 141 insertions, 93 deletions
diff --git a/src/devices/cpu/z8/z8.cpp b/src/devices/cpu/z8/z8.cpp
index 6f916fd4d3f..adf82562f04 100644
--- a/src/devices/cpu/z8/z8.cpp
+++ b/src/devices/cpu/z8/z8.cpp
@@ -15,12 +15,24 @@
- internal diagnostic ROM in data space (requires high voltage reset)
- what really happens when register pairs are unaligned?
+ Note that A8–A15 outputs are not enabled on Port 0 upon reset, except
+ on some later ROMless versions such as Z8691. This may redirect
+ external memory accesses, including program fetches, to FFxx until
+ P01M is written to. Z8681 is particularly affected by this.
+
*/
#include "emu.h"
#include "z8.h"
#include "z8dasm.h"
-#include "debugger.h"
+
+#define LOG_TIMER (1U << 1)
+#define LOG_RECEIVE (1U << 2)
+#define LOG_TRANSMIT (1U << 3)
+#define LOG_IRQ (1U << 4)
+
+#define VERBOSE 0
+#include "logmacro.h"
/***************************************************************************
CONSTANTS
@@ -119,6 +131,7 @@ DEFINE_DEVICE_TYPE(Z8611, z8611_device, "z8611", "Zilog Z8611")
DEFINE_DEVICE_TYPE(Z8671, z8671_device, "z8671", "Zilog Z8671")
DEFINE_DEVICE_TYPE(Z8681, z8681_device, "z8681", "Zilog Z8681")
DEFINE_DEVICE_TYPE(Z8682, z8682_device, "z8682", "Zilog Z8682")
+DEFINE_DEVICE_TYPE(Z86E02, z86e02_device, "z86e02", "Zilog Z86E02")
/***************************************************************************
@@ -138,6 +151,7 @@ void z8_device::preprogrammed_map(address_map &map)
void z8_device::register_map(address_map &map)
{
+ map.unmap_value_high();
map(0x00, 0x00).rw(FUNC(z8_device::p0_read), FUNC(z8_device::p0_write));
map(0x01, 0x01).rw(FUNC(z8_device::p1_read), FUNC(z8_device::p1_write));
map(0x02, 0x02).rw(FUNC(z8_device::p2_read), FUNC(z8_device::p2_write));
@@ -167,8 +181,8 @@ z8_device::z8_device(const machine_config &mconfig, device_type type, const char
, m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, preprogrammed ? address_map_constructor(FUNC(z8_device::preprogrammed_map), this) : address_map_constructor(FUNC(z8_device::program_map), this))
, m_data_config("data", ENDIANNESS_BIG, 8, 16, 0)
, m_register_config("register", ENDIANNESS_BIG, 8, 8, 0, address_map_constructor(FUNC(z8_device::register_map), this))
- , m_input_cb{{*this}, {*this}, {*this}, {*this}}
- , m_output_cb{{*this}, {*this}, {*this}, {*this}}
+ , m_input_cb(*this, 0xff)
+ , m_output_cb(*this)
, m_rom_size(rom_size)
, m_input{0xff, 0xff, 0xff, 0x0f}
{
@@ -233,6 +247,12 @@ const tiny_rom_entry *z8682_device::device_rom_region() const
}
+z86e02_device::z86e02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : z8_device(mconfig, Z86E02, tag, owner, clock, 0x200, false)
+{
+}
+
+
std::unique_ptr<util::disasm_interface> z8_device::create_disassembler()
{
return std::make_unique<z8_disassembler>();
@@ -286,7 +306,7 @@ uint16_t z8_device::mask_external_address(uint16_t addr)
uint8_t z8_device::fetch()
{
uint16_t real_pc = (m_pc < m_rom_size) ? m_pc : mask_external_address(m_pc);
- uint8_t data = m_cache->read_byte(real_pc);
+ uint8_t data = m_cache.read_byte(real_pc);
m_pc++;
@@ -299,7 +319,7 @@ uint8_t z8_device::fetch_opcode()
m_ppc = (m_pc < m_rom_size) ? m_pc : mask_external_address(m_pc);
debugger_instruction_hook(m_ppc);
- uint8_t data = m_cache->read_byte(m_ppc);
+ uint8_t data = m_cache.read_byte(m_ppc);
m_pc++;
@@ -319,7 +339,7 @@ uint16_t z8_device::fetch_word()
uint8_t z8_device::p0_read()
{
- uint8_t data = 0xff;
+ uint8_t data = 0;
uint8_t mask = 0;
switch (m_p01m & Z8_P01M_P0L_MODE_MASK)
@@ -373,7 +393,7 @@ void z8_device::p0_write(uint8_t data)
uint8_t z8_device::p1_read()
{
- uint8_t data = 0xff;
+ uint8_t data = 0;
uint8_t mask = 0;
switch (m_p01m & Z8_P01M_P1_MODE_MASK)
@@ -496,6 +516,7 @@ void z8_device::sio_receive()
// start bit validated
m_receive_sr |= 1 << 9;
m_receive_parity = false;
+ LOGMASKED(LOG_RECEIVE, "Start bit validated\n");
}
else
{
@@ -518,6 +539,7 @@ void z8_device::sio_receive()
request_interrupt(3);
m_receive_started = false;
m_receive_count = 0;
+ LOGMASKED(LOG_RECEIVE, "Character received: %02X\n", m_receive_buffer);
}
else
{
@@ -527,11 +549,14 @@ void z8_device::sio_receive()
// parity replaces received bit 7 if selected
if (BIT(m_receive_sr, 1) && (m_p3m & Z8_P3M_PARITY) != 0)
{
+ LOGMASKED(LOG_RECEIVE, "%d parity bit shifted in\n", BIT(m_receive_sr, 9));
if (m_receive_parity)
m_receive_sr |= 1 << 9;
else
m_receive_sr &= ~(1 << 9);
}
+ else
+ LOGMASKED(LOG_RECEIVE, "%d data bit shifted in\n", BIT(m_receive_sr, 9));
}
}
}
@@ -544,6 +569,7 @@ void z8_device::sio_receive()
m_receive_sr |= 1 << 9;
else if (BIT(m_receive_sr, 8))
{
+ LOGMASKED(LOG_RECEIVE, "Start bit noticed\n");
m_receive_started = true;
m_receive_sr = 0;
m_receive_count = 0;
@@ -561,7 +587,10 @@ void z8_device::sio_transmit()
{
m_transmit_sr >>= 1;
if (m_transmit_sr == 0)
+ {
+ LOGMASKED(LOG_TRANSMIT, "Transmit register empty\n");
request_interrupt(4);
+ }
else
{
// parity replaces received bit 7 if selected
@@ -571,9 +600,15 @@ void z8_device::sio_transmit()
m_transmit_sr |= 1;
else
m_transmit_sr &= ~1;
+ LOGMASKED(LOG_TRANSMIT, "%d parity bit shifted out\n", BIT(m_transmit_sr, 0));
+ }
+ else
+ {
+ LOGMASKED(LOG_TRANSMIT, "%d %s bit shifted out\n", BIT(m_transmit_sr, 0),
+ BIT(m_transmit_sr, 10) ? "start" : m_transmit_sr > 3 ? "data" : "stop");
+ if (BIT(m_transmit_sr, 0))
+ m_transmit_parity = !m_transmit_parity;
}
- else if (BIT(m_transmit_sr, 0))
- m_transmit_parity = !m_transmit_parity;
// serial output
p3_update_output();
@@ -588,6 +623,8 @@ uint8_t z8_device::sio_read()
void z8_device::sio_write(uint8_t data)
{
+ LOGMASKED(LOG_TRANSMIT, "(%04X): Character to transmit: %02X\n", m_ppc, data);
+
// overwrite shift register with data + 1 start bit + 2 stop bits
m_transmit_sr = (m_transmit_sr & 1) | (uint16_t(data) << 2) | (3 << 10);
m_transmit_parity = false;
@@ -665,7 +702,7 @@ void z8_device::t1_trigger()
case Z8_TMR_TIN_TRIGGER:
if (m_internal_timer[1]->enabled())
break;
-
+ [[fallthrough]];
case Z8_TMR_TIN_RETRIGGER:
if ((m_tmr & Z8_TMR_ENABLE_T1) != 0)
{
@@ -721,7 +758,7 @@ void z8_device::tmr_write(uint8_t data)
{
unsigned prescaler = (m_pre[0] >> 2) ? (m_pre[0] >> 2) : 64;
unsigned count = (m_t[0] ? m_t[0] : 256) * prescaler;
- logerror("(%04X): Load T0 at %.2f Hz\n", m_ppc, clock() / 8.0 / count);
+ LOGMASKED(LOG_TIMER, "(%04X): Load T0 at %.2f Hz\n", m_ppc, clock() / 8.0 / count);
}
if ((data & Z8_TMR_TOUT_MASK) == Z8_TMR_TOUT_T0)
@@ -745,7 +782,7 @@ void z8_device::tmr_write(uint8_t data)
{
unsigned prescaler = (m_pre[1] >> 2) ? (m_pre[1] >> 2) : 64;
unsigned count = (m_t[1] ? m_t[1] : 256) * prescaler;
- logerror("(%04X): Load T1 at %.2f Hz\n", m_ppc, clock() / 8.0 / count);
+ LOGMASKED(LOG_TIMER, "(%04X): Load T1 at %.2f Hz\n", m_ppc, clock() / 8.0 / count);
}
if ((data & Z8_TMR_TOUT_MASK) == Z8_TMR_TOUT_T1)
@@ -912,12 +949,12 @@ void z8_device::spl_write(uint8_t data)
uint16_t z8_device::register_pair_read(uint8_t offset)
{
- return m_regs->read_word_unaligned(offset);
+ return m_regs.read_word_unaligned(offset);
}
void z8_device::register_pair_write(uint8_t offset, uint16_t data)
{
- m_regs->write_word_unaligned(offset, data);
+ m_regs.write_word_unaligned(offset, data);
}
uint8_t z8_device::get_working_register(int offset) const
@@ -956,7 +993,7 @@ void z8_device::stack_push_byte(uint8_t src)
m_sp.w = sp;
// @SP <- src
- m_data->write_byte(mask_external_address(sp), src);
+ m_data.write_byte(mask_external_address(sp), src);
}
}
@@ -978,7 +1015,7 @@ void z8_device::stack_push_word(uint16_t src)
m_sp.w = sp;
// @SP <- src
- m_data->write_word_unaligned(mask_external_address(sp), src);
+ m_data.write_word_unaligned(mask_external_address(sp), src);
}
}
@@ -999,7 +1036,7 @@ uint8_t z8_device::stack_pop_byte()
{
// @SP <- src
uint16_t sp = m_sp.w;
- uint8_t byte = m_data->read_byte(mask_external_address(sp));
+ uint8_t byte = m_data.read_byte(mask_external_address(sp));
// SP <- SP + 1 (postincrement)
m_sp.w = sp + 1;
@@ -1025,7 +1062,7 @@ uint16_t z8_device::stack_pop_word()
{
// @SP <- src
uint16_t sp = m_sp.w;
- uint16_t word = m_data->read_word_unaligned(mask_external_address(sp));
+ uint16_t word = m_data.read_word_unaligned(mask_external_address(sp));
// SP <- SP + 2 (postincrement)
m_sp.w = sp + 2;
@@ -1173,18 +1210,12 @@ TIMER_CALLBACK_MEMBER(z8_device::timeout)
void z8_device::device_start()
{
- for (auto &cb : m_input_cb)
- cb.resolve_safe(0xff);
- for (auto &cb : m_output_cb)
- cb.resolve_safe();
-
/* set up the state table */
{
state_add(Z8_PC, "PC", m_pc).callimport();
state_add(STATE_GENPC, "GENPC", m_pc).callimport().noshow();
state_add(STATE_GENPCBASE, "CURPC", m_ppc).callimport().noshow();
state_add(Z8_SP, "SP", m_sp.w);
- state_add(STATE_GENSP, "GENSP", m_sp.w).noshow();
state_add(Z8_RP, "RP", m_rp);
state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).noshow().formatstr("%6s");
state_add(Z8_IMR, "IMR", m_imr);
@@ -1221,14 +1252,14 @@ void z8_device::device_start()
}
/* find address spaces */
- m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<0, 0, ENDIANNESS_BIG>();
- m_data = has_space(AS_DATA) ? &space(AS_DATA) : m_program;
- m_regs = &space(AS_IO);
+ space(AS_PROGRAM).cache(m_cache);
+ space(AS_PROGRAM).specific(m_program);
+ space(has_space(AS_DATA) ? AS_DATA : AS_PROGRAM).specific(m_data);
+ space(AS_IO).specific(m_regs);
/* allocate timers */
- m_internal_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z8_device::timeout<0>), this));
- m_internal_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(z8_device::timeout<1>), this));
+ m_internal_timer[0] = timer_alloc(FUNC(z8_device::timeout<0>), this);
+ m_internal_timer[1] = timer_alloc(FUNC(z8_device::timeout<1>), this);
/* Clear state */
std::fill(std::begin(m_irq_line), std::end(m_irq_line), CLEAR_LINE);
@@ -1301,7 +1332,10 @@ void z8_device::request_interrupt(int irq)
assert(irq >= 0 && irq < 6);
if (m_irq_initialized)
+ {
m_irq |= 1 << irq;
+ LOGMASKED(LOG_IRQ, "%s: IRQ%d requested\n", machine().time().to_string(), irq);
+ }
}
void z8_device::take_interrupt(int irq)
@@ -1314,7 +1348,7 @@ void z8_device::take_interrupt(int irq)
// acknowledge the IRQ
m_irq &= ~(1 << irq);
- standard_irq_callback(irq);
+ standard_irq_callback(irq, m_pc);
// get the interrupt vector address
uint16_t vector = irq * 2;
@@ -1326,8 +1360,8 @@ void z8_device::take_interrupt(int irq)
stack_push_byte(m_flags);
// branch to the vector
- m_pc = m_cache->read_byte(vector) << 8;
- m_pc |= m_cache->read_byte(vector + 1);
+ m_pc = m_cache.read_byte(vector) << 8;
+ m_pc |= m_cache.read_byte(vector + 1);
}
void z8_device::process_interrupts()
@@ -1539,6 +1573,7 @@ void z8_device::execute_set_input(int inputnum, int state)
{
switch ( inputnum )
{
+ // IRQ0 input is P32 (also DAV0/RDY0 handshake, not emulated)
case INPUT_LINE_IRQ0:
if (state != CLEAR_LINE && m_irq_line[0] == CLEAR_LINE)
request_interrupt(0);
@@ -1551,6 +1586,7 @@ void z8_device::execute_set_input(int inputnum, int state)
break;
+ // IRQ1 input is P33
case INPUT_LINE_IRQ1:
if (state != CLEAR_LINE && m_irq_line[1] == CLEAR_LINE)
request_interrupt(1);
@@ -1563,6 +1599,7 @@ void z8_device::execute_set_input(int inputnum, int state)
break;
+ // IRQ2 input is P31 (also TIN and DAV2/RDY2 handshake, latter not emulated)
case INPUT_LINE_IRQ2:
if (state != CLEAR_LINE && m_irq_line[2] == CLEAR_LINE)
request_interrupt(2);
@@ -1583,6 +1620,7 @@ void z8_device::execute_set_input(int inputnum, int state)
break;
+ // IRQ3 input is P30 (also serial DI)
case INPUT_LINE_IRQ3:
if (state != CLEAR_LINE && m_irq_line[3] == CLEAR_LINE && (m_p3m & Z8_P3M_P3_SERIAL) == 0)
request_interrupt(3);
diff --git a/src/devices/cpu/z8/z8.h b/src/devices/cpu/z8/z8.h
index 0411fb4e2bd..c50b40b140b 100644
--- a/src/devices/cpu/z8/z8.h
+++ b/src/devices/cpu/z8/z8.h
@@ -42,16 +42,15 @@ protected:
z8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t rom_size, bool preprogrammed);
// device-level overrides
- virtual void device_start() override;
- virtual void device_reset() override;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
// device_execute_interface overrides
- virtual uint32_t execute_min_cycles() const override { return 6; }
- virtual uint32_t execute_max_cycles() const override { return 27; }
- virtual uint32_t execute_input_lines() const override { return 4; }
- virtual bool execute_input_edge_triggered(int inputnum) const override { return true; }
- virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 2 - 1) / 2; }
- virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 2); }
+ virtual uint32_t execute_min_cycles() const noexcept override { return 6; }
+ virtual uint32_t execute_max_cycles() const noexcept override { return 27; }
+ virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return true; }
+ virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 2 - 1) / 2; }
+ virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 2); }
virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override;
@@ -65,23 +64,23 @@ protected:
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
- void program_map(address_map &map);
- void preprogrammed_map(address_map &map);
- void register_map(address_map &map);
+ void program_map(address_map &map) ATTR_COLD;
+ void preprogrammed_map(address_map &map) ATTR_COLD;
+ void register_map(address_map &map) ATTR_COLD;
private:
address_space_config m_program_config;
address_space_config m_data_config;
address_space_config m_register_config;
- address_space *m_program;
- memory_access_cache<0, 0, ENDIANNESS_BIG> *m_cache;
- address_space *m_data;
- address_space *m_regs;
+ memory_access<16, 0, 0, ENDIANNESS_BIG>::cache m_cache;
+ memory_access<16, 0, 0, ENDIANNESS_BIG>::specific m_program;
+ memory_access<16, 0, 0, ENDIANNESS_BIG>::specific m_data;
+ memory_access< 8, 0, 0, ENDIANNESS_BIG>::specific m_regs;
// callbacks
- devcb_read8 m_input_cb[4];
- devcb_write8 m_output_cb[4];
+ devcb_read8::array<4> m_input_cb;
+ devcb_write8::array<4> m_output_cb;
uint32_t m_rom_size;
@@ -191,9 +190,9 @@ private:
inline uint8_t fetch();
inline uint8_t fetch_opcode();
inline uint16_t fetch_word();
- inline uint8_t register_read(uint8_t offset) { return m_regs->read_byte(offset); }
+ inline uint8_t register_read(uint8_t offset) { return m_regs.read_byte(offset); }
inline uint16_t register_pair_read(uint8_t offset);
- inline void register_write(uint8_t offset, uint8_t data) { m_regs->write_byte(offset, data); }
+ inline void register_write(uint8_t offset, uint8_t data) { m_regs.write_byte(offset, data); }
inline void register_pair_write(uint8_t offset, uint16_t data);
inline uint8_t get_working_register(int offset) const;
inline uint8_t get_register(uint8_t offset) const;
@@ -205,10 +204,10 @@ private:
inline void set_flag(uint8_t flag, int state);
inline void clear(uint8_t dst);
inline void load(uint8_t dst, uint8_t src);
- inline void load_from_memory(address_space &space);
- inline void load_to_memory(address_space &space);
- inline void load_from_memory_autoinc(address_space &space);
- inline void load_to_memory_autoinc(address_space &space);
+ inline void load_from_memory(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space);
+ inline void load_to_memory(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space);
+ inline void load_from_memory_autoinc(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space);
+ inline void load_to_memory_autoinc(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space);
inline void pop(uint8_t dst);
inline void push(uint8_t src);
inline void add_carry(uint8_t dst, uint8_t src);
@@ -428,6 +427,13 @@ protected:
};
+class z86e02_device : public z8_device
+{
+public:
+ z86e02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+
// Zilog Z8601
DECLARE_DEVICE_TYPE(Z8601, z8601_device)
@@ -446,4 +452,7 @@ DECLARE_DEVICE_TYPE(Z8681, z8681_device)
// Zilog Z8682 ROMless (boot to 0812H)
DECLARE_DEVICE_TYPE(Z8682, z8682_device)
+// Zilog Z86E02
+DECLARE_DEVICE_TYPE(Z86E02, z86e02_device)
+
#endif // MAME_CPU_Z8_Z8_H
diff --git a/src/devices/cpu/z8/z8dasm.cpp b/src/devices/cpu/z8/z8dasm.cpp
index 08e50ca1eae..beef0da436a 100644
--- a/src/devices/cpu/z8/z8dasm.cpp
+++ b/src/devices/cpu/z8/z8dasm.cpp
@@ -60,7 +60,7 @@ const char *const z8_disassembler::CONDITION_CODE[16] =
#define ARG(_formatting, _value) { if (argc) util::stream_format(stream, ", "); util::stream_format(stream, _formatting, _value); argc++; }
#define arg_name(_value) ARG("%s", REGISTER_NAME[_value])
-#define arg_cc ARG("%s", CONDITION_CODE[OPH])
+#define arg_cc { ARG("%s", CONDITION_CODE[OPH]); if (OPH & 0x0e) step_cond; }
#define arg_r(_value) ARG(r, _value)
#define arg_Ir(_value) ARG(Ir, _value)
#define arg_Irr(_value) ARG(Irr, _value & 0x0f)
@@ -78,6 +78,7 @@ const char *const z8_disassembler::CONDITION_CODE[16] =
#define bytes(_count) pos += (_count - 1)
#define step_over flags = STEP_OVER
#define step_out flags = STEP_OUT
+#define step_cond flags = STEP_COND
/***************************************************************************
DISASSEMBLER
@@ -117,7 +118,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x07: mnemonic("ADD"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x08: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x09: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x0a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x0a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x0b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x0c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x0d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -134,7 +135,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x17: mnemonic("ADC"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x18: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x19: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x1a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x1a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x1b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x1c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x1d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -151,7 +152,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x27: mnemonic("SUB"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x28: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x29: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x2a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x2a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x2b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x2c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x2d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -168,7 +169,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x37: mnemonic("SBC"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x38: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x39: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x3a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x3a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x3b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x3c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x3d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -185,7 +186,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x47: mnemonic("OR"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x48: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x49: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x4a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x4a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x4b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x4c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x4d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -202,7 +203,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x57: mnemonic("AND"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x58: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x59: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x5a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x5a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x5b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x5c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x5d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -219,7 +220,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x67: mnemonic("TCM"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x68: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x69: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x6a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x6a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x6b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x6c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x6d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -236,7 +237,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x77: mnemonic("TM"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0x78: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x79: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x7a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x7a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x7b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x7c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x7d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -253,7 +254,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x87: illegal; break;
case 0x88: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x89: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x8a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x8a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x8b: mnemonic("JR"); arg_RA; bytes(2); break;
case 0x8c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x8d: mnemonic("JP"); arg_DA; bytes(3); break;
@@ -270,7 +271,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0x97: illegal; break;
case 0x98: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0x99: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0x9a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0x9a: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0x9b: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0x9c: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0x9d: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -287,7 +288,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xa7: mnemonic("CP"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0xa8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xa9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xaa: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xaa: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xab: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xac: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xad: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -304,7 +305,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xb7: mnemonic("XOR"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0xb8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xb9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xba: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xba: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xbb: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xbc: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xbd: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -321,7 +322,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xc7: mnemonic("LD"); arg_r(B0H); arg_X(B1, B0L); bytes(3); break;
case 0xc8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xc9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xca: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xca: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xcb: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xcc: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xcd: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -338,7 +339,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xd7: mnemonic("LD"); arg_r(B0L); arg_X(B1, B0H); bytes(3); break;
case 0xd8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xd9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xda: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xda: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xdb: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xdc: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xdd: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -355,7 +356,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xe7: mnemonic("LD"); arg_IR(B0); arg_IM(B1); bytes(3); break;
case 0xe8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xe9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xea: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xea: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xeb: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xec: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xed: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
@@ -372,7 +373,7 @@ offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_
case 0xf7: illegal; break;
case 0xf8: mnemonic("LD"); arg_r(OPH); arg_R(B0); bytes(2); break;
case 0xf9: mnemonic("LD"); arg_R(B0); arg_r(OPH); bytes(2); break;
- case 0xfa: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_over; break;
+ case 0xfa: mnemonic("DJNZ"); arg_r(OPH); arg_RA; bytes(2); step_cond; break;
case 0xfb: mnemonic("JR"); arg_cc; arg_RA; bytes(2); break;
case 0xfc: mnemonic("LD"); arg_r(OPH); arg_IM(B0); bytes(2); break;
case 0xfd: mnemonic("JP"); arg_cc; arg_DA; bytes(3); break;
diff --git a/src/devices/cpu/z8/z8ops.hxx b/src/devices/cpu/z8/z8ops.hxx
index b1cfae93970..e49b54ac8e5 100644
--- a/src/devices/cpu/z8/z8ops.hxx
+++ b/src/devices/cpu/z8/z8ops.hxx
@@ -139,7 +139,7 @@ INSTRUCTION( ld_IR2_R1 ) { mode_IR2_R1(load) }
INSTRUCTION( ld_R1_IM ) { mode_R1_IM(load) }
INSTRUCTION( ld_IR1_IM ) { mode_IR1_IM(load) }
-void z8_device::load_from_memory(address_space &space)
+void z8_device::load_from_memory(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space)
{
uint8_t operands = fetch();
uint8_t dst = get_working_register(operands >> 4);
@@ -148,29 +148,29 @@ void z8_device::load_from_memory(address_space &space)
uint16_t address = register_pair_read(src);
uint8_t data;
- if (&space == m_program && address < m_rom_size)
- data = m_cache->read_byte(address);
+ if (space.space().spacenum() == AS_PROGRAM && address < m_rom_size)
+ data = m_cache.read_byte(address);
else
data = space.read_byte(mask_external_address(address));
register_write(dst, data);
}
-void z8_device::load_to_memory(address_space &space)
+void z8_device::load_to_memory(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space)
{
uint8_t operands = fetch();
uint8_t src = get_working_register(operands >> 4);
uint8_t dst = get_working_register(operands & 0x0f);
uint16_t address = register_pair_read(dst);
- if (&space != m_program || address >= m_rom_size)
+ if (space.space().spacenum() != AS_PROGRAM || address >= m_rom_size)
address = mask_external_address(address);
uint8_t data = register_read(src);
space.write_byte(address, data);
}
-void z8_device::load_from_memory_autoinc(address_space &space)
+void z8_device::load_from_memory_autoinc(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space)
{
uint8_t operands = fetch();
uint8_t dst = get_working_register(operands >> 4);
@@ -180,8 +180,8 @@ void z8_device::load_from_memory_autoinc(address_space &space)
uint16_t address = register_pair_read(src);
uint8_t data;
- if (&space == m_program && address < m_rom_size)
- data = m_cache->read_byte(address);
+ if (space.space().spacenum() == AS_PROGRAM && address < m_rom_size)
+ data = m_cache.read_byte(address);
else
data = space.read_byte(mask_external_address(address));
register_write(real_dst, data);
@@ -190,7 +190,7 @@ void z8_device::load_from_memory_autoinc(address_space &space)
register_pair_write(src, address + 1);
}
-void z8_device::load_to_memory_autoinc(address_space &space)
+void z8_device::load_to_memory_autoinc(memory_access<16, 0, 0, ENDIANNESS_BIG>::specific &space)
{
uint8_t operands = fetch();
uint8_t src = get_working_register(operands >> 4);
@@ -200,7 +200,7 @@ void z8_device::load_to_memory_autoinc(address_space &space)
uint16_t address = register_pair_read(dst);
uint8_t data = register_read(real_src);
- if (&space != m_program || address >= m_rom_size)
+ if (space.space().spacenum() == AS_PROGRAM || address >= m_rom_size)
address = mask_external_address(address);
space.write_byte(address, data);
@@ -208,14 +208,14 @@ void z8_device::load_to_memory_autoinc(address_space &space)
register_write(src, real_src + 1);
}
-INSTRUCTION( ldc_r1_Irr2 ) { load_from_memory(*m_program); }
-INSTRUCTION( ldc_r2_Irr1 ) { load_to_memory(*m_program); }
-INSTRUCTION( ldci_Ir1_Irr2 ) { load_from_memory_autoinc(*m_program); }
-INSTRUCTION( ldci_Ir2_Irr1 ) { load_to_memory_autoinc(*m_program); }
-INSTRUCTION( lde_r1_Irr2 ) { load_from_memory(*m_data); }
-INSTRUCTION( lde_r2_Irr1 ) { load_to_memory(*m_data); }
-INSTRUCTION( ldei_Ir1_Irr2 ) { load_from_memory_autoinc(*m_data); }
-INSTRUCTION( ldei_Ir2_Irr1 ) { load_to_memory_autoinc(*m_data); }
+INSTRUCTION( ldc_r1_Irr2 ) { load_from_memory(m_program); }
+INSTRUCTION( ldc_r2_Irr1 ) { load_to_memory(m_program); }
+INSTRUCTION( ldci_Ir1_Irr2 ) { load_from_memory_autoinc(m_program); }
+INSTRUCTION( ldci_Ir2_Irr1 ) { load_to_memory_autoinc(m_program); }
+INSTRUCTION( lde_r1_Irr2 ) { load_from_memory(m_data); }
+INSTRUCTION( lde_r2_Irr1 ) { load_to_memory(m_data); }
+INSTRUCTION( ldei_Ir1_Irr2 ) { load_from_memory_autoinc(m_data); }
+INSTRUCTION( ldei_Ir2_Irr1 ) { load_to_memory_autoinc(m_data); }
void z8_device::pop(uint8_t dst)
{
@@ -325,7 +325,7 @@ void z8_device::decimal_adjust(uint8_t dst)
if (flag(C) | (data>0x99)) new_data+=0x60;
}
- set_flag_c(new_data & 0x100);
+ set_flag_c(flag(C)|(new_data & 0x100));
set_flag_s(new_data & 0x80);
new_data &= 0xff;
set_flag_z(new_data == 0);
@@ -777,7 +777,7 @@ INSTRUCTION( swap_IR1 ) { mode_IR1(swap) }
INSTRUCTION( ccf ) { m_flags ^= Z8_FLAGS_C; }
INSTRUCTION( di ) { m_imr &= ~Z8_IMR_ENABLE; }
-INSTRUCTION( ei ) { m_imr |= Z8_IMR_ENABLE; m_irq_initialized = true; }
+INSTRUCTION( ei ) { m_imr |= Z8_IMR_ENABLE; if (!m_irq_initialized) LOGMASKED(LOG_IRQ, "(%04X): IRQs first enabled\n", m_ppc); m_irq_initialized = true; }
INSTRUCTION( nop ) { /* no operation */ }
INSTRUCTION( rcf ) { set_flag_c(0); }
INSTRUCTION( scf ) { set_flag_c(1); }