trunk/src/emu/cpu/m6502/m740.c
r21908 | r21909 | |
63 | 63 | inst_substate = 0; |
64 | 64 | nmi_state = false; |
65 | 65 | irq_state = false; |
| 66 | m_irq_multiplex = 0; |
| 67 | m_irq_vector = 0xfffc; |
66 | 68 | apu_irq_state = false; |
67 | 69 | irq_taken = false; |
68 | 70 | v_state = false; |
r21908 | r21909 | |
86 | 88 | // doesn't affect the flags |
87 | 89 | UINT8 m740_device::do_rrf(UINT8 in) |
88 | 90 | { |
89 | | return ((in&0xf)<<4) | ((in&0xf0)>>4); |
| 91 | return ((in&0xf)<<4) | ((in&0xf0)>>4); |
90 | 92 | } |
91 | 93 | |
| 94 | void m740_device::execute_set_input(int inputnum, int state) |
| 95 | { |
| 96 | switch(inputnum) |
| 97 | { |
| 98 | case M740_INT0_LINE: |
| 99 | case M740_INT1_LINE: |
| 100 | case M740_INT2_LINE: |
| 101 | case M740_INT3_LINE: |
| 102 | case M740_INT4_LINE: |
| 103 | case M740_INT5_LINE: |
| 104 | case M740_INT6_LINE: |
| 105 | case M740_INT7_LINE: |
| 106 | case M740_INT8_LINE: |
| 107 | case M740_INT9_LINE: |
| 108 | case M740_INT10_LINE: |
| 109 | case M740_INT11_LINE: |
| 110 | case M740_INT12_LINE: |
| 111 | case M740_INT13_LINE: |
| 112 | case M740_INT14_LINE: // 37450 has 15 IRQ lines, no other known variant has that many |
| 113 | set_irq_line(inputnum - M740_INT0_LINE, state); |
| 114 | break; |
| 115 | |
| 116 | case V_LINE: |
| 117 | if(!v_state && state == ASSERT_LINE) |
| 118 | { |
| 119 | P |= F_V; |
| 120 | } |
| 121 | v_state = state == ASSERT_LINE; |
| 122 | break; |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | void m740_device::set_irq_line(int line, int state) |
| 127 | { |
| 128 | assert(line > 0); |
| 129 | assert(line <= M740_MAX_INT_LINE); |
| 130 | |
| 131 | if (state == ASSERT_LINE) |
| 132 | { |
| 133 | m_irq_multiplex |= (1<<line); |
| 134 | } |
| 135 | else |
| 136 | { |
| 137 | m_irq_multiplex &= ~(1<<line); |
| 138 | } |
| 139 | |
| 140 | irq_state = (m_irq_multiplex != 0); |
| 141 | |
| 142 | if (irq_state) |
| 143 | { |
| 144 | for (int i = 0; i < M740_MAX_INT_LINE; i++) |
| 145 | { |
| 146 | if (m_irq_multiplex & (1 << i)) |
| 147 | { |
| 148 | m_irq_vector = 0xfffc - (UINT16)(2 * i); |
| 149 | break; |
| 150 | } |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | // printf("M740 single IRQ state is %d (MPX %08x, vector %x)\n", irq_state, m_irq_multiplex, m_irq_vector); |
| 155 | } |
| 156 | |
92 | 157 | #include "cpu/m6502/m740.inc" |
trunk/src/emu/cpu/m6502/m740.h
r21908 | r21909 | |
44 | 44 | |
45 | 45 | class m740_device : public m6502_device { |
46 | 46 | public: |
47 | | m740_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
48 | | m740_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 47 | enum |
| 48 | { |
| 49 | M740_INT0_LINE = INPUT_LINE_IRQ0, // (fffc) |
| 50 | M740_INT1_LINE, // (fffa) |
| 51 | M740_INT2_LINE, // (fff8) |
| 52 | M740_INT3_LINE, // (fff6) |
| 53 | M740_INT4_LINE, // (fff4) |
| 54 | M740_INT5_LINE, // (fff2) |
| 55 | M740_INT6_LINE, // (fff0) |
| 56 | M740_INT7_LINE, // (ffee) |
| 57 | M740_INT8_LINE, // (ffec) |
| 58 | M740_INT9_LINE, // (ffea) |
| 59 | M740_INT10_LINE, // (ffe8) |
| 60 | M740_INT11_LINE, // (ffe6) |
| 61 | M740_INT12_LINE, // (ffe4) |
| 62 | M740_INT13_LINE, // (ffe2) |
| 63 | M740_INT14_LINE, // (ffe0) |
| 64 | M740_MAX_INT_LINE = M740_INT14_LINE, |
| 65 | M740_SET_OVERFLOW = m6502_device::V_LINE, |
| 66 | }; |
49 | 67 | |
50 | | virtual void device_reset(); |
| 68 | m740_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 69 | m740_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
51 | 70 | |
52 | | static const disasm_entry disasm_entries[0x100]; |
| 71 | virtual void device_reset(); |
53 | 72 | |
54 | | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
55 | | virtual void do_exec_full(); |
56 | | virtual void do_exec_partial(); |
| 73 | static const disasm_entry disasm_entries[0x100]; |
57 | 74 | |
| 75 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 76 | virtual void do_exec_full(); |
| 77 | virtual void do_exec_partial(); |
| 78 | virtual void execute_set_input(int inputnum, int state); |
| 79 | |
58 | 80 | protected: |
59 | 81 | #define O(o) void o ## _full(); void o ## _partial() |
60 | 82 | |
r21908 | r21909 | |
63 | 85 | UINT8 do_rrf(UINT8 in); |
64 | 86 | |
65 | 87 | // m740 opcodes |
| 88 | O(brk740_imp); |
66 | 89 | O(clt_imp); |
67 | 90 | O(set_imp); |
68 | 91 | O(ldm_imz); |
r21908 | r21909 | |
74 | 97 | O(bbs_bzr); O(bbs_acc); |
75 | 98 | O(rrf_zpg); |
76 | 99 | O(bra_rel); |
| 100 | O(jmp_zpi); |
77 | 101 | |
78 | 102 | #undef O |
79 | | }; |
80 | 103 | |
81 | | enum { |
82 | | M740_IRQ_LINE = m6502_device::IRQ_LINE, |
83 | | M740_NMI_LINE = m6502_device::NMI_LINE, |
84 | | M740_SET_OVERFLOW = m6502_device::V_LINE, |
| 104 | UINT32 m_irq_multiplex; |
| 105 | UINT16 m_irq_vector; |
| 106 | |
| 107 | void set_irq_line(int line, int state); |
85 | 108 | }; |
86 | 109 | |
87 | 110 | extern const device_type M740; |
trunk/src/emu/cpu/m6502/dm740.lst
r21908 | r21909 | |
1 | 1 | # m740 device |
2 | | brk_imp ora_idx kil_non bbs_acc nop_zpg ora_zpg asl_zpg bbs_bzr php_imp ora_imm asl_acc seb_acc nop_aba ora_aba asl_aba seb_biz |
| 2 | brk740_imp ora_idx kil_non bbs_acc nop_zpg ora_zpg asl_zpg bbs_bzr php_imp ora_imm asl_acc seb_acc nop_aba ora_aba asl_aba seb_biz |
3 | 3 | bpl_rel ora_idy clt_imp bbc_acc nop_zpx ora_zpx asl_zpx bbc_bzr clc_imp ora_aby nop_imp clb_acc nop_abx ora_abx asl_abx clb_biz |
4 | 4 | jsr_adr and_idx jsr_spg bbs_acc bit_zpg and_zpg rol_zpg bbs_bzr plp_imp and_imm rol_acc seb_acc bit_aba and_aba rol_aba seb_biz |
5 | 5 | bmi_rel and_idy set_imp bbc_acc nop_zpx and_zpx rol_zpx bbc_bzr sec_imp and_aby nop_imp clb_acc ldm_imz and_abx rol_abx clb_biz |
r21908 | r21909 | |
10 | 10 | bra_rel sta_idx rrf_zpg bbs_acc sty_zpg sta_zpg stx_zpg bbs_bzr dey_imp nop_imm txa_imp seb_acc sty_aba sta_aba stx_aba seb_biz |
11 | 11 | bcc_rel sta_idy kil_non bbc_acc sty_zpx sta_zpx stx_zpy bbc_bzr tya_imp sta_aby txs_imp clb_acc shy_abx sta_abx shx_aby clb_biz |
12 | 12 | ldy_imm lda_idx ldx_imm bbs_acc ldy_zpg lda_zpg ldx_zpg bbs_bzr tay_imp lda_imm tax_imp seb_acc ldy_aba lda_aba ldx_aba seb_biz |
13 | | bcs_rel lda_idy kil_non bbc_acc ldy_zpx lda_zpx ldx_zpy bbc_bzr clv_imp lda_aby tsx_imp clb_acc ldy_abx lda_abx ldx_aby clb_biz |
| 13 | bcs_rel lda_idy jmp_zpi bbc_acc ldy_zpx lda_zpx ldx_zpy bbc_bzr clv_imp lda_aby tsx_imp clb_acc ldy_abx lda_abx ldx_aby clb_biz |
14 | 14 | cpy_imm cmp_idx nop_imm bbs_acc cpy_zpg cmp_zpg dec_zpg bbs_bzr iny_imp cmp_imm dex_imp seb_acc cpy_aba cmp_aba dec_aba seb_biz |
15 | 15 | bne_rel cmp_idy kil_non bbc_acc nop_zpx cmp_zpx dec_zpx bbc_bzr cld_imp cmp_aby nop_imp clb_acc nop_abx cmp_abx dec_abx clb_biz |
16 | 16 | cpx_imm sbc_idx nop_imm bbs_acc cpx_zpg sbc_zpg inc_zpg bbs_bzr inx_imp sbc_imm nop_imp seb_acc cpx_aba sbc_aba inc_aba seb_biz |
trunk/src/emu/cpu/m6502/om740.lst
r21908 | r21909 | |
102 | 102 | PC += INT8(TMP); |
103 | 103 | prefetch(); |
104 | 104 | |
| 105 | jmp_zpi |
| 106 | TMP2 = read_pc(); |
| 107 | TMP = read(TMP2 & 0xff); |
| 108 | TMP = set_h(TMP, read((TMP2+1) & 0xff)); |
| 109 | PC = TMP; |
| 110 | prefetch(); |
| 111 | |
105 | 112 | reset740 |
106 | 113 | PC = read_direct(0xfffe); |
107 | 114 | PC = set_h(PC, read_direct(0xffff)); |
108 | 115 | prefetch(); |
109 | 116 | inst_state = -1; |
| 117 | |
| 118 | brk740_imp |
| 119 | // The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state) |
| 120 | if(irq_taken) { |
| 121 | read_pc_noinc(); |
| 122 | } else { |
| 123 | read_pc(); |
| 124 | } |
| 125 | write(SP, PC >> 8); |
| 126 | dec_SP(); |
| 127 | write(SP, PC); |
| 128 | dec_SP(); |
| 129 | write(SP, irq_taken ? P & ~F_B : P); |
| 130 | dec_SP(); |
| 131 | if(nmi_state) { |
| 132 | PC = read_direct(0xfffa); |
| 133 | PC = set_h(PC, read_direct(0xfffb)); |
| 134 | nmi_state = false; |
| 135 | standard_irq_callback(NMI_LINE); |
| 136 | } else { |
| 137 | PC = read_direct(m_irq_vector); |
| 138 | PC = set_h(PC, read_direct(m_irq_vector+1)); |
| 139 | if(irq_taken) |
| 140 | standard_irq_callback(IRQ_LINE); |
| 141 | } |
| 142 | irq_taken = false; |
| 143 | P |= F_I; // Do *not* move after the prefetch |
| 144 | prefetch(); |
| 145 | inst_state = -1; |
| 146 | |