Difference between revisions of "83Plus:Ports:01"
(→Comments) |
|||
Line 54: | Line 54: | ||
* '''Note:''' Group FB Key FE is NEGATE, not to be confused with SUBTRACT. | * '''Note:''' Group FB Key FE is NEGATE, not to be confused with SUBTRACT. | ||
− | * '''Note:''' Group DF Key FE would be ON, but the ON key is tested | + | * '''Note:''' Group DF Key FE would be ON, but the ON key is tested through [[83Plus:Ports:04|Port 04]], bit 3. |
* '''Note:''' Group EF Key BF (APPS) is called MATRIX on the TI-83. | * '''Note:''' Group EF Key BF (APPS) is called MATRIX on the TI-83. | ||
== Comments == | == Comments == | ||
− | |||
− | |||
You should disable interrupts or use a custom interrupt before manually reading this port, because TI's interrupt scans the keypad. If you leave TI's interrupt active when manually reading the keypad, sometimes it will fire between when you set and read the port, and you'll read garbage. | You should disable interrupts or use a custom interrupt before manually reading this port, because TI's interrupt scans the keypad. If you leave TI's interrupt active when manually reading the keypad, sometimes it will fire between when you set and read the port, and you'll read garbage. | ||
+ | |||
+ | All nonexistent keys read 1. | ||
+ | |||
+ | === Delay === | ||
+ | TI's code always resets the keypad before scanning; sometimes, you may get incorrect values if you scan without resetting first. | ||
Traditionally, a delay of a dozen or so clock cycles (6 MHz mode) is used between changing key groups and reading the result. The required delay seems to vary depending on the calculator; some require no delay, others a longer one. The delay is based on real time, not CPU clock cycles; you'll need to make your delay about 3 times longer in 15 MHz mode. However, as in the example, other people seem to find that resetting before every group change negates the need for a delay; some more experimentation is required. | Traditionally, a delay of a dozen or so clock cycles (6 MHz mode) is used between changing key groups and reading the result. The required delay seems to vary depending on the calculator; some require no delay, others a longer one. The delay is based on real time, not CPU clock cycles; you'll need to make your delay about 3 times longer in 15 MHz mode. However, as in the example, other people seem to find that resetting before every group change negates the need for a delay; some more experimentation is required. | ||
Line 78: | Line 81: | ||
ex (sp),hl | ex (sp),hl | ||
in a,(1)</pre> | in a,(1)</pre> | ||
+ | |||
+ | The reason for this has since been discovered to not be caused by slow hardware, but rather by capacitance in the keypad. When unselecting a group, it takes a while before the charge has dissipated. Resetting the keypad every time after using it will make this discharge happen while you're doing something else, and activating a group happens instantly. The number of pressed keys and the number of groups being deactivated plays a role in the time the discharge takes, but generally, 7 clock cycles should be enough. However, this may vary from keypad to keypad. | ||
+ | |||
+ | === Ghosting === | ||
+ | Because TI didn't add a diode to each key, you can also detect keys that aren't in a currently selected keygroup, as long as the other keygroup has at least one key in common with a selected keygroup. This means, for example, if F7 is selected, and the keys 2, 3, and 6 are pressed, Then keygroup FB will also be activated because F7 and FB have one key in common (namely FD). This makes it appear as though the 5 key is also pressed. This can also be used to make nonexistent keys appear active. However, as at least three keys have to be pressed for it to be noticeable, you don't have to worry in the most common use cases. | ||
+ | |||
+ | === Debouncing === | ||
+ | While a key is in a state between pressed and released, it will repeatedly turn on and off. If you are reading the keypad extremely quickly, it will appear as though the key is being pressed and released a number of times. You need to either wait longer between keypad scans, or you need to implement a proper debouncing algorithm. TI-OS does the first one by scanning the keypad in an interrupt that runs slowly enough for it to not have a noticeable effect. | ||
== Example == | == Example == |
Revision as of 16:37, 3 March 2020
Contents
Synopsis
Port Number: 01h
Function: Keyboard Port
This port reads key presses from the keypad. The keypad is divided into a series of groups.
Read Values
- Bits are set according whether corresponding keys from selected groups are pressed. Groups are selected through writing to the port. A pressed key reads a 0 bit. An unpressed key reads a 1 bit. The port reads FF after a reset (write FF).
Write Values
- $FF : Reset the keypad. This unselects all groups and resets the keypad state.
- Anything else : Any 0 bit adds the corresponding group to the list of monitored groups. When a key in a monitored group is pressed, the corresponding key bit reads 0, otherwise it reads 1 (active-low).
Key Map
The key map is laid out as follows:
Group Bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
---|---|---|---|---|---|---|---|---|---|---|
Group Mask | FE | FD | FB | F7 | EF | DF | BF | 7F | ||
Key Bit | (Mask) | |||||||||
0 | (FE) | DOWN | ENTER | (-) | . | 0 | GRAPH | |||
1 | (FD) | LEFT | + | 3 | 2 | 1 | STO | TRACE | ||
2 | (FB) | RIGHT | - | 6 | 5 | 4 | LN | ZOOM | ||
3 | (F7) | UP | * | 9 | 8 | 7 | LOG | WIND | ||
4 | (EF) | / | ) | ( | , | x2 | Y= | |||
5 | (DF) | ^ | TAN | COS | SIN | x-1 | 2nd | |||
6 | (BF) | CLEAR | VARS | PRGM | APPS | MATH | MODE | |||
7 | (7F) | STAT | X,T,θ,n | ALPHA | DEL |
- Note: Group FB Key FE is NEGATE, not to be confused with SUBTRACT.
- Note: Group DF Key FE would be ON, but the ON key is tested through Port 04, bit 3.
- Note: Group EF Key BF (APPS) is called MATRIX on the TI-83.
Comments
You should disable interrupts or use a custom interrupt before manually reading this port, because TI's interrupt scans the keypad. If you leave TI's interrupt active when manually reading the keypad, sometimes it will fire between when you set and read the port, and you'll read garbage.
All nonexistent keys read 1.
Delay
TI's code always resets the keypad before scanning; sometimes, you may get incorrect values if you scan without resetting first.
Traditionally, a delay of a dozen or so clock cycles (6 MHz mode) is used between changing key groups and reading the result. The required delay seems to vary depending on the calculator; some require no delay, others a longer one. The delay is based on real time, not CPU clock cycles; you'll need to make your delay about 3 times longer in 15 MHz mode. However, as in the example, other people seem to find that resetting before every group change negates the need for a delay; some more experimentation is required.
For me (Sorunome) this didn't seem to work: Using the following code didn't always have the correct keygroup selected when scanning (on a TI-84+SE of a friend of mine):
ld a,$ff out (1),a ld a,%10111110 out (1),a in a,(1)
While the following fixed it:
ld a,$ff out (1),a ld a,%10111110 out (1),a ex (sp),hl ex (sp),hl in a,(1)
The reason for this has since been discovered to not be caused by slow hardware, but rather by capacitance in the keypad. When unselecting a group, it takes a while before the charge has dissipated. Resetting the keypad every time after using it will make this discharge happen while you're doing something else, and activating a group happens instantly. The number of pressed keys and the number of groups being deactivated plays a role in the time the discharge takes, but generally, 7 clock cycles should be enough. However, this may vary from keypad to keypad.
Ghosting
Because TI didn't add a diode to each key, you can also detect keys that aren't in a currently selected keygroup, as long as the other keygroup has at least one key in common with a selected keygroup. This means, for example, if F7 is selected, and the keys 2, 3, and 6 are pressed, Then keygroup FB will also be activated because F7 and FB have one key in common (namely FD). This makes it appear as though the 5 key is also pressed. This can also be used to make nonexistent keys appear active. However, as at least three keys have to be pressed for it to be noticeable, you don't have to worry in the most common use cases.
Debouncing
While a key is in a state between pressed and released, it will repeatedly turn on and off. If you are reading the keypad extremely quickly, it will appear as though the key is being pressed and released a number of times. You need to either wait longer between keypad scans, or you need to implement a proper debouncing algorithm. TI-OS does the first one by scanning the keypad in an interrupt that runs slowly enough for it to not have a noticeable effect.
Example
ld a, 0FFh ;Reset the keypad. out (1), a ld a, 0FEh ;Select group 0. out (1), a in a, (1) ;Test for keys. and 2 ;Test for Left Arrow key by making A 0 if left was pressed. call z, LeftArrowPressed ;If 0 then left was pressed. ld a, 0FFh ;Reset the keypad. out (1), a