このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

M1 Macで作る、ファミコンソフトプログラミング。 アセンブラでハローワールド編

Game

2021.11.08

この記事は最終更新日から1年以上が経過しています。

どもです。

前回のこちらの記事に引き続きファミコンプログラミングでもと。

前回は、NES研究所さんのサンプルを動かして「HELLO WORLD」を表示させたのですが、今回は実際にアセンブラでプログラムを書いて作って行こうかと思います。

やりたいこととしては、前回同様に「HELLO WORLD」の文字を画面に出したい。

そんなの、「HELLO WORLD」の文字列を出すだけなら簡単でしょ。

と思いそうですが、昔々のがファミコン時代の頃には文字列というのもなく、端的に言うと文字を出すのも画像(スプライト)を作る必要がある訳なのです。

では、M1 Macの環境でファミコンゲームの作成を行って行きましょう。

 

環境
  • Mac mini (M1, 2020)
  • Mac OS 11.6
  • Apple clang version 13.0.0

スプライト画像作成

という訳で、スプライト画像の作成から行って行くのですが、それには「YYCHR」というツールを用いて作成していきます。

YYCHR – ダウンロード

https://w.atwiki.jp/yychr/

こちら、Windows用のアプリとなりますので、前回の「M1 (Appleシリコン)Macで Widowsアプリを起動」の記事で紹介したように、CrossOver Wineをインストールしそちらで起動します。

 

$ wine64 YYCHR.exe

起動すると、この様な表示になるかと思います。

今回は、「YYCHR」の使い方詳細は割愛させていただきます。

いつか機会があれば書いていきたいとは思いますが、こちらのYYCHRのWikiに使用方法など書かれているので、そちらを使用方法は確認していただけると理解できるかと思います。

ABC…とアルファベットのスプライトを作って行くのですが、こちらの書籍など参考にすると作成がスムーズに進みますので、レトロゲーム作成される方は、1冊持っておくのをオススメします!

 

created by Rinker
グラフィック社
¥3,673 (2024/10/09 07:38:06時点 Amazon調べ-詳細)

 

という事で、上記の書籍を参考に以下の様にスプライトの作成。

作成したスプライトは、character.chrファイルとして書き出しを行います。

 

アセンブラでプログラミング

先程、「YYCHR」で作成したスプライトのcharacter.chrファイルを読み込み、「HELLO WORLD」と表示される様に、hello.asmファイルのアセンブラプログラムを作成します。

作成するアセンブラプログラムは以下の様な感じです。

hello.asm

;---- iNES Header
    .inesprg 1 ; PRG 16KB
    .ineschr 1 ; CHR 8KB
    .inesmap 0 ; Mapper 0
    .inesmir 0 ; horizontal mirroring

;---- bank0
    .bank 0
    .org $C000 

RESET:
    sei
    cld

.vblankWait1
    bit $2002
    bpl .vblankWait1

.vblankWait2
    bit $2002
    bpl .vblankWait2

    ; reset PPU status
    lda $2002
    lda #$3F
    sta $2006
    lda #$00
    sta $2006

    ; X register initialization
    ldx #0

.loadBgPalette
    lda bgPalette, x
    sta $2007

    inx
    cpx #16
    bne .loadBgPalette

    ; reset PPU status
    lda $2002
    lda #$3F
    sta $2006
    lda #$10
    sta $2006

    ; X register initialization
    ldx #0

