Coded by OzzyOuzo on Feb 11 2021.
Unleash your Neo.Geo AES/MVS homebrew with 8x time more P memory :)
Bank switching enables access to a maximum of 9MB PROM memory.
Linear view such as [0x00100000-0x009fffff] is common place,
But bank switching mecanism allows only 1MB from 8MB of P2 Rom to be accessible by configuration switch.
The content of P1 Rom generally always sits between range [0x00100000-0x001fffff]. while 1MB pages from P2 Rom will be alternatively mapped to [0x00200000-0x002fffff].
Selecting the P Roms configuration is done by writing a 16b word at address : 0x2ffff0
code:
void reSetSpriteBank(u16 bank_)
{
(*((u16*)0x2ffff0)) = bank_;
}
configurations for a 8MB P2 Rom size (only 3bits are used to describe bank config) :
first 1MB of P2 Rom is mapped at 0x200000 which is default configuration
bank_ = 0 : (P1)-(P2-0) from memory range (0x100000)-(0x200000-0x2fffff) (default)
second 1MB page from P2 Rom starting at linear address 0x300000 is mapped at address 0x200000
bank_ = 1 : (P1)-(P2-1) from memory range (0x100000)-(0x300000-0x3fffff)
third 1MB page from P2 Rom starting at linear address 0x400000 is mapped at address 0x200000
bank_ = 2 : (P1)-(P2-2) from memory range (0x100000)-(0x400000-0x4fffff)
(etc etc etc)
bank_ = 3 : (P1)-(P2-3) from memory range (0x100000)-(0x500000-0x5fffff)
....
bank_ = 7 : (P1)-(P2-7) from memory range (0x100000)-(0x900000-0x9fffff)
A common usage for bank switching is to get access to sprite map data located in different banks before updating vram.
- select appropriate bank configuration to bind proper data.
- update vram
- a good idea would be to get back to default conf but you are the boss afterall ^^
pseudo code:
reSetSpriteBank(7);
writeSpriteVram(...);
reSetSpriteBank(0);
NGDataLinker will generate consistent addresses needed during link phase for data accessed through bank switching mecanism on P roms. Memory offsets are retreived from map files generated from GCC 2.95.2 which is part of NEODEV SDK.
Get Romwak 0.3f or above to further use concatenate option /c -> ( https://github.com/freem/romwak )
You need to compile and link each 1MB P Rom separately and link sequence should look as follow :
@REM Pseudo Makefile
@REM Compile example program which contains some of your data (let say some tables)
gcc -I%NEODEV%\m68k\include -m68000 -O3 -Wall -fomit-frame-pointer -ffast-math -fno-builtin -nostartfiles -nodefaultlibs -D__cart__ -c %SRCDIR%\dummyData.c -o %NEODEV%\tmp\dummyData.o
@REM Compile example from binary to object (let say a sprite map from gfxcc.exe for instance)
bin2elf dummy.map dummyMapSprite %NEODEV%\tmp\dummyMapSprite.o
@REM link program
@REM is generating foo2.map cooresponding to P2 ROM (p2rom.o)
gcc -L%NEODEV%\m68k\lib -m68000 -O3 -Wall -fomit-frame-pointer -ffast-math -fno-builtin -nostartfiles -nodefaultlibs -D__cart__ -Wl,-Map,foo2.map %NEODEV%/tmp/yourData.o %NEODEV%\tmp\dummyMapSprite.o -o p2rom.o
@REM Pad program rom
objcopy --gap-fill=0x00 --pad-to=0x100000 -R .data -O binary p2rom.o dev_p2.rom
(eventually you are repeating this process using multiple makefiles resulting in outputs : dev_p2.rom , dev_p3.rom, ... , dev_p9.rom )
ngDataLinker <GCC map file> <out directory>
the command:
ngDataLinker foo2.map ./
will generate header foo2.h in the current directory.
continuing with our pseudo makefile example foo2.h content should be as follow:
#ifndef _FOO2_H_
#define _FOO2_H_
//
//Generated by ngDataLinker 1.0 coded by Ozzy
//
#define dummyData 0x00200010
#define dummyMapSprite 0x00255510
#endif //_FOO2_H_
All generated headers will always produce data addresses within the range [0x00200010,0x002fffff] which is intended using bank switched memory.
Finally, including this header in your code will solve unreferenced data link errors during your main makefile link phase. (build/make)
For compatibility reasons it's better to use two P Rom files.
-
1MB P1 Rom is generated as usual from the main makefile ending with something like the line below :
objcopy --gap-fill=0x00 --pad-to=0x100000 -R .data -O binary test.o dev_p1.rom
then we need romwak to generate proper Rom format
romwak /f dev_p1.rom 202-p1.bin
romwak /p 202-p1.bin 202-p1.bin 1024 255
- 8MB P2 Rom is concatened with multiple 1MB P roms
simply creating p2 Rom into the proper format
romwak /f dev_p2.rom 202-p2.bin
romwak /p 202-p2.bin 202-p2.bin 1024 255
p3 Rom is converted to the proper rom format and then concatenated with P2 Rom
romwak /f dev_p3.rom 202-p3.rom
romwak /p 202-p3.rom 202-p3.rom 1024 255
romwak /c 202-p2.bin 202-p3.rom 202-p2.bin
(etc etc)
romwak /f dev_p4.rom 202-p4.rom
romwak /p 202-p4.rom 202-p4.rom 1024 255
romwak /c 202-p2.bin 202-p4.rom 202-p2.bin
romwak /f dev_p5.rom 202-p5.rom
romwak /p 202-p5.rom 202-p5.rom 1024 255
romwak /c 202-p2.bin 202-p5.rom 202-p2.bin
romwak /f dev_p6.rom 202-p6.rom
romwak /p 202-p6.rom 202-p6.rom 1024 255
romwak /c 202-p2.bin 202-p6.rom 202-p2.bin
romwak /f dev_p7.rom 202-p7.rom
romwak /p 202-p7.rom 202-p7.rom 1024 255
romwak /c 202-p2.bin 202-p7.rom 202-p2.bin
romwak /f dev_p8.rom 202-p8.rom
romwak /p 202-p8.rom 202-p8.rom 1024 255
romwak /c 202-p2.bin 202-p8.rom 202-p2.bin
romwak /f dev_p9.rom 202-p9.rom
romwak /p 202-p9.rom 202-p9.rom 1024 255
romwak /c 202-p2.bin 202-p9.rom 202-p2.bin
Enjoy.