How to get rid of the sprite ($00) in top left corner?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
Sebastian_L
Posts: 17
Joined: Tue Feb 16, 2021 12:31 pm

How to get rid of the sprite ($00) in top left corner?

Post by Sebastian_L » Mon Feb 22, 2021 8:58 am

Hello,

I have just compiled code from a tutorial.

One thing I noticed is, that in the top left corner is a little bit from the sprite tile $00.

The zeros are from the background tile, because I haven't set a background jet. So it is tile $00 with color palette $00.

1. So how do I fix the top left corner?

2. To fix the background I would use nametables? (.db $... and so on)

3. When I look at the Debug HexEditor in fceux the RAM is changing crazy (offset 005000 till 006000). Is it normal? (There is no movement on screen. Is it because the NMI handler is used for graphics updates?)

Thank you in advance for your answers!

Code: Select all

;; 1. The iNES Header
   .db "NES", $1a		;INES identifier
   .db $01				;number of PRG-Rom blocks the game will have
   .db $01				;number of CHR-Rom blocks the game will have
   .db $00, $01			;control bytes
   .db $00, $00, $00, $00, $00, $00, $00, $00		;filler


;; 2. Constants and Variables
   .enum $0000			;variables will eventually go here
   .ende


;; 3. Set the code starting point
   .org $C000			;this starts the code at the address $C000


;; 4. The RESET routine
;;turn things off and initialize
RESET:
   SEI					;SEI tells the code to ignore interrupts for the routine
   LDA #$00				;load 0 into the accumulator
   STA $2000			;disable the NMI
   STA $2001			;disable rendering
   STA $4010
   STA $4015
   LDA #$40				;loads HEX value 40 which is dec value 64
   STA $4017
   CLD					;disable decimal mode
   LDX #$FF				;loads value 255
   TXS					;initialize the stack
   bit $2002
vBlankWait1:
   bit $2002
   BPL vBlankWait1
   
;;clear out memory etc.
   LDA #$00				;loads zero into the accumulator
   LDX #$00				;loads zero into x
