Initial
This commit is contained in:
BIN
background.chr
Normal file
BIN
background.chr
Normal file
Binary file not shown.
19
game.cfg
Normal file
19
game.cfg
Normal file
@@ -0,0 +1,19 @@
|
||||
MEMORY {
|
||||
ZP: start = $00, size = $0100, type = rw, file = "";
|
||||
OAM: start = $0200, size = $0100, type = rw, file = "";
|
||||
RAM: start = $0300, size = $0500, type = rw, file = "";
|
||||
HDR: start = $0000, size = $0010, type = ro, file = %O, fill = yes, fillval = $00;
|
||||
PRG: start = $8000, size = $8000, type = ro, file = %O, fill = yes, fillval = $00;
|
||||
CHR: start = $0000, size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
|
||||
}
|
||||
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp;
|
||||
OAM: load = OAM, type = bss, align = $100;
|
||||
BSS: load = RAM, type = bss;
|
||||
HEADER: load = HDR, type = ro;
|
||||
CODE: load = PRG, type = ro, start = $8000;
|
||||
RODATA: load = PRG, type = ro;
|
||||
VECTORS: load = PRG, type = ro, start = $FFFA;
|
||||
TILES: load = CHR, type = ro;
|
||||
}
|
||||
530
game.s
Normal file
530
game.s
Normal file
@@ -0,0 +1,530 @@
|
||||
.segment "HEADER"
|
||||
|
||||
INES_MAPPER = 0
|
||||
INES_MIRROR = 1
|
||||
INES_SRAM = 0
|
||||
|
||||
.byte 'N', 'E', 'S', $1A
|
||||
.byte $02
|
||||
.byte $01
|
||||
.byte INES_MIRROR
|
||||
.byte (INES_MAPPER & %11110000)
|
||||
.byte $0, $0, $0, $0, $0, $0, $0, $0
|
||||
|
||||
|
||||
.segment "TILES"
|
||||
.incbin "background.chr"
|
||||
.incbin "sprite.chr"
|
||||
|
||||
|
||||
.segment "VECTORS"
|
||||
.word nmi
|
||||
.word reset
|
||||
.word irq
|
||||
|
||||
|
||||
.segment "CODE"
|
||||
reset:
|
||||
sei
|
||||
lda #0
|
||||
sta $2000
|
||||
sta $2001
|
||||
sta $4015
|
||||
sta $4010
|
||||
lda #40
|
||||
sta $4017
|
||||
cld
|
||||
ldx #$FF
|
||||
txs
|
||||
|
||||
bit $2002
|
||||
:
|
||||
bit $2002
|
||||
bpl :-
|
||||
|
||||
lda #0
|
||||
ldx #0
|
||||
:
|
||||
sta $0000, X
|
||||
sta $0100, X
|
||||
sta $0200, X
|
||||
sta $0300, X
|
||||
sta $0400, X
|
||||
sta $0500, X
|
||||
sta $0600, X
|
||||
sta $0700, X
|
||||
inx
|
||||
bne :-
|
||||
|
||||
lda #255
|
||||
ldx #0
|
||||
:
|
||||
sta oam, X
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
bne :-
|
||||
|
||||
:
|
||||
bit $2002
|
||||
bpl :-
|
||||
|
||||
lda #%10001000
|
||||
sta $2000
|
||||
jmp main
|
||||
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
nmi_lock: .res 1
|
||||
nmi_count: .res 1
|
||||
nmi_ready: .res 1
|
||||
nmt_update_len: .res 1
|
||||
scroll_x: .res 1
|
||||
scroll_y: .res 1
|
||||
scroll_nmt: .res 1
|
||||
temp: .res 1
|
||||
|
||||
.segment "BSS"
|
||||
nmt_update: .res 256
|
||||
palette: .res 32
|
||||
|
||||
.segment "OAM"
|
||||
oam: .res 256
|
||||
|
||||
.segment "CODE"
|
||||
nmi:
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
|
||||
lda nmi_lock
|
||||
beq :+
|
||||
jmp @nmi_end
|
||||
|
||||
:
|
||||
lda #1
|
||||
sta nmi_lock
|
||||
|
||||
lda nmi_ready
|
||||
bne :+
|
||||
jmp @ppu_update_end
|
||||
|
||||
:
|
||||
cmp #2
|
||||
bne :+
|
||||
lda #%00000000
|
||||
sta $2001
|
||||
ldx #0
|
||||
stx nmi_ready
|
||||
jmp @ppu_update_end
|
||||
|
||||
:
|
||||
ldx #0
|
||||
stx $2003
|
||||
lda #>oam
|
||||
sta $4014
|
||||
|
||||
lda #%10001000
|
||||
sta $2000
|
||||
lda $2002
|
||||
lda #$3F
|
||||
sta $2006
|
||||
stx $2006
|
||||
ldx #0
|
||||
:
|
||||
lda palette, X
|
||||
sta $2007
|
||||
inx
|
||||
cpx #32
|
||||
bcc :-
|
||||
|
||||
ldx #0
|
||||
cpx nmt_update_len
|
||||
bcs @scroll
|
||||
@nmt_update_loop:
|
||||
lda nmt_update, X
|
||||
sta $2006
|
||||
inx
|
||||
lda nmt_update, X
|
||||
sta $2006
|
||||
inx
|
||||
lda nmt_update, X
|
||||
sta $2007
|
||||
cpx nmt_update_len
|
||||
bcc @nmt_update_loop
|
||||
|
||||
lda #0
|
||||
sta nmt_update_len
|
||||
@scroll:
|
||||
lda scroll_nmt
|
||||
and #%00000011
|
||||
ora #%10001000
|
||||
sta $2000
|
||||
lda scroll_x
|
||||
sta $2005
|
||||
lda scroll_y
|
||||
sta $2005
|
||||
|
||||
lda #%00011110
|
||||
sta $2001
|
||||
|
||||
ldx #0
|
||||
stx nmi_ready
|
||||
@ppu_update_end:
|
||||
lda #0
|
||||
sta nmi_lock
|
||||
@nmi_end:
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
|
||||
|
||||
.segment "CODE"
|
||||
irq:
|
||||
rti
|
||||
|
||||
|
||||
.segment "CODE"
|
||||
ppu_update:
|
||||
lda #1
|
||||
sta nmi_ready
|
||||
:
|
||||
lda nmi_ready
|
||||
bne :-
|
||||
|
||||
rts
|
||||
|
||||
ppu_skip:
|
||||
lda nmi_count
|
||||
:
|
||||
cmp nmi_count
|
||||
beq :-
|
||||
|
||||
rts
|
||||
|
||||
ppu_off:
|
||||
lda #2
|
||||
sta nmi_ready
|
||||
:
|
||||
lda nmi_ready
|
||||
bne :-
|
||||
|
||||
rts
|
||||
|
||||
ppu_address_tile:
|
||||
lda $2002
|
||||
tya
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #$20
|
||||
sta $2006
|
||||
tya
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta temp
|
||||
txa
|
||||
ora temp
|
||||
sta $2006
|
||||
rts
|
||||
|
||||
ppu_update_tile:
|
||||
pha
|
||||
txa
|
||||
pha
|
||||
ldx nmt_update_len
|
||||
tya
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
ora #$20
|
||||
sta nmt_update, X
|
||||
inx
|
||||
tya
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta temp
|
||||
pla
|
||||
ora temp
|
||||
sta nmt_update, X
|
||||
inx
|
||||
pla
|
||||
sta nmt_update, X
|
||||
inx
|
||||
stx nmt_update_len
|
||||
rts
|
||||
|
||||
ppu_update_byte:
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
ldy nmt_update_len
|
||||
txa
|
||||
sta nmt_update, Y
|
||||
iny
|
||||
pla
|
||||
sta nmt_update, Y
|
||||
iny
|
||||
pla
|
||||
sta nmt_update, Y
|
||||
iny
|
||||
sty nmt_update_len
|
||||
rts
|
||||
|
||||
|
||||
PAD_A = $01
|
||||
PAD_B = $02
|
||||
PAD_SELECT = $04
|
||||
PAD_START = $08
|
||||
PAD_U = $10
|
||||
PAD_D = $20
|
||||
PAD_L = $40
|
||||
PAD_R = $80
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
gamepad: .res 1
|
||||
|
||||
.segment "CODE"
|
||||
; gamepad_poll: this reads the gamepad state into the variable labelled "gamepad"
|
||||
; This only reads the first gamepad, and also if DPCM samples are played they can
|
||||
; conflict with gamepad reading, which may give incorrect results.
|
||||
gamepad_poll:
|
||||
; strobe the gamepad to latch current button state
|
||||
lda #1
|
||||
sta $4016
|
||||
lda #0
|
||||
sta $4016
|
||||
; read 8 bytes from the interface at $4016
|
||||
ldx #8
|
||||
:
|
||||
pha
|
||||
lda $4016
|
||||
; combine low two bits and store in carry bit
|
||||
and #%00000011
|
||||
cmp #%00000001
|
||||
pla
|
||||
; rotate carry into gamepad variable
|
||||
ror
|
||||
dex
|
||||
bne :-
|
||||
sta gamepad
|
||||
rts
|
||||
|
||||
|
||||
.segment "RODATA"
|
||||
example_palette:
|
||||
.byte $0F,$15,$26,$37 ; bg0 purple/pink
|
||||
.byte $0F,$09,$19,$29 ; bg1 green
|
||||
.byte $0F,$01,$11,$21 ; bg2 blue
|
||||
.byte $0F,$00,$10,$30 ; bg3 greyscale
|
||||
.byte $0F,$18,$28,$38 ; sp0 yellow
|
||||
.byte $0F,$14,$24,$34 ; sp1 purple
|
||||
.byte $0F,$1B,$2B,$3B ; sp2 teal
|
||||
.byte $0F,$12,$22,$32 ; sp3 marine
|
||||
|
||||
.segment "ZEROPAGE"
|
||||
velocities: .res 8
|
||||
|
||||
cursor_x: .res 1
|
||||
cursor_y: .res 1
|
||||
temp_x: .res 1
|
||||
temp_y: .res 1
|
||||
var_m: .res 1
|
||||
var_n: .res 1
|
||||
var_o: .res 1
|
||||
var_p: .res 1
|
||||
|
||||
frame_counter: .res 1
|
||||
|
||||
.segment "CODE"
|
||||
main:
|
||||
ldx #0
|
||||
:
|
||||
lda example_palette, X
|
||||
sta palette, X
|
||||
inx
|
||||
cpx #32
|
||||
bcc :-
|
||||
|
||||
jsr setup_background
|
||||
jsr ppu_update
|
||||
|
||||
lda #$40
|
||||
sta cursor_x
|
||||
sta cursor_y
|
||||
|
||||
lda #0
|
||||
sta frame_counter
|
||||
|
||||
jsr init_objects
|
||||
@loop:
|
||||
@draw:
|
||||
jsr draw
|
||||
jsr ppu_update
|
||||
|
||||
lda frame_counter
|
||||
clc
|
||||
adc #1
|
||||
sta frame_counter
|
||||
jmp @loop
|
||||
|
||||
init_objects:
|
||||
lda #0
|
||||
sta var_n
|
||||
ldx #0
|
||||
:
|
||||
lda var_n
|
||||
clc
|
||||
adc #8
|
||||
sta var_n
|
||||
|
||||
sta oam+0, X ; Set Y position
|
||||
sta oam+3, X ; Set X position
|
||||
|
||||
txa
|
||||
lsr
|
||||
lsr
|
||||
sta oam+1, X
|
||||
|
||||
tay
|
||||
lda #0
|
||||
sta velocities, Y
|
||||
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
cpx #(8*4)
|
||||
bne :-
|
||||
|
||||
rts
|
||||
|
||||
draw:
|
||||
lda frame_counter
|
||||
and #1
|
||||
cmp #0
|
||||
bne @end
|
||||
|
||||
ldx #0
|
||||
ldy #0
|
||||
:
|
||||
lda velocities, Y
|
||||
clc
|
||||
adc #1 ; Add 2 to velocity
|
||||
sta velocities, Y
|
||||
|
||||
lda oam+0, X
|
||||
clc
|
||||
adc velocities, Y
|
||||
sta oam+0, X
|
||||
|
||||
cmp #200
|
||||
bmi :+
|
||||
lda #245
|
||||
sta velocities, Y
|
||||
:
|
||||
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
|
||||
iny
|
||||
cpy #8
|
||||
bne :--
|
||||
@end:
|
||||
rts
|
||||
|
||||
setup_background:
|
||||
lda $2002 ; reset latch
|
||||
lda #$20
|
||||
sta $2006
|
||||
lda #$00
|
||||
sta $2006
|
||||
; empty nametable
|
||||
lda #0
|
||||
ldy #30 ; 30 rows
|
||||
:
|
||||
ldx #32 ; 32 columns
|
||||
:
|
||||
sta $2007
|
||||
dex
|
||||
bne :-
|
||||
dey
|
||||
bne :--
|
||||
; set all attributes to 0
|
||||
ldx #64 ; 64 bytes
|
||||
:
|
||||
sta $2007
|
||||
dex
|
||||
bne :-
|
||||
; fill in an area in the middle with 1/2 checkerboard
|
||||
lda #1
|
||||
ldy #8 ; start at row 8
|
||||
:
|
||||
pha ; temporarily store A, it will be clobbered by ppu_address_tile routine
|
||||
ldx #8 ; start at column 8
|
||||
jsr ppu_address_tile
|
||||
pla ; recover A
|
||||
|
||||
ldx #8
|
||||
:
|
||||
sta $2007
|
||||
eor #$3
|
||||
inx
|
||||
cpx #(32-8)
|
||||
bcc :-
|
||||
eor #$3
|
||||
iny
|
||||
cpy #(30-8)
|
||||
bcc :--
|
||||
|
||||
lda #$24
|
||||
sta $2006
|
||||
lda #$00
|
||||
sta $2006
|
||||
lda #$00
|
||||
ldy #30
|
||||
:
|
||||
ldx #32
|
||||
:
|
||||
sta $2007
|
||||
clc
|
||||
adc #1
|
||||
and #3
|
||||
dex
|
||||
bne :-
|
||||
clc
|
||||
adc #1
|
||||
and #3
|
||||
dey
|
||||
bne :--
|
||||
|
||||
lda #0
|
||||
ldy #4
|
||||
:
|
||||
ldx #16
|
||||
:
|
||||
sta $2007
|
||||
dex
|
||||
bne :-
|
||||
|
||||
clc
|
||||
adc #%01010101
|
||||
dey
|
||||
bne :--
|
||||
|
||||
rts
|
||||
|
||||
5
run
Executable file
5
run
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
ca65 game.s -o game.o
|
||||
ld65 game.o -C game.cfg -o game.nes
|
||||
fceux game.nes
|
||||
|
||||
BIN
sprite.chr
Normal file
BIN
sprite.chr
Normal file
Binary file not shown.
Reference in New Issue
Block a user