Memory map: Difference between revisions

From SpecNext Wiki
Jump to: navigation, search
Johnnyo (talk | contribs)
 
(41 intermediate revisions by 10 users not shown)
Line 3: Line 3:
== Global Memory Map ==
== Global Memory Map ==


The total available RAM space of the Next is 512k on an unexpanded Next, or 1536k - 1.5mb - on a Next expanded to 2Mb. (The base Next has 1mb of memory but 512k of it is reserved for the ROMs and firmware.)
The total available RAM space of the Next is 768k on an unexpanded Next, or 1792k on a Next expanded to 2Mb. (The base Next has 1mb of memory but 256k of it is reserved for the ROMs and firmware.)


The Z80 processor in the next can access only 64k of memory at a time, and so the memory is divided into ''banks'' which are used in determining which memory it sees. Spectrum 128k memory management uses 16k banks. Next memory management uses 8k banks.
The Z80 processor in the Next can access only 64k of memory at a time, and so the memory is divided into ''banks'' which are used in determining which memory it sees. Spectrum 128k memory management, and [[NextBASIC]], use 16k banks. Next memory management via machine code uses 8k banks.


{|class="wikitable"
{|class="wikitable"
! 16k-bank !! 8k-bank !! True Address !! Description
! 16k-bank !! 8k-bank !! True Address !! Size !! Description || FPGA Core Selector
|-
|-
| - || - || $000000-$00ffff || ZX Spectrum ROM
| - || - || $000000-$00ffff || 64K || ZX Spectrum ROM ||  A20:A16 = 00000
|-
|-
| - || - || $010000-$013fff || EsxDOS ROM
| - || - || $010000-$011fff || 8K || divMMC ROM || A20:A16 = 00001,000
|-
|-
| - || - || $014000-$017fff || Multiface ROM
| - || - || $012000-$013fff || 8K || Reserved for future Alt ROM2 +3 || A20:A16 = 00001,001
|-
|-
| - || - || $018000-$01bfff || Multiface Extra ROM
| - || - || $014000-$017fff || 16K || Multiface ROM,RAM || A20:A16 = 00001,01
|-
|-
| - || - || $01c000-$01ffff || Multiface RAM
| - || - || $018000-$01bfff || 16K || Alt ROM0 128k || A20:A16 = 00001,10
|-
|-
| - || - || $020000-$05ffff || DivMMC RAM
| - || - || $01c000-$01ffff || 16K || Alt ROM1 48k  || A20:A16 = 00001,11
|-
|-
| 0 || 0-1 || $060000-$063fff || Standard RAM, may be used by EsxDOS
| - || - || $020000-$03ffff || 128K || divMMC RAM || A20:A16 = 00010
|-
|-
| 1 || 2-3 || $064000-$067fff || Standard RAM, contended on 128, may be used by EsxDOS
| 0-7 || 0-15 || $040000-$05ffff || 128K || ZX Spectrum RAM || A20:A16 = 00100
|-
|-
| 2 || 4-5 || $068000-$06afff || Standard RAM
| 8-15 || 16-31 || $060000-$07ffff || 128K || Extra RAM ||
|-
|-
| 3 || 6-7 || $06b000-$06ffff || Standard RAM, contended on 128, may be used by EsxDOS
| 16-47 || 32-95 || $080000-$0fffff || 512K || 1st extra IC RAM (available on unexpanded Next) ||
|-
|-
| 4 || 8-9 || $070000-$073fff || Standard RAM, contended on +2/+3
| 48-79 || 96-159 || $100000-$17ffff || 512K || 2nd extra IC RAM (only available on expanded Next) ||
|-
|-
| 5 || 10-11 || $074000-$077fff || ULA Screen, contended except on Pentagon
| 80-111 || 160-223 || $180000-$1fffff || 512K || 3rd extra IC RAM (only available on expanded Next) ||
|}
 
Additionally, the first few pages have certain uses and traits summarised below:
 
{|class="wikitable"
! 16k-banks !! 8k-banks !! Description
|-
|-
| 6 || 12-13 || $078000-$07afff || Standard RAM, contended on +2/+3
| 0 || 0-1 || Standard RAM, maybe used by esxDOS.  Initially mapped to $c000-$ffff.
|-
|-
| 7 || 14-15 || $07b000-$07ffff || ULA Shadow Screen, contended except on Pentagon
| 1 || 2-3 || Standard RAM, contended on 128, may be used by esxDOS, RAMdisk on NextZXOS.
|-
|-
| 8-10 || 16-21 || $080000-$08afff || Next RAM, Default Layer 2
| 2 || 4-5 || Standard RAM.  Initially mapped to $8000-$bfff.
|-
|-
| 11-13 || 22-28 || $08b000-$095fff || Next RAM, Default Layer 2 Shadow Screen
| 3 || 6-7 || Standard RAM, contended on 128, may be used by esxDOS, RAMdisk on NextZXOS.
|-
|-
| 14-39 || 29-79 || $095000-$0fffff || Next RAM
| 4 || 8-9 || Standard RAM, contended on +2/+3, RAMdisk on NextZXOS.
|-
|-
| 40-63 || 80-127 || $100000-$15ffff || 2Mb Expanded Next RAM (accessible via 128 memory management)
| 5 || 10-11 || ULA Screen, contended except on Pentagon, cannot be used by [[NextBASIC]] commands.  Initially mapped to $4000-$7fff.
|-
|-
| -- || 128-207 || $160000-$1ffffff || 2Mb Expanded Next RAM (accessible via Next management only)
| 6 || 12-13 || Standard RAM, contended on +2/+3, RAMdisk on NextZXOS.
|-
| 7 || 14-15 || ULA Shadow Screen, contended except on Pentagon, NextZXOS Workspace, cannot be used by [[NextBASIC]] commands
|-
| 8 || 16-17 || Next RAM, Default Layer 2, NextZXOS screen and extra data, cannot be used by [[NextBASIC]] commands
|-
| 9-10 || 18-21 || Next RAM, Rest of default Layer 2
|-
| 11-13 || 22-27 || Next RAM, Default Layer 2 Shadow Screen
|}
|}
Please note that NextZXOS moves the Layer 2 bank assignments. Therefore, Layer 2, after NextZXOS boots, is mapped to 16k-banks 9-11 (8k-banks 18-23). The Layer 2 shadow memory is also assigned to 16k-banks 9-11 (8k-banks 18-23).


