Difference between revisions of "NEO mapper v1"

From MSX Game Library

(Created page with "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. == Principles == The idea i...")
 
m (Aoineko moved page NEO mapper to NEO mapper v1 without leaving a redirect)
 
(32 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
== Principles ==
 
== Principles ==
  
The idea is to extend the ASCII mapper format using a 16-bit segment register so we could build hardware capable of running standard ASCII8/16 ROMs in addition to the new 16-bit format.
+
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.
  
The lower byte of 16-bit register is mapped to even address of bank switch memory space while higher byte is mapped to odd ones.
+
Like conventional mappers, the basic idea is to use data write signals to the cartridge to change the value of the ROM segment visible in each of the mapper's banks (sub-pages). So, predefined addresses can be used to write to the mapper registers (see [[#Format|tables below]]).
This means that older programs, which use the default even addresses (like 6000h), will be able to use this new mapper as if it had an 8-bit register (the low byte of the 16-bit register).
+
Read accesses, however, work as normal accesses to the memory visible through the banks.
 +
 
 +
Compared to conventional mappers, this proposal is based on two new main features:
 +
* 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).
 
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).
Line 33: Line 39:
  
 
== Format ==
 
== Format ==
 +
Write access to the mapper is use to change the value of the segment switching register of each bank.
 +
Here is the list of the predefined segment switching addresses.
 +
 +
As this new mapper uses 16-bit segment switching registers, it uses 2 bytes for the segment number to be selected in each bank.
 +