;;ready to start loop
ClearMemomryLoop:
   STA $0000,x			;store accumulator 0 into address $0000+x
   STA $0100,x			;store accumulator 0 into address $0100+x
   STA $0200,x			;store accumulator 0 into address $0200+x
   STA $0300,x			;store accumulator 0 into address $0300+x
   STA $0400,x			;store accumulator 0 into address $0400+x
   STA $0500,x			;store accumulator 0 into address $0500+x
   STA $0600,x			;store accumulator 0 into address $0600+x
   STA $0700,x			;store accumulator 0 into address $0700+x
   INX					;x goes up by one, so all of those + x's at the end that were zero the first time through are increased
   BNE ClearMemomryLoop	;loop again until all adresses + x (#$FF = 255) become 0


vBlankWait2:
   bit $2002
   BPL vBlankWait2

;;turn things back on now that we're set up
   LDA #%10010000		;loads this binary number to accumulator = 144 decimal
   STA $2000			;storing it here, turns NMI back on
   LDA #%00011110		;loads this binary number to accumulator = 30 decimal
   STA $2001			;enables rendering
   
   JMP MainGameLoop


;; 5. The NMI
NMI:
   ;PUSH registers to the stack to preserve them
   PHA					;this pushes the accumulator to the stack, it is the first thing there.
   TXA					;this loads whatever is in X into the accumulator
   PHA					;and pushes it into the accumulator, now the old 'A' is on the bottom and X is on top of it
   TYA					;this loads whatever is in Y into the accumulator
   PHA					;and pushes the accumulator to the stack, now Y is on top, X is in the middle and A is in the bottom
   
   
;;do NMI things here
;;transfer sprites to PPU
   LDA #$00				;puts 0 into the accumulator (low byte)
   STA $2003			;sets the low byte of the sprite RAM address
   LDA #$02				;puts 02 into the accumulator (high byte)
   STA $4014			;sets high byte of the RAM address and starts transfer
   ;read backwards: RAM address we loaded 00
   ;then loaded 02 (this has loaded low byte of 00, high byte 02 = it is a 16-bit address)
   ;high+low (02+00 or $0200), this the address for our sprite data
   
   ;load the palettes
   LDA $2002
   LDA #$3F
   STA $2006
   LDA #$00
   STA $2006
   LDX #$00
   
   ;ready to start loop
LoadPaletteLoop:
   LDA MyPalettes,x		;load value from the table that x equals to
   STA $2007			;store it to the address that handles palettes
   INX					;increase x
   CPX #$20				;compare it to hex 20 = 32 decimal (8 banks of 4 colors), so 32-times the loop
   BNE LoadPaletteLoop	;if 32-x is not 0, then start loop again
   
   
   
   
   LDA #%10010000		;turns on NMI, like in RESET = 144 decimal
   STA $2000
   LDA #%00011110		;turns on rendering, like in RESET = 30 decimal   
   STA $2001



   ;PULL registers from the stack and restore them
   ;first thing to pull is the top, then go down
   PLA					;pulls the top stack and put it in the accumulator
   TAY					;puts that value into Y, now Y is restored to what it was before NMI
   PLA					;pulls second stack value and puts it in accumulator
   TAX					;puts that value into X, now X is restored to what it was before NMI
   PLA					;pulls third stack value and puts it in accumulator, now Y, X and A are all restored
   RTI					;at the end of NMI, return from the interrupt

;; 6. The Main Game Loop
MainGameLoop:
   ;game logic will go here
   LDA #$80				;load decimal value 128 (=8x16)
   STA $0200			;store it to sprite 1's y address
   LDA #$80				;optional, load a different hex value for the x value
   STA $0203			;and store it to sprite 1's x address
   JMP MainGameLoop		;jumps back to MainGameLoop, create an infinite loop


;; 7. Sub Routines



;; 8. Includes and data tables
MyPalettes:
   ;backgroud
   .db $0F,$11,$17,$0a, $0F,$31,$01,$1c, $0F,$3c,$01,$14, $0F,$21,$39,$03
   ;sprites
   .db $0F,$27,$07,$30, $0F,$06,$05,$31, $0F,$2a,$2c,$16, $0F,$13,$14,$00


;; 9. The Vectors
   .org $fffa			;sets up at the very end of the code
   .dw NMI				;now the NMI points to our label NMI
   .dw RESET			;now the RESET points to our label RESET
   .dw 00
   
   .incbin "Mario.chr"	;this includes the graphics for the sprites in the assembly of the game
I have started NES programming! - Please be kind :D

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

Re: How to get rid of the sprite ($00) in top left corner?

Post by tokumaru » Mon Feb 22, 2021 9:04 am

Those are the sprites you're not using and were left with coordinates (0, 0) using tile 0. The way to fix this is to set the Y coordinate of unused sprites to a value that will put them off-screen (239-255).

Sebastian_L
Posts: 17
Joined: Tue Feb 16, 2021 12:31 pm

Re: How to get rid of the sprite ($00) in top left corner?

Post by Sebastian_L » Mon Feb 22, 2021 9:10 am

tokumaru wrote:
Mon Feb 22, 2021 9:04 am
Those are the sprites you're not using and were left with coordinates (0, 0) using tile 0. The way to fix this is to set the Y coordinate of unused sprites to a value that will put them off-screen (239-255).
Thank you for your fast answer.

I understand that so far, but I use the tile in the maingameloop:

Code: Select all

;; 6. The Main Game Loop
MainGameLoop:
   ;game logic will go here
   LDA #$80				;load decimal value 128 (=8x16)
   STA $0200			;store it to sprite 1's y address
   LDA #$80				;optional, load a different hex value for the x value
   STA $0203			;and store it to sprite 1's x address
   JMP MainGameLoop		;jumps back to MainGameLoop, create an infinite loop
Or is a bug in the code?

Thank you for your answer!
I have started NES programming! - Please be kind :D

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

Re: How to get rid of the sprite ($00) in top left corner?

Post by tokumaru » Mon Feb 22, 2021 9:18 am

You are using one sprite ($200-$203), but the OAM DMA in the NMI handler is updating all 64 sprites ($200-$2FF), and since you cleared all that memory with zeroes in the startup code, all 63 unused sprites are using tile 0 at coordinates (0, 0), and will show at the top left of the screen.

A quick fix would be to modify your memory clearing loop to write $ff to $200-$2FF instead of 0, since you're only using one hardcoded sprite at the moment, but in the long run you may need to implement a more dynamic way of hiding all the sprites you're not using.

Most games that fill the OAM dynamically will have a loop after all game objects have their sprites written to the OAM buffer that sets the Y coordinate of any remaining sprites to > 239.

Sebastian_L
Posts: 17
Joined: Tue Feb 16, 2021 12:31 pm

Re: How to get rid of the sprite ($00) in top left corner?

Post by Sebastian_L » Tue Feb 23, 2021 10:35 am

tokumaru wrote:
Mon Feb 22, 2021 9:18 am
You are using one sprite ($200-$203), but the OAM DMA in the NMI handler is updating all 64 sprites ($200-$2FF), and since you cleared all that memory with zeroes in the startup code, all 63 unused sprites are using tile 0 at coordinates (0, 0), and will show at the top left of the screen.

A quick fix would be to modify your memory clearing loop to write $ff to $200-$2FF instead of 0, since you're only using one hardcoded sprite at the moment, but in the long run you may need to implement a more dynamic way of hiding all the sprites you're not using.

Most games that fill the OAM dynamically will have a loop after all game objects have their sprites written to the OAM buffer that sets the Y coordinate of any remaining sprites to > 239.
Thank you! I tried it and it works!
I have started NES programming! - Please be kind :D

Post Reply