summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/alto2/alto2cpu.cpp4
-rw-r--r--src/devices/cpu/arm/arm.cpp6
-rw-r--r--src/devices/cpu/asap/asap.cpp8
-rw-r--r--src/devices/cpu/dsp32/dsp32.cpp12
-rw-r--r--src/devices/cpu/h8/h8.cpp2
-rw-r--r--src/devices/cpu/hd61700/hd61700.cpp4
-rw-r--r--src/devices/cpu/hphybrid/hphybrid.cpp9
-rw-r--r--src/devices/cpu/i386/i386.cpp92
-rw-r--r--src/devices/cpu/i386/i386.h9
-rw-r--r--src/devices/cpu/i386/i386op32.inc16
-rw-r--r--src/devices/cpu/i386/i386ops.h1
-rw-r--r--src/devices/cpu/i386/i386ops.inc63
-rw-r--r--src/devices/cpu/i386/i386priv.h41
-rw-r--r--src/devices/cpu/i386/i486ops.inc8
-rw-r--r--src/devices/cpu/i4004/i4004.cpp4
-rw-r--r--src/devices/cpu/i8089/i8089.cpp4
-rw-r--r--src/devices/cpu/i86/i86.txt15
-rw-r--r--src/devices/cpu/i960/i960.cpp8
-rw-r--r--src/devices/cpu/m37710/m37710il.h8
-rw-r--r--src/devices/cpu/m6800/6800dasm.cpp16
-rw-r--r--src/devices/cpu/m6800/6800ops.inc26
-rw-r--r--src/devices/cpu/m6800/6800tbl.inc28
-rw-r--r--src/devices/cpu/m6800/m6800.cpp4
-rw-r--r--src/devices/cpu/m6800/m6800.h2
-rw-r--r--src/devices/cpu/m68000/m68kcpu.cpp36
-rw-r--r--src/devices/cpu/m68000/m68kcpu.h4
-rw-r--r--src/devices/cpu/m68000/m68kmake.cpp2
-rw-r--r--src/devices/cpu/m68000/m68kops.cpp2
-rw-r--r--src/devices/cpu/m68000/makefile20
-rw-r--r--src/devices/cpu/mips/mips3.cpp67
-rw-r--r--src/devices/cpu/mips/mips3.h6
-rw-r--r--src/devices/cpu/mips/mips3com.cpp12
-rw-r--r--src/devices/cpu/mips/mips3com.h1
-rw-r--r--src/devices/cpu/mips/mips3drc.cpp6
-rw-r--r--src/devices/cpu/pdp1/pdp1.cpp2
-rw-r--r--src/devices/cpu/pdp1/tx0.cpp2
-rw-r--r--src/devices/cpu/powerpc/ppc.h7
-rw-r--r--src/devices/cpu/powerpc/ppccom.cpp28
-rw-r--r--src/devices/cpu/powerpc/ppcdrc.cpp10
-rw-r--r--src/devices/cpu/se3208/se3208.cpp32
-rw-r--r--src/devices/cpu/t11/t11.cpp4
-rw-r--r--src/devices/cpu/vtlb.cpp310
-rw-r--r--src/devices/cpu/vtlb.h88
-rw-r--r--src/devices/cpu/z80/z80.cpp144
-rw-r--r--src/devices/cpu/z80/z80.h4
45 files changed, 440 insertions, 737 deletions
diff --git a/src/devices/cpu/alto2/alto2cpu.cpp b/src/devices/cpu/alto2/alto2cpu.cpp
index a3538dee290..653f56949e5 100644
--- a/src/devices/cpu/alto2/alto2cpu.cpp
+++ b/src/devices/cpu/alto2/alto2cpu.cpp
@@ -204,7 +204,9 @@ alto2_cpu_device::alto2_cpu_device(const machine_config& mconfig, const char* ta
m_ether_a49(nullptr),
m_eth()
{
- m_is_octal = true;
+ m_ucode_config.m_is_octal = true;
+ m_const_config.m_is_octal = true;
+ m_iomem_config.m_is_octal = true;
memset(m_task_mpc, 0x00, sizeof(m_task_mpc));
memset(m_task_next2, 0x00, sizeof(m_task_next2));
memset(m_r, 0x00, sizeof(m_r));
diff --git a/src/devices/cpu/arm/arm.cpp b/src/devices/cpu/arm/arm.cpp
index 41724668f53..34dc1635639 100644
--- a/src/devices/cpu/arm/arm.cpp
+++ b/src/devices/cpu/arm/arm.cpp
@@ -259,7 +259,7 @@ void arm_cpu_device::cpu_write32( int addr, UINT32 data )
{
/* Unaligned writes are treated as normal writes */
m_program->write_dword(addr&ADDRESS_MASK,data);
- if (ARM_DEBUG_CORE && addr&3) logerror("%08x: Unaligned write %08x\n",R15,addr);
+ if (ARM_DEBUG_CORE && !DWORD_ALIGNED(addr)) logerror("%08x: Unaligned write %08x\n",R15,addr);
}
void arm_cpu_device::cpu_write8( int addr, UINT8 data )
@@ -272,9 +272,9 @@ UINT32 arm_cpu_device::cpu_read32( int addr )
UINT32 result = m_program->read_dword(addr&ADDRESS_MASK);
/* Unaligned reads rotate the word, they never combine words */
- if (addr&3)
+ if (!DWORD_ALIGNED(addr))
{
- if (ARM_DEBUG_CORE && addr&1)
+ if (ARM_DEBUG_CORE && !WORD_ALIGNED(addr))
logerror("%08x: Unaligned byte read %08x\n",R15,addr);
if ((addr&3)==1)
diff --git a/src/devices/cpu/asap/asap.cpp b/src/devices/cpu/asap/asap.cpp
index c22d0cdcee2..b369ab6d07b 100644
--- a/src/devices/cpu/asap/asap.cpp
+++ b/src/devices/cpu/asap/asap.cpp
@@ -364,7 +364,7 @@ inline UINT8 asap_device::readbyte(offs_t address)
inline UINT16 asap_device::readword(offs_t address)
{
// aligned reads are easy
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
return m_program->read_word(address);
// misaligned reads are tricky
@@ -379,7 +379,7 @@ inline UINT16 asap_device::readword(offs_t address)
inline UINT32 asap_device::readlong(offs_t address)
{
// aligned reads are easy
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
return m_program->read_dword(address);
// misaligned reads are tricky
@@ -405,7 +405,7 @@ inline void asap_device::writebyte(offs_t address, UINT8 data)
inline void asap_device::writeword(offs_t address, UINT16 data)
{
// aligned writes are easy
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
{
m_program->write_word(address, data);
return;
@@ -429,7 +429,7 @@ inline void asap_device::writeword(offs_t address, UINT16 data)
inline void asap_device::writelong(offs_t address, UINT32 data)
{
// aligned writes are easy
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
{
m_program->write_dword(address, data);
return;
diff --git a/src/devices/cpu/dsp32/dsp32.cpp b/src/devices/cpu/dsp32/dsp32.cpp
index f060e81d13c..98640f7d1b4 100644
--- a/src/devices/cpu/dsp32/dsp32.cpp
+++ b/src/devices/cpu/dsp32/dsp32.cpp
@@ -452,7 +452,8 @@ inline void dsp32c_device::WBYTE(offs_t addr, UINT8 data)
inline UINT16 dsp32c_device::RWORD(offs_t addr)
{
#if DETECT_MISALIGNED_MEMORY
- if (addr & 1) fprintf(stderr, "Unaligned word read @ %06X, PC=%06X\n", addr, PC);
+ if (!WORD_ALIGNED(addr))
+ osd_printf_error("Unaligned word read @ %06X, PC=%06X\n", addr, PC);
#endif
return m_program->read_word(addr);
}
@@ -460,7 +461,8 @@ inline UINT16 dsp32c_device::RWORD(offs_t addr)
inline UINT32 dsp32c_device::RLONG(offs_t addr)
{
#if DETECT_MISALIGNED_MEMORY
- if (addr & 3) fprintf(stderr, "Unaligned long read @ %06X, PC=%06X\n", addr, PC);
+ if (!DWORD_ALIGNED(addr))
+ osd_printf_error("Unaligned long read @ %06X, PC=%06X\n", addr, PC);
#endif
return m_program->read_dword(addr);
}
@@ -468,7 +470,8 @@ inline UINT32 dsp32c_device::RLONG(offs_t addr)
inline void dsp32c_device::WWORD(offs_t addr, UINT16 data)
{
#if DETECT_MISALIGNED_MEMORY
- if (addr & 1) fprintf(stderr, "Unaligned word write @ %06X, PC=%06X\n", addr, PC);
+ if (!WORD_ALIGNED(addr))
+ osd_printf_error("Unaligned word write @ %06X, PC=%06X\n", addr, PC);
#endif
m_program->write_word(addr, data);
}
@@ -476,7 +479,8 @@ inline void dsp32c_device::WWORD(offs_t addr, UINT16 data)
inline void dsp32c_device::WLONG(offs_t addr, UINT32 data)
{
#if DETECT_MISALIGNED_MEMORY
- if (addr & 3) fprintf(stderr, "Unaligned long write @ %06X, PC=%06X\n", addr, PC);
+ if (!DWORD_ALIGNED(addr))
+ osd_printf_error("Unaligned long write @ %06X, PC=%06X\n", addr, PC);
#endif
m_program->write_dword(addr, data);
}
diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp
index bc78626b00b..ba8b853e9ec 100644
--- a/src/devices/cpu/h8/h8.cpp
+++ b/src/devices/cpu/h8/h8.cpp
@@ -281,7 +281,7 @@ void h8_device::disassemble_am(char *&buffer, int am, offs_t pc, const UINT8 *op
"e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
};
- static const char *const r32_names[88] = {
+ static const char *const r32_names[8] = {
"er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp",
};
diff --git a/src/devices/cpu/hd61700/hd61700.cpp b/src/devices/cpu/hd61700/hd61700.cpp
index c786c7235ba..4e8d2c6590d 100644
--- a/src/devices/cpu/hd61700/hd61700.cpp
+++ b/src/devices/cpu/hd61700/hd61700.cpp
@@ -2654,7 +2654,7 @@ void hd61700_cpu_device::execute_run()
}
//if is in the internal ROM align the pc
- if ((m_fetch_addr&1) && m_pc < INT_ROM)
+ if (!WORD_ALIGNED(m_fetch_addr) && m_pc < INT_ROM)
set_pc((m_fetch_addr+1)>>1);
m_icount -= 3;
@@ -2871,7 +2871,7 @@ inline void hd61700_cpu_device::check_optional_jr(UINT8 arg)
{
if (arg & 0x80)
{
- if (m_pc < INT_ROM && !(m_fetch_addr&1)) read_op();
+ if (m_pc < INT_ROM && WORD_ALIGNED(m_fetch_addr)) read_op();
UINT8 arg1 = read_op();
diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp
index 052c7058604..71aec796760 100644
--- a/src/devices/cpu/hphybrid/hphybrid.cpp
+++ b/src/devices/cpu/hphybrid/hphybrid.cpp
@@ -673,12 +673,7 @@ UINT16 hp_hybrid_cpu_device::RM(UINT32 addr)
return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR);
case HP_REG_IV_ADDR:
- // Correct?
- if (!BIT(m_flags , HPHYBRID_IRH_SVC_BIT) && !BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) {
- return m_reg_IV;
- } else {
- return m_reg_IV | CURRENT_PA;
- }
+ return m_reg_IV;
case HP_REG_PA_ADDR:
return CURRENT_PA;
@@ -1021,7 +1016,7 @@ void hp_hybrid_cpu_device::check_for_interrupts(void)
// Do a double-indirect JSM IV,I instruction
WM(AEC_CASE_C , ++m_reg_R , m_reg_P);
- m_reg_P = RM(AEC_CASE_I , RM(HP_REG_IV_ADDR));
+ m_reg_P = RM(AEC_CASE_I , m_reg_IV + CURRENT_PA);
m_reg_I = fetch();
}
diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp
index f0d57ada9a0..4f593de3dea 100644
--- a/src/devices/cpu/i386/i386.cpp
+++ b/src/devices/cpu/i386/i386.cpp
@@ -41,23 +41,31 @@ const device_type PENTIUM4 = &device_creator<pentium4_device>;
i386_device::i386_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: cpu_device(mconfig, I386, "I386", tag, owner, clock, "i386", __FILE__)
+ , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
, m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0)
, m_io_config("io", ENDIANNESS_LITTLE, 32, 16, 0)
, m_smiact(*this)
{
m_program_config.m_logaddr_width = 32;
m_program_config.m_page_shift = 12;
+
+ // 32 unified
+ set_vtlb_dynamic_entries(32);
}
i386_device::i386_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int program_data_width, int program_addr_width, int io_data_width)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
+ , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
, m_program_config("program", ENDIANNESS_LITTLE, program_data_width, program_addr_width, 0)
, m_io_config("io", ENDIANNESS_LITTLE, io_data_width, 16, 0)
, m_smiact(*this)
{
m_program_config.m_logaddr_width = 32;
m_program_config.m_page_shift = 12;
+
+ // 32 unified
+ set_vtlb_dynamic_entries(32);
}
i386SX_device::i386SX_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
@@ -73,11 +81,15 @@ i486_device::i486_device(const machine_config &mconfig, const char *tag, device_
pentium_device::pentium_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: i386_device(mconfig, PENTIUM, "PENTIUM", tag, owner, clock, "pentium", __FILE__)
{
+ // 64 dtlb small, 8 dtlb large, 32 itlb
+ set_vtlb_dynamic_entries(96);
}
pentium_device::pentium_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
: i386_device(mconfig, type, name, tag, owner, clock, shortname, source)
{
+ // 64 dtlb small, 8 dtlb large, 32 itlb
+ set_vtlb_dynamic_entries(96);
}
mediagx_device::mediagx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
@@ -93,21 +105,29 @@ pentium_pro_device::pentium_pro_device(const machine_config &mconfig, const char
pentium_mmx_device::pentium_mmx_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pentium_device(mconfig, PENTIUM_MMX, "Pentium MMX", tag, owner, clock, "pentium_mmx", __FILE__)
{
+ // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
+ set_vtlb_dynamic_entries(96);
}
pentium2_device::pentium2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pentium_device(mconfig, PENTIUM2, "Pentium II", tag, owner, clock, "pentium2", __FILE__)
{
+ // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
+ set_vtlb_dynamic_entries(96);
}
pentium3_device::pentium3_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pentium_device(mconfig, PENTIUM3, "Pentium III", tag, owner, clock, "pentium3", __FILE__)
{
+ // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
+ set_vtlb_dynamic_entries(96);
}
pentium4_device::pentium4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: pentium_device(mconfig, PENTIUM4, "Pentium 4", tag, owner, clock, "pentium4", __FILE__)
{
+ // 128 dtlb, 64 itlb
+ set_vtlb_dynamic_entries(196);
}
@@ -956,10 +976,10 @@ void i386_device::i386_trap(int irq, int irq_gate, int trap_level)
//logerror("IRQ (%08x): Interrupt during V8086 task\n",m_pc);
if(type & 0x08)
{
- PUSH32(m_sreg[GS].selector & 0xffff);
- PUSH32(m_sreg[FS].selector & 0xffff);
- PUSH32(m_sreg[DS].selector & 0xffff);
- PUSH32(m_sreg[ES].selector & 0xffff);
+ PUSH32SEG(m_sreg[GS].selector & 0xffff);
+ PUSH32SEG(m_sreg[FS].selector & 0xffff);
+ PUSH32SEG(m_sreg[DS].selector & 0xffff);
+ PUSH32SEG(m_sreg[ES].selector & 0xffff);
}
else
{
@@ -981,7 +1001,7 @@ void i386_device::i386_trap(int irq, int irq_gate, int trap_level)
if(type & 0x08)
{
// 32-bit gate
- PUSH32(oldSS);
+ PUSH32SEG(oldSS);
PUSH32(oldESP);
}
else
@@ -1043,7 +1063,7 @@ void i386_device::i386_trap(int irq, int irq_gate, int trap_level)
else
{
PUSH32(oldflags & 0x00ffffff );
- PUSH32(m_sreg[CS].selector );
+ PUSH32SEG(m_sreg[CS].selector );
if(irq == 3 || irq == 4 || irq == 9 || irq_gate == 1)
PUSH32(m_eip );
else
@@ -1306,7 +1326,7 @@ void i386_device::i386_task_switch(UINT16 selector, UINT8 nested)
}
m_cr[3] = READ32(tss+0x1c); // CR3 (PDBR)
if(oldcr3 != m_cr[3])
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
/* Set the busy bit in the new task's descriptor */
if(selector & 0x0004)
@@ -1915,7 +1935,7 @@ void i386_device::i386_protected_mode_call(UINT16 seg, UINT32 off, int indirect,
if(operand32 != 0)
{
- PUSH32(oldSS);
+ PUSH32SEG(oldSS);
PUSH32(oldESP);
}
else
@@ -2049,7 +2069,7 @@ void i386_device::i386_protected_mode_call(UINT16 seg, UINT32 off, int indirect,
else
{
/* 32-bit operand size */
- PUSH32(m_sreg[CS].selector );
+ PUSH32SEG(m_sreg[CS].selector );
PUSH32(m_eip );
m_sreg[CS].selector = selector;
m_performed_intersegment_jump = 1;
@@ -2344,6 +2364,7 @@ void i386_device::i386_protected_mode_iret(int operand32)
I386_SREG desc,stack;
UINT8 CPL, RPL, DPL;
UINT32 newflags;
+ UINT8 IOPL = m_IOP1 | (m_IOP2 << 1);
CPL = m_CPL;
UINT32 ea = i386_translate(SS, (STACK_32BIT)?REG32(ESP):REG16(SP), 0);
@@ -2363,7 +2384,7 @@ void i386_device::i386_protected_mode_iret(int operand32)
if(V8086_MODE)
{
UINT32 oldflags = get_flags();
- if(!m_IOP1 || !m_IOP2)
+ if(IOPL != 3)
{
logerror("IRET (%08x): Is in Virtual 8086 mode and IOPL != 3.\n",m_pc);
FAULT(FAULT_GP,0)
@@ -2435,6 +2456,8 @@ void i386_device::i386_protected_mode_iret(int operand32)
{
UINT32 oldflags = get_flags();
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
+ if(CPL > IOPL)
+ newflags = (newflags & ~0x200 ) | (oldflags & 0x200);
}
set_flags(newflags);
m_eip = POP32() & 0xffff; // high 16 bits are ignored
@@ -2551,7 +2574,7 @@ void i386_device::i386_protected_mode_iret(int operand32)
}
if((desc.flags & 0x0080) == 0)
{
- logerror("IRET: Return CS segment is not present.\n");
+ logerror("IRET: (%08x) Return CS segment is not present.\n", m_pc);
FAULT(FAULT_NP,newCS & ~0x03)
}
if(newEIP > desc.limit)
@@ -2564,6 +2587,8 @@ void i386_device::i386_protected_mode_iret(int operand32)
{
UINT32 oldflags = get_flags();
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
+ if(CPL > IOPL)
+ newflags = (newflags & ~0x200 ) | (oldflags & 0x200);
}
if(operand32 == 0)
@@ -2733,6 +2758,8 @@ void i386_device::i386_protected_mode_iret(int operand32)
{
UINT32 oldflags = get_flags();
newflags = (newflags & ~0x00003000) | (oldflags & 0x00003000);
+ if(CPL > IOPL)
+ newflags = (newflags & ~0x200 ) | (oldflags & 0x200);
}
if(operand32 == 0)
@@ -3178,7 +3205,7 @@ void i386_device::i386_postload()
CHANGE_PC(m_eip);
}
-void i386_device::i386_common_init(int tlbsize)
+void i386_device::i386_common_init()
{
int i, j;
static const int regs8[8] = {AL,CL,DL,BL,AH,CH,DH,BH};
@@ -3211,7 +3238,6 @@ void i386_device::i386_common_init(int tlbsize)
m_program = &space(AS_PROGRAM);
m_direct = &m_program->direct();
m_io = &space(AS_IO);
- m_vtlb = vtlb_alloc(this, AS_PROGRAM, 0, tlbsize);
m_smi = false;
m_debugger_temp = 0;
m_lock = false;
@@ -3294,7 +3320,7 @@ void i386_device::i386_common_init(int tlbsize)
void i386_device::device_start()
{
- i386_common_init(32);
+ i386_common_init();
build_opcode_table(OP_I386);
m_cycle_table_rm = cycle_table_rm[CPU_CYCLES_I386].get();
@@ -3698,7 +3724,6 @@ void i386_device::zero_state()
void i386_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -3731,6 +3756,7 @@ void i386_device::device_reset()
// Family 3 (386), Model 0 (DX), Stepping 8 (D1)
REG32(EAX) = 0;
REG32(EDX) = (3 << 8) | (0 << 4) | (8);
+ m_cpu_version = REG32(EDX);
m_CPL = 0;
@@ -3804,7 +3830,7 @@ void i386_device::pentium_smi()
WRITE32(REG32(ESI), smram_state+SMRAM_ESI);
WRITE32(REG32(EDI), smram_state+SMRAM_EDI);
WRITE32(m_eip, smram_state+SMRAM_EIP);
- WRITE32(old_flags, smram_state+SMRAM_EAX);
+ WRITE32(old_flags, smram_state+SMRAM_EFLAGS);
WRITE32(m_cr[3], smram_state+SMRAM_CR3);
WRITE32(old_cr0, smram_state+SMRAM_CR0);
@@ -3890,7 +3916,7 @@ void i386_device::i386_set_a20_line(int state)
m_a20_mask = ~(1 << 20);
}
// TODO: how does A20M and the tlb interact
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
}
void i386_device::execute_run()
@@ -3976,7 +4002,7 @@ offs_t i386_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *opr
void i486_device::device_start()
{
- i386_common_init(32);
+ i386_common_init();
build_opcode_table(OP_I386 | OP_FPU | OP_I486);
build_x87_opcode_table();
@@ -3989,7 +4015,6 @@ void i486_device::device_start()
void i486_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4022,6 +4047,7 @@ void i486_device::device_reset()
// Family 4 (486), Model 0/1 (DX), Stepping 3
REG32(EAX) = 0;
REG32(EDX) = (4 << 8) | (0 << 4) | (3);
+ m_cpu_version = REG32(EDX);
CHANGE_PC(m_eip);
}
@@ -4033,8 +4059,7 @@ void i486_device::device_reset()
void pentium_device::device_start()
{
- // 64 dtlb small, 8 dtlb large, 32 itlb
- i386_common_init(96);
+ i386_common_init();
register_state_i386_x87();
build_opcode_table(OP_I386 | OP_FPU | OP_I486 | OP_PENTIUM);
@@ -4046,7 +4071,6 @@ void pentium_device::device_start()
void pentium_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4107,8 +4131,7 @@ void pentium_device::device_reset()
void mediagx_device::device_start()
{
- // probably 32 unified
- i386_common_init(32);
+ i386_common_init();
register_state_i386_x87();
build_x87_opcode_table();
@@ -4120,7 +4143,6 @@ void mediagx_device::device_start()
void mediagx_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4172,8 +4194,7 @@ void mediagx_device::device_reset()
void pentium_pro_device::device_start()
{
- // 64 dtlb small, 32 itlb
- i386_common_init(96);
+ i386_common_init();
register_state_i386_x87();
build_x87_opcode_table();
@@ -4185,7 +4206,6 @@ void pentium_pro_device::device_start()
void pentium_pro_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4247,8 +4267,7 @@ void pentium_pro_device::device_reset()
void pentium_mmx_device::device_start()
{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
+ i386_common_init();
register_state_i386_x87();
build_x87_opcode_table();
@@ -4260,7 +4279,6 @@ void pentium_mmx_device::device_start()
void pentium_mmx_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4320,8 +4338,7 @@ void pentium_mmx_device::device_reset()
void pentium2_device::device_start()
{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
+ i386_common_init();
register_state_i386_x87();
build_x87_opcode_table();
@@ -4333,7 +4350,6 @@ void pentium2_device::device_start()
void pentium2_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4387,8 +4403,7 @@ void pentium2_device::device_reset()
void pentium3_device::device_start()
{
- // 64 dtlb small, 8 dtlb large, 32 itlb small, 2 itlb large
- i386_common_init(96);
+ i386_common_init();
register_state_i386_x87_xmm();
build_x87_opcode_table();
@@ -4400,7 +4415,6 @@ void pentium3_device::device_start()
void pentium3_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
@@ -4456,8 +4470,7 @@ void pentium3_device::device_reset()
void pentium4_device::device_start()
{
- // 128 dtlb, 64 itlb
- i386_common_init(196);
+ i386_common_init();
register_state_i386_x87_xmm();
build_x87_opcode_table();
@@ -4469,7 +4482,6 @@ void pentium4_device::device_start()
void pentium4_device::device_reset()
{
zero_state();
- vtlb_flush_dynamic(m_vtlb);
m_sreg[CS].selector = 0xf000;
m_sreg[CS].base = 0xffff0000;
diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h
index c9ef38b4280..8e64458f228 100644
--- a/src/devices/cpu/i386/i386.h
+++ b/src/devices/cpu/i386/i386.h
@@ -8,7 +8,7 @@
#include "softfloat/milieu.h"
#include "softfloat/softfloat.h"
#include "debug/debugcpu.h"
-#include "cpu/vtlb.h"
+#include "divtlb.h"
#define INPUT_LINE_A20 1
@@ -24,7 +24,7 @@
#define X86_NUM_CPUS 4
-class i386_device : public cpu_device
+class i386_device : public cpu_device, public device_vtlb_interface
{
public:
// construction/destruction
@@ -270,8 +270,6 @@ struct I386_CALL_GATE
UINT8 *m_cycle_table_pm;
UINT8 *m_cycle_table_rm;
- vtlb_state *m_vtlb;
-
bool m_smm;
bool m_smi;
bool m_smi_latched;
@@ -335,6 +333,7 @@ struct I386_CALL_GATE
inline UINT32 DEC32(UINT32 dst);
inline void PUSH16(UINT16 value);
inline void PUSH32(UINT32 value);
+ inline void PUSH32SEG(UINT32 value);
inline void PUSH8(UINT8 value);
inline UINT8 POP8();
inline UINT16 POP16();
@@ -1411,7 +1410,7 @@ struct I386_CALL_GATE
void build_x87_opcode_table_df();
void build_x87_opcode_table();
void i386_postload();
- void i386_common_init(int tlbsize);
+ void i386_common_init();
void build_opcode_table(UINT32 features);
void pentium_smi();
void zero_state();
diff --git a/src/devices/cpu/i386/i386op32.inc b/src/devices/cpu/i386/i386op32.inc
index af5358e4bff..89c7bab44b4 100644
--- a/src/devices/cpu/i386/i386op32.inc
+++ b/src/devices/cpu/i386/i386op32.inc
@@ -475,7 +475,7 @@ void i386_device::i386_call_abs32() // Opcode 0x9a
}
else
{
- PUSH32(m_sreg[CS].selector );
+ PUSH32SEG(m_sreg[CS].selector );
PUSH32(m_eip );
m_sreg[CS].selector = ptr;
m_performed_intersegment_jump = 1;
@@ -1717,7 +1717,7 @@ void i386_device::i386_push_cs32() // Opcode 0x0e
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[CS].selector );
+ PUSH32SEG(m_sreg[CS].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -1731,7 +1731,7 @@ void i386_device::i386_push_ds32() // Opcode 0x1e
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[DS].selector );
+ PUSH32SEG(m_sreg[DS].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -1745,7 +1745,7 @@ void i386_device::i386_push_es32() // Opcode 0x06
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[ES].selector );
+ PUSH32SEG(m_sreg[ES].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -1759,7 +1759,7 @@ void i386_device::i386_push_fs32() // Opcode 0x0f a0
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[FS].selector );
+ PUSH32SEG(m_sreg[FS].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -1773,7 +1773,7 @@ void i386_device::i386_push_gs32() // Opcode 0x0f a8
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[GS].selector );
+ PUSH32SEG(m_sreg[GS].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -1787,7 +1787,7 @@ void i386_device::i386_push_ss32() // Opcode 0x16
else
offset = (REG16(SP) - 4) & 0xffff;
if(i386_limit_check(SS,offset) == 0)
- PUSH32(m_sreg[SS].selector );
+ PUSH32SEG(m_sreg[SS].selector );
else
FAULT(FAULT_SS,0)
CYCLES(CYCLES_PUSH_SREG);
@@ -2845,7 +2845,7 @@ void i386_device::i386_groupFF_32() // Opcode 0xff
}
else
{
- PUSH32(m_sreg[CS].selector );
+ PUSH32SEG(m_sreg[CS].selector );
PUSH32(m_eip );
m_sreg[CS].selector = selector;
m_performed_intersegment_jump = 1;
diff --git a/src/devices/cpu/i386/i386ops.h b/src/devices/cpu/i386/i386ops.h
index 2760b9cf410..ccf89a8720d 100644
--- a/src/devices/cpu/i386/i386ops.h
+++ b/src/devices/cpu/i386/i386ops.h
@@ -297,6 +297,7 @@ const i386_device::X86_OPCODE i386_device::s_x86_opcode_table[] =
{ 0x03, OP_2BYTE|OP_I386, &i386_device::i386_lsl_r16_rm16, &i386_device::i386_lsl_r32_rm32, false},
{ 0x06, OP_2BYTE|OP_I386, &i386_device::i386_clts, &i386_device::i386_clts, false},
{ 0x07, OP_2BYTE|OP_I386, &i386_device::i386_loadall, &i386_device::i386_loadall, false},
+ { 0x07, OP_2BYTE|OP_I486, &i386_device::i386_invalid, &i386_device::i386_invalid, false},
{ 0x08, OP_2BYTE|OP_I486, &i386_device::i486_invd, &i386_device::i486_invd, false},
{ 0x09, OP_2BYTE|OP_I486, &i386_device::i486_wbinvd, &i386_device::i486_wbinvd, false},
{ 0x0B, OP_2BYTE|OP_PENTIUM, &i386_device::pentium_ud2, &i386_device::pentium_ud2, false},
diff --git a/src/devices/cpu/i386/i386ops.inc b/src/devices/cpu/i386/i386ops.inc
index dc237c98469..2f13445c8be 100644
--- a/src/devices/cpu/i386/i386ops.inc
+++ b/src/devices/cpu/i386/i386ops.inc
@@ -701,7 +701,7 @@ void i386_device::i386_mov_cr_r32() // Opcode 0x0f 22
case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
case 3:
CYCLES(CYCLES_MOV_REG_CR3);
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
break;
case 4: CYCLES(1); break; // TODO
default:
@@ -2504,7 +2504,66 @@ void i386_device::i386_mov_tr_r32() // Opcode 0x0f 26
void i386_device::i386_loadall() // Opcode 0x0f 0x07 (0x0f 0x05 on 80286), undocumented
{
- fatalerror("i386: LOADALL unimplemented at %08X\n", m_pc - 1);
+ if(PROTECTED_MODE && (m_CPL != 0))
+ FAULT(FAULT_GP,0)
+ UINT32 ea = i386_translate(ES, REG32(EDI), 0);
+ m_cr[0] = READ32(ea) & 0xfffeffff; // wp not supported on 386
+ set_flags(READ32(ea + 0x04));
+ m_eip = READ32(ea + 0x08);
+ REG32(EDI) = READ32(ea + 0x0c);
+ REG32(ESI) = READ32(ea + 0x10);
+ REG32(EBP) = READ32(ea + 0x14);
+ REG32(ESP) = READ32(ea + 0x18);
+ REG32(EBX) = READ32(ea + 0x1c);
+ REG32(EDX) = READ32(ea + 0x20);
+ REG32(ECX) = READ32(ea + 0x24);
+ REG32(EAX) = READ32(ea + 0x28);
+ m_dr[6] = READ32(ea + 0x2c);
+ m_dr[7] = READ32(ea + 0x30);
+ m_task.segment = READ16(ea + 0x34);
+ m_ldtr.segment = READ16(ea + 0x38);
+ m_sreg[GS].selector = READ16(ea + 0x3c);
+ m_sreg[FS].selector = READ16(ea + 0x40);
+ m_sreg[DS].selector = READ16(ea + 0x44);
+ m_sreg[SS].selector = READ16(ea + 0x48);
+ m_sreg[CS].selector = READ16(ea + 0x4c);
+ m_sreg[ES].selector = READ16(ea + 0x50);
+ m_task.flags = READ32(ea + 0x54) >> 8;
+ m_task.base = READ32(ea + 0x58);
+ m_task.limit = READ32(ea + 0x5c);
+ m_idtr.base = READ32(ea + 0x64);
+ m_idtr.limit = READ32(ea + 0x68);
+ m_gdtr.base = READ32(ea + 0x70);
+ m_gdtr.limit = READ32(ea + 0x74);
+ m_ldtr.flags = READ32(ea + 0x78) >> 8;
+ m_ldtr.base = READ32(ea + 0x7c);
+ m_ldtr.limit = READ32(ea + 0x80);
+ m_sreg[GS].flags = READ32(ea + 0x84) >> 8;
+ m_sreg[GS].base = READ32(ea + 0x88);
+ m_sreg[GS].limit = READ32(ea + 0x8c);
+ m_sreg[FS].flags = READ32(ea + 0x90) >> 8;
+ m_sreg[FS].base = READ32(ea + 0x94);
+ m_sreg[FS].limit = READ32(ea + 0x98);
+ m_sreg[DS].flags = READ32(ea + 0x9c) >> 8;
+ m_sreg[DS].base = READ32(ea + 0xa0);
+ m_sreg[DS].limit = READ32(ea + 0xa4);
+ m_sreg[SS].flags = READ32(ea + 0xa8) >> 8;
+ m_sreg[SS].base = READ32(ea + 0xac);
+ m_sreg[SS].limit = READ32(ea + 0xb0);
+ m_sreg[CS].flags = READ32(ea + 0xb4) >> 8;
+ m_sreg[CS].base = READ32(ea + 0xb8);
+ m_sreg[CS].limit = READ32(ea + 0xbc);
+ m_sreg[ES].flags = READ32(ea + 0xc0) >> 8;
+ m_sreg[ES].base = READ32(ea + 0xc4);
+ m_sreg[ES].limit = READ32(ea + 0xc8);
+ m_CPL = (m_sreg[SS].flags >> 5) & 3; // cpl == dpl of ss
+
+ for(int i = 0; i < GS; i++)
+ {
+ m_sreg[i].valid = (m_sreg[i].flags & 0x80) ? true : false;
+ m_sreg[i].d = (m_sreg[i].flags & 0x4000) ? 1 : 0;
+ }
+ CHANGE_PC(m_eip);
}
void i386_device::i386_invalid()
diff --git a/src/devices/cpu/i386/i386priv.h b/src/devices/cpu/i386/i386priv.h
index 9913d851fa2..0a471adfe36 100644
--- a/src/devices/cpu/i386/i386priv.h
+++ b/src/devices/cpu/i386/i386priv.h
@@ -486,7 +486,7 @@ int i386_device::translate_address(int pl, int type, UINT32 *address, UINT32 *er
if(!(m_cr[0] & 0x80000000)) // Some (very few) old OS's won't work with this
return TRUE;
- const vtlb_entry *table = vtlb_table(m_vtlb);
+ const vtlb_entry *table = vtlb_table();
UINT32 index = *address >> 12;
vtlb_entry entry = table[index];
if(type == TRANSLATE_FETCH)
@@ -506,7 +506,7 @@ int i386_device::translate_address(int pl, int type, UINT32 *address, UINT32 *er
*error |= 1;
return FALSE;
}
- vtlb_dynload(m_vtlb, index, *address, entry);
+ vtlb_dynload(index, *address, entry);
return TRUE;
}
if(!(entry & (1 << type)))
@@ -557,7 +557,7 @@ UINT16 i386_device::FETCH16()
UINT16 value;
UINT32 address = m_pc, error;
- if( address & 0x1 ) { /* Unaligned read */
+ if( !WORD_ALIGNED(address) ) { /* Unaligned read */
value = (FETCH() << 0);
value |= (FETCH() << 8);
} else {
@@ -575,7 +575,7 @@ UINT32 i386_device::FETCH32()
UINT32 value;
UINT32 address = m_pc, error;
- if( m_pc & 0x3 ) { /* Unaligned read */
+ if( !DWORD_ALIGNED(m_pc) ) { /* Unaligned read */
value = (FETCH() << 0);
value |= (FETCH() << 8);
value |= (FETCH() << 16);
@@ -607,7 +607,7 @@ UINT16 i386_device::READ16(UINT32 ea)
UINT16 value;
UINT32 address = ea, error;
- if( ea & 0x1 ) { /* Unaligned read */
+ if( !WORD_ALIGNED(ea) ) { /* Unaligned read */
value = (READ8( address+0 ) << 0);
value |= (READ8( address+1 ) << 8);
} else {
@@ -624,7 +624,7 @@ UINT32 i386_device::READ32(UINT32 ea)
UINT32 value;
UINT32 address = ea, error;
- if( ea & 0x3 ) { /* Unaligned read */
+ if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */
value = (READ8( address+0 ) << 0);
value |= (READ8( address+1 ) << 8);
value |= (READ8( address+2 ) << 16),
@@ -644,7 +644,7 @@ UINT64 i386_device::READ64(UINT32 ea)
UINT64 value;
UINT32 address = ea, error;
- if( ea & 0x7 ) { /* Unaligned read */
+ if( !QWORD_ALIGNED(ea) ) { /* Unaligned read */
value = (((UINT64) READ8( address+0 )) << 0);
value |= (((UINT64) READ8( address+1 )) << 8);
value |= (((UINT64) READ8( address+2 )) << 16);
@@ -678,7 +678,7 @@ UINT16 i386_device::READ16PL0(UINT32 ea)
UINT16 value;
UINT32 address = ea, error;
- if( ea & 0x1 ) { /* Unaligned read */
+ if( !WORD_ALIGNED(ea) ) { /* Unaligned read */
value = (READ8PL0( address+0 ) << 0);
value |= (READ8PL0( address+1 ) << 8);
} else {
@@ -696,7 +696,7 @@ UINT32 i386_device::READ32PL0(UINT32 ea)
UINT32 value;
UINT32 address = ea, error;
- if( ea & 0x3 ) { /* Unaligned read */
+ if( !DWORD_ALIGNED(ea) ) { /* Unaligned read */
value = (READ8PL0( address+0 ) << 0);
value |= (READ8PL0( address+1 ) << 8);
value |= (READ8PL0( address+2 ) << 16);
@@ -732,7 +732,7 @@ void i386_device::WRITE16(UINT32 ea, UINT16 value)
{
UINT32 address = ea, error;
- if( ea & 0x1 ) { /* Unaligned write */
+ if( !WORD_ALIGNED(ea) ) { /* Unaligned write */
WRITE8( address+0, value & 0xff );
WRITE8( address+1, (value >> 8) & 0xff );
} else {
@@ -747,7 +747,7 @@ void i386_device::WRITE32(UINT32 ea, UINT32 value)
{
UINT32 address = ea, error;
- if( ea & 0x3 ) { /* Unaligned write */
+ if( !DWORD_ALIGNED(ea) ) { /* Unaligned write */
WRITE8( address+0, value & 0xff );
WRITE8( address+1, (value >> 8) & 0xff );
WRITE8( address+2, (value >> 16) & 0xff );
@@ -765,7 +765,7 @@ void i386_device::WRITE64(UINT32 ea, UINT64 value)
{
UINT32 address = ea, error;
- if( ea & 0x7 ) { /* Unaligned write */
+ if( !QWORD_ALIGNED(ea) ) { /* Unaligned write */
WRITE8( address+0, value & 0xff );
WRITE8( address+1, (value >> 8) & 0xff );
WRITE8( address+2, (value >> 16) & 0xff );
@@ -1000,6 +1000,23 @@ void i386_device::PUSH32(UINT32 value)
REG16(SP) = new_esp;
}
}
+
+void i386_device::PUSH32SEG(UINT32 value)
+{
+ UINT32 ea, new_esp;
+ if( STACK_32BIT ) {
+ new_esp = REG32(ESP) - 4;
+ ea = i386_translate(SS, new_esp, 1);
+ ((m_cpu_version & 0xf00) == 0x300) ? WRITE16(ea, value) : WRITE32(ea, value ); // 486 also?
+ REG32(ESP) = new_esp;
+ } else {
+ new_esp = (REG16(SP) - 4) & 0xffff;
+ ea = i386_translate(SS, new_esp, 1);
+ ((m_cpu_version & 0xf00) == 0x300) ? WRITE16(ea, value) : WRITE32(ea, value );
+ REG16(SP) = new_esp;
+ }
+}
+
void i386_device::PUSH8(UINT8 value)
{
if( m_operand_size ) {
diff --git a/src/devices/cpu/i386/i486ops.inc b/src/devices/cpu/i386/i486ops.inc
index d22f6c079c3..8be406692d4 100644
--- a/src/devices/cpu/i386/i486ops.inc
+++ b/src/devices/cpu/i386/i486ops.inc
@@ -312,7 +312,7 @@ void i386_device::i486_group0F01_16() // Opcode 0x0f 01
}
ea = GetEA(modrm,-1);
CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(m_vtlb, ea);
+ vtlb_flush_address(ea);
break;
}
default:
@@ -430,7 +430,7 @@ void i386_device::i486_group0F01_32() // Opcode 0x0f 01
}
ea = GetEA(modrm,-1);
CYCLES(25); // TODO: add to cycles.h
- vtlb_flush_address(m_vtlb, ea);
+ vtlb_flush_address(ea);
break;
}
default:
@@ -500,12 +500,12 @@ void i386_device::i486_mov_cr_r32() // Opcode 0x0f 22
case 0:
CYCLES(CYCLES_MOV_REG_CR0);
if((oldcr ^ m_cr[cr]) & 0x80010000)
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
break;
case 2: CYCLES(CYCLES_MOV_REG_CR2); break;
case 3:
CYCLES(CYCLES_MOV_REG_CR3);
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
break;
case 4: CYCLES(1); break; // TODO
default:
diff --git a/src/devices/cpu/i4004/i4004.cpp b/src/devices/cpu/i4004/i4004.cpp
index d4ba8891260..371074238c9 100644
--- a/src/devices/cpu/i4004/i4004.cpp
+++ b/src/devices/cpu/i4004/i4004.cpp
@@ -30,7 +30,9 @@ i4004_cpu_device::i4004_cpu_device(const machine_config &mconfig, const char *ta
, m_io_config("io", ENDIANNESS_LITTLE, 8, 6, 0)
, m_data_config("data", ENDIANNESS_LITTLE, 8, 12, 0), m_A(0), m_C(0), m_TEST(0), m_flags(0), m_program(nullptr), m_direct(nullptr), m_data(nullptr), m_io(nullptr), m_icount(0), m_pc_pos(0), m_addr_mask(0)
{
- m_is_octal = true;
+ m_program_config.m_is_octal = true;
+ m_io_config.m_is_octal = true;
+ m_data_config.m_is_octal = true;
}
diff --git a/src/devices/cpu/i8089/i8089.cpp b/src/devices/cpu/i8089/i8089.cpp
index 22494cfdd2f..ade9e4f768b 100644
--- a/src/devices/cpu/i8089/i8089.cpp
+++ b/src/devices/cpu/i8089/i8089.cpp
@@ -289,7 +289,7 @@ UINT16 i8089_device::read_word(bool space, offs_t address)
UINT16 data;
address_space *aspace = (space ? m_io : m_mem);
- if (sysbus_width() && !(address & 1))
+ if (sysbus_width() && WORD_ALIGNED(address))
{
data = aspace->read_word(address);
}
@@ -311,7 +311,7 @@ void i8089_device::write_word(bool space, offs_t address, UINT16 data)
{
address_space *aspace = (space ? m_io : m_mem);
- if (sysbus_width() && !(address & 1))
+ if (sysbus_width() && WORD_ALIGNED(address))
{
aspace->write_word(address, data);
}
diff --git a/src/devices/cpu/i86/i86.txt b/src/devices/cpu/i86/i86.txt
index 39b54d6a8d0..fb27b8526fe 100644
--- a/src/devices/cpu/i86/i86.txt
+++ b/src/devices/cpu/i86/i86.txt
@@ -29,6 +29,7 @@ mov sreg, doesnot disable until next operation is executed
8086/8088
---------
"mov cs, " causes unconditional jump!
+0xd6 is salc (sbb al,al) as all other intel x86-16 and -32 cpus
80C86/80C88
-----------
@@ -36,9 +37,10 @@ mov sreg, doesnot disable until next operation is executed
80186/80188
-----------
-integrated pic8259, pit8253, dma8253 (but not at standard pc addresses)
+integrated pic, timer and dmac entirely incompatible with 8259, 825[3,4] and 82[3,5]7
additional instructions
-"mov cs, " ?
+#BR/bound/int 5, #UD/illegal instruction/int 6, #NM/coprocessor unavailable/int 7 support
+"mov cs, " ignored (likely causes int 6)
shift count anded with 0x1f
80188
@@ -52,6 +54,7 @@ although it is based on 80186 instruction set, some behaviours follow 8086
8080 emulation mode
"mov cs, " ignored
shift count not anded (acts like 8086)
+0xd6 is xlat alias
NEC 70116 (V30)
---------------
@@ -69,11 +72,11 @@ no 8080 emulation mode
NEC V40
-------
-pinout, integrated peripherals as 80186
+pinout, integrated peripherals 8259,54,37 clones at nonpc compatible addresses
NEC V50
-------
-pinout, integrated peripherals as 80188
+pinout, integrated peripherals as v40
NEC V33?
--------
@@ -92,9 +95,9 @@ v30? emulation mode (without 8080 emulation mode)
80286
-----
-80186 with additional instructions
+80186 with additional instructions but no peripherals
24 bit address bus,
-protected mode
+protected mode selector/descriptor
80386 and later
---------------
diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp
index 224b844387c..f754445379b 100644
--- a/src/devices/cpu/i960/i960.cpp
+++ b/src/devices/cpu/i960/i960.cpp
@@ -26,7 +26,7 @@ i960_cpu_device::i960_cpu_device(const machine_config &mconfig, const char *tag,
UINT32 i960_cpu_device::i960_read_dword_unaligned(UINT32 address)
{
- if (address & 3)
+ if (!DWORD_ALIGNED(address))
return m_program->read_byte(address) | m_program->read_byte(address+1)<<8 | m_program->read_byte(address+2)<<16 | m_program->read_byte(address+3)<<24;
else
return m_program->read_dword(address);
@@ -34,7 +34,7 @@ UINT32 i960_cpu_device::i960_read_dword_unaligned(UINT32 address)
UINT16 i960_cpu_device::i960_read_word_unaligned(UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return m_program->read_byte(address) | m_program->read_byte(address+1)<<8;
else
return m_program->read_word(address);
@@ -42,7 +42,7 @@ UINT16 i960_cpu_device::i960_read_word_unaligned(UINT32 address)
void i960_cpu_device::i960_write_dword_unaligned(UINT32 address, UINT32 data)
{
- if (address & 3)
+ if (!DWORD_ALIGNED(address))
{
m_program->write_byte(address, data & 0xff);
m_program->write_byte(address+1, (data>>8)&0xff);
@@ -57,7 +57,7 @@ void i960_cpu_device::i960_write_dword_unaligned(UINT32 address, UINT32 data)
void i960_cpu_device::i960_write_word_unaligned(UINT32 address, UINT16 data)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
{
m_program->write_byte(address, data & 0xff);
m_program->write_byte(address+1, (data>>8)&0xff);
diff --git a/src/devices/cpu/m37710/m37710il.h b/src/devices/cpu/m37710/m37710il.h
index ffc1aed0a7a..eb79f0fddd6 100644
--- a/src/devices/cpu/m37710/m37710il.h
+++ b/src/devices/cpu/m37710/m37710il.h
@@ -42,7 +42,7 @@ inline UINT32 m37710_cpu_device::m37710i_read_16_normal(UINT32 address)
inline UINT32 m37710_cpu_device::m37710i_read_16_immediate(UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return m37710_read_8_immediate(address) | (m37710_read_8_immediate(address+1)<<8);
else
return m37710_read_16_immediate(address);
@@ -65,7 +65,7 @@ inline void m37710_cpu_device::m37710i_write_16_direct(UINT32 address, UINT32 va
inline UINT32 m37710_cpu_device::m37710i_read_24_normal(UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return m37710_read_8(address) | (m37710_read_16(address+1)<<8);
else
return m37710_read_16(address) | (m37710_read_8(address+2)<<16);
@@ -73,7 +73,7 @@ inline UINT32 m37710_cpu_device::m37710i_read_24_normal(UINT32 address)
inline UINT32 m37710_cpu_device::m37710i_read_24_immediate(UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return m37710_read_8_immediate(address) | (m37710_read_16_immediate(address+1)<<8);
else
return m37710_read_16_immediate(address) | (m37710_read_8_immediate(address+2)<<16);
@@ -81,7 +81,7 @@ inline UINT32 m37710_cpu_device::m37710i_read_24_immediate(UINT32 address)
inline UINT32 m37710_cpu_device::m37710i_read_24_direct(UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return m37710_read_8(address) | (m37710_read_16(address+1)<<8);
else
return m37710_read_16(address) | (m37710_read_8(address+2)<<16);
diff --git a/src/devices/cpu/m6800/6800dasm.cpp b/src/devices/cpu/m6800/6800dasm.cpp
index 49f908013cd..2e94ef3b62d 100644
--- a/src/devices/cpu/m6800/6800dasm.cpp
+++ b/src/devices/cpu/m6800/6800dasm.cpp
@@ -52,7 +52,8 @@ enum op_names {
rts, sba, sbca, sbcb, sec, sev, sta, stb,
_std, sei, sts, stx, suba, subb, subd, swi,
wai, tab, tap, tba, tim, tpa, tst, tsta,
- tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx
+ tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx,
+ bitx
};
static const char *const op_name_str[] = {
@@ -71,7 +72,8 @@ static const char *const op_name_str[] = {
"rts", "sba", "sbca", "sbcb", "sec", "sev", "sta", "stb",
"std", "sei", "sts", "stx", "suba", "subb", "subd", "swi",
"wai", "tab", "tap", "tba", "tim", "tpa", "tst", "tsta",
- "tstb", "tsx", "txs", "asx1", "asx2", "xgdx", "addx", "adcx"
+ "tstb", "tsx", "txs", "asx1", "asx2", "xgdx", "addx", "adcx",
+ "bitx"
};
/*
@@ -82,7 +84,7 @@ static const char *const op_name_str[] = {
* 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701
*/
-static const UINT8 table[0x102][3] = {
+static const UINT8 table[0x104][3] = {
{ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */
{lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0},
{inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0},
@@ -151,7 +153,11 @@ static const UINT8 table[0x102][3] = {
/* extra instruction $fc for NSC-8105 */
{addx,ext,0},
/* extra instruction $ec for NSC-8105 */
- {adcx,imb,0}
+ {adcx,imb,0},
+ /* extra instruction $bb for NSC-8105 */
+ {bitx,imx,0},
+ /* extra instruction $b2 for NSC-8105 */
+ {stx,imx,0}
};
/* some macros to keep things short */
@@ -188,6 +194,8 @@ static unsigned Dasm680x (int subtype, char *buf, unsigned pc, const UINT8 *opro
/* and check for extra instruction */
if (code == 0xfc) code = 0x0100;
if (code == 0xec) code = 0x0101;
+ if (code == 0x7b) code = 0x0102;
+ if (code == 0x71) code = 0x0103;
}
opcode = table[code][0];
diff --git a/src/devices/cpu/m6800/6800ops.inc b/src/devices/cpu/m6800/6800ops.inc
index cf0360c7538..078529d16ab 100644
--- a/src/devices/cpu/m6800/6800ops.inc
+++ b/src/devices/cpu/m6800/6800ops.inc
@@ -2073,11 +2073,12 @@ OP_HANDLER( ldd_ix )
}
/* $ec ADCX immediate -**** NSC8105 only. Flags are a guess - copied from addb_im() */
+// actually this is ADDX, causes garbage in nightgal.cpp otherwise
OP_HANDLER( adcx_im )
{
UINT16 t,r;
IMMBYTE(t);
- r = X+t+(CC&0x01);
+ r = X+t;
CLR_HNZVC;
SET_FLAGS8(X,t,r);
SET_H(X,t,r);
@@ -2282,3 +2283,26 @@ OP_HANDLER( stx_ex )
EXTENDED;
WM16(EAD,&m_x);
}
+
+/* NSC8105 specific, guessed opcodes (tested by Night Gal Summer) */
+// $bb - $mask & [X + $disp8]
+OP_HANDLER( btst_ix )
+{
+ UINT8 val;
+ UINT8 mask = M_RDOP_ARG(PCD);
+ {EA=X+(M_RDOP_ARG(PCD+1));PC+=2;}
+ val = RM(EAD) & mask;
+ CLR_NZVC; SET_NZ8(val);
+}
+
+// $b2 - assuming correct, store first byte to (X + $disp8)
+OP_HANDLER( stx_nsc )
+{
+ IMM8;
+ UINT8 val = RM(EAD);
+ IMM8;
+ EA = X + RM(EAD);
+ CLR_NZV;
+ SET_NZ8(val);
+ WM(EAD,val);
+} \ No newline at end of file
diff --git a/src/devices/cpu/m6800/6800tbl.inc b/src/devices/cpu/m6800/6800tbl.inc
index 38376dadd59..10515e54bdc 100644
--- a/src/devices/cpu/m6800/6800tbl.inc
+++ b/src/devices/cpu/m6800/6800tbl.inc
@@ -105,30 +105,54 @@ const m6800_cpu_device::op_func m6800_cpu_device::hd63701_insn[0x100] = {
};
const m6800_cpu_device::op_func m6800_cpu_device::nsc8105_insn[0x100] = {
+// 0
&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::nop, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tap, &m6800_cpu_device::illegal,&m6800_cpu_device::tpa,
+// 8
&m6800_cpu_device::inx, &m6800_cpu_device::clv, &m6800_cpu_device::dex, &m6800_cpu_device::sev, &m6800_cpu_device::clc, &m6800_cpu_device::cli, &m6800_cpu_device::sec, &m6800_cpu_device::sei,
+// 10
&m6800_cpu_device::sba, &m6800_cpu_device::illegal,&m6800_cpu_device::cba, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::tab, &m6800_cpu_device::illegal,&m6800_cpu_device::tba,
+// 18
&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::daa, &m6800_cpu_device::aba, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,
+// 20
&m6800_cpu_device::bra, &m6800_cpu_device::bhi, &m6800_cpu_device::brn, &m6800_cpu_device::bls, &m6800_cpu_device::bcc, &m6800_cpu_device::bne, &m6800_cpu_device::bcs, &m6800_cpu_device::beq,
+// 28
&m6800_cpu_device::bvc, &m6800_cpu_device::bpl, &m6800_cpu_device::bvs, &m6800_cpu_device::bmi, &m6800_cpu_device::bge, &m6800_cpu_device::bgt, &m6800_cpu_device::blt, &m6800_cpu_device::ble,
+// 30
&m6800_cpu_device::tsx, &m6800_cpu_device::pula, &m6800_cpu_device::ins, &m6800_cpu_device::pulb, &m6800_cpu_device::des, &m6800_cpu_device::psha, &m6800_cpu_device::txs, &m6800_cpu_device::pshb,
+// 38
&m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::rts, &m6800_cpu_device::rti, &m6800_cpu_device::illegal,&m6800_cpu_device::wai, &m6800_cpu_device::illegal,&m6800_cpu_device::swi,
+// 40
&m6800_cpu_device::suba_im,&m6800_cpu_device::sbca_im,&m6800_cpu_device::cmpa_im,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_im,&m6800_cpu_device::lda_im, &m6800_cpu_device::bita_im,&m6800_cpu_device::sta_im,
+// 48
&m6800_cpu_device::eora_im,&m6800_cpu_device::ora_im, &m6800_cpu_device::adca_im,&m6800_cpu_device::adda_im,&m6800_cpu_device::cmpx_im,&m6800_cpu_device::lds_im, &m6800_cpu_device::bsr, &m6800_cpu_device::sts_im,
+// 50
&m6800_cpu_device::suba_di,&m6800_cpu_device::sbca_di,&m6800_cpu_device::cmpa_di,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_di,&m6800_cpu_device::lda_di, &m6800_cpu_device::bita_di,&m6800_cpu_device::sta_di,
+// 58
&m6800_cpu_device::eora_di,&m6800_cpu_device::ora_di, &m6800_cpu_device::adca_di,&m6800_cpu_device::adda_di,&m6800_cpu_device::cmpx_di,&m6800_cpu_device::lds_di, &m6800_cpu_device::jsr_di, &m6800_cpu_device::sts_di,
+// 60
&m6800_cpu_device::suba_ix,&m6800_cpu_device::sbca_ix,&m6800_cpu_device::cmpa_ix,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ix,&m6800_cpu_device::lda_ix, &m6800_cpu_device::bita_ix,&m6800_cpu_device::sta_ix,
+// 68
&m6800_cpu_device::eora_ix,&m6800_cpu_device::ora_ix, &m6800_cpu_device::adca_ix,&m6800_cpu_device::adda_ix,&m6800_cpu_device::cmpx_ix,&m6800_cpu_device::lds_ix, &m6800_cpu_device::jsr_ix, &m6800_cpu_device::sts_ix,
+// 70
&m6800_cpu_device::suba_ex,&m6800_cpu_device::sbca_ex,&m6800_cpu_device::cmpa_ex,&m6800_cpu_device::illegal,&m6800_cpu_device::anda_ex,&m6800_cpu_device::lda_ex, &m6800_cpu_device::bita_ex,&m6800_cpu_device::sta_ex,
+// 78
&m6800_cpu_device::eora_ex,&m6800_cpu_device::ora_ex, &m6800_cpu_device::adca_ex,&m6800_cpu_device::adda_ex,&m6800_cpu_device::cmpx_ex,&m6800_cpu_device::lds_ex, &m6800_cpu_device::jsr_ex, &m6800_cpu_device::sts_ex,
+// 80
&m6800_cpu_device::nega, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::coma, &m6800_cpu_device::lsra, &m6800_cpu_device::rora, &m6800_cpu_device::illegal,&m6800_cpu_device::asra,
+// 88
&m6800_cpu_device::asla, &m6800_cpu_device::deca, &m6800_cpu_device::rola, &m6800_cpu_device::illegal,&m6800_cpu_device::inca, &m6800_cpu_device::illegal,&m6800_cpu_device::tsta, &m6800_cpu_device::clra,
+// 90
&m6800_cpu_device::negb, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::comb, &m6800_cpu_device::lsrb, &m6800_cpu_device::rorb, &m6800_cpu_device::illegal,&m6800_cpu_device::asrb,
+// 98
&m6800_cpu_device::aslb, &m6800_cpu_device::decb, &m6800_cpu_device::rolb, &m6800_cpu_device::illegal,&m6800_cpu_device::incb, &m6800_cpu_device::illegal,&m6800_cpu_device::tstb, &m6800_cpu_device::clrb,
+// a0
&m6800_cpu_device::neg_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ix, &m6800_cpu_device::lsr_ix, &m6800_cpu_device::ror_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ix,
+// a8
&m6800_cpu_device::asl_ix, &m6800_cpu_device::dec_ix, &m6800_cpu_device::rol_ix, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ix, &m6800_cpu_device::jmp_ix, &m6800_cpu_device::tst_ix, &m6800_cpu_device::clr_ix,
-&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::illegal,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::ror_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ex,
-&m6800_cpu_device::asl_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::inc_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::clr_ex,
+// b0
+&m6800_cpu_device::neg_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_nsc,&m6800_cpu_device::com_ex, &m6800_cpu_device::lsr_ex, &m6800_cpu_device::ror_ex, &m6800_cpu_device::illegal,&m6800_cpu_device::asr_ex,
+// b8
+&m6800_cpu_device::asl_ex, &m6800_cpu_device::dec_ex, &m6800_cpu_device::rol_ex, &m6800_cpu_device::btst_ix,&m6800_cpu_device::inc_ex, &m6800_cpu_device::jmp_ex, &m6800_cpu_device::tst_ex, &m6800_cpu_device::clr_ex,
&m6800_cpu_device::subb_im,&m6800_cpu_device::sbcb_im,&m6800_cpu_device::cmpb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_im,&m6800_cpu_device::ldb_im, &m6800_cpu_device::bitb_im,&m6800_cpu_device::stb_im,
&m6800_cpu_device::eorb_im,&m6800_cpu_device::orb_im, &m6800_cpu_device::adcb_im,&m6800_cpu_device::addb_im,&m6800_cpu_device::illegal,&m6800_cpu_device::ldx_im, &m6800_cpu_device::illegal,&m6800_cpu_device::stx_im,
&m6800_cpu_device::subb_di,&m6800_cpu_device::sbcb_di,&m6800_cpu_device::cmpb_di,&m6800_cpu_device::illegal,&m6800_cpu_device::andb_di,&m6800_cpu_device::ldb_di, &m6800_cpu_device::bitb_di,&m6800_cpu_device::stb_di,
diff --git a/src/devices/cpu/m6800/m6800.cpp b/src/devices/cpu/m6800/m6800.cpp
index 84d3b8d03e2..730d7a1be4b 100644
--- a/src/devices/cpu/m6800/m6800.cpp
+++ b/src/devices/cpu/m6800/m6800.cpp
@@ -488,7 +488,7 @@ const UINT8 m6800_cpu_device::cycles_63701[256] =
const UINT8 m6800_cpu_device::cycles_nsc8105[256] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
- /*0*/ XX,XX, 2,XX,XX, 2,XX, 2, 4, 2, 4, 2, 2, 2, 2, 2,
+ /*0*/ 5,XX, 2,XX,XX, 2,XX, 2, 4, 2, 4, 2, 2, 2, 2, 2,
/*1*/ 2,XX, 2,XX,XX, 2,XX, 2,XX,XX, 2, 2,XX,XX,XX,XX,
/*2*/ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
/*3*/ 4, 4, 4, 4, 4, 4, 4, 4,XX,XX, 5,10,XX, 9,XX,12,
@@ -499,7 +499,7 @@ const UINT8 m6800_cpu_device::cycles_nsc8105[256] =
/*8*/ 2,XX,XX, 2, 2, 2,XX, 2, 2, 2, 2,XX, 2,XX, 2, 2,
/*9*/ 2,XX,XX, 2, 2, 2,XX, 2, 2, 2, 2,XX, 2,XX, 2, 2,
/*A*/ 7,XX,XX, 7, 7, 7,XX, 7, 7, 7, 7,XX, 7, 4, 7, 7,
- /*B*/ 6,XX,XX, 6, 6, 6,XX, 6, 6, 6, 6,XX, 6, 3, 6, 6,
+ /*B*/ 6,XX,XX, 6, 6, 6,XX, 6, 6, 6, 6, 5, 6, 3, 6, 6,
/*C*/ 2, 2, 2,XX, 2, 2, 2, 3, 2, 2, 2, 2,XX, 3,XX, 4,
/*D*/ 3, 3, 3,XX, 3, 3, 3, 4, 3, 3, 3, 3,XX, 4,XX, 5,
/*E*/ 5, 5, 5,XX, 5, 5, 5, 6, 5, 5, 5, 5, 5, 6,XX, 7,
diff --git a/src/devices/cpu/m6800/m6800.h b/src/devices/cpu/m6800/m6800.h
index bb6055e8ad0..82696a6ee43 100644
--- a/src/devices/cpu/m6800/m6800.h
+++ b/src/devices/cpu/m6800/m6800.h
@@ -426,6 +426,8 @@ protected:
void cpx_im();
void cpx_ix();
void trap();
+ void btst_ix();
+ void stx_nsc();
};
diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp
index dc7e0b14a6f..aaa1db079cf 100644
--- a/src/devices/cpu/m68000/m68kcpu.cpp
+++ b/src/devices/cpu/m68000/m68kcpu.cpp
@@ -1383,7 +1383,7 @@ UINT16 m68000_base_device::readword_d32_mmu(offs_t address)
UINT32 address0 = pmmu_translate_addr(this, address);
if (mmu_tmp_buserror_occurred) {
return ~0;
- } else if (!(address & 1)) {
+ } else if (WORD_ALIGNED(address)) {
return m_space->read_word(address0);
} else {
UINT32 address1 = pmmu_translate_addr(this, address + 1);
@@ -1396,7 +1396,7 @@ UINT16 m68000_base_device::readword_d32_mmu(offs_t address)
}
}
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
return m_space->read_word(address);
result = m_space->read_byte(address) << 8;
return result | m_space->read_byte(address + 1);
@@ -1410,7 +1410,7 @@ void m68000_base_device::writeword_d32_mmu(offs_t address, UINT16 data)
UINT32 address0 = pmmu_translate_addr(this, address);
if (mmu_tmp_buserror_occurred) {
return;
- } else if (!(address & 1)) {
+ } else if (WORD_ALIGNED(address)) {
m_space->write_word(address0, data);
return;
} else {
@@ -1425,7 +1425,7 @@ void m68000_base_device::writeword_d32_mmu(offs_t address, UINT16 data)
}
}
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
{
m_space->write_word(address, data);
return;
@@ -1447,13 +1447,13 @@ UINT32 m68000_base_device::readlong_d32_mmu(offs_t address)
} else if ((address +3) & 0xfc) {
// not at page boundary; use default code
address = address0;
- } else if (!(address & 3)) { // 0
+ } else if (DWORD_ALIGNED(address)) { // 0
return m_space->read_dword(address0);
} else {
UINT32 address2 = pmmu_translate_addr(this, address+2);
if (mmu_tmp_buserror_occurred) {
return ~0;
- } else if (!(address & 1)) { // 2
+ } else if (WORD_ALIGNED(address)) { // 2
result = m_space->read_word(address0) << 16;
return result | m_space->read_word(address2);
} else {
@@ -1470,9 +1470,9 @@ UINT32 m68000_base_device::readlong_d32_mmu(offs_t address)
}
}
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
return m_space->read_dword(address);
- else if (!(address & 1))
+ else if (WORD_ALIGNED(address))
{
result = m_space->read_word(address) << 16;
return result | m_space->read_word(address + 2);
@@ -1493,14 +1493,14 @@ void m68000_base_device::writelong_d32_mmu(offs_t address, UINT32 data)
} else if ((address +3) & 0xfc) {
// not at page boundary; use default code
address = address0;
- } else if (!(address & 3)) { // 0
+ } else if (DWORD_ALIGNED(address)) { // 0
m_space->write_dword(address0, data);
return;
} else {
UINT32 address2 = pmmu_translate_addr(this, address+2);
if (mmu_tmp_buserror_occurred) {
return;
- } else if (!(address & 1)) { // 2
+ } else if (WORD_ALIGNED(address)) { // 2
m_space->write_word(address0, data >> 16);
m_space->write_word(address2, data);
return;
@@ -1519,12 +1519,12 @@ void m68000_base_device::writelong_d32_mmu(offs_t address, UINT32 data)
}
}
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
{
m_space->write_dword(address, data);
return;
}
- else if (!(address & 1))
+ else if (WORD_ALIGNED(address))
{
m_space->write_word(address, data >> 16);
m_space->write_word(address + 2, data);
@@ -1594,7 +1594,7 @@ UINT16 m68000_base_device::readword_d32_hmmu(offs_t address)
address = hmmu_translate_addr(this, address);
}
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
return m_space->read_word(address);
result = m_space->read_byte(address) << 8;
return result | m_space->read_byte(address + 1);
@@ -1608,7 +1608,7 @@ void m68000_base_device::writeword_d32_hmmu(offs_t address, UINT16 data)
address = hmmu_translate_addr(this, address);
}
- if (!(address & 1))
+ if (WORD_ALIGNED(address))
{
m_space->write_word(address, data);
return;
@@ -1627,9 +1627,9 @@ UINT32 m68000_base_device::readlong_d32_hmmu(offs_t address)
address = hmmu_translate_addr(this, address);
}
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
return m_space->read_dword(address);
- else if (!(address & 1))
+ else if (WORD_ALIGNED(address))
{
result = m_space->read_word(address) << 16;
return result | m_space->read_word(address + 2);
@@ -1647,12 +1647,12 @@ void m68000_base_device::writelong_d32_hmmu(offs_t address, UINT32 data)
address = hmmu_translate_addr(this, address);
}
- if (!(address & 3))
+ if (DWORD_ALIGNED(address))
{
m_space->write_dword(address, data);
return;
}
- else if (!(address & 1))
+ else if (WORD_ALIGNED(address))
{
m_space->write_word(address, data >> 16);
m_space->write_word(address + 2, data);
diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h
index 5cec889e002..7860298988f 100644
--- a/src/devices/cpu/m68000/m68kcpu.h
+++ b/src/devices/cpu/m68000/m68kcpu.h
@@ -626,7 +626,7 @@ static inline unsigned int m68k_read_pcrelative_8(m68000_base_device *m68k, unsi
static inline unsigned int m68k_read_pcrelative_16(m68000_base_device *m68k, unsigned int address)
{
- if(address & 1)
+ if (!WORD_ALIGNED(address))
return
(m68k->readimm16(address-1) << 8) |
(m68k->readimm16(address+1) >> 8);
@@ -638,7 +638,7 @@ static inline unsigned int m68k_read_pcrelative_16(m68000_base_device *m68k, uns
static inline unsigned int m68k_read_pcrelative_32(m68000_base_device *m68k, unsigned int address)
{
- if(address & 1)
+ if (!WORD_ALIGNED(address))
return
(m68k->readimm16(address-1) << 24) |
(m68k->readimm16(address+1) << 8) |
diff --git a/src/devices/cpu/m68000/m68kmake.cpp b/src/devices/cpu/m68000/m68kmake.cpp
index f36797d76ba..941ae23f0aa 100644
--- a/src/devices/cpu/m68000/m68kmake.cpp
+++ b/src/devices/cpu/m68000/m68kmake.cpp
@@ -670,7 +670,7 @@ static opcode_struct* find_opcode(char* name, int size, char* spec_proc, char* s
opcode_struct* op;
- for(op = g_opcode_input_table;op->name != nullptr;op++)
+ for(op = g_opcode_input_table;op->name[0] != 0;op++)
{
if( strcmp(name, op->name) == 0 &&
(size == op->size) &&
diff --git a/src/devices/cpu/m68000/m68kops.cpp b/src/devices/cpu/m68000/m68kops.cpp
index 0505f863c73..4cbeb42d78c 100644
--- a/src/devices/cpu/m68000/m68kops.cpp
+++ b/src/devices/cpu/m68000/m68kops.cpp
@@ -34872,3 +34872,5 @@ void m68ki_build_opcode_table(void)
/* ======================================================================== */
/* ============================== END OF FILE ============================= */
/* ======================================================================== */
+
+
diff --git a/src/devices/cpu/m68000/makefile b/src/devices/cpu/m68000/makefile
index 12b29fa267a..be25a067a78 100644
--- a/src/devices/cpu/m68000/makefile
+++ b/src/devices/cpu/m68000/makefile
@@ -8,24 +8,30 @@ ifeq ($(OS),os2)
EXE := .exe
endif
+ifndef verbose
+ SILENT = @
+endif
+CC = gcc
+CXX = g++
+
.PHONY: all clean
-all : m68kmake$(EXE) m68kops.c clean
+all : m68kmake$(EXE) m68kops.cpp
clean:
@echo Cleaning...
-@rm -f m68kmake$(EXE)
-@rm -f m68kmake.o
+ -@rm -f m68kops.*
-m68kmake.o: m68kmake.c
- @echo $(notdir $<)
- @gcc -x c++ -std=gnu++98 -o "$@" -c "$<"
+m68kmake.o: m68kmake.cpp
+ $(SILENT) $(CC) -x c++ -std=c++11 -o "$@" -c "$<"
m68kmake$(EXE) : m68kmake.o
@echo Linking $@...
- @g++ -lstdc++ $^ -o $@
+ $(SILENT) $(CXX) -lstdc++ $^ -o $@
-m68kops.c: m68kmake$(EXE) m68k_in.c
+m68kops.cpp: m68kmake$(EXE) m68k_in.cpp
@echo Generating M68K source files...
- @m68kmake$(EXE) . m68k_in.c
+ $(SILENT) ./m68kmake$(EXE) . m68k_in.cpp
diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp
index f4747b7304c..711b9c3edf4 100644
--- a/src/devices/cpu/mips/mips3.cpp
+++ b/src/devices/cpu/mips/mips3.cpp
@@ -120,8 +120,10 @@ const device_type RM7000BE = &device_creator<rm7000be_device>;
const device_type RM7000LE = &device_creator<rm7000le_device>;
+// VR4300 and VR5432 have 4 fewer PFN bits, and only 32 TLB entries
mips3_device::mips3_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, mips3_flavor flavor, endianness_t endianness)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
+ , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
, m_program_config("program", endianness, 32, 32, 0, 32, MIPS3_MIN_PAGE_SHIFT)
, m_flavor(flavor)
, m_core(nullptr)
@@ -134,7 +136,6 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons
, m_ll_value(0)
, m_lld_value(0)
, m_badcop_value(0)
- , m_tlb_table(nullptr)
, m_lwl(endianness == ENDIANNESS_BIG ? &mips3_device::lwl_be : &mips3_device::lwl_le)
, m_lwr(endianness == ENDIANNESS_BIG ? &mips3_device::lwr_be : &mips3_device::lwr_le)
, m_swl(endianness == ENDIANNESS_BIG ? &mips3_device::swl_be : &mips3_device::swl_le)
@@ -144,14 +145,13 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons
, m_sdl(endianness == ENDIANNESS_BIG ? &mips3_device::sdl_be : &mips3_device::sdl_le)
, m_sdr(endianness == ENDIANNESS_BIG ? &mips3_device::sdr_be : &mips3_device::sdr_le)
, c_system_clock(0)
- , m_pfnmask(0)
- , m_tlbentries(0)
+ , m_pfnmask(flavor == MIPS3_TYPE_VR4300 ? 0x000fffff : 0x00ffffff)
+ , m_tlbentries(flavor == MIPS3_TYPE_VR4300 ? 32 : MIPS3_MAX_TLB_ENTRIES)
, m_bigendian(endianness == ENDIANNESS_BIG)
, m_byte_xor(m_bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0))
, m_word_xor(m_bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0))
, c_icache_size(0)
, c_dcache_size(0)
- , m_vtlb(nullptr)
, m_fastram_select(0)
, m_debugger_temp(0)
, m_cache(CACHE_SIZE + sizeof(internal_mips3_state))
@@ -190,17 +190,14 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons
}
memset(m_fastram, 0, sizeof(m_fastram));
memset(m_hotspot, 0, sizeof(m_hotspot));
+
+ // configure the virtual TLB
+ set_vtlb_fixed_entries(2 * m_tlbentries + 2);
}
void mips3_device::device_stop()
{
- if (m_vtlb != nullptr)
- {
- vtlb_free(m_vtlb);
- m_vtlb = nullptr;
- }
-
if (m_drcfe != nullptr)
{
m_drcfe = nullptr;
@@ -331,28 +328,12 @@ void mips3_device::device_start()
m_program = &space(AS_PROGRAM);
m_direct = &m_program->direct();
- /* configure flavor-specific parameters */
- m_pfnmask = 0x00ffffff;
- m_tlbentries = MIPS3_MAX_TLB_ENTRIES;
-
- /* VR4300 and VR5432 have 4 fewer PFN bits, and only 32 TLB entries */
- if (m_flavor == MIPS3_TYPE_VR4300)
- {
- m_pfnmask = 0x000fffff;
- m_tlbentries = 32;
- }
-
/* set up the endianness */
m_program->accessors(m_memory);
- /* allocate the virtual TLB */
- m_vtlb = vtlb_alloc(this, AS_PROGRAM, 2 * m_tlbentries + 2, 0);
-
/* allocate a timer for the compare interrupt */
m_compare_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mips3_device::compare_int_callback), this));
- m_tlb_table = vtlb_table(m_vtlb);
-
UINT32 flags = 0;
/* initialize the UML generator */
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, flags, 8, 32, 2);
@@ -950,13 +931,13 @@ void mips3_device::device_reset()
entry->entry_hi = 0xffffffff;
entry->entry_lo[0] = 0xfffffff8;
entry->entry_lo[1] = 0xfffffff8;
- vtlb_load(m_vtlb, 2 * tlbindex + 0, 0, 0, 0);
- vtlb_load(m_vtlb, 2 * tlbindex + 1, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 0, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 1, 0, 0, 0);
}
/* load the fixed TLB range */
- vtlb_load(m_vtlb, 2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
- vtlb_load(m_vtlb, 2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
+ vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
+ vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID);
m_core->mode = (MODE_KERNEL << 1) | 0;
m_cache_dirty = TRUE;
@@ -969,7 +950,7 @@ bool mips3_device::memory_translate(address_spacenum spacenum, int intention, of
/* only applies to the program address space */
if (spacenum == AS_PROGRAM)
{
- const vtlb_entry *table = vtlb_table(m_vtlb);
+ const vtlb_entry *table = vtlb_table();
vtlb_entry entry = table[address >> MIPS3_MIN_PAGE_SHIFT];
if ((entry & (1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK)))) == 0)
return false;
@@ -998,7 +979,7 @@ offs_t mips3_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *op
inline bool mips3_device::RBYTE(offs_t address, UINT32 *result)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1031,7 +1012,7 @@ inline bool mips3_device::RBYTE(offs_t address, UINT32 *result)
inline bool mips3_device::RHALF(offs_t address, UINT32 *result)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1064,7 +1045,7 @@ inline bool mips3_device::RHALF(offs_t address, UINT32 *result)
inline bool mips3_device::RWORD(offs_t address, UINT32 *result)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1097,7 +1078,7 @@ inline bool mips3_device::RWORD(offs_t address, UINT32 *result)
inline bool mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 mem_mask)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
*result = (*m_memory.read_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
@@ -1120,7 +1101,7 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, UINT32 *result, UINT32 me
inline bool mips3_device::RDOUBLE(offs_t address, UINT64 *result)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
*result = (*m_memory.read_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff));
@@ -1143,7 +1124,7 @@ inline bool mips3_device::RDOUBLE(offs_t address, UINT64 *result)
inline bool mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64 mem_mask)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_READ_ALLOWED)
{
*result = (*m_memory.read_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), mem_mask);
@@ -1166,7 +1147,7 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, UINT64 *result, UINT64
inline void mips3_device::WBYTE(offs_t address, UINT8 data)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1200,7 +1181,7 @@ inline void mips3_device::WBYTE(offs_t address, UINT8 data)
inline void mips3_device::WHALF(offs_t address, UINT16 data)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1234,7 +1215,7 @@ inline void mips3_device::WHALF(offs_t address, UINT16 data)
inline void mips3_device::WWORD(offs_t address, UINT32 data)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
const UINT32 tlbaddress = (tlbval & ~0xfff) | (address & 0xfff);
@@ -1268,7 +1249,7 @@ inline void mips3_device::WWORD(offs_t address, UINT32 data)
inline void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_mask)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
(*m_memory.write_dword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
@@ -1292,7 +1273,7 @@ inline void mips3_device::WWORD_MASKED(offs_t address, UINT32 data, UINT32 mem_m
inline void mips3_device::WDOUBLE(offs_t address, UINT64 data)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
(*m_memory.write_qword)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data);
@@ -1316,7 +1297,7 @@ inline void mips3_device::WDOUBLE(offs_t address, UINT64 data)
inline void mips3_device::WDOUBLE_MASKED(offs_t address, UINT64 data, UINT64 mem_mask)
{
- const UINT32 tlbval = m_tlb_table[address >> 12];
+ const UINT32 tlbval = vtlb_table()[address >> 12];
if (tlbval & VTLB_WRITE_ALLOWED)
{
(*m_memory.write_qword_masked)(*m_program, (tlbval & ~0xfff) | (address & 0xfff), data, mem_mask);
diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h
index 9e0de9ed419..1715861bb89 100644
--- a/src/devices/cpu/mips/mips3.h
+++ b/src/devices/cpu/mips/mips3.h
@@ -15,7 +15,7 @@
#define __MIPS3_H__
-#include "cpu/vtlb.h"
+#include "divtlb.h"
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
@@ -245,7 +245,7 @@ struct compiler_state
class mips3_frontend;
-class mips3_device : public cpu_device
+class mips3_device : public cpu_device, public device_vtlb_interface
{
friend class mips3_frontend;
@@ -355,7 +355,6 @@ private:
UINT32 m_ll_value;
UINT64 m_lld_value;
UINT32 m_badcop_value;
- const vtlb_entry *m_tlb_table;
/* endian-dependent load/store */
typedef void (mips3_device::*loadstore_func)(UINT32 op);
@@ -389,7 +388,6 @@ private:
size_t c_dcache_size;
/* MMU */
- vtlb_state * m_vtlb;
mips3_tlb_entry m_tlb[MIPS3_MAX_TLB_ENTRIES];
/* fast RAM */
diff --git a/src/devices/cpu/mips/mips3com.cpp b/src/devices/cpu/mips/mips3com.cpp
index bcd6f6f349a..2fcf8de1844 100644
--- a/src/devices/cpu/mips/mips3com.cpp
+++ b/src/devices/cpu/mips/mips3com.cpp
@@ -325,8 +325,8 @@ void mips3_device::tlb_map_entry(int tlbindex)
/* the ASID doesn't match the current ASID, and if the page isn't global, unmap it from the TLB */
if (!tlb_entry_matches_asid(entry, current_asid) && !tlb_entry_is_global(entry))
{
- vtlb_load(m_vtlb, 2 * tlbindex + 0, 0, 0, 0);
- vtlb_load(m_vtlb, 2 * tlbindex + 1, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 0, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 1, 0, 0, 0);
return;
}
@@ -334,8 +334,8 @@ void mips3_device::tlb_map_entry(int tlbindex)
vpn = ((entry->entry_hi >> 13) & 0x07ffffff) << 1;
if (vpn >= (1 << (MIPS3_MAX_PADDR_SHIFT - MIPS3_MIN_PAGE_SHIFT)))
{
- vtlb_load(m_vtlb, 2 * tlbindex + 0, 0, 0, 0);
- vtlb_load(m_vtlb, 2 * tlbindex + 1, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 0, 0, 0, 0);
+ vtlb_load(2 * tlbindex + 1, 0, 0, 0);
return;
}
@@ -369,9 +369,9 @@ void mips3_device::tlb_map_entry(int tlbindex)
/* load the virtual TLB with the corresponding entries */
if ((effvpn + count) <= (0x80000000 >> MIPS3_MIN_PAGE_SHIFT) || effvpn >= (0xc0000000 >> MIPS3_MIN_PAGE_SHIFT))
- vtlb_load(m_vtlb, 2 * tlbindex + which, count, effvpn << MIPS3_MIN_PAGE_SHIFT, (pfn << MIPS3_MIN_PAGE_SHIFT) | flags);
+ vtlb_load(2 * tlbindex + which, count, effvpn << MIPS3_MIN_PAGE_SHIFT, (pfn << MIPS3_MIN_PAGE_SHIFT) | flags);
else
- vtlb_load(m_vtlb, 2 * tlbindex + which, 0, 0, 0);
+ vtlb_load(2 * tlbindex + which, 0, 0, 0);
}
}
diff --git a/src/devices/cpu/mips/mips3com.h b/src/devices/cpu/mips/mips3com.h
index 86d7f0c7a05..20facae78d0 100644
--- a/src/devices/cpu/mips/mips3com.h
+++ b/src/devices/cpu/mips/mips3com.h
@@ -14,7 +14,6 @@
#define __MIPS3COM_H__
#include "mips3.h"
-#include "cpu/vtlb.h"
/***************************************************************************
diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp
index 4e6e9771a38..7b6da3a1626 100644
--- a/src/devices/cpu/mips/mips3drc.cpp
+++ b/src/devices/cpu/mips/mips3drc.cpp
@@ -667,7 +667,7 @@ void mips3_device::static_generate_tlb_mismatch()
UML_RECOVER(block, I0, MAPVAR_PC); // recover i0,PC
UML_MOV(block, mem(&m_core->pc), I0); // mov <pc>,i0
UML_SHR(block, I1, I0, 12); // shr i1,i0,12
- UML_LOAD(block, I1, (void *)vtlb_table(m_vtlb), I1, SIZE_DWORD, SCALE_x4);// load i1,[vtlb_table],i1,dword
+ UML_LOAD(block, I1, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4);// load i1,[vtlb_table],i1,dword
if (PRINTF_MMU)
{
static const char text[] = "TLB mismatch @ %08X (ent=%08X)\n";
@@ -839,7 +839,7 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri
/* general case: assume paging and perform a translation */
UML_SHR(block, I3, I0, 12); // shr i3,i0,12
- UML_LOAD(block, I3, (void *)vtlb_table(m_vtlb), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword
+ UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword
UML_TEST(block, I3, iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED);// test i3,iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED
UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z
UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000
@@ -1226,7 +1226,7 @@ void mips3_device::generate_sequence_instruction(drcuml_block *block, compiler_s
/* validate our TLB entry at this PC; if we fail, we need to handle it */
if ((desc->flags & OPFLAG_VALIDATE_TLB) && (desc->pc < 0x80000000 || desc->pc >= 0xc0000000))
{
- const vtlb_entry *tlbtable = vtlb_table(m_vtlb);
+ const vtlb_entry *tlbtable = vtlb_table();
/* if we currently have a valid TLB read entry, we just verify */
if (tlbtable[desc->pc >> 12] & VTLB_FETCH_ALLOWED)
diff --git a/src/devices/cpu/pdp1/pdp1.cpp b/src/devices/cpu/pdp1/pdp1.cpp
index cbb43535d7f..d7a9ad008fb 100644
--- a/src/devices/cpu/pdp1/pdp1.cpp
+++ b/src/devices/cpu/pdp1/pdp1.cpp
@@ -384,7 +384,7 @@ pdp1_device::pdp1_device(const machine_config &mconfig, const char *tag, device_
: cpu_device(mconfig, PDP1, "PDP1", tag, owner, clock, "pdp1_cpu", __FILE__)
, m_program_config("program", ENDIANNESS_BIG, 32, 18, 0)
{
- m_is_octal = true;
+ m_program_config.m_is_octal = true;
}
diff --git a/src/devices/cpu/pdp1/tx0.cpp b/src/devices/cpu/pdp1/tx0.cpp
index 3a4fd7f1fb1..8e5b41776a0 100644
--- a/src/devices/cpu/pdp1/tx0.cpp
+++ b/src/devices/cpu/pdp1/tx0.cpp
@@ -61,7 +61,7 @@ tx0_device::tx0_device(const machine_config &mconfig, device_type type, const ch
, m_sel_handler(*this)
, m_io_reset_callback(*this)
{
- m_is_octal = true;
+ m_program_config.m_is_octal = true;
}
tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h
index 5e40ee88249..450b4ca2257 100644
--- a/src/devices/cpu/powerpc/ppc.h
+++ b/src/devices/cpu/powerpc/ppc.h
@@ -14,7 +14,7 @@
#ifndef __PPC_H__
#define __PPC_H__
-#include "cpu/vtlb.h"
+#include "divtlb.h"
#include "cpu/drcfe.h"
#include "cpu/drcuml.h"
#include "cpu/drcumlsh.h"
@@ -171,7 +171,7 @@ enum
class ppc_frontend;
-class ppc_device : public cpu_device
+class ppc_device : public cpu_device, public device_vtlb_interface
{
friend class ppc_frontend;
@@ -462,9 +462,6 @@ protected:
UINT32 m_sebr;
UINT32 m_ser;
- /* MMU */
- vtlb_state *m_vtlb;
-
/* architectural distinctions */
powerpc_flavor m_flavor;
UINT32 m_cap;
diff --git a/src/devices/cpu/powerpc/ppccom.cpp b/src/devices/cpu/powerpc/ppccom.cpp
index 9036ff2c794..a9a26b29a5c 100644
--- a/src/devices/cpu/powerpc/ppccom.cpp
+++ b/src/devices/cpu/powerpc/ppccom.cpp
@@ -209,11 +209,11 @@ const device_type PPC405GP = &device_creator<ppc405gp_device>;
ppc_device::ppc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, int address_bits, int data_bits, powerpc_flavor flavor, UINT32 cap, UINT32 tb_divisor, address_map_constructor internal_map)
: cpu_device(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
+ , device_vtlb_interface(mconfig, *this, AS_PROGRAM)
, m_program_config("program", ENDIANNESS_BIG, data_bits, address_bits, 0, internal_map)
, c_bus_frequency(0)
, m_core(nullptr)
, m_bus_freq_multiplier(1)
- , m_vtlb(nullptr)
, m_flavor(flavor)
, m_cap(cap)
, m_tb_divisor(tb_divisor)
@@ -224,6 +224,11 @@ ppc_device::ppc_device(const machine_config &mconfig, device_type type, const ch
{
m_program_config.m_logaddr_width = 32;
m_program_config.m_page_shift = POWERPC_MIN_PAGE_SHIFT;
+
+ // configure the virtual TLB
+ set_vtlb_dynamic_entries(POWERPC_TLB_ENTRIES);
+ if (m_cap & PPCCAP_603_MMU)
+ set_vtlb_fixed_entries(PPC603_FIXED_TLB_ENTRIES);
}
//ppc403_device::ppc403_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
@@ -708,9 +713,6 @@ void ppc_device::device_start()
if (!(m_cap & PPCCAP_4XX) && space_config()->m_endianness != ENDIANNESS_NATIVE)
m_codexor = 4;
- /* allocate the virtual TLB */
- m_vtlb = vtlb_alloc(this, AS_PROGRAM, (m_cap & PPCCAP_603_MMU) ? PPC603_FIXED_TLB_ENTRIES : 0, POWERPC_TLB_ENTRIES);
-
/* allocate a timer for the compare interrupt */
if ((m_cap & PPCCAP_OEA) && (m_tb_divisor))
m_decrementer_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(ppc_device::decrementer_int_callback), this));
@@ -1148,9 +1150,6 @@ void ppc_device::state_string_export(const device_state_entry &entry, std::strin
void ppc_device::device_stop()
{
- if (m_vtlb != nullptr)
- vtlb_free(m_vtlb);
- m_vtlb = nullptr;
}
@@ -1199,12 +1198,11 @@ void ppc_device::device_reset()
m_core->irq_pending = 0;
/* flush the TLB */
- vtlb_flush_dynamic(m_vtlb);
if (m_cap & PPCCAP_603_MMU)
{
for (int tlbindex = 0; tlbindex < PPC603_FIXED_TLB_ENTRIES; tlbindex++)
{
- vtlb_load(m_vtlb, tlbindex, 0, 0, 0);
+ vtlb_load(tlbindex, 0, 0, 0);
}
}
@@ -1385,7 +1383,7 @@ UINT32 ppc_device::ppccom_translate_address_internal(int intention, offs_t &addr
/* if we're simulating the 603 MMU, fill in the data and stop here */
if (m_cap & PPCCAP_603_MMU)
{
- UINT32 entry = vtlb_table(m_vtlb)[address >> 12];
+ UINT32 entry = vtlb_table()[address >> 12];
m_core->mmu603_cmp = 0x80000000 | ((segreg & 0xffffff) << 7) | (0 << 6) | ((address >> 22) & 0x3f);
m_core->mmu603_hash[0] = hashbase | ((hash << 6) & hashmask);
m_core->mmu603_hash[1] = hashbase | ((~hash << 6) & hashmask);
@@ -1465,7 +1463,7 @@ bool ppc_device::memory_translate(address_spacenum spacenum, int intention, offs
void ppc_device::ppccom_tlb_fill()
{
- vtlb_fill(m_vtlb, m_core->param0, m_core->param1);
+ vtlb_fill(m_core->param0, m_core->param1);
}
@@ -1476,7 +1474,7 @@ void ppc_device::ppccom_tlb_fill()
void ppc_device::ppccom_tlb_flush()
{
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
}
@@ -1492,7 +1490,7 @@ void ppc_device::ppccom_tlb_flush()
void ppc_device::ppccom_execute_tlbie()
{
- vtlb_flush_address(m_vtlb, m_core->param0);
+ vtlb_flush_address(m_core->param0);
}
@@ -1503,7 +1501,7 @@ void ppc_device::ppccom_execute_tlbie()
void ppc_device::ppccom_execute_tlbia()
{
- vtlb_flush_dynamic(m_vtlb);
+ vtlb_flush_dynamic();
}
@@ -1530,7 +1528,7 @@ void ppc_device::ppccom_execute_tlbl()
flags |= VTLB_FETCH_ALLOWED;
/* load the entry */
- vtlb_load(m_vtlb, entrynum, 1, address, (m_core->spr[SPR603_RPA] & 0xfffff000) | flags);
+ vtlb_load(entrynum, 1, address, (m_core->spr[SPR603_RPA] & 0xfffff000) | flags);
}
diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp
index ed502d344de..35b984d240d 100644
--- a/src/devices/cpu/powerpc/ppcdrc.cpp
+++ b/src/devices/cpu/powerpc/ppcdrc.cpp
@@ -743,11 +743,11 @@ void ppc_device::static_generate_tlb_mismatch()
UML_HANDLE(block, *m_tlb_mismatch); // handle tlb_mismatch
UML_RECOVER(block, I0, MAPVAR_PC); // recover i0,PC
UML_SHR(block, I1, I0, 12); // shr i1,i0,12
- UML_LOAD(block, I2, (void *)vtlb_table(m_vtlb), I1, SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword
+ UML_LOAD(block, I2, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword
UML_MOV(block, mem(&m_core->param0), I0); // mov [param0],i0
UML_MOV(block, mem(&m_core->param1), TRANSLATE_FETCH); // mov [param1],TRANSLATE_FETCH
UML_CALLC(block, (c_function)cfunc_ppccom_tlb_fill, this); // callc tlbfill,ppc
- UML_LOAD(block, I1, (void *)vtlb_table(m_vtlb), I1, SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword
+ UML_LOAD(block, I1, (void *)vtlb_table(), I1, SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword
UML_TEST(block, I1, VTLB_FETCH_ALLOWED); // test i1,VTLB_FETCH_ALLOWED
UML_JMPc(block, COND_Z, isi = label++); // jmp isi,z
UML_CMP(block, I2, 0); // cmp i2,0
@@ -1021,7 +1021,7 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite
if (((m_cap & PPCCAP_OEA) && (mode & MODE_DATA_TRANSLATION)) || (iswrite && (m_cap & PPCCAP_4XX) && (mode & MODE_PROTECTION)))
{
UML_SHR(block, I3, I0, 12); // shr i3,i0,12
- UML_LOAD(block, I3, (void *)vtlb_table(m_vtlb), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword
+ UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword
UML_TEST(block, I3, (UINT64)1 << translate_type); // test i3,1 << translate_type
UML_JMPc(block, COND_Z, tlbmiss = label++); // jmp tlbmiss,z
UML_LABEL(block, tlbreturn = label++); // tlbreturn:
@@ -1338,7 +1338,7 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite
UML_MOV(block, mem(&m_core->param1), translate_type); // mov [param1],translate_type
UML_CALLC(block, (c_function)cfunc_ppccom_tlb_fill, this); // callc tlbfill,ppc
UML_SHR(block, I3, I0, 12); // shr i3,i0,12
- UML_LOAD(block, I3, (void *)vtlb_table(m_vtlb), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword
+ UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword
UML_TEST(block, I3, (UINT64)1 << translate_type); // test i3,1 << translate_type
UML_JMPc(block, COND_NZ, tlbreturn); // jmp tlbreturn,nz
@@ -1703,7 +1703,7 @@ void ppc_device::generate_sequence_instruction(drcuml_block *block, compiler_sta
/* validate our TLB entry at this PC; if we fail, we need to handle it */
if ((desc->flags & OPFLAG_VALIDATE_TLB) && (m_core->mode & MODE_DATA_TRANSLATION))
{
- const vtlb_entry *tlbtable = vtlb_table(m_vtlb);
+ const vtlb_entry *tlbtable = vtlb_table();
/* if we currently have a valid TLB read entry, we just verify */
if (tlbtable[desc->pc >> 12] != 0)
diff --git a/src/devices/cpu/se3208/se3208.cpp b/src/devices/cpu/se3208/se3208.cpp
index 011cc103909..45c4c38cc86 100644
--- a/src/devices/cpu/se3208/se3208.cpp
+++ b/src/devices/cpu/se3208/se3208.cpp
@@ -54,27 +54,22 @@ se3208_device::se3208_device(const machine_config &mconfig, const char *tag, dev
UINT32 se3208_device::read_dword_unaligned(address_space &space, UINT32 address)
{
- switch (address & 3)
- {
- case 0:
+ if (DWORD_ALIGNED(address))
return space.read_dword(address);
- case 1:
- case 2:
- case 3:
- printf("%08x: dword READ unaligned %08x\n", m_PC, address);
+ else
+ {
+ osd_printf_debug("%08x: dword READ unaligned %08x\n", m_PC, address);
#if ALLOW_UNALIGNED_DWORD_ACCESS
return space.read_byte(address) | space.read_byte(address + 1) << 8 | space.read_byte(address + 2) << 16 | space.read_byte(address + 3) << 24;
#else
return 0;
#endif
}
-
- return 0;
}
UINT16 se3208_device::read_word_unaligned(address_space &space, UINT32 address)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
return space.read_byte(address) | space.read_byte(address+1)<<8;
else
return space.read_word(address);
@@ -82,31 +77,24 @@ UINT16 se3208_device::read_word_unaligned(address_space &space, UINT32 address)
void se3208_device::write_dword_unaligned(address_space &space, UINT32 address, UINT32 data)
{
- switch (address & 3)
- {
- case 0:
+ if (DWORD_ALIGNED(address))
space.write_dword(address, data);
- break;
-
- case 1:
- case 2:
- case 3:
+ else
+ {
#if ALLOW_UNALIGNED_DWORD_ACCESS
space.write_byte(address, data & 0xff);
space.write_byte(address + 1, (data >> 8) & 0xff);
space.write_byte(address + 2, (data >> 16) & 0xff);
space.write_byte(address + 3, (data >> 24) & 0xff);
#endif
- printf("%08x: dword WRITE unaligned %08x\n", m_PC, address);
-
- break;
+ osd_printf_debug("%08x: dword WRITE unaligned %08x\n", m_PC, address);
}
}
void se3208_device::write_word_unaligned(address_space &space, UINT32 address, UINT16 data)
{
- if (address & 1)
+ if (!WORD_ALIGNED(address))
{
space.write_byte(address, data & 0xff);
space.write_byte(address+1, (data>>8)&0xff);
diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp
index 72c2e80c91b..5e32e2081f5 100644
--- a/src/devices/cpu/t11/t11.cpp
+++ b/src/devices/cpu/t11/t11.cpp
@@ -49,7 +49,7 @@ t11_device::t11_device(const machine_config &mconfig, device_type type, const ch
, m_program_config("program", ENDIANNESS_LITTLE, 16, 16, 0)
, c_initial_mode(0)
{
- m_is_octal = true;
+ m_program_config.m_is_octal = true;
memset(m_reg, 0x00, sizeof(m_reg));
memset(&m_psw, 0x00, sizeof(m_psw));
}
@@ -59,7 +59,7 @@ t11_device::t11_device(const machine_config &mconfig, const char *tag, device_t
, m_program_config("program", ENDIANNESS_LITTLE, 16, 16, 0)
, c_initial_mode(0)
{
- m_is_octal = true;
+ m_program_config.m_is_octal = true;
memset(m_reg, 0x00, sizeof(m_reg));
memset(&m_psw, 0x00, sizeof(m_psw));
}
diff --git a/src/devices/cpu/vtlb.cpp b/src/devices/cpu/vtlb.cpp
deleted file mode 100644
index 4c9a9a2f311..00000000000
--- a/src/devices/cpu/vtlb.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- vtlb.c
-
- Generic virtual TLB implementation.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "vtlb.h"
-
-
-
-/***************************************************************************
- DEBUGGING
-***************************************************************************/
-
-#define PRINTF_TLB (0)
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* VTLB state */
-struct vtlb_state
-{
- cpu_device * cpudevice; /* CPU device */
- address_spacenum space; /* address space */
- int dynamic; /* number of dynamic entries */
- int fixed; /* number of fixed entries */
- int dynindex; /* index of next dynamic entry */
- int pageshift; /* bits to shift to get page index */
- int addrwidth; /* logical address bus width */
- std::vector<offs_t> live; /* array of live entries by table index */
- std::vector<int> fixedpages; /* number of pages each fixed entry covers */
- std::vector<vtlb_entry> table; /* table of entries by address */
-};
-
-
-
-/***************************************************************************
- INITIALIZATION/TEARDOWN
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_alloc - allocate a new VTLB for the
- given CPU
--------------------------------------------------*/
-
-vtlb_state *vtlb_alloc(device_t *cpu, address_spacenum space, int fixed_entries, int dynamic_entries)
-{
- vtlb_state *vtlb;
-
- /* allocate memory for the core structure */
- vtlb = auto_alloc_clear(cpu->machine(), <vtlb_state>());
-
- /* fill in CPU information */
- vtlb->cpudevice = downcast<cpu_device *>(cpu);
- vtlb->space = space;
- vtlb->dynamic = dynamic_entries;
- vtlb->fixed = fixed_entries;
- const address_space_config *spaceconfig = device_get_space_config(*cpu, space);
- assert(spaceconfig != nullptr);
- vtlb->pageshift = spaceconfig->m_page_shift;
- vtlb->addrwidth = spaceconfig->m_logaddr_width;
-
- /* validate CPU information */
- assert((1 << vtlb->pageshift) > VTLB_FLAGS_MASK);
- assert(vtlb->addrwidth > vtlb->pageshift);
-
- /* allocate the entry array */
- vtlb->live.resize(fixed_entries + dynamic_entries);
- memset(&vtlb->live[0], 0, vtlb->live.size()*sizeof(vtlb->live[0]));
- cpu->save_item(NAME(vtlb->live));
-
- /* allocate the lookup table */
- vtlb->table.resize((size_t) 1 << (vtlb->addrwidth - vtlb->pageshift));
- memset(&vtlb->table[0], 0, vtlb->table.size()*sizeof(vtlb->table[0]));
- cpu->save_item(NAME(vtlb->table));
-
- /* allocate the fixed page count array */
- if (fixed_entries > 0)
- {
- vtlb->fixedpages.resize(fixed_entries);
- memset(&vtlb->fixedpages[0], 0, fixed_entries*sizeof(vtlb->fixedpages[0]));
- cpu->save_item(NAME(vtlb->fixedpages));
- }
- return vtlb;
-}
-
-
-/*-------------------------------------------------
- vtlb_free - free an allocated VTLB
--------------------------------------------------*/
-
-void vtlb_free(vtlb_state *vtlb)
-{
- auto_free(vtlb->cpudevice->machine(), vtlb);
-}
-
-
-
-/***************************************************************************
- FILLING
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_fill - rcalled by the CPU core in
- response to an unmapped access
--------------------------------------------------*/
-
-int vtlb_fill(vtlb_state *vtlb, offs_t address, int intention)
-{
- offs_t tableindex = address >> vtlb->pageshift;
- vtlb_entry entry = vtlb->table[tableindex];
- offs_t taddress;
-
- if (PRINTF_TLB)
- printf("vtlb_fill: %08X(%X) ... ", address, intention);
-
- /* should not be called here if the entry is in the table already */
-// assert((entry & (1 << intention)) == 0);
-
- /* if we have no dynamic entries, we always fail */
- if (vtlb->dynamic == 0)
- {
- if (PRINTF_TLB)
- printf("failed: no dynamic entries\n");
- return FALSE;
- }
-
- /* ask the CPU core to translate for us */
- taddress = address;
- if (!vtlb->cpudevice->translate(vtlb->space, intention, taddress))
- {
- if (PRINTF_TLB)
- printf("failed: no translation\n");
- return FALSE;
- }
-
- /* if this is the first successful translation for this address, allocate a new entry */
- if ((entry & VTLB_FLAGS_MASK) == 0)
- {
- int liveindex = vtlb->dynindex++ % vtlb->dynamic;
-
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- vtlb->table[vtlb->live[liveindex] - 1] = 0;
-
- /* claim this new entry */
- vtlb->live[liveindex] = tableindex + 1;
-
- /* form a new blank entry */
- entry = (taddress >> vtlb->pageshift) << vtlb->pageshift;
- entry |= VTLB_FLAG_VALID;
-
- if (PRINTF_TLB)
- printf("success (%08X), new entry\n", taddress);
- }
-
- /* otherwise, ensure that different intentions do not produce different addresses */
- else
- {
- assert((entry >> vtlb->pageshift) == (taddress >> vtlb->pageshift));
- assert(entry & VTLB_FLAG_VALID);
-
- if (PRINTF_TLB)
- printf("success (%08X), existing entry\n", taddress);
- }
-
- /* add the intention to the list of valid intentions and store */
- entry |= 1 << (intention & (TRANSLATE_TYPE_MASK | TRANSLATE_USER_MASK));
- vtlb->table[tableindex] = entry;
- return TRUE;
-}
-
-
-/*-------------------------------------------------
- vtlb_load - load a fixed VTLB entry
--------------------------------------------------*/
-
-void vtlb_load(vtlb_state *vtlb, int entrynum, int numpages, offs_t address, vtlb_entry value)
-{
- offs_t tableindex = address >> vtlb->pageshift;
- int liveindex = vtlb->dynamic + entrynum;
- int pagenum;
-
- /* must be in range */
- assert(entrynum >= 0 && entrynum < vtlb->fixed);
-
- if (PRINTF_TLB)
- printf("vtlb_load %d for %d pages at %08X == %08X\n", entrynum, numpages, address, value);
-
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- {
- int pagecount = vtlb->fixedpages[entrynum];
- int oldtableindex = vtlb->live[liveindex] - 1;
- for (pagenum = 0; pagenum < pagecount; pagenum++)
- vtlb->table[oldtableindex + pagenum] = 0;
- }
-
- /* claim this new entry */
- vtlb->live[liveindex] = tableindex + 1;
-
- /* store the raw value, making sure the "fixed" flag is set */
- value |= VTLB_FLAG_FIXED;
- vtlb->fixedpages[entrynum] = numpages;
- for (pagenum = 0; pagenum < numpages; pagenum++)
- vtlb->table[tableindex + pagenum] = value + (pagenum << vtlb->pageshift);
-}
-
-/*-------------------------------------------------
- vtlb_dynload - load a dynamic VTLB entry
--------------------------------------------------*/
-
-void vtlb_dynload(vtlb_state *vtlb, UINT32 index, offs_t address, vtlb_entry value)
-{
- vtlb_entry entry = vtlb->table[index];
-
- if (vtlb->dynamic == 0)
- {
- if (PRINTF_TLB)
- printf("failed: no dynamic entries\n");
- return;
- }
-
- int liveindex = vtlb->dynindex++ % vtlb->dynamic;
- /* is entry already live? */
- if (!(entry & VTLB_FLAG_VALID))
- {
- /* if an entry already exists at this index, free it */
- if (vtlb->live[liveindex] != 0)
- vtlb->table[vtlb->live[liveindex] - 1] = 0;
-
- /* claim this new entry */
- vtlb->live[liveindex] = index + 1;
- }
- /* form a new blank entry */
- entry = (address >> vtlb->pageshift) << vtlb->pageshift;
- entry |= VTLB_FLAG_VALID | value;
-
- if (PRINTF_TLB)
- printf("success (%08X), new entry\n", address);
-
- vtlb->table[index] = entry;
-}
-
-/***************************************************************************
- FLUSHING
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_flush_dynamic - flush all knowledge
- from the dynamic part of the VTLB
--------------------------------------------------*/
-
-void vtlb_flush_dynamic(vtlb_state *vtlb)
-{
- int liveindex;
-
- if (PRINTF_TLB)
- printf("vtlb_flush_dynamic\n");
-
- /* loop over live entries and release them from the table */
- for (liveindex = 0; liveindex < vtlb->dynamic; liveindex++)
- if (vtlb->live[liveindex] != 0)
- {
- offs_t tableindex = vtlb->live[liveindex] - 1;
- vtlb->table[tableindex] = 0;
- vtlb->live[liveindex] = 0;
- }
-}
-
-
-/*-------------------------------------------------
- vtlb_flush_address - flush knowledge of a
- particular address from the VTLB
--------------------------------------------------*/
-
-void vtlb_flush_address(vtlb_state *vtlb, offs_t address)
-{
- offs_t tableindex = address >> vtlb->pageshift;
-
- if (PRINTF_TLB)
- printf("vtlb_flush_address %08X\n", address);
-
- /* free the entry in the table; for speed, we leave the entry in the live array */
- vtlb->table[tableindex] = 0;
-}
-
-
-
-/***************************************************************************
- ACCESSORS
-***************************************************************************/
-
-/*-------------------------------------------------
- vtlb_table - return a pointer to the base of
- the linear VTLB lookup table
--------------------------------------------------*/
-
-const vtlb_entry *vtlb_table(vtlb_state *vtlb)
-{
- return &vtlb->table[0];
-}
diff --git a/src/devices/cpu/vtlb.h b/src/devices/cpu/vtlb.h
deleted file mode 100644
index f63a0ac50f6..00000000000
--- a/src/devices/cpu/vtlb.h
+++ /dev/null
@@ -1,88 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- vtlb.h
-
- Generic virtual TLB implementation.
-
-***************************************************************************/
-
-#pragma once
-
-#ifndef __VTLB_H__
-#define __VTLB_H__
-
-
-
-/***************************************************************************
- CONSTANTS
-***************************************************************************/
-
-#define VTLB_FLAGS_MASK 0xff
-
-#define VTLB_READ_ALLOWED 0x01 /* (1 << TRANSLATE_READ) */
-#define VTLB_WRITE_ALLOWED 0x02 /* (1 << TRANSLATE_WRITE) */
-#define VTLB_FETCH_ALLOWED 0x04 /* (1 << TRANSLATE_FETCH) */
-#define VTLB_FLAG_VALID 0x08
-#define VTLB_USER_READ_ALLOWED 0x10 /* (1 << TRANSLATE_READ_USER) */
-#define VTLB_USER_WRITE_ALLOWED 0x20 /* (1 << TRANSLATE_WRITE_USER) */
-#define VTLB_USER_FETCH_ALLOWED 0x40 /* (1 << TRANSLATE_FETCH_USER) */
-#define VTLB_FLAG_FIXED 0x80
-
-
-
-/***************************************************************************
- TYPE DEFINITIONS
-***************************************************************************/
-
-/* represents an entry in the VTLB */
-typedef UINT32 vtlb_entry;
-
-
-/* opaque structure describing VTLB state */
-struct vtlb_state;
-
-
-
-/***************************************************************************
- FUNCTION PROTOTYPES
-***************************************************************************/
-
-
-/* ----- initialization/teardown ----- */
-
-/* allocate a new VTLB for the given CPU */
-vtlb_state *vtlb_alloc(device_t *cpu, address_spacenum space, int fixed_entries, int dynamic_entries);
-
-/* free an allocated VTLB */
-void vtlb_free(vtlb_state *vtlb);
-
-
-/* ----- filling ----- */
-
-/* called by the CPU core in response to an unmapped access */
-int vtlb_fill(vtlb_state *vtlb, offs_t address, int intention);
-
-/* load a fixed VTLB entry */
-void vtlb_load(vtlb_state *vtlb, int entrynum, int numpages, offs_t address, vtlb_entry value);
-
-/* load a dynamic VTLB entry */
-void vtlb_dynload(vtlb_state *vtlb, UINT32 index, offs_t address, vtlb_entry value);
-
-/* ----- flushing ----- */
-
-/* flush all knowledge from the dynamic part of the VTLB */
-void vtlb_flush_dynamic(vtlb_state *vtlb);
-
-/* flush knowledge of a particular address from the VTLB */
-void vtlb_flush_address(vtlb_state *vtlb, offs_t address);
-
-
-/* ----- accessors ----- */
-
-/* return a pointer to the base of the linear VTLB lookup table */
-const vtlb_entry *vtlb_table(vtlb_state *vtlb);
-
-
-#endif /* __VTLB_H__ */
diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp
index 345ea4334bf..e798a1153b2 100644
--- a/src/devices/cpu/z80/z80.cpp
+++ b/src/devices/cpu/z80/z80.cpp
@@ -10,6 +10,7 @@
* - If LD A,I or LD A,R is interrupted, P/V flag gets reset, even if IFF2
* was set before this instruction (implemented, but not enabled: we need
* document Z80 types first, see below)
+ * - WAIT only stalls between instructions now, it should stall immediately.
* - Ideally, the tiny differences between Z80 types should be supported,
* currently known differences:
* - LD A,I/R P/V flag reset glitch is fixed on CMOS Z80
@@ -3124,6 +3125,27 @@ OP(op,fe) { cp(arg());
OP(op,ff) { rst(0x38); } /* RST 7 */
+void z80_device::take_nmi()
+{
+ /* there isn't a valid previous program counter */
+ PRVPC = -1;
+
+ /* Check if processor was halted */
+ leave_halt();
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
+
+ m_iff1 = 0;
+ push(m_pc);
+ PCD = 0x0066;
+ WZ=PCD;
+ m_icount -= 11;
+ m_nmi_pending = FALSE;
+}
+
void z80_device::take_interrupt()
{
int irq_vector;
@@ -3206,6 +3228,11 @@ void z80_device::take_interrupt()
m_icount -= m_cc_ex[0xff];
}
WZ=PCD;
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
}
void nsc800_device::take_interrupt_nsc800()
@@ -3239,6 +3266,11 @@ void nsc800_device::take_interrupt_nsc800()
m_icount -= m_cc_op[0xff] + cc_ex[0xff];
WZ=PCD;
+
+#if HAS_LDAIR_QUIRK
+ /* reset parity flag after LD A,I or LD A,R */
+ if (m_after_ldair) F &= ~PF;
+#endif
}
/****************************************************************************
@@ -3474,44 +3506,25 @@ void nsc800_device::device_reset()
}
/****************************************************************************
- * Execute 'cycles' T-states. Return number of T-states really executed
+ * Execute 'cycles' T-states.
****************************************************************************/
void z80_device::execute_run()
{
- /* check for NMIs on the way in; they can only be set externally */
- /* via timers, and can't be dynamically enabled, so it is safe */
- /* to just check here */
- if (m_nmi_pending)
- {
- LOG(("Z80 '%s' take NMI\n", tag()));
- PRVPC = -1; /* there isn't a valid previous program counter */
- leave_halt(); /* Check if processor was halted */
-
-#if HAS_LDAIR_QUIRK
- /* reset parity flag after LD A,I or LD A,R */
- if (m_after_ldair) F &= ~PF;
-#endif
- m_after_ldair = FALSE;
-
- m_iff1 = 0;
- push(m_pc);
- PCD = 0x0066;
- WZ=PCD;
- m_icount -= 11;
- m_nmi_pending = FALSE;
- }
-
do
{
- /* check for IRQs before each instruction */
- if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
+ if (m_wait_state)
{
-#if HAS_LDAIR_QUIRK
- /* reset parity flag after LD A,I or LD A,R */
- if (m_after_ldair) F &= ~PF;
-#endif
- take_interrupt();
+ // stalled
+ m_icount = 0;
+ return;
}
+
+ // check for interrupts before each instruction
+ if (m_nmi_pending)
+ take_nmi();
+ else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
+ take_interrupt();
+
m_after_ei = FALSE;
m_after_ldair = FALSE;
@@ -3524,34 +3537,25 @@ void z80_device::execute_run()
void nsc800_device::execute_run()
{
- /* check for NMIs on the way in; they can only be set externally */
- /* via timers, and can't be dynamically enabled, so it is safe */
- /* to just check here */
- if (m_nmi_pending)
- {
- LOG(("Z80 '%s' take NMI\n", tag()));
- PRVPC = -1; /* there isn't a valid previous program counter */
- leave_halt(); /* Check if processor was halted */
-
- m_iff1 = 0;
- push(m_pc);
- PCD = 0x0066;
- WZ=PCD;
- m_icount -= 11;
- m_nmi_pending = FALSE;
- }
-
do
{
- /* check for NSC800 IRQs line RSTA, RSTB, RSTC */
- if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei)
- take_interrupt_nsc800();
+ if (m_wait_state)
+ {
+ // stalled
+ m_icount = 0;
+ return;
+ }
- /* check for IRQs before each instruction */
- if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
+ // check for interrupts before each instruction
+ if (m_nmi_pending)
+ take_nmi();
+ else if ((m_nsc800_irq_state[NSC800_RSTA] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTB] != CLEAR_LINE || m_nsc800_irq_state[NSC800_RSTC] != CLEAR_LINE) && m_iff1 && !m_after_ei)
+ take_interrupt_nsc800();
+ else if (m_irq_state != CLEAR_LINE && m_iff1 && !m_after_ei)
take_interrupt();
m_after_ei = FALSE;
+ m_after_ldair = FALSE;
PRVPC = PCD;
debugger_instruction_hook(this, PCD);
@@ -3587,6 +3591,9 @@ void z80_device::execute_set_input(int inputnum, int state)
case Z80_INPUT_LINE_WAIT:
m_wait_state = state;
break;
+
+ default:
+ break;
}
}
@@ -3594,17 +3601,6 @@ void nsc800_device::execute_set_input(int inputnum, int state)
{
switch (inputnum)
{
- case Z80_INPUT_LINE_BUSRQ:
- m_busrq_state = state;
- break;
-
- case INPUT_LINE_NMI:
- /* mark an NMI pending on the rising edge */
- if (m_nmi_state == CLEAR_LINE && state != CLEAR_LINE)
- m_nmi_pending = TRUE;
- m_nmi_state = state;
- break;
-
case NSC800_RSTA:
m_nsc800_irq_state[NSC800_RSTA] = state;
break;
@@ -3617,17 +3613,8 @@ void nsc800_device::execute_set_input(int inputnum, int state)
m_nsc800_irq_state[NSC800_RSTC] = state;
break;
- case INPUT_LINE_IRQ0:
- /* update the IRQ state via the daisy chain */
- m_irq_state = state;
- if (m_daisy.present())
- m_irq_state = m_daisy.update_irq_state();
-
- /* the main execute loop will take the interrupt */
- break;
-
- case Z80_INPUT_LINE_WAIT:
- m_wait_state = state;
+ default:
+ z80_device::execute_set_input(inputnum, state);
break;
}
}
@@ -3750,10 +3737,3 @@ nsc800_device::nsc800_device(const machine_config &mconfig, const char *tag, dev
}
const device_type NSC800 = &device_creator<nsc800_device>;
-
-
-
-WRITE_LINE_MEMBER( z80_device::irq_line )
-{
- set_input_line( INPUT_LINE_IRQ0, state );
-}
diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h
index c523f101a24..38cc207347e 100644
--- a/src/devices/cpu/z80/z80.h
+++ b/src/devices/cpu/z80/z80.h
@@ -19,6 +19,7 @@ enum
NSC800_RSTB,
NSC800_RSTC,
Z80_INPUT_LINE_WAIT,
+ Z80_INPUT_LINE_BOGUSWAIT, /* WAIT pin implementation used to be nonexistent, please remove this when all drivers are updated with Z80_INPUT_LINE_WAIT */
Z80_INPUT_LINE_BUSRQ
};
@@ -41,8 +42,6 @@ class z80_device : public cpu_device
public:
z80_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
- DECLARE_WRITE_LINE_MEMBER( irq_line );
-
void z80_set_cycle_tables(const UINT8 *op, const UINT8 *cb, const UINT8 *ed, const UINT8 *xy, const UINT8 *xycb, const UINT8 *ex);
template<class _Object> static devcb_base &set_irqack_cb(device_t &device, _Object object) { return downcast<z80_device &>(device).m_irqack_cb.set_callback(object); }
template<class _Object> static devcb_base &set_refresh_cb(device_t &device, _Object object) { return downcast<z80_device &>(device).m_refresh_cb.set_callback(object); }
@@ -238,6 +237,7 @@ protected:
void ei();
void take_interrupt();
+ void take_nmi();
// address spaces
const address_space_config m_program_config;