基礎知識
戦闘関係
音声で、「LISTENING ROOM」に入るためのメニュー→音声→♪コマンドが出現する条件を記した。
ここではLISTENING ROOM内における、
などを紹介する。
演奏については、サウンドドライバファンクションも参照のこと。
LISTENING ROOMの性質上、シナリオのクリア状況のフラグが多く関わってくる。
バンク$7E(WRAM, アドレス0000~1FFF)のミラーリングが$00なので、内容は同一。
$30:7FFE~$30:7FFFセーブデータの共有部の2バイト値で、最終編ベストエンドを見たかどうかのフラグ。
初期値は$0000で、最終編ベストエンドをクリアすると$E41Bが書き込まれる。
一度$E41Bが書き込まれると、セーブデータをすべてニューゲームで上書きしたとしても$0000に戻ることはない。
$7E:0A01($00:0A01)
プレイ中のセーブデータのシナリオクリア状況が1バイトで入る。
初期値(ニューゲーム時)は$00 (%0000 0000)。
Bit0~7が、中世, 原始, SF, 功夫, 西部, 現代, 近未来, 幕末に対応しており、クリアしていない場合は%0, クリアすると%1。
シナリオを再プレイすると%0に戻り、再プレイでクリアすれば再び%1が書き込まれる。
よって、中世編をクリアすると必ず$FF (%1111 1111)となり、最終編クリア時も変動なし。
$7E:0AB6~$7E:0ABD($00:0AB6~$00:0ABD)
プレイ中のセーブデータのシナリオクリア状況が8バイトで入る。
$7E:0A01との相違点は、クリア順も記録されるということ。
初期値(ニューゲーム時)はすべて$FFで、クリアしたシナリオIDが$7E:0AB6に入る。
シナリオIDは、中世 $00, 原始 $01, SF $02, 功夫 $03, 西部 $04, 現代 $05, 近未来 $06, 幕末 $07
他シナリオをクリアすると+1したアドレスに値が移動していく。
クリア済みシナリオをやり直す時は、そのシナリオIDは削除され($FFに戻る)クリアシナリオのIDは-1したアドレスに移動する。
少しわかりにくいので、実際の値で説明する。
$7E:0AB6~$7E:0ABDの8バイトを横に並べると、初期値は、
(16進数、$は省略。以下同様)
最初に現代編(ID$05)をクリアすると、
次にSF編(ID$02)をクリアすると、
と、最初にクリアした現代編(ID$05)の値が、$7E:0AB6から$7E:0AB7に移動し、$7E:0AB6にはSF編(ID$02)が入る。
続いて幕末編(ID$07), 近未来編(ID$06), 原始(ID$01), 西部(ID$04), 功夫(ID$03)とクリアしていくと、都度右に詰めていくため、
このように値が並び、中世編がプレイ可能になる。プレイ順により値の並びが変わってくることになる。
この時点で、幕末編(ID$07)を最初から再プレイすることを選ぶと、
ID$07が$FFに戻り、全体のIDの並びも左に詰めることになる。
以上の仕様のため、中世編をクリアすると必ず$7E:0AB6に$00が入り、最終編がプレイ可能となる。最終編クリア時は変動なし。
♪コマンドの出現条件は、
のいずれかを満たすことだが、LISTENING ROOMに入る直前にも、同じチェックを行っている。
♪でAボタンを押した直後のチェックが下の通り。
$C2/0651 BCS $03 [$0656] ;キャリーフラグが立っているとき[$0656]分岐 $C2/0653 JMP ($0532)[$C2:20AD] ;[$C2:20AD]へジャンプ(レジスタをスタックに積まない) $C2/20AD LDA $44 [$00:0544] ;Aに[$00:0545][$00:0544]をロード カーソル位置 $C2/20AF CMP #$0002 ;Aと$0002を減算比較(ステータスレジスタ変更のみ) $C2/20B2 BEQ $18 [$20CC] ;ゼロフラグが立っているとき[$20CC]分岐 ;ゼロフラグON LISTENING ROOMコマンドでAボタンを押した $C2/20CC LDA $307FFE[$30:7FFE] ;Aに[$30:7FFF][$30:7FFE]をロード 最終編ベストエンドフラグ $C2/20D0 CMP #$E41B ;Aと$E41Bを減算比較(ステータスレジスタ変更のみ) $C2/20D3 BEQ $08 [$20DD] ;ゼロフラグが立っているとき[$20DD]分岐 ;ゼロフラグOFF 最終編ベストエンドを見ていない $C2/20D5 LDA $0A01 [$7E:0A01] ;Aに[$7E:0A02][$7E:0A01]をロード シナリオクリア状況 $C2/20D8 AND #$00FF ;Aと$00FFで論理積 $C2/20DB BEQ $06 [$20E3] ;ゼロフラグが立っているとき[$20E3]分岐 ;ゼロフラグOFF 何かのシナリオをクリアしている ;処理合流 $C2/20DD LDA #$000D ;Aに$000Dをロード $C2/20E0 JMP $0677 [$C2:0677] ;[$C2:0677]へジャンプ(レジスタをスタックに積まない) $C2/0677 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/0679 STZ $4C [$00:054C] ;[$00:054D][$00:054C]に$0000を書き込み $C2/067B STA $46 [$00:0546] ;A($000D)を[$00:0547][$00:0546]に書き込み $C2/067D JSR $0770 [$C2:0770] ;[$C2:0770]へジャンプ
LISTENING ROOMのサブルーチンで最初に行う処理は、それまで演奏されていたBGMと効果音を停止することである。
(実際にはLISTENING ROOMを選択した時に選択用サウンドを鳴らしてからの処理が$C2/2214~$C2/222Aで指示されている)
$C2/2226 JSR $3C59 [$C2:3C59] ;[$C2:3C59]へジャンプ $C2/3C59 PHP ;ステータスレジスタをスタックへプッシュ $C2/3C5A REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/3C5C PHA ;Aレジスタをスタックにプッシュ $C2/3C5D LDA #$0001 ;Aに$0001をロード $C2/3C60 STA $1D01 [$7E:1D01] ;Aを[$7E:1D01]に書き込み $C2/3C63 LDA #$0180 ;Aに$0180をロード $C2/3C66 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;$7E:1D00~$7E:1D01 80 01 フェード用音量倍率 設定/変化 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/3C69 LDA #$00F0 ;Aに$00F0をロード $C2/3C6C JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;$7E:1D00 F0 音楽演奏停止 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/3C6F PLA ;Aレジスタにスタックからプル $C2/3C70 PLP ;Pレジスタにスタックからプル $C2/3C71 RTS ;サブルーチン戻り $C2/2229 PLP ;Pレジスタにスタックからプル $C2/222A RTS ;サブルーチン戻り
ここで、それまで演奏していたBGMと効果音をフェードアウトさせつつ演奏停止させる。
LISTENING ROOMの初期画面は、
の、どちらの条件でLISTENING ROOMに入れたかで変わる。
処理の分岐は$C2/653Cから。
この直前に$C2/62EF~$C2/6300の処理で、$7E:8A00~$7E:8BFFはすべて$00で埋められ初期化されている。
$C2/653C REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/653E LDA $307FFE[$30:7FFE] ;Aに[$30:7FFF][$30:7FFE]をロード $C2/6542 CMP #$E41B ;Aと$E41Bを減算比較(ステータスレジスタ変更のみ) $C2/6545 BNE $19 [$6560] ;ゼロフラグが立っていないとき[$6560]分岐 ;ゼロフラグON(最終編ベストエンド) $C2/6547 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/6549 LDA #$08 ;Aに$08をロード $C2/654B STA $8A00 [$7E:8A00] ;Aを[$7E:8A00]に書き込み $C2/654E LDA #$00 ;Aに$00をロード $C2/6550 LDY #$0001 ;Yに$0001をロード ;ループ処理 $C2/6553 STA $8A00,y[$7E:8A01] ;A($00~$07)を[$7E:8A01]~[$7E:8A08]に書き込み $C2/6556 INY ;Yをインクリメント +1 $C2/6557 INC A ;Aをインクリメント +1 $C2/6558 CMP #$08 ;Aと$08を減算比較(ステータスレジスタ変更のみ) $C2/655A BMI $F7 [$6553] ;ネガティブフラグが立っているとき[$6553]分岐 ;ループ処理ここまで $C2/655C STY $38 [$00:0538] ;Y($09)を[$00:0539][$00:0538]に書き込み $C2/655E BRA $1B [$657B] ;フラグにかかわりなく常に分岐[$657B] ;ゼロフラグOFF(最終編ベストエンドを見ていない) $C2/6560 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/6562 LDY #$0000 ;Yに$0000をロード $C2/6565 LDX #$0000 ;Xに$0000をロード ;ループ処理 $C2/6568 LDA $0AB6,x[$7E:0AB6] ;Aに[$7E:0AB6]~最大[$7E:0ABD]をロード $C2/656B CMP #$FF ;Aと$FFを減算比較(ステータスレジスタ変更のみ) $C2/656D BEQ $0A [$6579] ;ゼロフラグが立っているとき[$6579]分岐 $C2/656F STA $8A00,y[$7E:8A00] ;Aを[$7E:8A00+y]に書き込み $C2/6572 INY ;Yをインクリメント +1 $C2/6573 INX ;Xをインクリメント +1 $C2/6574 CPX #$0008 ;Xと$0008を減算比較(ステータスレジスタ変更のみ) $C2/6577 BMI $EF [$6568] ;ネガティブフラグが立っているとき[$6568]分岐 ;ループ処理ここまで $C2/6579 STY $38 [$00:0538] ;Y(ループ回数=ページ数)を[$00:0539][$00:0538]に書き込み ;処理合流 $C2/657B REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/657D STZ $36 [$00:0536] ;[$00:0537][$00:0536]に$0000を書き込み $C2/657F PLP ;Pレジスタにスタックからプル $C2/6580 RTS ;サブルーチン戻り
$C2/653E~$C2/6545の分岐条件が「他データも含めて、最終編ベストエンドを見たことがある」になる。
まずは、「他データも含めて、最終編ベストエンドを見たことがある」を満たしている、$C2/6547~$C2/655Eの処理を追ってみよう。
こちらでは、$7E:8A00以降に、以下のように値が書き込まれている。
| アドレス | 値 |
|---|---|
$7E:8A00 | $08 |
$7E:8A01 | $00 |
$7E:8A02 | $01 |
$7E:8A03 | $02 |
$7E:8A04 | $03 |
$7E:8A05 | $04 |
$7E:8A06 | $05 |
$7E:8A07 | $06 |
$7E:8A08 | $07 |
値はシナリオIDになる。
また、アドレスは順に、LISTENING ROOMのページになる。
つまり、最終編ベストエンドを見ると、最終編→中世編→原始編→SF編→功夫編→西部編→現代編→近未来編→幕末編でページ順が固定になる。
最後に、$C2/655Cで、[$00:0538]に値を書き込んだ回数(ループ処理回数)、つまり$09が入っており、これがそのままLISTENING ROOMのページ数になる。
一方、最終編ベストエンドは見ていないが、ひとつ以上シナリオをクリアした状態の処理は$C2/6560~$C2/6579。
こちらだと、
| アドレス | 値 |
|---|---|
$7E:8A00 | [$7E:0AB6] |
$7E:8A01 | [$7E:0AB7] |
$7E:8A02 | [$7E:0AB8] |
$7E:8A03 | [$7E:0AB9] |
$7E:8A04 | [$7E:0ABA] |
$7E:8A05 | [$7E:0ABB] |
$7E:8A06 | [$7E:0ABC] |
$7E:8A07 | [$7E:0ABD] |
クリアしたシナリオ順にシナリオIDが入るが、未クリアである$FFが書き込まれているアドレス以降は値を書き込まない($C2/656B~$C2/656Dの$FFとの減算比較・ゼロフラグ処理分岐)
例えば、現代・SFの順にクリアして、幕末編を開始した、というデータなら、$7E:0AB6~に、
と、値が入っているから、LISTENING ROOMを開くと、
| アドレス | 値 |
|---|---|
$7E:8A00 | $02 |
$7E:8A01 | $05 |
$7E:8A02 | $00 |
$7E:8A03 | $00 |
$7E:8A04 | $00 |
$7E:8A05 | $00 |
$7E:8A06 | $00 |
$7E:8A07 | $00 |
というように値が入る。
また、$C2/6579で、[$00:0538]に値を書き込んだ回数(ループ処理回数)が入っており、LISTENING ROOMのトータルのページ数になる。
上の例だと$02が入ることになる。
これで、LISTENING ROOMのどのページに何のシナリオのBGMが掲載され、どのページまでLRボタンで切り替えできるかが決まることになる。
最終編ベストエンドを見ていない場合、新たにクリアしたシナリオの順にLISTENING ROOMのページが作られるということになる。
(シナリオのクリア順が反映されるのは、このLISTENING ROOMの処理だけかもしれない?)
以上の処理により、$7E:8A00に入っている値が、LISTENING ROOMで最初に表示されるページのシナリオIDとなる。
つまり、
が、最初のページである。
この後はグラフィック関係の処理に移るが適度に端折る。
シナリオIDにより呼び出す値が変わるのは$C2/217E~から。
カーソル位置の処理になる。
メニュー画面のテキストは$C2/42D9~$C2/43B5で$7E:2000~にロードして、グラフィックデータをVRAMへ転送、と繰り返すが、LISTENING ROOMの曲名は$C2:A0AF~$C2:A29Cに入っている。
アドレス計算がややこしいので詳細は省略。
以下は、LISTENING ROOMのタイトル文字である文字列「LISTENING ROOM」をロードし$7E:2000~に書き込む処理である。
$C2/42D9 PHX ;Xレジスタをスタックにプッシュ $C2/42DA AND #$00FF ;Aと$00FFで論理積 $C2/42DD ASL A ;Aを算術左シフト *2 $C2/42DE TAX ;Aの値をXレジスタに転送 $C2/42DF LDA $C2A880,x[$C2:A904] ;Aに[$C2:A904]をロード A:0208 $C2/42E3 CLC ;キャリーフラグクリア $C2/42E4 ADC #$9380 ;A + $9380 $C2/42E7 STA $27 [$00:0527] ;Aを[$00:0528][$00:0527]に書き込み A:9588 $C2/42E9 LDA #$00C2 ;Aに$00C2をロード $C2/42EC STA $29 [$00:0529] ;Aを[$00:052A][$00:0529]に書き込み $C2/42EE LDA #$01FE ;Aに$01FEをロード $C2/42F1 STA $2B [$00:052B] ;Aを[$00:052C][$00:052B]に書き込み $C2/42F3 PLX ;Xレジスタにスタックからプル $C2/42F4 RTS ;サブルーチン戻り $C2/42F8 JMP $4386 [$C2:4386] ;[$C2:4386]へジャンプ(レジスタをスタックに積まない) $C2/4386 LDX $00 [$00:0500] ;Xに[$00:0501][$00:0500]をロード X:0000 $C2/4388 PHP ;ステータスレジスタをスタックへプッシュ $C2/4389 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア ;ループ処理 $C2/438B LDY $00 [$00:0500] ;Yに[$00:0501][$00:0500]をロード Y:0000 $C2/438D LDA [$27],y[$C2:9588] ;Aに[$C2:9589][$C2:9588](+1)をロード ※[$00:0528][$00:0527] = 9588をアドレスに $C2/438F INY ;Yをインクリメント +1 $C2/4390 AND #$00FF ;Aと$00FFで論理積 $C2/4393 BEQ $22 [$43B7] ;ゼロフラグが立っているとき[$43B7]分岐 $C2/4395 CMP #$0020 ;Aと$0020を減算比較(ステータスレジスタ変更のみ) $C2/4398 BPL $0F [$43A9] ;ネガティブフラグが立っていないとき[$43A9]分岐 $C2/43A9 STA $2000,x[$7E:2000] ;Aを[$7E:2000][$7E:2001]~[$7E:201B][$7E:201A]に書き込み $C2/43AC INX ;Xをインクリメント +1 $C2/43AD INX ;Xをインクリメント +1 $C2/43AE CPX #$01FE ;Xと$01FEを減算比較(ステータスレジスタ変更のみ) $C2/43B1 BPL $04 [$43B7] ;ネガティブフラグが立っていないとき[$43B7]分岐 $C2/43B3 CPX $2B [$00:052B] ;Xと[$00:052C][$00:052B]($01FE)を減算比較(ステータスレジスタ変更のみ) $C2/43B5 BMI $D6 [$438D] ;ネガティブフラグが立っているとき[$438D]分岐 ;ループ処理ここまで $C2/438D LDA [$27],y[$C2:9596] ;Aに[$C2:9597][$C2:9596]をロード $C2/438F INY ;Yをインクリメント +1 $C2/4390 AND #$00FF ;Aと$00FFで論理積 $C2/4393 BEQ $22 [$43B7] ;ゼロフラグが立っているとき[$43B7]分岐 $C2/43B7 STZ $2000,x[$7E:201C] ;[$7E:201C]に$00を書き込み $C2/43BA PLP ;Pレジスタにスタックからプル $C2/43BB RTS ;サブルーチン戻り $C2/3686 JSR $2DCB [$C2:2DCB] ;[$C2:2DCB]へジャンプ
$C2:9588~$C2:9597
を、text処理(デコード)などでデコードすると、
「LISTENING ROOM《区切り》ク」
となる。
区切りである00までが実際のテキストとして使用されることになる。
最初に表示されるページ・カーソル位置判定のサブルーチンは以下。
$C2/217E STZ $77 [$00:0577] ;[$00:0577]に$00を書き込み $C2/2180 LDY $36 [$00:0536] ;Yに[$00:0536]をロード LISTENING ROOMトータルページ数 $C2/2182 LDA $8A00,y[$7E:8A00] ;Aに[$7E:8A00]をロード LISTENING ROOM最初のページのシナリオID $C2/2185 AND #$00FF ;Aと$00FFで論理積 $C2/2188 STA $2EB1 [$7E:2EB1] ;Aを[$7E:2EB1]に書き込み $C2/218B TAX ;Aの値をXレジスタに転送 $C2/218C LDA $C27120,x[$C2:7122] ;Aに[$C27120,x]をロード x=シナリオID $C2/2190 AND #$00FF ;Aと$00FFで論理積 $C2/2193 STA $40 [$00:0540] ;Aを[$00:0540]に書き込み $C2/2195 JSR $077C [$C2:077C] ;[$C2:077C]へジャンプ ; ;[$00:0540] = [$C27120,x] x=シナリオID ;[$C2:7120]~[$C2:7128] 0D 11 14 16 19 1D 20 23 ; $C2/077C PHP ;ステータスレジスタをスタックへプッシュ $C2/077D SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/077F JSR $076E [$C2:076E] ;[$C2:076E]へジャンプ $C2/076E LDA $40 [$00:0540] ;Aに[$00:0540]をロード $C2/0770 PHP ;ステータスレジスタをスタックへプッシュ $C2/0771 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/0773 AND #$00FF ;Aと$00FFで論理積 $C2/0776 ASL A ;Aを算術左シフト *2 $C2/0777 ASL A ;Aを算術左シフト *2 $C2/0778 ASL A ;Aを算術左シフト *2 $C2/0779 TAX ;Aの値をXレジスタに転送 $C2/077A PLP ;Pレジスタにスタックからプル $C2/077B RTS ;サブルーチン戻り ; ;X = [$00:0540]*8 $C2/0782 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/0784 LDA $7E8E02,x[$7E:8EA2] ;Aに[$7E8E03,x][$7E8E02,x]をロード $C2/0788 STA $000700[$00:0700] ;Aを[$00:0701][$00:0700]に書き込み $C2/078C LDA $34 [$00:0534] ;Aに[$00:0535][$00:0534]をロード $C2/078E STA $000702[$00:0702] ;Aを[$00:0703][$00:0702]に書き込み $C2/0792 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/0794 LDA $7E8E00,x[$7E:8EA0] ;Aに[$7E8E00,x]をロード $C2/0798 STA $42 [$00:0542] ;Aを[$00:0542]に書き込み $C2/079A LDA $7E8E01,x[$7E:8EA1] ;Aに[$7E8E01,x]をロード $C2/079E STA $44 [$00:0544] ;Aを[$00:0544](カーソル位置)に書き込み $C2/07A0 JSR $4D35 [$C2:4D35] ;[$C2:4D35]へジャンプ
$C2/077Cから$C2/077Cの処理はこれまでにも紹介したことがある、メニュー画面におけるカーソル位置などの計算処理である。
メニュー画面なら、$C2/079Eにて、$7E8E01,xの値がカーソル位置の値として、[$00:0544]にが入る。
メニュー画面トップなら上部タブを左右に移動すると、装備・持ち物・技・隊形・音声・セーブと切り替えるたびに$00, $01, $02, $03, $04, $05と値が入る。
「音声」を選べば、ステレオ・モノラル・♪の順に$00, $01, $02となる。
ただ、LISTENING ROOMの場合、[$00:0544]に入る値はページ切り替え毎に$00から開始ではない。
演奏可能な曲にはシナリオID順に通しで番号が振ってあり、その番号がカーソル位置の数値になる。
カーソル位置の数値である、$7E8E01,xはどう計算されているか処理を見てみると、
$7E8E01,x
x = [$00:0540]*8
[$00:0540] = [$C27120,シナリオID] = [$C2:7120]~[$C2:7128]
[$C2:7120]~[$C2:7128]: 0D 11 14 16 19 1D 20 23 26
| シナリオ | $7E8E01,x | 値 |
|---|---|---|
| 中世 | $7E:8E69 | $00 |
| 原始 | $7E:8E89 | $04 |
| SF | $7E:8EA1 | $07 |
| 功夫 | $7E:8EB1 | $09 |
| 西部 | $7E:8EC9 | $0C |
| 現代 | $7E:8EE9 | $10 |
| 近未来 | $7E:8F01 | $13 |
| 幕末 | $7E:8F19 | $16 |
| 最終 | $7E:8F31 | $19 |
これらの値がカーソル位置、つまり曲のナンバリングでもある。
ここから、各ページの最初の曲のカーソル番号が判明する。
なお、先の処理では、
$7E8E00,x→[$00:0542]
[$7E8E03,x][$7E8E02,x]→[$00:0701][$00:0700]
という処理も行われている。
メニューを開いた時に、$C2:852E~$C2:8635→$7E:8E00~$7E:8F07へコピーされているのだが、この値はLISTENING ROOMで演奏可能な曲33曲のアドレスなどの呼び出しのデータ(各曲8バイト)にあたる。
BGMを演奏する場合、カーソル位置の値から、BGMIDを呼び出す必要がある。
;LISTENING ROOMでカーソル位置にある曲のBGM関係のデータ6バイトを$7E:2EB5~$7E:2EBAに書き込み $C2/22E8 PHP ;ステータスレジスタをスタックへプッシュ $C2/22E9 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/22EB LDA $44 [$00:0544] ;Aに[$00:0545][$00:0544]をロード カーソル値 $C2/22ED AND #$007F ;Aと$007Fで論理積 $C2/22F0 ASL A ;Aを算術左シフト *2 $C2/22F1 PHA ;Aレジスタをスタックにプッシュ $C2/22F2 ASL A ;Aを算術左シフト *2 $C2/22F3 CLC ;キャリーフラグクリア $C2/22F4 ADC $01,s [$00:1FF2] ;A + [$00:1FF2] ※sはスタックポインタ値(最後にスタックに積まれた値) $C2/22F6 STA $01,s [$00:1FF2] ;Aを[$00:1FF2]に書き込み $C2/22F8 PLA ;Aレジスタにスタックからプル $C2/22F9 CLC ;キャリーフラグクリア $C2/22FA ADC #$8B2B ;A + $8B2B $C2/22FD TAX ;Aの値をXレジスタに転送 $C2/22FE LDY #$2EB5 ;Yに$2EB5をロード $C2/2301 LDA #$0005 ;Aに$0005をロード $C2/2304 PHB ;DBレジスタをスタックにプッシュ $C2/2305 MVN C2 7E ;データ転送 ; ;A:転送データサイズ-1 $0005 ;X:転送元アドレス A + $8B2B ;Y:転送先アドレス $2EB5 ;オペランド:転送元と転送先バンク C2 -> 7E ;$C2:(A + $8B2B) -> $7E:2EB5 +5バイト ; $C2/2308 PLB ;DBレジスタにスタックからプル $C2/2309 LDA $2EB1 [$7E:2EB1] ;Aに[$7E:2EB1]をロード $C2/230C AND #$000F ;Aと$000Fで論理積 $C2/230F CMP #$0008 ;Aと$0008を減算比較(ステータスレジスタ変更のみ) $C2/2312 BNE $15 [$2329] ;ゼロフラグが立っていないとき[$2329]分岐 $C2/2329 PLP ;Pレジスタにスタックからプル $C2/232A RTS ;サブルーチン戻り
$C2/2305のMVNで呼び出す6バイトの値の最初の1バイトがBGMIDである。
つまり、BGMIDは$7E:2EB5に入るということになる。
MVNで呼び出す値は$C2:8B2B~$C2:8BF0に6バイト区切りで入っている。
ここまでをまとめると以下のようになる。
| シナリオ | カーソル 番号 | BGMID$7E:2EB5 | 曲名 |
|---|---|---|---|
| 中世 | $00 | $01 | 魔王への叙曲 |
| $01 | $19 | とどかぬ翼 | |
| $02 | $02 | 凛然なる戦い | |
| $03 | $1A | 魔王山を往く | |
| 原始 | $04 | $09 | NATIVE LIFE |
| $05 | $15 | いいお天気でしょっ! | |
| $06 | $16 | Kiss of Jealousy | |
| SF | $07 | $08 | UNSEEN SYNDROME |
| $08 | $49 | CAPTAIN SQUARE | |
| 功夫 | $09 | $0D | 鳥児在天空飛翔 魚児在河里游泳 |
| $0A | $14 | 老拳師下深山 | |
| $0B | $0E | 在中国的戦闘 | |
| 西部 | $0C | $04 | WANDERER |
| $0D | $07 | UNDER THE FAKE | |
| $0E | $06 | THE WILDS | |
| $0F | $38 | SANCHO・DE・LOS・PANCHOZ | |
| 現代 | $10 | $33 | 最強 ―VICTORY ROAD― |
| $11 | $0C | 猛者達‥‥ | |
| $12 | $10 | KNOCK YOU DOWN! | |
| 近未来 | $13 | $18 | GO!GO!ブリキ大王!! |
| $14 | $0A | WAIT FOR TRUTH | |
| $15 | $0B | PSYCHOで夜露死苦!! | |
| 幕末 | $16 | $17 | 密命 |
| $17 | $03 | 忍音 | |
| $18 | $05 | 殺陣! | |
| 最終 | $19 | $34 | LIVE・A・LIVE |
| $1A | $35 | CRY・A・LIVE | |
| $1B | $36 | WARM・A・LIVE | |
| $1C | $25 | SELECT・A・LIVE | |
| $1D | $37 | 絶望の都 | |
| $1E | $1B | 魔王オディオ | |
| $1F | $2B | MEGALOMANIA | |
| $20 | $3C | Silent Labyrinth |
曲にカーソルを合わせてAボタンで選択すると演奏開始になる。
音の演奏のためのサウンドドライバファンクションコマンドは$C2/232B~$C2/2380で指定している。その中の$C2/2214~$C2/222Aはサウンド停止処理で、前に鳴っていた曲を停止させる(といっても、LISTENINGROOMでは演奏開始前は無音だが)。
$C3/0004~$C3/017Fは、$7E:1D00~$7E:1D00をサウンドドライバファンクションコマンドとして$00:2140~$00:2143からARAM転送する処理なので、最後以外省略した。
演奏前にカーソルを移動させた時点で、カーソル位置のBGMIDが$7E:2EB5に入るのだが、演奏時にもう一度$C2/22E8~$C2/232Aを行ってカーソル位置のBGMIDを$7E:2EB5に入れている。念のためということなのか、そのあたりはよくわからない。
何にしても最終的に、演奏するBGMIDは$7E:2EB5に必ず入る。
$C2/232B JSR $2214 [$C2:2214] ;[$C2:2214]へジャンプ $C2/2214 PHP ;ステータスレジスタをスタックへプッシュ $C2/2215 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/2217 STZ $1D02 [$7E:1D02] ;[$7E:1D02]に$00を書き込み $C2/221A LDA #$0C81 ;Aに$0C81をロード $C2/221D JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 81 0C 00 BGMフェード用音量倍率 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/2220 LDA #$000F ;Aに$000Fをロード $C2/2223 JSR $4B15 [$C2:4B15] ;[$C2:4B15]へジャンプ ; ;(中略) ; $C2/2226 JSR $3C59 [$C2:3C59] ;[$C2:3C59]へジャンプ $C2/3C59 PHP ;ステータスレジスタをスタックへプッシュ $C2/3C5A REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/3C5C PHA ;Aレジスタをスタックにプッシュ $C2/3C5D LDA #$0001 ;Aに$0001をロード $C2/3C60 STA $1D01 [$7E:1D01] ;Aを[$7E:1D02][$7E:1D01]に書き込み $C2/3C63 LDA #$0180 ;Aに$0180をロード $C2/3C66 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 80 01 00 フェード用音量倍率 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/3C69 LDA #$00F0 ;Aに$00F0をロード $C2/3C6C JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ F0 00 演奏停止 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/3C6F PLA ;Aレジスタにスタックからプル $C2/3C70 PLP ;Pレジスタにスタックからプル $C2/3C71 RTS ;サブルーチン戻り $C2/2229 PLP ;Pレジスタにスタックからプル $C2/222A RTS ;サブルーチン戻り $C2/232E JSR $22E8 [$C2:22E8] ;[$C2:22E8]へジャンプ $C2/22E8 PHP ;ステータスレジスタをスタックへプッシュ $C2/22E9 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/22EB LDA $44 [$00:0544] ;Aに[$00:0544]をロード $C2/22ED AND #$007F ;Aと$007Fで論理積 $C2/22F0 ASL A ;Aを算術左シフト *2 $C2/22F1 PHA ;Aレジスタをスタックにプッシュ $C2/22F2 ASL A ;Aを算術左シフト *2 $C2/22F3 CLC ;キャリーフラグクリア $C2/22F4 ADC $01,s [$00:1FF6] ;A + [$00:1FF6] $C2/22F6 STA $01,s [$00:1FF6] ;Aを[$00:1FF6]に書き込み $C2/22F8 PLA ;Aレジスタにスタックからプル $C2/22F9 CLC ;キャリーフラグクリア $C2/22FA ADC #$8B2B ;A + $8B2B $C2/22FD TAX ;Aの値をXレジスタに転送 $C2/22FE LDY #$2EB5 ;Yに$2EB5をロード $C2/2301 LDA #$0005 ;Aに$0005をロード $C2/2304 PHB ;DBレジスタをスタックにプッシュ $C2/2305 MVN C2 7E ;データ転送 ;A:転送データサイズ-1 $0005 ;X:転送元アドレス A + $8B2B ;Y:転送先アドレス $2EB5 ;オペランド:転送元と転送先バンク 00 -> 00 ;$C2:(A + $8B2B) -> $7E:2EB5 +$0005バイト $C2/2308 PLB ;DBレジスタにスタックからプル $C2/2309 LDA $2EB1 [$7E:2EB1] ;Aに[$7E:2EB2][$7E:2EB1]をロード $C2/230C AND #$000F ;Aと$000Fで論理積 $C2/230F CMP #$0008 ;Aと$0008を減算比較(ステータスレジスタ変更のみ) $C2/2312 BNE $15 [$2329] ;ゼロフラグが立っていないとき[$2329]分岐 $C2/2314 LDA $0A10 [$7E:0A10] ;Aに[$7E:0A10]をロード $C2/2317 AND #$000F ;Aと$000Fで論理積 $C2/231A XBA ;Aレジスタの上位バイトと下位バイトを交換 $C2/231B LSR A ;Aを論理右シフト (/2) $C2/231C LSR A ;Aを論理右シフト (/2) $C2/231D TAX ;Aの値をXレジスタに転送 $C2/231E LDA $0D00,x[$7E:0E40] ;Aに[$7E:0E40]をロード $C2/2321 AND #$001F ;Aと$001Fで論理積 $C2/2324 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/2326 STA $2EB6 [$7E:2EB6] ;Aを[$7E:2EB6]に書き込み $C2/2329 PLP ;Pレジスタにスタックからプル $C2/232A RTS ;サブルーチン戻り $C2/2331 STZ $1D01 [$7E:1D01] ;[$7E:1D02][$7E:1D01]に$0000を書き込み $C2/2334 LDA #$0086 ;Aに$0086をロード $C2/2337 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 86 00 00 BGM演奏速度倍率 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/233A LDA #$0089 ;Aに$0089をロード $C2/233D JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 89 00 00 BGMピッチ倍率 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/2340 LDA #$00F5 ;Aに$00F5をロード $C2/2343 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ F5 00 BGMミュート設定 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/2346 LDA #$00F8 ;Aに$00F8をロード $C2/2349 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ F8 00 ? $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/234C LDA #$008F ;Aに$008Fをロード $C2/234F JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 8F 00 ? $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/2352 LDA #$00FF ;Aに$00FFをロード $C2/2355 STA $1D02 [$7E:1D02] ;Aを[$7E:1D03][$7E:1D02]に書き込み $C2/2358 LDA $2EB5 [$7E:2EB5] ;Aに[$7E:2EB6][$7E:2EB5]をロード BGMID $C2/235B AND #$00FF ;Aと$00FFで論理積 $C2/235E XBA ;Aレジスタの上位バイトと下位バイトを交換 $C2/235F ORA #$0010 ;Aと$0010で論理和 $C2/2362 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ ;AにBGMID・10と2バイト値が入る $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D01][$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ ;[$7E:1D00]~ 10 (BGMID) FF 00 $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/0131 PHB ;DBレジスタをスタックにプッシュ $C3/0160 JMP ($0734,x)[$C3:0180] ;[$C3:0180]へジャンプ(レジスタをスタックに積まない) $C3/0180 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C3/0182 LDA $01 [$00:1D01] ;Aに[$00:1D01]をロード BGMID $C3/0184 CMP $05 [$00:1D05] ;Aと[$00:1D05]を減算比較(ステータスレジスタ変更のみ) $C3/0186 BEQ $E9 [$0171] ;ゼロフラグが立っているとき[$0171]分岐(処理抜ける) ;ゼロフラグOFF ひとつ前に演奏していたBGMIDと今回演奏するBGMIDは一致しない $C3/0188 CMP $C33FC8[$C3:3FC8] ;Aと[$C3:3FC8]($4E)を減算比較(ステータスレジスタ変更のみ) $C3/018C BCS $E3 [$0171] ;キャリーフラグが立っているとき[$0171]分岐(処理抜ける) ;キャリーフラグON BGMIDが$4E以上(存在しない) $C3/018E JSR $062F [$C3:062F] ;[$C3:062F]へジャンプ $C3/062F PHP ;ステータスレジスタをスタックへプッシュ $C3/0630 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C3/0632 LDA $00 [$00:1D00] ;Aに[$00:1D00]をロード $C3/0634 CMP #$14 ;Aと$14を減算比較(ステータスレジスタ変更のみ) $C3/0636 BCS $10 [$0648] ;キャリーフラグが立っているとき[$0648]分岐 $C3/0638 LDX #$0000 ;Xに$0000をロード $C3/063B LDA $C30733,x[$C3:0733] ;Aに[$C3:0733]をロード $C3/063F BMI $0D [$064E] ;ネガティブフラグが立っているとき[$064E]分岐 $C3/064E PLP ;Pレジスタにスタックからプル $C3/064F RTS ;サブルーチン戻り $C3/0191 LDA $F3 [$00:1DF3] ;Aに[$00:1DF4][$00:1DF3]をロード $C3/0193 BEQ $03 [$0198] ;ゼロフラグが立っているとき[$0198]分岐 $C3/0198 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C3/019A LDA $01 [$00:1D01] ;Aに[$00:1D02][$00:1D01]をロード $C3/019C AND #$00FF ;Aと$00FFで論理積 $C3/019F TAX ;Aの値をXレジスタに転送 ;(中略) $C3/01BF JSR $060E [$C3:060E] ;[$C3:060E]へジャンプ ; ;(中略 サンプリングデータとシーケンスデータをARAM送信) ; $C3/0171 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C3/0173 STZ $00 [$00:1D00] ;[$00:1D00]に$00を書き込み ARAM送信終了、演奏開始 $C3/0175 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C3/0177 REP #$10 ;X/Yレジスタを16bit幅に変更、Xフラグをクリア $C3/0179 PLY ;Yレジスタにスタックからプル $C3/017A PLX ;Xレジスタにスタックからプル $C3/017B PLA ;Aレジスタにスタックからプル $C3/017C PLP ;Pレジスタにスタックからプル $C3/017D PLD ;Dレジスタにスタックからプル $C3/017E PLB ;DBレジスタにスタックからプル $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/2365 LDA $2EB9 [$7E:2EB9] ;Aに[$7E:2EB9]をロード $C2/2368 STA $95 [$00:0595] ;Aを[$00:0595]に書き込み $C2/236A STZ $97 [$00:0597] ;[$00:0597]に$00を書き込み $C2/236C LDA #$0020 ;Aに$0020をロード $C2/236F STA $98 [$00:0598] ;Aを[$00:0598]に書き込み $C2/2371 LDA #$0080 ;Aに$0080をロード $C2/2374 STA $9A [$00:059A] ;Aを[$00:059A]に書き込み $C2/2376 LDA #$0084 ;Aに$0084をロード $C2/2379 STA $9C [$00:059C] ;Aを[$00:059C]に書き込み $C2/237B LDA #$0080 ;Aに$0080をロード $C2/237E TSB $93 [$00:0593] ;Aと[$00:0593]で論理和を取り、メモリに書き戻し $C2/2380 JMP $06F4 [$C2:06F4] ;[$C2:06F4]へジャンプ(レジスタをスタックに積まない)
サウンドドライバファンクションをまとめると以下のようになる。
| No. | コマンド | 内容 |
|---|---|---|
| 01 | 81 0C 00 | BGMフェード用音量倍率($0Cかけて$00に音量下げる) |
| 02 | 80 01 00 | フェード用音量倍率($01かけて$00にフェードアウト) |
| 03 | F0 00 | 演奏停止 |
| 04 | (BGMID計算 $C2/22E8~$C2/232A) | |
| 05 | 86 00 00 | BGM演奏速度倍率(倍率設定なし) |
| 06 | 89 00 00 | BGMピッチ倍率(倍率設定なし) |
| 07 | F5 00 | BGMミュート設定(ミュートなし) |
| 08 | F8 00 | ? |
| 09 | 8F 00 | ? |
| 10 | 10 (BGMID) FF 00 | ボリューム$FF(デフォルト)でBGMIDのBGM演奏開始 |
No.01~03までは、それまで鳴っていたBGMを停止する処理。
LISTENINGROOMでは演奏曲を流している時以外は無音なので、必要のない処理のようにも思えるが、一応、ということなのだろうか。
No.04で再度サブルーチン$C2/22E8~$C2/232Aでこれから鳴らすBGMIDなどを算出している。
No.05以降が演奏するBGMの設定と演奏指示になる。
サウンドドライバファンクションで幾つか指示があるが、コマンド$86のBGM演奏速度倍率、コマンド$89のBGMピッチ倍率、コマンド$F5のBGMミュート設定は、引数がすべて$00で固定である。引数を別途分岐処理するようなサブルーチンではない。
このため、「PSYCHOで夜露死苦!!」のバーのバージョンや、「いいお天気でしょっ!」の夜バージョンといった、演奏速度やピッチ、ミュート設定を変更する曲はLISTENING ROOMでは演奏できないことになる。
また、演奏用のコマンドにコマンド$10を使っているので、コマンド$11で演奏する「届かぬ翼」のスローバージョンなども演奏できない。
(上の条件で演奏できる曲でもLISTENING ROOMでは聞けない場合が幾つかあるので、何を聞けるようにするかは色々な事情の上で決まったのであろうが……)
演奏終了時は、効果音(カーソル系効果音のキャンセル音)を鳴らしてから演奏を停止する。
演奏終了処理は$C2/2383~$C2/238Fで、そこから演奏開始時の「演奏曲を停止する」処理の$C2/2214~$C2/222Aにジャンプするため、演奏停止する。
;キャンセル音演奏 $C2/3C42 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C2/3C44 PHA ;Aレジスタをスタックにプッシュ $C2/3C45 LDA #$21 ;Aに$21をロード $C2/3C47 JSR $3CAC [$C2:3CAC] ;[$C2:3CAC]へジャンプ $C2/3CAC STA $1D00 [$7E:1D00] ;Aを[$7E:1D00]に書き込み $C2/3CAF JSL $C30004[$C3:0004] ;[$C3:0004]へジャンプ $C3/0004 JMP $0131 [$C3:0131] ;[$C3:0131]へジャンプ(レジスタをスタックに積まない) ;(中略) $C3/017F RTL ;サブルーチン戻り $C2/3CB3 RTS ;サブルーチン戻り $C2/3C4A PLA ;Aレジスタにスタックからプル $C2/3C4B PLP ;Pレジスタにスタックからプル $C2/3C4C RTS ;サブルーチン戻り ; ;(中略) ; ;演奏終了処理 $C2/2383 LDA $93 [$00:0593] ;Aに[$00:0593]をロード $C2/2385 AND #$0080 ;Aと$0080で論理積 $C2/2388 BEQ $0B [$2395] ;ゼロフラグが立っているとき[$2395]分岐 $C2/238A LDA #$0040 ;Aに$0040をロード $C2/238D TSB $93 [$00:0593] ;Aと[$00:0593]で論理和を取り、メモリに書き戻し $C2/238F JSR $2214 [$C2:2214] ;[$C2:2214]へジャンプ ;演奏曲を停止する処理$C2/2214~$C2/222A $C2/2214 PHP ;ステータスレジスタをスタックへプッシュ ;(後略)
以上、LISTENING ROOMの大まかな処理を紹介した。