unagi script syntax 0.5.4

--スクリプト仕様--
==概要==
テキストファイルで15程度の命令を組み合わせたものです。命令は上から下へ
順番に実行しますが、ごく簡素なループを設定することが出来ます。
行数制限は 256 です。

==定数の表記方法==
数字の頭に下記の記号をいれると各進数を使うことが出来ます。
0b, %:   2進数
0x, $:  16進数
(なし): 10進数

10進数字の末尾に文字をいれると下記の扱いになります。
K: 値 * 0x400 (K 表示は個人的には混乱するので使用を推奨しません)
M: 値 * 0x20000

==変数の表記方法==
一部の命令の引数として変数を使うことが出来ます。変数の有効範囲は 
STEP_START から STEP_END のループ内部で、ループを抜けると使えません。
変数名は単語の先頭1文字だけで識別しています。

==変数と演算子の使い方==
変数展開は実装が非常に複雑なので、制限が多く、単純なものになってしまい
ました。実装できる人はぜひ拡張をしてください。
変数は下記のように1つか3つの単語で記載します。3つの場合は必ずスペース
をはさんでください。

[ex0] [ex1] [ex2]
ex0, ex2 - 変数
ex1 - 演算子, 下記が使用できます

+  算術加算
>> 論理右シフト
<< 論理左シフト
&  AND, 論理積
|  OR,  論理和
^  XOR, 排他的論理和

シフトで指定ビットのみ出したいという要望があるかもしれないのですが、問
題となる MMC1 はマッパ側でビット0だけ読んでいるのでなしにしました。必
要がありましたらお問い合わせください。

==行頭空白について==
行頭の空白とタブは無視しますので、ループのネストに使ってください。

==エラーチェック==
各種入力文字の妥当性判断と、ROM/RAM イメージサイズと設定値と命令での読
み込みサイズを比較します。

--スクリプト命令リファレンス--
モードによって使用可能な命令が異なります。
d: ROM DUMP MODE
r: RAM READ MODE
w: RAM WRITE MODE
f: flashmemory/SRAM PROGRAM MODE

------------------------------
(改行のみ)
mode: 全て
なにも行いません。

------------------------------
#
mode: 全て
コメント扱いでなにも行いません。

------------------------------
MAPPER [num]
mode: df
NES ヘッダのマッパ番号を記載します。

------------------------------
MIRROR [HVA]
mode: d
スクロール方式を指定します。指定しない場合は H とみなしますが、初期の
マッパ(nrom, unrom など)を除いてこの項目は指定する必要がありません。

------------------------------
CPU_ROMSIZE [bytesize]
mode: d
プログラムROMイメージの容量をバイト単位で記載します。
値は最大値にしても構いませんが、読み込み時間がかかります。
0x4000 未満を指定すると NES ヘッダをつけません。

------------------------------
CPU_RAMSIZE [bytesize] 
mode: rw
バックアップRAMイメージの容量をバイト単位で記載します。

------------------------------
PPU_ROMSIZE [bytesize]
mode: d
キャラクタROMイメージの容量をバイト単位で記載します。指定しない場合は
キャラクタRAMとみなします。

------------------------------
DUMP_START
mode: 全て
上記の設定が完了したと明示します。この後に上記の命令を使用するとエラー
になります。

------------------------------
CPU_READ [address] [length]
mode: d
CPUアドレスから指定の長さのデータを読み込みます。定数のみ。
address 有効範囲は 0x8000-0xffff.
length 有効範囲は 1-0x4000.

------------------------------
CPU_WRITE [address] [ex0] [ex1] [ex2]
mode: 全て
CPUアドレスに ex012 を計算したデータを書き込みます。ex0 のみでも可。
address 有効範囲は 0x5000-0xffff.

------------------------------
CPU_RAMRW [address] [length]
mode: rw
コマンドラインのモードによって異なります。
RAM DUMP:  CPUアドレスから指定の長さのデータを読み込みます。定数のみ。
RAM WRITE: target file を読み込み、指定アドレスへデータを書き込みます。
           書き込み前に RAM 領域を書き込みテストを行います。
           書き込み完了後、同じエリアを読み込み、確認結果を表示します。
address 有効範囲は 0x6000-0x7fff.
length 有効範囲は 1-0x2000.

------------------------------
PPU_RAMFIND
mode: d
mmc1/3 のようにソフトによってキャラクタのメモリが RAM か ROM か異なる
場合に使用します。PPU メモリ領域に書き込みを行い、書き込みが成功した場
合は以後の命令を中断します。CPU メモリ領域の読み込みが完了した後に使用
します。

------------------------------
PPU_READ [address] [length]
mode: d
PPUアドレスから指定の長さのデータを読み込みます。定数のみ。
address 有効範囲は 0x0000-0x1fff.
length 有効範囲は 0-0x2000.
length 0 時は実際にはアクセスしますが、バッファに保存されません。
mmc2/4 の制御にのみ必要。

------------------------------
STEP_START [name] [start] [end] [next]
mode: 全て
ループの開始と変数宣言を行います。ループは C でいうところの 
for(name = start; name < end; name += next) と同じ物です。引数の制限が
多いので無限ループが起きないはずです。
name  - 変数名, 重複不可。小文字の a から z を使用可能。
start - 変数初期値, 0 から 0xff まで。定数 C_START, P_START が使用可能。
end   - ループ脱出条件, 0 から 0x100 まで, 条件は < です。<= ではあり
        ません。定数 C_END, P_END が使用可能。
next  - ループ加算値, 1 から 0x100 まで。

STEP_START 定義時に start >= end となっていた場合、ループ内部を評価し
ません。この場合引数などのエラーチェックを行わないので注意してください。

必要性と簡素化のためループは3つまでです。問題がありましたらお問い合わ
せください。

------------------------------
STEP_END
mode: 全て
ループの変数更新とループ分岐を行います。ループが終わった場合は変数を破
棄します。

------------------------------
DUMP_END
mode: 全て
スクリプトの終了を明示します。それ以降の命令を読み込みません。
