Page 1 of 2

nametable questions

Posted: Sat Dec 13, 2008 8:49 pm
by GradualGames
if a screen can contain up to 32x30 tiles, that means we can have 960 tiles on the screen...however a single nametable entry is 8 bits long (right??), so that means you can only have 256 possible unique tiles on the screen and the rest of the 960 must be repeated (from the 256)? If that is true, then how does one load a .chr file without an associated nametable----or do .chr editing programs such as yy-chr output both the pattern table and the name table? If there's an easy non hand holding answer then great otherwise I'm sure I'll get it eventually.

Thanks,
-Zom
nes noob

Posted: Sat Dec 13, 2008 9:41 pm
by Celius
The name table is 32x30 tiles big, yes, and there are 960 8-bit entries for tile data. There are 64 8-bit entries that follow after that in each name table which represent color attribute data (2 bits for each 2x2 block. There's more info about that in NEStech and stuff, and that doesn't seem to be the topic so I'm not going to go too in depth about that).

You have a pattern table that has 256 unique tiles. Each 8-bit entry in the name table for tile data displays that corresponding tile in the pattern table. The pattern tables are drawn with a CHR editor with the intent of forming them into something meaningful on the name table. I'm not quite sure what you mean by loading the pattern table without an associated name table, could you be a little more specific?

Posted: Sat Dec 13, 2008 10:59 pm
by GradualGames
Celius wrote: I'm not quite sure what you mean by loading the pattern table without an associated name table, could you be a little more specific?
I have attempted to use YY-CHR (a tool available from this site) in a tutorial nes program. I haven't yet found enough information to learn what exactly is in the resulting .chr files. I'm assuming it must have a pattern table, a name table, and attributes. I suppose the trick is just knowing where all these tables begin once you've loaded them into the proper location in CHR -rom? I've gotten the file to recognizably load in, but it appears that the offsets are all incorrect. I may have asked my questions prematurely as I haven't dug in as far as I'd like yet. If I'm still stuck after a while I'll be back. Thanks, -Zom

Posted: Sun Dec 14, 2008 12:10 am
by Celius
Pattern tables, and nametables/attributes are different things. CHR data refers specifically to pattern tables. A CHR file includes nothing but pattern table data. If you're using 8k of CHR ROM, that data is already stored on a chip and you don't have to do any writing to the PPU for pattern tables. However, with name tables, you have to write to the PPU. Attributes are part of the name table. So they, too, must be written to the PPU. Palette data also has to be written to the PPU.

Posted: Sun Dec 14, 2008 8:37 am
by GradualGames
Ok, I understand now. The tool I was trying, yy-chr only makes the pattern tables---I will need a seperate tool for arranging/designing the name tables and attribute tables. Upon looking at the list of tools available here, looks like there are tools that can do each of these things. Thanks, -Zom

How to set up the attribute table

Posted: Thu Jan 08, 2009 10:02 pm
by bbbirddd
I have been having trouble with name tables and attribute tables. I was trying to use GBAguy's map2bin program, but I was getting annoyed with it so I decided to try other programs. I wanted something to help with making name tables and attribute tables, so I tried NES Screen Arranger but I can't figure out how to run the darn program in XP. So I decided to write the nametable into my code directly. So I came up with this:

Code: Select all

tilepal: .incbin "our.pal"		; include pallete and label its location "tilepal"
ourMap2:.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
ourMap:	.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db 17,18,17,18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
			
; .incbin "map20.map" 	; include map files and label its location "ourMap"
; ourMap2: .incbin "bkg21.map"

; ////////////////////////Bank 2: CHR ROM - Sprite/Background Data//////////////////////

	.bank 2				
	.org $0000
	.incbin "bkg.bkg"
	
	.org $1000
	.incbin "our.spr"
(I added a little extra of the code around the table so you can get a sense of where I placed it)

Now, this seems to work, except I tried to make my rom so that when I press the A key, the background changes (it basically just adds ourMap2, but I don't think that's really important for my problem). When I do this, the background does change correctly, but the colors get all screwed up and some random background tiles flicker around the screen (in Nintendulator). I think the problem has to do with the fact that I'm not dealing with the attribute table part correctly, but I don't really understand it. I've looked in a number of recommended docs, but they all seem sort of unhelpful. So if anyone could give me suggestions about how I can directly deal with attribute tables in my above code (or a good method that works with XP for setting up nametables and attribute tables in a GUI) that would be excellent. Thanks :D

Posted: Thu Jan 08, 2009 10:26 pm
by Celius
I bet your code isn't executed with the screen shut off. It needs to either be within natural Vblank (NMI is fired on the start of this), or in a forced Vblank. So for a quick fix, write:

lda #$00
sta $2001

before your updating code is executed. Then afterwards, turn the screen back on with whatever settings you had before.

EDIT: Try Tepple's Name Table Editor, too. This works on XP.

Posted: Thu Jan 08, 2009 10:37 pm
by bbbirddd
Celius, yep that worked. I still get an odd effect when I execute my rom, however. It's a flickering of my background that occurs at the bottom of the screen (I only want the tiles to appear toward the top, just moving slightly up and down with A presses. It might have to do with the way I'm just adding another row onto the top of the nametable. I'll try to muck around with it a bit and see).

About Tepple's Name Table Editor, where can I find that? I don't see it under the Graphics Tools.

Thanks for the help!

Posted: Thu Jan 08, 2009 10:46 pm
by Celius
I think if you click on tepples' "www" it should take you to his site, where I think you can download it. For some reason, it's not listed under the tools though...

Your flickering is caused by shutting the screen off, I think. If you execute the code during Vblank, and make sure it takes less than ~2200 cycles, there shouldn't be any flickering.

Posted: Thu Jan 08, 2009 11:05 pm
by bbbirddd
Thanks I got Tepple's editor so I'll try that out.

Regarding the flickering, I think I am running it during VBlank. I'm truly a noob to both NES and assembly, so I might have this wrong. This is the code that controls the background when A is pressed:

Code: Select all

AKEYdown:						; code executed when A is pressed

vblankwait1:
	lda $2002
	bpl vblankwait1
	
	lda #$00					; turn the screen off
	sta $2001 

	lda #$20					; reset to beginning of name table
	sta $2006
	sta $2006

	lda BKGset					; check which background is loaded
	cmp #0
	bne BG1

	
	ldx #$00
loadNames2:						; switch to background 2 (1 is loaded originally)
	lda ourMap2, x
	inx
	sta $2007
	cpx #4*32
	bne loadNames2
	lda #1
	sta BKGset

	lda #%00011110				; turn the screen back on
	sta $2001		

	jmp NOTHINGdown
	
BG1:
	
	ldx #$00					
loadNames3:						; switch to background 1
	lda ourMap, x 				
	inx							
	sta $2007					
	cpx #4*32 					
	bne loadNames3 				
	lda #0
	sta BKGset
	
	lda #%00011110				; turn the screen back on
	sta $2001	
	
	jmp NOTHINGdown
(I have BKGset set to zero in the beginning of my code)

I'm not sure how to test whether or not it takes less than 2200 cycles (and I'm also not sure what that means). I'm not sure if this is something I can see with my emulator, but I generally use Nintendulator and also have Nestopia and Jnes. Any help would be appreciated. Again, I'm new at this, so sorry if these are basic questions.

