Nov17th

CC65(CA65) のバックアップソース(No.7)

Top / CC65(CA65)

*CC65(CA65) is [#h4e2e31b]
-各種ファミコンエミュレータで動作する.nesファイルを生成するassembler

*環境整備 [#ic5d41d2]
-CC65
available for downloadからwindows版をダウンロード
http://www.cc65.org/oldindex.php#Download

-NES研究室サンプル
サンプル1をダウンロード
http://hp.vector.co.jp/authors/VA042397/nes/sample.html

-Virtual NES
作成した.nesファイルのエミュレート用

-makeコマンド
make for Windowsをインストール
Completeパッケージをダウンロード
http://gnuwin32.sourceforge.net/packages/make.htm
~

*ビルド [#ge41a965]
-NES研究室のサンプル内のmakefileを利用してmake
--makeコマンドはcygwinを入れるかmake on Windowsを入れる
--メモリマップを記述したmain.cfgも必要

-以下のファイルを同じディレクトリに入れて,cmd.exeからmakeを実行
--CC65一式
--各種割り込みを記述した,mainとなる.asmファイル
--makefile
--main.cfg
~

*文法 [#jb601fa9]
-16進数値
$を付ける
例: $00、$81

-即値
#を付ける
例: #$00、 #$29
~

*コントロールコマンド [#h2cb4431]
-.segment
セグメントを切り替える。
データやニーモニックを配置するには、.cfgファイルでセグメントにメモリ割り当てをしておく必要がある。
#highlight(cpp){{
.segment "HEADER"
    ...
    ...

.segment "INIT"
    ...
    ...
}}

-.byte
バイトサイズのデータ(8bit)を配置する。
.cfgファイルでセグメントにメモリを割り当てる必要がある。
#highlight(cpp){{
.segment "DATA"
    .byte    $06    ;0x06
    .byte    $4E, $45, $53, $1A    ;NES Header
}}

-.word
ワードサイズのデータ(16bit)を配置する。
#highlight(cpp){{
.segment "DATA"
    .word    $0000    ;0x0000
    .word    $3E64    ;0x3E64
}}

-.proc、.endproc
サブルーチンを定義する。
#highlight(cpp){{
.proc Reset
    ....
.endproc
}}
~

*サウンド再生 [#d3f2cde9]
-440Hz(ラ)の矩形波音を一瞬だけ再生
--レジスタにセットする値x = 1790000 / (f * 32) - 1 = 126 = $007e
--$4002にセットする値の下位8bit,$4003に上位8bitをセット
#highlight(cpp){{
;初期化ブロック 割り込み後など
.segment "STARTUP"
.proc    Reset
    ;サウンド有効化
    lda    #$1F
    sta    $4015

;ゲームループ
.proc    mainLoop
;再生
    lda    #$7e
    sta    $4002
    lda    #$00
    sta    $4003
}}

*メモ [#e73c7d8d]
-:+ ,:-
Unnamed Label、無名ラベル
+・-の数だけ前・後ろの無名ラベル:に飛ぶ
#highlight(cpp){{
    jmp    :+
    lda    #$00    ;スキップ
:   lda    #$01    ;ここから

    jmp    :+++    ;増やせる
:   lda    #$00    ;スキップ
:   lda    #$01    ;スキップ
:   lda    #$02    ;ここから    

}}
#highlight(cpp){{
:   lda    #$00    ;永久ループ
    jmp    :-
    lda    #$01    ;呼ばれない
}}

-@ラベル
普通のラベル内だけで有効なラベル
ループ等に用いられる
Cheap Labelと呼ばれる

-jmpで飛んだ先からrtsで帰ってこれる
.proc~.endprocとの違いは不明
jmpは一方通行もできるから、.procは戻ってくることを明確にしてるのかもしれない

-.ifdef、.else、.endifを使えばプリプロセスで分岐制御できる

-?jsrでラベル以外の番地に飛ぶ方法
8bitレジスタで16bitアドレスを計算する方法が分からんちん

-プログラムのエントリーポイントはリセット割り込みの指定先アドレスになる。

-$0000番地から4+12byte分の領域は、NES用ヘッダのデータが指定される。
先頭4byteには固有の値が、残りの12byteにはバンクの数やミラーリング方式が指定される。
#highlight(cpp){{
.segment "HEADER"    ;$0000に配置
    .byte    $4E, $45, $53, $1A    ;NES Header
    .byte    $02                            ;プログラムバンク数
    .byte    $01                            ;キャラクターバンク数
    .byte    $01                            ;ミラーリング方式(垂直ミラーリング)
    .byte    $00                            ;不明
    .byte    $00, $00, $00, $00    ;不明
    .byte    $00, $00, $00, $00    ;不明
}}

-$FFFA番地からword3つ分の領域は、各種割り込みの分岐先が指定される。
上から順に、VBlank割り込み、リセット割り込み、ハードウェア割り込み。
#highlight(cpp){{
.segment "STARTUP"
.proc Reset
.endproc

.segment "INTERRUPT"    ;$FFFAに配置
    .word    $0000    ;VBlank
    .word    Reset     ;リセット
    .word    $0000    ;ハードウェア
}}

-メモリサイズは8bit以上16bit以下なので、16bitの値で指定する。
レジスタにメモリアドレスを格納する場合2つ使用する必要がある。

-ROMとRAMの違いを押さえておく

-VirtualNESだと.incbinにオフセット値を与える命令が使えない
#highlight(cpp){{
    .incbin "data.dat", $100
}}
これが含まれると「未定義の命令が実行されました」のダイアログが出て止まる
~

*リンク [#xf983ebc]
-NES研究室
http://hp.vector.co.jp/authors/VA042397/nes/index.html
ニーモニックやアーキテクチャ、サンプルなどなど

-CA65 Users Guide
http://www.cc65.org/doc/ca65.html

-Control Commands
http://www.cc65.org/doc/ca65-11.html
.byte等のCC65用プリプロセスコマンド集。

#highlight(end)