/***************************************************************************** ** apple1_kbd_poll ** ** Keyboard polling handles both ordinary keys and the special RESET ** and CLEAR SCREEN switches. ** ** For ordinary keys, this implements 2-key rollover to reduce the ** chance of missed keypresses. If we press a key and then press a ** second key while the first hasn't been completely released, as ** might happen during rapid typing, only the second key is ** registered; the first key is ignored. ** ** If multiple newly-pressed keys are found, the one closest to the ** end of the input ports list is counted; the others are ignored. *****************************************************************************/ static void apple1_kbd_poll(int dummy) { int port, bit; int key_pressed; UINT32 shiftkeys, ctrlkeys; /* This holds the values of all the input ports for ordinary keys seen during the last scan. */ static UINT32 kbd_last_scan[] = { 0, 0, 0, 0 }; static int reset_flag = 0; /* First we check the RESET and CLEAR SCREEN pushbutton switches. */ /* The RESET switch resets the CPU and the 6820 PIA. */ if (readinputport(5) & 0x0001) { if (!reset_flag) { reset_flag = 1; /* using PULSE_LINE does not allow us to press and hold key */ cpunum_set_input_line(0, INPUT_LINE_RESET, ASSERT_LINE); pia_reset(); } } else if (reset_flag) { /* RESET released--allow the processor to continue. */ reset_flag = 0; cpunum_set_input_line(0, INPUT_LINE_RESET, CLEAR_LINE); } /* The CLEAR SCREEN switch clears the video hardware. */ if (readinputport(5) & 0x0002) { if (!apple1_vh_clrscrn_pressed) { /* Ignore further video writes, and clear the screen. */ apple1_vh_clrscrn_pressed = 1; apple1_vh_dsp_clr(); } } else if (apple1_vh_clrscrn_pressed) { /* CLEAR SCREEN released--pay attention to video writes again. */ apple1_vh_clrscrn_pressed = 0; } /* Now we scan all the input ports for ordinary keys, recording new keypresses while ignoring keys that were already pressed in the last scan. */ apple1_kbd_data = 0; key_pressed = 0; /* The keyboard strobe line should always be low when a scan starts. */ pia_set_input_ca1(0, 0); shiftkeys = readinputport(4) & 0x0003; ctrlkeys = readinputport(4) & 0x000c; for (port = 0; port < 4; port++) { UINT32 portval = readinputport(port); UINT32 newkeys = portval & ~(kbd_last_scan[port]); if (newkeys) { key_pressed = 1; for (bit = 0; bit < 16; bit++) { if (newkeys & 1) { apple1_kbd_data = (ctrlkeys) ? apple1_control_keymap[port*16 + bit] : (shiftkeys) ? apple1_shifted_keymap[port*16 + bit] : apple1_unshifted_keymap[port*16 + bit]; } newkeys >>= 1; } } kbd_last_scan[port] = portval; } if (key_pressed) { /* The keyboard will pulse its strobe line when a key is pressed. A 10-usec pulse is typical. */ pia_set_input_ca1(0, 1); timer_set(TIME_IN_USEC(10), 0, apple1_kbd_strobe_end); } }
/***************************************************************************** ** apple1_kbd_poll ** ** Keyboard polling handles both ordinary keys and the special RESET ** and CLEAR SCREEN switches. ** ** For ordinary keys, this implements 2-key rollover to reduce the ** chance of missed keypresses. If we press a key and then press a ** second key while the first hasn't been completely released, as ** might happen during rapid typing, only the second key is ** registered; the first key is ignored. ** ** If multiple newly-pressed keys are found, the one closest to the ** end of the input ports list is counted; the others are ignored. *****************************************************************************/ static TIMER_CALLBACK(apple1_kbd_poll) { apple1_state *state = machine.driver_data<apple1_state>(); int port, bit; int key_pressed; UINT32 shiftkeys, ctrlkeys; pia6821_device *pia = machine.device<pia6821_device>("pia"); static const char *const keynames[] = { "KEY0", "KEY1", "KEY2", "KEY3" }; /* This holds the values of all the input ports for ordinary keys seen during the last scan. */ /* First we check the RESET and CLEAR SCREEN pushbutton switches. */ /* The RESET switch resets the CPU and the 6820 PIA. */ if (input_port_read(machine, "KEY5") & 0x0001) { if (!state->m_reset_flag) { state->m_reset_flag = 1; /* using PULSE_LINE does not allow us to press and hold key */ cputag_set_input_line(machine, "maincpu", INPUT_LINE_RESET, ASSERT_LINE); pia->reset(); } } else if (state->m_reset_flag) { /* RESET released--allow the processor to continue. */ state->m_reset_flag = 0; cputag_set_input_line(machine, "maincpu", INPUT_LINE_RESET, CLEAR_LINE); } /* The CLEAR SCREEN switch clears the video hardware. */ if (input_port_read(machine, "KEY5") & 0x0002) { if (!state->m_vh_clrscrn_pressed) { /* Ignore further video writes, and clear the screen. */ state->m_vh_clrscrn_pressed = 1; apple1_vh_dsp_clr(machine); } } else if (state->m_vh_clrscrn_pressed) { /* CLEAR SCREEN released--pay attention to video writes again. */ state->m_vh_clrscrn_pressed = 0; } /* Now we scan all the input ports for ordinary keys, recording new keypresses while ignoring keys that were already pressed in the last scan. */ state->m_kbd_data = 0; key_pressed = 0; /* The keyboard strobe line should always be low when a scan starts. */ pia->ca1_w(0); shiftkeys = input_port_read(machine, "KEY4") & 0x0003; ctrlkeys = input_port_read(machine, "KEY4") & 0x000c; for (port = 0; port < 4; port++) { UINT32 portval, newkeys; portval = input_port_read(machine, keynames[port]); newkeys = portval & ~(state->m_kbd_last_scan[port]); if (newkeys) { key_pressed = 1; for (bit = 0; bit < 16; bit++) { if (newkeys & 1) { state->m_kbd_data = (ctrlkeys) ? apple1_control_keymap[port*16 + bit] : (shiftkeys) ? apple1_shifted_keymap[port*16 + bit] : apple1_unshifted_keymap[port*16 + bit]; } newkeys >>= 1; } } state->m_kbd_last_scan[port] = portval; } if (key_pressed) { /* The keyboard will pulse its strobe line when a key is pressed. A 10-usec pulse is typical. */ pia->ca1_w(1); machine.scheduler().timer_set(attotime::from_usec(10), FUNC(apple1_kbd_strobe_end)); } }
void apple1_state::machine_reset() { /* Reset the display hardware. */ apple1_vh_dsp_clr(machine()); }