ファミコンROM作ってみた:開発編(環境）

#CC65コンパイラ環境構築

###コンパイラダウンロード
コンパイラは下記のリンクのスナップショットを利用しました。

https://cc65.github.io/
サイト内、Widows Snapshotのリンクからダウンロードサイトに飛べます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/90a10571-e8b6-1b7b-e920-18de2d365448.png)

クリックしてしばらく待つとcc65-snapshot-win32.zipのダウンロードができるようになりますので、ダウンロードして任意の場所に展開しましょう。

###展開結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/a8e27902-6bf9-3e5d-0c36-52b70c12c056.png)

###機能確認
下記のコードとビルド用のバッチファイルを同じフォルダに入れてでコンパイラが動作するのかを確認

cc65@wikiのhallo cc65ページ
test.cのコード
https://w.atwiki.jp/cc65/pages/14.html

```hallo.c
#include <conio.h>
int main (void)
{
    clrscr();
    cprintf("hello cc65");
    while(1)
    {
    }
    return 0;
}
```

```build.bat
rem utf-8
chcp 65001

rem 展開したコンパイラのパス
set CC65_PATH="C:\Program1\cc65-snapshot-win32"
PATH %CC65_PATH%\bin;%PATH%

rem set命令でコンパイラに必要な定義を設定
set CA65_INC=%CC65_PATH%\include
set CC65_INC=%CC65_PATH%\include
set LD65_CFG=%CC65_PATH%\cfg
set LD65_LIB=%CC65_PATH%\lib
set LD65_OBJ=%CC65_PATH%\obj
set CC65_HOME=%CC65_PATH%
 
rem コンパイル(.sファイル作成）
cc65 -t nes hallo.c

rem アセンブル(.oファイル作成）
ca65 -t nes hallo.s

rem リンク(.nesファイル作成）
ld65 -t nes hallo.o nes.lib -o hallo.nes

pause
```
hallo.nes実行結果（※VirtualNES利用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/ab8420f0-86ca-f63e-1e3f-a15c33e6199a.png)

動作が確認出来たらコンパイラの環境は完了。

#各種NESエミュレーターダウンロード
作成したROMの動作確認のために、NESエミュレーターを数種類用意しておきましょう。
（それぞれで仕様が違う為か、動作が違うケースがあります）

VirtualNES　※各ビューワーが用意されているVirtualNESがまずは利用しやすいかもしれません。
http://virtuanes.s1.xrea.com/

nesterj
http://www.dcn.ne.jp/~otim2/nesterj/

nestopia
http://nestopia.sourceforge.net/

FCEUX ※各種デバッグ用に
http://fceux.com/web/home.html

#makeファイルの利用環境
複数ファイルでコードを記載しやすいようmakefileを用意できるようにしておきます。

###make環境のインストール
下記リンク先からまず、MSYS2（msys2-x86_64-????????.exe)をダウンロードし、インストールします。
https://www.msys2.org/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/d2bce0c1-2615-eb66-e03e-ddb7deb76610.png)

トップページにある通り、Msys2.exeを実行（※インストールの最後にも実行のチェックボックスがあります）し、下記のコマンドで各種インストールを行ってください。

```
$ pacman -Syu
```
```
$ pacman -Su
```
```
$ pacman -S --needed base-devel mingw-w64-x86_64-toolchain
```


次に、下記のリンク先からComplete package, except sources	のSetUpを選択し、make-?.??.exeをダウンロードし、実行します。
http://gnuwin32.sourceforge.net/packages/make.htm
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/f0723906-c74b-dcba-02f4-bbff2a43a8b7.png)

そのままインストールを進めると下記のフォルダに実行ファイルがコピーされます。
C:\Program Files (x86)\GnuWin32

環境変数に上記のパスを指定しておきましょう。
システム＞システムの詳細設定＞環境変数＞環境変数のパス設定
（Path環境変数にインストールしたフォルダを追加しておきましょう）

コマンドプロンプトで”make -v"と打ってみましょう。
正常にインストールされている下記のような説明が出てくるので、これでmakeが利用できるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181347/944439fb-db8a-7f02-9f01-0047f8cd7eb8.png)

###Makefileの記述
"MakeFile"という名前で、hallo.cの入れてあるフォルダに入れてください。
好みでソースファイル用のフォルダを作成してDIR定義を追記してもいいと思います。
LIB_DIRは別途ファンクションコード用の場所を分けたい場合に定義できるようにしてあります。