== Z80 Visible Memory map ==
== Z80 Visible Memory map ==
Line 56: Line 72:
! Area !! 16k-slot !! 8k-slot !! Default 16k-bank !! Default 8k-bank !! Description
! Area !! 16k-slot !! 8k-slot !! Default 16k-bank !! Default 8k-bank !! Description
|-
|-
| $0000-$1fff || rowspan=2 | 1 || 1 || rowspan=2 | ROM || ROM (255) || Normally ROM. Writes mappable by layer 2. IRQ and NMI routines here.
| $0000-$1fff || rowspan=2 | 1 || 0 || rowspan=2 | ROM || ROM (255) || Normally ROM. R/W redirect by [[Layer 2]]. IRQ and NMI routines here.
|-
|-
| $2000-$3fff || 2 || ROM (255) || Normally ROM. Writes mapped by Layer 2.  
| $2000-$3fff || 1 || ROM (255) || Normally ROM. R/W redirect by [[Layer 2]].
|-
|-
| $4000-$5fff || rowspan=2 | 2 || 3 || rowspan=2 | 5 || 10 || Normally used for normal/shadow ULA screen.  
| $4000-$5fff || rowspan=2 | 2 || 2 || rowspan=2 | 5 || 10 || Normally used for normal/shadow ULA screen.  
|-
|-
| $6000-$7fff || 4 || 11 || Timex ULA extended attribute/graphics area.
| $6000-$7fff || 3 || 11 || Timex ULA extended attribute/graphics area.
|-
|-
| $8000-$9fff || rowspan=2 | 3 || 5 || rowspan=2 | 2 || 4 || Free RAM.  
| $8000-$9fff || rowspan=2 | 3 || 4 || rowspan=2 | 2 || 4 || Free RAM.  
|-
|-
| $a000-$bfff || 6 || 5 || Free RAM.
| $a000-$bfff || 5 || 5 || Free RAM.
|-
|-
| $c000-$dfff || rowspan=2 | 4 || 7 || rowspan=2 | 0 || 0 || Free RAM. Only this area is remappable by 128 memory management.
| $c000-$dfff || rowspan=2 | 4 || 6 || rowspan=2 | 0 || 0 || Free RAM. Only this area is remappable by 128 memory management.
|-
|-
| $e000-$ffff || 8 || 1 || Free RAM. Only this area is remappable by 128 memory management.
| $e000-$ffff || 7 || 1 || Free RAM. Only this area is remappable by 128 memory management.
|}
|}
=== Memory decoding order ===
(check also current [https://gitlab.com/SpectrumNext/ZX_Spectrum_Next_FPGA/-/blob/master/cores/zxnext/src/zxnext.vhd#L2918 VHDL source])
The 0-16k area could be remapped by several different mechanics, the priority order of these (from highest priority to lowest):
# bootrom
# multiface
# divmmc
# layer 2 mapping
# mmu
# config mode
# romcs expansion bus
# rom
The 16k-48k area is either mapped by MMU or overshadowed by Layer2 mapping:
# layer 2 mapping
# mmu
Finally the remaining top 16k, the 48k-64k area is mapped only by MMU.
Additionally, there's 16KB + 8KB KB which exist in two instances: as an "internal bram" and as an "external sram":
Accesses to (the RAM of 16KB) "bank 5" or (the first 8KB RAM of the RAM of 16KB) "bank 7" always go to internal bram with the following three exceptions:
1 ''Layer 2 itself has a direct connection to external sram'' so while (the core is) reading bytes to generate video, all bytes read (for Layer 2) come from external sram.  It (Layer 2) has no connection to internal bram so its "bank 5" or "bank 7" accesses are from external sram and not internal bram.
2 ''Layer 2 mapping is a mapping to external sram only.''  So (in the context of Layer 2 mapping) "bank 5" or "bank 7" will not come from internal bram but from external sram which is how the cpu can uncover that otherwise hidden memory in external sram.
3 The config mapping is also an external sram mapping.


== Paging techniques ==
== Paging techniques ==
Line 79: Line 127:
128-style memory management can only alter the bank addressed at $c000 (16k-slot 4, or 8k-slot 7-8). The active 16k-bank at $c000 is selected by writing the 3 LSBs of the 16k-bank number to the bottom 3 bits of {{PortNo|$7FFD}}, and the 3 MSBs to the bottom 3 bits of {{PortNo|$DFFD}}. (The reason for the division is that the original Spectrum 128, having only 128k of memory, only needed 3 bits.)
128-style memory management can only alter the bank addressed at $c000 (16k-slot 4, or 8k-slot 7-8). The active 16k-bank at $c000 is selected by writing the 3 LSBs of the 16k-bank number to the bottom 3 bits of {{PortNo|$7FFD}}, and the 3 MSBs to the bottom 3 bits of {{PortNo|$DFFD}}. (The reason for the division is that the original Spectrum 128, having only 128k of memory, only needed 3 bits.)


On an unexpanded Next, this allows any 16k-bank to be paged in at $c000. On an expanded next, there are not enough bits available to access the banks at the bottom of the expanded memory, so Next memory management must be used to access these.
On an unexpanded Next, this allows any 16k-bank to be paged in at $c000. On an expanded Next, there are not enough bits available to access the banks at the bottom of the expanded memory, so Next memory management must be used to access these.


If you are using the standard interrupt handler or OS routines, then any time you write to {{PortNo|$7FFD}} you should also store the value at $5B5C. Any time you write to {{PortNo|$1FFD}} you should also store the value at $5B67. There is no corresponding system variable for the Next-only {{PortNo|$DFFD}} and standard OS routines may not support the extended banks properly.
If you are using the standard interrupt handler or OS routines, then any time you write to {{PortNo|$7FFD}} you should also store the value at $5B5C. Any time you write to {{PortNo|$1FFD}} you should also store the value at $5B67. There is no corresponding system variable for the Next-only {{PortNo|$DFFD}} and standard OS routines may not support the extended banks properly.
Line 98: Line 146:


=== Layer 2 Switching ===
=== Layer 2 Switching ===
Layer 2 switching can allow any 16k-bank to be ''written to'' (but not read) in 16k-slot 1, by writing the 16k-bank number to {{NextRegNo|$12}} and then enabling Layer 2 paging by writing a value with the LSB set to {{PortNo|$123B}}.
Layer 2 switching can allow one of the 16k-banks to be ''written to'' or ''read from'' in 16k-slot 1, by writing the 16k-bank number to {{NextRegNo|$12}} and then enabling Layer 2 paging by setting the paging bits in {{PortNo|$123B}}. You can use also the {{NextRegNo|$13}} for the same purpose (change of register $12 is immediately visible at display, while register $13 is not related to display in any way, it works only as bank selector for writing into slot 1). Since core 3.0 you can page not only first 16kiB, but whole 48kiB of Layer 2 to address region $0000..$BFFF).
 
Writing to/reading from this paging area will then write/read the appropriate area of memory, whereas the other operation may remain unaffected and use the area mapped by other memory management.


Writing to this area will then write the appropriate area of memory, whereas ''reading'' from it will give the area mapped by other memory management.
Layer 2 is actually 3 banks big, so using Layer 2 controls to access different "sections" of Layer 2 can access the two following banks after the one selected in register $12/$13.


=== Next Memory Management ===
=== Next Memory Management ===
The 8k-bank accessed in an 8k-slot is selected by writing the 8k-bank number to the bottom 7 bits of the 8 Next registers from {{NextRegNo|$50}} upwards. $50 addresses 8k-slot 0, $51 addresses 8k-slot 1, and so on.
The 8k-bank accessed in an 8k-slot is selected by writing the 8k-bank number to bits 7-0 of the 8 Next registers from {{NextRegNo|$50}} upwards. $50 addresses 8k-slot 0, $51 addresses 8k-slot 1, and so on.


In addition, in 8k-slots 1 and 2 only, the ROM can be paged in by selecting the otherwise nonexistent 8k-page $FF. Whether the high or the low 8k of the ROM is mapped is determined by which 8k-slot is used.
In addition, in 8k-slots 0 and 1 only, the ROM can be paged in by selecting the otherwise nonexistent 8k-page $FF. Whether the high or the low 8k of the ROM is mapped is determined by which 8k-slot is used.


=== Interactions between paging methods ===
=== Interactions between paging methods ===
Line 122: Line 172:
ROM can be paged out by enabling AllRam mode, or by using Next memory management. Beware that some programs may assume that they can find ROM service routines at fixed addresses between $0000-$3fff. More importantly, if the default interrupt mode (IM 1) is set, the Z80 '''will''' jump the program counter to $0038 every frame expecting to find an interrupt handler there. If it does not, pain and suffering will likely result. [[Extended Z80 instruction set#DI|DI]] is your friend. On the plus side, this does allow you to write your own interrupt handler without the nuisance of using IM 2.
ROM can be paged out by enabling AllRam mode, or by using Next memory management. Beware that some programs may assume that they can find ROM service routines at fixed addresses between $0000-$3fff. More importantly, if the default interrupt mode (IM 1) is set, the Z80 '''will''' jump the program counter to $0038 every frame expecting to find an interrupt handler there. If it does not, pain and suffering will likely result. [[Extended Z80 instruction set#DI|DI]] is your friend. On the plus side, this does allow you to write your own interrupt handler without the nuisance of using IM 2.


Activating [[Layer 2]]'s paging will not affect ROM operation, because it only remaps ''writes'', not reads.
Activating [[Layer 2]]'s paging will not affect ROM operation, because it only remaps ''writes'', not reads. With core 3.0 you can now enable this paging also for ''read'' operation, that will hide ROM data and for example IM 1 interrupt request will execute the data from the Layer 2 bank.


== Screen ==
== Screen ==
16k-Bank 5 is the bank read by the ULA to determine what to show on screen. The ULA connects directly to the larger memory space ignoring mapping; the screen is always 16k-Bank 5, no matter where in memory it is (or if it is switched in at all). Setting bit 3 of {{PortNo|$7FFD}} will have the ULA read from 16k-bank 7 (the "shadow screen") instead, which can be used as an alternate screen. Beware that '''this does not map 16k-bank 7 into RAM'''; to alter 16k-bank 7 it must be mapped by other means.
16k-Bank 5 is the bank read by the ULA to determine what to show on screen. The ULA connects directly to the larger memory space ignoring mapping; the screen is always 16k-Bank 5, no matter where in memory it is (or if it is switched in at all). Setting bit 3 of {{PortNo|$7FFD}} will have the ULA read from 16k-bank 7 (the "shadow screen") instead, which can be used as an alternate screen. Beware that '''this does not map 16k-bank 7 into RAM'''; to alter 16k-bank 7 it must be mapped by other means.

Latest revision as of 19:03, 4 December 2025

The Next supports two memory management models which operate in tandem. One is a unique memory management system for the Next. The other is an expanded version of the memory manager from the original Spectrum 128 and +2/+3 series.

Global Memory Map

The total available RAM space of the Next is 768k on an unexpanded Next, or 1792k on a Next expanded to 2Mb. (The base Next has 1mb of memory but 256k of it is reserved for the ROMs and firmware.)

The Z80 processor in the Next can access only 64k of memory at a time, and so the memory is divided into banks which are used in determining which memory it sees. Spectrum 128k memory management, and NextBASIC, use 16k banks. Next memory management via machine code uses 8k banks.

16k-bank 8k-bank True Address Size Description FPGA Core Selector
- - $000000-$00ffff 64K ZX Spectrum ROM A20:A16 = 00000
- - $010000-$011fff 8K divMMC ROM A20:A16 = 00001,000
- - $012000-$013fff 8K Reserved for future Alt ROM2 +3 A20:A16 = 00001,001
- - $014000-$017fff 16K Multiface ROM,RAM A20:A16 = 00001,01
- - $018000-$01bfff 16K Alt ROM0 128k A20:A16 = 00001,10
- - $01c000-$01ffff 16K Alt ROM1 48k A20:A16 = 00001,11
- - $020000-$03ffff 128K divMMC RAM A20:A16 = 00010
0-7 0-15 $040000-$05ffff 128K ZX Spectrum RAM A20:A16 = 00100
8-15 16-31 $060000-$07ffff 128K Extra RAM
16-47 32-95 $080000-$0fffff 512K 1st extra IC RAM (available on unexpanded Next)
48-79 96-159 $100000-$17ffff 512K 2nd extra IC RAM (only available on expanded Next)
80-111 160-223 $180000-$1fffff 512K 3rd extra IC RAM (only available on expanded Next)

Additionally, the first few pages have certain uses and traits summarised below:

16k-banks 8k-banks Description
0 0-1 Standard RAM, maybe used by esxDOS. Initially mapped to $c000-$ffff.
1 2-3 Standard RAM, contended on 128, may be used by esxDOS, RAMdisk on NextZXOS.
2 4-5 Standard RAM. Initially mapped to $8000-$bfff.
3 6-7 Standard RAM, contended on 128, may be used by esxDOS, RAMdisk on NextZXOS.
4 8-9 Standard RAM, contended on +2/+3, RAMdisk on NextZXOS.
5 10-11 ULA Screen, contended except on Pentagon, cannot be used by NextBASIC commands. Initially mapped to $4000-$7fff.
6 12-13 Standard RAM, contended on +2/+3, RAMdisk on NextZXOS.
7 14-15 ULA Shadow Screen, contended except on Pentagon, NextZXOS Workspace, cannot be used by NextBASIC commands
8 16-17 Next RAM, Default Layer 2, NextZXOS screen and extra data, cannot be used by NextBASIC commands
9-10 18-21 Next RAM, Rest of default Layer 2
11-13 22-27 Next RAM, Default Layer 2 Shadow Screen

Please note that NextZXOS moves the Layer 2 bank assignments. Therefore, Layer 2, after NextZXOS boots, is mapped to 16k-banks 9-11 (8k-banks 18-23). The Layer 2 shadow memory is also assigned to 16k-banks 9-11 (8k-banks 18-23).

Z80 Visible Memory map

At start up, the 16-bit address space of the Z80 is mapped to memory as follows:

Area 16k-slot 8k-slot Default 16k-bank Default 8k-bank Description
$0000-$1fff 1 0 ROM ROM (255) Normally ROM. R/W redirect by Layer 2. IRQ and NMI routines here.
$2000-$3fff 1 ROM (255) Normally ROM. R/W redirect by Layer 2.
$4000-$5fff 2 2 5 10 Normally used for normal/shadow ULA screen.
$6000-$7fff 3 11 Timex ULA extended attribute/graphics area.
$8000-$9fff 3 4 2 4 Free RAM.
$a000-$bfff 5 5 Free RAM.
$c000-$dfff 4 6 0 0 Free RAM. Only this area is remappable by 128 memory management.
$e000-$ffff 7 1 Free RAM. Only this area is remappable by 128 memory management.

Memory decoding order

(check also current VHDL source)

The 0-16k area could be remapped by several different mechanics, the priority order of these (from highest priority to lowest):

  1. bootrom
  2. multiface
  3. divmmc
  4. layer 2 mapping
  5. mmu
  6. config mode
  7. romcs expansion bus
  8. rom


The 16k-48k area is either mapped by MMU or overshadowed by Layer2 mapping:

  1. layer 2 mapping
  2. mmu


Finally the remaining top 16k, the 48k-64k area is mapped only by MMU.

Additionally, there's 16KB + 8KB KB which exist in two instances: as an "internal bram" and as an "external sram":

Accesses to (the RAM of 16KB) "bank 5" or (the first 8KB RAM of the RAM of 16KB) "bank 7" always go to internal bram with the following three exceptions:

1 Layer 2 itself has a direct connection to external sram so while (the core is) reading bytes to generate video, all bytes read (for Layer 2) come from external sram. It (Layer 2) has no connection to internal bram so its "bank 5" or "bank 7" accesses are from external sram and not internal bram.

2 Layer 2 mapping is a mapping to external sram only. So (in the context of Layer 2 mapping) "bank 5" or "bank 7" will not come from internal bram but from external sram which is how the cpu can uncover that otherwise hidden memory in external sram.

3 The config mapping is also an external sram mapping.

Paging techniques

128-style memory management

128-style memory management can only alter the bank addressed at $c000 (16k-slot 4, or 8k-slot 7-8). The active 16k-bank at $c000 is selected by writing the 3 LSBs of the 16k-bank number to the bottom 3 bits of {{#ask: PortNumber::$7FFD }} ($7FFD{{#ask: PortNumber::$7FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}), and the 3 MSBs to the bottom 3 bits of {{#ask: PortNumber::$DFFD }} ($DFFD{{#ask: PortNumber::$DFFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}). (The reason for the division is that the original Spectrum 128, having only 128k of memory, only needed 3 bits.)

On an unexpanded Next, this allows any 16k-bank to be paged in at $c000. On an expanded Next, there are not enough bits available to access the banks at the bottom of the expanded memory, so Next memory management must be used to access these.

If you are using the standard interrupt handler or OS routines, then any time you write to {{#ask: PortNumber::$7FFD }} ($7FFD{{#ask: PortNumber::$7FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}) you should also store the value at $5B5C. Any time you write to {{#ask: PortNumber::$1FFD }} ($1FFD{{#ask: PortNumber::$1FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}) you should also store the value at $5B67. There is no corresponding system variable for the Next-only {{#ask: PortNumber::$DFFD }} ($DFFD{{#ask: PortNumber::$DFFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}) and standard OS routines may not support the extended banks properly.

128 Special Paging Mode

"Special paging mode" (also called "AllRam mode" or "CP/M mode") is enabled by writing a value with the LSB set to {{#ask: PortNumber::$1FFD }} ($1FFD{{#ask: PortNumber::$1FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}). Depending on the 3 low bits of this value a memory configuration is selected as follows:

Bits Slot 1 Slot 2 Slot 3 Slot 4
%001 0 1 2 3
%011 4 5 6 7
%101 4 5 6 3
%111 4 7 6 3

Layer 2 Switching

Layer 2 switching can allow one of the 16k-banks to be written to or read from in 16k-slot 1, by writing the 16k-bank number to {{#ask: TBRegisterNumber::$12 }} ($12) and then enabling Layer 2 paging by setting the paging bits in {{#ask: PortNumber::$123B }} ($123B{{#ask: PortNumber::$123B |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}). You can use also the {{#ask: TBRegisterNumber::$13 }} ($13) for the same purpose (change of register $12 is immediately visible at display, while register $13 is not related to display in any way, it works only as bank selector for writing into slot 1). Since core 3.0 you can page not only first 16kiB, but whole 48kiB of Layer 2 to address region $0000..$BFFF).

Writing to/reading from this paging area will then write/read the appropriate area of memory, whereas the other operation may remain unaffected and use the area mapped by other memory management.

Layer 2 is actually 3 banks big, so using Layer 2 controls to access different "sections" of Layer 2 can access the two following banks after the one selected in register $12/$13.

Next Memory Management

The 8k-bank accessed in an 8k-slot is selected by writing the 8k-bank number to bits 7-0 of the 8 Next registers from {{#ask: TBRegisterNumber::$50 }} ($50) upwards. $50 addresses 8k-slot 0, $51 addresses 8k-slot 1, and so on.

In addition, in 8k-slots 0 and 1 only, the ROM can be paged in by selecting the otherwise nonexistent 8k-page $FF. Whether the high or the low 8k of the ROM is mapped is determined by which 8k-slot is used.

Interactions between paging methods

In normal mode, changes made in 128 style and Next style memory management are synchronized. The most recent change always has priority. This means that using 128-style memory management to select a new 16k-bank in 16k-slot 4 will update the MMU registers for the two 8k-slots with the corresponding 8k-bank numbers.

However, enabling 128 special paging mode (AllRam mode) mode will override the Next MMU. The bank selections from the AllRam mode table will override the set pages in the Next registers. The MMU registers can still be changed, but they will have no effect until special paging mode is disabled.

Since the 128-style memory management ports are not readable, there is no synchronization applicable in the other direction.

ROM paging and selection

$0000-$3fff is usually mapped to ROM. This area can only be fully remapped using Next memory management. ROM is not considered one of the numbered banks; it is mapped to the two 8k-banks by default, or by setting their 8k-bank numbers to 255.

The 128k Spectrum has 2 ROM pages. Which of these is mapped is selected by altering Bit 4 of {{#ask: PortNumber::$7FFD }} ($7FFD{{#ask: PortNumber::$7FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}). The +2a/+3 has 4 ROM pages; the extra bit needed to select between these is bit 2 of {{#ask: PortNumber::$1FFD }} ($1FFD{{#ask: PortNumber::$1FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}). This maintains compatibility with the original machines' ROM paging as long as the ROM is not paged out.

Paging out ROM

ROM can be paged out by enabling AllRam mode, or by using Next memory management. Beware that some programs may assume that they can find ROM service routines at fixed addresses between $0000-$3fff. More importantly, if the default interrupt mode (IM 1) is set, the Z80 will jump the program counter to $0038 every frame expecting to find an interrupt handler there. If it does not, pain and suffering will likely result. DI is your friend. On the plus side, this does allow you to write your own interrupt handler without the nuisance of using IM 2.

Activating Layer 2's paging will not affect ROM operation, because it only remaps writes, not reads. With core 3.0 you can now enable this paging also for read operation, that will hide ROM data and for example IM 1 interrupt request will execute the data from the Layer 2 bank.

Screen

16k-Bank 5 is the bank read by the ULA to determine what to show on screen. The ULA connects directly to the larger memory space ignoring mapping; the screen is always 16k-Bank 5, no matter where in memory it is (or if it is switched in at all). Setting bit 3 of {{#ask: PortNumber::$7FFD }} ($7FFD{{#ask: PortNumber::$7FFD |mainlabel=- |headers=hide |intro= /  |?NumberDec#- }}) will have the ULA read from 16k-bank 7 (the "shadow screen") instead, which can be used as an alternate screen. Beware that this does not map 16k-bank 7 into RAM; to alter 16k-bank 7 it must be mapped by other means.