z80:Ports:Port01
Basic Info
Port Address: 01
This port reads key presses from the keypad. The keypad is divided into a series of groups.
Writing to Port
$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).
Reading from Port
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).
Key Map:
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) | / | ) | ( | , | x^^2^^ | 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 elsewhere (a "special case" key - after all, it is the ON key). Note: Group EF Key BF (APPS) is called MATRIX on the TI-83.
Comments
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.
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.
Example Uses
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