.setcpu "6502"
.feature c_comments ; /* comments */ の複数行のコメントを許可(通常はセミコロン)
.feature underline_in_numbers ; 数値の途中に %1010_0010 のようにアンダーバーを挟めるようにする(2進数の表記に便利
; ここで指定しているものはiNESヘッダーという
; https://www.nesdev.org/wiki/INESを参照
.segment "HEADER"
.byte "NES", $1a
.byte $02 ; プログラム領域のサイズ(16KB * 2)
.byte $01 ; キャラクタ領域のサイズ(8KB * 1)
.byte $01 ; 垂直ミラー(2画面が横方向につながる)
.byte $00
.byte $00, $00, $00, $00
.byte $00, $00, $00, $00
;! 定数追加
PPU_CTRL1 = $2000 ; 上位のビットからNMIのON/OFF,PPUのマスター/スレーブ(よくわからない),スプライトのサイズ,
; BGの開始アドレス,スプライトの開始アドレス,VRAMのインクリメント量,スクリーン番号
PPU_CTRL2 = $2001 ; 赤強調,緑強調,青強調,スプライトの表示,BGの表示,左端スプライトの表示,左端BGの表示,カラーモード
PPU_SCROLL = $2005 ; スクロール座標を指定するときに使う(一回目のストア→X座標,二回目のストア→Y座標)
PPU_ADDR = $2006 ; VRAMのアドレス指定に使う(一回目→上位,二回目→下位のバイト)
PPU_DATA = $2007 ; VRAMにストアするときに使う
.code ; 以下プログラム領域
.segment "STARTUP" ; 起動時のプログラム開始位置
RESET: ; RESETという名前のラベル(ここにジャンプさせることができる)
sei ; IRQ禁止(割り込み処理の禁止)
cld ; BCD禁止(BCD機能はファミコンで除外されているので,やる必要性はわからない)
ldx #$ff ; X = #0xff(アドレスではなく,即値)
txs ; スタックレジスタ(S)に#$ffを指定
lda #0 ; #がついてないのは10進数を示す
; 画面をOFFに
sta PPU_CTRL1
sta PPU_CTRL2
; RAMの初期化(ある初期値,ここでは0を入れること)を行う
lda #0
CLEAR_MEMORY:
sta $00, x ; $00XX番台は$XXと省略できる
sta $0100, x
sta $0200, x
sta $0300, x
sta $0400, x
sta $0500, x
sta $0600, x
inx
bne CLEAR_MEMORY ; X == 0(Xが$ffからオーバーフローして0に戻る)までループ
; $0700番台にはスプライト情報を入れる
; 都合がいいので#$ffで初期化
lda #$ff
CLEAR_SPRITE_MEMORY:
sta $0700, x
inx
bne CLEAR_SPRITE_MEMORY
; VRAM(PPUのRAM)を初期化する
; アドレス$2000を初期化開始位置に指定
lda #$20
sta PPU_ADDR
lda #$00
sta PPU_ADDR
; $100回のループ(Xレジスタがカウンタ)を8回ループさせる(Yレジスタがカウンタ)
; なので,$2000~$27ff($800の領域)を初期化できる
; $2000~$23ffが画面1,$2400~$27ffが画面2(画面1の横隣り)の領域
ldx #0
ldy #8
CLEAR_VRAM:
sta PPU_DATA
inx
bne CLEAR_VRAM
dey
bne CLEAR_VRAM
lda #>($2000+13+14*$20) ; 16bitのうち上位8bitだけ使う書き方
sta PPU_ADDR
lda #<($2000+13+14*$20) ; 下位8bit
sta PPU_ADDR
lda #'H'
sta PPU_DATA
lda #'E'
sta PPU_DATA
lda #'L'
sta PPU_DATA
lda #'L'
sta PPU_DATA
lda #'O'
sta PPU_DATA
; パレットテーブル(色を管理する領域)へパレットデータを転送
; $3f00から開始
lda #$3f
sta PPU_ADDR
lda #$00
sta PPU_ADDR
ldx #$00
TRANSFAR_PALETTE:
lda PALETTES, x ; 高級言語的に書くと A = palettes[x]
sta PPU_DATA ; $3f00から順($3f00のあとは$3f01,そのあとは$3f02...)にストアされていく(ストア=RAMへの書き込み)
inx
cpx #$10
bne TRANSFAR_PALETTE ; X = $10までループ
;! 以下省略