Copyright (C) 2003-2011 デグレファクトリー
この資料は SNES SPC700 Player v2.15.2 以降に準拠しています。
Script700, Script700 SE は、保存しただけでは演奏できない SPC を可能な限り演奏させるようにする拡張規格です。
ほとんどの曲は SPC700 (サウンド CPU) の処理だけで演奏を行っていますが、ごく一部の曲では 65C816 (メイン CPU) とデータをやりとりして演奏しているものがあり、その場合は SPC700 の動作だけでは正しく演奏できません。 そこで、 65C816 と SPC700 との間で行われるデータ交換の作業自体も実機と同じように行うことで、そのような特殊な曲でも演奏可能にします。
この改良版 SNESAPU.DLL は、 41568k 氏が立案された Script700 規格と木下氏が立案された Script700 SE 規格の一部のコマンドと構文に互換性を持たせ、独自拡張の命令を合わせた Script700 互換機能を搭載しています。
この資料では Script700 互換機能で対応している Script700 コマンドの仕様について説明しています。
独自の Script700 エンジンを使用しているため、同じ Script700 コマンドでも、他のプレイヤーと仕様や動作が異なる場合があります。 また、サポートしていない機能があるため、完全互換ではありません。 あらかじめご了承ください。
Script700 互換機能に搭載されているすべてのコマンドに対してのサポートをデグレファクトリーで行っております。 同じコマンドでも細かい部分で本家 Script700 (SE) とは動作が異なる場合がありますので、本家の方へのご質問はご遠慮ください。
Script700 を SPC ファイルに適用させるには、以下のように操作します。
1. SPC ファイルと同じ場所に下記のような名前のファイルを作成します。 ファイル名によって優先順位が決まっており、複数存在する場合はより上側のファイルが優先されます。
(1) (SPC ファイル名).700
(2) (SPC ファイル名).7SE
(3) 65816.700
(4) 65816.7SE
(SPC ファイル名) の部分には拡張子 .spc は含みません。 例: sample.spc と同じ場所に sample.700
プレイヤーによって優先順位、または認識可能なファイル名が異なります。
(3), (4) はフォルダ内の全 SPC に対して適用する場合に使用します。
2. 作成したファイルをテキスト エディタで開き、コマンドを入力して保存します。
3. Script700 に対応している SPC プレイヤーで通常通り演奏を開始します。
正常に演奏されない場合は Script700 がプレイヤー側で正しく認識されているか、使用している Script700 がその曲専用のものであるか確認してください。
SNES SPC700 Player での確認方法: [設定] - [情報表示] - [Script700 デバッグ] を選択 → ウィンドウ左下の 「UsedSize」 が 000000 以外で表示されていれば認識されています。
Script700 互換機能では、以下の 3 つの領域で構成された Script700 を使用しています。
記述例
m #0 0 ┐ e │スクリプト領域 ┘ m 20 ┐ e │拡張コマンド領域 ┘ 0007CBA380AD4E52 ┐ 79A3C4E7BB524042 │データ領域 ┘
SPC700 にデータを送ったり、逆に SPC700 からデータを受け取ったり、計算したりなどといったプログラムを記述する場所です。
Script700 では 「スクリプト ゾーン」、 Script700 SE では 「スタンダード コマンド領域」 にあたります。
e コマンドで領域を抜けます。
DSP の処理に割り込みを行い、制御を変更します。 具体的には特定の音を消したり、音色を変えたり、音程を変えたりすることができます。
Script700 では 「拡張コマンド ゾーン」、 Script700 SE では 「スタートアップ コマンド領域」 にあたります。
e コマンドで領域を抜けます。
スクリプト領域で使用したいデータ (数値) が比較的大量にある場合、ここにまとめてデータを記述することができます。
Script700 では p コマンドで読み込める外部ファイルにあたります。
16 進数の数値を文字列として記述します。 ファイルの最後まで続きます。
Script700 互換機能のスクリプト領域で対応しているコマンドとその構文は以下の通りです。
bxx 命令のジャンプ先を指定します。
:[LABEL]
[LABEL] | ラベル番号。 0~1023 を指定します。 |
指定したクロック分 (2,048 kHz) だけ Script700 の動作を停止させます。
w {PARAM3}
{PARAM3} |
指定した値 (パラメータ 1) を指定した場所 (パラメータ 2) に上書きします。
数値指定 (リテラル値) への代入はできません。
m {PARAM1} {PARAM2}
{PARAM1} | |
{PARAM2} |
指定した値 (パラメータ 1、 2) をそれぞれ [CMP1] [CMP2] にコピーして、値の比較や動的ポインタを使用する準備を行います。
c {PARAM1} {PARAM1}
{PARAM1} |
指定した値 (パラメータ 1、 2) の演算結果を指定した場所 (パラメータ 2) に上書きします。
a {PARAM1} {PARAM2} ; P2=P1+P2
s {PARAM1} {PARAM2} ; P2=P1-P2
u {PARAM1} {PARAM2} ; P2=P1×P2
d {PARAM1} {PARAM2} ; P2=P1÷P2 (符号あり)
{PARAM1} | |
{PARAM2} |
指定した値 (パラメータ 1、 2) の演算結果を指定した場所 (パラメータ 2) に上書きします。
n {PARAM1} + {PARAM2} ; P2=P1+P2
n {PARAM1} - {PARAM2} ; P2=P1-P2
n {PARAM1} * {PARAM2} ; P2=P1×P2
n {PARAM1} / {PARAM2} ; P2=P1÷P2 (符号あり)
n {PARAM1} \ {PARAM2} ; P2=P1÷P2 (符号なし)
n {PARAM1} % {PARAM2} ; P2=P1 MOD P2 (余り, 符号あり)
n {PARAM1} $ {PARAM2} ; P2=P1 MOD P2 (余り, 符号なし)
n {PARAM1} & {PARAM2} ; P2=P1 AND P2 (論理積)
n {PARAM1} | {PARAM2} ; P2=P1 OR P2 (論理和)
n {PARAM1} ^ {PARAM2} ; P2=P1 XOR P2 (排他的論理和)
n {PARAM1} < {PARAM2} ; P2=P1 << P2 (左シフト)
n {PARAM1} _ {PARAM2} ; P2=P1 >> P2 (右シフト, 符号あり)
n {PARAM1} > {PARAM2} ; P2=P1 >> P2 (右シフト, 符号なし)
n {PARAM1} ! {PARAM2} ; P2=NOT P1 (否定)
{PARAM1} | |
{PARAM2} |
c コマンドで指定した条件値を比較して、ラベルへジャンプします。
bra (#)[LABEL],w[WORK] ; 無条件でジャンプ beq (#)[LABEL],w[WORK] ; [CMP1]=[CMP2] ならジャンプ bne (#)[LABEL],w[WORK] ; [CMP1]≠[CMP2] ならジャンプ bge (#)[LABEL],w[WORK] ; [CMP1]≦[CMP2] (符号あり) ならジャンプ ble (#)[LABEL],w[WORK] ; [CMP1]≧[CMP2] (符号あり) ならジャンプ bgt (#)[LABEL],w[WORK] ; [CMP1]<[CMP2] (符号あり) ならジャンプ blt (#)[LABEL],w[WORK] ; [CMP1]>[CMP2] (符号あり) ならジャンプ bcc (#)[LABEL],w[WORK] ; [CMP1]≦[CMP2] (符号なし) ならジャンプ blo (#)[LABEL],w[WORK] ; [CMP1]≧[CMP2] (符号なし) ならジャンプ bhi (#)[LABEL],w[WORK] ; [CMP1]<[CMP2] (符号なし) ならジャンプ bcs (#)[LABEL],w[WORK] ; [CMP1]>[CMP2] (符号なし) ならジャンプ
[LABEL] | ラベル番号。 0~1023 を指定します。 |
w[WORK] | ユーザー ワーク メモリ。 w0~w7 を指定します。 |
bxx コマンドの記録が許可されていた状態で最後に実行された bxx コマンドの直後にジャンプします (最大 63 ステップ)。
r コマンド実行後、自動的に r1 コマンドが実行されます (bxx コマンドの記録が許可されます)。
r
bxx コマンドを実行しても戻り先を記録しないように設定します。
r0
bxx コマンドを実行した際に戻り先を記録するように設定します。
初期状態では許可に設定されています。
r1
スクリプトの実行を中止して処理を終了します。
q
何も行いません (ウェイトもかかりません) が、コマンドとして認識します。
nop
スクリプト領域を終了します。 これ以降は拡張コマンド領域となります。
e ::
Script700 互換機能のスクリプト領域で対応しているパラメータは以下の通りです。
{PARAM1} = #[NUM],[PORT],i[PORT],o[PORT],w[WORK],r(b)[RAM],rw[RAM],rd[RAM],x[XRAM],d(b)[DATA],dw[DATA],dd[DATA],
#?,?,i?,o?,w?,r(b)?,rw?,rd?,x?,d(b)?,dw?,dd?
{PARAM2} = [#[NUM]],(i)[PORT],o[PORT],w[WORK],r(b)[RAM],rw[RAM],rd[RAM],x[XRAM],d(b)[DATA],dw[DATA],dd[DATA],
[#?],(i)?,o?,w?,r(b)?,rw?,rd?,x?,d(b)?,dw?,dd?
{PARAM3} = (#)[NUM],i[PORT],o[PORT],w[WORK],r(b)[RAM],rw[RAM],rd[RAM],x[XRAM],d(b)[DATA],dw[DATA],dd[DATA],
(#)?,i?,o?,w?,r(b)?,rw?,rd?,x?,d(b)?,dw?,dd?
() 内は省略可能です。 例えば "bra 3" と "bra #3" は同じ意味です。
{PARAM2} の #[NUM] と #? は指定しても例外にはなりませんが、無視されます。
"," で区切られた項目の中からひとつだけ使うことができます。 例えば "n #2 +* w0" のように、複数は書けません。 "n #2 + w0" や "n #2 * w0" と書きます。
#[NUM] | 数値 (リテラル)。 任意の数値を指定します。 |
i[PORT] | SPC 入力ポート番号。 i0~i3 を指定します。 |
o[PORT] | SPC 出力ポート番号。 o0~o3 を指定します。 |
[PORT] | 書き込み時は i[PORT]、読み込み時は i[PORT] または o[PORT] と同じです。 |
w[WORK] | ユーザー ワーク メモリ。 w0~w7 を指定します。 |
r(b)[RAM] | SPC RAM メモリ。 r0~r65535 を指定します。 |
rw[RAM] | SPC RAM メモリ。 rw0~rw65535 を指定します。 |
rd[RAM] | SPC RAM メモリ。 rd0~rd65535 を指定します。 |
x[XRAM] | SPC EXTRA RAM メモリ。 x0~x63 を指定します。 |
d(b)[DATA] | データ領域のメモリ。 d0 以上の値を指定します。 |
dw[DATA] | データ領域のメモリ。 dw0 以上の値を指定します。 |
dd[DATA] | データ領域のメモリ。 dd0 以上の値を指定します。 |
xx? | 数値指定の代わりに [CMP1] [CMP2] を使用します (補足説明の 「動的ポインタ機能」 を参照してください)。 |
[PORT], i[PORT], o[PORT] は SPC700 に入力する、または SPC700 から出力される 4 つのポートにアクセスする際に使用します。 8 ビットの領域が 4 個あり、 8 ビット単位でアクセスできます。 入力ポートに値を設定することで、サウンド ドライバに命令を送信します。 ほとんどは演奏を進めたり、曲を変えたり、音量を変えたり、効果音を鳴らしたりする場合に使用します。
i[PORT] に値を書き込むと、 SPC700 のポートに書き込み信号を送ります。
o[PORT] は SPC700 からポートに出力された値を読み取ることができます。 基本的には読み取り専用で、書き込んでも動作は変化しません。
[PORT] は、書き込み時は i[PORT]、読み込み時は o[PORT] と同じ動作をします。 ただし、読み込み時でも SPC700 からのポート出力がない場合は i[PORT] から読み込みます。
w[WORK] (ユーザー ワーク メモリ) は Script700 を実行する上でユーザーが自由に利用することができる作業用のメモリ領域です。 いくら書き換えても SPC700 の動作に影響はありません。 Script700 実行前にすべての領域が 0 で初期化されます。 32 ビットの領域が 8 個あり、いずれも 32 ビット単位でアクセスできます (8 ビット、 16 ビット単位でのアクセスはできません)。
r(b)[RAM],rw[RAM],rd[RAM] は SPC700 が使用する 64KB (65,536 バイト) のメモリにアクセスする際に使用します。 r(b)[RAM] は 8 ビット、 rw[RAM] は 16 ビット、 rd[RAM] は 32 ビット単位で任意のアドレスにアクセスできます。 rw65535 や rd65533 など、範囲外になった場合は例外にはなりませんが、値の保証はできません。 SPC700 の動作にかなり影響があり、サウンド ドライバの動作を書き換えたり、ドライバが対応していない出力を直接取得したりできます。
x[XRAM] は SPC700 がリセット後の初期プログラムとして使用する 64 バイトのメモリにアクセスする際に使用します。 8 ビット単位で任意のアドレスにアクセスできます。 通常は使用することはありません。
d(b)[DATA],dw[DATA],dd[DATA] は Script700 で定義したデータ領域のメモリにアクセスする際に使用します。 d(b)[DATA] は 8 ビット、 dw[DATA] は 16 ビット、 dd[DATA] は 32 ビット単位で任意のアドレスにアクセスできます。 確保されているデータ領域のサイズを超えてアドレスを指定した場合は例外にはなりませんが、値の保証はできません。 また、値を書き込むことはできますが、基本的には読み取り専用として使用します。
Script700 互換機能の拡張コマンド領域で対応しているコマンドとその構文は以下の通りです。
指定した波形番号だけ音を消します。 再度指定でミュートを解除します。
m [SOUND],!
[SOUND] | 音色番号。 0~255 を指定します。 |
! | すべての波形番号を対象にします。 |
指定した値 (パラメータ 1, 波形番号) を指定した値 (パラメータ 2, 波形番号) に置き換えます。
c [SOUND],! [SOUND]
[SOUND] | 音色番号。 0~255 を指定します。 |
! | すべての波形番号を対象にします。 |
指定した値 (パラメータ 1, 波形番号) の発音周波数を指定した値 (パラメータ 2) だけずらします。
d [SOUND],! [RATE]
[SOUND] | 音色番号。 0~255 を指定します。 |
! | すべての波形番号を対象にします。 |
[RATE] | 発音周波数。 任意の数値を指定します。 |
指定した値 (パラメータ 1, 波形番号) の音量を指定した値 (パラメータ 2) だけ倍率変更します。
v [SOUND],!,l,r,lr,vl,vr,el,er [VOLUME]
[SOUND] | 音色番号。 0~255 を指定します。 |
! | すべての波形番号を対象にします。 |
l | マスター音量とエコー音量 (左) を対象にします。 |
r | マスター音量とエコー音量 (右) を対象にします。 |
lr | マスター音量とエコー音量 (左右) を対象にします。 |
vl | マスター音量 (左) を対象にします。 |
vr | マスター音量 (右) を対象にします。 |
el | エコー音量 (左) を対象にします。 |
er | エコー音量 (右) を対象にします。 |
[VOLUME] | 音量の倍率。 65536 を 1 倍として、任意の数値を指定します。 |
拡張コマンド領域を終了します。 これ以降はデータ領域となります。
e
本家 Script700 の p コマンド、 bt0 コマンド、 p パラメータは非対応です。 データ領域を利用することで代用できますが、同じコマンドは使えません。
本家 Script700 SE の f コマンド、 fc コマンドは非対応です。 代用できるコマンド、機能はありません。
改良版 SNESAPU.DLL では、 Script700 コマンドを DLL 内部のパーサーに通すことでテキストからバイナリに変換し、実行時は変換後のバイナリ データを使用します。 バイナリ データを保持するメモリ容量は 1,024KB の制限があるため、容量を超えるスクリプトは実行できません。
バイナリ メモリの使用量は SNES SPC700 Player の Script700 デバッグ機能で確認することができます。 "100000" 表示 (16 進数) が最大です。 なお、バイナリ変換前のテキスト スクリプトは 16MB まで読み込むことができます。
m コマンドなどでデータ領域を書き換えることができますが、シーク時の動作は不定です。
常に変化する値を格納する場合は必ずユーザー ワーク メモリをご利用いただき、データ領域は読み取り専用としてください。
ラベル、コマンド間には、必ず 1 つ以上のスペース、改行、または TAB を記述します。 改行で終わらなくてもかまいません。
パラメータ間には、必ず 1 つ以上のスペース、または TAB を記述します (改行は不可)。
改行コードは CR, LF, CRLF に対応しています。
例) 改行で終わらない書き方
m 0 w0 :0 w 16384 a #1 w0 m w0 0 bra 0
例) パラメータ間は改行不可
m #0 w0 ; これは正常に動作します m #0 ; これは動作しません w0 ; (パラメータ 1 と 2 の間に改行があります)
すべてのコマンド、パラメータのアルファベットに大文字と小文字の区別はありません。 大文字でも小文字でも同じように動作します。
例) 大文字と小文字
m #0 w0 ; 小文字 M #0 W0 ; 大文字 (どちらも同じ)
通常、パラメータに指定する数値はすべて 10 進数ですが、 16 進数の記述も可能です。 16 進数の場合は最初に 0x を付けて記述します (大文字と小文字の区別はありません)。
データ領域を除いて、すべての数値指定で 10 進数・ 16 進数の表記が可能です (データ領域では 16 進数しか記述できません)。
他のプレイヤーとの互換性を考慮する場合は、データ領域を使わずに、すべて 10 進数での記述をお勧めします。
例) 10 進数と 16 進数
m #255 w0 ; 10 進数 【推奨】 m #65535 w0 m rd347 w0 m #0xFF w0 ; 16 進数 m #0xffFF w0 m rd0X15b w0 :0x0F ; ラベルでも可能 e m 0x2F ; ミュート指定でも可能
bxx コマンドを使用して無限ループを作成する際、 w コマンドを使用しないと Script700 の動作が終わらず、応答が停止 (ハング) します。 終わらない処理の場合は、必ずループのどこかに w コマンドを入れてください。
例) ループ中には w コマンド
:1 a #1 0 w 1 ; ここで Script700 の動作を 1 クロックだけ停止 bra 1
コマンドを解析中、対応していないコマンド、パラメータなどが見つかった場合、その行にある残りのコマンドはすべて無視され、次の行の解析に移ります。
この仕組みを利用して、コマンドの対応状況による分岐や、注釈文の処理を行うことができます。
例) s コマンドの対応状況により分岐する場合
s w0 - w1 bra 1 ; s コマンドに対応していない場合、 "bra 1" は実行されずここに来ます。 :1 ; s コマンドに対応している場合、 "bra 1" が実行されてここに来ます。
例) ある 1 文に注釈をつける場合
(存在しないコマンド文字はすべて注釈文の先頭として使用できます。 ; は注釈用で、使用できないコマンドとして予約されており、最も安全です。)
n #1 - w0 ; work[0]-- 【推奨】 n #1 + w0 // work[0]++ n #4 * w0 ' work[0] *= 4 n #4 / w0 # work[0] /= 4
強制的に次の行へ進むケースは以下の通りです。
・ 対応していないコマンドが出現したとき。
・ サポートされていないパラメータの指定が出現したとき ("m +7 *4" など)。
何らかの理由でコマンドの実行ができない場合は処理がスキップされ、改行の有無にかかわらず次のコマンドを実行します。
例) 次の行に移らないケース
d #0 w0 bra 1 ; work[0] /= 0 (0 による除算) は単純に無視され "bra 1" が実行されるため ; ここには来ません。 :1 ; 必ずここにジャンプします。
無視されるケースは以下の通りです。
・ w コマンドで指定された時間が 0 だったとき。
・ d, n コマンドで 0 による除算が行われようとしたとき (演算を行わないため、値は変化しません)。
・ bxx コマンドのジャンプ先のラベルが存在しなかったとき。
・ r コマンドで戻り先の bxx コマンドが存在しなかったとき。
・ すでに拡張コマンド領域になっているときに :: ラベルが出現したとき。
・ nop コマンドが出現したとき。
オーバーフローした場合、あふれた桁は破棄されます。
例) オーバーフロー
m #0xFFFFFFFF w0 ; work[0] = 0xFFFFFFFF ; work[0] はこれ以上加算できませんが... a #1 w0 ; こうやってもエラーにはならず... ; work[0] = 0x00000000 になります。 a #-1 w0 ; work[0] = 0x00000000 で減算すれば... ; work[0] = 0xFFFFFFFF になります。 m #0 w9 ; work[9] は存在しませんが... ; 実際は work[1] に 0 が代入されます。 ; パラメータは必要なビットより上位ビットはすべて 0 になるためエラーになりません。 ; 例えば work[] は 8 個であるため下位 3 ビットのみが使用され、あとは 0 になります。 ; 簡単に言えば、実際に指定された数値を 8 で割った余りが使用されることになります。 ; 5 → 0...0101b → 101b → 5 (そのまま) ; 9 → 0...1001b → 001b → 1 (9 が 1 に変わる)
オーバーフローした場合でも bxx コマンドの動作には影響を与えません (Script700 互換機能にはフラグの概念がありません)。
変数の値を他の変数に代入する場合、消費ビット数が少ないと下位ビットのみがコピーされ、消費ビット数が多いと上位の余分なビットはすべて 0 で埋められます。
例) ビット変換
m #0xF1E7038F w0 ; work[0] = 0xF1E7038F m w0 0 ; port[0] = work[0] ; port[0] == 0x8F ; work は 32 ビット、 port は 8 ビットであるため、 ; 実際に port[0] に入力される値は下位 8 ビット (0x8F) となります。 ; port[1] ~ port[3] の数値には影響しません。 m #0xF1E7038F w0 ; work[0] = 0xF1E7038F m 0 w0 ; work[0] = port[0] (0x4D) ; work[0] == 0x0000004D ; work[0] に 8 ビットを超える値 (0x100 以上) が入っていたとしても ; port の値を書き込むと、上位 24 ビットは 0 で埋まります。 ; 仮に port[0] の値が 0x4D だった場合、 work[0] に代入すると ; work[0] の中身は 0x0000004D になります (0xF1E7034D ではありません)。
Script700 と Script700 SE の互換性を維持するため、スクリプト領域の e コマンドと拡張コマンド領域の :: ラベルを併用する際は、必ず e から先に書いてください。
× 悪い例
:: ; ここから拡張コマンド領域 e ; しかし、ここで拡張コマンド領域が終了し... m 3 ; この指定は意味がありません。
○ 良い例
e ; ここから拡張コマンド領域 :: ; 拡張コマンド領域では :: は無視されるため... m 3 ; まだ拡張コマンド領域なので有効です。
改良版 SNESAPU.DLL に搭載されている Script700 互換機能の最も重要な特徴が 「動的ポインタ機能」 です。
各パラメータで、数値指定の代わりに ? を使用することで、読み出す、または書き込む場所を動的に変化させることができます (bxx コマンドでは ? を使用できません。 代わりに work[] を使用できます)。
例) 動的ポインタの例
; (1) [通常の指定] m w0 w1 ; work[1] = work[0] ; (2) [動的ポインタで指定] c #0 #1 ; cmp2 = 1, cmp1 = 0 m w? w? ; work[cmp2] = work[cmp1] ; (1) と (2) は同じ効果です。 c コマンドのパラメータ 1 と ; パラメータ 2 に指定された値 (0 と 1) が ? と置き換わります。 ; 以下のような書き方をすれば、ネスト処理が可能です。 ; work[work[1]] = work[work[0]] c w0 w1 m w? w? ; work[work[work[1]]] = work[work[0]] c w0 w1 c #? w? ; #? は [CMP1] そのままの値 (=w0) m w? w? ; data[data[port[work[0]]]] = 1 c #? w0 ; パラメータ 1 は #? 以外でも OK ですが、 c #? ? ; #? は最も処理数が少なく、消費バイト数も 1 バイトで c #? dd? ; 最も効率が良いため、推奨します。 m #1 dd?
以下に Script700 コマンドの記述例を記載します。
1) 定期的 (16,384 クロック経過ごと) にポート 0 の値を 1 ずつ加算する
m 0 w0 ; work[0] に出力ポート 0 の値を代入 :0 w 16384 ; 16,384 クロック待機 ←────┐ a #1 w0 ; work[0] に 1 を加算 │ m w0 0 ; 入力ポート 0 に work[0] をセット │ bra 0 ; 無条件でラベル :0 へ移動 ─────┘
2) 一部の音色 (音色番号 127) のみを出力する
e ; スクリプトなし :: m ! ; すべての音色をミュート m 127 ; 音色番号 127 のみミュートを解除
3) 64KB APU RAM のアドレス 0x1E7A のデータを 0x7F に書き換える
m #0x7F r0x1E7A ; ram[0x1E7A] に 0x7F を代入
4) 64KB APU RAM のアドレス 0x45E から 0x40 バイト分のデータをデータ領域に指定した値に書き換える
m #0 w0 ; work[0] に 0 を代入 m #0x45E w1 ; work[1] に 0x45E を代入 :0 c w0 w1 ; cmp1 = work[0], cmp2 = work[1] m dd? rd? ; ram[cmp2] = data[cmp1] ; つまり ram[work[1]] = data[work[0]] ; コピーは 4 バイト単位 a #4 w0 ; work[0] に 4 を加算 a #4 w1 ; work[1] に 4 を加算 c #0x40 w0 ; cmp1 = 0x40, cmp2 = work[0] bne 0 ; cmp1 と cmp2 が異なる値のとき :0 へ移動 ; つまり work[0] ≠ 0x40 のとき :0 へ移動 e ; 終了 e ; 拡張コマンド領域なし ; ここからデータ領域 ; TAB, 半角スペース, 0 ~ 9, A ~ F, a ~ f 以外の文字が来たら ; 次の行から再度解析が始まります。 6F9147EB 107A7FCD 9813E7CA 9E7F1A4E ; 0x10 バイト F1F131F0 EF1EB341 A674AC45 31DBBE1F ; 0x20 バイト 46FBE1BB F11EBA11 111FEF20 CF220E9A ; 0x30 バイト 0041BB25 30EDFFBA 01012ECE 3300EF20 ; 0x40 バイト ; なお、データ領域は空白や改行は無視されるので、以下のような書き方でも ; 問題ありません。 好みで記述してください。 6F 91 47 EB 10 7A 7F CD 98 13 E7 CA 9E 7F 1A 4E 6F9147EB107A7FCD9813E7CA9E7F1A4E 6 F 9 1 4 7 E B 1 0 7 A 7 F C D 9 8 1 3 E 7 C A 9 E 7 F 1 A 4 E