Posted: Thu Jan 08, 2009 11:37 pm
by Celius
How long code takes to execute is measured in "cycles". For example, "LDA #2" takes 2 cycles to execute. "LDA ($23),y" takes 5 cycles to execute. A scanline (a horizontal row of pixels on the screen) is rendered in the time it takes for the NES to execute 113.333 cycles worth of instructions. Vblank, a period of time in which no rendering takes place, lasts for 2200 cycles. It turns out with some technical stuff that a whole frame is drawn in ~30,000 cycles. For this reason, code has to be optimized so it doesn't take a really long time to execute. For cycle counts on each instruction, refer to:

http://www.obelisk.demon.co.uk/6502/reference.html

So, with this in mind, it seems that you are in a loop, starting from Vblank, looping 4*32 (128) times. Let's time the loop:

Code: Select all

        
loadNames3:                  ; switch to background 1
   lda ourMap, x     ;4            
   inx                     ;6
   sta $2007      ;10               
   cpx #4*32         ;12       
   bne loadNames3   ;15
Going through the loop once takes 15 cycles. This loop is executed 128 times. 128 * 15 = 1920. That's 1920 cycles there, which means that it should take less time than is in Vblank. What might be happening is that you wait for Vblank, then you jump to the "AKey" routine, then by the time you return to the game loop, it checks for Vblank, and it reads that you're still in Vblank, and it executes the same code twice, thus spilling out of Vblank. Try putting this in the very beggining of your endless loop:

