-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathchapter-next-memory.tex
498 lines (360 loc) · 23.7 KB
/
chapter-next-memory.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
\section{Memory Map and Paging}
\label{zx_next_memorypaging}
% ──────────────────────────────────────────────────────────────
% ─██████──────────██████─██████████████─██████──────────██████─
% ─██░░██████████████░░██─██░░░░░░░░░░██─██░░██████████████░░██─
% ─██░░░░░░░░░░░░░░░░░░██─██░░██████████─██░░░░░░░░░░░░░░░░░░██─
% ─██░░██████░░██████░░██─██░░██─────────██░░██████░░██████░░██─
% ─██░░██──██░░██──██░░██─██░░██████████─██░░██──██░░██──██░░██─
% ─██░░██──██░░██──██░░██─██░░░░░░░░░░██─██░░██──██░░██──██░░██─
% ─██░░██──██████──██░░██─██░░██████████─██░░██──██████──██░░██─
% ─██░░██──────────██░░██─██░░██─────────██░░██──────────██░░██─
% ─██░░██──────────██░░██─██░░██████████─██░░██──────────██░░██─
% ─██░░██──────────██░░██─██░░░░░░░░░░██─██░░██──────────██░░██─
% ─██████──────────██████─██████████████─██████──────────██████─
% ──────────────────────────────────────────────────────────────
\newcommand{\MemEmpty}{\multicolumn{1}{c}{}}
\newcommand{\MemArrow}[1]{\multicolumn{1}{c}{\IfEq{#1}{<}{\LArrowLine{1em}}{\RArrowLine{1em}}}}
ZX Spectrum Next comes with 1024K (expanded version with 2048K) of memory. But it can't see it all at once.
\subsection{Banks and Slots}
Due to its 16-bit address bus, Next can only address 2\textsuperscript{16} = 65.536 bytes or 64K of memory at a time. To get access to all available memory, it's divided into smaller chunks called ``banks''\footnote{You may also see the term ``page'' used instead of ``bank'' (in fact, that's why the process of swapping banks into slots is usually called ``paging''). I also noticed sometimes 64K addressable memory is referred to as ``bank''. In this book, I will keep naming consistent to avoid confusion.}.
Next supports two interchangeable memory management models. One is inherited from the original Spectrums and clones and uses 16K banks. The other is unique to Next and uses 8K banks. Hence, addressable 64K is also divided into 16K or 8K ``slots'' into which banks are swapped in and out. In a way, slots are like windows into available memory.
Banks are selected by their number - the first bank is {\tt 0}, second {\tt 1} and so on. If you ever worked with arrays, banks and their numbers work the same as array data and indexes. Both 16K and 8K banks start with number {\tt 0} at the same address. So if 16K bank $n$ is selected, then the two corresponding 8K bank numbers would be $n \times 2$ and $n \times 2 + 1$.
After startup, addressable 64K space is mapped like this:
\begin{ElegantTableX}{|l|l|l|l|l|X|}[
\newcommand{\StartRow}[7]{\MemAddr{#1}-\MemAddr{#2} & \multirow[t]{2}{*}{{\tt #3}} & {\tt #4} & \multirow[t]{2}{*}{#5} & #6 & #7 \\}
\newcommand{\EndRow}[5]{\MemAddr{#1}-\MemAddr{#2} & & {\tt #3} & & #4 & #5 \\}
]
\ElegantHeader[]{
&
\multicolumn{2}{c|}{\EH{Slots}} &
\multicolumn{2}{c|}{\EH{Banks}} &
}
\ElegantHeader{
\multirow{-2}{*}{\EH{Address}} & % in second line and negative value to draw over row colour
\multicolumn{1}{c}{\EH{16K}} &
\multicolumn{1}{c|}{\EH{8K}} &
\multicolumn{1}{c}{\EH{16K}} &
\multicolumn{1}{c|}{\EH{8K}} &
\multirow{-2}{*}{\EH{Description}}
}
\StartRow{0000}{1FFF}{0}{0}{ROM}{ROM}{ROM, R/W redirect by L2, IRQ, NMI}
\EndRow{2000}{3FFF} {1} {ROM}{ROM, R/W redirect by Layer 2}
\hline
\StartRow{4000}{5FFF}{1}{2}{5}{10}{Normal/shadow ULA screen, Tilemap}
\EndRow{6000}{7FFF} {3} {11}{ULA extended attribute/graphics, Tilemap}
\hline
\StartRow{8000}{9FFF}{2}{4}{2}{4}{Free RAM}
\EndRow{A000}{BFFF} {5} {5}{Free RAM}
\hline
\StartRow{C000}{DFFF}{3}{6}{0}{0}{Free RAM}
\EndRow{E000}{FFFF} {7} {1}{Free RAM}
\end{ElegantTableX}
\subsection{Default Bank Traits}
First few addressable banks have certain uses and traits:
\NewDocumentEnvironment{BankTraitTable}{ +!b }{
\begin{ElegantTableX}{|l|l|X|}
\ElegantHeader[]{ \multicolumn{2}{|c|}{\EH{Banks}} & }
\ElegantHeader{
\multicolumn{1}{|c}{\EH{16K}} &
\multicolumn{1}{c|}{\EH{8K}} &
\multirow{-2}{*}{\EH{Description}}
}
#1
\end{ElegantTableX}
}{}
\newcommand{\BankTraitRow}[5][\hline]{{\tt #2} & {\tt #3}-{\tt #4} & #5 \\ #1}
\newcommand{\BankTraitRowMulti}[6][\hline]{{\tt #2}-{\tt #3} & {\tt #4}-{\tt #5} & #6 \\ #1}
\begin{BankTraitTable}
\BankTraitRow{0}{0}{1}{Standard RAM, maybe used by EsxDOS. Initially mapped to \MemAddr{C000}-\MemAddr{FFFF}}
\BankTraitRow[]{1}{2}{3}{Standard RAM, contended on 128, may be used by EsxDOS, RAM disk on NextZXOS}
\end{BankTraitTable}
\begin{BankTraitTable}
\BankTraitRow{2}{4}{5}{Standard RAM. Initially mapped to \MemAddr{8000}-\MemAddr{BFFF}}
\BankTraitRow{3}{6}{7}{Standard RAM, contended on 128, may be used by EsxDOS, RAM disk on NextZXOS}
\BankTraitRow{4}{8}{9}{Standard RAM, contended on +2/+3, RAM disk on NextZXOS}
\BankTraitRow{5}{10}{11}{ULA Screen, contended except on Pentagon, cannot be used by NextBASIC commands. Initially mapped to \MemAddr{4000}-\MemAddr{7FFF}}
\BankTraitRow{6}{12}{13}{Standard RAM, contended on +2/+3, RAM disk on NextZXOS}
\BankTraitRow{7}{14}{15}{ULA Shadow Screen, contended except on Pentagon, NextZXOS Workspace, cannot be used by NextBASIC commands}
\BankTraitRow{8}{16}{17}{Next RAM, Default Layer 2, NextZXOS screen and extra data, cannot be used by NextBASIC commands}
\BankTraitRowMulti{9}{10}{18}{21}{Next RAM, Rest of default Layer 2}
\BankTraitRowMulti[]{11}{13}{22}{27}{Next RAM, Default Layer 2 Shadow Screen}
\end{BankTraitTable}
\subsection{Memory Map}
As hinted before, not all available memory is addressable by programs. The first 256K is always reserved for ROMs and firmware. Hence bank {\tt 0} starts at absolute address \MemAddr{40000}:
\begin{ElegantTableX}{|l|l|l|l|l|l|X|}[
\newcommand{\MapROMRowNoPrefix}[4]{- & - & #1 & \MemAddr{#2}-\MemAddr{#3} & #4 \\}
\newcommand{\MapROMRow}[4]{& & \MapROMRowNoPrefix{#1}{#2}{#3}{#4}}
\newcommand{\MapRow}[8]{& & {\tt #1}-{\tt #2} & {\tt #3}-{\tt #4} & #5 & \MemAddr{#6}-\MemAddr{#7} & #8 \\}
\newcommand{\MapDelim}{\cline{3-7}}
]
\ElegantHeader{\multicolumn{2}{|c|}{} & \EH{16K bank} & \EH{8K bank} & \EH{Size} & \EH{Absolute Address} & \EH{Description}}
\multirow{11}{*}{\rotatebox[origin=c]{90}{\LArrowLine{1.75cm} Expanded Next \RArrowLine{1.75cm}}} &
\multirow{9}{*}{\rotatebox[origin=c]{90}{\LArrowLine{0.92cm} Unexpanded Next \RArrowLine{0.92cm}}} &
\MapROMRowNoPrefix{64K}{000000}{00FFFF}{ZX Spectrum ROM}
\MapDelim
\MapROMRow{16K}{010000}{013FFF}{EsxDOS ROM}
\MapDelim
\MapROMRow{16K}{014000}{017FFF}{Multiface ROM}
\MapDelim
\MapROMRow{16K}{018000}{01BFFF}{Multiface Extra ROM}
\MapDelim
\MapROMRow{16K}{01C000}{01FFFF}{Multiface RAM}
\MapDelim
\MapROMRow{128K}{020000}{03FFFF}{DivMMC RAM}
\MapDelim
\MapRow{0}{7}{0}{15}{128K}{040000}{05FFFF}{Standard 128K RAM}
\MapDelim
\MapRow{8}{15}{16}{31}{128K}{060000}{07FFFF}{Extra RAM}
\MapDelim
\MapRow{16}{47}{32}{95}{512K}{080000}{0FFFFF}{1st Extra IC RAM}
\cline{2-7}
\MapRow{48}{79}{96}{159}{512K}{080000}{0FFFFF}{1st Extra IC RAM}
\MapDelim
\MapRow{80}{111}{160}{223}{512K}{080000}{0FFFFF}{2st Extra IC RAM}
\end{ElegantTableX}
So when swapping in, for example:
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item 16K bank 20 to slot 3 and writing 10 bytes to memory \MemAddr{C000} (start of 16K slot 3), we're effectively writing to absolute memory \MemAddr{90000}-\MemAddr{90009} ({\tt \MemAddr{40000} + 20 $\times$ 16384})
\item 8K bank 30 to slot 5 and writing 10 bytes to memory \MemAddr{A000} (start of 8K slot 5), we're effectively writing to absolute memory \MemAddr{7C000}-\MemAddr{7C009} ({\tt \MemAddr{40000} + 30 $\times$ 8192})
\end{itemize}.
\subsection{Legacy Paging Modes}
As mentioned, Next inherits the memory management models from the Spectrum 128K/+2/+3 models and Pentagon clones. It's unlikely you will use these modes for Next programs, as Next own model is much simpler to use. They are still briefly described here though in case you will encounter them in older programs. All legacy models use 16K slots and banks.
\NewDocumentEnvironment{PagingTableLegacy}{ +!b }{
% note: we need to use constant column widths so that all tables exactly match their cells...
% this table uses elegant background and spacing
\begin{ElegantTable}{|p{1cm}|C{1.55cm}|C{1.55cm}|C{1.55cm}|C{1.55cm}|}[][]
\ElegantHeader{\EH{Slot} & {\tt 0} & {\tt 1} & {\tt 2} & {\tt 3}}
\end{ElegantTable}
\vspace*{-0.75em}
% second table touches top one, repeats borders, but without extra spacing that elegant table uses
\begin{tabular}{|p{1cm}|C{1.55cm}|C{1.55cm}|C{1.55cm}|C{1.55cm}|}
Start & \MemAddr{0000} & \MemAddr{4000} & \MemAddr{8000} & \MemAddr{C000} \\
End & \MemAddr{3FFF} & \MemAddr{7FFF} & \MemAddr{BFFF} & \MemAddr{FFFF} \\
\hline
\end{tabular}
\vspace*{-0.7em}
% third table touches second one but without borders and with extra column at the end.
\begin{tabular}{p{1cm}C{1.55cm}C{1.55cm}C{1.55cm}C{1.55cm}l}
#1
\end{tabular}
}{}
\newcommand{\PagingTableLegacyItem}[5]{ #1 & #2 & #3 & #4 & #5 \\ }
\subsubsection{128K Mode}
\begin{PagingTableLegacy}
\PagingTableLegacyItem{}{$\uparrow$}{}{}{$\uparrow$}
\PagingTableLegacyItem{}{\tt ROM 0-1}{}{}{\multicolumn{2}{l}{{\tt BANK 0-7} on 128K}}
\PagingTableLegacyItem{}{}{}{}{\multicolumn{2}{l}{{\tt BANK 0-127} on Next}}
\end{PagingTableLegacy}
Allows selecting:
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item 16K ROM to be visible in the bottom 16K slot (0) from 2 possible banks
\item 16K RAM to be visible in the top 16K slot (3) from 8 possible banks (128 banks on Next)
\end{itemize}
Ports involved:
% note: since all ports are declared on the same page, we group the page in more info section below the table
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item \PortTextXRef[]{7FFD} bit 4 selects ROM bank for slot 0
\item \PortTextXRef[]{7FFD} bits 2-0 select one of 8 RAM banks for slot 3
\item \PortTextXRef[]{DFFD} bits 3-0 are added as MSB to 2-0 from \MemAddr{7FFD} to form 128 banks for slot 3 (Next specific)
\end{itemize}
See page \PortPage{7FFD} for details on ports \MemAddr{7FFD} and \MemAddr{DFFD}. If you are using the standard interrupt handler or OS routines, then any time you write to \PortTextXRef[]{7FFD} you should also store the value at \MemAddr{5B5C}.
\subsubsection{+3 Normal Mode}
\begin{PagingTableLegacy}
\PagingTableLegacyItem{}{$\uparrow$}{}{}{$\uparrow$}
\PagingTableLegacyItem{}{\tt ROM 0-3}{}{}{\multicolumn{2}{l}{{\tt BANK 0-7} on 128K}}
\PagingTableLegacyItem{}{}{}{}{\multicolumn{2}{l}{{\tt BANK 0-127} on Next}}
\end{PagingTableLegacy}
Allows selecting:
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item 16K ROM to be visible in the bottom 16K slot (0) from 4 possible banks
\item 16K RAM to be visible in the top 16K slot (3) from 8 possible banks (128 banks on Next)
\end{itemize}
\pagebreak
Ports involved:
% note: since all ports are declared on the same page, we group the page in more info section below the table
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item \PortTextXRef[]{1FFD} bit 2 as LSB selects ROM bank for slot 0
\item \PortTextXRef[]{7FFD} bit 4 forms MSB selects ROM bank for slot 0
\item \PortTextXRef[]{7FFD} bits 2-0 select one of 8 RAM banks for slot 3
\item \PortTextXRef[]{DFFD} bits 3-0 are added as MSB to 2-0 from \MemAddr{7FFD} to form 128 banks for slot 3 (Next specific)
\end{itemize}
See page \PortPage{7FFD} for details on ports \MemAddr{1FFD}, \MemAddr{7FFD} and \MemAddr{DFFD}. If you are using the standard interrupt handler or OS routines, then any time you write to \PortTextXRef[]{1FFD} you should also store the same value at \MemAddr{5B67} and any time your write to \PortTextXRef[]{7FFD} you should also store the value at \MemAddr{5B5C}.
\subsubsection{+3 All-RAM Mode}
\begin{PagingTableLegacy}
\PagingTableLegacyItem{}{$\uparrow$}{$\uparrow$}{$\uparrow$}{$\uparrow$}
\PagingTableLegacyItem{\tt 00 =}{\tt BANK 0}{\tt BANK 1}{\tt BANK 2}{\tt BANK 3}
\PagingTableLegacyItem{\tt 01 =}{\tt BANK 4}{\tt BANK 5}{\tt BANK 6}{\tt BANK 7}
\PagingTableLegacyItem{\tt 10 =}{\tt BANK 4}{\tt BANK 5}{\tt BANK 6}{\tt BANK 3}
\PagingTableLegacyItem{\tt 11 =}{\tt BANK 4}{\tt BANK 7}{\tt BANK 6}{\tt BANK 3}
\multirow{2}{*}{$\Big\downarrow$}$\downarrow$ & \\
\multicolumn{5}{l}{~~Lo bit = bit 1 from \MemAddr{1DDF}} \\
\multicolumn{5}{l}{Hi bit = bit 2 from \MemAddr{1DDF}} \\
\end{PagingTableLegacy}
Also called ``Special Mode'' or ``CP/M Mode''. Allows selecting all 4 slots from limited selection of banks as shown in the table above.
Ports involved:
% note: since all ports are declared on the same page, we group the page in more info section below the table
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item \PortTextXRef[]{1FFD} bit 0 enables All-RAM (if {\tt 1}) or normal mode ({\tt 0})
\item \PortTextXRef[]{1FFD} bits 2-1 select memory configuration
\end{itemize}
See page \PortPage{1FFD} for details on port \MemAddr{1FFD}. If you are using the standard interrupt handler or OS routines, then any time you write to \PortTextXRef[]{1FFD} you should also store the same value at \MemAddr{5B67}.
\subsubsection{Pentagon 512K/1024K Mode}
Next also supports paging implementation from Pentagon spectrums. It's unlikely you will ever use it on Next, so just mentioning for completness sake. You can find more information on Next Dev Wiki\footnote{\url{https://wiki.specnext.dev/Next_Memory_Bank_Select}} or internet if interested.
\pagebreak
\subsection{Next MMU Paging Mode}
Next MMU based paging mode is much more flexible in that it allows mapping 8K banks into any 8K slot of memory available to the CPU. This is the only mode that allows paging in all 2048K on extended Next. It's also the simplest to use - a single {\tt NEXTREG} instruction assigning bank number to desired MMU slot register.
In this mode, 64K memory accessible to the CPU is divided into 8 slots called MMU0 through MMU7, as shown in the diagram below. Physical memory is thus divided into 96 (or 224 on expanded Next) 8K banks.
% similar to legacy tables, but less width per column
\begin{ElegantTable}{|p{1.8cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|}[][]
\ElegantHeader{
\EH{16K Slot} &
\multicolumn{2}{c|}{\tt 0} &
\multicolumn{2}{c|}{\tt 1} &
\multicolumn{2}{c|}{\tt 2} &
\multicolumn{2}{c|}{\tt 3}
}
\ElegantHeader{
\EH{8K Slot} &
{\tt 0} &
{\tt 1} &
{\tt 2} &
{\tt 3} &
{\tt 4} &
{\tt 5} &
{\tt 6} &
{\tt 7}
}
\end{ElegantTable}
\vspace*{-0.75em}
\begin{tabular}{|p{1.8cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|C{1.1cm}|}
\hline
Start & \MemAddr{0000} & \MemAddr{2000} & \MemAddr{4000} & \MemAddr{6000} & \MemAddr{8000} & \MemAddr{A000} & \MemAddr{C000} & \MemAddr{E000} \\
End & \MemAddr{1FFF} & \MemAddr{3FFF} & \MemAddr{5FFF} & \MemAddr{7FFF} & \MemAddr{9FFF} & \MemAddr{BFFF} & \MemAddr{DFFF} & \MemAddr{FFFF} \\
\hline
\end{tabular}
\vspace*{-0.7em}
\begin{tabular}{p{1.8cm}C{1.1cm}C{1.1cm}C{1.1cm}C{1.1cm}C{1.1cm}C{1.1cm}C{1.1cm}C{1.1cm}}
& $\uparrow$ & $\uparrow$ & $\uparrow$ & $\uparrow$ & $\uparrow$ & $\uparrow$ & $\uparrow$ & $\uparrow$ \\
& {\tt BANK} & {\tt BANK} & {\tt BANK} & {\tt BANK} & {\tt BANK} & {\tt BANK} & {\tt BANK} & {\tt BANK} \\
& {\tt 0-255} & {\tt 0-255} & {\tt 0-255} & {\tt 0-255} & {\tt 0-255} & {\tt 0-255} & {\tt 0-255} & {\tt 0-255} \\
\end{tabular}
Bank selection is set via Next registers (see page \PortPage{50} for details):
% note: since all ports are declared on the same page, we group the page in more info section below the table
\begin{itemize}[topsep=0pt,itemsep=0pt]
\item \PortTextXRef[]{50}
\item \PortTextXRef[]{51}
\item \PortTextXRef[]{52}
\item \PortTextXRef[]{53}
\item \PortTextXRef[]{54}
\item \PortTextXRef[]{55}
\item \PortTextXRef[]{56}
\item \PortTextXRef[]{57}
\end{itemize}
While not absolutely required, it's good practice to store original slot values and then restore before exiting program or returning from subroutines.
Example of writing 10 bytes ({\tt 00 01 02 03 04 05 06 07 08 09}) to 8K bank 30 swapped in to slot 5. As mentioned before, this will effectively write to absolute memory \MemAddr{7C000}-\MemAddr{7C009}:
\begin{tcblisting}{}
NEXTREG &55, 30 ; swap bank 30 to slot 5
LD DE, &A000 ; slot 5 starts at &A000
LD A, 0 ; starting data to write
LD B, 10 ; number of bytes to write
next:
LD (DE), A ; write next byte
INC A ; increment source byte
INC DE ; increment destination location
DJNZ next
\end{tcblisting}
% note: since both ports are declared on the same page, we group the page
Note: registers \PortTextXRef[]{50} and \PortTextXRef[]{51} (page \PortPage{50}) have extra ``functionality'': ROM can be automatically paged in if otherwise nonexistent 8K page \MemAddr{FF} is set. Low or high 8K ROM bank is automatically determined based on which 8K slot is used. This may be useful if temporarily paging RAM into the bottom 16K region and then wanting to restore back to ROM.
\subsection{Interaction Between Paging Modes}
As mentioned, legacy and Next paging modes are interchangeable. Changing banks in one will be reflected in the other. The most recent change always has priority. Again, keep in mind that legacy modes use 16K banks, therefore single bank change will affect 2 8K banks.
\subsubsection{Paging Out ROM}
ROM is usually mapped to the bottom 16K slot, addresses \MemAddr{0000}-\MemAddr{3FFF}. This area can only be remapped using +3 All-RAM or Next MMU-based mode. Beware though that some programs may expect to find ROM routines at fixed addresses between \MemAddr{0000} and \MemAddr{3FFF}. And if default interrupt mode (IM 1) is set, Z80 will expect to find interrupt handler at the address \MemAddr{0038}.
\subsubsection{ULA}
ULA always reads content from 16K bank 5. This is mapped to 16K slot 1 by default, addresses \MemAddr{4000}-\MemAddr{7FFF}. ULA will always use bank 5, regardless of which bank is mapped to slot 1, or which slot bank 5 is mapped to (or if it is mapped into any slot at all).
You can redirect ULA to read from 16K bank 7 instead (the ``shadow screen'', used for double-buffering), using bit 3 of \PortTextXRef{7FFD}. However, you still need to map bank 7 into one of the slots if you want to read or write to it (that's 8K banks 14 and 15 if using MMU for paging). Read more in ULA chapter, section \XRef{zx_next_ula}.
\subsubsection{Layer 2 Paging}
Layer 2 uses specific ports and registers that are can be used to change memory mapping. For example, the bottom 16K slot can be set for write and read access. Layer 2 also supports a double-buffering scheme of its own. Though any other mapping mode discussed here can be used as well. See Layer 2 chapter, section \XRef{zx_next_layer2} for more details.
\pagebreak
\subsection{Paging Mode Ports and Registers}
\label{zx_next_memorypaging_registers}
% note: almost all references to ports are described on this same page spread, hence no page numbers in XRefs
\subsubsection{\PortDeclaration{1FFD}}
\begin{NextPort}
\PortBits{7-3}
\PortDesc{Unused, use 0}
\PortBits{2}
\PortDesc{In normal mode high bit of ROM selection. With low bit from bit 4 of \MemAddr{7FFD}:}
\PortDescOnly{
\begin{PortBitConfig}
\PortBitLine{00}{ROM0 = 128K editor and menu system}
\PortBitLine{01}{ROM1 = 128K syntax checker}
\PortBitLine{10}{ROM2 = +3DOS}
\PortBitLine{11}{ROM3 = 48K BASIC}
\end{PortBitConfig}
}
\PortDescOnly{In special mode: high bit of memory configuration number}
\PortBits{1}
\PortDesc{In special mode: low bit of memory configuration number}
\PortBits{0}
\PortDesc{Paging mode: 0 = normal, 1 = special}
\end{NextPort}
\subsubsection{\PortDeclaration{7FFD}}
\begin{NextPort}
\PortBits{7-6}
\PortDesc{Extra two bits for 16K RAM bank if in Pentagon 512K/1024K mode (see \PortTextXRef[]{DFFD} below)}
\PortBits{5}
\PortDesc{{\tt 1} locks pages; cannot be unlocked until next reset on regular ZX128)}
\PortBits{4}
\PortDesc{128K: ROM select ({\tt 0} = 128K editor, {\tt 1} = 48K BASIC)}
\PortDescOnly{+2/+3: low bit of ROM select (see \PortTextXRef[]{1FFD} above)}
\PortBits{3}
\PortDesc{ULA layer shadow screen toggle (0 = bank 5, 1 = bank 7)}
\PortBits{2-0}
\PortDesc{Bank number for slot 4 (\MemAddr{C000})}
\end{NextPort}
\subsubsection{\PortDeclaration{DFFD}}
\begin{NextPort}
\PortBits{7}
\PortDesc{1 to set Pentagon 512K/1024K mode}
\PortBits{3-0}
\PortDesc{Most significant bits of the 16K RAM bank selected in \PortTextXRef[]{7FFD}}
\end{NextPort}
\subsubsection{\PortDeclaration{50}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{51}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{52}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{53}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{54}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{55}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{56}}
\vspace*{-2ex}
\subsubsection{\PortDeclaration{57}}
\begin{NextPort}
\PortBits{7-0}
\PortDesc{Selects 8K bank stored in corresponding 8K slot}
\end{NextPort}
\subsubsection{\PortDeclaration{8E}}
\begin{NextPort}
\PortBits{7}
\PortDesc{Access to bit 0 of \PortTextXRef[]{DFFD}}
\PortBits{6-4}
\PortDesc{Access to bits 2-0 of \PortTextXRef[]{7FFD}}
\PortBits{3}
\PortDesc{Read will always return {\tt 1}}
\PortDescOnly{Write {\tt 1} to change RAM bank, {\tt 0} for no change to MMU6,7, \MemAddr{7FFD} and \MemAddr{DFFD}}
\PortBits{2}
\PortDesc{{\tt 0} for normal paging mode, {\tt 1} for special all-RAM mode}
\PortBits{1}
\PortDesc{Access to bit 2 of \PortTextXRef[]{1FFD}}
\PortBits{0}
\PortDesc{If bit 2 = {\tt 0} (normal mode): bit 4 of \PortTextXRef[]{7FFD}}
\PortDescOnly{If bit 2 = {\tt 1} (special mode): bit 1 of \PortTextXRef[]{1FFD}}
\end{NextPort}
Acts as a shortcut for reading and writing \PortTextXRef[]{1FFD}, \PortTextXRef[]{7FFD} and \PortTextXRef[]{DFFD} all at once. Mainly to simplify classic Spectrum memory mapping. Though, as mentioned, Next specific programs should prefer MMU based memory mapping.
\pagebreak