NES Rom Expansion 102
by: TFG (palacios_barreda!at!yahoo!dot!com!dot!mx)
-------------------------------------------------


+--------------+
| Introduction |
+--------------+

Welcome to the second part of my attempt to cover the basics of NES rom expansion. For this document, I decided to use 'Dig Dug'. It's a mapper 0 rom, easy to work with and perfect for our mapper hack.

+----------+
| Rom info |
+----------+

Format  - iNES
Mapper  - 0
PRG-ROM - 16K
CHR-ROM - 8K

+----------------------------+
| What mapper should I pick? |
+----------------------------+

You have quite a large list to chose from. Your decision depends on the plans for your hack. For instance, if you want to make a music hack (or just want some really good music included in your hack), your best pick would be Namcot 106 (aka Mapper 19). This mapper supports a few extra audio channels (other than the 4 supported by the NES, 5 if you count DMC.). If you want a more versatile mapper (extra PRG-ROM & CHR-ROM, to name a few features), Mapper 4 (aka MMC3) is the perfect solution.

Some mappers are harder to implement than others. For this example, I decided to use Mapper 3 (CNROM) as it has only one register and it's very easy to setup. (for a more gentle learning curve's sake).

By this point you should already have a copy of /Firebug/'s 'Comprehensive NES Mapper Document'.

+---------------------------------------------------------------------------+
|                                                                           |  
| Ŀ                                                       |
|  Mapper 3: CNROM                                                        |
|                                                        | 
|                                                                           |
| Ŀ    |
|  This mapper is used on many older U.S. and Japanese games, such as     |
|  Solomon's Key, Gradius, and Hudson's Adventure Island.                 |
|     |
|                                                                           |
| Ŀ   Ŀ      |
|  $8000  $FFFF Ĵ CCCCCCCC                                           |
|                                                |
|                                                                        |
|                                                                        |
|                          Select 8K VROM bank at PPU $0000       |
|                           |
|                                                                           | 
| Notes: - The ROM size is either 16K or 32K and is not switchable. It is   |
|          loaded in the same manner as a NROM game; in other words,        |
|           it's loaded at $8000 if it's a 32K ROM size, and at $C000 if    |
|           it's a 16K ROM size. (This is because a 6502 CPU requires       | 
|           several vectors to be at $FFFA  $FFFF, and therefore ROM needs | 
|           to be there at all times.)                                      |
|        - The first 8K VROM bank is swapped into PPU $0000 when the cart   |
|           is reset.                                                       |
|        - This is probably the simplest memory mapper and can easily be    |
|           incorporated into a NES emulator.                               |
+---------------------------------------------------------------------------+

Each mapper has one or more registers. These registers are the mapper's control panel. In this particular case, the only port avaliable is located in the $8000-$FFFF range of the CPU memory. What does that mean? Well, if you write a number (a bank number) to any address within this range, you are going to trigger the mapper's functionality.

lda #$01
sta $8000

In other words, load 8K of CHR-ROM at PPU $0000. If you aren't sure of what PPU $0000 means, you should go back and re-read Yoshi's NES documentation.

+-------------------+
| Adding the mapper |
+-------------------+

