Game Doesn't Run

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Game Doesn't Run

Post by WJYkK » Sat Jan 23, 2010 1:48 pm

Hi everyone! I'm fairly new to the whole NES development scene, so please bare with me. I have attempted numerous times to assemble in ASM6 (which succeeded) and run this code in Nestopia, but I get a "corrupted ROM" message. Please help me if you may.

Code: Select all

.byte "NES",$1a
.byte $10     ;16PRG banks X 16KB/bank = 256KB
.byte $00     ;We got CHR-*RAM*, not ROM
.byte $70,$00 ;AOROM mapper
DSB 8         ;Fill everything with 0s

.org $8000
reset:
	sei			;No IRQs
	cld			;No decimal mode
	ldx #$40
	stx $4017
	ldx #$ff
	txs
	inx
	stx $2000
	stx $2001
	stx $4010

	;Wait VBLANK #1
-	lda $2002
	bpl -
	
	;Clear RAM. Do modern PCs do this anyways?
-	lda #$00
	sta $000,x
	sta $100,x
	sta $200,x
	;Skip $300
	sta $400,x
	sta $500,x
	sta $600,x
	sta $700,x
	lda #$fe
	sta $300,x
	inx
	bne -
	
	;Wait VBLANK #2; then we're ready!
-	lda $2002
	bpl -
	
	;Initialize
	;jsr init_gfx
	;jsr init_ctrl
	;jsr init_snd
	
	;And finally, display what we got!
	;lda #%10000000
	;sta $2000
	lda #%10000000
	sta $2001
	
loop: jmp loop
nmi: rti

.pad $fffa
.word nmi,reset,0

.incbin my.chr
my.chr is exactly 8KB (8192B). Maybe it has to do with Mapper 7?

tepples
Posts: 22014
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Jan 23, 2010 2:22 pm

Mapper 7 should not have CHR ROM. All CHR data should be stored in PRG ROM and copied to CHR RAM at runtime. The header says the file should be exactly 262160 bytes; is this true?
Do modern PCs do this anyways?
You're not making a program to run on "modern PCs". You're making a program to run on a Nintendo Entertainment System. At power on, the contents of the internal RAM aren't predictable. Clearing everything helps define the environment in which your program runs.

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Sat Jan 23, 2010 4:12 pm

So this is odd. I swapped to Mapper 0, progressed until it was a bit clear to me what am I doing, removed the .incbin, and found out I could only place up to 2 16kb PRG-ROM banks (.byte $02 instead of $10). That's not standard, right? How could I increase the ROM size (at the moment it's 32,784 bytes)? And where is the location of CHR-RAM anyways?

I feel like a total newbie. Kinda sad. And about that comment... well, it was just a dumb witty comment. Go figure.

User avatar
Memblers
Site Admin
Posts: 3855
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Sat Jan 23, 2010 5:17 pm

Do you really have that much data already? 32kB is huge for code. If you're just starting out, it's probably better to worry about mappers later, and just use standard NROM (mapper 0). NROM is supposed to have CHR-ROM, but emulators allow you set the # of CHR pages to 0, giving you CHR-RAM instead. I almost always use CHR-RAM, myself.

CHR-RAM is in the same place as CHR-ROM, it's just that the CPU won't normally have a reason to access the ROM (when present). This is mapped into $0000-$1FFF on the PPU's memory, and is accessed the same way nametables and palettes are (starting at $2000 in PPU memory).

If you use mapper #7, there are 2 issues. The main one is that you'll need vectors and a little boot code in every 32kB bank, because it will start up in a random one. The other is "bus conflicts", try a search for that on here and if that doesn't help I'll explain it. But for mapper #7 specifically, I think some (but not all) of the boards have a chip to work around bus conflicts. Kind of a waste of an IC, IMHO, heheh. (unless there's some advantage I'm not aware of)

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Sat Jan 23, 2010 5:59 pm

Really, the only reason I want to use Mapper 7 is for mirroring (HUD, maybe an extra BG layer, etc.) so if there is an easy mapper (or method) to do that without all these issues and whatnot, I'd like some input.

tepples
Posts: 22014
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sat Jan 23, 2010 6:11 pm

Memblers wrote:If you're just starting out, it's probably better to worry about mappers later, and just use standard NROM (mapper 0). NROM is supposed to have CHR-ROM, but emulators allow you set the # of CHR pages to 0, giving you CHR-RAM instead.
Mapper 34 (BNROM) is probably more pedantically correct. (To specify that, use ".byte $20,$20".) But if you specifically want the 1-screen mirroring, you probably want mapper 7 (A*ROM).
But for mapper #7 specifically, I think some (but not all) of the boards have a chip to work around bus conflicts.
  • AMROM has bus conflicts.
  • ANROM has anti-bus-conflict circuit implemented with a 74HC02 chip. This might be considered a waste of an IC.
  • AOROM uses 32-pin ROMs, making room for 256 KiB ROMs and an extra positive chip enable line on pin 31. This CE is connected to R/W, which avoids bus conflicts without another IC.

