diff options
Diffstat (limited to 'src/devices/cpu')
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; |