• Fichier: invader.asm
  • Path: /invader_nes/InvaderNES/invader.asm
  • File size: 9.32 KB
  • MIME-type: text/x-asm
  • Charset: utf-8
 
Retour
.segment "HEADER"	
	.byte	"NES", $1A			; iNES header identifier
	.byte	2					; 2x 16KB PRG code
	.byte	1					; 1x  8KB CHR data
	.byte	$01, $00			; mapper 0, vertical mirroring

; "NES" linker config requires a STARTUP section, even if it's empty
.segment "STARTUP"
.segment "ZEROPAGE"
.segment "CODE"

reset:
	sei							; disable IRQs
	cld							; disable decimal mode
	ldx	#$40
	stx	$4017					; disable APU frame IRQ
	ldx	#$ff					; set up stack
	txs							;  .
	inx							; now X = 0
	stx	$2000					; disable NMI
	stx	$2001					; disable rendering
	stx	$4010					; disable DMC IRQs

	jsr vBlankWait 				; wait for vblank to make sure PPU is ready

@clear_memory:
	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	@clear_memory

	jsr vBlankWait 				; wait for vblank, PPU is ready after this
	
load_palettes:
	lda	$2002					; read PPU status to reset the high/low latch
	lda	#$3f					; write the high byte of $3f00
	sta	$2006					;  .
	lda	#$00					; write the low byte of $3f00
	sta	$2006					;  .
	ldx	#$00
@loop:
	lda	bgPalette, x			; load palette byte
	sta	$2007					; write to PPU
	inx							; set index to next byte
	cpx	#$10
	bne	@loop					; if x = $10, 32 bytes copied, all done

	ldx #$00 					; reset our index to 0 for the next loop
@sLoop:
    lda sPalette, x     		; load palette byte
    sta $2007					; write to PPU
    inx                   		; set index to next byte
    cpx #$10            
    bne @sLoop  				; if x = $10, all done
	
    jsr vBlankWait

load_background:
	lda	$2002					; read PPU status to reset the high/low latch
	lda	#$20
	sta	$2006					; write the high byte of $2000 address
	lda	#$00
	sta	$2006					; write the low byte of $2000 address

	lda #<background
	sta $03
	lda #>background
	sta $04
	
	ldx	#$00					; start out at 0
	ldy #$00
@OutsideLoop:
@InsideLoop:
	lda	($03), y				; load data from address (background + x)
	sta	$2007					; write to PPU
	iny							; x = x + 1
	cpy	#$00					; compare x to hex $80, decimal 128

	bne	@InsideLoop

	inc $04
	inx
	cpx #$04

	bne @OutsideLoop
	
	lda	#%10001000				; enable NMI, sprites from pattern table 0, background from pattern table 1
	sta	$2000
	lda	#%00011110				; enable sprites, enable background, no clipping on left
	sta	$2001

forever:
	jmp	forever
 
; NMI handler
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

  	jsr ReadController

	ldx #$00
	ldy #$00

	lda #$03
	sta $03
updateTruck:
  	lda truckMetasprite+1, y
  	sta $0200, y
  	iny
  	cpy $03
  	bne updateTruck
  	lda truckMetasprite+1, y
  	clc
  	adc $02
  	sta $0200, y
  	iny
  	tya
  	clc
  	adc #$03
  	sta $03
  	inx
  	cpx truckMetasprite
  	bne updateTruck

	; This is the PPU clean up section, so rendering the next frame starts
	lda	#%10001000				; enable NMI, sprites from pattern table 0,
	sta	$2000					; background from pattern table 1
	lda	#%00011110				; enable sprites, enable background,
	sta	$2001					;  no clipping on left

	lda	#$00					; tell the PPU there is no background scrolling
	sta	$2005
	sta	$2005
	
	rti

vBlankWait:
	bit	$2002
	bpl	vBlankWait
	rts

ReadController:
	lda #$01
  	sta $4016 
  	lda #$00
  	sta $4016 
  	ldx #$08

