diff options
Diffstat (limited to 'src/devices/cpu/m6502')
-rw-r--r-- | src/devices/cpu/m6502/om65c02gk.lst | 88 | ||||
-rw-r--r-- | src/devices/cpu/m6502/r65c02gk.cpp | 109 | ||||
-rw-r--r-- | src/devices/cpu/m6502/r65c02gk.h | 74 |
3 files changed, 271 insertions, 0 deletions
diff --git a/src/devices/cpu/m6502/om65c02gk.lst b/src/devices/cpu/m6502/om65c02gk.lst new file mode 100644 index 00000000000..9c2d732f062 --- /dev/null +++ b/src/devices/cpu/m6502/om65c02gk.lst @@ -0,0 +1,88 @@ +# license:BSD-3-Clause +# copyright-holders:Peter Trauner +# r65c02gk opcodes + +brk_c_imp + if(irq_taken || nmi_state) { + read_pc_noinc(); + } else { + read_pc(); + } + write(SP, PC >> 8); + dec_SP(); + write(SP, PC); + dec_SP(); + write(SP, irq_taken || nmi_state ? P & ~F_B : P); + dec_SP(); + if(irq_taken && nmi_state) { + PC = read_arg(0x7ffa); + PC = set_h(PC, read_arg(0x7ffb)); + nmi_state = false; + standard_irq_callback(NMI_LINE); + } else { + static int level=interrupt_controller.getlevel(); // !no gameking dual core expected + if (level==IRQ_GK3A) { + PC = read_arg(0x7fe2); + PC = set_h(PC, read_arg(0x7fe3)); + } else if (level==IRQ_GK3B) { + PC = read_arg(0x7fe4); + PC = set_h(PC, read_arg(0x7fe5)); + } else if (level==IRQ_TIMERUSER) { + m_bank4000->set_base(bank4000_irq); + PC = read_arg(0x7fee); + PC = set_h(PC, read_arg(0x7fef)); + } else if (level==IRQ_INPUTS) { + m_bank4000->set_base(bank4000_irq); + PC = read_arg(0x7ff0); + PC = set_h(PC, read_arg(0x7ff1)); + } else if (level==IRQ_USER) { + m_bank4000->set_base(bank4000_irq); + PC = read_arg(0x7ff2); + PC = set_h(PC, read_arg(0x7ff3)); + } else if (level==IRQ_TIMER/*INPUT_LINE_IRQ9*/) { + m_bank4000->set_base(bank4000_irq); + PC = read_arg(0x7ff4); + PC = set_h(PC, read_arg(0x7ff5)); + } else if (level==IRQ_6606) { + PC = read_arg(0x7ff6); + PC = set_h(PC, read_arg(0x7ff7)); + } else { + PC = read_arg(0x7ffe); + PC = set_h(PC, read_arg(0x7fff)); + if(irq_taken) + standard_irq_callback(IRQ_LINE); + } + } + irq_taken = false; + P = (P | F_I) & ~F_D; // Do *not* move after the prefetch + prefetch(); + inst_state = -1; + + +rti_imp + read_pc_noinc(); + read(SP); + inc_SP(); + P = read(SP) | (F_B|F_E); + inc_SP(); + PC = read(SP); + inc_SP(); + PC = set_h(PC, read(SP)); + m_bank4000->set_base(bank4000_normal); + prefetch(); + +wai_imp + read_pc_noinc(); /* same as m65c02 version, seams to be right*/ + read_pc_noinc(); + while(!nmi_state && !irq_state) { + eat-all-cycles; + } + prefetch(); + +# exceptions +reset + PC = read_arg(0x7ffc); + PC = set_h(PC, read_arg(0x7ffd)); + prefetch(); + inst_state = -1; +
\ No newline at end of file diff --git a/src/devices/cpu/m6502/r65c02gk.cpp b/src/devices/cpu/m6502/r65c02gk.cpp new file mode 100644 index 00000000000..6ffecf92934 --- /dev/null +++ b/src/devices/cpu/m6502/r65c02gk.cpp @@ -0,0 +1,109 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/*************************************************************************** + + r65c02gk.c + + Rockwell 65c02gb, additional interrupts, interrupt bankswitching + +***************************************************************************/ + +#include "emu.h" +#include "r65c02gk.h" + +const device_type R65C02GK = &device_creator<r65c02gk_device>; + +r65c02gk_device::r65c02gk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + r65c02_device(mconfig, R65C02GK, "R65C02GK", tag, owner, clock, "r65c02gk", __FILE__) +{ +} + +r65c02gk_device::r65c02gk_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) : + r65c02_device(mconfig, type, name, tag, owner, clock, shortname, source) +{ +} + +offs_t r65c02gk_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); +} + +void r65c02gk_device::device_reset() +{ + r65c02_device::device_reset(); + interrupt_controller.Reset(); +} + +void r65c02gk_device::set_irq_bank(memory_bank *m_bank4000_, UINT8 *bank4000_normal_, UINT8 *bank4000_irq_) { + m_bank4000 = m_bank4000_; + bank4000_normal=bank4000_normal_; + bank4000_irq=bank4000_irq_; +} + +void r65c02gk_device::execute_set_input(int inputnum, int state) +{ + switch(inputnum) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: + interrupt_controller.states[inputnum]=state; + irq_state= interrupt_controller.getlevel()>=0; + break; + case R65C02GK_NMI_LINE: nmi_state = nmi_state || (state == ASSERT_LINE); break; +#if 0 + case APU_IRQ_LINE: apu_irq_state = state == ASSERT_LINE; break; + case V_LINE: + if(!v_state && state == ASSERT_LINE) + P |= F_V; + v_state = state == ASSERT_LINE; + break; +#endif + } +// logerror("%.6f irq num:%d state:%d irq:%x level:%x\n",machine().time().as_double(), inputnum, state, irq_state, interrupt_controller.getlevel()); +} + +#if 0 +void r65c02gk_device::prefetch() +{ + sync = true; + sync_w(ASSERT_LINE); + NPC = PC; + IR = mintf->read_decrypted(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 r65c02gk_device::prefetch_wai() +{ + sync = true; + sync_w(ASSERT_LINE); + NPC = PC; + IR = mintf->read_decrypted(PC); + sync = false; + sync_w(CLEAR_LINE); + + if (irq_state || nmi_state) + PC++; + if((nmi_state || ((irq_state || apu_irq_state) && !(P & F_I))) && !inhibit_interrupts) { + irq_taken = true; + IR = 0x00; + } +} + +void r65c02gk_device::prefetch_noirq() +{ + sync = true; + sync_w(ASSERT_LINE); + NPC = PC; + IR = mintf->read_decrypted(PC); + sync = false; + sync_w(CLEAR_LINE); + PC++; +} +#endif + +#include "cpu/m6502/r65c02gk.hxx" diff --git a/src/devices/cpu/m6502/r65c02gk.h b/src/devices/cpu/m6502/r65c02gk.h new file mode 100644 index 00000000000..878c0ab43f7 --- /dev/null +++ b/src/devices/cpu/m6502/r65c02gk.h @@ -0,0 +1,74 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/*************************************************************************** + + r65c02gk.h + + gameking 65c02 with bitwise instructions and wai instruction, additional + interrupt vectors, special vector address base + + +***************************************************************************/ + +#ifndef __R65C02GK_H__ +#define __R65C02GK_H__ + +#include "r65c02.h" + +class r65c02gk_device : public r65c02_device { +public: + r65c02gk_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + r65c02gk_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); + + static const disasm_entry disasm_entries[0x100]; + + virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override; + virtual void do_exec_full() override; + virtual void do_exec_partial() override; + enum { + IRQ_GK3A=INPUT_LINE_IRQ0, + IRQ_GK3B, + IRQ_TIMERUSER=INPUT_LINE_IRQ6, + IRQ_INPUTS, //449C, + IRQ_USER, //=INPUT_LINE_IRQ8, + IRQ_TIMER, //=INPUT_LINE_IRQ9, + IRQ_6606, + R65C02GK_IRQ_LINE12 = IRQ_GK3A/*R65C02GK_IRQ_LINE0*/+12, + R65C02GK_NMI_LINE = INPUT_LINE_NMI // >12 +// R65C02GK_SET_OVERFLOW = m6502_device::V_LINE, + }; + + void set_irq_bank(memory_bank *m_bank4000, UINT8 *bank4000_normal, UINT8 *bank4000_irq); +protected: + UINT8 *bank4000_normal, *bank4000_irq; + virtual void device_reset() override; + virtual void execute_set_input(int inputnum, int state) override; + memory_bank *m_bank4000; + +#if 0 + void prefetch(); + void prefetch_noirq(); + void prefetch_wai(); +#endif + + struct InterruptController { // nearly nothing known about it, only enough to get bios working + bool states[13]; + int getlevel() { for (int i=12; i>=0; --i) { if (states[i]) return i; } return -1; } + void Reset() { memset(states, 0, sizeof(states)); } + } interrupt_controller; + + #define O(o) void o ## _full(); void o ## _partial() + + O(brk_c_imp); + O(rti_imp); + O(wai_imp); + + // exceptions + O(reset); + +}; + + +extern const device_type R65C02GK; + +#endif |