WaitOutOfVblank:
lda $2002
bmi WaitOutOfVblank

Then after that comes:

WaitVblank:
lda $2002
bpl WaitVblank

This waits until Vblank isn't being executed to check for it again. This may fix your problem.

Posted: Thu Jan 08, 2009 11:45 pm
by bbbirddd
I pasted in both of those parts together just after my "infinite" loop starts, and you're right, it doesn't flicker anymore, but now it takes about 4 seconds before I can change the background by pressing A. Is there a way to make this a lot quicker? Is it possible to load my other nametable into $2400 and then somehow switch to it more quickly?

Posted: Thu Jan 08, 2009 11:59 pm
by Celius
4 seconds?? That's not normal... Nothing should take 4 seconds to execute unless you're trying to do something REALLY REALLY complex. 4 seconds is 240 frames. This should be running at a rate where it takes 1 frame to execute (1/60 of a second). Heck, even 3D could be handled on the NES in under 4 seconds (it has been, in a LOT less than 4 seconds).

There has to be some other problem here. I suggest you place your controller code in the NMI routine instead of the endless loop. And then you can eliminate all "lda $2002, bpl loop" statements.

Also, if you write to the name table at $2400, all you have to do is set bit 0 of $2000.

Posted: Fri Jan 09, 2009 12:22 am
by bbbirddd
Thanks for the help. I think it's getting too late for me to think about this (i'm in NH). I tried to do what you said but I don't think I get it. I'll take another look in the morning. Here's my code in case you'd like to take a look:


Code: Select all

	.inesprg 1					; /////INES Header/////
	.ineschr 1
	.inesmap 0
	.inesmir 1
	
; ////////////////////////Bank 1: PRG ROM - Interrupt Table/////////////////////////////


	.bank 1
	.org $FFFA
	.dw VBlank_Routine			; address to execute on VBlank
	.dw Start
	.dw 0

; ////////////////////////Bank 0: PRG ROM - Program Code////////////////////////////////

	.bank 0
	.org $0000					; /////Variables/////
	
VBlankOrNo:	.db 0
BKGset:		.db 0
								; /////Sprite DMA/////
						
	.org $0300 					; OAM copy location

Sprite1_Y:		.db	0			; sprite #1's Y value
Sprite1_T:		.db	0 			; sprite #1's tile number
Sprite1_S:		.db	0  			; sprite #1's special byte
Sprite1_X:		.db	0			; sprite #1's X value
UnusedSprites: 	.db 0

	.org $8000					; program code location
	
Start:							; /////Screen Setup/////

	sei 						; just some stuff that's standard to do at reset
	cld
	ldx #$FF
	txs 

	lda #00						; set every variable to zero
	sta Sprite1_Y
	sta Sprite1_T
	sta Sprite1_S
	sta Sprite1_X
	sta VBlankOrNo
	sta BKGset
	sta UnusedSprites

	lda #$FF					; clear OAM with $FFs (except for Sprite1_* variables)
	ldx #0
ClearSprites:
	sta UnusedSprites, x
	inx
	cpx #252
	bne ClearSprites
	
	lda #0
	sta $2000
	sta $2001					; turn the PPU off
	
wait1:							; wait (why?)
	lda $2002
	bpl wait1

wait2:
	lda $2002
	bpl wait2

	lda #50						; set initial sprite position to 50,50
	sta Sprite1_Y
	sta Sprite1_X
	lda #0
	sta Sprite1_S				; set initial sprite color
	lda #1
	sta Sprite1_T

								; /////32-Color Palette/////
	
	lda #$3F					; $2006 = PPU memory address
	sta $2006					; $3F00-$3F10 = image palette location (the first half of the 32 colors)
	lda #$00					; $3F10-$3F20 = sprite palette location (the second half of the 32 colors)
	sta $2006

	ldx #$00
loadpal:						; load 32-color pallete
	lda tilepal, x
	sta $2007					; $2007 = PPU memory data
	inx
	cpx #32
	bne loadpal
	
								; /////Background/////

	lda #$20
	sta $2006 					; $2020-$23C0 = name table 0 (32x25 tiles)
	sta $2006 

	ldx #$00
loadNames:						; load background name table (bkg12.map)
	lda ourMap, x
	inx
	sta $2007					; $2007 = PPU memory data
	cpx #4*32
	bne loadNames

								; /////Screen Setup/////
	
	lda #%10001000				; screen pattern table = $0000, sprite pattern table = $1000, name table = $2000
	sta $2000
	lda #%00011110				; BG = black, show sprites, screen on, don't clip anything, color display
	sta $2001	
	