User avatar
Banshaku
Posts: 2377
Joined: Tue Jun 24, 2008 8:38 pm
Location: Japan
Contact:

Post by Banshaku » Sat Jan 23, 2010 6:20 pm

From my own experience, I wouldn't worry much about the hardware in your current stage of learning ;) There is so many things you don't know at the moment that you cannot yet make the right decision and this is normal.

I would first focus on making a no mapper rom work and learn to code the basics in it so you can get comfortable with programming. By basic I mean to load name table data with attribute in your own format (metatile or not), learn how to define sprite, how to scroll, how to use the NMI the right moment etc.

Once you can do all your basic things, which could be after a few months, a lot of things about the nes will become clearer and you will be able to make better decision.

For example, my current project that I'm working on (the MM9 proof of concept) uses a MMC3 but it doesn't need it at all: it could run on a no mapper rom properly. The only reason I use an MM3 is because that's the only dev cart I have at the moment ;)

Don't rush it for now, it's not hard to switch code from mapper to another when you just starting to experiment with the nes.

User avatar
Memblers
Site Admin
Posts: 3855
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers » Sat Jan 23, 2010 7:17 pm

In this case, you can make a 32kB mapper 7 ROM. That would be fine. If you need more space later, you can easily step up to 64kB, 128kB, 256, etc.

If 4-screen mirroring is any good to you, you could consider that. Only a couple games used it in the past, but it's trivial to add it to new cart (it's on my Squeedo mapper).

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Sat Jan 23, 2010 11:24 pm

Alright, thanks for the answers! I'll try to learn as I go along how to use scrolling and mirroring without mappers. Hopefully the whole mapper issue won't affect me at all.

E: would it be possible to create a "background layer" through mirroring or is using sprites the only choice?

E2: hmm, I remember seeing a few months (years?) ago a good scrolling document on NESDev, but I can't seem to find it anymore. Got any suggestions?

User avatar
tokumaru
Posts: 11744
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru » Sun Jan 24, 2010 1:32 am

WJYkK wrote:E: would it be possible to create a "background layer" through mirroring or is using sprites the only choice?
I'm not sure I understand what you're asking. Do you want to simulate two independently scrolling planes, is that it? If so, mirroring doesn't have much to do with it.

There are 2 common ways to simulate (yes, it's always fake because the NES has only 1 background plane and there is no way around it) multiple scrolling planes. One is to modify the horizontal scroll during rendering to divide the screen in stripes that can scroll independently. This is often referred to as "parallax". The disadvantage of this method is that one planes can never overlap, so this technique is very limited. Also, you have to use something to detect the exact time to change the scroll, such as sprite 0 hits, scanline counters, timed code, or a combination of those.

The other method is to use a repetitive background and dynamically modify the tiles used to draw those parts, so that they appear to be scrolling differently from the foreground. The disadvantage is that you can't do this for detailed backgrounds and it if you use CHR-RAM it will take a lot of VBlank time to modify the tiles (I've only seen games with CHR-ROM using this trick, because they can easily bankswitch the needed tiles).

Here is a video with several games that use one technique or the other, some even use both (Sword Master). These are pretty tough tricks to pull off without mappers, but it's possible. But before trying you should study what these games are doing.
E2: hmm, I remember seeing a few months (years?) ago a good scrolling document on NESDev, but I can't seem to find it anymore. Got any suggestions?
As far as I know, there is no document describing tricks like the ones I mentioned above, I've only seen very simple and direct documents describing what the PPU registers related to scrolling do. Tricks are usually things you have to figure out for yourself, by looking at how the commercial games do it.

What the technical documents describe is nothing amazing, because scrolling is a pretty simple thing actually. It's basically just you telling the PPU from where to start rendering every frame (using register $2005), or several times per frame. If you need to change the vertical scroll mid-screen you have to exploit some obscure PPU details explained in this document.

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Sun Jan 24, 2010 2:48 pm

Alright, I'll consider that. Thanks to everyone who have responded!

CartCollector
Posts: 122
Joined: Mon Oct 30, 2006 8:32 pm

Post by CartCollector » Sun Jan 24, 2010 4:41 pm

