Compare commits

..

No commits in common. "b1a1b112eb1dd3811a58d6f5a775a05a7a179eff" and "457968233615a0170b0cb7ca3fe1a55411c062aa" have entirely different histories.

15 changed files with 429 additions and 335 deletions

View File

@ -1,9 +1,10 @@
# Spaceship NES # Spaceship NES
This a project to learn how in the past they made games, spoiler alert it was in assembly, so I'm trying to learn how to make a basic arcade game with the help of book.famicon.party and learning how, in the process, learn some assembly and how the NES works. This a test to learn how in the past they made games, spoiler alert it was in assembly, so I'm trying to learn how to make a basic arcade game with the help of book.famicon.party and learning how, in the process, learn some assembly and how the NES works.
![imagen](https://github.com/LinkHpp/Spaceship_NES/assets/63952783/578254fe-2f7d-4bc3-bf45-fb5a79a9d5c3) ![Spaceship_Image](https://github.com/LinkHpp/Spaceship_NES/assets/63952783/2f1ead34-9c9c-464c-be67-1257c0ae228d)
<img src="[Spaceship_Image](https://github.com/LinkHpp/Spaceship_NES/assets/63952783/2f1ead34-9c9c-464c-be67-1257c0ae228d)" width="100" height="100">
## How to compile .nes ## How to compile .nes
If you want to use my code and change things to compile the .nes just use the assemble.sh file to create it! If you want to use my code and change things to compile the .nes just use the assemble.sh file to create it!
NOTE: It only works on Linux if you are using Windows you'll have to do it manual NOTE: It only works on Linux if you are using Windows you'll have to do it manual

5
assemble.sh Executable file → Normal file
View File

@ -1,6 +1,5 @@
#! /bin/sh #! /bin/sh
ca65 src/spaceship.asm ca65 src/helloworld.asm
ca65 src/reset.asm ca65 src/reset.asm
ca65 src/controllers.asm ld65 src/reset.o src/helloworld.o -C nes.cfg -o helloworld.nes
ld65 src/reset.o src/controllers.o src/spaceship.o -C nes.cfg -o spaceship.nes

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,18 +1,7 @@
PPUCTRL = $2000 PPUCTRL = $2000
PPUMASK = $2001 PPUMASK = $2001
PPUSTATUS = $2002 PPUSTATUS = $2002
PPUSCROLL = $2005
PPUADDR = $2006 PPUADDR = $2006
PPUDATA = $2007 PPUDATA = $2007
OAMADDR = $2003 OAMADDR = $2003
OAMDMA = $4014 OAMDMA = $4014
CONTROLLER1 = $4016
BTN_RIGHT = %00000001
BTN_LEFT = %00000010
BTN_DOWN = %00000100
BTN_UP = %00001000
BTN_START = %00010000
BTN_SELECT =%00100000
BTN_B = %01000000
BTN_A = %10000000

View File

@ -1,35 +0,0 @@
.include "constants.inc"
.segment "ZEROPAGE"
.importzp pad1
.segment "CODE"
.export read_controller
.proc read_controller
PHA
TXA
PHA
PHP
LDA #$01
STA CONTROLLER1
LDA #$00
STA CONTROLLER1
LDA #%00000001
STA pad1
get_buttons:
LDA CONTROLLER1
LSR A
ROL pad1
BCC get_buttons
PLP
PLA
TAX
PLA
RTS
.endproc

Binary file not shown.

View File

@ -2,7 +2,7 @@
.byte $4e, $45, $53, $1a ; Magic string that always begins an iNES header .byte $4e, $45, $53, $1a ; Magic string that always begins an iNES header
.byte $02 ; Number of 16KB PRG-ROM banks .byte $02 ; Number of 16KB PRG-ROM banks
.byte $01 ; Number of 8KB CHR-ROM banks .byte $01 ; Number of 8KB CHR-ROM banks
.byte %00000000 ; Vertical mirroring, no save RAM, no mapper .byte %00000001 ; Vertical mirroring, no save RAM, no mapper
.byte %00000000 ; No special-case flags set, no mapper .byte %00000000 ; No special-case flags set, no mapper
.byte $00 ; No PRG-RAM present .byte $00 ; No PRG-RAM present
.byte $00 ; NTSC format .byte $00 ; NTSC format

421
src/helloworld.asm Normal file
View File

@ -0,0 +1,421 @@
.include "constants.inc"
.include "header.inc"
.segment "CODE"
.proc irq_handler
RTI
.endproc
.proc nmi_handler
LDA #$00
STA OAMADDR
LDA #$02
STA OAMDMA
;Update tiles *after* DMA transfer
JSR update_player
JSR draw_player
LDA #$00
STA $2005
STA $2005
RTI
.endproc
.import reset_handler
.proc draw_player
;save registers
PHP
PHA
TXA
PHA
TYA
PHA
;write player ship tile numbers
LDA #$05
STA $0201
LDA #$06
STA $0205
LDA #$07
STA $0209
LDA #$08
STA $020D
; write player ship tile attributes
; use palette 0
LDA #$00
STA $0202
STA $0206
STA $020A
STA $020E
; store tile locations
; top left tile:
LDA player_y
STA $0200
LDA player_x
STA $0203
;top right tile (x+8):
LDA player_y
STA $0204
LDA player_x
CLC
ADC #$08
STA $0207
;bottom left tile (y+8)
LDA player_y
CLC
ADC #$08
STA $0208
LDA player_x
STA $020B
;bottom right tile (x+8, y+8)
LDA player_y
CLC
ADC #$08
STA $020C
LDA player_x
CLC
ADC #$08
STA $020F
; restore registers and return
PLA
TAY
PLA
TAX
PLA
PLP
RTS
.endproc
.proc update_player
PHP
PHA
TXA
PHA
TYA
PHA
LDA player_x
CMP #$e0
BCC not_at_right_edge
; if BCC is not taken, we are greater than $e0
LDA #$00
STA player_dir ; start moving left
JMP direction_set ; we already chose a direction,
; so we can skip the left side check
not_at_right_edge:
LDA player_x
CMP #$10
BCS direction_set
; if BCS not taken, we are less than $10
LDA #$01
STA player_dir ; start moving right
direction_set:
; now, actually update player_x
LDA player_dir
CMP #$01
BEQ move_right
; if player_dir minus $01 is not zero,
; that means player_dir was $00 and
; we need to move left
DEC player_x
JMP exit_subroutine
move_right:
INC player_x
exit_subroutine:
; all done, clean up an return
PLA
TAY
PLA
TAX
PLA
PLP
RTS
.endproc
.export main
.proc main
LDX PPUSTATUS
LDX #$3f
STX PPUADDR
LDX #$00
STX PPUADDR
LDX #$00
load_palettes:
LDA palettes,X
STA PPUDATA
INX
CPX #$20
BNE load_palettes
LDX #$00
; write a nametable
; Big Stars
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$72
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$68
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$74
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$5A
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$CB
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$64
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$C7
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$55
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$B9
STA PPUADDR
LDX #$2F
STX PPUDATA
LDA PPUSTATUS
LDA #$23
STA PPUADDR
LDA #$6D
STA PPUADDR
LDX #$2F
STX PPUDATA
; write a nametable
; Medium Stars
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$64
STA PPUADDR
LDX #$2D
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$4F
STA PPUADDR
LDX #$2D
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$B9
STA PPUADDR
LDX #$2D
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$DD
STA PPUADDR
LDX #$2D
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$4D
STA PPUADDR
LDX #$2D
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$D1
STA PPUADDR
LDX #$2D
STX PPUDATA
; write a nametable
; Small Stars
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$3A
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$20
STA PPUADDR
LDA #$B9
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$4D
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$4D
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$21
STA PPUADDR
LDA #$F0
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$26
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$E4
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$22
STA PPUADDR
LDA #$CE
STA PPUADDR
LDX #$2E
STX PPUDATA
LDA PPUSTATUS
LDA #$23
STA PPUADDR
LDA #$36
STA PPUADDR
LDX #$2E
STX PPUDATA
; finally, attribute table
LDA PPUSTATUS
LDA #$23
STA PPUADDR
LDA #$D4
STA PPUADDR
LDA #%01110000
STA PPUDATA
vblankwait: ; wait for another vblank before continuing
BIT PPUSTATUS
BPL vblankwait
LDA #%10010000 ; turn on NMIs, sprites use first pattern table
STA PPUCTRL
LDA #%00011110 ; turn on screen
STA PPUMASK
forever:
JMP forever
.endproc
.segment "ZEROPAGE"
player_x: .res 1
player_y: .res 1
player_dir: .res 1
.exportzp player_x, player_y
.segment "RODATA"
palettes:
.byte $0f, $12, $23, $27
.byte $0f, $2b, $3c, $39
.byte $0f, $0c, $07, $13
.byte $0f, $19, $09, $29
.byte $0f, $2d, $10, $15
.byte $0f, $19, $09, $29
.byte $0f, $19, $09, $29
.byte $0f, $19, $09, $29
sprite:
.byte $70, $05, $00, $80
.byte $70, $06, $00, $88
.byte $78, $07, $00, $80
.byte $78, $08, $00, $88
.segment "VECTORS"
.addr nmi_handler, reset_handler, irq_handler
.segment "CHR"
.incbin "starfield.chr"

Binary file not shown.

View File

@ -1,281 +0,0 @@
.include "constants.inc"
.include "header.inc"
.segment "CODE"
.proc irq_handler
RTI
.endproc
.import read_controller
.proc nmi_handler
LDA #$00
STA OAMADDR
LDA #$02
STA OAMDMA
;Update tiles *after* DMA transfer
JSR update_player
JSR draw_player
JSR read_controller
LDA scroll
CMP #$00
BNE set_scroll_positions
LDA ppucrtl_settings
EOR #%00000010
STA ppucrtl_settings
STA PPUCTRL
LDA #240
STA scroll
set_scroll_positions:
LDA #$00
STA PPUSCROLL
DEC scroll
LDA scroll
STA PPUSCROLL
RTI
.endproc
.import reset_handler
.proc draw_player
;save registers
PHP
PHA
TXA
PHA
TYA
PHA
;write player ship tile numbers
LDA #$05
STA $0201
LDA #$06
STA $0205
LDA #$07
STA $0209
LDA #$08
STA $020D
; write player ship tile attributes
; use palette 0
LDA #$03
STA $0202
STA $0206
STA $020A
STA $020E
; store tile locations
; top left tile:
LDA player_y
STA $0200
LDA player_x
STA $0203
;top right tile (x+8):
LDA player_y
STA $0204
LDA player_x
CLC
ADC #$08
STA $0207
;bottom left tile (y+8)
LDA player_y
CLC
ADC #$08
STA $0208
LDA player_x
STA $020B
;bottom right tile (x+8, y+8)
LDA player_y
CLC
ADC #$08
STA $020C
LDA player_x
CLC
ADC #$08
STA $020F
; restore registers and return
PLA
TAY
PLA
TAX
PLA
PLP
RTS
.endproc
.proc update_player
PHP
PHA
TXA
PHA
TYA
PHA
LDA pad1
AND #BTN_LEFT
BEQ check_right
DEC player_x
DEC player_x
check_right:
LDA pad1
AND #BTN_RIGHT
BEQ check_up
INC player_x
INC player_x
check_up:
LDA pad1
AND #BTN_UP
BEQ check_down
DEC player_y
DEC player_y
check_down:
LDA pad1
AND #BTN_DOWN
BEQ done_checking
INC player_y
INC player_y
done_checking:
PLA
TAY
PLA
TAX
PLA
PLP
RTS
.endproc
.export main
.proc main
LDA #239
STA scroll
LDX PPUSTATUS
LDX #$3f
STX PPUADDR
LDX #$00
STX PPUADDR
LDX #$00
load_palettes:
LDA palettes,X
STA PPUDATA
INX
CPX #$20
BNE load_palettes
load_background:
LDX PPUSTATUS
LDX #$20
STX PPUADDR
LDX #$00
STX PPUADDR
LDA #<background
STA pointerLo
LDA #>background
STA pointerHi
LDX #$00
LDY #$00
outsideloop:
insideloop:
LDA (pointerLo), y
STA PPUDATA
INY
BNE insideloop
INC pointerHi
INX
CPX #$04
BNE outsideloop
load_background2:
LDX PPUSTATUS
LDX #$28
STX PPUADDR
LDX #$00
STX PPUADDR
LDA #<background2
STA pointerLo
LDA #>background2
STA pointerHi
LDX #$00
LDY #$00
outsideloop2:
insideloop2:
LDA (pointerLo), y
STA PPUDATA
INY
BNE insideloop2
INC pointerHi
INX
CPX #$04
BNE outsideloop2
LDA #%10010000
STA ppucrtl_settings
STA PPUCTRL
vblankwait: ; wait for another vblank before continuing
BIT PPUSTATUS
BPL vblankwait
LDA #%10010000 ; turn on NMIs, sprites use first pattern table
STA PPUCTRL
LDA #%00011110 ; turn on screen
STA PPUMASK
forever:
JMP forever
.endproc
.segment "ZEROPAGE"
player_x: .res 1
player_y: .res 1
pointerLo: .res 1
pointerHi: .res 1
scroll: .res 1
ppucrtl_settings: .res 1
pad1: .res 1
.exportzp player_x, player_y
.exportzp pad1
.segment "RODATA"
palettes: .incbin "background.pal"
sprite:
.byte $70, $05, $00, $80
.byte $70, $06, $00, $88
.byte $78, $07, $00, $80
.byte $78, $08, $00, $88
background: .incbin "background.nam"
background2: .incbin "background2.nam"
.segment "VECTORS"
.addr nmi_handler, reset_handler, irq_handler
.segment "CHR"
.incbin "starfield.chr"

Binary file not shown.

Binary file not shown.