diff options
Diffstat (limited to 'src/devices/cpu/z8')
-rw-r--r-- | src/devices/cpu/z8/z8.cpp | 104 | ||||
-rw-r--r-- | src/devices/cpu/z8/z8.h | 55 | ||||
-rw-r--r-- | src/devices/cpu/z8/z8dasm.cpp | 35 | ||||
-rw-r--r-- | src/devices/cpu/z8/z8ops.hxx | 40 |
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); } |