diff options
author | Miodrag Milanovic <mmicko@gmail.com> | 2015-09-13 08:41:44 +0200 |
---|---|---|
committer | Miodrag Milanovic <mmicko@gmail.com> | 2015-09-13 08:41:44 +0200 |
commit | f88cefad27a1737c76e09d99c9fb43e173506081 (patch) | |
tree | 2d8167d03579c46e226471747eb4407bd00ed6fa /src/emu/cpu/m6502/m6502.c | |
parent | e92ac9e0fa8e99869894bea00589bbb526be30aa (diff) |
Move all devices into separate part of src tree (nw)
Diffstat (limited to 'src/emu/cpu/m6502/m6502.c')
-rw-r--r-- | src/emu/cpu/m6502/m6502.c | 724 |
1 files changed, 0 insertions, 724 deletions
diff --git a/src/emu/cpu/m6502/m6502.c b/src/emu/cpu/m6502/m6502.c deleted file mode 100644 index 01b2b8f0f98..00000000000 --- a/src/emu/cpu/m6502/m6502.c +++ /dev/null @@ -1,724 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Olivier Galibert -/*************************************************************************** - - m6502.c - - Mostek 6502, original NMOS variant - -***************************************************************************/ - -#include "emu.h" -#include "debugger.h" -#include "m6502.h" - -const device_type M6502 = &device_creator<m6502_device>; - -m6502_device::m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - cpu_device(mconfig, M6502, "M6502", tag, owner, clock, "m6502", __FILE__), - sync_w(*this), - program_config("program", ENDIANNESS_LITTLE, 8, 16), - sprogram_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16) -{ - direct_disabled = false; -} - -m6502_device::m6502_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) : - cpu_device(mconfig, type, name, tag, owner, clock, shortname, source), - sync_w(*this), - program_config("program", ENDIANNESS_LITTLE, 8, 16), - sprogram_config("decrypted_opcodes", ENDIANNESS_LITTLE, 8, 16) -{ - direct_disabled = false; -} - -void m6502_device::device_start() -{ - if(direct_disabled) - mintf = new mi_default_nd; - else - mintf = new mi_default_normal; - - init(); -} - -void m6502_device::init() -{ - mintf->program = &space(AS_PROGRAM); - mintf->sprogram = has_space(AS_DECRYPTED_OPCODES) ? &space(AS_DECRYPTED_OPCODES) : mintf->program; - - mintf->direct = &mintf->program->direct(); - mintf->sdirect = &mintf->sprogram->direct(); - - sync_w.resolve_safe(); - - state_add(STATE_GENPC, "GENPC", NPC).noshow(); - state_add(STATE_GENPCBASE, "GENPCBASE", PPC).noshow(); - state_add(STATE_GENSP, "GENSP", SP).noshow(); - state_add(STATE_GENFLAGS, "GENFLAGS", P).callimport().formatstr("%6s").noshow(); - state_add(M6502_PC, "PC", NPC).callimport(); - state_add(M6502_A, "A", A); - state_add(M6502_X, "X", X); - state_add(M6502_Y, "Y", Y); - state_add(M6502_P, "P", P).callimport(); - state_add(M6502_S, "SP", SP); - state_add(M6502_IR, "IR", IR); - - save_item(NAME(PC)); - save_item(NAME(NPC)); - save_item(NAME(A)); - save_item(NAME(X)); - save_item(NAME(Y)); - save_item(NAME(P)); - save_item(NAME(SP)); - save_item(NAME(TMP)); - save_item(NAME(TMP2)); - save_item(NAME(IR)); - save_item(NAME(nmi_state)); - save_item(NAME(irq_state)); - save_item(NAME(apu_irq_state)); - save_item(NAME(v_state)); - save_item(NAME(inst_state)); - save_item(NAME(inst_substate)); - save_item(NAME(inst_state_base)); - save_item(NAME(irq_taken)); - save_item(NAME(inhibit_interrupts)); - - m_icountptr = &icount; - - PC = 0x0000; - NPC = 0x0000; - A = 0x00; - X = 0x80; - Y = 0x00; - P = 0x36; - SP = 0x01bd; - TMP = 0x0000; - TMP2 = 0x00; - IR = 0x00; - nmi_state = false; - irq_state = false; - apu_irq_state = false; - irq_taken = false; - v_state = false; - inst_state = STATE_RESET; - inst_substate = 0; - inst_state_base = 0; - sync = false; - inhibit_interrupts = false; -} - -void m6502_device::device_reset() -{ - inst_state = STATE_RESET; - inst_substate = 0; - inst_state_base = 0; - nmi_state = false; - irq_state = false; - apu_irq_state = false; - irq_taken = false; - v_state = false; - sync = false; - sync_w(CLEAR_LINE); - inhibit_interrupts = false; -} - - -UINT32 m6502_device::execute_min_cycles() const -{ - return 1; -} - -UINT32 m6502_device::execute_max_cycles() const -{ - return 10; -} - -UINT32 m6502_device::execute_input_lines() const -{ - return NMI_LINE+1; -} - -void m6502_device::do_adc_d(UINT8 val) -{ - UINT8 c = P & F_C ? 1 : 0; - P &= ~(F_N|F_V|F_Z|F_C); - UINT8 al = (A & 15) + (val & 15) + c; - if(al > 9) - al += 6; - UINT8 ah = (A >> 4) + (val >> 4) + (al > 15); - if(!UINT8(A + val + c)) - P |= F_Z; - else if(ah & 8) - P |= F_N; - if(~(A^val) & (A^(ah << 4)) & 0x80) - P |= F_V; - if(ah > 9) - ah += 6; - if(ah > 15) - P |= F_C; - A = (ah << 4) | (al & 15); -} - -void m6502_device::do_adc_nd(UINT8 val) -{ - UINT16 sum; - sum = A + val + (P & F_C ? 1 : 0); - P &= ~(F_N|F_V|F_Z|F_C); - if(!UINT8(sum)) - P |= F_Z; - else if(INT8(sum) < 0) - P |= F_N; - if(~(A^val) & (A^sum) & 0x80) - P |= F_V; - if(sum & 0xff00) - P |= F_C; - A = sum; -} - -void m6502_device::do_adc(UINT8 val) -{ - if(P & F_D) - do_adc_d(val); - else - do_adc_nd(val); -} - -void m6502_device::do_arr_nd() -{ - bool c = P & F_C; - P &= ~(F_N|F_Z|F_C|F_V); - A >>= 1; - if(c) - A |= 0x80; - if(!A) - P |= F_Z; - else if(INT8(A)<0) - P |= F_N; - if(A & 0x40) - P |= F_V|F_C; - if(A & 0x20) - P ^= F_V; -} - -void m6502_device::do_arr_d() -{ - // The adc/ror interaction gives an extremely weird result - bool c = P & F_C; - P &= ~(F_N|F_Z|F_C|F_V); - UINT8 a = A >> 1; - if(c) - a |= 0x80; - if(!a) - P |= F_Z; - else if(INT8(a) < 0) - P |= F_N; - if((a ^ A) & 0x40) - P |= F_V; - - if((A & 0x0f) >= 0x05) - a = ((a + 6) & 0x0f) | (a & 0xf0); - - if((A & 0xf0) >= 0x50) { - a += 0x60; - P |= F_C; - } - A = a; -} - -void m6502_device::do_arr() -{ - if(P & F_D) - do_arr_d(); - else - do_arr_nd(); -} - -void m6502_device::do_cmp(UINT8 val1, UINT8 val2) -{ - P &= ~(F_N|F_Z|F_C); - UINT16 r = val1-val2; - if(!r) - P |= F_Z; - else if(INT8(r) < 0) - P |= F_N; - if(!(r & 0xff00)) - P |= F_C; -} - -void m6502_device::do_sbc_d(UINT8 val) -{ - UINT8 c = P & F_C ? 0 : 1; - P &= ~(F_N|F_V|F_Z|F_C); - UINT16 diff = A - val - c; - UINT8 al = (A & 15) - (val & 15) - c; - if(INT8(al) < 0) - al -= 6; - UINT8 ah = (A >> 4) - (val >> 4) - (INT8(al) < 0); - if(!UINT8(diff)) - P |= F_Z; - else if(diff & 0x80) - P |= F_N; - if((A^val) & (A^diff) & 0x80) - P |= F_V; - if(!(diff & 0xff00)) - P |= F_C; - if(INT8(ah) < 0) - ah -= 6; - A = (ah << 4) | (al & 15); -} - -void m6502_device::do_sbc_nd(UINT8 val) -{ - UINT16 diff = A - val - (P & F_C ? 0 : 1); - P &= ~(F_N|F_V|F_Z|F_C); - if(!UINT8(diff)) - P |= F_Z; - else if(INT8(diff) < 0) - P |= F_N; - if((A^val) & (A^diff) & 0x80) - P |= F_V; - if(!(diff & 0xff00)) - P |= F_C; - A = diff; -} - -void m6502_device::do_sbc(UINT8 val) -{ - if(P & F_D) - do_sbc_d(val); - else - do_sbc_nd(val); -} - -void m6502_device::do_bit(UINT8 val) -{ - P &= ~(F_N|F_Z|F_V); - UINT8 r = A & val; - if(!r) - P |= F_Z; - if(val & 0x80) - P |= F_N; - if(val & 0x40) - P |= F_V; -} - -UINT8 m6502_device::do_asl(UINT8 v) -{ - P &= ~(F_N|F_Z|F_C); - UINT8 r = v<<1; - if(!r) - P |= F_Z; - else if(INT8(r) < 0) - P |= F_N; - if(v & 0x80) - P |= F_C; - return r; -} - -UINT8 m6502_device::do_lsr(UINT8 v) -{ - P &= ~(F_N|F_Z|F_C); - if(v & 1) - P |= F_C; - v >>= 1; - if(!v) - P |= F_Z; - return v; -} - -UINT8 m6502_device::do_ror(UINT8 v) -{ - bool c = P & F_C; - P &= ~(F_N|F_Z|F_C); - if(v & 1) - P |= F_C; - v >>= 1; - if(c) - v |= 0x80; - if(!v) - P |= F_Z; - else if(INT8(v)<0) - P |= F_N; - return v; -} - -UINT8 m6502_device::do_rol(UINT8 v) -{ - bool c = P & F_C; - P &= ~(F_N|F_Z|F_C); - if(v & 0x80) - P |= F_C; - v <<= 1; - if(c) - v |= 0x01; - if(!v) - P |= F_Z; - else if(INT8(v)<0) - P |= F_N; - return v; -} - -UINT8 m6502_device::do_asr(UINT8 v) -{ - P &= ~(F_N|F_Z|F_C); - if(v & 1) - P |= F_C; - v >>= 1; - if(!v) - P |= F_Z; - else if(v & 0x40) { - P |= F_N; - v |= 0x80; - } - return v; -} - -void m6502_device::execute_run() -{ - if(inst_substate) - do_exec_partial(); - - while(icount > 0) { - if(inst_state < 0xff00) { - PPC = NPC; - inst_state = IR | inst_state_base; - if(machine().debug_flags & DEBUG_FLAG_ENABLED) - debugger_instruction_hook(this, NPC); - } - do_exec_full(); - } -} - -void m6502_device::execute_set_input(int inputnum, int state) -{ - switch(inputnum) { - case IRQ_LINE: irq_state = state == ASSERT_LINE; break; - case APU_IRQ_LINE: apu_irq_state = state == ASSERT_LINE; break; - case NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break; - case V_LINE: - if(!v_state && state == ASSERT_LINE) - P |= F_V; - v_state = state == ASSERT_LINE; - break; - } -} - - -const address_space_config *m6502_device::memory_space_config(address_spacenum spacenum) const -{ - switch(spacenum) - { - case AS_PROGRAM: return &program_config; - case AS_DECRYPTED_OPCODES: return has_configured_map(AS_DECRYPTED_OPCODES) ? &sprogram_config : NULL; - default: return NULL; - } -} - - -void m6502_device::state_import(const device_state_entry &entry) -{ - switch(entry.index()) { - case STATE_GENFLAGS: - case M6502_P: - P = P | (F_B|F_E); - break; - case M6502_PC: - PC = NPC; - irq_taken = false; - prefetch(); - PPC = NPC; - inst_state = IR | inst_state_base; - break; - } -} - -void m6502_device::state_export(const device_state_entry &entry) -{ -} - -void m6502_device::state_string_export(const device_state_entry &entry, std::string &str) -{ - switch(entry.index()) { - case STATE_GENFLAGS: - case M6502_P: - strprintf(str, "%c%c%c%c%c%c", - P & F_N ? 'N' : '.', - P & F_V ? 'V' : '.', - P & F_D ? 'D' : '.', - P & F_I ? 'I' : '.', - P & F_Z ? 'Z' : '.', - P & F_C ? 'C' : '.'); - break; - } -} - - -UINT32 m6502_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -UINT32 m6502_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -offs_t m6502_device::disassemble_generic(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options, const disasm_entry *table) -{ - const disasm_entry &e = table[oprom[0] | inst_state_base]; - UINT32 flags = e.flags | DASMFLAG_SUPPORTED; - buffer += sprintf(buffer, "%s", e.opcode); - - switch(e.mode) { - case DASM_non: - flags |= 1; - break; - - case DASM_aba: - sprintf(buffer, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_abx: - sprintf(buffer, " $%02x%02x, x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_aby: - sprintf(buffer, " $%02x%02x, y", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_acc: - sprintf(buffer, " a"); - flags |= 1; - break; - - case DASM_adr: - sprintf(buffer, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_bzp: - sprintf(buffer, "%d $%02x", (oprom[0] >> 4) & 7, opram[1]); - flags |= 2; - break; - - case DASM_iax: - sprintf(buffer, " ($%02x%02x, x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_idx: - sprintf(buffer, " ($%02x, x)", opram[1]); - flags |= 2; - break; - - case DASM_idy: - sprintf(buffer, " ($%02x), y", opram[1]); - flags |= 2; - break; - - case DASM_idz: - sprintf(buffer, " ($%02x), z", opram[1]); - flags |= 2; - break; - - case DASM_imm: - sprintf(buffer, " #$%02x", opram[1]); - flags |= 2; - break; - - case DASM_imp: - flags |= 1; - break; - - case DASM_ind: - sprintf(buffer, " ($%02x%02x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_isy: - sprintf(buffer, " ($%02x, s), y", opram[1]); - flags |= 2; - break; - - case DASM_iw2: - sprintf(buffer, " #$%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_iw3: - sprintf(buffer, " #$%02x%02x%02x", opram[3], opram[2], opram[1]); - flags |= 4; - break; - - case DASM_rel: - sprintf(buffer, " $%04x", (pc & 0xf0000) | UINT16(pc + 2 + INT8(opram[1]))); - flags |= 2; - break; - - case DASM_rw2: - sprintf(buffer, " $%04x", (pc & 0xf0000) | UINT16(pc + 2 + INT16((opram[2] << 8) | opram[1]))); - flags |= 3; - break; - - case DASM_zpb: - sprintf(buffer, "%d $%02x, $%04x", (oprom[0] >> 4) & 7, opram[1], (pc & 0xf0000) | UINT16(pc + 3 + INT8(opram[2]))); - flags |= 3; - break; - - case DASM_zpg: - sprintf(buffer, " $%02x", opram[1]); - flags |= 2; - break; - - case DASM_zpi: - sprintf(buffer, " ($%02x)", opram[1]); - flags |= 2; - break; - - case DASM_zpx: - sprintf(buffer, " $%02x, x", opram[1]); - flags |= 2; - break; - - case DASM_zpy: - sprintf(buffer, " $%02x, y", opram[1]); - flags |= 2; - break; - - case DASM_imz: - sprintf(buffer, " #$%02x, $%02x", opram[1], opram[2]); - flags |= 3; - break; - - case DASM_spg: - sprintf(buffer, " \\$%02x", opram[1]); - flags |= 2; - break; - - case DASM_biz: - sprintf(buffer, " %d, $%02x", (opram[0] >> 5) & 7, opram[1]); - flags |= 2; - break; - - case DASM_bzr: - sprintf(buffer, " %d, $%02x, $%04x", (opram[0] >> 5) & 7, opram[1], (pc & 0xf0000) | UINT16(pc + 3 + INT8(opram[2]))); - flags |= 3; - break; - - case DASM_bar: - sprintf(buffer, " %d, a, $%04x", (opram[0] >> 5) & 7, (pc & 0xf0000) | UINT16(pc + 3 + INT8(opram[1]))); - flags |= 2; - break; - - case DASM_bac: - sprintf(buffer, " %d, a", (opram[0] >> 5) & 7); - flags |= 1; - break; - - default: - fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); - abort(); - } - return flags; -} - -void m6502_device::prefetch() -{ - sync = true; - sync_w(ASSERT_LINE); - NPC = PC; - IR = mintf->read_sync(PC); - sync = false; - sync_w(CLEAR_LINE); - - if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) { - irq_taken = true; - IR = 0x00; - } else - PC++; -} - -void m6502_device::prefetch_noirq() -{ - sync = true; - sync_w(ASSERT_LINE); - NPC = PC; - IR = mintf->read_sync(PC); - sync = false; - sync_w(CLEAR_LINE); - PC++; -} - -void m6502_device::set_nz(UINT8 v) -{ - P &= ~(F_Z|F_N); - if(v & 0x80) - P |= F_N; - if(!v) - P |= F_Z; -} - -offs_t m6502_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) -{ - return disassemble_generic(buffer, pc, oprom, opram, options, disasm_entries); -} - - -UINT8 m6502_device::memory_interface::read_9(UINT16 adr) -{ - return read(adr); -} - -void m6502_device::memory_interface::write_9(UINT16 adr, UINT8 val) -{ - write(adr, val); -} - - -UINT8 m6502_device::mi_default_normal::read(UINT16 adr) -{ - return program->read_byte(adr); -} - -UINT8 m6502_device::mi_default_normal::read_sync(UINT16 adr) -{ - return sdirect->read_byte(adr); -} - -UINT8 m6502_device::mi_default_normal::read_arg(UINT16 adr) -{ - return direct->read_byte(adr); -} - - -void m6502_device::mi_default_normal::write(UINT16 adr, UINT8 val) -{ - program->write_byte(adr, val); -} - -UINT8 m6502_device::mi_default_nd::read_sync(UINT16 adr) -{ - return sprogram->read_byte(adr); -} - -UINT8 m6502_device::mi_default_nd::read_arg(UINT16 adr) -{ - return program->read_byte(adr); -} - - -WRITE_LINE_MEMBER( m6502_device::irq_line ) -{ - set_input_line( M6502_IRQ_LINE, state ); -} - -WRITE_LINE_MEMBER( m6502_device::nmi_line ) -{ - set_input_line( M6502_NMI_LINE, state ); -} - -#include "cpu/m6502/m6502.inc" |