diff options
Diffstat (limited to 'src/devices/cpu/h8/h8.cpp')
-rw-r--r-- | src/devices/cpu/h8/h8.cpp | 620 |
1 files changed, 363 insertions, 257 deletions
diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 338023eab12..6e0991a991d 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -2,10 +2,20 @@ // copyright-holders:Olivier Galibert /*************************************************************************** - h8.h + h8.cpp H8-300 base cpu emulation + TODO: + - use logmacro and be quiet by default, same for H8 peripherals that + currently have "static constexpr int V" + - Verify H8H opcode map, some opcodes currently for H8H are H8S-only. + Base H8/300 (eg. H8/325) opcode map is correct. + - NVRAM won't work properly when it goes into SSBY (software standby + mode) and the power button triggers an IRQ to wake up instead of RES. + Obviously, MAME always starts at reset-phase at power-on, so it's more + like a 'known issue' instead of a TODO since it can't really be fixed. + - add STBY pin (hardware standby mode, can only wake up with reset) ***************************************************************************/ @@ -13,28 +23,34 @@ #include "h8.h" #include "h8_dma.h" #include "h8_dtc.h" +#include "h8_port.h" #include "h8d.h" -h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor map_delegate) : +h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor map_delegate) : cpu_device(mconfig, type, tag, owner, clock), + device_nvram_interface(mconfig, *this), m_program_config("program", ENDIANNESS_BIG, 16, 16, 0, map_delegate), + m_internal_ram(*this, "internal_ram"), m_read_adc(*this, 0), - m_read_port(*this, 0), + m_read_port(*this, 0xff), m_write_port(*this), m_sci(*this, "sci%u", 0), m_sci_tx(*this), m_sci_clk(*this), + m_standby_cb(*this), m_PPC(0), m_NPC(0), m_PC(0), m_PIR(0), m_EXR(0), m_CCR(0), m_MAC(0), m_MACF(0), - m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0), m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_required(false), m_irq_nmi(false) + m_TMP1(0), m_TMP2(0), m_TMPR(0), m_inst_state(0), m_inst_substate(0), m_icount(0), m_bcount(0), + m_irq_vector(0), m_taken_irq_vector(0), m_irq_level(0), m_taken_irq_level(0), m_irq_nmi(false), + m_standby_pending(false), m_standby_time(0), m_nvram_defval(0), m_nvram_battery(true) { m_supports_advanced = false; m_mode_advanced = false; m_mode_a20 = false; m_has_exr = false; m_has_mac = false; - m_mac_saturating = false; m_has_trace = false; m_has_hc = true; + nvram_enable_backup(false); // disable nvram by default for(unsigned int i=0; i != m_read_adc.size(); i++) m_read_adc[i].bind().set([this, i]() { return adc_default(i); }); @@ -46,7 +62,8 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char u16 h8_device::adc_default(int adc) { - logerror("read of un-hooked adc %d\n", adc); + if(!machine().side_effects_disabled()) + logerror("read of un-hooked adc %d\n", adc); return 0; } @@ -54,8 +71,9 @@ const char h8_device::port_names[] = "123456789abcdefg"; u8 h8_device::port_default_r(int port) { - logerror("read of un-hooked port %c (PC=%X)\n", port_names[port], m_PPC); - return 0; + if(!machine().side_effects_disabled()) + logerror("read of un-hooked port %c (PC=%X)\n", port_names[port], m_PPC); + return 0xff; } void h8_device::port_default_w(int port, u8 data) @@ -65,7 +83,7 @@ void h8_device::port_default_w(int port, u8 data) void h8_device::device_config_complete() { - uint8_t addrbits = m_mode_advanced ? (m_mode_a20 ? 20 : 24) : 16; + u8 addrbits = m_mode_advanced ? (m_mode_a20 ? 20 : 24) : 16; m_program_config.m_addr_width = m_program_config.m_logaddr_width = addrbits; } @@ -74,14 +92,14 @@ void h8_device::device_start() space(AS_PROGRAM).cache(m_cache); space(AS_PROGRAM).specific(m_program); - uint32_t pcmask = m_mode_advanced ? 0xffffff : 0xffff; - state_add<uint32_t>(H8_PC, "PC", + u32 pcmask = m_mode_advanced ? 0xffffff : 0xffff; + state_add<u32>(H8_PC, "PC", [this]() { return m_NPC; }, - [this](uint32_t pc) { m_PC = m_PPC = m_NPC = pc; m_PIR = read16i(m_PC); m_PC += 2; prefetch_done_noirq_notrace(); } + [this](u32 pc) { m_PC = m_PPC = m_NPC = pc; m_PIR = read16i(m_PC); m_PC += 2; prefetch_done_noirq_notrace(); } ).mask(pcmask); - state_add<uint32_t>(STATE_GENPC, "GENPC", + state_add<u32>(STATE_GENPC, "GENPC", [this]() { return m_NPC; }, - [this](uint32_t pc) { m_PC = m_PPC = m_NPC = pc; m_PIR = read16i(m_PC); m_PC += 2; prefetch_done_noirq_notrace(); } + [this](u32 pc) { m_PC = m_PPC = m_NPC = pc; m_PIR = read16i(m_PC); m_PC += 2; prefetch_done_noirq_notrace(); } ).mask(pcmask).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_PPC).mask(pcmask).noshow(); state_add(H8_CCR, "CCR", m_CCR); @@ -128,6 +146,9 @@ void h8_device::device_start() state_add(H8_R7, "ER7", m_TMPR).callimport().callexport().formatstr("%9s"); } + save_item(NAME(m_current_dma)); + save_item(NAME(m_cycles_base)); + save_item(NAME(m_PPC)); save_item(NAME(m_NPC)); save_item(NAME(m_PC)); @@ -136,16 +157,25 @@ void h8_device::device_start() save_item(NAME(m_R)); save_item(NAME(m_EXR)); save_item(NAME(m_CCR)); + save_item(NAME(m_MAC)); + save_item(NAME(m_MACF)); save_item(NAME(m_TMP1)); save_item(NAME(m_TMP2)); + save_item(NAME(m_TMPR)); + save_item(NAME(m_inst_state)); save_item(NAME(m_inst_substate)); + save_item(NAME(m_requested_state)); + save_item(NAME(m_bcount)); + save_item(NAME(m_count_before_instruction_step)); save_item(NAME(m_irq_vector)); save_item(NAME(m_taken_irq_vector)); save_item(NAME(m_irq_level)); save_item(NAME(m_taken_irq_level)); save_item(NAME(m_irq_nmi)); - save_item(NAME(m_current_dma)); + save_item(NAME(m_standby_pending)); + save_item(NAME(m_standby_time)); + save_item(NAME(m_nvram_battery)); set_icountptr(m_icount); @@ -170,6 +200,7 @@ void h8_device::device_start() void h8_device::device_reset() { + m_cycles_base = machine().time().as_ticks(clock()); m_inst_state = STATE_RESET; m_inst_substate = 0; m_count_before_instruction_step = 0; @@ -182,8 +213,72 @@ void h8_device::device_reset() m_taken_irq_level = -1; m_current_dma = -1; m_current_dtc = nullptr; + + m_standby_pending = false; + m_standby_cb(0); +} + + +// nvram handling + +bool h8_device::nvram_write(util::write_stream &file) +{ + // if it's currently not battery-backed, don't save at all + if(!m_nvram_battery) + return true; + + // internal RAM + if(m_internal_ram) { + auto const [err, actual] = write(file, &m_internal_ram[0], m_internal_ram.bytes()); + if(err) + return false; + } + + // I/O ports + for(h8_port_device &port : h8_port_device_enumerator(*this)) { + if(!port.nvram_write(file)) + return false; + } + + return true; +} + +bool h8_device::nvram_read(util::read_stream &file) +{ + // internal RAM + if(m_internal_ram) { + auto const [err, actual] = read(file, &m_internal_ram[0], m_internal_ram.bytes()); + if (err || (m_internal_ram.bytes() != actual)) + return false; + } + + // I/O ports + for(h8_port_device &port : h8_port_device_enumerator(*this)) { + if(!port.nvram_read(file)) + return false; + } + + return true; +} + +void h8_device::nvram_default() +{ + if(!nvram_backup_enabled() || !m_internal_ram) + return; + + // default nvram from mytag:nvram region if it exists (only the internal RAM for now) + memory_region *region = memregion("nvram"); + if(region != nullptr) { + if(region->bytes() != m_internal_ram.bytes()) + fatalerror("%s: Wrong region size (expected 0x%x, found 0x%x)", region->name(), m_internal_ram.bytes(), region->bytes()); + + std::copy_n(®ion->as_u16(), m_internal_ram.length(), &m_internal_ram[0]); + } + else + std::fill_n(&m_internal_ram[0], m_internal_ram.length(), m_nvram_defval); } + bool h8_device::trigger_dma(int vector) { bool dma_triggered = false; @@ -232,27 +327,7 @@ void h8_device::request_state(int state) m_requested_state = state; } -uint32_t h8_device::execute_min_cycles() const noexcept -{ - return 1; -} - -uint32_t h8_device::execute_max_cycles() const noexcept -{ - return 1; -} - -uint32_t h8_device::execute_input_lines() const noexcept -{ - return 0; -} - -bool h8_device::execute_input_edge_triggered(int inputnum) const noexcept -{ - return inputnum == INPUT_LINE_NMI; -} - -void h8_device::recompute_bcount(uint64_t event_time) +void h8_device::recompute_bcount(u64 event_time) { if(!event_time || event_time >= total_cycles() + m_icount) { m_bcount = 0; @@ -282,7 +357,7 @@ void h8_device::execute_run() while(m_icount > m_bcount) { if(m_inst_state < 0x10000) { m_PPC = m_NPC; - if(machine().debug_flags & DEBUG_FLAG_ENABLED) + if(debugger_enabled()) debugger_instruction_hook(m_NPC); } do_exec_full(); @@ -299,7 +374,7 @@ void h8_device::execute_run() } } -void h8_device::add_event(uint64_t &event_time, uint64_t new_event) +void h8_device::add_event(u64 &event_time, u64 new_event) { if(!new_event) return; @@ -412,33 +487,48 @@ void h8_device::state_string_export(const device_state_entry &entry, std::string // FIXME: one-state bus cycles are only provided for on-chip ROM & RAM in H8S/2000 and H8S/2600. // All other accesses take *at least* two states each, and additional wait states are often programmed for external memory! -uint16_t h8_device::read16i(uint32_t adr) +u16 h8_device::read16i(u32 adr) { - m_icount--; + if(m_has_exr) + m_icount--; + else + m_icount -= 2; return m_cache.read_word(adr & ~1); } -uint8_t h8_device::read8(uint32_t adr) +u8 h8_device::read8(u32 adr) { - m_icount--; + if(m_has_exr) + m_icount--; + else + m_icount -= 2; return m_program.read_byte(adr); } -void h8_device::write8(uint32_t adr, uint8_t data) +void h8_device::write8(u32 adr, u8 data) { - m_icount--; + if(m_has_exr) + m_icount--; + else + m_icount -= 2; m_program.write_byte(adr, data); } -uint16_t h8_device::read16(uint32_t adr) +u16 h8_device::read16(u32 adr) { - m_icount--; + if(m_has_exr) + m_icount--; + else + m_icount -= 2; return m_program.read_word(adr & ~1); } -void h8_device::write16(uint32_t adr, uint16_t data) +void h8_device::write16(u32 adr, u16 data) { - m_icount--; + if(m_has_exr) + m_icount--; + else + m_icount -= 2; m_program.write_word(adr & ~1, data); } @@ -447,6 +537,13 @@ bool h8_device::exr_in_stack() const return false; } +void h8_device::take_interrupt() +{ + m_inst_state = STATE_IRQ; + m_taken_irq_vector = m_irq_vector; + m_taken_irq_level = m_irq_level; +} + void h8_device::prefetch_done() { if(m_requested_state != -1) { @@ -456,11 +553,9 @@ void h8_device::prefetch_done() m_inst_state = STATE_DMA; else if(m_current_dtc) m_inst_state = STATE_DTC; - else if(m_irq_vector) { - m_inst_state = STATE_IRQ; - m_taken_irq_vector = m_irq_vector; - m_taken_irq_level = m_irq_level; - } else if(m_has_trace && (m_EXR & EXR_T) && exr_in_stack()) + else if(m_irq_vector) + take_interrupt(); + else if(m_has_trace && (m_EXR & EXR_T) && exr_in_stack()) m_inst_state = STATE_TRACE; else m_inst_state = m_IR[0] = m_PIR; @@ -474,6 +569,13 @@ void h8_device::prefetch_done_noirq() m_inst_state = m_IR[0] = m_PIR; } +void h8_device::prefetch_done_notrace() +{ + prefetch_done(); + if(m_inst_state == STATE_TRACE) + m_inst_state = m_IR[0] = m_PIR; +} + void h8_device::prefetch_done_noirq_notrace() { m_inst_state = m_IR[0] = m_PIR; @@ -484,15 +586,23 @@ void h8_device::set_irq(int irq_vector, int irq_level, bool irq_nmi) m_irq_vector = irq_vector; m_irq_level = irq_level; m_irq_nmi = irq_nmi; + + // wake up from software standby with an external interrupt + if(standby() && m_irq_vector) { + notify_standby(0); + resume(SUSPEND_REASON_CLOCK); + m_standby_cb(0); + take_interrupt(); + } } void h8_device::internal(int cycles) { - m_icount -= cycles; - - // All internal operations take an even number of states (at least 2 each) on H8/300L and H8/300H + // on H8/300, H8/300L, H8/300H (not H8S), all internal operations take an even number of states (at least 2 each) if(!m_has_exr) - m_icount--; + m_icount -= cycles + 1; + else + m_icount -= cycles; } void h8_device::illegal() @@ -511,259 +621,255 @@ int h8_device::trapa_setup() throw emu_fatalerror("%s: Trapa setup called but unimplemented.\n", tag()); } -uint8_t h8_device::do_addx8(uint8_t v1, uint8_t v2) +u8 h8_device::do_addx8(u8 v1, u8 v2) { - uint16_t res = v1 + v2 + (m_CCR & F_C ? 1 : 0); - m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; - if(((v1 & 0xf) + (v2 & 0xf) + (m_CCR & F_C ? 1 : 0)) & 0x10) + u8 c = m_CCR & F_C ? 1 : 0; + u16 res = v1 + v2 + c; + m_CCR &= ~(F_N|F_V|F_C); + if(m_has_hc) { + if(((v1 & 0xf) + (v2 & 0xf) + c) & 0x10) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint8_t(res)) - m_CCR |= F_Z; - else if(int8_t(res) < 0) + if(u8(res)) + m_CCR &= ~F_Z; + if(s8(res) < 0) m_CCR |= F_N; if(~(v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; if(res & 0x100) m_CCR |= F_C; return res; - } -uint8_t h8_device::do_subx8(uint8_t v1, uint8_t v2) +u8 h8_device::do_subx8(u8 v1, u8 v2) { - uint16_t res = v1 - v2 - (m_CCR & F_C ? 1 : 0); + u8 c = m_CCR & F_C ? 1 : 0; + u16 res = v1 - v2 - c; m_CCR &= ~(F_N|F_V|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; - if(((v1 & 0xf) - (v2 & 0xf) - (m_CCR & F_C ? 1 : 0)) & 0x10) + if(m_has_hc) { + if(((v1 & 0xf) - (v2 & 0xf) - c) & 0x10) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(uint8_t(res)) + if(u8(res)) m_CCR &= ~F_Z; - if(int8_t(res) < 0) + if(s8(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; if(res & 0x100) m_CCR |= F_C; return res; - } -uint8_t h8_device::do_inc8(uint8_t v1, uint8_t v2) +u8 h8_device::do_inc8(u8 v1, u8 v2) { - uint8_t res = v1 + v2; + u8 res = v1 + v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int8_t(res) < 0) + else if(s8(res) < 0) m_CCR |= F_N; - if((v1^v2) & (v1^res) & 0x80) + if(~(v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; return res; } -uint16_t h8_device::do_inc16(uint16_t v1, uint16_t v2) +u16 h8_device::do_inc16(u16 v1, u16 v2) { - uint16_t res = v1 + v2; + u16 res = v1 + v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int16_t(res) < 0) + else if(s16(res) < 0) m_CCR |= F_N; - if((v1^v2) & (v1^res) & 0x8000) + if(~(v1^v2) & (v1^res) & 0x8000) m_CCR |= F_V; return res; } -uint32_t h8_device::do_inc32(uint32_t v1, uint32_t v2) +u32 h8_device::do_inc32(u32 v1, u32 v2) { - uint32_t res = v1 + v2; + u32 res = v1 + v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int32_t(res) < 0) + else if(s32(res) < 0) m_CCR |= F_N; - if((v1^v2) & (v1^res) & 0x80000000) + if(~(v1^v2) & (v1^res) & 0x80000000) m_CCR |= F_V; return res; } -uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2) +u8 h8_device::do_add8(u8 v1, u8 v2) { - uint16_t res = v1 + v2; + u16 res = v1 + v2; m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; + if(m_has_hc) { if(((v1 & 0xf) + (v2 & 0xf)) & 0x10) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint8_t(res)) + if(!u8(res)) m_CCR |= F_Z; - else if(int8_t(res) < 0) + else if(s8(res) < 0) m_CCR |= F_N; if(~(v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; if(res & 0x100) m_CCR |= F_C; return res; - } -uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2) +u16 h8_device::do_add16(u16 v1, u16 v2) { - uint32_t res = v1 + v2; + u32 res = v1 + v2; m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; - if(((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000) + if(m_has_hc) { + if(((v1 & 0xfff) + (v2 & 0xfff)) & 0x1000) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint16_t(res)) + if(!u16(res)) m_CCR |= F_Z; - else if(int16_t(res) < 0) + else if(s16(res) < 0) m_CCR |= F_N; if(~(v1^v2) & (v1^res) & 0x8000) m_CCR |= F_V; if(res & 0x10000) m_CCR |= F_C; return res; - } -uint32_t h8_device::do_add32(uint32_t v1, uint32_t v2) +u32 h8_device::do_add32(u32 v1, u32 v2) { - uint64_t res = uint64_t(v1) + uint64_t(v2); + u64 res = u64(v1) + u64(v2); m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; + if(m_has_hc) { if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint32_t(res)) + if(!u32(res)) m_CCR |= F_Z; - else if(int32_t(res) < 0) + else if(s32(res) < 0) m_CCR |= F_N; if(~(v1^v2) & (v1^res) & 0x80000000) m_CCR |= F_V; - if(res & 0x100000000U) + if(res & 0x100000000ULL) m_CCR |= F_C; return res; } -uint8_t h8_device::do_dec8(uint8_t v1, uint8_t v2) +u8 h8_device::do_dec8(u8 v1, u8 v2) { - uint8_t res = v1 - v2; + u8 res = v1 - v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int8_t(res) < 0) + else if(s8(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; return res; } -uint16_t h8_device::do_dec16(uint16_t v1, uint16_t v2) +u16 h8_device::do_dec16(u16 v1, u16 v2) { - uint16_t res = v1 - v2; + u16 res = v1 - v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int16_t(res) < 0) + else if(s16(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x8000) m_CCR |= F_V; return res; } -uint32_t h8_device::do_dec32(uint32_t v1, uint32_t v2) +u32 h8_device::do_dec32(u32 v1, u32 v2) { - uint32_t res = v1 - v2; + u32 res = v1 - v2; m_CCR &= ~(F_N|F_V|F_Z); if(!res) m_CCR |= F_Z; - else if(int32_t(res) < 0) + else if(s32(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x80000000) m_CCR |= F_V; return res; } -uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2) +u8 h8_device::do_sub8(u8 v1, u8 v2) { - uint16_t res = v1 - v2; + u16 res = v1 - v2; m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; + if(m_has_hc) { if(((v1 & 0xf) - (v2 & 0xf)) & 0x10) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint8_t(res)) + if(!u8(res)) m_CCR |= F_Z; - else if(int8_t(res) < 0) + else if(s8(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x80) m_CCR |= F_V; if(res & 0x100) m_CCR |= F_C; return res; - } -uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2) +u16 h8_device::do_sub16(u16 v1, u16 v2) { - uint32_t res = v1 - v2; + u32 res = v1 - v2; m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; - if(((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000) + if(m_has_hc) { + if(((v1 & 0xfff) - (v2 & 0xfff)) & 0x1000) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint16_t(res)) + if(!u16(res)) m_CCR |= F_Z; - else if(int16_t(res) < 0) + else if(s16(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x8000) m_CCR |= F_V; if(res & 0x10000) m_CCR |= F_C; return res; - } -uint32_t h8_device::do_sub32(uint32_t v1, uint32_t v2) +u32 h8_device::do_sub32(u32 v1, u32 v2) { - uint64_t res = uint64_t(v1) - uint64_t(v2); + u64 res = u64(v1) - u64(v2); m_CCR &= ~(F_N|F_V|F_Z|F_C); - if(m_has_hc) - { - m_CCR &= ~F_H; + if(m_has_hc) { if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000) m_CCR |= F_H; + else + m_CCR &= ~F_H; } - if(!uint32_t(res)) + if(!u32(res)) m_CCR |= F_Z; - else if(int32_t(res) < 0) + else if(s32(res) < 0) m_CCR |= F_N; if((v1^v2) & (v1^res) & 0x80000000) m_CCR |= F_V; - if(res & 0x100000000U) + if(res & 0x100000000ULL) m_CCR |= F_C; return res; } -uint8_t h8_device::do_shal8(uint8_t v) +u8 h8_device::do_shal8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80) @@ -773,12 +879,12 @@ uint8_t h8_device::do_shal8(uint8_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_shal16(uint16_t v) +u16 h8_device::do_shal16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x8000) @@ -788,12 +894,12 @@ uint16_t h8_device::do_shal16(uint16_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_shal32(uint32_t v) +u32 h8_device::do_shal32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80000000) @@ -803,12 +909,12 @@ uint32_t h8_device::do_shal32(uint32_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_shar8(uint8_t v) +u8 h8_device::do_shar8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -823,7 +929,7 @@ uint8_t h8_device::do_shar8(uint8_t v) return v; } -uint16_t h8_device::do_shar16(uint16_t v) +u16 h8_device::do_shar16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -838,7 +944,7 @@ uint16_t h8_device::do_shar16(uint16_t v) return v; } -uint32_t h8_device::do_shar32(uint32_t v) +u32 h8_device::do_shar32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -853,7 +959,7 @@ uint32_t h8_device::do_shar32(uint32_t v) return v; } -uint8_t h8_device::do_shll8(uint8_t v) +u8 h8_device::do_shll8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80) @@ -861,12 +967,12 @@ uint8_t h8_device::do_shll8(uint8_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_shll16(uint16_t v) +u16 h8_device::do_shll16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x8000) @@ -874,12 +980,12 @@ uint16_t h8_device::do_shll16(uint16_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_shll32(uint32_t v) +u32 h8_device::do_shll32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80000000) @@ -887,12 +993,12 @@ uint32_t h8_device::do_shll32(uint32_t v) v <<= 1; if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_shlr8(uint8_t v) +u8 h8_device::do_shlr8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -903,7 +1009,7 @@ uint8_t h8_device::do_shlr8(uint8_t v) return v; } -uint16_t h8_device::do_shlr16(uint16_t v) +u16 h8_device::do_shlr16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -914,7 +1020,7 @@ uint16_t h8_device::do_shlr16(uint16_t v) return v; } -uint32_t h8_device::do_shlr32(uint32_t v) +u32 h8_device::do_shlr32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 1) @@ -925,7 +1031,7 @@ uint32_t h8_device::do_shlr32(uint32_t v) return v; } -uint8_t h8_device::do_shal2_8(uint8_t v) +u8 h8_device::do_shal2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40) @@ -936,12 +1042,12 @@ uint8_t h8_device::do_shal2_8(uint8_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_shal2_16(uint16_t v) +u16 h8_device::do_shal2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x4000) @@ -952,12 +1058,12 @@ uint16_t h8_device::do_shal2_16(uint16_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_shal2_32(uint32_t v) +u32 h8_device::do_shal2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40000000) @@ -968,12 +1074,12 @@ uint32_t h8_device::do_shal2_32(uint32_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_shar2_8(uint8_t v) +u8 h8_device::do_shar2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -988,7 +1094,7 @@ uint8_t h8_device::do_shar2_8(uint8_t v) return v; } -uint16_t h8_device::do_shar2_16(uint16_t v) +u16 h8_device::do_shar2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -1003,7 +1109,7 @@ uint16_t h8_device::do_shar2_16(uint16_t v) return v; } -uint32_t h8_device::do_shar2_32(uint32_t v) +u32 h8_device::do_shar2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -1018,7 +1124,7 @@ uint32_t h8_device::do_shar2_32(uint32_t v) return v; } -uint8_t h8_device::do_shll2_8(uint8_t v) +u8 h8_device::do_shll2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40) @@ -1026,12 +1132,12 @@ uint8_t h8_device::do_shll2_8(uint8_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_shll2_16(uint16_t v) +u16 h8_device::do_shll2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x4000) @@ -1039,12 +1145,12 @@ uint16_t h8_device::do_shll2_16(uint16_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_shll2_32(uint32_t v) +u32 h8_device::do_shll2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40000000) @@ -1052,12 +1158,12 @@ uint32_t h8_device::do_shll2_32(uint32_t v) v <<= 2; if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_shlr2_8(uint8_t v) +u8 h8_device::do_shlr2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -1068,7 +1174,7 @@ uint8_t h8_device::do_shlr2_8(uint8_t v) return v; } -uint16_t h8_device::do_shlr2_16(uint16_t v) +u16 h8_device::do_shlr2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -1079,7 +1185,7 @@ uint16_t h8_device::do_shlr2_16(uint16_t v) return v; } -uint32_t h8_device::do_shlr2_32(uint32_t v) +u32 h8_device::do_shlr2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 2) @@ -1090,7 +1196,7 @@ uint32_t h8_device::do_shlr2_32(uint32_t v) return v; } -uint8_t h8_device::do_rotl8(uint8_t v) +u8 h8_device::do_rotl8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80) @@ -1098,12 +1204,12 @@ uint8_t h8_device::do_rotl8(uint8_t v) v = (v << 1) | (v >> 7); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotl16(uint16_t v) +u16 h8_device::do_rotl16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x8000) @@ -1111,12 +1217,12 @@ uint16_t h8_device::do_rotl16(uint16_t v) v = (v << 1) | (v >> 15); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotl32(uint32_t v) +u32 h8_device::do_rotl32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80000000) @@ -1124,12 +1230,12 @@ uint32_t h8_device::do_rotl32(uint32_t v) v = (v << 1) | (v >> 31); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotr8(uint8_t v) +u8 h8_device::do_rotr8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x01) @@ -1137,12 +1243,12 @@ uint8_t h8_device::do_rotr8(uint8_t v) v = (v << 7) | (v >> 1); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotr16(uint16_t v) +u16 h8_device::do_rotr16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x0001) @@ -1150,12 +1256,12 @@ uint16_t h8_device::do_rotr16(uint16_t v) v = (v << 15) | (v >> 1); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotr32(uint32_t v) +u32 h8_device::do_rotr32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x00000001) @@ -1163,96 +1269,96 @@ uint32_t h8_device::do_rotr32(uint32_t v) v = (v << 31) | (v >> 1); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotxl8(uint8_t v) +u8 h8_device::do_rotxl8(u8 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80) m_CCR |= F_C; v = (v << 1) | c; if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotxl16(uint16_t v) +u16 h8_device::do_rotxl16(u16 v) { - uint16_t c = m_CCR & F_C ? 1 : 0; + u16 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x8000) m_CCR |= F_C; v = (v << 1) | c; if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotxl32(uint32_t v) +u32 h8_device::do_rotxl32(u32 v) { - uint32_t c = m_CCR & F_C ? 1 : 0; + u32 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x80000000) m_CCR |= F_C; v = (v << 1) | c; if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotxr8(uint8_t v) +u8 h8_device::do_rotxr8(u8 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x01) m_CCR |= F_C; v = (v >> 1) | (c << 7); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotxr16(uint16_t v) +u16 h8_device::do_rotxr16(u16 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x0001) m_CCR |= F_C; v = (v >> 1) | (c << 15); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotxr32(uint32_t v) +u32 h8_device::do_rotxr32(u32 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x00000001) m_CCR |= F_C; v = (v >> 1) | (c << 31); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotl2_8(uint8_t v) +u8 h8_device::do_rotl2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40) @@ -1260,12 +1366,12 @@ uint8_t h8_device::do_rotl2_8(uint8_t v) v = (v << 2) | (v >> 6); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotl2_16(uint16_t v) +u16 h8_device::do_rotl2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x4000) @@ -1273,12 +1379,12 @@ uint16_t h8_device::do_rotl2_16(uint16_t v) v = (v << 2) | (v >> 14); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotl2_32(uint32_t v) +u32 h8_device::do_rotl2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40000000) @@ -1286,12 +1392,12 @@ uint32_t h8_device::do_rotl2_32(uint32_t v) v = (v << 2) | (v >> 30); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotr2_8(uint8_t v) +u8 h8_device::do_rotr2_8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x02) @@ -1299,12 +1405,12 @@ uint8_t h8_device::do_rotr2_8(uint8_t v) v = (v << 6) | (v >> 2); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotr2_16(uint16_t v) +u16 h8_device::do_rotr2_16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x0002) @@ -1312,12 +1418,12 @@ uint16_t h8_device::do_rotr2_16(uint16_t v) v = (v << 14) | (v >> 2); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotr2_32(uint32_t v) +u32 h8_device::do_rotr2_32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x00000002) @@ -1325,137 +1431,137 @@ uint32_t h8_device::do_rotr2_32(uint32_t v) v = (v << 30) | (v >> 2); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotxl2_8(uint8_t v) +u8 h8_device::do_rotxl2_8(u8 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40) m_CCR |= F_C; - v = (v << 2) | (c << 1) | ((v >> 6) & 0x01); + v = (v << 2) | (c << 1) | (v >> 7); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotxl2_16(uint16_t v) +u16 h8_device::do_rotxl2_16(u16 v) { - uint16_t c = m_CCR & F_C ? 1 : 0; + u16 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x4000) m_CCR |= F_C; - v = (v << 2) | (c << 1) | ((v >> 14) & 0x0001); + v = (v << 2) | (c << 1) | (v >> 15); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotxl2_32(uint32_t v) +u32 h8_device::do_rotxl2_32(u32 v) { - uint32_t c = m_CCR & F_C ? 1 : 0; + u32 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x40000000) m_CCR |= F_C; - v = (v << 2) | (c << 1) | ((v >> 30) & 0x00000001); + v = (v << 2) | (c << 1) | (v >> 31); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -uint8_t h8_device::do_rotxr2_8(uint8_t v) +u8 h8_device::do_rotxr2_8(u8 v) { - uint8_t c = m_CCR & F_C ? 1 : 0; + u8 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x02) m_CCR |= F_C; v = (v >> 2) | (c << 6) | (v << 7); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; return v; } -uint16_t h8_device::do_rotxr2_16(uint16_t v) +u16 h8_device::do_rotxr2_16(u16 v) { - uint16_t c = m_CCR & F_C ? 1 : 0; + u16 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x0002) m_CCR |= F_C; v = (v >> 2) | (c << 14) | (v << 15); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; return v; } -uint32_t h8_device::do_rotxr2_32(uint32_t v) +u32 h8_device::do_rotxr2_32(u32 v) { - uint32_t c = m_CCR & F_C ? 1 : 0; + u32 c = m_CCR & F_C ? 1 : 0; m_CCR &= ~(F_N|F_V|F_Z|F_C); if(v & 0x00000002) m_CCR |= F_C; v = (v >> 2) | (c << 30) | (v << 31); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; return v; } -void h8_device::set_nzv8(uint8_t v) +void h8_device::set_nzv8(u8 v) { m_CCR &= ~(F_N|F_V|F_Z); if(!v) m_CCR |= F_Z; - else if(int8_t(v) < 0) + else if(s8(v) < 0) m_CCR |= F_N; } -void h8_device::set_nzv16(uint16_t v) +void h8_device::set_nzv16(u16 v) { m_CCR &= ~(F_N|F_V|F_Z); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; } -void h8_device::set_nzv32(uint32_t v) +void h8_device::set_nzv32(u32 v) { m_CCR &= ~(F_N|F_V|F_Z); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; } -void h8_device::set_nz16(uint16_t v) +void h8_device::set_nz16(u16 v) { m_CCR &= ~(F_N|F_Z); if(!v) m_CCR |= F_Z; - else if(int16_t(v) < 0) + else if(s16(v) < 0) m_CCR |= F_N; } -void h8_device::set_nz32(uint32_t v) +void h8_device::set_nz32(u32 v) { m_CCR &= ~(F_N|F_Z); if(!v) m_CCR |= F_Z; - else if(int32_t(v) < 0) + else if(s32(v) < 0) m_CCR |= F_N; } |