From 856bdf95e0e3f3155e8ba579a784450b085de874 Mon Sep 17 00:00:00 2001 From: Zev Averbach Date: Tue, 21 Feb 2023 17:23:20 +0100 Subject: [PATCH] controller --- controller/controller.asm | 262 ++++++++++++++++++++++++++++++++++++++ controller/controller.fns | 26 ++++ controller/controller.nes | Bin 0 -> 24592 bytes controller/mario.chr | Bin 0 -> 8192 bytes palette/palette.asm | 35 ++++- palette/palette.nes | Bin 24592 -> 16400 bytes sprites/mario.chr | Bin 0 -> 8192 bytes sprites/sprites.asm | 116 +++++++++++++++++ sprites/sprites.fns | 10 ++ sprites/sprites.nes | Bin 0 -> 24592 bytes 10 files changed, 446 insertions(+), 3 deletions(-) create mode 100644 controller/controller.asm create mode 100644 controller/controller.fns create mode 100644 controller/controller.nes create mode 100644 controller/mario.chr create mode 100644 sprites/mario.chr create mode 100644 sprites/sprites.asm create mode 100644 sprites/sprites.fns create mode 100644 sprites/sprites.nes diff --git a/controller/controller.asm b/controller/controller.asm new file mode 100644 index 0000000..9753190 --- /dev/null +++ b/controller/controller.asm @@ -0,0 +1,262 @@ + .inesprg 1 ; 1x 16KB PRG code + .ineschr 1 ; 1x 8KB CHR data + .inesmap 0 ; mapper 0 = NROM, no bank swapping + .inesmir 1 ; background mirroring + + +;;;;;;;;;;;;;;; + + + .bank 0 + .org $C000 +RESET: + SEI ; disable IRQs + CLD ; disable decimal mode + LDX #$40 + STX $4017 ; disable APU frame IRQ + LDX #$FF + TXS ; Set up stack + INX ; now X = 0 + STX $2000 ; disable NMI + STX $2001 ; disable rendering + STX $4010 ; disable DMC IRQs + +vblankwait1: ; First wait for vblank to make sure PPU is ready + BIT $2002 + BPL vblankwait1 + +clrmem: + LDA #$00 + STA $0000, x + STA $0100, x + STA $0200, x + STA $0400, x + STA $0500, x + STA $0600, x + STA $0700, x + LDA #$FE + STA $0300, x + INX + BNE clrmem + +vblankwait2: ; Second wait for vblank, PPU is ready after this + BIT $2002 + BPL vblankwait2 + + +LoadPalettes: + LDA $2002 ; read PPU status to reset the high/low latch + LDA #$3F + STA $2006 ; write the high byte of $3F00 address + LDA #$00 + STA $2006 ; write the low byte of $3F00 address + LDX #$00 ; start out at 0 +LoadPalettesLoop: + LDA palette, x ; load data from address (palette + the value in x) + ; 1st time through loop it will load palette+0 + ; 2nd time through loop it will load palette+1 + ; 3rd time through loop it will load palette+2 + ; etc + STA $2007 ; write to PPU + INX ; X = X + 1 + CPX #$20 ; Compare X to hex $10, decimal 16 - copying 16 bytes = 4 sprites + BNE LoadPalettesLoop ; Branch to LoadPalettesLoop if compare was Not Equal to zero + ; if compare was equal to 32, keep going down + + + +LoadSprites: + LDX #$00 ; start at 0 +LoadSpritesLoop: + LDA sprites, x ; load data from address (sprites + x) + STA $0200, x ; store into RAM address ($0200 + x) + INX ; X = X + 1 + CPX #$20 ; Compare X to hex $20, decimal 32 + BNE LoadSpritesLoop ; Branch to LoadSpritesLoop if compare was Not Equal to zero + ; if compare was equal to 32, keep going down + + + + LDA #%10000000 ; enable NMI, sprites from Pattern Table 1 + STA $2000 + + LDA #%00010000 ; enable sprites + STA $2001 + +Forever: + JMP Forever ;jump back to Forever, infinite loop + + + +NMI: + LDA #$00 + STA $2003 ; set the low byte (00) of the RAM address + LDA #$02 + STA $4014 ; set the high byte (02) of the RAM address, start the transfer + + +LatchController: + LDA #$01 + STA $4016 + LDA #$00 + STA $4016 ; tell both the controllers to latch buttons + +SkipSeveralButtons: + ; discard input from buttons A, B, Select and Start + LDA $4016 + LDA $4016 + LDA $4016 + LDA $4016 + +; LoadSpritesLoop: +; LDA sprites, x ; load data from address (sprites + x) +; STA $0200, x ; store into RAM address ($0200 + x) +; INX ; X = X + 1 +; CPX #$20 ; Compare X to hex $20, decimal 32 +; BNE LoadSpritesLoop ; Branch to LoadSpritesLoop if compare was Not Equal to zero +; ; if compare was equal to 32, keep going down + +ReadUp: + LDA $4016 ; player 1 - Up + AND #%00000001 ; only look at bit 0 + BEQ ReadUpDone ; branch to ReadBDone if button is NOT pressed (0) + ; add instructions here to do something when button IS pressed (1) + LDX #0200 + MoveSpritesLoop: + TXA ; load sprite Y position + SEC ; make sure carry flag is set + SBC #$01 ; A = A - 1 + SBC #$01 ; A = A - 1 + STA ; save sprite Y position + INX + INX + INX + INX + CPX #$10 + BNE MoveSpritesLoop + ReadUpDone: ; handling this button is done + + +ReadDown: + LDA $4016 ; player 1 - Down + AND #%00000001 ; only look at bit 0 + BEQ ReadDownDone ; branch to ReadBDone if button is NOT pressed (0) + ; add instructions here to do something when button IS pressed (1) + LDA $0200 ; load sprite Y position + CLC + ADC #$01 ; A = A - 1 + ADC #$01 ; A = A - 1 + STA $0200 ; save sprite Y position + LDA $0204 ; load sprite Y position + CLC + ADC #$01 ; A = A + 1 + ADC #$01 ; A = A - 1 + STA $0204 ; save sprite Y position + LDA $0208 ; load sprite Y position + CLC + ADC #$01 ; A = A - 1 + ADC #$01 ; A = A - 1 + STA $0208 ; save sprite Y position + LDA $020C ; load sprite Y position + CLC + ADC #$01 ; A = A - 1 + ADC #$01 ; A = A - 1 + STA $020C ; save sprite Y position +ReadDownDone: ; handling this button is done + +ReadLeft: + LDA $4016 ; player 1 - Right + AND #%00000001 ; only look at bit 0 + BEQ ReadLeftDone ; 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 + SBC #$01 ; A = A - 1 + STA $0203 ; save sprite X position + LDA $0207 ; load sprite X position + SEC ; make sure the carry flag is set + SBC #$01 ; A = A + 1 + SBC #$01 ; A = A - 1 + STA $0207 ; save sprite X position + LDA $020B ; load sprite X position + SEC ; make sure the carry flag is set + SBC #$01 ; A = A + 1 + SBC #$01 ; A = A - 1 + STA $020B ; save sprite X position + LDA $020F ; load sprite X position + SEC ; make sure the carry flag is set + SBC #$01 ; A = A + 1 + SBC #$01 ; A = A - 1 + STA $020F ; save sprite X position +ReadLeftDone: ; handling this button is done + + +ReadRight: + LDA $4016 ; player 1 - Left + AND #%00000001 ; only look at bit 0 + BEQ ReadRightDone ; 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 + ADC #$01 ; A = A + 1 + STA $0203 ; save sprite X position + LDA $0207 ; load sprite X position + CLC ; make sure the carry flag is clear + ADC #$01 ; A = A + 1 + ADC #$01 ; A = A + 1 + STA $0207 ; save sprite X position + LDA $020B ; load sprite X position + CLC ; make sure the carry flag is clear + ADC #$01 ; A = A + 1 + ADC #$01 ; A = A + 1 + STA $020B ; save sprite X position + LDA $020F ; load sprite X position + CLC ; make sure the carry flag is clear + ADC #$01 ; A = A + 1 + ADC #$01 ; A = A + 1 + STA $020F ; save sprite X position +ReadRightDone: ; handling this button is done + + + + RTI ; return from interrupt + +;;;;;;;;;;;;;; + + + + .bank 1 + .org $E000 +palette: + .db $0F,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$0F + .db $0F,$1C,$15,$14,$31,$02,$38,$3C,$0F,$1C,$15,$14,$31,$02,$38,$3C + +mario_sprite_addresses_vert: + .db $00,$04,$08,$0C + +mario_sprite_addresses_horiz: + .db $03,$07,$0B,$0F + +sprites: + ;vert tile attr horiz + .db $80, $32, $00, $80 ;sprite 0 + .db $80, $33, $00, $88 ;sprite 1 + .db $88, $34, $00, $80 ;sprite 2 + .db $88, $35, $00, $88 ;sprite 3 + + .org $FFFA ;first of the three vectors starts here + .dw NMI ;when an NMI happens (once per frame if enabled) the + ;processor will jump to the label NMI: + .dw RESET ;when the processor first turns on or is reset, it will jump + ;to the label RESET: + .dw 0 ;external interrupt IRQ is not used in this tutorial + + +;;;;;;;;;;;;;; + + + .bank 2 + .org $0000 + .incbin "mario.chr" ;includes 8KB graphics file from SMB1 diff --git a/controller/controller.fns b/controller/controller.fns new file mode 100644 index 0000000..24dc3d8 --- /dev/null +++ b/controller/controller.fns @@ -0,0 +1,26 @@ +; controller.asm +LoadSpritesLoop = $C059 +LoadPalettes = $C03D +LatchController = $C07B +Forever = $C06E +palette = $E000 +ReadLeftDone = $C10E +LoadPalettesLoop = $C04C +ReadUp = $C091 +ReadDown = $C0A8 +ReadRightDone = $C141 +ReadDownDone = $C0DB +SkipSeveralButtons = $C085 +LoadSprites = $C057 +vblankwait1 = $C014 +ReadUpDone = $C0A8 +vblankwait2 = $C038 +clrmem = $C019 +RESET = $C000 +sprites = $E028 +ReadLeft = $C0DB +mario_sprite_addresses_vert = $E020 +NMI = $C071 +ReadRight = $C10E +MoveSpritesLoop = $C09A +mario_sprite_addresses_horiz = $E024 diff --git a/controller/controller.nes b/controller/controller.nes new file mode 100644 index 0000000000000000000000000000000000000000..b32ea5e06fcb0c7414b4017ccc23ac8b50cc8fa2 GIT binary patch literal 24592 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 AJpcdz literal 0 HcmV?d00001 diff --git a/controller/mario.chr b/controller/mario.chr new file mode 100644 index 0000000000000000000000000000000000000000..d150cccdfb35f2cf6ee6124dc9839cb43f35fdf8 GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/palette/palette.asm b/palette/palette.asm index 5c1bb9e..a4936bf 100644 --- a/palette/palette.asm +++ b/palette/palette.asm @@ -54,8 +54,9 @@ vblankwait2: ; Second wait for vblank, PPU is ready after this PaletteData: .db $0F,$31,$32,$33,$0F,$35,$36,$37,$0F,$39,$3A,$3B,$0F,$3D,$3E,$0F .db $0F,$1C,$15,$14,$0F,$02,$38,$3C,$0F,$1C,$15,$14,$0F,$02,$38,$3C - ; using a loop, load the values stored in PaletteData into the background and sprite palettes LDX #$00 + +; using a loop, load the values stored in PaletteData into the background and sprite palettes LoadPalettesLoop: LDA PaletteData, x STA $2007 ; store the value of the Accumulator in the next memory slot in the PPU (referred to by this 'port' located at $2007) @@ -63,13 +64,41 @@ LoadPalettesLoop: CPX #$20 ; is X == 32? BNE LoadPalettesLoop +; load sprites +LDA #$00 +STA $2003 ; set the low byte of the RAM address +LDA #$02 +STA $4014 ; set the high byte of the RAM address + +; the DMA (direct memory address) transfer will start automatically after the above is executed. +; +; each sprite needs 4 bytes of data for its position and tile info: +; 1. Y position (vertical) -- $00 is the top, $EF is the bottom +; 2. tile number (0 to 256) +; 3. attributes (color and display info) +; 7 flip vertical +; 6 flip horiz +; 5 priority (0: in front of BG, 1: behind it) +; 1 and 0: color palette of sprite -- choose four of the 16 colors +; 4. X position (horiz) +; there are 64 bytes of sprite memory, four bytes for each of the 16 sprites. They're located at $0200-$02FF. +; +; set up the sprite data +; +LDA #$80 +STA $0200 ; put sprite 0 in center ($80) of screen vertically +STA $0203 ; put sprite 0 in center ($80) of screen horizontally +LDA #$00 +STA $0201 ; tile number = 0 +STA $0202 ; color palette = 0, no flipping + +NMI: + Forever: JMP Forever ;jump back to Forever, infinite loop -NMI: - RTI ;;;;;;;;;;;;;; diff --git a/palette/palette.nes b/palette/palette.nes index 35b65afd694627f5a5097ac8d7dd08058246b403..ccc18f62e24ca8a8861eed961dd2975bcf51d71b 100644 GIT binary patch delta 9 QcmbPmfN??t;|2i-026crV*mgE literal 24592 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 literal 0 HcmV?d00001 diff --git a/sprites/sprites.asm b/sprites/sprites.asm new file mode 100644 index 0000000..68e6638 --- /dev/null +++ b/sprites/sprites.asm @@ -0,0 +1,116 @@ + .inesprg 1 ; 1x 16KB PRG code + .ineschr 1 ; 1x 8KB CHR data + .inesmap 0 ; mapper 0 = NROM, no bank swapping + .inesmir 1 ; background mirroring + + +;;;;;;;;;;;;;;; + + + .bank 0 + .org $C000 +RESET: + SEI ; disable IRQs + CLD ; disable decimal mode + LDX #$40 + STX $4017 ; disable APU frame IRQ + LDX #$FF + TXS ; Set up stack + INX ; now X = 0 + STX $2000 ; disable NMI + STX $2001 ; disable rendering + STX $4010 ; disable DMC IRQs + +vblankwait1: ; First wait for vblank to make sure PPU is ready + BIT $2002 + BPL vblankwait1 + +clrmem: + LDA #$00 + STA $0000, x + STA $0100, x + STA $0300, x + STA $0400, x + STA $0500, x + STA $0600, x + STA $0700, x + LDA #$FE + STA $0200, x ;move all sprites off screen + INX + BNE clrmem + +vblankwait2: ; Second wait for vblank, PPU is ready after this + BIT $2002 + BPL vblankwait2 + + + +; ************** NEW CODE **************** +LoadPalettes: + LDA $2002 ; read PPU status to reset the high/low latch + LDA #$3F + STA $2006 ; write the high byte of $3F00 address + LDA #$00 + STA $2006 ; write the low byte of $3F00 address + LDX #$00 +LoadPalettesLoop: + LDA palette, x ;load palette byte + STA $2007 ;write to PPU + INX ;set index to next byte + CPX #$20 + BNE LoadPalettesLoop ;if x = $20, 32 bytes copied, all done + + + + LDA #$20 + STA $0200 ; put sprite 0 in center ($80) of screen vert + STA $0203 ; put sprite 0 in center ($80) of screen horiz + LDA #$01 + STA $0201 ; tile number = 0 + LDA #$02 + STA $0202 ; color = 0, no flipping + + LDA #%10000000 ; enable NMI, sprites from Pattern Table 0 + STA $2000 + + LDA #%00010000 ; enable sprites + STA $2001 + +Forever: + JMP Forever ;jump back to Forever, infinite loop + + + +NMI: + LDA #$00 + STA $2003 ; set the low byte (00) of the RAM address + LDA #$02 + STA $4014 ; set the high byte (02) of the RAM address, start the transfer + + RTI ; return from interrupt + +;;;;;;;;;;;;;; + + + + .bank 1 + .org $E000 +palette: + .db $0F,$31,$32,$33,$0F,$35,$36,$37,$0F,$39,$3A,$3B,$0F,$3D,$3E,$0F + .db $0F,$1C,$15,$14,$0F,$02,$38,$3C,$0F,$1C,$15,$14,$0F,$02,$38,$3C + + + .org $FFFA ;first of the three vectors starts here + .dw NMI ;when an NMI happens (once per frame if enabled) the + ;processor will jump to the label NMI: + .dw RESET ;when the processor first turns on or is reset, it will jump + ;to the label RESET: + .dw 0 ;external interrupt IRQ is not used in this tutorial + + +;;;;;;;;;;;;;; + + + .bank 2 + .org $0000 + .incbin "mario.chr" ;includes 8KB graphics file from SMB1 diff --git a/sprites/sprites.fns b/sprites/sprites.fns new file mode 100644 index 0000000..f7bbc2c --- /dev/null +++ b/sprites/sprites.fns @@ -0,0 +1,10 @@ +; sprites.asm +LoadPalettes = $C03D +Forever = $C073 +palette = $E000 +LoadPalettesLoop = $C04C +vblankwait1 = $C014 +vblankwait2 = $C038 +clrmem = $C019 +RESET = $C000 +NMI = $C076 diff --git a/sprites/sprites.nes b/sprites/sprites.nes new file mode 100644 index 0000000000000000000000000000000000000000..1b4804a4c00391574226d1592dd53c806ee5ffaf GIT binary patch literal 24592 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 rJb3pb4-P#y$%iKVp^4pW&mEE7_{+US8JWLt literal 0 HcmV?d00001