Beispiel #1
0
/* Return nonzero if a pending NMI should be dispatched now.  This takes
   account for the internal delays of the 6510, but does not actually check
   the status of the NMI line.  */
inline static int interrupt_check_nmi_delay(interrupt_cpu_status_t *cs,
                                            CLOCK cpu_clk)
{
    CLOCK nmi_clk = cs->nmi_clk + INTERRUPT_DELAY;

    /* BRK (0x00) delays the NMI by one opcode.  */
    /* TODO DO_INTERRUPT sets last opcode to 0: can NMI occur right after IRQ? */
    if (OPINFO_NUMBER(*cs->last_opcode_info_ptr) == 0x00) {
        return 0;
    }

    /* Branch instructions delay IRQs and NMI by one cycle if branch
       is taken with no page boundary crossing.  */
    if (OPINFO_DELAYS_INTERRUPT(*cs->last_opcode_info_ptr)) {
        nmi_clk++;
    }

    if (cpu_clk >= nmi_clk) {
        return 1;
    }

    return 0;
}
Beispiel #2
0
/* Handle matrix fetch events.  FIXME: could be made slightly faster.  */
void ted_fetch_alarm_handler(CLOCK offset, void *data)
{
    CLOCK last_opcode_first_write_clk, last_opcode_last_write_clk;

    /* This kludgy thing is used to emulate the behavior of the 6510 when BA
       goes low.  When BA goes low, every read access stops the processor
       until BA is high again; write accesses happen as usual instead.  */

    if (offset > 0) {
        switch (OPINFO_NUMBER(last_opcode_info)) {
            case 0:
                /* In BRK, IRQ and NMI the 3rd, 4th and 5th cycles are write
                   accesses, while the 1st, 2nd, 6th and 7th are read accesses.  */
                last_opcode_first_write_clk = maincpu_clk - 10;
                last_opcode_last_write_clk = maincpu_clk - 6;
                break;

            case 0x20:
                /* In JSR, the 4th and 5th cycles are write accesses, while the
                   1st, 2nd, 3rd and 6th are read accesses.  */
                last_opcode_first_write_clk = maincpu_clk - 6;
                last_opcode_last_write_clk = maincpu_clk - 4;
                break;

            default:
                /* In all the other opcodes, all the write accesses are the last
                   ones.  */
                if (maincpu_num_write_cycles() != 0) {
                    last_opcode_last_write_clk = maincpu_clk - 2;
                    last_opcode_first_write_clk = maincpu_clk
                                                  - maincpu_num_write_cycles() * 2;
                } else {
                    last_opcode_first_write_clk = (CLOCK)0;
                    last_opcode_last_write_clk = last_opcode_first_write_clk;
                }
                break;
        }
    } else { /* offset <= 0, i.e. offset == 0 */
        /* If we are called with no offset, we don't have to care about write
           accesses.  */
        last_opcode_first_write_clk = last_opcode_last_write_clk = 0;
    }

    {
        CLOCK sub;
        CLOCK write_offset;

        if (ted.fetch_clk < (last_opcode_first_write_clk - 1)
            || ted.fetch_clk > last_opcode_last_write_clk) {
            sub = 0;
        } else {
            sub = last_opcode_last_write_clk - ted.fetch_clk + 1;
        }

        handle_fetch_matrix(offset, sub, &write_offset);
        last_opcode_first_write_clk += write_offset;
        last_opcode_last_write_clk += write_offset;
    }
    if ((offset > 11) && (ted.fastmode)) {
        dma_maincpu_steal_cycles(ted.fetch_clk, -(((signed)offset - 11) / 2), 0);
        ted_delay_oldclk(-(((signed)offset - 11) / 2));
    }
}