Difference between revisions of "NEO mapper v1"
From MSX Game Library
(→Format) |
(→Format) |
||
Line 36: | Line 36: | ||
== Format == | == Format == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
=== NEO-8 mapper === | === NEO-8 mapper === | ||
Line 80: | Line 62: | ||
* Maximum number of segments: 4096 | * Maximum number of segments: 4096 | ||
* Maximum ROM size: 32 MB | * Maximum ROM size: 32 MB | ||
+ | |||
+ | === NEO-16 mapper === | ||
+ | |||
+ | * Size of a segment: 16 KB | ||
+ | * Segment switching addresses: | ||
+ | {| class="wikitable" | ||
+ | ! Bank (16kB) !! Switching address !! Initial segment | ||
+ | |- style="background:#EEF;" | ||
+ | | 0: 0000h~3FFFh || 4000h (mirror at 0000h, 8000h and A000h) || 0003h | ||
+ | |- | ||
+ | | 1: 4000h~7FFFh || 4200h (mirror at 0200h, 8200h and A200h) || 0000h | ||
+ | |- | ||
+ | | 2: 8000h~BFFFh || 4400h (mirror at 0400h, 8400h and A400h) || 0001h | ||
+ | |- style="background:#DDD;" | ||
+ | | 3: C000h~FFFFh || 4600h (mirror at 0600h, 8600h and A600h) || 0002h | ||
+ | |} | ||
+ | * Maximum number of segments: 4096 | ||
+ | * Maximum ROM size: 64 MB | ||
== Appendix == | == Appendix == |
Revision as of 09:13, 7 December 2023
Here's a proposal for a mapper format operating with a 16-bit segment register and allowing ROMs larger than the 2/4 MB limit of classic mappers.
Contents
Principles
This mapper format is designed to facilitate the creation of MSX games, not only by increasing the size of the ROM available for content, but also by offering programmers new possibilities for organizing their code and data.
It is based on two new features compared to conventional mappers:
- A 16-bit segment register,
- Banks covering all 4 pages of MSX memory space.
Page 3's usefulness is rather limited by its strong usage constraints, but page 0's makes it easy to have an extra 16 KB accessible at any time (either by temporarily disabling interrupts for the duration of accesses, or by adding its own ISR).
For the time being, we propose to reserve the 4 most significant bits for future extensions for the format (such as SRAM or sound chips support for example). This leaves 12 bits to select which segment is visible in each bank, for a maximum of 4096 segments. The reserved bits, must be set to 0.
Higher byte | Lower byte | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
0 | 0 | 0 | 0 | Segment MSB | Segment LSB |
The maximum ROM size is therefore 32 MB (for 8 KB segments) or 64 MB (for 16 KB segments).
Detection by emulators should be fairly easy (counting ROM write accesses).
Format
NEO-8 mapper
- Size of a segment: 8 KB
- Segment switching addresses:
Bank (8kB) | Switching address | Initial segment |
---|---|---|
0: 0000h~1FFFh | 4000h (mirror at 0000h, 8000h and A000h) | 0006h |
1: 2000h~3FFFh | 4100h (mirror at 0100h, 8100h and A100h) | 0007h |
2: 4000h~5FFFh | 4200h (mirror at 0200h, 8200h and A200h) | 0000h |
3: 6000h~7FFFh | 4300h (mirror at 0300h, 8300h and A300h) | 0001h |
4: 8000h~9FFFh | 4400h (mirror at 0400h, 8400h and A400h) | 0002h |
5: A000h~BFFFh | 4500h (mirror at 0500h, 8500h and A500h) | 0003h |
6: C000h~DFFFh | 4600h (mirror at 0600h, 8600h and A600h) | 0004h |
7: E000h~FFFFh | 4700h (mirror at 0700h, 8700h and A700h) | 0005h |
- Maximum number of segments: 4096
- Maximum ROM size: 32 MB
NEO-16 mapper
- Size of a segment: 16 KB
- Segment switching addresses:
Bank (16kB) | Switching address | Initial segment |
---|---|---|
0: 0000h~3FFFh | 4000h (mirror at 0000h, 8000h and A000h) | 0003h |
1: 4000h~7FFFh | 4200h (mirror at 0200h, 8200h and A200h) | 0000h |
2: 8000h~BFFFh | 4400h (mirror at 0400h, 8400h and A400h) | 0001h |
3: C000h~FFFFh | 4600h (mirror at 0600h, 8600h and A600h) | 0002h |
- Maximum number of segments: 4096
- Maximum ROM size: 64 MB
Appendix
Bank switching cost
The cost of switching only the lower or higher byte of the 16-bit segment register is the same that switching segment for standard ASCII/Konami mappers.
; Direct access LD A,n ; 8 t-states LD (nn),A ; 14 t-states ; Indirect access LD HL,nn ; 11 t-states LD (HL),n ; 11 t-states
Although a program can avoid having to change the 2 bytes of the segment register at once, there are cases where this may be necessary. In such cases, the cost is higher, but remains reasonable.
; Direct access LD HL,nn ; 11 t-states LD (nn),HL ; 17 t-states ; Indirect access LD DE,nn ; 11 t-states LD HL,nn ; 11 t-states LD (HL),E ; 8 t-states INC HL ; 7 t-states LD (HL),D ; 8 t-states
MSXgl
MSXgl uses macros to encapsulate bank switching mechanisms. It would therefore be totally transparent for a user to switch, for example, from an ASCII8 or even Konami-SCC mapper, to an NEO-8 mapper.
#define SET_BANK_SEGMENT(bank, segment) /* ... */ // Make segment #30 visible through bank #1 SET_BANK_SEGMENT(1, 30);