Please read, don't tl;dr and run the 'out.nes' file; it's possibly the most boring NES file you'll see in your whole life, it just cycles the background color slowly.
Basically I wanted to play with mapper 69 (FME-7) using ca65/ld65 and I wanted to do things clean: configuring the NES header, managing PRG-ROM banks, etc. Now I wrote a set of assembly and include files along with a linker script, and I thought of a "system" that could hopefully apply to other mappers. This "system" is just a bunch of files that one would use to NESdev quickly on a particular mapper. It describes the mapper and allow easy configuration of the NES header and code/data placement in segments (the segments are PRG banks); any data placed in a segment can be easily accessed without knowing exactly where it is located.
So, now the NESdev-kit consists of:
- nes-header.s/.inc : these files describe a NES v1 header. These files does not need to be edited;
- configure.inc : contains macros to configure the NES header. One would just have to 'call' them to configure the NES file;
- core.s/.inc : core definitions, it declares the 6502 vectors and other 'core' things;
- mapperN.s/.inc (not currently in the zip file) : macros and routines to control mapper N's registers.
- mapperN.ld : Linker script for mapper N. Unfortunately, in most cases this file would need to be edited in a project, but the edits would be minimal and located at one particular place.
configure.inc currently contains these 2 macros:
- nesconfig mirroring, mapper, batterybackupsram
configure mirroring, mapper and whether there is battery backed SRAM. The last parameter is optional and defaults to 'no'. Choosing a mapper with this macro just merely verify that the appropriate linker script is used to link the NES program, an assert fires if the mapper parameter don't match with the linker script; - nessize nprgrombank_16K, nchrbank_8K, nprgrambank_8K
configure PRG-ROM, CHR-ROM/RAM and PRG-RAM size. The last two parameters default to 0.
Now for the bank mapping thing:
If you look at the linker script (it's pretty big and ugly, but it does the job) you'll find at the SEGMENT section, a bunch of PRGBK** segment definitions. It's suited for FME-7. One can configure the runtime address for a segment (bank) really quick: change the x in "run = ROMSByyATx000" to 6/8/A/C, and you basically changed the runtime address of the PRG bank yy.
Now look at foo.s in the zip file, the code is not so good but it illustrates that code in other segments is easily accessible. The nmi basically calls some_routine which is located in another bank. The nice thing is, the following code will map the bank where some_routime is located at the runtime address it expects to be, and successfully calls it:
Code: Select all
; FME-7: select bank of some_routine where it expects to be run.
ldy #(8 + >.bank(some_routine))
lda #<.bank(some_routine)
sty $8000
sta $A000
jsr some_routine
Now for the NESdev-kit project, it would simply involve having other mappers defined and refine the kit, as I surely have overlooked some things. There are some easy mappers, but some (MMC3 and particularly MMC5) will cause trouble. That's why I want to bring your lights here. The goal would be to make "The NESdev-kit" that would allow novice programmers to easily start a NESdev project with a mapper of his choice, it should be as user-friendly as it is possible by using only the cc65 toolsuite. If it becomes mature enough, a simple "wizard" in NESICIDE would setup automatically all the rest that can't just be done with cc65 et al. While I only consider assembly, I think it might be doable to somewhat support some banking features in C but I haven't looked into it at all; if it's possible to do it, it would be even nicer because it would lower even more the "entry-level" for programming a NES game—well, a big one, as Shiru insisted on the fact that the biggest problem with C in cc65 was code size.
Any relevant suggestion, criticism, is more than welcome.