Beispiel #1
0
void viacore_signal(via_context_t *via_context, int line, int edge)
{
    switch (line) {
        case VIA_SIG_CA1:
            if ((edge ? 1 : 0) == (via_context->via[VIA_PCR] & 0x01)) {
                if (IS_CA2_TOGGLE_MODE() && !(via_context->ca2_state)) {
                    via_context->ca2_state = 1;
                    (via_context->set_ca2)(via_context, via_context->ca2_state);
                }
                via_context->ifr |= VIA_IM_CA1;
                update_myviairq(via_context);
#ifdef MYVIA_NEED_LATCHING
                if (IS_PA_INPUT_LATCH()) {
                    via_context->ila = (via_context->read_pra)(via_context, addr);
                }
#endif
            }
            break;
        case VIA_SIG_CA2:
            if (!(via_context->via[VIA_PCR] & 0x08)) {
                via_context->ifr |= (((edge << 2)
                                    ^ via_context->via[VIA_PCR]) & 0x04) ?
                                    0 : VIA_IM_CA2;
                update_myviairq(via_context);
            }
            break;
        case VIA_SIG_CB1:
            if ((edge ? 0x10 : 0) == (via_context->via[VIA_PCR] & 0x10)) {
                if (IS_CB2_TOGGLE_MODE() && !(via_context->cb2_state)) {
                    via_context->cb2_state = 1;
                    (via_context->set_cb2)(via_context, via_context->cb2_state);
                }
                via_context->ifr |= VIA_IM_CB1;
                update_myviairq(via_context);
#ifdef MYVIA_NEED_LATCHING
                if (IS_PB_INPUT_LATCH()) {
                    via_context->ilb = (via_context->read_prb)(via_context);
                }
#endif
            }
            break;
        case VIA_SIG_CB2:
            if (!(via_context->via[VIA_PCR] & 0x80)) {
                via_context->ifr |= (((edge << 6)
                                    ^ via_context->via[VIA_PCR]) & 0x40) ?
                                    0 : VIA_IM_CB2;
                update_myviairq(via_context);
            }
            break;
    }
}
Beispiel #2
0
BYTE viacore_read_(via_context_t *via_context, WORD addr)
{
#endif
    BYTE byte = 0xff;
    CLOCK rclk;

    addr &= 0xf;

    via_context->read_clk = *(via_context->clk_ptr);
    via_context->read_offset = 0;
    rclk = *(via_context->clk_ptr);

    if (addr >= VIA_T1CL && addr <= VIA_IER) {
        if (via_context->tai && (via_context->tai < *(via_context->clk_ptr)))
            viacore_intt1(*(via_context->clk_ptr) - via_context->tai,
                          (void *)via_context);
        if (via_context->tbi && (via_context->tbi < *(via_context->clk_ptr)))
            viacore_intt2(*(via_context->clk_ptr) - via_context->tbi,
                          (void *)via_context);
    }

    switch (addr) {

      case VIA_PRA:             /* port A */
        via_context->ifr &= ~VIA_IM_CA1;
        if ((via_context->via[VIA_PCR] & 0x0a) != 0x02) {
            via_context->ifr &= ~VIA_IM_CA2;
        }
        if (IS_CA2_HANDSHAKE()) {
            via_context->ca2_state = 0;
            (via_context->set_ca2)(via_context, via_context->ca2_state);
            if (IS_CA2_PULSE_MODE()) {
                via_context->ca2_state = 1;
                (via_context->set_ca2)(via_context, via_context->ca2_state);
            }
        }
        if (via_context->ier & (VIA_IM_CA1 | VIA_IM_CA2))
            update_myviairq(via_context);

      case VIA_PRA_NHS: /* port A, no handshake */
        /* WARNING: this pin reads the voltage of the output pins, not
           the ORA value as the other port. Value read might be different
           from what is expected due to excessive load. */
#ifdef MYVIA_NEED_LATCHING
        if (IS_PA_INPUT_LATCH()) {
            byte = via_context->ila;
        } else {
            byte = (via_context->read_pra)(via_context, addr);
        }
#else
        byte = (via_context->read_pra)(via_context, addr);
#endif
        via_context->ila = byte;
        via_context->last_read = byte;
        return byte;

      case VIA_PRB:             /* port B */
        via_context->ifr &= ~VIA_IM_CB1;
        if ((via_context->via[VIA_PCR] & 0xa0) != 0x20)
            via_context->ifr &= ~VIA_IM_CB2;
        if (via_context->ier & (VIA_IM_CB1 | VIA_IM_CB2))
            update_myviairq(via_context);

        /* WARNING: this pin reads the ORA for output pins, not
           the voltage on the pins as the other port. */
#ifdef MYVIA_NEED_LATCHING
        if (IS_PB_INPUT_LATCH()) {
            byte = via_context->ilb;
        } else {
            byte = (via_context->read_prb)(via_context);
        }
#else
        byte = (via_context->read_prb)(via_context);
#endif
        via_context->ilb = byte;
        byte = (byte & ~(via_context->via[VIA_DDRB]))
               | (via_context->via[VIA_PRB] & via_context->via[VIA_DDRB]);

        if (via_context->via[VIA_ACR] & 0x80) {
            update_myviatal(via_context, rclk);
            byte = (byte & 0x7f)
                   | (((via_context->pb7 ^ via_context->pb7x)
                   | via_context->pb7o) ? 0x80 : 0);
        }
        via_context->last_read = byte;
        return byte;

        /* Timers */

      case VIA_T1CL /*TIMER_AL */ :     /* timer A low */
        via_context->ifr &= ~VIA_IM_T1;
        update_myviairq(via_context);
        via_context->last_read = (BYTE)(myviata(via_context) & 0xff);
        return via_context->last_read;

      case VIA_T1CH /*TIMER_AH */ :     /* timer A high */
        via_context->last_read = (BYTE)((myviata(via_context) >> 8) & 0xff);
        return via_context->last_read;

      case VIA_T2CL /*TIMER_BL */ :     /* timer B low */
        via_context->ifr &= ~VIA_IM_T2;
        update_myviairq(via_context);
        via_context->last_read = (BYTE)(myviatb(via_context) & 0xff);
        return via_context->last_read;

      case VIA_T2CH /*TIMER_BH */ :     /* timer B high */
        via_context->last_read = (BYTE)((myviatb(via_context) >> 8) & 0xff);
        return via_context->last_read;

      case VIA_SR:              /* Serial Port Shift Register */
        via_context->last_read = via_context->via[addr];
        return via_context->last_read;

        /* Interrupts */

      case VIA_IFR:             /* Interrupt Flag Register */
        {
            BYTE t = via_context->ifr;
            if (via_context->ifr & via_context->ier /*[VIA_IER] */ )
                t |= 0x80;
            via_context->last_read = t;
            return (t);
        }

      case VIA_IER:             /* 6522 Interrupt Control Register */
        via_context->last_read = (via_context->ier /*[VIA_IER] */  | 0x80);
        return via_context->last_read;

    }                           /* switch */

    via_context->last_read = via_context->via[addr];

    return via_context->via[addr];
}