just tried to get my sprite moving with the controller, but I failed.
Do I use the right code? At the right position?
And do I speak with the right sprite?
Thank you in advance for your answers!
Here is my code so far:
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 $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 LDA #$FF STA $0200,x ;store accumulator 255 into address $0200+x (sprite tiles) 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 ;CONTROLLER LatchController: LDA #$01 STA $4016 LDA #$00 STA $4016 ; tell both the controllers to latch buttons ReadA: LDA $4016 ; player 1 - A AND #%00000001 ; only look at bit 0 BEQ ReadADone ; branch to ReadADone if button is NOT pressed (0) ; add instructions here to do something when button IS pressed (1) LDA $0203 ; load sprite X position CLC ; make sure the carry flag is clear ADC #$01 ; A = A + 1 STA $0203 ; save sprite X position ReadADone: ; handling this button is done ReadB: LDA $4016 ; player 1 - B AND #%00000001 ; only look at bit 0 BEQ ReadBDone ; branch to ReadBDone if button is NOT pressed (0) ; add instructions here to do something when button IS pressed (1) LDA $0203 ; load sprite X position SEC ; make sure carry flag is set SBC #$01 ; A = A - 1 STA $0203 ; save sprite X position ReadBDone: ; handling this button is done ;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 LDA #$00 STA $0201 STA $0202 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