summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author AJR <ajrhacker@users.noreply.github.com>2018-08-12 02:11:58 -0400
committer AJR <ajrhacker@users.noreply.github.com>2018-08-12 02:11:58 -0400
commita459faa90fceb95cdd6af60276d48f949f115fb3 (patch)
treefda7d121d3507de079511da07cea68686fe57077
parent33983bf43e60e26361a07bd8922860bbf311fda5 (diff)
Emulate V33/V53 expanded addressing mode, including BRKXA and RETXA instructions
Mask address expressions correctly in debug memory view when using physical addresses beyond logical limits
-rw-r--r--src/devices/cpu/nec/nec.cpp69
-rw-r--r--src/devices/cpu/nec/nec.h16
-rw-r--r--src/devices/cpu/nec/necinstr.hxx4
-rw-r--r--src/devices/cpu/nec/necpriv.h10
-rw-r--r--src/devices/cpu/nec/v25priv.h2
-rw-r--r--src/devices/cpu/nec/v53.cpp11
-rw-r--r--src/devices/cpu/nec/v53.h4
-rw-r--r--src/emu/debug/dvmemory.cpp2
-rw-r--r--src/mame/drivers/mpc3000.cpp4
9 files changed, 89 insertions, 33 deletions
diff --git a/src/devices/cpu/nec/nec.cpp b/src/devices/cpu/nec/nec.cpp
index 9296d952ba5..b4205b54a2c 100644
--- a/src/devices/cpu/nec/nec.cpp
+++ b/src/devices/cpu/nec/nec.cpp
@@ -122,14 +122,14 @@ DEFINE_DEVICE_TYPE(V33, v33_device, "v33", "NEC V33")
DEFINE_DEVICE_TYPE(V33A, v33a_device, "v33a", "NEC V33A")
-
-nec_common_device::nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type)
+nec_common_device::nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type, address_map_constructor internal_port_map)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 20, 0)
- , m_io_config("io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 16, 0)
+ , m_program_config("program", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, chip_type == V33_TYPE ? 24 : 20, 0, chip_type == V33_TYPE ? 20 : 0, chip_type == V33_TYPE ? 14 : 0)
+ , m_io_config("io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, 16, 0, internal_port_map)
, m_prefetch_size(prefetch_size)
, m_prefetch_cycles(prefetch_cycles)
, m_chip_type(chip_type)
+ , m_v33_transtable(*this, "v33_transtable")
{
}
@@ -158,14 +158,43 @@ device_memory_interface::space_config_vector nec_common_device::memory_space_con
* complete guess below, nbbatman will not work
* properly without. */
v33_device::v33_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nec_common_device(mconfig, V33, tag, owner, clock, true, 6, 1, V33_TYPE)
+ : nec_common_device(mconfig, V33, tag, owner, clock, true, 6, 1, V33_TYPE, address_map_constructor(FUNC(v33_device::v33_internal_port_map), this))
{
}
v33a_device::v33a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : nec_common_device(mconfig, V33A, tag, owner, clock, true, 6, 1, V33_TYPE)
+ : nec_common_device(mconfig, V33A, tag, owner, clock, true, 6, 1, V33_TYPE, address_map_constructor(FUNC(v33a_device::v33_internal_port_map), this))
+{
+}
+
+
+uint16_t nec_common_device::aex_r()
+{
+ return m_aex ? 1 : 0;
+}
+
+void nec_common_device::v33_internal_port_map(address_map &map)
{
+ map(0xff00, 0xff7f).ram().share("v33_transtable");
+ map(0xff80, 0xff81).r(FUNC(nec_common_device::aex_r)).unmapw();
+ map(0xff82, 0xffff).unmaprw();
+}
+
+
+offs_t nec_common_device::v33_translate(offs_t addr)
+{
+ if (m_aex)
+ return uint32_t(m_v33_transtable[(addr >> 14) & 63]) << 14 | (addr & 0x03fff);
+ else
+ return addr & 0xfffff;
+}
+
+bool nec_common_device::memory_translate(int spacenum, int intention, offs_t &address)
+{
+ if (m_chip_type == V33_TYPE && spacenum == AS_PROGRAM)
+ address = v33_translate(address);
+ return true;
}
@@ -265,6 +294,9 @@ void nec_common_device::device_reset()
m_poll_state = 1;
m_halted = 0;
+ if (m_chip_type == V33_TYPE)
+ m_aex = false;
+
Sreg(PS) = 0xffff;
Sreg(SS) = 0;
Sreg(DS0) = 0;
@@ -300,6 +332,13 @@ void nec_common_device::nec_trap()
nec_interrupt(NEC_TRAP_VECTOR, BRK);
}
+void nec_common_device::nec_brk(unsigned int_num)
+{
+ m_ip = read_mem_word(int_num*4);
+ Sreg(PS) = read_mem_word(int_num*4+2);
+ CHANGE_PC;
+}
+
void nec_common_device::external_int()
{
if (m_pending_irq & NMI_IRQ)
@@ -418,10 +457,19 @@ void nec_common_device::device_start()
save_item(NAME(m_prefetch_reset));
m_program = &space(AS_PROGRAM);
- if(m_program->data_width() == 8) {
+ if (m_program->data_width() == 8)
+ {
auto cache = m_program->cache<0, 0, ENDIANNESS_LITTLE>();
m_dr8 = [cache](offs_t address) -> u8 { return cache->read_byte(address); };
- } else {
+ }
+ else if (m_chip_type == V33_TYPE)
+ {
+ save_item(NAME(m_aex));
+ auto cache = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
+ m_dr8 = [cache, this](offs_t address) -> u8 { return cache->read_byte(v33_translate(address)); };
+ }
+ else
+ {
auto cache = m_program->cache<1, 0, ENDIANNESS_LITTLE>();
m_dr8 = [cache](offs_t address) -> u8 { return cache->read_byte(address); };
}
@@ -444,6 +492,9 @@ void nec_common_device::device_start()
state_add( NEC_SS, "SS", Sreg(SS)).formatstr("%04X");
state_add( NEC_DS, "DS0", Sreg(DS0)).formatstr("%04X");
+ if (m_chip_type == V33_TYPE)
+ state_add(NEC_AEX, "AEX", m_aex);
+
state_add( STATE_GENPC, "GENPC", m_debugger_temp).callexport().noshow();
state_add( STATE_GENPCBASE, "CURPC", m_debugger_temp).callexport().noshow();
state_add( STATE_GENSP, "GENSP", m_debugger_temp).callimport().callexport().noshow();
@@ -485,7 +536,7 @@ void nec_common_device::state_import(const device_state_entry &entry)
switch (entry.index())
{
case NEC_PC:
- if( m_debugger_temp - (Sreg(PS)<<4) < 0x10000 )
+ if (m_debugger_temp - (Sreg(PS)<<4) < 0x10000)
{
m_ip = m_debugger_temp - (Sreg(PS)<<4);
}
diff --git a/src/devices/cpu/nec/nec.h b/src/devices/cpu/nec/nec.h
index 5d8e2ad3338..243fbfb5a7e 100644
--- a/src/devices/cpu/nec/nec.h
+++ b/src/devices/cpu/nec/nec.h
@@ -14,6 +14,7 @@ enum
NEC_PC=0,
NEC_IP, NEC_AW, NEC_CW, NEC_DW, NEC_BW, NEC_SP, NEC_BP, NEC_IX, NEC_IY,
NEC_FLAGS, NEC_ES, NEC_CS, NEC_SS, NEC_DS,
+ NEC_AEX,
NEC_PENDING
};
@@ -22,7 +23,7 @@ class nec_common_device : public cpu_device
{
protected:
// construction/destruction
- nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type);
+ nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type, address_map_constructor internal_port_map = address_map_constructor());
// device-level overrides
virtual void device_start() override;
@@ -39,6 +40,7 @@ protected:
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
+ virtual bool memory_translate(int spacenum, int intention, offs_t &address) override;
// device_state_interface overrides
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
@@ -93,11 +95,14 @@ private:
uint8_t m_prefetch_cycles;
int8_t m_prefetch_count;
uint8_t m_prefetch_reset;
- uint32_t m_chip_type;
+ const uint32_t m_chip_type;
uint32_t m_prefix_base; /* base address of the latest prefix segment */
uint8_t m_seg_prefix; /* prefix segment indicator */
+ bool m_aex;
+ optional_shared_ptr<uint16_t> m_v33_transtable;
+
uint32_t m_EA;
uint16_t m_EO;
uint16_t m_E16;
@@ -109,6 +114,12 @@ private:
static const nec_ophandler s_nec_instruction[256];
static const nec_eahandler s_GetEA[192];
+protected:
+ void v33_internal_port_map(address_map &map);
+ uint16_t aex_r();
+ offs_t v33_translate(offs_t addr);
+
+private:
inline void prefetch();
void do_prefetch(int previous_ICount);
inline uint8_t fetch();
@@ -116,6 +127,7 @@ private:
uint8_t fetchop();
void nec_interrupt(unsigned int_num, int source);
void nec_trap();
+ void nec_brk(unsigned int_num);
void external_int();
void i_add_br8();
diff --git a/src/devices/cpu/nec/necinstr.hxx b/src/devices/cpu/nec/necinstr.hxx
index 0499c49c65b..f1209d675a9 100644
--- a/src/devices/cpu/nec/necinstr.hxx
+++ b/src/devices/cpu/nec/necinstr.hxx
@@ -45,8 +45,8 @@ OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2;
case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break;
case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break;
case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break;
- case 0xe0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break;
- case 0xf0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break;
+ case 0xe0 : BRKXA(true); CLK(12); break;
+ case 0xf0 : BRKXA(false); CLK(12); break;
case 0xff : ModRM = fetch(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break;
default: logerror("%06x: Unknown V20 instruction\n",PC()); break;
}
diff --git a/src/devices/cpu/nec/necpriv.h b/src/devices/cpu/nec/necpriv.h
index 459fa5017b4..08ce013f891 100644
--- a/src/devices/cpu/nec/necpriv.h
+++ b/src/devices/cpu/nec/necpriv.h
@@ -52,10 +52,10 @@ enum BREGS {
/************************************************************************/
-#define read_mem_byte(a) m_program->read_byte(a)
-#define read_mem_word(a) m_program->read_word_unaligned(a)
-#define write_mem_byte(a,d) m_program->write_byte((a),(d))
-#define write_mem_word(a,d) m_program->write_word_unaligned((a),(d))
+#define read_mem_byte(a) m_program->read_byte(m_chip_type == V33_TYPE ? v33_translate(a) : (a))
+#define read_mem_word(a) m_program->read_word_unaligned(m_chip_type == V33_TYPE ? v33_translate(a) : (a))
+#define write_mem_byte(a,d) m_program->write_byte(m_chip_type == V33_TYPE ? v33_translate(a) : (a), (d))
+#define write_mem_word(a,d) m_program->write_word_unaligned(m_chip_type == V33_TYPE ? v33_translate(a) : (a), (d))
#define read_port_byte(a) m_io->read_byte(a)
#define read_port_word(a) m_io->read_word_unaligned(a)
@@ -84,6 +84,8 @@ enum BREGS {
#define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); }
#define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); }
+#define BRKXA(aex) { if (m_chip_type == V33_TYPE) { nec_brk(fetch()); m_aex = aex; } else logerror("%06x: %sXA instruction is V33 exclusive\n", PC(), aex ? "BRK" : "RET"); }
+
#define GetModRM uint32_t ModRM=fetch()
/* Cycle count macros:
diff --git a/src/devices/cpu/nec/v25priv.h b/src/devices/cpu/nec/v25priv.h
index eb60c8f041d..ee885142dd5 100644
--- a/src/devices/cpu/nec/v25priv.h
+++ b/src/devices/cpu/nec/v25priv.h
@@ -141,6 +141,8 @@ enum BREGS {
#define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); }
#define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); }
+#define BRKXA(aex) { logerror("%06x: %sXA instruction is V33 exclusive\n", PC(), aex ? "BRK" : "RET"); }
+
#define GetModRM uint32_t ModRM=fetch()
/* Cycle count macros:
diff --git a/src/devices/cpu/nec/v53.cpp b/src/devices/cpu/nec/v53.cpp
index 410867e804e..697d12d461f 100644
--- a/src/devices/cpu/nec/v53.cpp
+++ b/src/devices/cpu/nec/v53.cpp
@@ -172,13 +172,6 @@ m_DST = 0x00;
m_DMK = 0x0f;
*/
-device_memory_interface::space_config_vector v53_base_device::memory_space_config() const
-{
- auto r = nec_common_device::memory_space_config();
- r.emplace_back(std::make_pair(AS_IO, &m_io_space_config));
- return r;
-}
-
void v53_base_device::device_reset()
{
nec_common_device::device_reset();
@@ -416,6 +409,7 @@ WRITE_LINE_MEMBER(v53_base_device::hack_w)
void v53_base_device::v53_internal_port_map(address_map &map)
{
+ v33_internal_port_map(map);
map(0xffe0, 0xffe0).w(FUNC(v53_base_device::BSEL_w)); // 0xffe0 // uPD71037 DMA mode bank selection register
map(0xffe1, 0xffe1).w(FUNC(v53_base_device::BADR_w)); // 0xffe1 // uPD71037 DMA mode bank register peripheral mapping (also uses OPHA)
// AM_RANGE(0xffe2, 0xffe3) // (reserved , 0x00ff) // 0xffe2
@@ -532,8 +526,7 @@ MACHINE_CONFIG_END
v53_base_device::v53_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type) :
- nec_common_device(mconfig, type, tag, owner, clock, true, prefetch_size, prefetch_cycles, chip_type),
- m_io_space_config( "io", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor(FUNC(v53_base_device::v53_internal_port_map), this) ),
+ nec_common_device(mconfig, type, tag, owner, clock, true, prefetch_size, prefetch_cycles, chip_type, address_map_constructor(FUNC(v53_base_device::v53_internal_port_map), this)),
m_v53tcu(*this, "pit"),
m_v53dmau(*this, "upd71071dma"),
m_v53icu(*this, "upd71059pic"),
diff --git a/src/devices/cpu/nec/v53.h b/src/devices/cpu/nec/v53.h
index c5f695a5dd0..c91a264bbf6 100644
--- a/src/devices/cpu/nec/v53.h
+++ b/src/devices/cpu/nec/v53.h
@@ -201,10 +201,6 @@ protected:
void install_peripheral_io();
- const address_space_config m_io_space_config;
-
- virtual space_config_vector memory_space_config() const override;
-
uint8_t m_SCTL;
uint8_t m_OPSEL;
diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp
index 1d735293b6e..c81aa45c20e 100644
--- a/src/emu/debug/dvmemory.cpp
+++ b/src/emu/debug/dvmemory.cpp
@@ -635,7 +635,7 @@ bool debug_view_memory::needs_recompute()
const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source);
offs_t val = m_expression.value();
if (source.m_space)
- val = source.m_space->address_to_byte(val & source.m_space->logaddrmask());
+ val = source.m_space->address_to_byte(val & (m_no_translation ? source.m_space->addrmask() : source.m_space->logaddrmask()));
recompute = true;
m_topleft.y = (val - m_byte_offset) / m_bytes_per_row;
m_topleft.y = std::max(m_topleft.y, 0);
diff --git a/src/mame/drivers/mpc3000.cpp b/src/mame/drivers/mpc3000.cpp
index b80c55d697d..17b55b75a8e 100644
--- a/src/mame/drivers/mpc3000.cpp
+++ b/src/mame/drivers/mpc3000.cpp
@@ -96,8 +96,8 @@ void mpc3000_state::machine_reset()
void mpc3000_state::mpc3000_map(address_map &map)
{
- map(0x00000, 0x8ffff).ram();
- map(0xa0000, 0xfffff).rom().region("maincpu", 0x20000); // first 0x20000 of the ROM is not used
+ map(0x000000, 0x07ffff).mirror(0x80000).rom().region("maincpu", 0);
+ map(0x300000, 0x38ffff).ram();
}
void mpc3000_state::mpc3000_io_map(address_map &map)