; ------------------------Controller Loop Begin-------------------------------

infinite:				

;WaitOutOfVblank:
;	lda $2002
;	bmi WaitOutOfVblank 
	
;WaitVblank:
;	lda $2002
;	bpl WaitVblank 

WaitForVBlank:					; /////VBlank/////		
	lda VBlankOrNo
	cmp #1						; check if A = 1 (VBlank)
	bne WaitForVBlank			; if A = 0 loop
	dec VBlankOrNo				; decrease VBlankOrNo by 1 (A = 0)
	
	lda #3						; /////Sprite Info Load/////
	sta $4014					; $4014 = sprite DMA register (transfers 
	
								; /////Controller Setup/////
	
	lda #$01					; reset pad #1
	sta $4016					; $4016 = joypad #1 (1 = reset, 0 = clear)
	lda #$00
	sta $4016


VBlank_Routine:					; /////VBlank Routine/////
	inc VBlankOrNo				; at VBlank add 1 to VBlankOrNo (1 if VBlank, 0 if not)
	
								; /////Test Button Status/////
	
	lda $4016					; read A status
	and #1						; if the low-order bit is equal to 1, the button is pressed
	bne AKEYdown				; branch to AKEYdown if 
	
	lda $4016					; read B status
	lda $4016					; read SELECT status
	lda $4016					; read START status
	
	lda $4016					; read UP status
	and #1						; check if UP is pressed
	bne UPKEYdown				; branch to UPKEYdown if pressed
	
	lda $4016					; read DOWN status
	and #1						; check if DOWN is pressed
	bne DOWNKEYdown				; branch to DOWNKEYdown if pressed

	lda $4016					; read LEFT status
	and #1						; check if LEFT is pressed
	bne LEFTKEYdown				; branch to LEFTKEYdown if pressed

	lda $4016					; read RIGHT status
	and #1						; check if RIGHT is pressed
	bne RIGHTKEYdown			; branch to RIGHTKEYdown if pressed
	jmp NOTHINGdown

								; /////Button Press Actions/////
							
AKEYdown:						; code executed when A is pressed

	lda #$00					; turn the screen off
	sta $2001 

	lda #$20					; reset to beginning of name table
	sta $2006
	sta $2006

	lda BKGset					; check which background is loaded
	cmp #0
	bne BG1

	
	ldx #$00
loadNames2:						; switch to background 2 (1 is loaded originally)
	lda ourMap2, x
	inx
	sta $2007
	cpx #4*32
	bne loadNames2
	lda #1
	sta BKGset

	lda #%00011110				; turn the screen back on
	sta $2001		

	jmp NOTHINGdown
	
BG1:
	
	ldx #$00					
loadNames3:						; switch to background 1
	lda ourMap, x 				
	inx							
	sta $2007					
	cpx #4*32 					
	bne loadNames3 				
	lda #0
	sta BKGset
	
	lda #%00011110				; turn the screen back on
	sta $2001	
	
	jmp NOTHINGdown				

UPKEYdown:						; code executed when UP is pressed
	lda Sprite1_Y
	clc
	sbc #1  					; subtract 1 from Sprite1_Y
	sta Sprite1_Y
	jmp NOTHINGdown

DOWNKEYdown:					; code executed when DOWN is pressed
	lda Sprite1_Y 
	clc
	adc #1  					; add 1 to Sprite1_Y
	sta Sprite1_Y
	jmp NOTHINGdown

LEFTKEYdown:					; code executed when LEFT is pressed
				
	lda Sprite1_S
	and #%10111111
	sta Sprite1_S
	lda Sprite1_X
	clc
	sbc #1  					; subtract 1 from Sprite1_X
	sta Sprite1_X
	jmp NOTHINGdown

RIGHTKEYdown:					; code executed when RIGHT is pressed
	
	lda Sprite1_S
	ora #%01000000
	sta Sprite1_S
	lda Sprite1_X
	clc
	adc #1						; add 1 to Sprite1_X
	sta Sprite1_X
								; return from interrupt
NOTHINGdown:
	rti
	
	jmp infinite
; ------------------------Controller Loop End---------------------------------

								; /////Include Binary Files/////

tilepal: .incbin "our.pal"		; include pallete and label its location "tilepal"
ourMap2:.db  1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2
		.db 17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18 
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		
ourMap:	.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2
		.db 17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18,17,18 
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
		.db  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
			
; .incbin "map20.map" 	; include map files and label its location "ourMap"
; ourMap2: .incbin "bkg21.map"

; ////////////////////////Bank 2: CHR ROM - Sprite/Background Data//////////////////////

	.bank 2				
	.org $0000
	.incbin "bkg1.bkg"
	
	.org $1000
	.incbin "our.spr"
	

Posted: Fri Jan 09, 2009 12:34 am
by Celius
The following revision should work:

Code: Select all

------------------------Controller Loop Begin-------------------------------

infinite:
	jmp infinite

VBlank_Routine:
   lda #3                  ; /////Sprite Info Load/////
   sta $4014               ; $4014 = sprite DMA register (transfers
   
                        ; /////Controller Setup/////
   
   lda #$01               ; reset pad #1
   sta $4016               ; $4016 = joypad #1 (1 = reset, 0 = clear)
   lda #$00
   sta $4016
                        ; /////Test Button Status/////
   
   lda $4016               ; read A status
   and #1                  ; if the low-order bit is equal to 1, the button is pressed
   bne AKEYdown            ; branch to AKEYdown if
   
   lda $4016               ; read B status
   lda $4016               ; read SELECT status
   lda $4016               ; read START status
   
   lda $4016               ; read UP status
   and #1                  ; check if UP is pressed
   bne UPKEYdown            ; branch to UPKEYdown if pressed
   
   lda $4016               ; read DOWN status
   and #1                  ; check if DOWN is pressed
   bne DOWNKEYdown            ; branch to DOWNKEYdown if pressed

   lda $4016               ; read LEFT status
   and #1                  ; check if LEFT is pressed
   bne LEFTKEYdown            ; branch to LEFTKEYdown if pressed

   lda $4016               ; read RIGHT status
   and #1                  ; check if RIGHT is pressed
   bne RIGHTKEYdown         ; branch to RIGHTKEYdown if pressed
   jmp NOTHINGdown

                        ; /////Button Press Actions/////
                     
AKEYdown:                  ; code executed when A is pressed

   lda #$00               ; turn the screen off
   sta $2001

   lda #$20               ; reset to beginning of name table
   sta $2006
   sta $2006

   lda BKGset               ; check which background is loaded
   cmp #0
   bne BG1

   
   ldx #$00
loadNames2:                  ; switch to background 2 (1 is loaded originally)
   lda ourMap2, x
   inx
   sta $2007
   cpx #4*32
   bne loadNames2
   lda #1
   sta BKGset

   lda #%00011110            ; turn the screen back on
   sta $2001      

   jmp NOTHINGdown
   
BG1:
   
   ldx #$00               
loadNames3:                  ; switch to background 1
   lda ourMap, x             
   inx                     
   sta $2007               
   cpx #4*32                
   bne loadNames3             
   lda #0
   sta BKGset
   
   lda #%00011110            ; turn the screen back on
   sta $2001   
   
   jmp NOTHINGdown            

UPKEYdown:                  ; code executed when UP is pressed
   lda Sprite1_Y
   sec
   sbc #1                 ; subtract 1 from Sprite1_Y
   sta Sprite1_Y
   jmp NOTHINGdown

DOWNKEYdown:               ; code executed when DOWN is pressed
   lda Sprite1_Y
   clc
   adc #1                 ; add 1 to Sprite1_Y
   sta Sprite1_Y
   jmp NOTHINGdown

LEFTKEYdown:               ; code executed when LEFT is pressed
            
   lda Sprite1_S
   and #%10111111
   sta Sprite1_S
   lda Sprite1_X
   sec
   sbc #1                 ; subtract 1 from Sprite1_X
   sta Sprite1_X
   jmp NOTHINGdown

RIGHTKEYdown:               ; code executed when RIGHT is pressed
   
   lda Sprite1_S
   ora #%01000000
   sta Sprite1_S
   lda Sprite1_X
   clc
   adc #1                  ; add 1 to Sprite1_X
   sta Sprite1_X
                        ; return from interrupt
NOTHINGdown:
   rti
; ------------------------Controller Loop End--------------------------------- 
Replace the code between the "Controller Loop Begin" and "Controller Loop End" breaks with the code above. I fixed some things so that you aren't doing anything in the endless loop, because you don't need to be doing anything in it. It's all done in the NMI.