summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/i86/i286.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/i86/i286.cpp')
-rw-r--r--src/devices/cpu/i86/i286.cpp50
1 files changed, 25 insertions, 25 deletions
diff --git a/src/devices/cpu/i86/i286.cpp b/src/devices/cpu/i86/i286.cpp
index 5ef63380888..bfe4dc7c728 100644
--- a/src/devices/cpu/i86/i286.cpp
+++ b/src/devices/cpu/i86/i286.cpp
@@ -2,7 +2,6 @@
// copyright-holders:Carl
#include "emu.h"
#include "i286.h"
-#include "debugger.h"
#include "i86inline.h"
/*
@@ -165,13 +164,14 @@ const uint8_t i80286_cpu_device::m_i80286_timing[] =
13, /* (80186) BOUND */
};
-DEFINE_DEVICE_TYPE(I80286, i80286_cpu_device, "i80286", "Intel I80286")
+DEFINE_DEVICE_TYPE(I80286, i80286_cpu_device, "i80286", "Intel 80286")
i80286_cpu_device::i80286_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: i8086_common_cpu_device(mconfig, I80286, tag, owner, clock)
, m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0)
, m_opcodes_config("opcodes", ENDIANNESS_LITTLE, 16, 24, 0)
, m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0)
+ , m_a20_callback(*this)
, m_out_shutdown_func(*this)
{
memcpy(m_timing, m_i80286_timing, sizeof(m_i80286_timing));
@@ -222,6 +222,7 @@ void i80286_cpu_device::device_reset()
void i80286_cpu_device::device_start()
{
i8086_common_cpu_device::device_start();
+
save_item(NAME(m_trap_level));
save_item(NAME(m_msw));
save_item(NAME(m_base));
@@ -275,10 +276,10 @@ void i80286_cpu_device::device_start()
state_add( I286_VECTOR, "V", m_int_vector).formatstr("%02X");
state_add( I286_PC, "PC", m_pc).callimport().formatstr("%06X");
- state_add( STATE_GENPCBASE, "CURPC", m_pc ).callimport().formatstr("%06X").noshow();
+ state_add<uint32_t>( STATE_GENPCBASE, "CURPC", [this] { return m_base[CS] + m_prev_ip; }).mask(0xffffff).noshow();
state_add( I8086_HALT, "HALT", m_halt ).mask(1);
- m_out_shutdown_func.resolve_safe();
+ m_a20_callback.resolve_safe(0xffffff);
}
device_memory_interface::space_config_vector i80286_cpu_device::memory_space_config() const
@@ -316,7 +317,6 @@ void i80286_cpu_device::state_import(const device_state_entry &entry)
break;
case STATE_GENPC:
- case STATE_GENPCBASE:
if (m_pc - m_base[CS] > m_limit[CS])
{
// TODO: should this call data_descriptor instead of ignoring jumps outside the current segment?
@@ -331,6 +331,7 @@ void i80286_cpu_device::state_import(const device_state_entry &entry)
}
}
m_ip = m_pc - m_base[CS];
+ m_prev_ip = m_ip;
break;
}
}
@@ -370,8 +371,9 @@ void i80286_cpu_device::state_string_export(const device_state_entry &entry, std
}
}
-bool i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address)
+bool i80286_cpu_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space)
{
+ target_space = &space(spacenum);
if(spacenum == AS_PROGRAM)
address &= m_amask;
@@ -382,21 +384,16 @@ void i80286_cpu_device::execute_set_input(int inptnum, int state)
{
if(inptnum == INPUT_LINE_NMI)
{
- if(m_nmi_state == state)
- {
- return;
- }
- m_nmi_state = state;
- if(state != CLEAR_LINE)
+ if(!m_nmi_state && state)
{
m_pending_irq |= NMI_IRQ;
}
+ m_nmi_state = state;
}
else if(inptnum == INPUT_LINE_A20)
- m_amask = m_a20_callback.isnull() ? 0xffffff : m_a20_callback(state);
+ m_amask = m_a20_callback(state);
else
{
- m_irq_state = state;
if(state == CLEAR_LINE)
{
m_pending_irq &= ~INT_IRQ;
@@ -758,7 +755,7 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
throw TRAP(FAULT_GP, IDXTBL(selector));
if(!PRES(r))
- throw TRAP(FAULT_NP, IDXTBL(selector)); // this order is important
+ throw TRAP(FAULT_NP, IDXTBL(selector)); // this order is important
if(offset > LIMIT(desc))
throw TRAP(FAULT_GP, 0);
@@ -769,10 +766,11 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
m_limit[CS] = LIMIT(desc);
m_base[CS] = BASE(desc);
m_rights[CS] = RIGHTS(desc);
- m_ip = offset;
+ m_prev_ip = m_ip = offset;
}
else
- { // systemdescriptor
+ {
+ // systemdescriptor
uint16_t gatesel = GATESEL(desc);
if(!gate)
@@ -850,6 +848,7 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
if (SEGDESC(r) || (GATE(r) != TSSDESCIDLE))
throw TRAP(FAULT_GP,IDXTBL(selector));
+ [[fallthrough]];
case TSSDESCIDLE:
switch_task(selector, gate);
load_flags(CompressFlags(), CPL);
@@ -862,7 +861,7 @@ void i80286_cpu_device::code_descriptor(uint16_t selector, uint16_t offset, int
}
else
{
- m_ip = offset;
+ m_prev_ip = m_ip = offset;
m_sregs[CS]=selector;
m_base[CS]=selector<<4;
m_rights[CS]=0x93;
@@ -878,13 +877,13 @@ void i80286_cpu_device::interrupt_descriptor(int number, int hwint, int error)
if(number == -1)
{
- number = standard_irq_callback(0);
+ number = standard_irq_callback(0, update_pc() & m_amask);
- m_irq_state = CLEAR_LINE;
- m_pending_irq &= ~INT_IRQ;
hwint = 1;
}
+ debugger_exception_hook(number);
+
if(!PM)
{
PUSH(flags & ~0xf000);
@@ -979,7 +978,7 @@ void i80286_cpu_device::interrupt_descriptor(int number, int hwint, int error)
m_limit[CS] = LIMIT(gatedesc);
m_base[CS] = BASE(gatedesc);
m_rights[CS] = RIGHTS(gatedesc);
- m_ip = GATEOFF(desc);
+ m_prev_ip = m_ip = GATEOFF(desc);
m_TF = 0;
m_NT = 0;
if(GATE(RIGHTS(desc)) == INTGATE)
@@ -1075,6 +1074,7 @@ void i80286_cpu_device::execute_run()
if(m_halt || m_shutdown)
{
+ debugger_wait_hook();
m_icount = 0;
return;
}
@@ -1090,8 +1090,8 @@ void i80286_cpu_device::execute_run()
{
if ( m_fire_trap >= 2 )
{
- interrupt(1);
m_fire_trap = 0;
+ interrupt(1);
}
else
{
@@ -1340,7 +1340,7 @@ m_limit[sreg] = LIMIT(desc); }
LOADDESC(0x842, SS);
LOADDESC(0x848, DS);
#undef LOADDESC
- // void cast supresses warning
+ // void cast suppresses warning
#define LOADDESC(addr, reg, r) { desc[1] = read_word(addr); desc[2] = read_word(addr + 2); desc[0] = read_word(addr + 4); \
reg.base = BASE(desc); (void)(r); reg.limit = LIMIT(desc); }
LOADDESC(0x84e, m_gdtr, 1);
@@ -1888,7 +1888,7 @@ reg.base = BASE(desc); (void)(r); reg.limit = LIMIT(desc); }
break;
}
}
-
+ [[fallthrough]];
default:
if(!common_op(op))
{