All even-numbered addresses (bit #0 of the address set to 0) access the low byte of the 16-bit register, while odd-numbered addresses (bit #0 of the address set to 1) access the high byte.
 +
This way, the segment number can be initialized at once with the Z80 instructions for 16-bit memory write access.
  
Below, the parts in blue are the only additions to the standard ASCII8/16 format.
+
=== NEO-8 mapper ===
 +
 
 +
* Size of a segment: 8 KB
 +
* Segment switching addresses:
 +
{| class="wikitable"
 +
! Bank (8kB) !! Switching address !! Initial segment
 +
|- style="background:#EEF;"
 +
| 0: 0000h~1FFFh || 4000h (mirror at 0000h, 8000h and A000h) || 0006h
 +
|- style="background:#EEF;"
 +
| 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
 +
|- style="background:#DDD;"
 +
| 6: C000h~DFFFh || 4600h (mirror at 0600h, 8600h and A600h) || 0004h
 +
|- style="background:#DDD;"
 +
| 7: E000h~FFFFh || 4700h (mirror at 0700h, 8700h and A700h) || 0005h
 +
|}
 +
* Maximum number of segments: 4096
 +
* Maximum ROM size: 32 MB
  
=== NEO16 mapper ===
+
=== NEO-16 mapper ===
  
 +
* Size of a segment: 16 KB
 +
* Segment switching addresses:
 
{| class="wikitable"
 
{| class="wikitable"
 
! Bank (16kB) !! Switching address !! Initial segment
 
! Bank (16kB) !! Switching address !! Initial segment
 +
|- style="background:#EEF;"
 +
| 0: 0000h~3FFFh || 4000h (mirror at 0000h, 8000h and A000h) || 0003h
 
|-
 
|-
| 0: 4000h~7FFFh (mirror: C000h~FFFFh) || 6000h {{COLOR|blue|(mirror: even address up to 67FEh)}} || 0000h
+
| 1: 4000h~7FFFh || 4200h (mirror at 0200h, 8200h and A200h) || 0000h
 
|-
 
|-
| 1: 8000h~BFFFh (mirror: 0000h~3FFFh) || 7000h {{COLOR|blue|(mirror: even address up to 77FEh)}} || 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 number of segments: 4096
 
* Maximum ROM size: 64 MB
 
* Maximum ROM size: 64 MB
  
=== NEO8 mapper ===
+
== Appendix ==
 +
 
 +
=== Segment switching address format ===
  
 +
The segment switching address is designed as:
 
{| class="wikitable"
 
{| class="wikitable"
! Bank (8kB) !! Switching address !! Initial segment
 
 
|-
 
|-
| 0: 4000h~5FFFh (mirror: C000h~DFFFh) || 6000h {{COLOR|blue|(mirror: even address up to 67FEh)}} || 0000h
+
!colspan="17"| 16-bit address
 
|-
 
|-
| 1: 6000h~7FFFh (mirror: E000h~FFFFh) || 6800h {{COLOR|blue|(mirror: even address up to 6FFEh)}} || 0000h
+
! 15 || 14 || 13 || 12 || 11 || 10 || 9 || 8
 +
|
 +
! 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0
 
|-
 
|-
| 2: 8000h~9FFFh (mirror: 0000h~1FFFh) || 7000h {{COLOR|blue|(mirror: even address up to 77FEh)}} || 0000h
+
| P || P || x || x || x || B || B || B || || x || x || x || x || x || x || x || R
|-
 
| 3: A000h~BFFFh (mirror: 2000h~3FFFh) || 7800h {{COLOR|blue|(mirror: even address up to 7FFEh)}} || 0000h
 
 
|}
 
|}
 
+
Where:
* Maximum number of segments: 4096
+
* 'PP' (0-3) is the page selection for the MSX to redirect access to the mappers slot.
* Maximum ROM size: 32 MB
+
* 'BBB' (0-7) is the bank's register to write in.
 
+
* 'R' (0-1) is the segment switching register's byte selector (0: less significant byte; 1: most significant byte).
== Appendix ==
+
* 'x' can be any value (generating mirroring).
  
 
=== Bank switching cost ===
 
=== 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 mappers.
+
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
 
  ; Direct access
Line 91: Line 134:
 
  INC HL      ;  7 t-states
 
  INC HL      ;  7 t-states
 
  LD (HL),D  ;  8 t-states
 
  LD (HL),D  ;  8 t-states
 
=== Naming ===
 
If the ASCII-EX (extended ASCII) name poses any legal issue, we could simply called those mappers EX8 and EX16.
 
  
 
=== MSXgl ===
 
=== 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 ASCII-EX8 mapper.
+
MSXgl uses macros to wrap 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) /* ... */
 
  #define SET_BANK_SEGMENT(bank, segment) /* ... */
Line 104: Line 144:
 
  SET_BANK_SEGMENT(1, 30);
 
  SET_BANK_SEGMENT(1, 30);
  
[[Category:Proposal]]
+
[[Category:Proposal]][[Category:Proposal/Mapper]]

Latest revision as of 01:02, 3 January 2024

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.

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.

Like conventional mappers, the basic idea is to use data write signals to the cartridge to change the value of the ROM segment visible in each of the mapper's banks (sub-pages). So, predefined addresses can be used to write to the mapper registers (see tables below). Read accesses, however, work as normal accesses to the memory visible through the banks.

Compared to conventional mappers, this proposal is based on two new main features:

  • 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

Write access to the mapper is use to change the value of the segment switching register of each bank. Here is the list of the predefined segment switching addresses.

As this new mapper uses 16-bit segment switching registers, it uses 2 bytes for the segment number to be selected in each bank. All even-numbered addresses (bit #0 of the address set to 0) access the low byte of the 16-bit register, while odd-numbered addresses (bit #0 of the address set to 1) access the high byte. This way, the segment number can be initialized at once with the Z80 instructions for 16-bit memory write access.

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

Segment switching address format

The segment switching address is designed as:

16-bit address
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
P P x x x B B B x x x x x x x R

Where:

  • 'PP' (0-3) is the page selection for the MSX to redirect access to the mappers slot.
  • 'BBB' (0-7) is the bank's register to write in.
  • 'R' (0-1) is the segment switching register's byte selector (0: less significant byte; 1: most significant byte).
  • 'x' can be any value (generating mirroring).

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 wrap 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);