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