(I've only seen games with CHR-ROM using this trick, because they can easily bankswitch the needed tiles).
Actually Battletoads uses that effect for the second level where you're rappelling down the cave. But then again, Battletoads chops off a whole bunch of scanlines, so it has time to do a lot of writes to CHR-RAM.

Also, here's a document which has a whole lot on scrolling, including how to do 4-screen scrolling with only two name tables: http://jonathan.microclub.ch/NES_raster/

User avatar
tokumaru
Posts: 11744
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru » Sun Jan 24, 2010 5:21 pm

Oh yeah, I forgot about Bregalad's doc. Also forgot about Battletoads. Sorry!

WJYkK
Posts: 60
Joined: Thu Dec 24, 2009 12:23 am
Location: Igloo and Bear Land (Canada)
Contact:

Post by WJYkK » Mon Jan 25, 2010 5:38 pm

I don't know, maybe I'm dumb, but I just can't get anything displayed with this code. And yes, I was switching into PAL mode just to see the top row.

Code: Select all

.byte "NES",$1a
.byte $01     ;1PRG-ROM bank X 16KB/bank
.byte $01     ;1CHR-ROM bank X 8KB/bank
.byte $00,$00 ;No mapper
DSB 8         ;Fill everything with 0s

.org $C000
reset:
	sei			;No IRQs
	cld			;No decimal mode
	ldx #$40
	stx $4017
	ldx #$ff
	txs
	inx
	stx $2000
	stx $2001
	stx $4010

	;Wait VBLANK #1
-	lda $2002
	bpl -
	
	;Clear RAM
-	lda #$00
	sta $000,x
	sta $100,x
	sta $200,x
	;Skip $300
	sta $400,x
	sta $500,x
	sta $600,x
	sta $700,x
	lda #$fe
	sta $300,x
	inx
	bne -
	
	;Wait VBLANK #2; then we're ready!
-	lda $2002
	bpl -
	
	;Initialize
	jsr init_gfx
	;jsr init_ctrl
	;jsr init_snd
	
	;And finally, display what we got!
	lda #%10010000 ;NMI,BG comes 4KB later
	sta $2000
	lda #%00011000 ;Render sprites and BG
	sta $2001
	
loop: jmp loop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GFX INIT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

init_gfx:
	jsr init_gfx_palettes
	;jsr init_gfx_sprites
	jsr init_gfx_bg
	jsr init_gfx_attr
	;jsr init_gfx_scroll
	rts

init_gfx_palettes:	
	lda $2002
	lda #$3f
	ldx #$00
	sta $2006
	stx $2006
-	lda palette,x
	sta $2007
	inx
	cpx #$20
	bne -
	rts
	
init_gfx_bg:
	lda $2002
	lda #$20
	ldx #$00
	sta $2006
	stx $2006
-	lda hud,x
	sta $2007
	inx
	cpx #$05
	bne -
	rts
	
init_gfx_attr:
	lda $2002
	lda #$23
	sta $2006
	lda #$c0
	sta $2006
	ldx #$00
-	lda attr,x
	sta $2007
	inx
	cpx #$08
	bne -
	rts

nmi: rti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;STORAGE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.org $e000

palette:
	.db $30,$0f,$0f,$0f, $0f,$0f,$0f,$0f, $0f,$0f,$0f,$0f, $0f,$0f,$0f,$0f
	.db $0f,$0f,$0f,$0f, $0f,$0f,$0f,$0f, $0f,$0f,$0f,$0f, $0f,$0f,$0f,$0f

hud:
	.db $00,$01,$02,$10,$0d
;	.byte "	                        "
;	.byte "SCORE  WORLD        LIVES  STATS"

attr:
	.db #%00000000, #%00000000, #%00000000, #%00000000, #%00000000, #%00000000, #%00000000, #%00000000

.pad $fffa
.word nmi,reset,0

.incbin my.chr
I have no clue what I'm doing wrong.

User avatar
tokumaru
Posts: 11744
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru » Mon Jan 25, 2010 6:02 pm

Your code seems correct, I think your problem is the palette. You have set the first color to white but all others to black. The thing is that some other colors map to the same phisical address as the first color, so you are replacing the white with black, so you only see black.

Change you palette to:

Code: Select all

palette:
   .db $30,$0f,$0f,$0f, $30,$0f,$0f,$0f, $30,$0f,$0f,$0f, $30,$0f,$0f,$0f
   .db $30,$0f,$0f,$0f, $30,$0f,$0f,$0f, $30,$0f,$0f,$0f, $30,$0f,$0f,$0f
And you should see something.

EDIT: found the post saying what palette slots are mirrors. So when you wrote black to $3F10 you replaced the white at $3F00.

Post Reply