基礎知識
戦闘関係
前ページの行動ポイントの説明を前提として、順序ポイントについて記す。
敵ターンが回ってきた時、行動する敵は1体である。
敵が1体だけなら、その敵が行動することが確定だが、敵が複数体いる時、どのように行動順を決めるのか。
行動順判定に使うのが、各敵に設定された順序ポイントになる。
順序ポイント(2バイト)は、nは敵番号(0~E)として、メモリアドレス[$7E:ACn5][$7E:ACn4]に格納される。
値は2バイトなので$0000~$FFFFを取る。サブルーチンを見る限り、オーバーフローや、計算値が負の値になった場合の対策はなされているようである。
結論を言えば、一番順序ポイントが大きい敵が行動するが、該当する敵が複数の場合、敵番号が大きい敵が優先になる。
ややこしいのは順序ポイントの増減方法である。
ZsnsK's F**kin' Site様の順序ポイントの項目を見ての通り、順序ポイントの増減は、行動や状況により計算方法が変わってくる。
このページでは、
に分けて説明していく。
ちなみに結論だけまとめると、新たな順序ポイントの計算方法は以下のようになる。
「攻撃時の減少値」「発生時修正値」「攻撃以外の増加値」は、行動異常と順序ポイントで説明しているので参照のこと。
「攻撃以外の増加値」にのみ符号付き8ビット整数の負数が混ざっているので少しややこしい。
戦闘開始時、順序ポイント初期値は以下サブルーチンで決定される。
$C1/EBCA BMI $1F [$EBEB] ;ネガティブフラグが立っているとき[$EBEB]分岐 $C1/EBCC BEQ $F9 [$EBC7] ;ゼロフラグが立っているとき[$EBC7]分岐 $C1/EBCE LDY $0002,x[$00:1B02] ;Yに[$00:1B02]をロード $C1/EBD1 LDA #$00 ;Aに$00をロード $C1/EBD3 SEC ;キャリーフラグON $C1/EBD4 SBC $0028,y[$00:1A28] ;A - [$00:1A28](敵データ08 知) $C1/EBD7 STA $7E9104,x[$7E:AC04] ;Aを[$7E:AC04]に書き込み $C1/EBDB LDA #$00 ;Aに$00をロード $C1/EBDD STA $7E9105,x[$7E:AC05] ;Aを[$7E:AC05]に書き込み $C1/EBE1 STA $7E9106,x[$7E:AC06] ;Aを[$7E:AC06]に書き込み $C1/EBE5 STA $7E9107,x[$7E:AC07] ;Aを[$7E:AC07]に書き込み $C1/EBE9 BRA $DC [$EBC7] ;フラグにかかわりなく常に分岐[$EBC7] $C1/EBC7 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ
X:1Bn0(nは敵番号)で、戦闘開始時にいる敵すべてに上の処理を行う。
Y:1A?0で、敵種類1~4でYはそれぞれ$1A00, $1A40, $1A50, $1AC0となる。
上は敵番号0、敵種類1としてアドレスを紹介しておく。
$C1/EBD1~の処理を追ってみると、
[$7E:AC04] = $100 - [$00:1A28](敵データ08 知)
[$7E:AC05] = $00
と、なっている。
知が1以上の敵は繰り下がりがおき、キャリーフラグがOFFになる。
順序ポイント初期値は、その敵の「$100(256) - 知」になることがわかる。
だが、知が0の敵(岩やしょく台など)は、
[$7E:AC04] = $100 - $00 = $00(キャリーフラグON)
繰り下がりが起こらないまま、下1バイトがそのまま[$7E:AC04]に入るため、知が0の敵だけ、順序ポイント初期値は$00である。
つまり、
順序ポイント初期値 = ($100(256) - 知) & $FF
と考えれば良いことになる。
例えば同種類の敵が3体居て(敵番号0、敵番号1、敵番号2)、戦闘開始直後に味方が何もせずひたすらYボタンを連打していると行動ポイントが255を越えて敵ターンに移るが、同種類の敵だと戦闘開始時の順序ポイントは同一である。
この場合、順序ポイント判定で、最後に値を判定する敵番号2が優先となり、敵番号2が何かの行動を取るということになる。
最終編に登場する「次元 源左衛門×3」は、初期配置が多少ズレることはあるが、基本的には画面左から順に敵番号0, 1, 2なので、戦闘開始直後にYボタンを連打すると、一番右の次元 源左衛門が行動するはずだ。
順序ポイントが増減する時、その時の敵の行動異常の値が関わることが多いので、まず行動異常について説明しておく。
行動異常はID$0~$Fの16種類。データはアドレス$D5:644B~$D5:64CAに格納されている。
敵番号n(n = 0~E)の行動異常は[$7E:AAn2]に入っている($00~$0F)。
行動異常1種につき8バイト分のデータが格納されているのだが、その中の3~6番目が行動順に関わるパラメータである。
| No. | 内容 |
|---|---|
| 0 | 上4ビットが使用不能になる技番号 下から3ビット目が1かつ行動異常0でないなら、移動パターン-1 |
| 1 | - |
| 2 | レベル変動値 |
| 3 | 行動順・発生時修正値 |
| 4 | 行動順・被ダメージ定数 |
| 5 | 行動順・攻撃以外の増加値 |
| 6 | 行動順・攻撃時の減少値 |
| 7 | - |
実質6種類のデータしか入っていない。
この後の計算手順からすると、行動異常データ6は6~7にまたがった2バイトのデータ(ただし上1バイトは$00)、と見て良いようだ。
実際のデータは以下のようになっている。
行動異常データ2~6は、カッコ内に10進数を併記した。
以下数値は符号付き8ビット整数扱いなので、負数になる場合はマイナス記号で記載。
| 行動異常 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| $0 | $04 | $00 | $00(0) | $07(7) | $02(2) | $01(1) | $32(50) | $00 |
| $1 | $04 | $00 | $01(1) | $09(9) | $03(3) | $03(3) | $28(40) | $00 |
| $2 | $04 | $00 | $02(2) | $0C(12) | $05(5) | $03(3) | $1E(30) | $00 |
| $3 | $04 | $00 | $FE(-2) | $06(6) | $02(2) | $01(1) | $46(70) | $00 |
| $4 | $04 | $00 | $FC(-4) | $04(4) | $01(1) | $00(0) | $50(80) | $00 |
| $5 | $84 | $00 | $00(0) | $09(9) | $03(3) | $03(3) | $28(40) | $00 |
| $6 | $C4 | $00 | $00(0) | $09(9) | $03(3) | $03(3) | $28(40) | $00 |
| $7 | $E4 | $00 | $00(0) | $09(9) | $03(3) | $03(3) | $28(40) | $00 |
| $8 | $FA | $00 | $FB(-5) | $01(1) | $0F(15) | $FE(-2) | $64(100) | $00 |
| $9 | $F0 | $00 | $02(2) | $04(4) | $01(1) | $05(5) | $05(5) | $00 |
| $A | $E0 | $00 | $FE(-2) | $0F(15) | $08(8) | $0A(10) | $05(5) | $00 |
| $B | $00 | $00 | $00(0) | $05(5) | $02(2) | $07(7) | $23(35) | $00 |
| $C | $10 | $00 | $02(2) | $06(6) | $0F(15) | $00(0) | $2D(35) | $00 |
| $D | $C0 | $00 | $FB(-5) | $00(0) | $08(8) | $07(7) | $32(50) | $00 |
| $E | $00 | $00 | $FC(-4) | $09(9) | $0F(15) | $00(0) | $64(100) | $00 |
| $F | $7C | $00 | $03(3) | $0F(15) | $0F(15) | $0F(15) | $00(0) | $00 |
行動異常で順序ポイントなどが変動する時は、まず、以下サブルーチンで行動異常8バイト分のデータを呼び出す。
ここでは、行動異常0、つまり敵の通常状態における行動異常のデータを呼び出したとする。
$C1/1CF7 PHX ;Xをスタックにプッシュ $C1/1CF8 LDA $7E8F02,x ;Aに[$7E:AAn2](敵番号nの行動異常)をロード ($00をロード) $C1/1CFC ASL A ;Aを算術左シフト *2 $C1/1CFD ASL A ;Aを算術左シフト *2 $C1/1CFE ASL A ;Aを算術左シフト *2 $C1/1CFF REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/1D01 AND #$00F8 ;Aと$00F8で論理積 $C1/1D04 ADC $D50060[$D5:0060] ;A + [$D5:0060] $C1/1D08 TAX ;Aの値をXレジスタに転送 $C1/1D09 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1D0B LDY #$0320 ;Yに$0320をロード ;ループ処理ここから $C1/1D0E LDA $D50000,x[$D5:644B] ;Aに[$D5:644B+n]をロード $C1/1D12 STA $0000,y[$00:0320] ;Aを[$00:0320+n]に書き込み $C1/1D15 INX ;Xをインクリメント +1 $C1/1D16 INY ;Yをインクリメント +1 $C1/1D17 CPY #$0328 ;Yと$0328を減算比較(ステータスレジスタ変更のみ) $C1/1D1A BNE $F2 [$1D0E] ;ゼロフラグが立っていないとき[$1D0E]分岐 ;ループ処理ここまで $C1/1D1C PLX ;Xレジスタにスタックからプル $C1/1D1D RTS ;サブルーチン戻り
行動異常0のデータは$D5:644Bから開始になり、アドレスに8を加えると行動異常1, 2, ……の開始アドレスを呼び出せることになるが、その計算が$C1/1CF7~$C1/1D08である。
$C1/1CF8で、敵番号nの行動異常[$7E:AAn2]を呼び出し、
[$7E:AAn2]*8 & $00F8 + [$D5:0060]($644B)
で、行動異常の開始アドレスが呼び出せ、Xレジスタに転送している。
行動異常0、つまり敵の通常状態における行動異常のデータの開始アドレスは[$D5:644B]である。
$C1/1D0E~$C1/1D1Aはループ処理で、行動異常0の8バイトのデータを、[$00:0320]~[$00:0327]の8バイトにコピーしている。
| 行動異常No | 元アドレス | コピー先アドレス | 内容 |
|---|---|---|---|
| 0 | [$D5:644B] | [$00:0320] | 上4ビットが使用不能になる技番号 |
| 1 | [$D5:644C] | [$00:0321] | -(必ず$00) |
| 2 | [$D5:644D] | [$00:0322] | レベル変動値 |
| 3 | [$D5:644E] | [$00:0323] | 行動順・発生時修正値 |
| 4 | [$D5:644F] | [$00:0324] | 行動順・被ダメージ定数 |
| 5 | [$D5:6450] | [$00:0325] | 行動順・攻撃以外の増加値 |
| 6 | [$D5:6451] | [$00:0326] | 行動順・攻撃時の減少値 |
| 7 | [$D5:6452] | [$00:0327] | -(必ず$00) |
こうして呼び出した行動異常の値から、順序ポイントの増減を計算する。
行動異常が関係しない場合もあるが、合わせて説明していく。
敵が攻撃すると、以下サブルーチンで、攻撃した敵自身の順序ポイントが変動する。
$C1/1C77 STZ $27 [$00:0327] ;[$00:0327]に$00を書き込み $C1/1C79 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1C7B LDA $7E9104,x ;Aに[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)をロード $C1/1C7F SEC ;キャリーフラグON $C1/1C80 SBC $26 [$00:0326] ;A - [$00:0327][$00:0326](行動順・攻撃時の減少値) $C1/1C82 BCS $03 [$1C87] ;キャリーフラグが立っているとき[$1C87]分岐 ;キャリーフラグOFF $C1/1C84 LDA #$0000 ;Aに$0000をロード ;キャリーフラグON $C1/1C87 STA $7E9104,x ;Aを[$7E:ACn4](敵番号nの順序ポイント下1バイト)に書き込み $C1/1C8B SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1C8D RTS ;サブルーチン戻り
上の計算を追っていくと、新たな[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)は、
[$7E:ACn5][$7E:ACn4] - [$00:0327][$00:0326](行動順・攻撃時の減少値)
ただし[$00:0327]=$00
ただし減算結果が負の値になったら$0000
に変更されることがわかる。
要するに、新たな順序ポイントは、
max(順序ポイント - 攻撃時の減少値, $0000)
攻撃時の減少値のデータは行動異常データ06。
通常時(状態異常0)だと$32で、行動異常により、最小で$00、最大で$64の値となる。
必ず正の値なので、
「敵が攻撃すると、順序ポイントが$00~$64減少する」
ということがわかる。
行動異常が発生した時は、行動異常に従って順序ポイントが変動する。
このため、例えば、行動異常が発生する技をくらった時、「行動異常発生時の順序ポイント変動」→(行動異常から回復しなかった場合)「攻撃された時の順序ポイント変動」と両方の処理を行うことになる。
$C1/1C91 STZ $24 [$00:0324] ;[$00:0324]に$00を書き込み $C1/1C93 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1C95 LDA $7E9104,x ;Aに[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)をロード $C1/1C99 LSR A ;Aを論理右シフト (/2) $C1/1C9A CLC ;キャリーフラグクリア $C1/1C9B ADC $23 [$00:0323] ;A + [$00:0323](行動順・発生時修正値) $C1/1C9D BCC $03 [$1CA2] ;キャリーフラグが立っていないとき[$1CA2]分岐 ;キャリーフラグON $C1/1C9F LDA #$FFFF ;Aに$FFFFをロード ;キャリーフラグOFF $C1/1CA2 STA $7E9104,x ;Aを[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)に書き込み $C1/1CA6 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1CA8 RTS ;サブルーチン戻り
処理を見ると、[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)は、
trunc([$7E:ACn5][$7E:ACn4]/2) + [$00:0323](行動順・発生時修正値)
ただし加算結果が$FFFFを越えたら$FFFF
に変更されている。
要するに、新たな順序ポイントは、
min(trunc(順序ポイント/2) + 発生時修正値, $FFFF)
発生時修正値のデータは行動異常データ03。
通常時(状態異常0)だと$07で、行動異常により、最小で$00、最大で$0Fの値となる。
順序ポイントを半減してから発生時修正値を加算するので、この結果により順序ポイントが元の値より増えるか減るかは、元の順序ポイントと発生時修正値次第である。
ただし、発生時修正値が最大でも$0Fと小さめなので、増える可能性の方が低め。
敵が味方に攻撃される、フィールドダメージを受ける、毒状態で毒のダメージを受ける、といった、敵のHPが減少する行動後の順序ポイント変動は以下。
敵種類1での処理とする。
なお、$C1/1CBFで呼び出す[$00:2135][$00:2134]には、総ダメージ量が計算され入った状態である。
$C1/1CAC LDY $0002,x ;Yに[$00:1Bn2]をロード $C1/1CAF REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/1CB1 LDA $0010,y[$00:1A10] ;Aに[$00:1A11][$00:1A10](敵種類1の最大HP)をロード $C1/1CB4 LSR A ;Aを論理右シフト (/2) $C1/1CB5 LSR A ;Aを論理右シフト (/2) $C1/1CB6 LSR A ;Aを論理右シフト (/2) $C1/1CB7 LSR A ;Aを論理右シフト (/2) $C1/1CB8 BNE $01 [$1CBB] ;ゼロフラグが立っていないとき[$1CBB]分岐 $C1/1CBB STA $10 [$00:0310] ;Aを[$00:0310]に書き込み $C1/1CBD SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1CBF LDY $2134 [$00:2134] ;Yに[$00:2135][$00:2134]をロード $C1/1CC2 STY $4204 [$00:4204] ;Yを[$00:4205][$00:4204]に書き込み $C1/1CC5 LDA $10 [$00:0310] ;Aに[$00:0310](敵の最大HP/$10)をロード $C1/1CC7 STA $4206 [$00:4206] ;Aを[$00:4206]に書き込み $C1/1CCA JSR $46C8 [$C1:46C8] ;[$C1:46C8]へジャンプ ; ;符号付16bit / 8bit ;$4204-$4205 / $4206 ($4214-$4215に商、$4216に余りが入る) ;総ダメージ / trunc(敵の最大HP/$10) ; $C1/46C8 NOP ;計算待ち $C1/46C9 RTS ;サブルーチン戻り $C1/1CCD LDA $4214 [$00:4214] ;Aに[$00:4214](商の下1バイト)をロード $C1/1CD0 INC A ;Aをインクリメント +1 $C1/1CD1 CMP #$10 ;Aと$10を減算比較(ステータスレジスタ変更のみ) $C1/1CD3 BCC $02 [$1CD7] ;キャリーフラグが立っていないとき[$1CD7]分岐 ;キャリーフラグON $C1/1CD5 LDA #$0F ;Aに$0Fをロード ;キャリーフラグOFF $C1/1CD7 STA $4202 [$00:4202] ;Aを[$00:4202]に書き込み $C1/1CDA LDA $24 [$00:0324] ;Aに[$00:0324](行動順・被ダメージ定数)をロード $C1/1CDC STA $4203 [$00:4203] ;Aを[$00:4203]に書き込み $C1/1CDF JSR $46C9 [$C1:46C9] ;[$C1:46C9]へジャンプ ; ;符号付8bit x 8bit ;$4202 * $4203 ($4216-$4217に乗算結果) ; $C1/46C9 RTS ;サブルーチン戻り ; $C1/1CE2 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/1CE4 LDA $7E9104,x ;Aに[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)をロード $C1/1CE8 ADC $4216 [$00:4216] ;A + [$00:4216][$00:4216](乗算結果2バイト) $C1/1CEB BCC $03 [$1CF0] ;キャリーフラグが立っていないとき[$1CF0]分岐 ;キャリーフラグON $C1/1CED LDA #$FFFF ;Aに$FFFFをロード ;キャリーフラグOFF $C1/1CF0 STA $7E9104,x ;Aを[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)に書き込み $C1/1CF4 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/1CF6 RTS ;サブルーチン戻り
乗算や除算が混ざるので少々ややこしいが、最初の除算と、次の乗算に分けてみると、
N = max(trunc(総ダメージ / trunc(敵の最大HP/$10))+1, $0F)
として($C1/1CD7の時点のAレジスタの値)
[$7E:ACn5][$7E:ACn4] + N * 被ダメージ定数
ただし加算結果が$FFFFを越えたら$FFFF
である。
まとめると、
[$7E:ACn5][$7E:ACn4] + max(trunc(総ダメージ / trunc(敵の最大HP/$10))+1, $0F) * 被ダメージ定数
ただし加算結果が$FFFFを越えたら$FFFF
が、新たな順序ポイント[$7E:ACn5][$7E:ACn4]になっている。
要するに、新たな順序ポイントは、
min(順序ポイント + max(trunc(総ダメージ / trunc(敵の最大HP/$10))+1, $0F) * 被ダメージ定数, $FFFF)
被ダメージ定数のデータは行動異常データ04。
通常時(状態異常0)だと$02で、行動異常により、最小で$01、最大で$0Fの値となる。
計算式より、敵がダメージを受けた時は必ず順序ポイントが増加する。
また、計算結果から、「敵が受けたダメージ(総ダメージ)/敵の最大HP」が大きいほど順序ポイントの増加量が多い。
つまり、受けたダメージ量の最大HPに対する割合が高いほど順序ポイントの増加量が多い。
味方の攻撃以外の行動(1マス移動、Yボタン足踏み、パス、向き変え)、または敵味方全員行動できない状態が該当。
敵が味方に攻撃される場合は上の$C1/1CAC~$C1/1CF6の処理が入るが、それ以外の味方の行動(1マス移動、Yボタン足踏み、パス、向き変え)でも、以下処理で敵全体の順序ポイントが変動する。
また、味方全員がタメ時間の最中で敵が攻撃などできる位置でもない、という、敵味方全員行動できない状況でも、同じ処理が1フレーム(1/60秒)毎に同じく以下処理が入る。
$C1/1C02 LDA $25 [$00:0325] ;Aに[$00:0325](行動順・攻撃以外の増加値)をロード $C1/1C04 BMI $22 [$1C28] ;ネガティブフラグが立っているとき[$1C28]分岐 ;ネガティブフラグOFF(攻撃以外の増加値が正の値) $C1/1C06 LDA $7E9104,x[$7E:ACn4] ;Aに[$7E:ACn4](順序ポイント下1バイト)をロード $C1/1C0A CLC ;キャリーフラグクリア $C1/1C0B ADC $25 [$00:0325] ;A + [$00:0325](行動順・攻撃以外の増加値) $C1/1C0D STA $7E9104,x[$7E:ACn4] ;Aを[$7E:ACn4](順序ポイント下1バイト)に書き込み $C1/1C11 BCC $31 [$1C44] ;キャリーフラグが立っていないとき[$1C44]分岐 ;キャリーフラグON $C1/1C13 LDA $7E9105,x[$7E:ACn5] ;Aに[$7E:ACn5](順序ポイント上1バイト)をロード $C1/1C17 INC A ;Aをインクリメント +1 $C1/1C18 BEQ $06 [$1C20] ;ゼロフラグが立っているとき[$1C20]分岐 ;ゼロフラグOFF $C1/1C1A STA $7E9105,x[$7E:ACn5] ;Aを[$7E:ACn5](順序ポイント上1バイト)に書き込み $C1/1C1E BRA $24 [$1C44] ;フラグにかかわりなく常に分岐[$1C44] ;ゼロフラグON $C1/1C20 LDA #$FF ;Aに$FFをロード $C1/1C22 STA $7E9104,x[$7E:ACn4] ;Aを[$7E:ACn4](順序ポイント下1バイト)に書き込み $C1/1C26 BRA $1C [$1C44] ;フラグにかかわりなく常に分岐[$1C44] ;$C1/1C04でネガティブフラグON(攻撃以外の増加値が負の値) $C1/1C28 LDA $7E9104,x[$7E:ACn4] ;Aに[$7E:ACn4](順序ポイント下1バイト)をロード $C1/1C2C CLC ;キャリーフラグクリア $C1/1C2D ADC $25 [$00:0325] ;A + [$00:0325](行動順・攻撃以外の増加値) $C1/1C2F STA $7E9104,x[$7E:ACn4] ;Aを[$7E:ACn4](順序ポイント下1バイト)に書き込み $C1/1C33 BCS $0F [$1C44] ;キャリーフラグが立っているとき[$1C44]分岐 ;キャリーフラグOFF $C1/1C35 LDA $7E9105,x[$7E:ACn5] ;Aに[$7E:ACn5](順序ポイント上1バイト)をロード $C1/1C39 BEQ $07 [$1C42] ;ゼロフラグが立っているとき[$1C42]分岐 ;ゼロフラグOFF $C1/1C3B DEC A ;Aをデクリメント -1 $C1/1C3C STA $7E9105,x[$7E:ACn5] ;Aを[$7E:ACn5](順序ポイント上1バイト)に書き込み $C1/1C40 BRA $02 [$1C44] ;フラグにかかわりなく常に分岐[$1C44] ;ゼロフラグON $C1/1C42 LDA #$00 ;Aに$00をロード $C1/1C44 CMP #$00 ;Aと$00を減算比較(ステータスレジスタ変更のみ) $C1/1C46 BNE $05 [$1C4D] ;ゼロフラグが立っていないとき[$1C4D]分岐 ;ゼロフラグON $C1/1C48 JSR $6150 [$C1:6150] ;[$C1:6150]へジャンプ ;(戦闘乱数生成) $C1/1C4B AND #$0F ;Aと$0Fで論理積 ;ゼロフラグOFF $C1/1C4D STA $7E9104,x[$7E:ACn4] ;Aを[$7E:ACn4]に書き込み $C1/1C51 RTS ;サブルーチン戻り
最初の$C1/1C04で、[$00:0325](行動順・攻撃以外の増加値)のネガティブフラグ分岐がある。
攻撃以外の増加値のデータは行動異常データ05。
行動異常$8だけ符号付き8ビット整数における負の値$FEであり、他は0または正の数($00~$0F)が入っているため、$C1/1C04の分岐は実質、行動異常$8かどうかの分岐である。
まず、攻撃以外の増加値が0または正の値である、$C1/1C06以降の処理を見てみる。
[$7E:AC04](順序ポイント下1バイト)と[$7E:AC05](順序ポイント上1バイト)に分けて処理をしているが、これは順序ポイント2バイトに攻撃以外の増加値1バイトを加算した時、下1バイトで繰り上がり・繰り下がりが起きた時、上1バイトの処理を別にしなければならないためである。
つまり、
(順序ポイント2バイト) + $00[$00:0325]
のように2バイト同士の加算で扱う必要がある。
攻撃以外の増加値が正の値なら、
[$7E:ACn5][$7E:ACn4] + [$00:0325](攻撃以外の増加値)
ただし加算結果が$FFFFを越えたら$FFFF
の計算と考えて問題ない。
ただ、この結果が$00の時、$C1/1C46でゼロフラグ分岐により$C1/1C48に進む。
$C1/1C48で戦闘乱数生成サブルーチンに飛んで、$00~$FFの乱数をAに入れて戻ることになる。
$C1/1C4Bで、($00~$FFの乱数) & $0Fを計算し、最終的に[$7E:AC04](順序ポイント下1バイト)に入っているから、
[$7E:ACn5][$7E:ACn4] + [$00:0325](攻撃以外の増加値)
ただし加算結果が$FFFFを越えたら$FFFF
ただし計算結果が$0000だったら($00~$FFの乱数) & $0F
と、いうことになる。
加算の場合、答えは必ず正の数である。
続いて、攻撃以外の増加値が負の値である、$C1/1C28以降の処理を見てみる。
こちらは負の値$FEの加算をすることになるが、実際には、
(順序ポイント2バイト) + $FFFE
という計算をしないと符号付き16ビット整数の正負の計算ができない。
※手っ取り早く考えるなら10進数のように-2すれば良いのだが。
ただ、
[$7E:ACn4] + $FEの結果が符号付き8ビット整数で負[$7E:ACn5]の値が$00という両方の条件を満たしていると、「順序ポイント2バイト-2」の結果が0以下になるので、その場合の分岐で、
「順序ポイント2バイト-2」の結果が0以下だったら
($00~$FFの乱数) & $0F
としているのが上処理である。
結果、新たな順序ポイント[$7E:ACn5][$7E:ACn4]は、
[$7E:ACn5][$7E:ACn4] + 攻撃以外の増加値
[$7E:ACn5][$7E:ACn4] - 2
ということになる。
10進数の正負の数で表せば、新たな順序ポイントは以下のようにわかりやすくまとめられる。
min(順序ポイント + 攻撃以外の増加値, 65535)
ただし計算結果が0以下だったら(0~255の乱数) & 15
ここから先の処理($C1/8E5E~)は、敵ターンにて順序ポイントから行動が回ってきた場合の処理である。
$C1/8E5E CPX #$0000 ;Xと$0000を減算比較(ステータスレジスタ変更のみ) $C1/8E61 BNE $01 [$8E64] ;ゼロフラグが立っていないとき[$8E64]分岐 $C1/8E64 LDA $0005,x[$00:1Bn5] ;Aに[$00:1Bn5](技関係状態)をロード $C1/8E67 BNE $15 [$8E7E] ;ゼロフラグが立っていないとき[$8E7E]分岐 ;技関係状態 $00:通常 $40:タメ時間中 $F0:技を出している最中 ;ゼロフラグON 技関係状態 $00:通常 $C1/8E69 LDA $7E8F07,x[$7E:AAn7] ;Aに[$7E:AAn7](状態異常)をロード $C1/8E6D BIT #$B0 ;Aと$B0($1011 0000)で論理積(ステータスフラグ変更のみ) $C1/8E6F BEQ $0E [$8E7F] ;ゼロフラグが立っているとき[$8E7F]分岐 ;ゼロフラグOFF(石化、マヒ、眠り) $C1/8E71 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/8E73 LDA $7E9104,x[$7E:AC04] ;Aに[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)をロード $C1/8E77 LSR A ;Aを論理右シフト (/2) $C1/8E78 STA $7E9104,x[$7E:AC04] ;Aを[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)に書き込み $C1/8E7C SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/8E7E RTS ;サブルーチン戻り
行動不能な状態異常(石化、マヒ、眠り)で行動順が回ってくると、敵は何も行動できないが、順序ポイント変動は行われる。
この時の計算は、行動異常が関係してこないパターンである。
実質、マヒと眠り用だが(石化すると敵は戦闘不能扱いなので)、$C1/8E69~$C1/8E6Dの処理は「石化、マヒ、眠りのいずれかまたは複数の状態異常」を判定しているので、石化も含めて紹介。
まず、敵がタメ時間中ではないことを確認する($C1/8E64~$C1/8E67)。
ここでタメ時間中と判定されると$C1/8E7Eにジャンプなので、サブルーチンから抜ける。
つまり、敵が技のタメ時間中だと、順序ポイントの増減は起こらない(敵味方すべてがタメ時間や行動できない場合は、先に記した処理)。
更に、$C1/8E69~$C1/8E6Dで、該当の敵キャラの状態異常が「石化、マヒ、眠りのいずれかまたは複数の状態異常」の時、$C1/8E71~で順序ポイントの処理をする。
[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)は、
[$7E:ACn5][$7E:ACn4]/2)
に変更されている。
要するに、新たな順序ポイントは、trunc(順序ポイント/2)
ほぼ半分に減ることになる。
なお、状態異常でない場合($C1/8E6F)、この後の「敵が1マス移動する」の処理中の$C1/8F7Fにジャンプしている。
$C1/8F77 LDX $AC [$00:03AC] ;Xに[$00:03AC]をロード $C1/8F79 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C1/8F7B LDA $7E9104,x[$7E:ACn4] ;Aに[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)をロード $C1/8F7F LSR A ;Aを論理右シフト (/2) $C1/8F80 STA $10 [$00:0310] ;Aを[$00:0311][$00:0310]に書き込み $C1/8F82 LSR A ;Aを論理右シフト (/2) $C1/8F83 CLC ;キャリーフラグクリア $C1/8F84 ADC $10 [$00:0310] ;A + [$00:0311][$00:0310] $C1/8F86 STA $7E9104,x[$7E:ACn4] ;Aを[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)に書き込み $C1/8F8A SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/8F8C RTS ;サブルーチン戻り
こちらも行動異常が関係してこないパターンで、敵の移動による順序ポイント変動になる。
サブルーチンのアドレスを見ると行動不能な状態異常による順序ポイント変動から連続しており、このあたりのアドレスで順序ポイント処理をしていることがわかる。
上にも記したが、敵が石化、マヒ、眠りでなければこの処理に飛ぶようになっている。
処理を見ると、[$7E:ACn5][$7E:ACn4](敵番号nの順序ポイント)は、
[$7E:ACn5][$7E:ACn4]/2) + trunc([$7E:ACn5][$7E:ACn4]/4)
に変更されている。新たな順序ポイントは、
trunc(順序ポイント/2) + trunc(順序ポイント/4)
大まかには、元の順序ポイントの3/4に変化していることがわかる。
行動異常には関係なく、移動すると順序ポイントが割合で減少することがわかる。
以上が順序ポイントの変動計算である。
では、上のようにして計算された順序ポイントから、実際に行動する敵を選ぶサブルーチンを紹介する。
前ページの行動ポイント判定サブルーチン$C1/8E51~で、敵ターンに回った直後、つまり$C1/92C3にジャンプしてからは以下のようになる。
タイプがBREAKDOWN, OBJECTの敵は処理が途中で分岐するため、ここでは通常タイプの敵が複数いる場合のサブルーチンで紹介する。
$C1/8E51 LDA $AF [$00:03AF] ;Aに[$00:03AF](行動ポイント上1バイト)をロード $C1/8E53 BNE $01 [$8E56] ;ゼロフラグが立っていないとき[$8E56]分岐 $C1/8E56 LDA $B8 [$00:03B8] ;Aに[$00:03B8]をロード $C1/8E58 BNE $01 [$8E5B] ;ゼロフラグが立っていないとき[$8E5B]分岐 $C1/8E5B JSR $92C3 [$C1:92C3] ;[$C1:92C3]へジャンプ ;ここから敵ターンに回る処理 $C1/92C3 JSR $933C [$C1:933C] ;[$C1:933C]へジャンプ $C1/933C STZ $16 [$00:0316] ;[$00:0316]に$00を書き込み $C1/933E LDX #$1AF0 ;Xに$1AF0をロード $C1/9341 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ $C1/E1A9 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/E1AB TXA ;Xレジスタの値をAレジスタに転送 $C1/E1AC ADC #$0010 ;A + $0010 (=A:1B00) $C1/E1AF TAX ;Aの値をXレジスタに転送 $C1/E1B0 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/E1B2 CPX #$1C00 ;Xと$1C00を減算比較(ステータスレジスタ変更のみ) $C1/E1B5 BEQ $11 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 $C1/E1B7 LDA $0001,x[$00:1B01] ;Aに[$00:1B01](敵番号0戦闘状態)をロード $C1/E1BA BIT #$40 ;Aと$40で論理積(ステータスフラグ変更のみ) $C1/E1BC BNE $07 [$E1C5] ;ゼロフラグが立っていないとき[$E1C5]分岐 $C1/E1C5 LDA #$7F ;Aに$7Fをロード $C1/E1C7 RTS ;サブルーチン戻り $C1/9344 BEQ $FB [$9341] ;ゼロフラグが立っているとき[$9341]分岐 $C1/9346 BMI $0E [$9356] ;ネガティブフラグが立っているとき[$9356]分岐 $C1/9348 LDY $0002,x[$00:1B02] ;Yに[$00:1B02]をロード $C1/934B LDA $002F,y[$00:1A2F] ;Aに[$00:1A2F](敵データ15 タイプ)をロード $C1/934E BIT #$06 ;Aと$06で論理積(ステータスフラグ変更のみ) $C1/9350 BNE $EF [$9341] ;ゼロフラグが立っていないとき[$9341]分岐 ;ゼロフラグOFF BREAKDOWN, OBJECT $C1/9341 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ ;ゼロフラグON $C1/9352 LDA #$FF ;Aに$FFをロード $C1/9354 STA $16 [$00:0316] ;Aを[$00:0316]に書き込み $C1/9356 RTS ;サブルーチン戻り $C1/92C6 LDX #$1AF0 ;Xに$1AF0をロード $C1/92C9 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ
$C1/92C3から$C1/92C9まで、まずは敵番号nの戦闘状態を確認してフィールドにいるかどうか判定、続いて敵データ15で敵のタイプ判定をして、BREAKDOWNやOBJECTでなければ続いて順序ポイント判定へ、という手順のようである。
詳細は省く。
$C1/E1A9 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/E1AB TXA ;Xレジスタの値をAレジスタに転送 $C1/E1AC ADC #$0010 ;A + $0010 $C1/E1AF TAX ;Aの値をXレジスタに転送 $C1/E1B0 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/E1B2 CPX #$1C00 ;Xと$1C00を減算比較(ステータスレジスタ変更のみ) $C1/E1B5 BEQ $11 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 $C1/E1B7 LDA $0001,x[$00:1B01] ;Aに[$00:1B01](敵番号0戦闘状態)をロード $C1/E1BA BIT #$40 ;Aと$40で論理積(ステータスフラグ変更のみ) $C1/E1BC BNE $07 [$E1C5] ;ゼロフラグが立っていないとき[$E1C5]分岐 $C1/E1C5 LDA #$7F ;Aに$7Fをロード $C1/E1C7 RTS ;サブルーチン戻り $C1/92CC BEQ $FB [$92C9] ;ゼロフラグが立っているとき[$92C9]分岐 $C1/92CE BMI $66 [$9336] ;ネガティブフラグが立っているとき[$9336]分岐 $C1/92D0 LDY $0002,x[$00:1B02] ;Yに[$00:1B02]をロード $C1/92D3 LDA $002F,y[$00:1A2F] ;Aに[$00:1A2F](敵データ15 タイプ)をロード $C1/92D6 BIT #$04 ;Aと$04で論理積(ステータスフラグ変更のみ)OBJECT $C1/92D8 BNE $EF [$92C9] ;ゼロフラグが立っていないとき[$92C9]分岐 ;ゼロフラグON $C1/92DA BIT #$02 ;Aと$02で論理積(ステータスフラグ変更のみ)BREAKDOWN $C1/92DC BEQ $0C [$92EA] ;ゼロフラグが立っているとき[$92EA]分岐 ;ゼロフラグON $C1/92EA LDA $7E9104,x[$7E:AC04] ;Aに[$7E:AC04]をロード 敵番号0順序ポイント(下1バイト)94 $C1/92EE STA $10 [$00:0310] ;Aを[$00:0310]に書き込み $C1/92F0 LDA $7E9105,x[$7E:AC05] ;Aに[$7E:AC05]をロード 敵番号0順序ポイント(上1バイト)00 $C1/92F4 STA $11 [$00:0311] ;Aを[$00:0311]に書き込み $C1/92F6 STX $14 [$00:0314] ;Xを[$00:0314]に書き込み $C1/92F8 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ
ここからが順序ポイントの判定である。
まず、敵番号0の順序ポイントを読み出す。
敵番号0の戦闘状態が「味方キャラが敵状態($40)」ではなければ$C1/92D0~の判定に進む。
再度、敵データ15から、OBJECTやBREAKDOWNではない場合、$C1/92EA~の順序ポイントの読み込みが開始になる。
(ちなみにBREAKDOWNだと、先に敵番号xの行動異常[$7E:AAx2]に$00を書き込む処理が挟まる)
$C1/92EA~$C1/92F4では敵番号0順序ポイント[$7E:AC05][$7E:AC04]を、[$00:0311][$00:0310]にコピーする。
[$00:0310] 敵番号0順序ポイント(下1バイト)[$00:0311] 敵番号0順序ポイント(上1バイト)X(X:1B00)を[$00:0314]に書き込んでから、$C1/E1A9にジャンプする。
;ループ処理ここから $C1/E1A9 REP #$21 ;Aを16bit幅に変更、キャリーフラグクリア $C1/E1AB TXA ;Xレジスタの値をAレジスタに転送 $C1/E1AC ADC #$0010 ;A + $0010 $C1/E1AF TAX ;Aの値をXレジスタに転送 $C1/E1B0 SEP #$20 ;MフラグON Aレジスタは8bit幅 $C1/E1B2 CPX #$1C00 ;Xと$1C00を減算比較(ステータスレジスタ変更のみ) $C1/E1B5 BEQ $11 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 $C1/E1B7 LDA $0001,x[$00:1B11] ;Aに[$00:1B11](敵番号1戦闘状態)をロード $C1/E1BA BIT #$40 ;Aと$40で論理積(ステータスフラグ変更のみ) $C1/E1BC BNE $07 [$E1C5] ;ゼロフラグが立っていないとき[$E1C5]分岐 ;ゼロフラグON(戦闘状態が$40か$80) $C1/E1BE CMP #$80 ;Aと$80を減算比較(ステータスレジスタ変更のみ) $C1/E1C0 BEQ $06 [$E1C8] ;ゼロフラグが立っているとき[$E1C8]分岐 ;ゼロフラグON(戦闘状態$80、つまり敵総数+1なので敵の判定すべて終了) $C1/E1C8 LDA #$80 ;Aに$80をロード ;$C1/E1BCでゼロフラグOFF $C1/E1C5 LDA #$7F ;Aに$7Fをロード $C1/E1C7 RTS ;サブルーチン戻り $C1/92FB BEQ $FB [$92F8] ;ゼロフラグが立っているとき[$92F8]分岐 $C1/92FD BMI $32 [$9331] ;ネガティブフラグが立っているとき[$9331]分岐 ;ネガティブフラグONの時ループ抜けて$C1/9331へ ;ネガティブフラグOFF $C1/92FF LDY $0002,x[$00:1B12] ;Yに[$00:1B12]をロード $C1/9302 LDA $002F,y[$00:1A2F] ;Aに[$00:1A2F](敵データ15 タイプ)をロード $C1/9305 BIT #$04 ;Aと$04で論理積(ステータスフラグ変更のみ)OBJECT $C1/9307 BNE $EF [$92F8] ;ゼロフラグが立っていないとき[$92F8]分岐 ;ゼロフラグON $C1/9309 BIT #$02 ;Aと$02で論理積(ステータスフラグ変更のみ)BREAKDOWN $C1/930B BEQ $0C [$9319] ;ゼロフラグが立っているとき[$9319]分岐 ;ゼロフラグOFF(BREAKDOWN) $C1/930D LDA #$00 ;Aに$00をロード $C1/930F STA $7E8F02,x[$7E:AAx2] ;Aを[$7E:AAx2]に書き込み $C1/9313 LDA $16 [$00:0316] ;Aに[$00:0316]をロード $C1/9315 BEQ $E1 [$92F8] ;ゼロフラグが立っているとき[$92F8]分岐 $C1/9317 BRA $00 [$9319] ;フラグにかかわりなく常に分岐[$9319] ;ゼロフラグON $C1/9319 LDA $7E9104,x[$7E:AC14] ;Aに[$7E:AC14]をロード 敵番号1順序ポイント(下1バイト) $C1/931D STA $12 [$00:0312] ;Aを[$00:0312]に書き込み $C1/931F LDA $7E9105,x[$7E:AC15] ;Aに[$7E:AC15]をロード 敵番号1順序ポイント(上1バイト) $C1/9323 STA $13 [$00:0313] ;Aを[$00:0313]に書き込み $C1/9325 LDY $12 [$00:0312] ;Yに[$00:0313][$00:0312]をロード $C1/9327 CPY $10 [$00:0310] ;Yと[$00:0311][$00:0310]を減算比較(ステータスレジスタ変更のみ) $C1/9329 BCC $CD [$92F8] ;キャリーフラグが立っていないとき[$92F8]分岐 ;キャリーフラグON $C1/932B STY $10 [$00:0310] ;Yを[$00:0311][$00:0310]に書き込み $C1/932D STX $14 [$00:0314] ;Xを[$00:0315][$00:0314]に書き込み $C1/932F BRA $C7 [$92F8] ;フラグにかかわりなく常に分岐[$92F8] ;キャリーフラグOFF $C1/92F8 JSR $E1A9 [$C1:E1A9] ;[$C1:E1A9]へジャンプ ;ループ処理ここまで
上のループ処理は、敵番号1以降の全ての敵に対して行い、敵番号nの戦闘状態を判定して敵総数+1の時点でループを抜けるようになっている。
$C1/9319~からが順序ポイント判定で、敵番号1順序ポイント[$7E:AC15][$7E:AC14]を、[$00:0313][$00:0312]にコピーする。
[$00:0310] 敵番号0順序ポイント(下1バイト)[$00:0311] 敵番号0順序ポイント(上1バイト)[$00:0312] 敵番号1順序ポイント(下1バイト)[$00:0313] 敵番号1順序ポイント(上1バイト)$C1/9325から、[$00:0313][$00:0312]と[$00:0311][$00:0310]の減算比較・キャリーフラグ判定である。
つまり、
敵番号1順序ポイント - 敵番号0順序ポイント
の計算だから、キャリーフラグが立つのは減算結果が0以上、敵番号1順序ポイント≧敵番号0順序ポイントの時である。
キャリーフラグが立つ場合は$C1/932B~の処理だが、
[$00:0311][$00:0310] 敵番号0順序ポイント→敵番号1順序ポイントに上書き[$00:0313][$00:0312] 敵番号1順序ポイント更に、[$00:0315][$00:0314]にXの値を書き込むが、この時点のX:1B10、つまり敵番号のデータの開始アドレスである。
キャリーフラグが立たない、つまり敵番号1順序ポイント < 敵番号0順序ポイントなら上処理は入らない。
つまり、[$00:0311][$00:0310]には、順序ポイントが大きいか、同値なら敵番号の大きな方の順序ポイントが残されることになる。
これを、敵番号を+1しながら繰り返すことで、最終的に[$00:0311][$00:0310]にはすべての敵の中で最も大きい順序ポイントが残されることになる。
また、[$00:0315][$00:0314]にも、すべての敵の中で最も大きい順序ポイントを持つ敵番号のデータの開始アドレスが入ることになる。
では、すべての敵の判定を終えて、$C1/92FDからループを抜けた後を見てみよう。
$C1/92FB BEQ $FB [$92F8] ;ゼロフラグが立っているとき[$92F8]分岐 $C1/92FD BMI $32 [$9331] ;ネガティブフラグが立っているとき[$9331]分岐 $C1/9331 LDX $14 [$00:0314] ;Xに[$00:0315][$00:0314](順序ポイント最大値の敵番号)をロード $C1/9333 STX $AC [$00:03AC] ;Xを[$00:03AD][$00:03AC]に書き込み $C1/9335 RTS ;サブルーチン戻り
Xに[$00:0315][$00:0314](順序ポイント最大値の敵番号)をロードすることで、該当敵番号の敵の処理が始まる。
これにて、敵ターンで行動する敵が決まった。
なお、この後だが、$C1/9335でサブルーチンが戻り、$C1/8E5Bの続きの処理に飛ぶ。
その続きのアドレスは$C1/8E5E~$C1/8E7F。
つまり、先に紹介した「行動不能な状態異常(石化、マヒ、眠り)で行動順が回ってくる」の処理である。
$C1/8E5E CPX #$0000 ;Xと$0000を減算比較(ステータスレジスタ変更のみ) ;(中略) $C1/8E7F JSR $90A2 [$C1:90A2] ;[$C1:90A2]へジャンプ $C1/90A2 LDA $7E8F02,x[$7E:AAn2] ;Aに[$7E:AAn2](行動異常)をロード $C1/90A6 BEQ $1C [$90C4] ;ゼロフラグが立っているとき[$90C4]分岐 ;ゼロフラグOFF(行動異常0以外) $C1/90A8 LDA $0005,x[$00:1Bn5] ;Aに[$00:1Bn5](技関係状態)をロード $C1/90AB BNE $17 [$90C4] ;ゼロフラグが立っていないとき[$90C4]分岐 ;ゼロフラグOFF(タメ時間中ではない) $C1/90AD LDA $7E9106,x[$7E:ACn6] ;Aに[$7E:ACn6]をロード $C1/90B1 BNE $11 [$90C4] ;ゼロフラグが立っていないとき[$90C4]分岐 ;ゼロフラグON(行動異常解除判定処理へ) $C1/90B3 JSR $6150 [$C1:6150] ;[$C1:6150]へジャンプ ;(戦闘乱数計算) $C1/90B6 AND #$7F ;Aと$7F($0111 1111)で論理積 $C1/90B8 CMP $7E9000,x[$7E:ABn0] ;Aと[$7E:ABn0](LV(現在値))を減算比較(ステータスレジスタ変更のみ) $C1/90BC BCS $06 [$90C4] ;キャリーフラグが立っているとき[$90C4]分岐 ;キャリーフラグOFF $C1/90BE LDA #$00 ;Aに$00をロード $C1/90C0 STA $7E8F02,x[$7E:AAn2] ;Aを[$7E:AAn2](行動異常)に書き込み ;ゼロフラグON(行動異常0) $C1/90C4 RTS ;サブルーチン戻り $C1/8E82 JSR $1CF7 [$C1:1CF7] ;[$C1:1CF7]へジャンプ
「行動不能な状態異常」の処理を抜けると$C1/90A2~$C1/90C4の処理にジャンプする。
ここは敵行動前の行動異常解除判定である。
行動異常0でない限り、戦闘乱数($00~$FF) & $7F($0111 1111) - LV(現在値)でキャリーフラグが立たない時は行動異常を0に上書きする、という処理になる。
戦闘乱数($00~$FF)と$7Fの論理積は、乱数を上7ビットの$00~$7Fに変更するのと同じなので、
乱数(0~127) - LV(現在値) < 0
つまり、LV(現在値)が乱数(0~127)より大きい時、行動異常を解除する
という処理になる。
確率としては
LV(現在値) / 128
で解除であり、レベルが高いほど行動異常から元に戻りやすい。
さて、その判定後に$C1/8E82で[$C1:1CF7]へジャンプしている。
既に上で説明した通り、$C1/1CF7~$C1/1D1Dは行動異常8バイト分のデータを呼び出す処理で、続いて順序ポイント処理を行っている。
このあたりがすべて連続した処理だったということである。