@ReadControllerLoop:
  	lda $4016 
  	lsr A 						; use bit shifting to pull lowest bit from controller and put into buttons
  	rol $05
  	dex
  	bne @ReadControllerLoop

  	lda $05
  	and #%00000001
  	cmp #%00000001
  	bne @SkipRight

  	lda $02
  	cmp #$C0
  	beq @SkipRight
  	clc
  	adc #$01
  	sta $02

@SkipRight:
	lda $05
  	and #%00000010
  	cmp #%00000010
  	bne @end

  	lda $02
  	cmp #$00
  	beq @end
  	sec
  	sbc #$01
  	sta $02

 @end:
 	rts

; DATA

background:
	.byte $2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29
	.byte $2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b
	.byte $29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b
	.byte $29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$2b,$2b
	.byte $29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29
	.byte $2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29
	.byte $2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$2b,$2b,$2b
	.byte $2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b
	.byte $2b,$2b,$2b,$2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$2b,$2b,$2b,$2b,$2b,$2b,$2b,$29
	.byte $2b,$2b,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$29,$29,$29,$29,$24,$25,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$24,$25,$29,$29,$29,$29,$29,$29,$24,$25,$29,$29,$29,$29,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$24,$25,$29,$29,$24,$25,$29,$29,$29,$29,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$29,$29,$29,$29,$24,$25,$29,$29,$24,$25,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29,$29,$24,$25,$29
	.byte $29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29,$29
	.byte $29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29,$29,$26,$27,$29
	.byte $2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a
	.byte $28,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48
	.byte $28,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48
	.byte $28,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48,$48
	.byte $2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a
	.byte $2a,$15,$08,$04,$12,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$0c,$14,$0d,$08,$13,$08,$0e,$0d,$12,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a
	.byte $2a,$2d,$2d,$2d,$2d,$2d,$2d,$2d,$2d,$2a,$2a,$2a,$2c,$2c,$2c,$2c,$2c,$2c,$2c,$2c,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a
	.byte $2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a

	.byte	%00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
	.byte	%00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
	.byte	%00000000, %10100000, %00000000, %00000000, %01010000, %00000000, %01010000, %00000000
	.byte	%01010101, %10101010, %01010000, %10101010, %01010101, %10100000, %01010101, %10101010
	.byte	%01010101, %10101010, %01010101, %10101010, %01010101, %10101010, %01010101, %10101010
	.byte	%01010101, %01011010, %01010101, %01011010, %01010101, %01011010, %01010101, %01011010
	.byte	%01010101, %01010101, %01010101, %01010101, %01010101, %01010101, %01010101, %01010101
	.byte	%11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %01010101, %01010101

bgPalette:
	.byte $2D,$1C,$21,$31
	.byte $2D,$00,$3D,$30
	.byte $2D,$00,$0B,$30
	.byte $2D,$00,$06,$27

truckMetasprite:
	.byte $14
	.byte $BE,$13,$00,$00
  	.byte $B9,$14,$00,$08
  	.byte $C1,$15,$00,$08
  	.byte $C1,$15,$00,$28
  	.byte $AE,$17,$00,$10
  	.byte $B6,$18,$00,$10
  	.byte $BE,$19,$00,$10
  	.byte $BE,$1A,$00,$18
  	.byte $B6,$1B,$00,$18
  	.byte $AE,$1A,$80,$18
  	.byte $AE,$1D,$01,$20
  	.byte $A9,$1E,$00,$28
  	.byte $A1,$1F,$00,$28
  	.byte $AE,$1A,$C0,$30
  	.byte $B6,$1B,$40,$30
  	.byte $BE,$1A,$40,$30
  	.byte $B6,$20,$01,$20
  	.byte $B1,$21,$01,$28
  	.byte $B9,$22,$01,$28
  	.byte $BE,$1C,$80,$20

sPalette:
	.byte $2D,$0F,$3D,$2D
	.byte $2D,$0F,$3D,$06
	.byte $2D,$00,$0A,$30
	.byte $2D,$00,$06,$27

;;;;;;;;;;;;;;  
  
.segment "VECTORS"

	.word	nmi
	.word	reset
	.word	0
  
;;;;;;;;;;;;;;  
  
.segment "CHARS"

	.incbin	"invader.chr"	; includes 8KB graphics