Open up a hex editor, load you iNES Dig Dug rom image and modify the mapper number (that'd be offset 06h, set it to 0x30). Refer to your iNES format document to figure out why 0x30 and not 0x03 as you expected.

As almost every other Mapper 0 rom, this game has little to none free space. The mapper we picked doesn't have PRG-ROM swapping capabilities, however, it uses only 16K of PRG-ROM; which means we can add an extra bank.

Modify the PRG-ROM flag of you iNES header (offset 04h = 0x02) and insert 0x4000 bytes at offset 10h. Test your rom.

There you go. Now you have a Mapper 3 rom with a free 16K bank of PRG-ROM waiting to be exploited.

+----------------+
| Making it work |
+----------------+

Since this mapper focuses on CHR-ROM, we'll have to add an extra 8K bank of CHR-ROM to test it. Use the CHR-ROM bank that comes with this guide or rip your own from any other game.

Insert new_gfx.chr at offset A010h and update the iNES CHR-ROM flag (offset 05h = 0x02)

We have to re-allocate some of the game's code to make our new PRG-ROM bank usable. Run your rom in FCEUd and press F1. Scroll down to $FFFA and write those 2 bytes down (0x000C) 16 bit pointers are stored backwards, so, the correct address spells: $C000. That's the CPU address of the RESET vector (refer to Yoshi's documentation to learn more about interrupts). This means that whenever the game starts or gets reset, it'll jump to that address.

We are going to add a simple 'PRESS ANY BUTTON TO CONTINUE' screen to test our new gfx.

Use x816 to assemble
--------------------

.MEM 8
.INDEX 8
.BASE $8000

new_reset:

lda #$01
sta $8000
jmp $c000

.END

--------------------

$C000 is the address for the reset vector. Since we want our hack-screen to appear before the game's title screen, a quick solution would be to redirect the game to our code in order to anticipate the title screen. Assemble and insert that code at offset 10h ($8000 in terms of CPU memory). Now, update the vector table and set the reset interrupt to $8000 (800Ch = 0x0080). Remember that the interrupt table is located at the end of the last 16K PRG-ROM bank.

Basically, the code is telling the mapper to load CHR-ROM Bank #1 into PPU $0000 (counting from 0). Refer to the mapper's chart posted earlier.

You should get a full working game with a different font and glitchy (non-font) graphics. Now, let's add our 'PRESS..' screen and make it work like it is supposed to.

I added a few comments to the code. If you have specific questions about the code, either, drop me a line or go to #consoledev at espernet.

Use x816 to assemble 
Insert at offset 10h
--------------------

.MEM 8
.INDEX 8
.BASE $8000

new_reset:

-	lda $2002
	bpl -
--	lda $2002
	bpl --

; Load chrt

_ge aidAMldaeset:

l	da #$01
sta ; Tuon nse'PRESS.ldaeset:
0
l	da #$
--
l	jsameatio_PRESS.lda ; WFFA apacs.creldaeset:
3F
l	da #$
--6ldaeset:
0
l	da #$
--6	ldaesxt:
0
l	bpl -pac_. Na,x
l	da #$
--7
l	inx
l	cpxt:
10
l	bp m-lda ; WFFA aagoibuNow,terru. Naldaesxt:
40ldaeset:
23
l	da #$
--6ldaeset:
C0
l	da #$
--6ldaeset:
0
l-	da #$
--7
l	dex
l	bp m-ld		lda ; WFFA aet's"to a"ldaeset:
20
l	da #$
--6ldaeset:
82
l	da #$
--6ldaesxt:
0
laesetstr_CEUd ,x
la ; Convble ASCII the gamifferbouta ; 'A'00 $41 (ASCII)a ; 'A'00 $0A (PROPIETARY)a 	
l-	dec
l	dbct:
37
l	da #$
--7
l	inx
l	esetstr_CEUd ,x
l	bp m-		;an? 0 thxorkloopldaeset:
0
l	da #$
--5
l	da #$
--5
la ; Tuon nn'PRESS.ldaeset:%nto 1010
l	da #$
--
l	eset:%nto100
0
l	da #$
--
sta ; R andkey
u s_key:	ldaeset:
0
l	da #$4016ldaeset:
1
l	da #$4016ldaesyt:
8_reset:
4016lda' sc:
1
l	bas onters nser
l	dey
l	bp m-ld	a $8u s_keysta onters nser:ldaeset:
0
l	da #$
--
 ; tuon nse'PRESS.ldaeset:
0
l	da #$rupt pl --
 Use the CHR-0ld	a $8000
 plG shouldcommentorigis fd set trstiop sta str_CEUd :lda.db " simple 'PRESS ANY BUTTON TO",
sta pac_. Na:lda.db $02,$30,$30,$30lda.db $02,$30,$30,$30lda.db $02,$30,$30,$30lda.db $02,$30,$30,$30lda ; Catio'PRESS.ldeatio_PRESS.:ldaeset:
20
l	da #$
--6	ldaeset:
0
l	da #$
--6ldaesyt:
4_resetxt:
FFldaeset:
ff2
	bda #$
--7
l	dex
l	bp m--
l	dey
l	bp m-ld	 gajmp $c000
set 10h
--------------- work |
+----------This meitld I pick? |
+----+her gadee e Ikin getempt up. (foed plible isnce this ddressfis fdasics of NES rom o Yoshi'spper hack.

+------Mini-FAQ Rom info |
+------Q: Wrom.
do Iku sh.

?
A: http://www.googbaned /stioch?q=.

+ x816 tor+ 2 bappe----Q: .

e picked makem oXP!
A: Imory. W mak000 mreset,stOM, we'll ssign to lesimplese hato Righerbleen,MMC3)roon-m Noir g in FCEUd a'p'terruptin gebrfullup,MMC3)ro th capme alogis ddre me)roon-m. Caeen, depend'Mimple'w,tetor tables almddreg0). Refer xle  .pn? .
rtc fign gebfoerele ihics, weit    to.----Q: Wr$C000$nnnnis d?
A: disc mald.ledev. at or go to #c