; INES header setup .inesprg 1 ; One 16k prg bank .ineschr 1 ; One 8k chr bank .inesmir 1 ; Vertical map mirroring .inesmap 0 ; Use mapper 0 .bank 0 .org $C000 ;16Kb PRG-ROM, 8Kb CHR-ROM Palette: ;.db $22,$29,$1a,$0f,$0f,$36,$17,$0f,$0f,$30,$21,$0f,$0f,$27,$17,$0f .incbin "mario.pal" SetPalette: ; Setup PPU transfer address ldx #HIGH($3F00) stx $2006 ldx #LOW($3F00) stx $2006 ldx #32 ldy #LOW(Palette) .Write: lda Palette,Y sta $2007 iny dex bne .Write ldx #0 stx $2006 stx $2006 rts ;Done! ;------------------------------------- SetPatternTable: ; Setup PPU transfer address ldx #HIGH($2000) stx $2006 ldx #LOW($2000) stx $2006 ldx #0 ldy #0 .Write: sty $2007 iny dex bne .Write jsr WaitVBlank ldx #0 ldy #0 .Write2: sty $2007 iny dex bne .Write2 jsr WaitVBlank ldx #0 ldy #0 .Write3: sty $2007 iny dex bne .Write3 ldx #0 stx $2006 stx $2006 rts ;Done! ;------------------------------------ SetAttributeTable: ; Setup PPU transfer address ldx #HIGH($23C0) ;High byte of $23C0 stx $2006 ldx #LOW($23C0) ;Low byte of $23C0 stx $2006 ldx #64 .Write: sty $2007 ;iny dex bne .Write ldx #0 stx $2006 stx $2006 rts ;Done! ;--------------------------------------- BlankSprites: lda #$0 sta $2003 ldx #64 .Write: lda #$F8 sta $2004 ldy #$0 sty $2004 sty $2004 sty $2004 dex bne .Write ldx #0 stx $2006 stx $2006 rts ;Done! ;--------------------------------------- UpdateMarioFrame: lda Mario.Frame asl A asl A asl A .DoUpdate: clc sta $201 ; Sprite 1 tile number adc #1 sta $205 ; Sprite 2 tile number adc #1 sta $209 ; Sprite 3 tile number adc #1 sta $20D ; Sprite 4 tile number adc #1 sta $211 ; Sprite 5 tile number adc #1 sta $215 ; Sprite 6 tile number adc #1 sta $219 ; Sprite 7 tile number adc #1 sta $21D ; Sprite 8 tile number rts ;--------------------------------------- UpdateMarioPosition: tya pha ldx Mario.X ldy Mario.Y stx $203 ; Sprite 1 X pos stx $20B ; Sprite 3 X Pos stx $213 ; Sprite 5 X Pos stx $21B ; Sprite 7 X Pos sty $200 ; Sprite 1 Y pos sty $204 ; Sprite 2 Y pos txa clc adc #8 sta $207 ; Sprite 2 X pos sta $20F ; Sprite 4 X Pos sta $217 ; Sprite 6 X Pos sta $21F ; Sprite 8 X Pos tya clc adc #8 sta $208 ; Sprite 3 Y Pos sta $20C ; Sprite 4 Y Pos clc adc #8 sta $210 ; Sprite 5 Y Pos sta $214 ; Sprite 6 Y Pos clc adc #8 sta $218 ; Sprite 7 Y Pos sta $21C ; Sprite 8 Y Pos pla tay rts ;--------------------------------------- WaitVBlank: .WaitV: lda $2002 bpl .WaitV ;Wait for vertical blanking interval rts ;--------------------------------------- Reset_Routine: cld ;Clear decimal flag sei ;Disable interrupts ldx #$00 dex txs ;Top of stack at $1FF inx jsr WaitVBlank ldx #0 stx $2000 jsr SetPalette jsr SetPatternTable jsr WaitVBlank ldx #%10010000 stx $2000 ldx #%00011110 stx $2001 jsr WaitVBlank ;jsr BlankSprites ldx #0 ; Wipe sprites .SpriteWipeLoop lda #$f8 sta $200,X inx lda #0 sta $200,X inx sta $200,X inx sta $200,X inx bne .SpriteWipeLoop ; /Wipe Sprites jsr UpdateMarioFrame ldy #$AA attrCount = $300 sprCount = $301 Mario.X = $310 Mario.Y = $311 Mario.Frame = $312 Mario.aDir = $313 ; Animation direction lda #127 sta Mario.Y .poop: jsr WaitVBlank lda #60 cmp attrCount bne .skiptable lda #0 sta attrCount jsr SetAttributeTable .skiptable: inc attrCount lda #4 ;7 ; Check if sprite should be updated cmp sprCount bne .skipspriteupdate lda #0 ; start sprite update; reset frame counter sta sprCount inc Mario.Frame lda Mario.Frame cmp #3 beq .animatechange jmp .animateover .animatechange: lda #128 sta Mario.aDir lda #0 sta Mario.Frame jmp .animateover .animateover: jsr UpdateMarioFrame .skipspriteupdate: inc sprCount iny inc Mario.X inc Mario.X jsr UpdateMarioPosition lda #2 sta $4014 ; DMA transfer from $200 jmp .poop ;stx $2000 ;stx $2001 ;Screen display off, amongst other things ;Interrupt Vectors ;------------------------------------- NMI_Routine: rti IRQ_Routine: rti ;Vector Table ;------------------------------------- .bank 1 .org $FFFA .dw NMI_Routine .dw Reset_Routine .dw IRQ_Routine ;Not used, just points to RTI ;CHR Bank ;------------------------------------- .bank 2 .org $0000 .incbin "mario.chr"