diff options
author | hap <happppp@users.noreply.github.com> | 2017-11-14 20:58:54 +0100 |
---|---|---|
committer | hap <happppp@users.noreply.github.com> | 2017-11-14 20:58:54 +0100 |
commit | 56e8f3bd0a001e44dd2935a34b666056b1312241 (patch) | |
tree | 721dcdf71747213b7edd396c6838a2012e909a65 | |
parent | b2d10f7b4172e976be61ec21cbdd1d031bd10958 (diff) |
i8085: finished with cleanups (nw)
-rw-r--r-- | src/devices/cpu/i8085/i8085.cpp | 700 |
1 files changed, 345 insertions, 355 deletions
diff --git a/src/devices/cpu/i8085/i8085.cpp b/src/devices/cpu/i8085/i8085.cpp index bbcb195b2fa..13be55d6a26 100644 --- a/src/devices/cpu/i8085/i8085.cpp +++ b/src/devices/cpu/i8085/i8085.cpp @@ -142,7 +142,6 @@ constexpr u16 ADDR_RST65 = 0x0034; constexpr u16 ADDR_RST75 = 0x003c; - /*************************************************************************** STATIC TABLES ***************************************************************************/ @@ -254,6 +253,351 @@ void i8085a_cpu_device::device_clock_changed() /*************************************************************************** + CORE INITIALIZATION +***************************************************************************/ + +void i8085a_cpu_device::init_tables() +{ + u8 zs; + int i, p; + for (i = 0; i < 256; i++) + { + /* cycles */ + lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i]; + + /* flags */ + zs = 0; + if (i==0) zs |= ZF; + if (i&128) zs |= SF; + p = 0; + if (i&1) ++p; + if (i&2) ++p; + if (i&4) ++p; + if (i&8) ++p; + if (i&16) ++p; + if (i&32) ++p; + if (i&64) ++p; + if (i&128) ++p; + lut_zs[i] = zs; + lut_zsp[i] = zs | ((p&1) ? 0 : PF); + } +} + +void i8085a_cpu_device::device_start() +{ + m_PC.d = 0; + m_SP.d = 0; + m_AF.d = 0; + m_BC.d = 0; + m_DE.d = 0; + m_HL.d = 0; + m_WZ.d = 0; + m_halt = 0; + m_im = 0; + m_status = 0; + m_after_ei = 0; + m_nmi_state = 0; + m_irq_state[3] = m_irq_state[2] = m_irq_state[1] = m_irq_state[0] = 0; + m_trap_pending = 0; + m_trap_im_copy = 0; + m_sod_state = 0; + m_ietemp = false; + + init_tables(); + + /* set up the state table */ + { + state_add(I8085_PC, "PC", m_PC.w.l); + state_add(STATE_GENPC, "GENPC", m_PC.w.l).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_PC.w.l).noshow(); + state_add(I8085_SP, "SP", m_SP.w.l); + state_add(STATE_GENSP, "GENSP", m_SP.w.l).noshow(); + state_add(STATE_GENFLAGS, "GENFLAGS", m_AF.b.l).noshow().formatstr("%8s"); + state_add(I8085_A, "A", m_AF.b.h).noshow(); + state_add(I8085_B, "B", m_BC.b.h).noshow(); + state_add(I8085_C, "C", m_BC.b.l).noshow(); + state_add(I8085_D, "D", m_DE.b.h).noshow(); + state_add(I8085_E, "E", m_DE.b.l).noshow(); + state_add(I8085_F, "F", m_AF.b.l).noshow(); + state_add(I8085_H, "H", m_HL.b.h).noshow(); + state_add(I8085_L, "L", m_HL.b.l).noshow(); + state_add(I8085_AF, "AF", m_AF.w.l); + state_add(I8085_BC, "BC", m_BC.w.l); + state_add(I8085_DE, "DE", m_DE.w.l); + state_add(I8085_HL, "HL", m_HL.w.l); + state_add(I8085_STATUS, "STATUS", m_status); + state_add(I8085_SOD, "SOD", m_sod_state).mask(0x1); + state_add(I8085_SID, "SID", m_ietemp).mask(0x1).callimport().callexport(); + state_add(I8085_INTE, "INTE", m_ietemp).mask(0x1).callimport().callexport(); + } + + m_program = &space(AS_PROGRAM); + m_direct = &m_program->direct(); + m_io = &space(AS_IO); + + /* resolve callbacks */ + m_out_status_func.resolve_safe(); + m_out_inte_func.resolve_safe(); + m_in_sid_func.resolve_safe(0); + m_out_sod_func.resolve_safe(); + + /* register for state saving */ + save_item(NAME(m_PC.w.l)); + save_item(NAME(m_SP.w.l)); + save_item(NAME(m_AF.w.l)); + save_item(NAME(m_BC.w.l)); + save_item(NAME(m_DE.w.l)); + save_item(NAME(m_HL.w.l)); + save_item(NAME(m_halt)); + save_item(NAME(m_im)); + save_item(NAME(m_status)); + save_item(NAME(m_after_ei)); + save_item(NAME(m_nmi_state)); + save_item(NAME(m_irq_state)); + save_item(NAME(m_trap_pending)); + save_item(NAME(m_trap_im_copy)); + save_item(NAME(m_sod_state)); + + m_icountptr = &m_icount; +} + + +/*************************************************************************** + COMMON RESET +***************************************************************************/ + +void i8085a_cpu_device::device_reset() +{ + m_PC.d = 0; + m_halt = 0; + m_im &= ~IM_I75; + m_im |= IM_M55 | IM_M65 | IM_M75; + m_after_ei = false; + m_trap_pending = false; + m_trap_im_copy = 0; + set_inte(0); + set_sod(0); +} + + +/*************************************************************************** + COMMON STATE IMPORT/EXPORT +***************************************************************************/ + +void i8085a_cpu_device::state_import(const device_state_entry &entry) +{ + switch (entry.index()) + { + case I8085_SID: + if (m_ietemp) + { + m_im |= IM_SID; + } + else + { + m_im &= ~IM_SID; + } + break; + + case I8085_INTE: + if (m_ietemp) + { + m_im |= IM_IE; + } + else + { + m_im &= ~IM_IE; + } + break; + + default: + fatalerror("CPU_IMPORT_STATE(i808x) called for unexpected value\n"); + } +} + +void i8085a_cpu_device::state_export(const device_state_entry &entry) +{ + switch (entry.index()) + { + case I8085_SID: + m_ietemp = ((m_im & IM_SID) != 0) && m_in_sid_func() != 0; + break; + + case I8085_INTE: + m_ietemp = ((m_im & IM_IE) != 0); + break; + + default: + fatalerror("CPU_EXPORT_STATE(i808x) called for unexpected value\n"); + } +} + +void i8085a_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const +{ + switch (entry.index()) + { + case STATE_GENFLAGS: + str = string_format("%c%c%c%c%c%c%c%c", + m_AF.b.l & 0x80 ? 'S':'.', + m_AF.b.l & 0x40 ? 'Z':'.', + m_AF.b.l & 0x20 ? 'X':'.', // X5 + m_AF.b.l & 0x10 ? 'H':'.', + m_AF.b.l & 0x08 ? '?':'.', + m_AF.b.l & 0x04 ? 'P':'.', + m_AF.b.l & 0x02 ? 'V':'.', + m_AF.b.l & 0x01 ? 'C':'.'); + break; + } +} + +offs_t i8085a_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +{ + extern CPU_DISASSEMBLE( i8085 ); + return CPU_DISASSEMBLE_NAME(i8085)(this, stream, pc, oprom, opram, options); +} + + +/*************************************************************************** + INTERRUPTS +***************************************************************************/ + +void i8085a_cpu_device::execute_set_input(int irqline, int state) +{ + int newstate = (state != CLEAR_LINE); + + /* NMI is edge-triggered */ + if (irqline == INPUT_LINE_NMI) + { + if (!m_nmi_state && newstate) + m_trap_pending = true; + m_nmi_state = newstate; + } + + /* RST7.5 is edge-triggered */ + else if (irqline == I8085_RST75_LINE) + { + if (!m_irq_state[I8085_RST75_LINE] && newstate) + m_im |= IM_I75; + m_irq_state[I8085_RST75_LINE] = newstate; + } + + /* remaining sources are level triggered */ + else if (irqline < ARRAY_LENGTH(m_irq_state)) + m_irq_state[irqline] = state; +} + +void i8085a_cpu_device::break_halt_for_interrupt() +{ + /* de-halt if necessary */ + if (m_halt) + { + m_PC.w.l++; + m_halt = 0; + set_status(0x26); /* int ack while halt */ + } + else + set_status(0x23); /* int ack */ +} + +void i8085a_cpu_device::check_for_interrupts() +{ + /* TRAP is the highest priority */ + if (m_trap_pending) + { + /* the first RIM after a TRAP reflects the original IE state; remember it here, + setting the high bit to indicate it is valid */ + m_trap_im_copy = m_im | 0x80; + + /* reset the pending state */ + m_trap_pending = false; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(INPUT_LINE_NMI); + + /* push the PC and jump to $0024 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_TRAP; + m_icount -= 11; + } + + /* followed by RST7.5 */ + else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE)) + { + /* reset the pending state (which is CPU-visible via the RIM instruction) */ + m_im &= ~IM_I75; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST75_LINE); + + /* push the PC and jump to $003C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST75; + m_icount -= 11; + } + + /* followed by RST6.5 */ + else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST65_LINE); + + /* push the PC and jump to $0034 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST65; + m_icount -= 11; + } + + /* followed by RST5.5 */ + else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST55_LINE); + + /* push the PC and jump to $002C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST55; + m_icount -= 11; + } + + /* followed by classic INTR */ + else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE)) + { + u32 vector; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + vector = standard_irq_callback(I8085_INTR_LINE); + + /* use the resulting vector as an opcode to execute */ + set_inte(0); + switch (vector & 0xff0000) + { + case 0xcd0000: /* CALL nnnn */ + m_icount -= 7; + op_push(m_PC); + case 0xc30000: /* JMP nnnn */ + m_icount -= 10; + m_PC.d = vector & 0xffff; + break; + + default: + LOG("i8085 take int $%02x\n", vector); + execute_one(vector & 0xff); + break; + } + } +} + + +/*************************************************************************** OPCODE HELPERS ***************************************************************************/ @@ -486,145 +830,6 @@ void i8085a_cpu_device::op_rst(u8 v) /*************************************************************************** - INTERRUPTS -***************************************************************************/ - -void i8085a_cpu_device::execute_set_input(int irqline, int state) -{ - int newstate = (state != CLEAR_LINE); - - /* NMI is edge-triggered */ - if (irqline == INPUT_LINE_NMI) - { - if (!m_nmi_state && newstate) - m_trap_pending = true; - m_nmi_state = newstate; - } - - /* RST7.5 is edge-triggered */ - else if (irqline == I8085_RST75_LINE) - { - if (!m_irq_state[I8085_RST75_LINE] && newstate) - m_im |= IM_I75; - m_irq_state[I8085_RST75_LINE] = newstate; - } - - /* remaining sources are level triggered */ - else if (irqline < ARRAY_LENGTH(m_irq_state)) - m_irq_state[irqline] = state; -} - -void i8085a_cpu_device::break_halt_for_interrupt() -{ - /* de-halt if necessary */ - if (m_halt) - { - m_PC.w.l++; - m_halt = 0; - set_status(0x26); /* int ack while halt */ - } - else - set_status(0x23); /* int ack */ -} - -void i8085a_cpu_device::check_for_interrupts() -{ - /* TRAP is the highest priority */ - if (m_trap_pending) - { - /* the first RIM after a TRAP reflects the original IE state; remember it here, - setting the high bit to indicate it is valid */ - m_trap_im_copy = m_im | 0x80; - - /* reset the pending state */ - m_trap_pending = false; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(INPUT_LINE_NMI); - - /* push the PC and jump to $0024 */ - op_push(m_PC); - set_inte(0); - m_PC.w.l = ADDR_TRAP; - m_icount -= 11; - } - - /* followed by RST7.5 */ - else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE)) - { - /* reset the pending state (which is CPU-visible via the RIM instruction) */ - m_im &= ~IM_I75; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST75_LINE); - - /* push the PC and jump to $003C */ - op_push(m_PC); - set_inte(0); - m_PC.w.l = ADDR_RST75; - m_icount -= 11; - } - - /* followed by RST6.5 */ - else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST65_LINE); - - /* push the PC and jump to $0034 */ - op_push(m_PC); - set_inte(0); - m_PC.w.l = ADDR_RST65; - m_icount -= 11; - } - - /* followed by RST5.5 */ - else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST55_LINE); - - /* push the PC and jump to $002C */ - op_push(m_PC); - set_inte(0); - m_PC.w.l = ADDR_RST55; - m_icount -= 11; - } - - /* followed by classic INTR */ - else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE)) - { - u32 vector; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - vector = standard_irq_callback(I8085_INTR_LINE); - - /* use the resulting vector as an opcode to execute */ - set_inte(0); - switch (vector & 0xff0000) - { - case 0xcd0000: /* CALL nnnn */ - m_icount -= 7; - op_push(m_PC); - case 0xc30000: /* JMP nnnn */ - m_icount -= 10; - m_PC.d = vector & 0xffff; - break; - - default: - LOG("i8085 take int $%02x\n", vector); - execute_one(vector & 0xff); - break; - } - } -} - -/*************************************************************************** COMMON EXECUTION ***************************************************************************/ @@ -1411,218 +1616,3 @@ void i8085a_cpu_device::execute_one(int opcode) break; } // end big switch } - - - - - -/*************************************************************************** - CORE INITIALIZATION -***************************************************************************/ - -void i8085a_cpu_device::init_tables() -{ - u8 zs; - int i, p; - for (i = 0; i < 256; i++) - { - /* cycles */ - lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i]; - - /* flags */ - zs = 0; - if (i==0) zs |= ZF; - if (i&128) zs |= SF; - p = 0; - if (i&1) ++p; - if (i&2) ++p; - if (i&4) ++p; - if (i&8) ++p; - if (i&16) ++p; - if (i&32) ++p; - if (i&64) ++p; - if (i&128) ++p; - lut_zs[i] = zs; - lut_zsp[i] = zs | ((p&1) ? 0 : PF); - } -} - - -void i8085a_cpu_device::device_start() -{ - m_PC.d = 0; - m_SP.d = 0; - m_AF.d = 0; - m_BC.d = 0; - m_DE.d = 0; - m_HL.d = 0; - m_WZ.d = 0; - m_halt = 0; - m_im = 0; - m_status = 0; - m_after_ei = 0; - m_nmi_state = 0; - m_irq_state[3] = m_irq_state[2] = m_irq_state[1] = m_irq_state[0] = 0; - m_trap_pending = 0; - m_trap_im_copy = 0; - m_sod_state = 0; - m_ietemp = false; - - init_tables(); - - /* set up the state table */ - { - state_add(I8085_PC, "PC", m_PC.w.l); - state_add(STATE_GENPC, "GENPC", m_PC.w.l).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_PC.w.l).noshow(); - state_add(I8085_SP, "SP", m_SP.w.l); - state_add(STATE_GENSP, "GENSP", m_SP.w.l).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", m_AF.b.l).noshow().formatstr("%8s"); - state_add(I8085_A, "A", m_AF.b.h).noshow(); - state_add(I8085_B, "B", m_BC.b.h).noshow(); - state_add(I8085_C, "C", m_BC.b.l).noshow(); - state_add(I8085_D, "D", m_DE.b.h).noshow(); - state_add(I8085_E, "E", m_DE.b.l).noshow(); - state_add(I8085_F, "F", m_AF.b.l).noshow(); - state_add(I8085_H, "H", m_HL.b.h).noshow(); - state_add(I8085_L, "L", m_HL.b.l).noshow(); - state_add(I8085_AF, "AF", m_AF.w.l); - state_add(I8085_BC, "BC", m_BC.w.l); - state_add(I8085_DE, "DE", m_DE.w.l); - state_add(I8085_HL, "HL", m_HL.w.l); - state_add(I8085_STATUS, "STATUS", m_status); - state_add(I8085_SOD, "SOD", m_sod_state).mask(0x1); - state_add(I8085_SID, "SID", m_ietemp).mask(0x1).callimport().callexport(); - state_add(I8085_INTE, "INTE", m_ietemp).mask(0x1).callimport().callexport(); - } - - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - m_io = &space(AS_IO); - - /* resolve callbacks */ - m_out_status_func.resolve_safe(); - m_out_inte_func.resolve_safe(); - m_in_sid_func.resolve_safe(0); - m_out_sod_func.resolve_safe(); - - /* register for state saving */ - save_item(NAME(m_PC.w.l)); - save_item(NAME(m_SP.w.l)); - save_item(NAME(m_AF.w.l)); - save_item(NAME(m_BC.w.l)); - save_item(NAME(m_DE.w.l)); - save_item(NAME(m_HL.w.l)); - save_item(NAME(m_halt)); - save_item(NAME(m_im)); - save_item(NAME(m_status)); - save_item(NAME(m_after_ei)); - save_item(NAME(m_nmi_state)); - save_item(NAME(m_irq_state)); - save_item(NAME(m_trap_pending)); - save_item(NAME(m_trap_im_copy)); - save_item(NAME(m_sod_state)); - - m_icountptr = &m_icount; -} - - -/*************************************************************************** - COMMON RESET -***************************************************************************/ - -void i8085a_cpu_device::device_reset() -{ - m_PC.d = 0; - m_halt = 0; - m_im &= ~IM_I75; - m_im |= IM_M55 | IM_M65 | IM_M75; - m_after_ei = false; - m_trap_pending = false; - m_trap_im_copy = 0; - set_inte(0); - set_sod(0); -} - - - -/*************************************************************************** - COMMON STATE IMPORT/EXPORT -***************************************************************************/ - -void i8085a_cpu_device::state_import(const device_state_entry &entry) -{ - switch (entry.index()) - { - case I8085_SID: - if (m_ietemp) - { - m_im |= IM_SID; - } - else - { - m_im &= ~IM_SID; - } - break; - - case I8085_INTE: - if (m_ietemp) - { - m_im |= IM_IE; - } - else - { - m_im &= ~IM_IE; - } - break; - - default: - fatalerror("CPU_IMPORT_STATE(i808x) called for unexpected value\n"); - } -} - - -void i8085a_cpu_device::state_export(const device_state_entry &entry) -{ - switch (entry.index()) - { - case I8085_SID: - m_ietemp = ((m_im & IM_SID) != 0) && m_in_sid_func() != 0; - break; - - case I8085_INTE: - m_ietemp = ((m_im & IM_IE) != 0); - break; - - default: - fatalerror("CPU_EXPORT_STATE(i808x) called for unexpected value\n"); - } -} - -void i8085a_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const -{ - switch (entry.index()) - { - case STATE_GENFLAGS: - str = string_format("%c%c%c%c%c%c%c%c", - m_AF.b.l & 0x80 ? 'S':'.', - m_AF.b.l & 0x40 ? 'Z':'.', - m_AF.b.l & 0x20 ? 'X':'.', // X5 - m_AF.b.l & 0x10 ? 'H':'.', - m_AF.b.l & 0x08 ? '?':'.', - m_AF.b.l & 0x04 ? 'P':'.', - m_AF.b.l & 0x02 ? 'V':'.', - m_AF.b.l & 0x01 ? 'C':'.'); - break; - } -} - - - - - -offs_t i8085a_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) -{ - extern CPU_DISASSEMBLE( i8085 ); - return CPU_DISASSEMBLE_NAME(i8085)(this, stream, pc, oprom, opram, options); -} |