static BYTE read_ciapb(cia_context_t *cia_context) { BYTE byte; BYTE val = 0xff; BYTE val_outhi = ((cia_context->c_cia[CIA_DDRA]) & (cia_context->c_cia[CIA_DDRB])) & (cia_context->c_cia[CIA_PRB]); BYTE msk = cia_context->old_pa & ~joystick_value[2]; BYTE m; int i; for (m = 0x1, i = 0; i < 8; m <<= 1, i++) { if (!(msk & m)) { val &= ~keyarr[i]; /* 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 pressing either shift-lock or two or more keys of the same column is required to drive port B low, pressing a single key is not enough (and the port will read back as high). (see testprogs/CIA/ciaports) The initial value for val_outhi will drive the respective port B bits high if the above mentioned condition is met, which gives the expected result for single key presses. */ if (ciapb_forcelow(i)) { val_outhi &= ~m; } } } for (m = 0x1, i = 8; i < 11; m <<= 1, i++) { if (!(extended_keyboard_rows_mask & m)) { val &= ~keyarr[i]; /* FIXME: what about the above mentioned case here? */ } } byte = val & (cia_context->c_cia[CIA_PRB] | ~(cia_context->c_cia[CIA_DDRB])); byte |= val_outhi; byte &= ~joystick_value[1]; #ifdef HAVE_MOUSE if (_mouse_enabled && (mouse_port == 1)) { if (mouse_type == MOUSE_TYPE_NEOS) { byte &= neos_mouse_read(); } if (mouse_kind == MOUSE_KIND_POLLED) { byte &= mouse_poll(); } } #endif 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 & 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; }