Example #1
0
static BYTE read_ciapb(cia_context_t *cia_context)
{
    BYTE byte;
    BYTE val = 0xff;
    BYTE val_outhi;
    BYTE msk, tmp;
    BYTE m;
    int i;

    /* loop over rows,
       pull down all bits connected to a row which is output and active.
     */
    val_outhi = (cia_context->c_cia[CIA_DDRB]) & (cia_context->c_cia[CIA_PRB]);

    DBGB(("PB val_outhi:%02x ddra:%02x pa:%02x ddrb:%02x pb:%02x ", val_outhi,
          cia_context->c_cia[CIA_DDRA], cia_context->c_cia[CIA_PRA],
          cia_context->c_cia[CIA_DDRB], cia_context->c_cia[CIA_PRB]));

    msk = cia_context->old_pa & read_joyport_dig(JOYPORT_2);
    if (c64keyboard_active) {
        for (m = 0x1, i = 0; i < 8; m <<= 1, i++) {
            if (!(msk & m)) {
                tmp = matrix_get_active_columns_by_row(i);
                val &= ~tmp;

                /*
                    Handle the special case when both port A and port B are programmed as output,
                    port A outputs (active) low, and port B outputs high.

                    In this case either connecting one port A 0 bit (by pressing either shift-lock)
                    or two or more port A 0 bits (by pressing keys of the same column) to one port B
                    bit is required to drive port B low (see testprogs/CIA/ciaports)
                */
                if ((cia_context->c_cia[CIA_DDRA] & ~cia_context->c_cia[CIA_PRA] & m) &&
                    (cia_context->c_cia[CIA_DDRB] & cia_context->c_cia[CIA_PRB] & tmp)) {
                    DBGB(("(%d)", i));
                    if (ciapb_forcelow(i, (BYTE)(cia_context->c_cia[CIA_DDRA] & ~cia_context->c_cia[CIA_PRA]))) {
                        val_outhi &= ~tmp;
                        DBGB(("<force low, val_outhi:%02x>", val_outhi));
                    }
                }
            }
        }
    }
    DBGB((" val:%02x val_outhi:%02x", val, val_outhi));

    /* loop over columns,
       pull down all bits connected to a column which is output and active.
       handles the case when port b is used for both input and output
     */
    msk = cia_context->old_pb & read_joyport_dig(JOYPORT_1);
    if (c64keyboard_active) {
        for (m = 0x1, i = 0; i < 8; m <<= 1, i++) {
            if (!(msk & m)) {
                val &= ~matrix_get_active_columns_by_column(i);
            }
        }
    }
    DBGB((" val:%02x", val));

    byte = val & (cia_context->c_cia[CIA_PRB] | ~(cia_context->c_cia[CIA_DDRB]));
    byte |= val_outhi;
    byte &= read_joyport_dig(JOYPORT_1);

    DBGB((" out:%02x\n", byte));

    return byte;
}
Example #2
0
static BYTE read_ciapb(cia_context_t *cia_context)
{
    BYTE byte;
    BYTE val = 0xff;
    BYTE val_outhi;
    BYTE msk, tmp;
    BYTE m;
    int i;

    /* loop over rows,
       pull down all bits connected to a row which is output and active.
     */
    val_outhi = (cia_context->c_cia[CIA_DDRB]) & (cia_context->c_cia[CIA_PRB]);

    DBGB(("PB val_outhi:%02x ddra:%02x pa:%02x ddrb:%02x pb:%02x ", val_outhi,
          cia_context->c_cia[CIA_DDRA], cia_context->c_cia[CIA_PRA],
          cia_context->c_cia[CIA_DDRB], cia_context->c_cia[CIA_PRB]));

    msk = cia_context->old_pa & ~joystick_value[2];
    for (m = 0x1, i = 0; i < 8; m <<= 1, i++) {
        if (!(msk & m)) {
            tmp = matrix_get_active_columns_by_row(i);
            val &= ~tmp;

            /*
                Handle the special case when both port A and port B are programmed as output,
                port A outputs (active) low, and port B outputs high.

                In this case either connecting one port A 0 bit (by pressing either shift-lock)
                or two or more port A 0 bits (by pressing keys of the same column) to one port B
                bit is required to drive port B low (see testprogs/CIA/ciaports)
            */
            if ((cia_context->c_cia[CIA_DDRA] & ~cia_context->c_cia[CIA_PRA] & m) &&
                (cia_context->c_cia[CIA_DDRB] & cia_context->c_cia[CIA_PRB] & tmp)) {
                DBGB(("(%d)", i));
                if (ciapb_forcelow(i, (BYTE)(cia_context->c_cia[CIA_DDRA] & ~cia_context->c_cia[CIA_PRA]))) {
                    val_outhi &= ~tmp;
                    DBGB(("<force low, val_outhi:%02x>", val_outhi));
                }
            }
        }
    }
    DBGB((" val:%02x val_outhi:%02x", val, val_outhi));

    /* loop over columns,
       pull down all bits connected to a column which is output and active.
       handles the case when port b is used for both input and output
     */
    msk = cia_context->old_pb & ~joystick_value[1];
    for (m = 0x1, i = 0; i < 8; m <<= 1, i++) {
        if (!(msk & m)) {
            val &= ~matrix_get_active_columns_by_column(i);
        }
    }
    DBGB((" val:%02x", val));

    byte = val & (cia_context->c_cia[CIA_PRB] | ~(cia_context->c_cia[CIA_DDRB]));
    byte |= val_outhi;
    byte &= ~joystick_value[1];

    DBGB((" out:%02x\n", byte));

#ifdef HAVE_MOUSE
    if (_mouse_enabled && (mouse_port == 1)) {
        switch (mouse_type) {
        case MOUSE_TYPE_NEOS:
            byte &= neos_mouse_read();
            break;
        case MOUSE_TYPE_SMART:
            byte &= smart_mouse_read();
            break;
        case MOUSE_TYPE_ST:
        case MOUSE_TYPE_AMIGA:
        case MOUSE_TYPE_CX22:
            byte &= mouse_poll();
            break;
        case MOUSE_TYPE_MICROMYS:
            byte &= micromys_mouse_read();
            break;
        default:
            break;
        }
    }
#endif

    return byte;
}