```Makefile
PROJECT  := $(shell basename $(CURDIR))

LIB_DIR  := 
SRC_DIR  := .
BIN_DIR  := bin
OBJ_DIR  := obj

TARGET   := $(BIN_DIR)/$(PROJECT).nes
CFGFILE  := $(LIB_DIR)/build.cfg

CFILES   := $(wildcard $(SRC_DIR)/*.c) $(wildcard $(LIB_DIR)/*.c)
SFILES   := $(wildcard $(SRC_DIR)/*.s) $(wildcard $(SRC_DIR)/*.asm) $(wildcard $(LIB_DIR)/*.asm)
LIBS     := nes.lib

OBJS     := \
	$(foreach file, $(CFILES), $(OBJ_DIR)/$(basename $(notdir $(file))).o) \
	$(foreach file, $(SFILES), $(OBJ_DIR)/$(basename $(notdir $(file))).o)

DEPENDS  := $(wildcard $(OBJ_DIR)/*.dep)

ASFLAGS  := -t nes
CFLAGS   := -t nes -j 
LDFLAGS  := -t nes

CC       := cl65
AS       := cl65
LD       := ld65
RM       := rm -rf
MKDIR    := mkdir

$(OBJ_DIR)/%.o: $(LIB_DIR)/%.c
	$(CC) $(CFLAGS) --create-dep $@.dep -c -o $@ $<

$(OBJ_DIR)/%.o: $(LIB_DIR)/%.s
	$(AS) $(ASFLAGS) --create-dep $@.dep -c -o $@ $<

$(OBJ_DIR)/%.o: $(LIB_DIR)/%.asm
	$(AS) $(ASFLAGS) --create-dep $@.dep -c -o $@ $<

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
	$(CC) $(CFLAGS) --create-dep $@.dep -c -o $@ $<

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.s
	$(AS) $(ASFLAGS) --create-dep $@.dep -c -o $@ $<

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.asm
	$(AS) $(ASFLAGS) --create-dep $@.dep -c -o $@ $<


.PHONY: all
all: clean init $(TARGET)

.PHONY: clean
clean:
	- $(RM) $(BIN_DIR)
	- $(RM) $(OBJ_DIR)


.PHONY: init
init:
	@$(if $(shell ls | grep $(BIN_DIR)) , , $(MKDIR) $(BIN_DIR))
	@$(if $(shell ls | grep $(OBJ_DIR)) , , $(MKDIR) $(OBJ_DIR))

.PHONY: run
run: all
	$(VM_PATH) $(TARGET)

$(TARGET): $(OBJS)
	@ echo Create $@
	$(LD) $(LDFLAGS) -m $@.map -o $@ --obj $(OBJS) --lib $(LIBS)
	@ echo Done.

-include $(DEPENDS)
```

###make実行用のバッチファイル
MakeFileと同一のフォルダに入れて実行してください。
MSYS_HOME、CC65_HOMEはそれぞれインストールした場所のフォルダを指定してください。
（※環境変数に設定していれば不要です）

```_makefile.bat
set MSYS_HOME=c:\msys64
set CC65_HOME=C:\Program1\cc65-snapshot-win32
set PATH=%CC65_HOME%\bin;%MSYS_HOME%\usr\bin;%PATH%

make

pause
```

#参考
cc65@wiki
https://w.atwiki.jp/cc65/

日経ソフトウエア 2020年11月号
「ファミコンで動くゲームを作ろう」記事


#関連記事
[ファミコンROM作ってみた](https://qiita.com/tmori/items/a130fb0364dc5f757d67)
[ファミコンROM作ってみた:開発編(画像コンバーター）](https://qiita.com/tmori/items/e952a9d5e150e60af393)
[ファミコンROM作ってみた:開発編(環境）](https://qiita.com/tmori/items/14e250c52d362a403cbe)
[ファミコンROM作ってみた:開発編(ビルド）](https://qiita.com/tmori/items/ab1f163667878a7c9bf5)
[ファミコンROM作ってみた:開発編(コード設計）](https://qiita.com/tmori/items/d49fd2b261fcab86f0a4)
[ファミコンROM作ってみた:開発編(共通関数ライブラリ）](https://qiita.com/tmori/items/bc0cebefe64959337428)
[ファミコンROM作ってみた:開発編(プロダクト用関数ライブラリ）](https://qiita.com/tmori/items/ad667c6dd8cd2c27f80b)
[ファミコンROM作ってみた:開発編(mainとフローの処理コード）](https://qiita.com/tmori/items/ed9f4d85fb7fcc99ccae)
[ファミコンROM作ってみた:開発編(キャラクター制御コード）](https://qiita.com/tmori/items/ddf96075f05d0a1f710d)