-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathchapter-next-keyboard.tex
125 lines (93 loc) · 6.98 KB
/
chapter-next-keyboard.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
\section{Keyboard}
\label{zx_next_keyboard}
% ───────────────────────────────────────────────────────────────────
% ─██████──████████─██████████████─████████──████████─██████████████─
% ─██░░██──██░░░░██─██░░░░░░░░░░██─██░░░░██──██░░░░██─██░░░░░░░░░░██─
% ─██░░██──██░░████─██░░██████████─████░░██──██░░████─██░░██████████─
% ─██░░██──██░░██───██░░██───────────██░░░░██░░░░██───██░░██─────────
% ─██░░██████░░██───██░░██████████───████░░░░░░████───██░░██████████─
% ─██░░░░░░░░░░██───██░░░░░░░░░░██─────████░░████─────██░░░░░░░░░░██─
% ─██░░██████░░██───██░░██████████───────██░░██───────██████████░░██─
% ─██░░██──██░░██───██░░██───────────────██░░██───────────────██░░██─
% ─██░░██──██░░████─██░░██████████───────██░░██───────██████████░░██─
% ─██░░██──██░░░░██─██░░░░░░░░░░██───────██░░██───────██░░░░░░░░░░██─
% ─██████──████████─██████████████───────██████───────██████████████─
% ───────────────────────────────────────────────────────────────────
Next inherits ZX Spectrum keyboard handling, so all legacy programs will work out of the box. Additionally, it allows reading the status of extended keys.
\subsection{Legacy Keyboard Status}
ZX Spectrum uses 8$\times$5 matrix for reading keyboard status. This means 40 distinct keys can be represented. The keyboard is read from \PortTextXRef{xxFE} with particular high bytes. There are 8 possible bytes, each will return the status of 5 associated keys. If a key is pressed, the corresponding bit is set to {\tt 0} and vice versa.
Example for checking if {\tt P} or {\tt I} is pressed:
\begin{tcblisting}{}
LD BC, &DFFE ; We want to read keys..... YUIOP
IN A, (C) ; A holds values in bits... 43210
checkP:
BIT 0, A ; test bit 0 of A (P key)
JR NZ checkI ; if bit0=1, P not pressed
... ; P is pressed
checkI:
BIT 2, A ; test bit 2 of A (I key)
JR NZ continue ; if bit2=1, I not pressed
... ; I is pressed
continue:
\end{tcblisting}
As mentioned in Ports chapter, section \XRef{zx_next_ports_examples}, we can slightly improve performance if we replace first two lines with:
\begin{tcblisting}{}
LD A, &DF
IN (&FE)
\end{tcblisting}
Reading the port in first example requires 22 t-states (10+12) vs. 18 (7+11). The difference is small, but it can add up as typically keyboard is read multiple times per frame.
The first program is more understandable at a glance - the port address is given as a whole 16-bit value, as usually provided in the documentation. The second program splits it into 2 8-bit values, so intent may not be immediately apparent. Of course, one learns the patterns with experience, but it nonetheless demonstrates the compromise between readability and speed.
\subsection{Next Extended Keys}
% note: we only show page number after last port xref since both are declared on the same page, but if this changes in the future, we should update this text accordingly
Next uses larger 8$\times$7 matrix for keyboard, with 10 additional keys. By default, hardware is translating keys from extra two columns into the existing 8$\times$5 set. But you can turn this off with bit {\tt 4} of \PortTextXRef{68}. Extra keys can be read separately via \PortTextXRef[]{B0} and \PortTextXRef[]{B1}, details on page \PortPage{B0}.
\subsection{Keyboard Ports and Registers}
\label{zx_next_keyboard_registers}
\subsubsection{\PortDeclaration{xxFE}}
\vspace*{-1em} % for some reason LaTeX adds some unwanted vertical space between title and text!?
Returns keyboard status when read with certain high byte values:
{
\tt
\setlength{\extrarowheight}{0pt}
\def\arraystretch{0.1}
\begin{tabular}{p{0.7cm}|cp{1cm}p{1cm}p{1cm}p{1.3cm}p{1.5cm}}
~xx & & 4 & 3 & 2 & 1 & 0 \instrb \\
\hline
\MemAddr{7F}\instrt & & B & N & M & Symb & Space \\
\MemAddr{BF}\instrt & & H & J & K & L & Enter \\
\MemAddr{DF}\instrt & & Y & U & I & O & P \\
\MemAddr{EF}\instrt & & 6 & 7 & 8 & 9 & 0 \\
\MemAddr{F7}\instrt & & 5 & 4 & 3 & 2 & 1 \\
\MemAddr{FB}\instrt & & T & R & E & W & Q \\
\MemAddr{FD}\instrt & & G & F & D & S & A \\
\MemAddr{FE}\instrt\instrb & & V & C & X & Z & Caps \\
\end{tabular}
}
Bits are reversed: if a key is pressed, the corresponding bit is {\tt 0}, if a key is not pressed, bit is {\tt 1}.
% note: we don't show page next to port since we use more verbose link to the section+page afterwards
Note: when written to, \PortTextXRef[]{xxFEWrite} is used to set border colour and audio devices. See ULA Layer, section \PortXRef{xxFEWrite} for details.
\subsubsection{\PortTextXRef[]{68}}
\PortDeclarationXRef{Tilemap}{68}
\subsubsection{\PortDeclaration{B0}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{B1}}
\newcommand{\PortNextExtKey}[2]{{\tt 0} if key pressed, {\tt 1} otherwise & {\tt #1} & {\tt #2} \\ }
\begin{NextPort}[cp{5.5cm}p{1.5cm}X][Bit & Effect & \MemAddr{B0} & \MemAddr{B1}]
\PortBits{7}
\PortNextExtKey{;}{Delete}
\PortBits{6}
\PortNextExtKey{"}{Edit}
\PortBits{5}
\PortNextExtKey{,}{Break}
\PortBits{4}
\PortNextExtKey{.}{Inv Video}
\PortBits{3}
\PortNextExtKey{Up}{True Video}
\PortBits{2}
\PortNextExtKey{Down}{Graph}
\PortBits{1}
\PortNextExtKey{Left}{Caps Lock}
\PortBits{0}
\PortNextExtKey{Right}{Extend}
\end{NextPort}
Available since core 3.1.5
\pagebreak