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; }
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; }