M740 updates: [R. Belmont]

- Added JMP (zp) instruction
- Working interrupts
- Moved 6502 family V line to make room for up to 16 IRQs
This commit is contained in:
R. Belmont 2013-03-17 14:03:58 +00:00
parent fb25423e7a
commit 4bafebcd59
5 changed files with 141 additions and 16 deletions

View File

@ -1,5 +1,5 @@
# m740 device
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
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
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
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
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
@ -10,7 +10,7 @@ bvs_rel adc_idy kil_non bbc_acc nop_zpx adc_zpx ror_zpx
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
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
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
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
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
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
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
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

View File

@ -49,7 +49,7 @@ public:
IRQ_LINE = INPUT_LINE_IRQ0,
APU_IRQ_LINE = INPUT_LINE_IRQ1,
NMI_LINE = INPUT_LINE_NMI,
V_LINE = 10
V_LINE = INPUT_LINE_IRQ0 + 16
};
m6502_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);

View File

@ -63,6 +63,8 @@ void m740_device::device_reset()
inst_substate = 0;
nmi_state = false;
irq_state = false;
m_irq_multiplex = 0;
m_irq_vector = 0xfffc;
apu_irq_state = false;
irq_taken = false;
v_state = false;
@ -86,7 +88,70 @@ UINT8 m740_device::do_seb(UINT8 in, UINT8 bit)
// doesn't affect the flags
UINT8 m740_device::do_rrf(UINT8 in)
{
return ((in&0xf)<<4) | ((in&0xf0)>>4);
return ((in&0xf)<<4) | ((in&0xf0)>>4);
}
void m740_device::execute_set_input(int inputnum, int state)
{
switch(inputnum)
{
case M740_INT0_LINE:
case M740_INT1_LINE:
case M740_INT2_LINE:
case M740_INT3_LINE:
case M740_INT4_LINE:
case M740_INT5_LINE:
case M740_INT6_LINE:
case M740_INT7_LINE:
case M740_INT8_LINE:
case M740_INT9_LINE:
case M740_INT10_LINE:
case M740_INT11_LINE:
case M740_INT12_LINE:
case M740_INT13_LINE:
case M740_INT14_LINE: // 37450 has 15 IRQ lines, no other known variant has that many
set_irq_line(inputnum - M740_INT0_LINE, state);
break;
case V_LINE:
if(!v_state && state == ASSERT_LINE)
{
P |= F_V;
}
v_state = state == ASSERT_LINE;
break;
}
}
void m740_device::set_irq_line(int line, int state)
{
assert(line > 0);
assert(line <= M740_MAX_INT_LINE);
if (state == ASSERT_LINE)
{
m_irq_multiplex |= (1<<line);
}
else
{
m_irq_multiplex &= ~(1<<line);
}
irq_state = (m_irq_multiplex != 0);
if (irq_state)
{
for (int i = 0; i < M740_MAX_INT_LINE; i++)
{
if (m_irq_multiplex & (1 << i))
{
m_irq_vector = 0xfffc - (UINT16)(2 * i);
break;
}
}
}
// printf("M740 single IRQ state is %d (MPX %08x, vector %x)\n", irq_state, m_irq_multiplex, m_irq_vector);
}
#include "cpu/m6502/m740.inc"

View File

@ -44,16 +44,38 @@
class m740_device : public m6502_device {
public:
m740_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
m740_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
enum
{
M740_INT0_LINE = INPUT_LINE_IRQ0, // (fffc)
M740_INT1_LINE, // (fffa)
M740_INT2_LINE, // (fff8)
M740_INT3_LINE, // (fff6)
M740_INT4_LINE, // (fff4)
M740_INT5_LINE, // (fff2)
M740_INT6_LINE, // (fff0)
M740_INT7_LINE, // (ffee)
M740_INT8_LINE, // (ffec)
M740_INT9_LINE, // (ffea)
M740_INT10_LINE, // (ffe8)
M740_INT11_LINE, // (ffe6)
M740_INT12_LINE, // (ffe4)
M740_INT13_LINE, // (ffe2)
M740_INT14_LINE, // (ffe0)
M740_MAX_INT_LINE = M740_INT14_LINE,
M740_SET_OVERFLOW = m6502_device::V_LINE,
};
virtual void device_reset();
m740_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
m740_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
static const disasm_entry disasm_entries[0x100];
virtual void device_reset();
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
virtual void do_exec_full();
virtual void do_exec_partial();
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);
virtual void do_exec_full();
virtual void do_exec_partial();
virtual void execute_set_input(int inputnum, int state);
protected:
#define O(o) void o ## _full(); void o ## _partial()
@ -63,6 +85,7 @@ protected:
UINT8 do_rrf(UINT8 in);
// m740 opcodes
O(brk740_imp);
O(clt_imp);
O(set_imp);
O(ldm_imz);
@ -74,14 +97,14 @@ protected:
O(bbs_bzr); O(bbs_acc);
O(rrf_zpg);
O(bra_rel);
O(jmp_zpi);
#undef O
};
enum {
M740_IRQ_LINE = m6502_device::IRQ_LINE,
M740_NMI_LINE = m6502_device::NMI_LINE,
M740_SET_OVERFLOW = m6502_device::V_LINE,
UINT32 m_irq_multiplex;
UINT16 m_irq_vector;
void set_irq_line(int line, int state);
};
extern const device_type M740;

View File

@ -102,8 +102,45 @@ bra_rel
PC += INT8(TMP);
prefetch();
jmp_zpi
TMP2 = read_pc();
TMP = read(TMP2 & 0xff);
TMP = set_h(TMP, read((TMP2+1) & 0xff));
PC = TMP;
prefetch();
reset740
PC = read_direct(0xfffe);
PC = set_h(PC, read_direct(0xffff));
prefetch();
inst_state = -1;
brk740_imp
// The 6502 bug when a nmi occurs in a brk is reproduced (case !irq_taken && nmi_state)
if(irq_taken) {
read_pc_noinc();
} else {
read_pc();
}
write(SP, PC >> 8);
dec_SP();
write(SP, PC);
dec_SP();
write(SP, irq_taken ? P & ~F_B : P);
dec_SP();
if(nmi_state) {
PC = read_direct(0xfffa);
PC = set_h(PC, read_direct(0xfffb));
nmi_state = false;
standard_irq_callback(NMI_LINE);
} else {
PC = read_direct(m_irq_vector);
PC = set_h(PC, read_direct(m_irq_vector+1));
if(irq_taken)
standard_irq_callback(IRQ_LINE);
}
irq_taken = false;
P |= F_I; // Do *not* move after the prefetch
prefetch();
inst_state = -1;