1. はじめに

セガ ゲームギアは1990年10月に発売されたセガの携帯型ゲームハード。当時、国内の携帯ゲーム機市場はモノクロの任天堂 ゲームボーイが主流でしたが、本機はカラー液晶を備え全世界で1000万台ほど普及しました。
なお、写真のちいかわはゲームギアとなんの関係もありません。
本記事では、私のようなド素人でも順番を追ってコピペすれば「ゲームギアのエミュレーターでプログラムが動く」ことを目標としています。
プログラミング言語はZ80のアセンブリ言語、開発環境はWindows11です。今回はプログラムそのものの内容には踏み込まず概略の説明のみにとどめています。
「細かいことはいいんだよ! ワイもさっぱりわかんねぇから」という姿勢なので、わからないところはChatGPTや詳しい方に聞いてくださいませ。
記載内容の間違い、誤記、誤字脱字、へんてこなコードなどは当方の責任です。皆様方におかれましては正しく変換してもらいつつ暖かくご指導を賜れれば幸いです。
2. 準備するもの
いろいろなアプリが出ていますが、今回は下記でトライ! 記事の段階ごとに紹介していくので、急いでインストールなどはしなくて大丈夫です。
- エディタ(プログラムを書くためのソフト)
- メモ帳などのテキストエディタやVisual Sutudio Codeなどの開発ソフト
- 本記事ではメモ帳を使います(ちなみに普段はVisual Studioを使っています)
- アセンブラとリンカ(書いたプログラムを機械で読めるようにするプログラム)
- WLA-DX
- ゲームギアミュレーター
- Gearsystem
3. プログラム作成のながれ
プログラム作成の流れは以下となります。
- エディタでプログラムをコピペ
- WLA-DXに付属するWLA-Z80でオブジェクトファイル(機械が読める一歩手前のファイル)に変換
- WLA-DXに付属するWLALINKで実行ファイル(機械が読めるファイル)に変換
- ゲームギアエミュレーター Gearsystemで実行
- 喜ぶ!
4. アセンブリプログラムのファイルを作る
適当な場所に保存用フォルダを作り、メモ帳を開き「名前をつけて保存」しましょう。この時、ファイルの種類は「すべてのファイル」、拡張子はアセンブリファイルを示す「.asm」あたりをつけておくとなにかと便利です。
本記事ではプログラムをコピペするファイルを「chapter_1.asm」とし、フォルダ構成は以下としました。
C:/
└ ggProgrammings
└ chapter_1_helloWorld/
└ chapter_1.asm など
5. レッツコピペ ~Hello Worldのプログラムを作る
本記事のプログラム部分(黒い背景のところ)を上から順にメモ帳のファイルにコピペして保存してもらえればOKです。
「私がわかる範囲」「ポイントかなと思う部分」についてブロックごとに解説を加えております。興味があったら読んでみてね。
5-1. 初期設定のコピペ
;========================================
; 1.WLA-DX バンク、スロット設定
;========================================
.memorymap
defaultslot 0
slotsize $8000
slot 0 $0000
.endme
.rombankmap
bankstotal 1
banksize $8000
banks 1
.endro
;========================================
; 2.変数定義
;========================================
.define VDPControl $bf
.define VDPData $be
.define VRAMWrite $4000
.define CRAMWrite $c000
;========================================
; 3.SDSCタグ SMSロムヘッダー
;========================================
.sdsctag 0.1,"Hello World!", "GG Programming Tutorial 1","SEGA-YAROW"
;========================================
; 4.バンク指定
;========================================
.bank 0 slot 0
.org $0000
;========================================
; 5.割り込みモードの指定
;========================================
di
im 1
jp main
.org $0066
;========================================
; 6.ポーズボタン制御
;========================================
;割り込み時になにもしない
retn
5-1-1. バンク・スロット設定
ゲームギアのCPU Z80が扱えるメモリは64KB。ゲームギアのメモリ構成(メモリマップ)では1ページを16KBに区切り4ページ構成となります。先頭3ページでバンクの切り替えが可能。より大きな容量の情報を扱うことができます。最後の1ページはメインRAMなどに使われます。
今回は小規模なプログラムなのでバンク切り替えは使用していません。
5-1-2. 変数定義
プログラムをわかりやすくするために、特定の値や場所を変数として名前をつけておきます。
例えば、画像を表示するために使うVDPプロセッサにアクセスするには、\$BFというI/Oポートを使います。I/Oポートは、CPUが外部のチップやデバイスと情報をやり取りするための「出口」のようなものです。
\$BFをそのままプログラムの中で何度も書いてもいいのですが、プログラムを分かりやすくするために、VDPControlという名前の変数を使って、$BFの場所をまとめておくことにしています。
5-1-3. SDSCタグ SMSロムヘッダー
ゲームギアのソフトであることを識別する情報を生成します。WLA-DXの独自機能になります。特定のメモリ領域に識別情報を直接書いてもよいでしょう。やや微妙な話が絡む気がするので自分で調べてみてね。
5-2. VDPやVRAMの初期設定のコピペ
;========================================
; 7.プログラム本体
;========================================
main:
ld sp, $dff0 ; スタックポインタ初期化
;========================================
; 7-1.VDP設定
;========================================
;VDPの準備待ち
init_vdp:
in A,($7E)
cp $B0
jp nz, init_vdp
;VDPの 設定
ld hl, VDPInitData
ld b, VDPInitDataEnd-VDPInitData
ld c, VDPControl
otir
;========================================
; 7-2.VRAMを初期化
;========================================
ld hl, $0000 | VRAMWrite ; VRAMの先頭アドレスをVRAMへセット
call SetVDPAddress
ld bc, $4000 ;16KBをクリア
clear_vram:
xor a
out (VDPData), a
dec bc
ld a, b
or c
jr nz, clear_vram
5-2-1. VDPの設定
ゲームギアでは、VDP(Video Display Processor)が画面表示を司ります。このVDPは画像表示に必要なデータを管理するVRAMという専用のメモリ領域を使用しています。ゲーム内の背景やスプライト、スクロール設定などのデータをこのVRAMに書き込むことで、画面に画像が表示される仕組みです。
ここではVDPの初期設定としてレジスタ0~10の専用領域に設定情報を書き込んでいます。
5-3. VDPへ画像関連の諸データの書き込みと表示のコピペ
;========================================
; 7-3.パレットデータをパレットテーブルへ書き込む
;========================================
ld hl, $0000 | CRAMWrite ; パレットデータの先頭アドレスをVRAMへセット
call SetVDPAddress
ld hl, PaletteData ; パレットデータの書き込み
ld bc, PaletteDataEnd-PaletteData ;データサイズ(繰り返し処理に必要)
call CopyToVDP
;========================================
; 7-4.タイルパターンをパターンテーブルへ書き込む
;========================================
ld hl, $0000 | VRAMWrite ; タイルパターンの先頭アドレスをVRAMへセット
call SetVDPAddress
ld hl, FontData ; タイルパターンの書き込み
ld bc, FontDataEnd-FontData
; ld bc, FontDataSize ;外部ファイルを使う場合(コメントアウト中)
call CopyToVDP
;==============================================================
; 7-5.ネームテーブルを書き込む
;==============================================================
ld hl,$3AD4 | VRAMWrite ; ネームテーブルの先頭アドレスをVRAMへセット
call SetVDPAddress
ld hl, Message ; ネームテーブルを書き込み
write_nametable:
ld a, (hl)
cp $ff
jr z, end_nametable
out (VDPData), a
xor a
out (VDPData), a
inc hl
jr write_nametable
end_nametable:
;========================================
; 7-6.スクリーン起動
;========================================
;VDPレジスター番号1で画面をコントロール(0:OFF 1:ON)
ld a, %11000000
; |||||||`- 固定 0
; ||||||`-- 1スプライトにつき2タイル利用(8x16ドット)
; |||||`--- 固定 0
; ||||`---- 固定 0
; |||`----- 固定 0
; ||`------ VBlank 割り込み
; |`------- ディスプレイ起動
; `------- 固定 1
out (VDPControl), a
ld a, $81
out (VDPControl), a
; プログラム停止ループ
-: jr -
5-3-1. 画像表示の流れ
ゲームギアなどレトロゲームハードでは、画像の表示に至る手順があります。
- 画像に使うカラーパレット情報を、画像表示をつかさどるVDPのVRAMの指定領域(パレット)に書きこむ
- 画像を8×8ドットなどに分解したタイルパターンを、同じくVRAMの指定領域(パターンテーブル)に書き込む
- 画面上のタイル並び順を、同じくVRAMの指定領域(ネームテーブル)に書き込む。VRAMの書き込み位置で表示場所を指定
これらが正しく実行されると画像が表示されます。
5-4. 補助関数のコピペ
;==============================================================
; 8.補助関数
;==============================================================
SetVDPAddress:
; VDPアドレスをセットします
; パラメータ: hl = アドレス
push af
ld a, l
out (VDPControl), a
ld a, h
out (VDPControl), a
pop af
ret
CopyToVDP:
; VDPへデータを書き込み
; パラメータ: hl = データのアドレス、bc = データ長
; a, hl, bcに設定
copy_loop:
ld a, (hl) ;アドレス内のデータを取得
out (VDPData), a
inc hl ;次のアドレスへ
dec bc
ld a, b
or c
jr nz, copy_loop
ret
5-4-1. 補助関数
VDPのアドレスをセットする命令、VDPに情報を流す命令などはまとめておいて呼び出せるようにしています。繰り返し使うような命令はまとめておくと便利。
5-5. データのコピペ
;==============================================================
; 9.データ
;==============================================================
;VDPの設定データ(設定情報,レジスタ番号)
VDPInitData:
.db $04,$80,$00,$81,$ff,$82,$ff,$85,$ff,$86,$ff,$87,$00,$88,$00,$89,$ff,$8a
VDPInitDataEnd:
;パレットデータ
PaletteData:
.dw $000 $FFF ; 黒と白
PaletteDataEnd:
;タイルパターンデータ
FontData:
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $BB $00 $00 $00 $BB $00 $00 $00 $BB $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $BB $00 $00 $00 $01 $00 $00 $00 $BB $00 $00 $00 $BB $00 $00 $00 $BB $00 $00 $00 $01 $00 $00 $00 $BB $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $81 $00 $00 $00 $6F $00 $00 $00 $83 $00 $00 $00 $ED $00 $00 $00 $03 $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $1D $00 $00 $00 $5B $00 $00 $00 $17 $00 $00 $00 $EF $00 $00 $00 $D1 $00 $00 $00 $B5 $00 $00 $00 $71 $00 $00 $00 $FF $00 $00 $00
.db $8F $00 $00 $00 $77 $00 $00 $00 $77 $00 $00 $00 $8F $00 $00 $00 $75 $00 $00 $00 $7B $00 $00 $00 $85 $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $C7 $00 $00 $00 $BF $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $BF $00 $00 $00 $C7 $00 $00 $00 $FF $00 $00 $00
.db $C7 $00 $00 $00 $FB $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FB $00 $00 $00 $C7 $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $6D $00 $00 $00 $AB $00 $00 $00 $C7 $00 $00 $00 $AB $00 $00 $00 $6D $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $01 $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $8F $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $FD $00 $00 $00 $FB $00 $00 $00 $F7 $00 $00 $00 $EF $00 $00 $00 $DF $00 $00 $00 $BF $00 $00 $00 $7F $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $79 $00 $00 $00 $75 $00 $00 $00 $6D $00 $00 $00 $5D $00 $00 $00 $3D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $8F $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $FD $00 $00 $00 $83 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $FD $00 $00 $00 $E3 $00 $00 $00 $FD $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $BB $00 $00 $00 $BB $00 $00 $00 $7B $00 $00 $00 $7B $00 $00 $00 $01 $00 $00 $00 $FB $00 $00 $00 $FB $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $03 $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $03 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FB $00 $00 $00 $FB $00 $00 $00 $F7 $00 $00 $00 $F7 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $8F $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $DF $00 $00 $00 $BF $00 $00 $00 $7F $00 $00 $00 $BF $00 $00 $00 $DF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $F7 $00 $00 $00 $FB $00 $00 $00 $FD $00 $00 $00 $FB $00 $00 $00 $F7 $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $E3 $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $45 $00 $00 $00 $55 $00 $00 $00 $4B $00 $00 $00 $7D $00 $00 $00 $87 $00 $00 $00 $FF $00 $00 $00
.db $C7 $00 $00 $00 $BB $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $01 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $07 $00 $00 $00 $7B $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7B $00 $00 $00 $07 $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $07 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $07 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7F $00 $00 $00 $61 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $01 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $F1 $00 $00 $00 $FB $00 $00 $00 $FB $00 $00 $00 $FB $00 $00 $00 $7B $00 $00 $00 $7B $00 $00 $00 $87 $00 $00 $00 $FF $00 $00 $00
.db $79 $00 $00 $00 $67 $00 $00 $00 $1F $00 $00 $00 $6F $00 $00 $00 $77 $00 $00 $00 $7B $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $39 $00 $00 $00 $55 $00 $00 $00 $6D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $3D $00 $00 $00 $5D $00 $00 $00 $6D $00 $00 $00 $75 $00 $00 $00 $79 $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $6D $00 $00 $00 $75 $00 $00 $00 $7B $00 $00 $00 $85 $00 $00 $00 $FF $00 $00 $00
.db $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $83 $00 $00 $00 $7D $00 $00 $00 $7F $00 $00 $00 $83 $00 $00 $00 $FD $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $BB $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $6D $00 $00 $00 $55 $00 $00 $00 $39 $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $3D $00 $00 $00 $DB $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $D7 $00 $00 $00 $B7 $00 $00 $00 $79 $00 $00 $00 $FF $00 $00 $00
.db $7D $00 $00 $00 $7D $00 $00 $00 $BB $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $01 $00 $00 $00 $FB $00 $00 $00 $F7 $00 $00 $00 $EF $00 $00 $00 $DF $00 $00 $00 $BF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $07 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $07 $00 $00 $00 $FF $00 $00 $00
.db $7F $00 $00 $00 $BF $00 $00 $00 $DF $00 $00 $00 $EF $00 $00 $00 $F7 $00 $00 $00 $FB $00 $00 $00 $FD $00 $00 $00 $FF $00 $00 $00
.db $C1 $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $C1 $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $D7 $00 $00 $00 $BB $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $DF $00 $00 $00 $EF $00 $00 $00 $F7 $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $83 $00 $00 $00 $FD $00 $00 $00 $81 $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FF $00 $00 $00
.db $7F $00 $00 $00 $7F $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7F $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $FD $00 $00 $00 $FD $00 $00 $00 $81 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $01 $00 $00 $00 $7F $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $C1 $00 $00 $00 $BF $00 $00 $00 $07 $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FD $00 $00 $00 $C1 $00 $00 $00 $FF $00 $00 $00
.db $7F $00 $00 $00 $7F $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $C7 $00 $00 $00 $FF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $F1 $00 $00 $00 $FF $00 $00 $00 $FB $00 $00 $00 $7B $00 $00 $00 $7B $00 $00 $00 $87 $00 $00 $00 $FF $00 $00 $00
.db $7F $00 $00 $00 $7F $00 $00 $00 $79 $00 $00 $00 $67 $00 $00 $00 $1F $00 $00 $00 $67 $00 $00 $00 $79 $00 $00 $00 $FF $00 $00 $00
.db $3F $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $BF $00 $00 $00 $C1 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $13 $00 $00 $00 $6D $00 $00 $00 $6D $00 $00 $00 $6D $00 $00 $00 $6D $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $03 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $83 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $03 $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $83 $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FD $00 $00 $00 $FD $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $71 $00 $00 $00 $4F $00 $00 $00 $3F $00 $00 $00 $7F $00 $00 $00 $7F $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $81 $00 $00 $00 $7F $00 $00 $00 $83 $00 $00 $00 $FD $00 $00 $00 $03 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $EF $00 $00 $00 $01 $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $F1 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $81 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $BB $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $7D $00 $00 $00 $7D $00 $00 $00 $6D $00 $00 $00 $55 $00 $00 $00 $BB $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $39 $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $D7 $00 $00 $00 $39 $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $7D $00 $00 $00 $BB $00 $00 $00 $D7 $00 $00 $00 $EF $00 $00 $00 $DF $00 $00 $00 $BF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $01 $00 $00 $00 $F7 $00 $00 $00 $EF $00 $00 $00 $DF $00 $00 $00 $01 $00 $00 $00 $FF $00 $00 $00
.db $E7 $00 $00 $00 $DF $00 $00 $00 $DF $00 $00 $00 $3F $00 $00 $00 $DF $00 $00 $00 $DF $00 $00 $00 $E7 $00 $00 $00 $FF $00 $00 $00
.db $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $EF $00 $00 $00 $FF $00 $00 $00
.db $CF $00 $00 $00 $F7 $00 $00 $00 $F7 $00 $00 $00 $F9 $00 $00 $00 $F7 $00 $00 $00 $F7 $00 $00 $00 $CF $00 $00 $00 $FF $00 $00 $00
.db $9F $00 $00 $00 $6D $00 $00 $00 $F3 $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
.db $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00 $FF $00 $00 $00
FontDataEnd:
;外部ファイルを使う場合(コメントアウト中)
;FontData:
;.incbin "fonttiles.bin" fsize FontDataSize
;ネームテーブルデータ
Message:
.db "Hello World!"
.db $ff
5-5-1. データ
ここでは、VDPの初期設定情報、パレットデータ、タイルパターンデータ(今回はフォント)、ネームテーブルデータをまとめてあります。
5-5-2. パレットデータ
ゲームギアは4096色中背景16色、スプライト・背景共用16色の計32色が利用可能です。ここでは黒(\$000)と白(\$FFF)を指定しています。スプライト側のパレットデータの先頭は透過色となります。
5-5-3. タイルパターンデータ
下記データのように、文字コードに対応する箇所に英大文字・小文字・数字を配置しました。
5-5-4. ネームテーブルデータ
タイルパターンの並びを指定しています。・・・でも"Hello World!"って書いてあるのはなぜ? これは「H」などの文字のASCIIコードとタイルパターンの配置や順番を合わせているから。
例)「H」ASCIIコードは\$048。タイルパターン「H」の配置場所も\$048に配置。
6. 実行ファイルの作成
6-1. WLA-DXの準備
プログラムの準備ができたら、さっそくゲームギアで実行できるファイルに変換する必要があります。ここで使うのがWLA-DX。まずはWLA-DXのダウンロードします。以下の最後の方にある「Version 10.6 of WLA DX, built from the sources in GitHub」でよいでしょう。
解凍の上、適当なフォルダに置きます。本記事では下記のようにしました。
C:/
└ myapps/
└ wladx/
6-2. コマンドプロンプトにパスを通す
苦手な人も多いコマンドプロンプトの作業です。
やる時はやらねばならぬ。
コマンドプロンプトでWLA-DXのプログラムを呼び出すとき、C:\myapps\wladx\wla-z80.exeのようにフルパスで書けば使うことができますがなにかと不便。wla-z80と書けばすぐプログラムが使えるようにしたいところです。
コマンドプロンプトを立ち上げ以下のコマンドで「WLA-DXのフォルダ」にパスを通します。「C:\myapps\wladx」の部分はご自身の環境に合わせて変えましょう。
このwladxフォルダにある実行ファイル(例えばwla-z80.exeなど)は名前の部分(wla-z80など)だけで実行できるようになります。
setx PATH "%PATH%;C:\myapps\wladx"
wla-z80とコマンドを打って使い方の表示が出ればパスが通っています。
C:\Users\username>wla-z80
WLA Z80 Macro Assembler v9.2
Written by Ville Helin in 1998-2004
USAGE: wla-z80 -[iMqtvx]{lo} [DEFINITIONS] <ASM FILE> [OUTPUT FILE]
Commands: Options:
l Library file i Add list file information
o Object file M Output makefile rules
q Quiet
t Test compile
v Verbose messages
x Extra compile time definitions
パスが通ってなかったら?
コマンドプロンプトで「echo %PATH%」と打つと登録されているパスが表示されるので正しく登録されているか確認しましょう。削除や変更はChatGPTあたりに聞くとうまく教えてくれます。
ひとまずパスが通ったものとして進みます。
6-3. 中間ファイル(オブジェクトファイル)の作成
さて、作成したchapter_1.asmをWLA-DX付属のwla-z80を使って機械で読めるファイルの一歩手前に変換します。
6-3-1. フォルダの移動
まず、コマンドプロンプトを開きchapter_1.asmファイルのあるフォルダまで移動しましょう。
フォルダのパスはWindowsのフォルダ上で右クリックをして「パスのコピー」をしておくとコピペで済みます。
C:\>cd C:\ggProgrammings\chapter_1_helloWorld
6-3-2. 機械で読めるように変換(アセンブル)
次にWLA-DXに付属するwla-z80というプログラムでchapter_1.asmをchapter_1.oという機械語ファイルに変換します。
D:\ggProgrammings\chapter_1_helloWorld>wla-z80 -o chapter_1.o chapter_1.asm
作業フォルダ内にchapter_1.oができていれば完了です。
6-4. 実行ファイル(ggファイル)の作成
6-4-1. 実行ファイル作成の準備(リンクファイル作成)
仕上げにゲームギアで実行可能な実行ファイル(chapter_1.gg)を作るため、リンク処理を行います。アセンブラではリンカというプログラムを使って仕上げます。
この処理を行う手前でどんなファイルをリンクするかを指示するファイルを作ります。
メモ帳で新規作成して、linkfile.lnkを以下の内容で作りましょう。chapter_1.asmのあるフォルダに保存してください。「名前を付けて保存」をするときにファイルの種類が「すべてのファイル」になっているか確認しましょう。
[objects]
chapter_1.o
6-4-2. 実行ファイルの作成 (リンク処理)
WLA-DXに付属するwlalinkというプログラムで、ゲームギアで実行可能なファイル「chapter_1.gg」を作成します。
コマンドプロンプトで以下のようなコマンドで実行できます。
D:\ggProgrammings\chapter_1_helloWorld>wlalink linkfile.lnk chapter_1.gg
作業フォルダ内にchapter_1.ggができていれば完成です。
7. ゲームギアエミュレーターでHello World!
最後にゲームギアのエミュレーターを導入して、Hello World!しましょう。
7-1. エミュレーター Gearsystemのインストール
下記リンクのDownlodsにある「Gearsystem-3.7.0-windows-x64.zip」をダウンロードしましょう。
圧縮ファイルなので解凍したうえで適当なフォルダに保存しておきます。
本フォルダ内の「gearsystem」をダブルクリックすれば立ち上がります。
注意したいのが、このプログラムや開きたいデータのパスやフォルダ名に「ダウンロード」や「ドキュメント」など全角2バイト文字が含まれる場合うまく動作しないことがあります。半角英数字とフォルダ名に支障のない記号のみで構成される場所に保存しましょう。
7-2. プログラムの実行でHello World!
Gearsystemが立ち上がったら「Open Rom」から「chapter_1.gg」を開きましょう。
Hello World! が表示されれば完成です。
7-3. デバッグモードで中身をのぞく
さて、Hello World!成功だけではもったいないので、中身も少し見ていきましょう。
ゲームギアでの画像表示には色を指定する「パレットデータ」、画像を8×8ドットのパネル状に登録する「タイルパターンデータ(パターンテーブルに登録)」、タイルパターンの画面上の配置を決める「ネームテーブルデータ」の3つ情報が必要です。
Gearsystemの以下の箇所からデバッグモードを使い中身をのぞけます。
デバッグモードでもなにも表示されなかったら、「Debug」の中の「Show VRAM Viewer」にチェックをつけましょう。
VRAM VeiwerでVRAMの中のパレットやタイルパターンやネームテーブルの読み込み状況が分かります。
7-3-1. パレットの状況
7-3-2. タイルパターンの状況(タイルテーブル)
フォントデータは永遠剣様のeienken8x8ASCIIを利用しました。お礼申し上げます。
7-3-3. ネームテーブルの状況
黄緑色の枠が実際の画面の表示領域となります。ネームテーブル自体は画面の外側にも情報を持つことができます。画面外にあらかじめタイルパターンを読み込んでおけば、スクロール時も画面の書き換えが少なくなにかと便利。
というわけで、このデバッグモードをうまく活用すると、プログラムのチェックに使えて便利ですね!
おつかれさまでした
Hello World!できましたか? 興味のある部分を少しづつ調べると理解がはかどるかと思います。参考文献やサイトも下部に用意しました。
ぜひみんなトライしてくれよな!
チャレンジしよう1
画像(タイルパターン)の表示位置を指定するネームテーブルのVRAMアドレスは\$0000~\$3EFEまで。プログラム「7-5.ネームテーブルを書き込む」の\$3AD4部分を変えると表示位置が変わるぞ!
GearsystemのデバッグモードにあるVDP Viewerのネームテーブルなども参照しながら遊んでみよう。
ld hl,$3AD4 | VRAMWrite ; ネームテーブルの先頭アドレス
チャレンジしよう2
プログラム「9.データ」のネームテーブルデータ"Hello World!"を書き換えてみよう! 文字が変わるぞ。
;ネームテーブルデータ
Message:
.db "Hello World!"
.db $ff
おまけ 実機で動かしてみる
chapter_1.ggを実機で動かしてみました。
用意するのはmicro SDカードスロットのあるゲームギアカートリッジ。EverDrive GGなどが有名ですが、今回はAliexpressで2000円台のFLASH GEAR GGを使ってみました。micro SDカードつき。
なお、SDカードの中にデータがいろいろ詰まっている感じがしますが気のせいです。いいな、なにもなかった。なかったんだ・・・
カートリッジのスロットにあるmicro SDカードをはずしてPCのデータを移します。SDカード内に適当なフォルダを作り、chapter_1.ggをコピー。FLASH GEARでは、数字を使ったファイル名はエラーが出る場合もあります。そのため、chapter_1.ggのファイル名をchapter_a.ggなど数字を使わないものにしておきましょう。
カートリッジにSDカードを戻し、ゲームギアにさして起動するとフォルダやファイルが選択できます。chapter_a.ggを選択してロード、Hello World!が画面に映れば成功です。
実機で表示できるととてもうれしい。ハピハピハッピーであります。
参考資料・謝辞
本記事は以下の情報を参考にしました。また、フォントデータは永遠剣様のeienken8x8ASCIIを利用しました。厚くお礼申し上げます。
フォントデータ
書籍
- 堀 桂太郎, 浅川 毅 『Z80アセンブラ入門』 東京電機大学出版局
サイト