ポケモンFRLG TID決定時の乱数初期化処理を見てみた
当方初心者です。乱数ガチ勢向けの新情報とかはありません。
名前決めて暗転した直後の処理
--------sub start--------
8000564 10 B5 PUSH {R4,LR}
8000566 06 48 LDR R0, [PC, #$06]
8000568 04 88 LDRH R4, [R0, #$00] //$4000104(TM1CNT_L)タイトル画面と主人公の名前決める画面で動いてる 他の画面では止まったまま
800056A 20 1C ADD R0, R4, #$00
800056C 43 F0 BLL #$0043
800056E 9E FF BLH #$079E //初期乱数を代入するサブルーチンへジャンプ
8000570 04 49 LDR R1, [PC, #$04]
8000572 00 20 MOV R0, #$00
8000574 08 80 STRH R0, [R1, #$00]
8000576 04 48 LDR R0, [PC, #$04]
8000578 04 80 STRH R4, [R0, #$00]
800057A 10 BC POP {R4}
800057C 01 BC POP {R0}
800057E 00 47 BX R0
----------------
--------sub start--------
80444AC 00 04 LSL R0, R0, #$10
80444AE 00 0C LSR R0, R0, #$10//上2バイトを0にする
80444B0 01 49 LDR R1, [PC, #$01]
80444B2 08 60 STR R0, [R1, #$00]//乱数アドレスへ代入
80444B4 70 47 BX LR
----------------
$4000104(TM1CNT_L)にはハードウェアのタイマーの値入ってるっぽい。ブレークポイントは効かなかった。
多分乱数ガチ勢が初期シード集めとかしてるのはここの挙動が読めないからだと思う。
AIに色々聞いたりエミュで軽く試したりしてみたが、一致させる詳しい条件は分からなかった。
疑問点
- タイトル画面終了時に一旦止まったTM1CNT_Lは、名前決定画面で再起動されるTM1CNT_Lには影響無さそう?
- 名前決定画面に入ってから決定までのフレーム数が一致して、かつボタン入力とかの状態が何らかの条件を満たせば一致する?
以上、難しそうなのでこれ以上の調査は多分しません。終わり。
SFC版DQ1,2 ブレス・呪文のダメージ計算についての調査+α
よく参照されてる記事がありますが、詳細な処理内容、装備補正がどこで入るのか等が分からないので調査してみました。
よく参照されてる記事↓
https://bamboo.ninja-web.net/dq1,2/damage-disp/DQ12randave_jsplot2.html
アセンブリはよく分からないので、AIに聞きながら「なんとなくこうっぽい?」で進めてます。正確性は保証できません。
ダメージ乱数補正処理について
気付いたこと
256をダメージ幅で割り切れない場合は低ダメージが出やすいようです。
例えば振れ幅が9の火の息(12~20)の場合、乱数が255の時に255/9=28余り3。
そのため、12~15は29/256、16~20は28/256の確率で出ることになります。
また、割り算と切り捨てが入るので大きい値よりも小さい値の方が出やすくなります。
例
乱数2回で72を引く場合、2連続で72を引く必要がある。
乱数2回で65を引く場合、65,66の組み合わせでも切り捨てで65となる。
激しい炎のダメージ幅は8で割り切れるにも関わらず72が出る確率が65より低いのは、この仕様によるものだと思います。
処理内容
サブルーチン(ブレス・呪文ダメージ)
2026/03/20追記:敵・味方のベホイミもこのサブルーチンで計算されている
0BA5AD DA PHX
0BA5AE A9 00 LDA #$00
0BA5B0 EB XBA
0BA5B1 AD 67 00 LDA $0067
0BA5B4 29 03 AND #$03 //ここで下位2bitをマスクしてループ回数決定
0BA5B6 AA TAX
0BA5B7 BF 09 A6 0B LDA $0BA609,X
0BA5BB 85 08 STA $08
0BA5BD 64 09 STZ $09
0BA5BF 48 PHA
0BA5C0 AD 30 10 LDA $1030 //ダメージ最大値を読み込み。(はげほなら0x48)
0BA5C3 38 SEC
0BA5C4 ED 2F 10 SBC $102F //ダメージ最大値から最小値を引く。(48-41=7)
0BA5C7 A2 00 00 LDX #$0000
0BA5CA 86 0A STX $0A
//ループ開始
0BA5CC 48 PHA //サブルーチン内で計算する値をスタックへ
0BA5CD 22 7E A5 0B JSL $0BA57E //サブルーチン(振れ幅内の乱数を返す)へ
0BA5D1 18 CLC
0BA5D2 65 0A ADC $0A //合計値計算
0BA5D4 85 0A STA $0A //合計値の一時保存
0BA5D6 A9 00 LDA #$00
0BA5D8 65 0B ADC $0B
0BA5DA 85 0B STA $0B
0BA5DC 68 PLA //スタックからダメージ幅(8)を取り出す
0BA5DD E8 INX //ループ回数カウント+1
0BA5DE E4 08 CPX $08 //ループ回数確認
0BA5E0 90 EA BCC $0BA5CC //回数に達していなければ0BA5CCに戻る
//ループ終了
0BA5E2 68 PLA
0BA5E3 85 08 STA $08
0BA5E5 C2 20 REP #$20
0BA5E7 A5 0A LDA $0A //合計値をロード
0BA5E9 A6 08 LDX $08 //ループ回数をロード
0BA5EB E0 01 00 CPX #$0001
0BA5EE F0 11 BEQ $0BA601
0BA5F0 4A LSR
0BA5F1 A6 08 LDX $08
0BA5F3 E0 02 00 CPX #$0002
0BA5F6 F0 09 BEQ $0BA601
0BA5F8 4A LSR
0BA5F9 A6 08 LDX $08
0BA5FB E0 04 00 CPX #$0004
0BA5FE F0 01 BEQ $0BA601
0BA600 4A LSR //ここまで、ループ回数に応じて割り算
0BA601 E2 20 SEP #$20
0BA603 18 CLC
0BA604 6D 2F 10 ADC $102F //計算した乱数に、ダメージ最低値を足す
0BA607 FA PLX
0BA608 6B RTL
サブルーチン(振れ幅内の乱数を返す)
0BA57E DA PHX
0BA57F 1A INC //受け取った値+1(はげほなら8)
0BA580 48 PHA //スタックに8を一時保存
0BA581 22 50 A5 0B JSL $0BA550 //サブルーチン(0~255の乱数生成)
0BA585 A6 E2 LDX $E2 //生成した乱数取り出し
0BA587 8E 04 42 STX $4204 //乱数をハードウェアにセット
0BA58A 68 PLA //スタックから8を取り出し
0BA58B 8D 06 42 STA $4206 //8をハードウェアにセット
0BA58E EA NOP //ここからハードウェアの割り算処理待ち
0BA58F EA NOP
0BA590 EA NOP
0BA591 EA NOP
0BA592 EA NOP
0BA593 EA NOP
0BA594 EA NOP
0BA595 EA NOP //ここまで待ち
0BA596 AD 16 42 LDA $4216 //ハードウェアから割り算の余りを取得
0BA599 FA PLX
0BA59A 6B RTL //戻る
サブルーチン(0~255の乱数生成)
0BA550 C2 20 REP #$20
0BA552 A5 E2 LDA $E2
0BA554 48 PHA
0BA555 A5 E0 LDA $E0
0BA557 06 E0 ASL $E0
0BA559 26 E2 ROL $E2
0BA55B 18 CLC
0BA55C 65 E0 ADC $E0
0BA55E 85 E0 STA $E0
0BA560 68 PLA
0BA561 65 E2 ADC $E2
0BA563 85 E2 STA $E2
0BA565 A5 E0 LDA $E0
0BA567 18 CLC
0BA568 69 49 35 ADC #$3549
0BA56B 65 67 ADC $67
0BA56D 85 E0 STA $E0
0BA56F A5 E2 LDA $E2
0BA571 69 00 00 ADC #$0000
0BA574 85 E2 STA $E2
0BA576 E2 20 SEP #$20
0BA578 A9 00 LDA #$00
0BA57A EB XBA
0BA57B A5 E2 LDA $E2
0BA57D 6B RTL
計算順について
結論
乱数補正の後に3/4倍処理が入るっぽいです。
各ダメージの確率を知りたい場合、冒頭の記事の数値を参照し、補正して一緒になる数値は合算した確率でいいと思います。
例
激しい炎の68と69は共に、3/4倍で切り捨てて51になる。
⇒68と69の確率を合算して49.59270358%の確率で51ダメージとなる。
根拠
以下は実行時のTrace Log。Aレジスタの中身がダメージの値(16進数)になっている。
0B906B LDA $00 [$000000] = $0044 A:000E X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdiZC V:251 H:326
0B906D AND #$00FF A:0044 X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdizC V:251 H:334
0B9070 PHA A:0044 X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdizC V:252 H:0
024B MOV A,$F4 [CPUIO0] = $00 A:00 X:50 Y:00 S:FD P:nvpbhiZc V:252 H:3
0B9071 ASL A:0044 X:0000 Y:0000 S:02E1 D:0000 DB:00 P:nvmxdizC V:252 H:7
0B9072 ADC $01,S [$0002E2] = $0044 A:0088 X:0000 Y:0000 S:02E1 D:0000 DB:00 P:nvmxdizc V:252 H:11
024D BEQ $024A A:00 X:50 Y:00 S:FD P:nvpbhiZc V:252 H:18
0B9074 STA $01,S [$0002E2] = $0044 A:00CC X:0000 Y:0000 S:02E1 D:0000 DB:00 P:nvmxdizc V:252 H:20
0B9076 PLA A:00CC X:0000 Y:0000 S:02E1 D:0000 DB:00 P:nvmxdizc V:252 H:30
0B9077 LSR A:00CC X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdizc V:252 H:39
024A RET A:00 X:50 Y:00 S:FD P:nvpbhiZc V:252 H:40
0B9078 LSR A:0066 X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdizc V:252 H:42
0B9079 SEP #$20 A:0033 X:0000 Y:0000 S:02E3 D:0000 DB:00 P:nvmxdizc V:252 H:46
・LDAでAレジスタにダメージ値(0x44 = 68)を読み込み
・ASLでAレジスタの値を2倍(0x88)
・ADCでAレジスタの値を加算(0xCC ここまでで3倍になる)
・LSR1/2倍を2回行って1/4倍(0x33 = 51)
実際にこの後ダメージは51だった。
この後もう一度試したら、読み込まれるダメージ値が変わっていました。
計算終了時点でAレジスタが0x30、実際のダメージが48。
このことから、既に乱数補正済みの数値を読み込んで3/4倍処理が走っていることが分かります。
処理内容(サブルーチン全体)
0B9069 C2 20 REP #$20 //16bitモードに変更
0B906B A5 00 LDA $00 //Aレジスタにダメージ値読み込み
0B906D 29 FF 00 AND #$00FF //下位8bitを使うためのマスク
0B9070 48 PHA //スタックに保存
0B9071 0A ASL //Aレジスタ2倍
0B9072 63 01 ADC $01,S //Aレジスタ+スタック⇒元の値の3倍
0B9074 83 01 STA $01,S //スタックをきれいにする処理らしい①
0B9076 68 PLA //スタックをきれいにする処理らしい②
0B9077 4A LSR //÷2
0B9078 4A LSR //÷2 →元の値の3/4倍
0B9079 E2 20 SEP #$20 //8bitモードに戻す
0B907B 85 00 STA $00 //結果をメモリに保存
0B907D 80 A9 BRA $0B9028
追記
勇者の通常攻撃ダメージの計算ルーチン
--------sub start--------
0BA05A 64 03 STZ $03
0BA05C DA PHX
0BA05D AE 60 0F LDX $0F60
0BA060 BD E2 0F LDA $0FE2,X
0BA063 FA PLX
0BA064 C9 FF CMP #$FF
0BA066 F0 01 BEQ $0BA069
0BA068 4A LSR //守備力/2
0BA069 85 01 STA $01
0BA06B A5 00 LDA $00
0BA06D 38 SEC
0BA06E E5 01 SBC $01 //攻撃力-守備力/2
0BA070 90 43 BCC $0BA0B5
0BA072 4A LSR //(攻撃力-守備力/2)/2 基礎値計算完了
0BA073 C9 02 CMP #$02
0BA075 90 3E BCC $0BA0B5 //2回ならジャンプ
0BA077 85 03 STA $03
0BA079 C9 09 CMP #$09
0BA07B 90 3F BCC $0BA0BC //9以下ならジャンプ
0BA07D 8D 02 42 STA $4202
0BA080 A9 07 LDA #$07
0BA082 8D 03 42 STA $4203 //基礎値*7
0BA085 EA NOP
0BA086 EA NOP
0BA087 EA NOP
0BA088 C2 20 REP #$20
0BA08A AD 16 42 LDA $4216
0BA08D 4A LSR
0BA08E 4A LSR
0BA08F 4A LSR //基礎値*7/8 最低ダメージ計算完了
0BA090 85 06 STA $06 //最低ダメージメモ
0BA092 E2 20 SEP #$20
0BA094 A5 03 LDA $03 //基礎値読み込み
0BA096 4A LSR
0BA097 4A LSR //基礎値/4
0BA098 1A INC //+1
0BA099 48 PHA
0BA09A 22 50 A5 0B JSL $0BA550 //乱数生成サブルーチンへ
0BA09E 8D 02 42 STA $4202 //乱数0-255をセット
0BA0A1 68 PLA
0BA0A2 8D 03 42 STA $4203 //ダメージ振れ幅をセット
0BA0A5 EA NOP
0BA0A6 EA NOP
0BA0A7 EA NOP
0BA0A8 EA NOP
0BA0A9 AC 16 42 LDY $4216 //セットした値の積を取得
0BA0AC 84 08 STY $08 //乗算結果を格納
0BA0AE A5 09 LDA $09 //乗算結果の上位バイトをAレジスタに読み込み(÷256)
0BA0B0 18 CLC
0BA0B1 65 06 ADC $06 //Aレジスタに最低ダメージを加算(最終ダメージ)
0BA0B3 80 12 BRA $0BA0C7
0BA0B5 AD 67 00 LDA $0067
0BA0B8 29 01 AND #$01
0BA0BA 80 0B BRA $0BA0C7
0BA0BC A9 02 LDA #$02
0BA0BE 22 7E A5 0B JSL $0BA57E
0BA0C2 18 CLC
0BA0C3 65 03 ADC $03
0BA0C5 3A DEC
0BA0C6 3A DEC
0BA0C7 C9 00 CMP #$00
0BA0C9 D0 07 BNE $0BA0D2
0BA0CB 9C 91 0C STZ $0C91
0BA0CE 9C 92 0C STZ $0C92
0BA0D1 60 RTS
----------------
敵の通常攻撃のダメージを計算するルーチン
ロジックは同じっぽい
--------sub start--------
0B8AF4 A6 AE LDX $AE
0B8AF6 B9 DB 0F LDA $0FDB,Y
0B8AF9 85 00 STA $00
0B8AFB 64 03 STZ $03
0B8AFD BD 3D 0C LDA $0C3D,X
0B8B00 4A LSR //守備力/2
0B8B01 85 01 STA $01
0B8B03 A5 00 LDA $00
0B8B05 38 SEC
0B8B06 E5 01 SBC $01 //攻撃力-守備力/2
0B8B08 90 44 BCC $0B8B4E
0B8B0A 4A LSR //(攻撃力-守備力/2)/2 基礎値計算完了
0B8B0B 85 03 STA $03 //基礎値をメモ
0B8B0D C9 02 CMP #$02
0B8B0F 90 3D BCC $0B8B4E //2以下の場合ジャンプ
0B8B11 C9 09 CMP #$09
0B8B13 90 41 BCC $0B8B56 //9以下の場合ジャンプ
0B8B15 8D 02 42 STA $4202
0B8B18 A9 07 LDA #$07
0B8B1A 8D 03 42 STA $4203 //基礎値*7をハードウェアで計算
0B8B1D EA NOP
0B8B1E EA NOP
0B8B1F EA NOP
0B8B20 C2 20 REP #$20
0B8B22 AD 16 42 LDA $4216
0B8B25 4A LSR
0B8B26 4A LSR
0B8B27 4A LSR //基礎値*7/8 最低ダメージ計算完了
0B8B28 85 06 STA $06 //最低ダメージをメモ
0B8B2A E2 20 SEP #$20
0B8B2C A5 03 LDA $03 //基礎値読み込み
0B8B2E 4A LSR
0B8B2F 4A LSR //基礎値/4
0B8B30 1A INC //+1
0B8B31 48 PHA
0B8B32 22 50 A5 0B JSL $0BA550 //乱数生成
0B8B36 8D 02 42 STA $4202
0B8B39 68 PLA
0B8B3A 8D 03 42 STA $4203
0B8B3D EA NOP
0B8B3E EA NOP
0B8B3F EA NOP
0B8B40 EA NOP
0B8B41 AC 16 42 LDY $4216
0B8B44 84 08 STY $08
0B8B46 A5 09 LDA $09 //乗算結果の上位バイトを取得
0B8B48 18 CLC
0B8B49 65 06 ADC $06 //最低ダメージを加算(最終ダメージ)
0B8B4B 4C 63 8B JMP $8B63
0B8B4E 22 50 A5 0B JSL $0BA550
0B8B52 29 01 AND #$01
0B8B54 80 0D BRA $0B8B63
0B8B56 A5 03 LDA $03
0B8B58 A9 02 LDA #$02
0B8B5A 22 7E A5 0B JSL $0BA57E
0B8B5E 18 CLC
0B8B5F 65 03 ADC $03
0B8B61 3A DEC
0B8B62 3A DEC
0B8B63 C9 00 CMP #$00
0B8B65 D0 08 BNE $0B8B6F
0B8B67 9C 91 0C STZ $0C91
0B8B6A 9C 92 0C STZ $0C92
0B8B6D 38 SEC
0B8B6E 60 RTS
----------------
ホイミ回復量計算
25-28の確率がそれぞれ43/256、29,30の確率がそれぞれ42/256になると思われる
--------sub start--------
0BA59B DA PHX
0BA59C AD 30 10 LDA $1030 //30
0BA59F 38 SEC
0BA5A0 ED 2F 10 SBC $102F //30-25
0BA5A3 22 7E A5 0B JSL $0BA57E //振れ幅内の乱数を返すサブルーチン
0BA5A7 18 CLC
0BA5A8 6D 2F 10 ADC $102F //計算結果+最低値25
0BA5AB FA PLX
0BA5AC 6B RTL
----------------
薬草の計算処理
振れ幅16なので、一様分布
--------sub start--------
0BAE25 64 1B STZ $1B
0BAE27 A9 0F LDA #$0F //15(振れ幅取得)
0BAE29 22 7E A5 0B JSL $0BA57E //0-15の乱数取得
0BAE2D 18 CLC
0BAE2E 69 14 ADC #$14 //振れ幅+20(回復量の計算完了)
0BAE30 A6 1A LDX $1A
0BAE32 18 CLC
0BAE33 7D 09 0C ADC $0C09,X
0BAE36 90 02 BCC $0BAE3A
0BAE38 A9 FF LDA #$FF
0BAE3A DD 2D 0C CMP $0C2D,X
0BAE3D 90 03 BCC $0BAE42
0BAE3F BD 2D 0C LDA $0C2D,X
0BAE42 9D 09 0C STA $0C09,X
0BAE45 A5 70 LDA $70
0BAE47 30 07 BMI $0BAE50
0BAE49 A9 12 LDA #$12
0BAE4B 22 63 83 09 JSL $098363
0BAE4F 6B RTL
----------------
通常と会心の分岐部分
--------sub start--------
0B9FA6 BD 35 0C LDA $0C35,X
0B9FA9 85 00 STA $00
0B9FAB 22 50 A5 0B JSL $0BA550
0B9FAF C9 08 CMP #$08
0B9FB1 B0 15 BCS $0B9FC8 //Aレジスタの値が8以上の場合、通常ダメージへ
0B9FB3 20 D9 A0 JSR $A0D9 //会心ダメージへ
0B9FB6 BD BB 0F LDA $0FBB,X
0B9FB9 D0 03 BNE $0B9FBE
0B9FBB FE BB 0F INC $0FBB,X
0B9FBE AD 91 0C LDA $0C91
0B9FC1 8D 49 10 STA $1049
0B9FC4 A0 02 00 LDY #$0002
0B9FC7 6B RTL
----------------
会心ダメージ計算
下位3乱数が24/256、上位8乱数が23/256の確率で出る
--------sub start--------
0BA0D9 A9 0A LDA #$0A
0BA0DB 22 7E A5 0B JSL $0BA57E //0~10の乱数を返す
0BA0DF 1A INC //乱数+1
0BA0E0 18 CLC
0BA0E1 69 36 ADC #$36 //乱数+1+54 → 55~65になる
0BA0E3 8D 02 42 STA $4202
0BA0E6 A5 00 LDA $00
0BA0E8 8D 03 42 STA $4203
0BA0EB EA NOP
0BA0EC EA NOP
0BA0ED EA NOP
0BA0EE C2 20 REP #$20
0BA0F0 AD 16 42 LDA $4216 //55~65×攻撃力
0BA0F3 4A LSR
0BA0F4 4A LSR
0BA0F5 4A LSR
0BA0F6 4A LSR
0BA0F7 4A LSR
0BA0F8 4A LSR //÷64
0BA0F9 C9 FE 00 CMP #$00FE
0BA0FC 90 03 BCC $0BA101
0BA0FE A9 FE 00 LDA #$00FE
0BA101 E2 20 SEP #$20
0BA103 C9 00 CMP #$00
0BA105 F0 C0 BEQ $0BA0C7
0BA107 8D 91 0C STA $0C91
0BA10A 9C 92 0C STZ $0C92
0BA10D 60 RTS
----------------
行動順計算
--------sub start--------
0B9E1E A2 00 00 LDX #$0000
0B9E21 9B TXY
0B9E22 AD A0 0F LDA $0FA0
0B9E25 F0 03 BEQ $0B9E2A
0B9E27 4C 62 9E JMP $9E62
0B9E2A A9 7F LDA #$7F
0B9E2C 22 7E A5 0B JSL $0BA57E //サブルーチンへ 0-127の乱数を返す
0B9E30 8D 02 42 STA $4202
0B9E33 B9 D4 0F LDA $0FD4,Y //敵の素早さ
0B9E36 8D 03 42 STA $4203
0B9E39 EA NOP
0B9E3A EA NOP
0B9E3B EA NOP
0B9E3C DA PHX
0B9E3D AE 16 42 LDX $4216 //Xレジスタに乱数と振れ幅の乗算結果取得
0B9E40 86 0D STX $0D
0B9E42 FA PLX
0B9E43 B9 D4 0F LDA $0FD4,Y
0B9E46 38 SEC
0B9E47 E5 0E SBC $0E //最大値-振れ幅の減少分
0B9E49 9D 80 0B STA $0B80,X
0B9E4C E8 INX
0B9E4D A9 00 LDA #$00
0B9E4F 9D 80 0B STA $0B80,X
0B9E52 99 4B 0F STA $0F4B,Y
0B9E55 E8 INX
0B9E56 C8 INY
0B9E57 98 TYA
0B9E58 CD DC 0E CMP $0EDC
0B9E5B 90 CD BCC $0B9E2A
0B9E5D AD E6 0C LDA $0CE6
0B9E60 F0 33 BEQ $0B9E95
0B9E62 A0 00 00 LDY #$0000
0B9E65 A9 57 LDA #$57
0B9E67 22 7E A5 0B JSL $0BA57E //サブルーチンへ 0-87の乱数を返す
0B9E6B 8D 02 42 STA $4202
0B9E6E B9 21 0C LDA $0C21,Y //勇者の素早さ
0B9E71 8D 03 42 STA $4203
0B9E74 EA NOP
0B9E75 EA NOP
0B9E76 EA NOP
0B9E77 DA PHX
0B9E78 AE 16 42 LDX $4216
0B9E7B 86 06 STX $06
0B9E7D FA PLX
0B9E7E B9 21 0C LDA $0C21,Y
0B9E81 38 SEC
0B9E82 E5 07 SBC $07
0B9E84 9D 80 0B STA $0B80,X
0B9E87 E8 INX
0B9E88 A9 01 LDA #$01
0B9E8A 9D 80 0B STA $0B80,X
0B9E8D E8 INX
0B9E8E C8 INY
0B9E8F 98 TYA
0B9E90 CD E6 0C CMP $0CE6
0B9E93 90 D0 BCC $0B9E65
0B9E95 AD DC 0E LDA $0EDC
0B9E98 48 PHA
0B9E99 AD A0 0F LDA $0FA0
0B9E9C F0 03 BEQ $0B9EA1
0B9E9E 9C DC 0E STZ $0EDC
0B9EA1 8A TXA
0B9EA2 4A LSR
0B9EA3 20 AB 9E JSR $9EAB
0B9EA6 68 PLA
0B9EA7 8D DC 0E STA $0EDC
0B9EAA 6B RTL
----------------
勇者睡眠時の行動処理
--------sub start--------
0BA97A E2 10 SEP #$10
0BA97C 64 00 STZ $00
0BA97E A0 00 LDY #$00
0BA980 B9 BE 0E LDA $0EBE,Y //ラリホーフラグ読み込み 最初は4
0BA983 F0 0E BEQ $0BA993 //0ならジャンプ
0BA985 A9 02 LDA #$02
0BA987 99 BB 0F STA $0FBB,Y //勇者の行動に02(防御)をセット
0BA98A C8 INY
0BA98B CC E6 0C CPY $0CE6
0BA98E 90 F0 BCC $0BA980 //多分、人数分ループ処理
0BA990 38 SEC
0BA991 80 01 BRA $0BA994
0BA993 18 CLC
0BA994 C2 10 REP #$10
0BA996 6B RTL
----------------
勇者起床判定
--------sub start--------
00D514 F0 E3 BEQ $00D4F9
00D516 B9 BE 0E LDA $0EBE,Y
00D519 F0 1F BEQ $00D53A //眠りフラグ0ならジャンプ
00D51B C9 01 CMP #$01
00D51D F0 04 BEQ $00D523 //1ならジャンプ
00D51F 3A DEC //フラグを更新(4→3→2→1と減らす)
00D520 99 BE 0E STA $0EBE,Y
00D523 AA TAX
00D524 22 50 A5 0B JSL $0BA550 //乱数取得
00D528 DD 75 D2 CMP $D275,X //乱数と以下の数値を比較
//D276(3T目以降) : C0、D277(2T目) : 80、D278(1T目) : 40
00D52B 90 04 BCC $00D531//乱数が規定値未満なら、起床処理へ
00D52D A0 08 00 LDY #$0008 //表示用眠っているフラグ?
00D530 60 RTS
----------------
勇者起床処理
--------sub start--------
00D531 A9 00 LDA #$00
00D533 99 BE 0E STA $0EBE,Y
00D536 A0 0A 00 LDY #$000A //表示用起きたフラグ?
00D539 60 RTS
----------------
以下、DQ2での検証
敵出現時のHP決定処理
--------sub start--------
0B9D7C C9 0A CMP #$0A
0B9D7E 90 30 BCC $0B9DB0//最大HP10未満の分岐
0B9D80 DA PHX
0B9D81 5A PHY
0B9D82 48 PHA
0B9D83 A9 14 LDA #$14 //Aレジスタに20を入れる
0B9D85 22 7E A5 0B JSL $0BA57E //振れ幅内(0~20)の乱数を返す
0B9D89 18 CLC
0B9D8A 69 50 ADC #$50 //0~20の乱数+80
0B9D8C 8D 02 42 STA $4202 //80~100の値をセット
0B9D8F 68 PLA
0B9D90 8D 03 42 STA $4203 //元のHPをセット
0B9D93 EA NOP
0B9D94 EA NOP
0B9D95 EA NOP
0B9D96 EA NOP
0B9D97 AE 16 42 LDX $4216 //80~100の値×元のHP
0B9D9A 8E 04 42 STX $4204
0B9D9D A9 64 LDA #$64
0B9D9F 8D 06 42 STA $4206
0B9DA2 EA NOP
0B9DA3 EA NOP
0B9DA4 EA NOP
0B9DA5 EA NOP
0B9DA6 EA NOP
0B9DA7 EA NOP
0B9DA8 EA NOP
0B9DA9 EA NOP
0B9DAA AD 14 42 LDA $4214 //÷100
0B9DAD 7A PLY
0B9DAE FA PLX
0B9DAF 60 RTS
----------------
RTA in Japan Winter 2025 感想
RTA in Japan Winter 2025に走者・解説として参加しました。

走者としてはオンライン含めて5回目、解説としては初の参加でした。
『星のカービィ ウルトラスーパーデラックス』のカテゴリー「Beat RotK」RTA
— RTA in Japan (@RTAinJapan) 2025年12月27日
走者のみりいさん(@miririi6)、takkaさん(@Gwtakka)、Clomyさん(@H19b31n1352t)、リカンさん(@rikan_lapin)、解説のわかざさん(@Wakaza_wkz)、お疲れさまでした。
配信はこちらから⇒https://t.co/iSbmGPKZXj#RTAinJapan pic.twitter.com/rbLRYgevan
『ゼルダ』のカテゴリー「Any%」RTA
— RTA in Japan (@RTAinJapan) 2025年12月27日
走者のオクトパスカルさん(@octopuscal428)、解説のみりいさん(@miririi6)、お疲れさまでした。
クリアタイムは 12:10 でした。
ラスボスのドラゴンを神速で沈めクリア!
神速の迷宮突破でした。GG!
配信はこちらから⇒https://t.co/iSbmGPKZXj#RTAinJapan pic.twitter.com/JPS4TxXlGF
カービィ
走りの反省点なのですが、ダイナ1面のミックス時、パラソルで同時吸いするまでのかっこいい動きで「パチパチあるだろうなー どのくらい反応あるかなー」とか考えてたらミックスに集中できずミスりました。集中すべきところで意識を別のところに持っていったらダメですね。
ちなみに、銀河に願いをの途中で「ペゴッ」って感じの音が頻繁に鳴っています。(長い間一位で走ってたので配信上にも乗ってる。)これはDSの不具合でタッチが誤動作しているために鳴っています。
元々は誤動作しない正常なDSを使う予定だったのですが、当日使う予定だった正常なDSの取り込みがうまく動かなくなったので急遽不具合のあるDSを使うことになりました。音はちょっと気になるけど無視してください。
DS2台目なかったら普通に詰んでました。持ってきててよかった~。
解説のわかざさんには4人並走の解説という難しいポジションで色々と頑張っていただきました。ありがとうございました。
最後のノヴァ爆破が想像以上に反響大きかったですね。
ゼルダ
知り合いのオクトパスカルさんがゼルダを走ることになり、このゲームを走っている日本人が他に僕しかいないということで解説に起用いただきました。2人とも、ゼルダ勢というよりはゲームウォッチ勢(?)です。
本番では想定以上にタイムが早かったこともあり、最低限のゲーム内容説明とゲーム概要説明で終わってしまいました。もう少しプレイングも詳しく話したかったのですが、走者解説2人ともゲームウォッチ好きな人間なので話したい周辺情報が多くてね……。
空いた時間にオクトパスカルさんが持ってきた実機のゼルダやマンホール(ニューワイド版)を遊ばせてもらいました。どちらも海外限定発売で、本体だけで数万円、箱付きならもっと高額になる貴重なものです。
ギャラリーに収録されているゲームでも実機ならではのプレイ感覚の違いが味わえて面白かったです。
ちなみに今のゼルダ世界1位は0xwasさんです。RiJの時にオクトパスカルさんがGBAのROMを貸して、その2日後にはWR更新してました。
終わり
ゲームキューブのディスク読み込み不良の対処法について
近年(2021年頃から?)、ゲームキューブのディスク読み込み不良が多くの本体が発生しています。
経年劣化によって多くの本体で同時多発的に起きている問題と思われ、私も借り物含め4台ほどの初期型GC全てでこの問題に悩まされました。
一時的な対処法(非推奨)
この問題に簡単に対処する方法としては、ディスクドライブの可変抵抗を低くする方法が知られています。
「ゲームキューブ 読み込み不良」検索上位の記事↓
ディスクを読まないゲームキューブを自分で修理してみた - 積みゲーマー死ねない
【修理徹底解説】ゲームキューブのディスクが読み込まないので、分解してレーザー出力調整してみた | 英二六ブログ
しかし、これらの方法で読み込めるようにしても、数か月~1年程度使っていると再びディスクを読み込まなくなってしまいます。
根本的な対処法
以下の動画で紹介されています。
詳しいことは動画本編を見てもらえばいいのですが、少しだけ説明。
- 読み込み不良の原因は、コンデンサーの劣化によるレーザーの出力不足。
- 可変抵抗による修理は、レーザーの出力を上げて延命していただけ。
- コンデンサーを取り換えることで、抵抗値を従来の値に戻しても問題無く読み込めるようになる。
交換手順は私は説明できないので、動画や他の方のブログ記事などを参考にしてください。自己責任でお願いします。
なお、本記事投稿時点でこれらの動画はGoogle検索の上位に出てきません。(Youtubeでは検索上位に出ているが。)
ということで、本記事投稿のメインの目的は上記の動画への動線を増やすことだったりします。
その他の代替策
GBIやSwissの専用機としてGCを使っている場合、ディスクドライブを復活させる以外にも複数の起動方法があります。いずれもゲームディスクからSave Exploitするより早く、便利に起動できるようになります。
2025年現在、入手しやすいものは以下の2つです。(GC LoaderやCubeODEは入手困難という認識)
picoboot
特徴
- はんだ付けが必要。
- 起動時に好きなソフトを直接起動できる。
- 費用は1500-2000円程度。(セットでSDGeckoまたはSD2SP2もついてくる。)
biosの画面すら飛ばして即好きなソフトを起動できるため、非常に快適な環境になります。はんだ付けが得意な人ならコンデンサ交換の代わりにこちらだけ導入すればいいかもしれません。
導入記事:【GCハード改造】Picoboot導入記事 - 聖域跡地(仮)
FlippyDrive
特徴
- はんだ付け不要。
- 通常起動後、SDカードのファイルを直接指定して起動できる。
- 費用は約10000円。
- かなり長納期。
ゲームキューブ本来のbios起動後にディスクドライブをエミュレーションしているため、picobootと比べると自由度は低いようです。価格も高めですが、はんだ付け無しで起動する貴重な手段です。
picoboot買ってはんだ付けをココナラとかで外注した方が早くて安くて快適かも。
余談
調べてみたら割と初期からコンデンサ交換してた人もいるみたいです。
しかし読み込み不良修理の検索に全く引っかからず誰も気づかなかったという……。
GBギャラリー4 自己ベスト一覧
ある程度真面目にやったやつだけ載せます。
1000点超えた段階で満足してやめたのもありますが。
まるごと保存・復元は本ゲーム起動中1度も使っていません。
2025/11/08追記:現在VCのデータを吸い出してGBIでプレイしています。GBIで新しく出した記録を右側にカッコで併記します。
FIRE
いま - やさしい:1034
いま - むずかしい:928(1982)
いま - すごくむずかしい:357(984)
むかし - やさしい:669(1026)
むかし - むずかしい:691(2701)
ギャラリー1の3DSVCでいま版すごくむずかしい9999点達成済み。
DONKEY KONG 3
いま - 1P:1030
むかし - 1P:1000
1000点でやめたシリーズ。
特に難しい要素は無い。
DONKEY KONG JR.
いま - やさしい:1047
いま - むずかしい:774(1200)
むかし - やさしい:266(855)
むかし - むずかしい:277(534)
むかし版むずい。
MARIO'S CEMENT FACORY
いま - やさしい:1000
いま - むずかしい:1002
むかし - やさしい:1000
むかし - むずかしい:1000
1000点でやめたシリーズ。
むかし版はスペランカーみたいに落ちたら4ぬのでちょっと難しいが、安定取ればわりといける。
RAIN SHOWER
いま - やさしい:1397
いま - むずかしい:1148
むかし - やさしい:1584
むかし - むずかしい:640
むかし版GAME Bではカラスが勝手に紐を動かしてくるのでストレスがすごい。
GAME Aの1584はかなり上振れた。
BOXING
いま - 1P:15
むかし - 1P:16
15点(☆5)でやめたシリーズ。
特に難しい要素は無い。
CHEF
いま - やさしい:1370
いま - むずかしい:1568
いま - すごくむずかしい:279
むかし - やさしい:805
むかし - むずかしい:995
いま版はヨッシーが大きくなる時やタマゴを産む時など、動きが止まって食べてくれない場合がある。これがものすごいストレス。
こういう目に見えづらい余計な要素をゲムヲ系ゲームに持ち込むな。
むかし版GAME Bでギリギリ1000点行けてないの悔しい。
FIRE ATTACK
いま - やさしい:1009
いま - むずかしい:1907
むかし - やさしい:650(792)
むかし - むずかしい:493
むかし版はまあまあ難しいが、出てきた順に対応すればいいだけなのでFIREよりはやりやすい印象。でもそんなに頑張ってないので低スコア。
OCTPUS
いま - やさしい:1026
いま - むずかしい:1003
むかし - やさしい:843(2048)
むかし - むずかしい:772(1710)
むかし版けっこう頑張って1000点目指したけど、どっかでやらかす。こまめに戻るのと宝取り続けるのどっちがいいのかね?
DONKEY KONG
いま - やさしい:1004
いま - むずかしい:1000
むかし - やさしい:940
むかし - むずかしい:571
むかし版の2段目が苦手。
MARIO BROS.
いま - やさしい:1651
いま - むずかしい:1158
いま - すごくむずかしい:1644
むかし - やさしい:575(4408)
むかし - むずかしい:598(1170)
ギャラリー3のSwitchOnlineでむかし版GAME B 9999点達成済み。
MANHOLE(以下、いま版無し)
むかし - やさしい:5376(9999)
むかし - むずかしい:2981(9999)
一番遊んだゲーム。
時々Aボタンが2回反応してしまい、それが原因でミスることがある。ソフト側の問題か僕が使ってるWiiUの問題か不明。(追記:WiiU側でした。GBIでは発生していません。)
ギャラリー1の3DSVCでむかし版GAME B 9999点達成済み。
PARACHUTE
やさしい:1148(2846)
むずかしい:(1109)
むずかしい最高速度で木に引っかかったのが落ちてくるとき、ありえん速さで落ちるから常に警戒しないといけない
BOMB SWEEPER
むずかしい:3160
パターン全暗記したらどのくらいいけるのか気になる。
進めるほど残り時間が短くなっていくので、どこかで操作が間に合わなくなりそう。
CLIMBER
2237
操作をいくらでも早くできるアクションゲーム。
スピード感があって気持ちいい。
ZELDA
9999
周を重ねると敵の体力増えてちょっとずつ大変になる。
でもそんなに難しくない。
DQ1RTA 竜王乙ってメッセージ速度1で不思議実持ってて吟味する場合について考えてみた
タイトル長いけど普通によくあるシチュエーション
今回比較するパターン
パターン①:セーブ後即リセットしてメッセージ速度を変えてから吟味開始
パターン②:セーブ後吟味して、成功ならセーブ&リセットしてメッセージ速度を変える(失敗ならリセしてパターン①と合流)
前提
メッセージ速度は絶対8にする(タイム差知らないけど、単純化のため)
吟味成功後はセーブせずに竜王城に向かう
計測
セーブから会話終了まで 2.1秒
不思議実使用からセーブまで 4.9秒
吟味失敗ロス 1回あたり18.2秒
計算結果
パターン②を使う場合のパターン①との差分
・1回目成功→7秒ロス
・1回目失敗→2回目の挑戦時点で16.1秒のアドバンテージ
結論
4吟味でも5吟味でもパターン②の方が期待値早そう
HPバーの計算式
ごあいさつ
こちらは Pokemon Past Generation Advent Calendar 2024 3日目の記事です。
「ネタあるけど枠埋まってるからいいや」と思ってたら空いたので入れさせていただきました。
結論
- 少なくとも3-5世代においては、HPバーの長さは48ピクセル。*1
- 少なくとも3世代においては、"現在HP/最大HP*48(小数点以下切捨て、0以上1未満は1)"がHPバーの長さになると思われる。*2
- バーの長さを判別するためには、なるべく高解像度でキャプチャして上からこのように画像をのせてやるのがおすすめ。(私の環境ではどうしてもちょっと滲む。)

結論から話せとこの間小学校で習ったので結論から言いました。計算式は適当に仮説立てて計算したら一発で当たったので、特に紆余曲折とか無いです。
HPが49以上の敵に関しては1ピクセルの中に複数のHPが入っていることがあります。その場合は正確に特定することはできません。
HPバーと向き合うことにした背景
敵のHPバーには数値が表示されないのですが、RTAでは正確な数値を知ることで戦略を変えたいという場面がちょくちょくあります。
(例)「PP節約のため、確実に倒せるなら弱い技で代用したい」「低威力の命中安定技で倒せるか知りたい」「効果抜群・いまひとつのテキストを出したくないので、等倍技で倒せるか知りたい」「敵の回復ラインに入らないよう調整したい」等
しかし、ネットで調べてもHPバーの仕様に関する記事は見つかりませんでした。
ということで、以前は仕方なくエミュで一個一個調べては比較画像を作り、目印を覚えて判別していました。

これでは比較画像作りも面倒だし、覚えるのも大変です。
ちなみに日本版はまだマシで、英語版では文字が左右にキュッとまとまってるので目印がなくなってさらに判別し辛いです。無理ゲーです。

ということで、
- できれば計算式を特定して計算だけで分かるようにしたい。
- 英語版でも現実的に見分ける手段が欲しい。
と思い考えた結果が上記の結論です。
これ乱数とか対戦とかやってる人にとって役に立つんですかね?ナイトヘッドでHPの個体値判別するとかならできるかなあ。
おわりに
個人的に、ポケモンwiki等で手に入らなくて困っている情報はまだあります。
例えば、ダメージ計算式の持ち物補正・ランク補正・バッジ補正がどの順番でかかるのかが分かりません。順番が変わると端数処理の関係でダメージが変わってくるので割と重要です。確定だと思ってたら実は乱数15/16でしたーなんてこともあり得るので。
こういったことも気が向いたときに調べて共有できたらいいなと思います。*4
いつか自分で解析できるようになりたいなあ。
終わり。
明日はサイファー氏によるポケスタ2の乱数についての記事です。