mirror of
https://github.com/holub/mame
synced 2025-10-05 16:50:57 +03:00
1364 lines
26 KiB
C++
1364 lines
26 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Olivier Galibert
|
|
/***************************************************************************
|
|
|
|
h8.h
|
|
|
|
H8-300 base cpu emulation
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "debugger.h"
|
|
#include "h8.h"
|
|
#include "h8_dma.h"
|
|
#include "h8_dtc.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) :
|
|
cpu_device(mconfig, type, tag, owner, clock),
|
|
program_config("program", ENDIANNESS_BIG, 16, 16, 0, map_delegate),
|
|
io_config("io", ENDIANNESS_BIG, 16, 16, -1), program(nullptr), io(nullptr), cache(nullptr), PPC(0), NPC(0), PC(0), PIR(0), EXR(0), CCR(0), MAC(0), MACF(0),
|
|
TMP1(0), TMP2(0), TMPR(0), inst_state(0), inst_substate(0), icount(0), bcount(0), irq_vector(0), taken_irq_vector(0), irq_level(0), taken_irq_level(0), irq_required(false), irq_nmi(false)
|
|
{
|
|
supports_advanced = false;
|
|
mode_advanced = false;
|
|
mode_a20 = false;
|
|
has_exr = false;
|
|
mac_saturating = false;
|
|
has_trace = false;
|
|
}
|
|
|
|
void h8_device::device_config_complete()
|
|
{
|
|
uint8_t addrbits = mode_advanced ? (mode_a20 ? 20 : 24) : 16;
|
|
program_config.m_addr_width = program_config.m_logaddr_width = addrbits;
|
|
}
|
|
|
|
void h8_device::device_start()
|
|
{
|
|
program = &space(AS_PROGRAM);
|
|
cache = program->cache<1, 0, ENDIANNESS_BIG>();
|
|
io = &space(AS_IO);
|
|
|
|
state_add(STATE_GENPC, "GENPC", NPC).noshow();
|
|
state_add(STATE_GENPCBASE, "CURPC", PPC).noshow();
|
|
if(has_exr)
|
|
state_add(STATE_GENFLAGS, "GENFLAGS", CCR).formatstr("%11s").noshow();
|
|
else
|
|
state_add(STATE_GENFLAGS, "GENFLAGS", CCR).formatstr("%8s").noshow();
|
|
state_add(H8_PC, "PC", NPC);
|
|
state_add(H8_CCR, "CCR", CCR);
|
|
|
|
if(has_exr)
|
|
state_add(H8_EXR, "EXR", EXR);
|
|
if(!supports_advanced) {
|
|
state_add(H8_R0, "R0", R[0]);
|
|
state_add(H8_R1, "R1", R[1]);
|
|
state_add(H8_R2, "R2", R[2]);
|
|
state_add(H8_R3, "R3", R[3]);
|
|
state_add(H8_R4, "R4", R[4]);
|
|
state_add(H8_R5, "R5", R[5]);
|
|
state_add(H8_R6, "R6", R[6]);
|
|
state_add(H8_R7, "R7", R[7]);
|
|
} else {
|
|
state_add(H8_R0, "R0", R[0]).noshow();
|
|
state_add(H8_R1, "R1", R[1]).noshow();
|
|
state_add(H8_R2, "R2", R[2]).noshow();
|
|
state_add(H8_R3, "R3", R[3]).noshow();
|
|
state_add(H8_R4, "R4", R[4]).noshow();
|
|
state_add(H8_R5, "R5", R[5]).noshow();
|
|
state_add(H8_R6, "R6", R[6]).noshow();
|
|
state_add(H8_R7, "R7", R[7]).noshow();
|
|
state_add(H8_E0, "E0", R[8]).noshow();
|
|
state_add(H8_E1, "E1", R[9]).noshow();
|
|
state_add(H8_E2, "E2", R[10]).noshow();
|
|
state_add(H8_E3, "E3", R[11]).noshow();
|
|
state_add(H8_E4, "E4", R[12]).noshow();
|
|
state_add(H8_E5, "E5", R[13]).noshow();
|
|
state_add(H8_E6, "E6", R[14]).noshow();
|
|
state_add(H8_E7, "E7", R[15]).noshow();
|
|
state_add(H8_R0, "ER0", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R1, "ER1", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R2, "ER2", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R3, "ER3", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R4, "ER4", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R5, "ER5", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R6, "ER6", TMPR).callimport().callexport().formatstr("%9s");
|
|
state_add(H8_R7, "ER7", TMPR).callimport().callexport().formatstr("%9s");
|
|
}
|
|
|
|
save_item(NAME(PPC));
|
|
save_item(NAME(NPC));
|
|
save_item(NAME(PC));
|
|
save_item(NAME(PIR));
|
|
save_item(NAME(IR));
|
|
save_item(NAME(R));
|
|
save_item(NAME(EXR));
|
|
save_item(NAME(CCR));
|
|
save_item(NAME(TMP1));
|
|
save_item(NAME(TMP2));
|
|
save_item(NAME(inst_state));
|
|
save_item(NAME(inst_substate));
|
|
save_item(NAME(irq_vector));
|
|
save_item(NAME(taken_irq_vector));
|
|
save_item(NAME(irq_level));
|
|
save_item(NAME(taken_irq_level));
|
|
save_item(NAME(irq_nmi));
|
|
|
|
set_icountptr(icount);
|
|
|
|
PC = 0;
|
|
PPC = 0;
|
|
NPC = 0;
|
|
memset(IR, 0, sizeof(IR));
|
|
memset(R, 0, sizeof(R));
|
|
EXR = 0;
|
|
CCR = 0;
|
|
MAC = 0;
|
|
MACF = 0;
|
|
inst_state = STATE_RESET;
|
|
inst_substate = 0;
|
|
count_before_instruction_step = 0;
|
|
requested_state = -1;
|
|
dma_device = nullptr;
|
|
dtc_device = nullptr;
|
|
}
|
|
|
|
void h8_device::device_reset()
|
|
{
|
|
inst_state = STATE_RESET;
|
|
inst_substate = 0;
|
|
count_before_instruction_step = 0;
|
|
requested_state = -1;
|
|
|
|
irq_vector = 0;
|
|
irq_level = -1;
|
|
irq_nmi = false;
|
|
taken_irq_vector = 0;
|
|
taken_irq_level = -1;
|
|
current_dma = nullptr;
|
|
current_dtc = nullptr;
|
|
}
|
|
|
|
bool h8_device::trigger_dma(int vector)
|
|
{
|
|
return (dma_device && dma_device->trigger_dma(vector)) || (dtc_device && dtc_device->trigger_dtc(vector));
|
|
}
|
|
|
|
void h8_device::set_current_dma(h8_dma_state *state)
|
|
{
|
|
current_dma = state;
|
|
if(!state)
|
|
logerror("DMA done\n");
|
|
else
|
|
logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d autoreq=%d\n",
|
|
state->source, state->dest, state->incs, state->incd,
|
|
state->count, state->mode_16 ? 16 : 8, state->autoreq);
|
|
|
|
}
|
|
|
|
void h8_device::set_current_dtc(h8_dtc_state *state)
|
|
{
|
|
current_dtc = state;
|
|
}
|
|
|
|
void h8_device::request_state(int state)
|
|
{
|
|
requested_state = state;
|
|
}
|
|
|
|
uint32_t h8_device::execute_min_cycles() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
uint32_t h8_device::execute_max_cycles() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
uint32_t h8_device::execute_input_lines() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool h8_device::execute_input_edge_triggered(int inputnum) const
|
|
{
|
|
return inputnum == INPUT_LINE_NMI;
|
|
}
|
|
|
|
void h8_device::recompute_bcount(uint64_t event_time)
|
|
{
|
|
if(!event_time || event_time >= total_cycles() + icount) {
|
|
bcount = 0;
|
|
return;
|
|
}
|
|
bcount = total_cycles() + icount - event_time;
|
|
}
|
|
|
|
void h8_device::execute_run()
|
|
{
|
|
internal_update(total_cycles());
|
|
|
|
icount -= count_before_instruction_step;
|
|
if(icount < 0) {
|
|
count_before_instruction_step = -icount;
|
|
icount = 0;
|
|
} else
|
|
count_before_instruction_step = 0;
|
|
|
|
while(bcount && icount <= bcount)
|
|
internal_update(total_cycles() + icount - bcount);
|
|
|
|
if(icount > 0 && inst_substate)
|
|
do_exec_partial();
|
|
|
|
while(icount > 0) {
|
|
while(icount > bcount) {
|
|
if(inst_state < 0x10000) {
|
|
PPC = NPC;
|
|
if(machine().debug_flags & DEBUG_FLAG_ENABLED)
|
|
debugger_instruction_hook(NPC);
|
|
}
|
|
do_exec_full();
|
|
}
|
|
if(icount > 0)
|
|
while(bcount && icount <= bcount)
|
|
internal_update(total_cycles() + icount - bcount);
|
|
if(icount > 0 && inst_substate)
|
|
do_exec_partial();
|
|
}
|
|
if(icount < 0) {
|
|
count_before_instruction_step = -icount;
|
|
icount = 0;
|
|
}
|
|
}
|
|
|
|
void h8_device::add_event(uint64_t &event_time, uint64_t new_event)
|
|
{
|
|
if(!new_event)
|
|
return;
|
|
if(!event_time || event_time > new_event)
|
|
event_time = new_event;
|
|
}
|
|
|
|
void h8_device::internal_update()
|
|
{
|
|
internal_update(total_cycles());
|
|
}
|
|
|
|
device_memory_interface::space_config_vector h8_device::memory_space_config() const
|
|
{
|
|
return space_config_vector {
|
|
std::make_pair(AS_PROGRAM, &program_config),
|
|
std::make_pair(AS_IO, &io_config)
|
|
};
|
|
}
|
|
|
|
|
|
void h8_device::state_import(const device_state_entry &entry)
|
|
{
|
|
switch(entry.index()) {
|
|
case H8_R0:
|
|
case H8_R1:
|
|
case H8_R2:
|
|
case H8_R3:
|
|
case H8_R4:
|
|
case H8_R5:
|
|
case H8_R6:
|
|
case H8_R7: {
|
|
int r = entry.index() - H8_R0;
|
|
R[r + 8] = TMPR >> 16;
|
|
R[r] = TMPR;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void h8_device::state_export(const device_state_entry &entry)
|
|
{
|
|
switch(entry.index()) {
|
|
case H8_R0:
|
|
case H8_R1:
|
|
case H8_R2:
|
|
case H8_R3:
|
|
case H8_R4:
|
|
case H8_R5:
|
|
case H8_R6:
|
|
case H8_R7: {
|
|
int r = entry.index() - H8_R0;
|
|
TMPR = (R[r + 8] << 16) | R[r];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void h8_device::state_string_export(const device_state_entry &entry, std::string &str) const
|
|
{
|
|
switch(entry.index()) {
|
|
case STATE_GENFLAGS:
|
|
if(has_exr)
|
|
str = string_format("%c%c %c%c%c%c%c%c%c%c",
|
|
(EXR & EXR_T) ? 'T' : '-',
|
|
'0' + (EXR & EXR_I),
|
|
(CCR & F_I) ? 'I' : '-',
|
|
(CCR & F_UI) ? 'u' : '-',
|
|
(CCR & F_H) ? 'H' : '-',
|
|
(CCR & F_U) ? 'U' : '-',
|
|
(CCR & F_N) ? 'N' : '-',
|
|
(CCR & F_Z) ? 'Z' : '-',
|
|
(CCR & F_V) ? 'V' : '-',
|
|
(CCR & F_C) ? 'C' : '-');
|
|
else
|
|
str = string_format("%c%c%c%c%c%c%c%c",
|
|
(CCR & F_I) ? 'I' : '-',
|
|
(CCR & F_UI) ? 'u' : '-',
|
|
(CCR & F_H) ? 'H' : '-',
|
|
(CCR & F_U) ? 'U' : '-',
|
|
(CCR & F_N) ? 'N' : '-',
|
|
(CCR & F_Z) ? 'Z' : '-',
|
|
(CCR & F_V) ? 'V' : '-',
|
|
(CCR & F_C) ? 'C' : '-');
|
|
break;
|
|
case H8_R0:
|
|
case H8_R1:
|
|
case H8_R2:
|
|
case H8_R3:
|
|
case H8_R4:
|
|
case H8_R5:
|
|
case H8_R6:
|
|
case H8_R7: {
|
|
int r = entry.index() - H8_R0;
|
|
str = string_format("%04x %04x", R[r + 8], R[r]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint16_t h8_device::read16i(uint32_t adr)
|
|
{
|
|
icount--;
|
|
return cache->read_word(adr & ~1);
|
|
}
|
|
|
|
uint16_t h8_device::fetch()
|
|
{
|
|
uint16_t res = read16i(PC);
|
|
PC += 2;
|
|
return res;
|
|
}
|
|
|
|
uint8_t h8_device::read8(uint32_t adr)
|
|
{
|
|
icount--;
|
|
return program->read_byte(adr);
|
|
}
|
|
|
|
void h8_device::write8(uint32_t adr, uint8_t data)
|
|
{
|
|
icount--;
|
|
program->write_byte(adr, data);
|
|
}
|
|
|
|
uint16_t h8_device::read16(uint32_t adr)
|
|
{
|
|
icount--;
|
|
return program->read_word(adr & ~1);
|
|
}
|
|
|
|
void h8_device::write16(uint32_t adr, uint16_t data)
|
|
{
|
|
icount--;
|
|
program->write_word(adr & ~1, data);
|
|
}
|
|
|
|
bool h8_device::exr_in_stack() const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
void h8_device::prefetch_done()
|
|
{
|
|
if(requested_state != -1) {
|
|
inst_state = requested_state;
|
|
requested_state = -1;
|
|
} else if(current_dma && !current_dma->suspended)
|
|
inst_state = STATE_DMA;
|
|
else if(current_dtc)
|
|
inst_state = STATE_DTC;
|
|
else if(irq_vector) {
|
|
inst_state = STATE_IRQ;
|
|
taken_irq_vector = irq_vector;
|
|
taken_irq_level = irq_level;
|
|
} else if(has_trace && (EXR & EXR_T) && exr_in_stack())
|
|
inst_state = STATE_TRACE;
|
|
else
|
|
inst_state = IR[0] = PIR;
|
|
}
|
|
|
|
void h8_device::prefetch_done_noirq()
|
|
{
|
|
if(has_trace && (EXR & EXR_T) && exr_in_stack())
|
|
inst_state = STATE_TRACE;
|
|
else
|
|
inst_state = IR[0] = PIR;
|
|
}
|
|
|
|
void h8_device::prefetch_done_noirq_notrace()
|
|
{
|
|
inst_state = IR[0] = PIR;
|
|
}
|
|
|
|
void h8_device::set_irq(int _irq_vector, int _irq_level, bool _irq_nmi)
|
|
{
|
|
irq_vector = _irq_vector;
|
|
irq_level = _irq_level;
|
|
irq_nmi = _irq_nmi;
|
|
}
|
|
|
|
void h8_device::internal(int cycles)
|
|
{
|
|
icount -= cycles;
|
|
}
|
|
|
|
void h8_device::illegal()
|
|
{
|
|
logerror("Illegal instruction at address %x\n", PPC);
|
|
icount = -10000000;
|
|
}
|
|
|
|
int h8_device::trace_setup()
|
|
{
|
|
throw emu_fatalerror("%s: Trace setup called but unimplemented.\n", tag());
|
|
}
|
|
|
|
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)
|
|
{
|
|
uint16_t res = v1 + v2 + (CCR & F_C ? 1 : 0);
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xf) + (v2 & 0xf) + (CCR & F_C ? 1 : 0)) & 0x10)
|
|
CCR |= F_H;
|
|
if(!uint8_t(res))
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if(~(v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
if(res & 0x100)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint8_t h8_device::do_subx8(uint8_t v1, uint8_t v2)
|
|
{
|
|
uint16_t res = v1 - v2 - (CCR & F_C ? 1 : 0);
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xf) - (v2 & 0xf) - (CCR & F_C ? 1 : 0)) & 0x10)
|
|
CCR |= F_H;
|
|
if(!uint8_t(res))
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
if(res & 0x100)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint8_t h8_device::do_inc8(uint8_t v1, uint8_t v2)
|
|
{
|
|
uint8_t res = v1 + v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint16_t h8_device::do_inc16(uint16_t v1, uint16_t v2)
|
|
{
|
|
uint16_t res = v1 + v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int16_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x8000)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint32_t h8_device::do_inc32(uint32_t v1, uint32_t v2)
|
|
{
|
|
uint32_t res = v1 + v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int32_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80000000)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint8_t h8_device::do_add8(uint8_t v1, uint8_t v2)
|
|
{
|
|
uint16_t res = v1 + v2;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xf) + (v2 & 0xf)) & 0x10)
|
|
CCR |= F_H;
|
|
if(!uint8_t(res))
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if(~(v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
if(res & 0x100)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint16_t h8_device::do_add16(uint16_t v1, uint16_t v2)
|
|
{
|
|
uint32_t res = v1 + v2;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xfff) + (v2 & 0xffff)) & 0x1000)
|
|
CCR |= F_H;
|
|
if(!uint16_t(res))
|
|
CCR |= F_Z;
|
|
else if(int16_t(res) < 0)
|
|
CCR |= F_N;
|
|
if(~(v1^v2) & (v1^res) & 0x8000)
|
|
CCR |= F_V;
|
|
if(res & 0x10000)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint32_t h8_device::do_add32(uint32_t v1, uint32_t v2)
|
|
{
|
|
uint64_t res = uint64_t(v1) + uint64_t(v2);
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xfffffff) + (v2 & 0xfffffff)) & 0x10000000)
|
|
CCR |= F_H;
|
|
if(!uint32_t(res))
|
|
CCR |= F_Z;
|
|
else if(int32_t(res) < 0)
|
|
CCR |= F_N;
|
|
if(~(v1^v2) & (v1^res) & 0x80000000)
|
|
CCR |= F_V;
|
|
if(res & 0x100000000U)
|
|
CCR |= F_C;
|
|
return res;
|
|
}
|
|
|
|
uint8_t h8_device::do_dec8(uint8_t v1, uint8_t v2)
|
|
{
|
|
uint8_t res = v1 - v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint16_t h8_device::do_dec16(uint16_t v1, uint16_t v2)
|
|
{
|
|
uint16_t res = v1 - v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int16_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x8000)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint32_t h8_device::do_dec32(uint32_t v1, uint32_t v2)
|
|
{
|
|
uint32_t res = v1 - v2;
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!res)
|
|
CCR |= F_Z;
|
|
else if(int32_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80000000)
|
|
CCR |= F_V;
|
|
return res;
|
|
}
|
|
|
|
uint8_t h8_device::do_sub8(uint8_t v1, uint8_t v2)
|
|
{
|
|
uint16_t res = v1 - v2;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xf) - (v2 & 0xf)) & 0x10)
|
|
CCR |= F_H;
|
|
if(!uint8_t(res))
|
|
CCR |= F_Z;
|
|
else if(int8_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80)
|
|
CCR |= F_V;
|
|
if(res & 0x100)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint16_t h8_device::do_sub16(uint16_t v1, uint16_t v2)
|
|
{
|
|
uint32_t res = v1 - v2;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xfff) - (v2 & 0xffff)) & 0x1000)
|
|
CCR |= F_H;
|
|
if(!uint16_t(res))
|
|
CCR |= F_Z;
|
|
else if(int16_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x8000)
|
|
CCR |= F_V;
|
|
if(res & 0x10000)
|
|
CCR |= F_C;
|
|
return res;
|
|
|
|
}
|
|
|
|
uint32_t h8_device::do_sub32(uint32_t v1, uint32_t v2)
|
|
{
|
|
uint64_t res = uint64_t(v1) - uint64_t(v2);
|
|
CCR &= ~(F_N|F_V|F_Z|F_C|F_H);
|
|
if(((v1 & 0xfffffff) - (v2 & 0xfffffff)) & 0x10000000)
|
|
CCR |= F_H;
|
|
if(!uint32_t(res))
|
|
CCR |= F_Z;
|
|
else if(int32_t(res) < 0)
|
|
CCR |= F_N;
|
|
if((v1^v2) & (v1^res) & 0x80000000)
|
|
CCR |= F_V;
|
|
if(res & 0x100000000U)
|
|
CCR |= F_C;
|
|
return res;
|
|
}
|
|
|
|
uint8_t h8_device::do_shal8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80)
|
|
CCR |= F_C;
|
|
if((v & 0xc0) == 0x40 || (v & 0xc0) == 0x80)
|
|
CCR |= F_V;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shal16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x8000)
|
|
CCR |= F_C;
|
|
if((v & 0xc000) == 0x4000 || (v & 0xc000) == 0x8000)
|
|
CCR |= F_V;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shal32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80000000)
|
|
CCR |= F_C;
|
|
if((v & 0xc0000000) == 0x40000000 || (v & 0xc0000000) == 0x80000000)
|
|
CCR |= F_V;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shar8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x40) {
|
|
v |= 0x80;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shar16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x4000) {
|
|
v |= 0x8000;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shar32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x40000000) {
|
|
v |= 0x80000000;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shll8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80)
|
|
CCR |= F_C;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shll16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x8000)
|
|
CCR |= F_C;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shll32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80000000)
|
|
CCR |= F_C;
|
|
v <<= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shlr8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shlr16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shlr32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 1)
|
|
CCR |= F_C;
|
|
v >>= 1;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shal2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40)
|
|
CCR |= F_C;
|
|
if((v & 0xc0) == 0x40 || (v & 0xc0) == 0x80 ||
|
|
(v & 0x60) == 0x20 || (v & 0x60) == 0x40)
|
|
CCR |= F_V;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shal2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x4000)
|
|
CCR |= F_C;
|
|
if((v & 0xc000) == 0x4000 || (v & 0xc000) == 0x8000 ||
|
|
(v & 0x6000) == 0x2000 || (v & 0x6000) == 0x4000)
|
|
CCR |= F_V;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shal2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40000000)
|
|
CCR |= F_C;
|
|
if((v & 0xc0000000) == 0x40000000 || (v & 0xc0000000) == 0x80000000 ||
|
|
(v & 0x60000000) == 0x20000000 || (v & 0x60000000) == 0x40000000)
|
|
CCR |= F_V;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shar2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x20) {
|
|
v |= 0xc0;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shar2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x2000) {
|
|
v |= 0xc000;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shar2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if (v & 0x20000000) {
|
|
v |= 0xc0000000;
|
|
CCR |= F_N;
|
|
}
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shll2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40)
|
|
CCR |= F_C;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shll2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x4000)
|
|
CCR |= F_C;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shll2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40000000)
|
|
CCR |= F_C;
|
|
v <<= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_shlr2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_shlr2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_shlr2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 2)
|
|
CCR |= F_C;
|
|
v >>= 2;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotl8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80)
|
|
CCR |= F_C;
|
|
v = (v << 1) | (v >> 7);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotl16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x8000)
|
|
CCR |= F_C;
|
|
v = (v << 1) | (v >> 15);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotl32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80000000)
|
|
CCR |= F_C;
|
|
v = (v << 1) | (v >> 31);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotr8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x01)
|
|
CCR |= F_C;
|
|
v = (v << 7) | (v >> 1);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotr16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x0001)
|
|
CCR |= F_C;
|
|
v = (v << 15) | (v >> 1);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotr32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x00000001)
|
|
CCR |= F_C;
|
|
v = (v << 31) | (v >> 1);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotxl8(uint8_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80)
|
|
CCR |= F_C;
|
|
v = (v << 1) | c;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotxl16(uint16_t v)
|
|
{
|
|
uint16_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x8000)
|
|
CCR |= F_C;
|
|
v = (v << 1) | c;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotxl32(uint32_t v)
|
|
{
|
|
uint32_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x80000000)
|
|
CCR |= F_C;
|
|
v = (v << 1) | c;
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotxr8(uint8_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x01)
|
|
CCR |= F_C;
|
|
v = (v >> 1) | (c << 7);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotxr16(uint16_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x0001)
|
|
CCR |= F_C;
|
|
v = (v >> 1) | (c << 15);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotxr32(uint32_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x00000001)
|
|
CCR |= F_C;
|
|
v = (v >> 1) | (c << 31);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotl2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (v >> 6);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotl2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x4000)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (v >> 14);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotl2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40000000)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (v >> 30);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotr2_8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x02)
|
|
CCR |= F_C;
|
|
v = (v << 6) | (v >> 2);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotr2_16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x0002)
|
|
CCR |= F_C;
|
|
v = (v << 14) | (v >> 2);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotr2_32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x00000002)
|
|
CCR |= F_C;
|
|
v = (v << 30) | (v >> 2);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotxl2_8(uint8_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (c << 1) | ((v >> 6) & 0x01);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotxl2_16(uint16_t v)
|
|
{
|
|
uint16_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x4000)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (c << 1) | ((v >> 14) & 0x0001);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotxl2_32(uint32_t v)
|
|
{
|
|
uint32_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x40000000)
|
|
CCR |= F_C;
|
|
v = (v << 2) | (c << 1) | ((v >> 30) & 0x00000001);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint8_t h8_device::do_rotxr2_8(uint8_t v)
|
|
{
|
|
uint8_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x02)
|
|
CCR |= F_C;
|
|
v = (v >> 2) | (c << 6) | (v << 7);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint16_t h8_device::do_rotxr2_16(uint16_t v)
|
|
{
|
|
uint16_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x0002)
|
|
CCR |= F_C;
|
|
v = (v >> 2) | (c << 14) | (v << 15);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
uint32_t h8_device::do_rotxr2_32(uint32_t v)
|
|
{
|
|
uint32_t c = CCR & F_C ? 1 : 0;
|
|
CCR &= ~(F_N|F_V|F_Z|F_C);
|
|
if(v & 0x00000002)
|
|
CCR |= F_C;
|
|
v = (v >> 2) | (c << 30) | (v << 31);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
return v;
|
|
}
|
|
|
|
void h8_device::set_nzv8(uint8_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int8_t(v) < 0)
|
|
CCR |= F_N;
|
|
}
|
|
|
|
void h8_device::set_nzv16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
}
|
|
|
|
void h8_device::set_nzv32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_V|F_Z);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
}
|
|
|
|
void h8_device::set_nz16(uint16_t v)
|
|
{
|
|
CCR &= ~(F_N|F_Z);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int16_t(v) < 0)
|
|
CCR |= F_N;
|
|
}
|
|
|
|
void h8_device::set_nz32(uint32_t v)
|
|
{
|
|
CCR &= ~(F_N|F_Z);
|
|
if(!v)
|
|
CCR |= F_Z;
|
|
else if(int32_t(v) < 0)
|
|
CCR |= F_N;
|
|
}
|
|
|
|
std::unique_ptr<util::disasm_interface> h8_device::create_disassembler()
|
|
{
|
|
return std::make_unique<h8_disassembler>();
|
|
}
|
|
|
|
#include "cpu/h8/h8.hxx"
|