.loadSpritePalette
    lda spritePalette, x
    sta $2007

    inx
    cpx #16
    bne .loadSpritePalette

    ; H
    lda #$50
    sta $0200
    lda #$07
    sta $0201
    lda #%00000001
    sta $0202
    lda #$10
    sta $0203


    ; E
    lda #$50
    sta $0204
    lda #$04
    sta $0205
    lda #%00000011
    sta $0206
    lda #$18
    sta $0207

    ; L
    lda #$50
    sta $0208
    lda #$0B
    sta $0209
    lda #%00000011
    sta $020A
    lda #$1F
    sta $020B

    ; L
    lda #$50
    sta $020C
    lda #$0B
    sta $020D
    lda #%00000011
    sta $020E
    lda #$26
    sta $020F

    ; O
    lda #$50
    sta $0210
    lda #$0E
    sta $0211
    lda #%00000011
    sta $0212
    lda #$2D
    sta $0213

    ; W
    lda #$50
    sta $0214
    lda #$16
    sta $0215
    lda #%00000011
    sta $0216
    lda #$37
    sta $0217

    ; O
    lda #$50
    sta $0218
    lda #$0E
    sta $0219
    lda #%00000011
    sta $021A
    lda #$3F
    sta $021B

    ; R
    lda #$50
    sta $021C
    lda #$11
    sta $021D
    lda #%00000011
    sta $021E
    lda #$46
    sta $021F

    ; L
    lda #$50
    sta $0220
    lda #$0B
    sta $0221
    lda #%00000011
    sta $0222
    lda #$4D
    sta $0223

    ; D
    lda #$50
    sta $0224
    lda #$03
    sta $0225
    lda #%00000011
    sta $0226
    lda #$54
    sta $0227

    ; NMI
    lda #%10000000
    sta $2000
    lda #%00010000
    sta $2001

.forever
    jmp .forever
  
NMI:
    lda #$00
    sta $2003
    lda #$02
    sta $4014
    rti

IRQ:
    rti

spritePalette:
    .byte $0D, $01, $05, $20
    .byte $0D, $01, $05, $20
    .byte $0D, $01, $05, $20
    .byte $0D, $01, $05, $20

bgPalette:
    .byte $01, $32, $36, $3A
    .byte $01, $22, $26, $2A
    .byte $01, $12, $16, $1A
    .byte $01, $02, $06, $0A

;---- bank1
    .bank 1
    .org $FFFA
    .word NMI
    .word RESET
    .word IRQ


;---- bank2 (CHR bank0)
    .bank 2
    .org $0000
    .incbin "character.chr"

色々書かれていますが、全部説明となると途方もないので、とりあえず、bank2に先程作成したスプライトのcharacter.chrを読み込んで、.loadSpritePaletteでスプライトの種類、位置を設定して画面に配置しております。

それでは、上記のアセンブラプログラムを元に、ファミコン実行ファイル「.nes」形式にアセンブルするために「nesasm」をインストールしていきます。

nesasm インストール

NES 6502 assemblyをアセンブルするため「nesasm」をインストールしていきます。「nesasm」のソースはgithubに上がっております。

 

nesasm

https://github.com/camsaul/nesasm

zipファイルをダウンロードを行うか、git clone行うかしローカルにファイルをダウンロードします。

以下のコマンドを実行nesasmをインストールします。

$ cd source && make && sudo make install

インストール完了後、nesasmコマンド実行し、以下の様に表示すれば問題なくインストール完了です。

nesasm
NES Assembler (v3.1)

nesasm [-options] [-? (for help)] infile

-s/S   : show segment usage
-l #   : listing file output level (0-3)
-m     : force macro expansion in listing
-raw   : prevent adding a ROM header
-srec  : create a Motorola S-record file
infile : file to be assembled

 

先程の作成したスプライトのcharacter.chrファイルと、hello.asmが置かれたディレクトリにて以下のコマンドを実行します。

$ nesasm hello.asm

すると、新しく「hello.fns」と「hello.nes」ファイルが生成されます。

「hello.nes」ファイルが実行ファイルとなりますので、エミュレーターを使ってデバッグしてみましょう。

 

シミュレータでデバッグ

ファミコンシミュレータは沢山存在します。

とりあえず、開発用として重宝されている有名な「fceux」でデバッグを行うと。

fceux

おお。問題なく表示されていますね。

続いて、「Open Emu」でデバッグしてみると。

 

Open Emu

おや、「LD」の2文字が表示されません。。

バグか。。と思われがちですが、ファミコンの仕様としてはこちらが正解。

スプライトは、同時に8個以上並べられない仕様なのです。8個以上並べると表示されなくなります。

Open Emuのコアは、FCE Ultraぽいので、こちらのほうが仕様に沿っていて、FCE Ultraからフォークされて拡張された「fceux」では仕様通りではないって感じでしょうか。(検証してみた感想)

という訳で、仕様に沿って文字表示されたいとなると、Wからの文字をずらしたりすると良いでしょうか。

Wから Y座標を10ずらしてみます。

; W
    lda #$60
....

 

すると、以下の様に全てのスプライトが表示され「HELLO WORLD」と認識できました。

この手法はなにか見覚えありますね。

そう、チャレンジャーのゲーム中によく出てくる文字表示の表現だ!

仕様に沿って、8個以上文字が並ばないように、少しずつずらして、文字を表示されているのがわかりますね。

当時はおしゃれでやっているのかと思っておりましたが、そういった理由があったのですね。

 

終わり

と、ざっくり書いてきましたが、アセンブラでプログラムを作成すると辛いことが確認できましたので(そりゃそうだ 笑)、現在では C言語などでも作成できるようになっておりますので、今後は開発する際はそちらでやって行こうかなとか思っております。

ただ、やることいっぱいなので、後になっていくのだろうなぁと思っております。。。

ではでは。またまた。

Comment

Related Article

M1Macで、PSP モンハン3 をプレイする。

2022.01.23

M1 Macで作る、ファミコンソフトプログラミング。 アセンブラでハローワールド編

2021.11.08

う、動くぞ! M1 Mac(Big Sur)で PS2ソフトを遊ぶ。PCSX2 Mac版を起動

2021.11.07

ゲオ 驚異の80%オフセール開催中! 中古ソフト大量購入!! まだ間に合う急げぇ〜!

2021.10.24

【2021】ゲオのサマーセール 980円以下のゲームソフトが半額!8月16日(月)まで。で購入したもの。

2021.08.08

M1(Appleシリコン)Macで、ファミコンソフトプログラミング。 サクッと開発環境準備編

2021.03.21

ゲオのサマーセール 980円以下のゲームソフトが半額!8月16日(日)まで。で購入したもの。

2020.08.13

Mac用 エミュレーター 「OpenEmu」が、V2.2リリース!GameCube対応して更に神アプリ進化!

2020.01.01

この時期になると、やたらレトロゲームをやりたくなるのはなんですかね?ハードオフに向かうの巻その2

2019.12.31

この時期になると、やたらレトロゲームをやりたくなるのはなんですかね?ハードオフに向かうの巻

2019.12.14

CATEGORY LIST

LATEST NEWS

Mac VSCodeで、SFML C++開発環境を作る。

C++

2024.09.09

Rust-SDL2 examplesをすべて試す

Rust

2024.09.01

JavaScriptで、DOMを放り投げる処理

JavaScript

2024.07.27

Rustで創る MOS 6502 CPU その2

Rust

2024.07.23

Rustで創る MOS 6502 CPU その1

Rust

2024.07.19

汎用 3D mesh/model viewerを求め。と、簡単に、FBXファイルをglTF(glb)に変換ツールを求め。

C++

2024.06.06

M1 Macで、OpenGL GLUTを使ってコンパイルする

C

2024.04.27

Rust - Actix Web mongo ユーザー登録 JWT認証

Rust

2024.03.24

Rust - Actix Web JWT 認証認可 APIの作成

Rust

2024.02.25

Rust - Actix Web × JSON 静的ファイルをAPIで返却

Rust

2024.01.19

Rust - Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

5分で学ぶ RustでWave Function Collapse (波動関数崩壊アルゴリズム)

Rust

2024.01.15

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US