4.9. 命名神解析

4.9.1. 解析
4.9.1.1. 「はなす」直後
4.9.1.2. 命名神の怒りに触れている名前の処理
4.9.1.3. 入力&チェック
4.9.1.4. 決定
4.9.1.5. 終了間際
4.9.1.6. サブルーチン $C3F186 - 現在の名前と入力した名前との比較ルーチン
4.9.1.7. サブルーチン $C3F1DF - オリジナルの名前かどうかチェック
4.9.1.8. サブルーチン $C3F214 - 予約キャラ名かどうかチェック
4.9.1.9. サブルーチン $C3F2A7 - 仲間の名前と重複しているかチェック
4.9.1.10. サブルーチン $C3F2F6 - 禁断の名前かどうかチェック
4.9.1.11. サブルーチン $C3F34A - 「ああああ」タイプかどうかチェック
4.9.2. データ
4.9.2.1. イベント用キャラクターの名前 ID 配列
4.9.2.2. 禁断の名前 ID 配列

ここでは、命名神の処理について述べる。 特に、変な名前をつけようと試みるときの展開に注目したい。

ゲントの村の海底にいる命名神に仕える神官等にはなしかけると、 命名神によってパーティーのメンバーの名前を変えることができる。 その処理はアドレス $C3E893 にある。 以下、アセンブリコードリストを読み解いていく。

4.9.1. 解析

4.9.1.1. 「はなす」直後

神官のしゃべり始めから、 名前を変えるキャラクターもしくはふくろを選択するところまでの処理を示す。

.routine  命名神処理
C3/E893:    08          PHP 
C3/E894:    C230        REP #$30
C3/E896:    48          PHA 
C3/E897:    DA          PHX 
C3/E898:    5A          PHY 
C3/E899:    8B          PHB 
C3/E89A:    F47E7E      PEA $7E7E
C3/E89D:    AB          PLB 
C3/E89E:    AB          PLB 
C3/E89F:    0073        BRK #$73            ■わしは 命名神マリナン様に[AD]つかえる神官じゃ。
C3/E8A1:    19
C3/E8A2:    22E980C3    JSR $C380E9         ■はい・いいえ
C3/E8A6:    9003        BCC $E8AB           if(いいえ){
C3/E8A8:    822C02      BRL $EAD7               goto 終了;
                                            }
.label  命名神::だれの?
C3/E8AB:    0074        BRK #$74            ■うむ では だれの名前を
C3/E8AD:    19          
C3/E8AE:    A9A500      LDA #$00A5          a = 00A5h;
C3/E8B1:    221BF0C3    JSR $C3F01B         ■だれウィンドウ表示&選択待ち
C3/E8B5:    9007        BCC $E8BE           if(cancel){
C3/E8B7:    2228B7C3    JSR $C3B728             ■ウィンドウ消去
C3/E8BB:    821902      BRL $EAD7               goto 終了;
                                            }
C3/E8BE:    CEB038      DEC $38B0           --$7E38B0;
C3/E8C1:    2228B7C3    JSR $C3B728         ■ウィンドウ消去
C3/E8C5:    8D3E30      STA $303E
C3/E8C8:    AA          TAX                 x = $7E303E;
C3/E8C9:    221C2BC4    JSR $C42B1C         ■(02FF) a = パーティの人数
C3/E8CD:    02FF
C3/E8CF:    48          PHA 
C3/E8D0:    AD3E30      LDA $303E
C3/E8D3:    C301        CMP $01,S
C3/E8D5:    9015        BCC $E8EC           if($7E303E >= パーティ人数){
C3/E8D7:    68          PLA                     // a == パーティの人数
C3/E8D8:    A90080      LDA #$8000              // ふくろとみなす
C3/E8DB:    8D4030      STA $3040               $7E3040 = 8000h;
C3/E8DE:    227AF3C3    JSR $C3F37A             ■名前が怒りにふれているかチェック
C3/E8E2:    9002        BCC $E8E6               if(carry){
C3/E8E4:    8029        BRA $E90F                   goto 怒りにふれておる;
                                                }
C3/E8E6:    007D        BRK #$7D                ■むう それは……ふくろか?
C3/E8E8:    19
C3/E8E9:    829B00      BRL $E987               goto ふくろの新しい名前は?;
                                            }
C3/E8EC:    68          PLA                 // パーティの人数
C3/E8ED:    8A          TXA                 a = x;
C3/E8EE:    22262CC4    JSR $C42C26         ■キャラ ID と関係あり??
C3/E8F2:    02FFFE
C3/E8F5:    8E4030      STX $3040           $7E3040 = x;
C3/E8F8:    227A5DC4    JSR $C45D7A         ●??
C3/E8FC:    FEFF
C3/E8FE:    C90200      CMP #$0002          // この判定がわからん
C3/E901:    D006        BNE $E909           if(a == 0002h){
C3/E903:    007C        BRK #$7C                ■むっ 他人の名前を 勝手に[AD]かえようと いうのか?
C3/E905:    19
C3/E906:    82C201      BRL $EACB               goto 他にだれか;
                                            }
C3/E909:    227AF3C3    JSR $C3F37A         ■名前が怒りにふれているかチェック
C3/E90D:    9078        BCC $E987           if(carry) goto ふくろの新しい名前は?

4.9.1.2. 命名神の怒りに触れている名前の処理

名前を変えたいキャラクターまたはふくろが、 既に命名神の怒りに触れている名前であるときの処理を示す。 紙面の都合で神官のセリフをかなり省略しているが、 怒りを鎮めるには 5000 ゴールド払えと言っているシーンだ。

.label  命名神::怒りにふれておる
C3/E90F:    008B        BRK #$8B            ■なんと! その名は 命名神の[AD]怒りに ふれておる!
C3/E911:    19
C3/E912:    A90300      LDA #$0003          a = 0003h;
C3/E915:    223672C3    JSR $C37236         ●??
C3/E919:    CEB038      DEC $38B0           --$7E3B80;
C3/E91C:    2262C3C1    JSR $C1C362         ●??
C3/E920:    008C        BRK #$8C            ■それで よいかな。
C3/E922:    19
C3/E923:    22E980C3    JSR $C380E9         ■はい・いいえ
C3/E927:    900A        BCC $E933           if(いいえ){
C3/E929:    008D        BRK #$8D                ■では やはり そのままじゃ。
C3/E92B:    19
C3/E92C:    220482C3    JSR $C38204             ■$7E3068-$7E33E7 ゼロクリア
C3/E930:    829801      BRL $EACB               goto 他にだれか;
                                            }
C3/E933:    A98813      LDA #$1388
C3/E936:    8D7A38      STA $387A           $7E387A = 1388h; // 5000d
C3/E939:    9C7C38      STZ $387C           $7E387C = 0000h;
C3/E93C:    2259EEC3    JSR $C3EE59         ●大小比較
C3/E940:    900A        BCC $E94C           if(carry){
C3/E942:    0090        BRK #$90                ■ん? ざんねんながら[AD]そんな大金は
C3/E944:    19
C3/E945:    220482C3    JSR $C38204             ■$7E3068-$7E33E7 ゼロクリア
C3/E949:    827F01      BRL $EACB               goto 他にだれか;
                                            }
C3/E94C:    A98813      LDA #$1388
C3/E94F:    8570        STA $70             $70 = 1388h;
C3/E951:    6472        STZ $72             $72 = 0000h;
C3/E953:    229528C4    JSR $C42895         ●引き算??
C3/E957:    70
C3/E958:    AD4030      LDA $3040
C3/E95B:    C90080      CMP #$8000
C3/E95E:    D005        BNE $E965           if($7E3040 == 8000h){
C3/E960:    A9C809      LDA #$09C8              a = 09C8h;
C3/E963:    800A        BRA $E96F               goto 支払い;
                                            }
C3/E965:    AE3E30      LDX $303E           x = $7E303E;
C3/E968:    22A14FC4    JSR $C44FA1         ■(02FEFF) a = キャラクタ x の現在の名前の文字列 ID
C3/E96C:    02FEFF
.label  命名神::支払い
C3/E96F:    8D285A      STA $5A28           $7E5A28 = a;
C3/E972:    227799C5    JSR $C59977         ■[D3]は 5000ゴールドを[AD]さしだした。
C3/E976:    8E19
C3/E978:    A90300      LDA #$0003          a = 0003h;
C3/E97B:    223672C3    JSR $C37236         ■ウィンドウ表示 or 準備
C3/E97F:    CEB038      DEC $38B0           --$7E38B0;
C3/E982:    008F        BRK #$8F            ■よろしい。では [B2]の[AD]新しい名前を 教えてくれ。
C3/E984:    19
C3/E985:    801D        BRA $E9A4           goto 名前入力;

4.9.1.3. 入力&チェック

まず例の名前入力用ウィンドウを表示する。

.label  命名神::新しい名前は?
C3/E987:    AD4030      LDA $3040
C3/E98A:    C90080      CMP #$8000
C3/E98D:    D005        BNE $E994           if($7E3040 == 8000h){
C3/E98F:    A9C809      LDA #$09C8              a = 09C8h;
C3/E992:    800A        BRA $E99E               goto 新しい名前を教えて;
                                            }
C3/E994:    AE3E30      LDX $303E           x = $7E303E;
C3/E997:    22A14FC4    JSR $C44FA1         ■(02FEFF) a = キャラクタ x の現在の名前の文字列 ID
C3/E99B:    02FEFF
.label  命名神::新しい名前を教えて
C3/E99E:    8D285A      STA $5A28           $7E5A28 = a;
C3/E9A1:    0075        BRK #$75            ■[B2]の名前をかえるのじゃな。[AD]では 新しい名前を
C3/E9A3:    19
.label  命名神::名前入力
C3/E9A4:    22D01BC3    JSR $C31BD0         ●??
C3/E9A8:    22E2CEC5    JSR $C5CEE2         ●ウィンドウの表示クリア??
C3/E9AC:    22C3EAC5    JSR $C5EAC3         ●??
C3/E9B0:    22932EC9    JSR $C92E93         ■$7E3888 ^= 000008h;
            88387E
            080000
C3/E9BA:    22E2CEC5    JSR $C5CEE2         ●ウィンドウの表示クリア??

ここから、プレイヤーが入力した名前をいろいろな方法で調べる処理が続く。 まずは、現在の名前と全く同じ名前を入力したかどうかを調べて、 もし同じなら「他に誰か~」処理へ移る。

C3/E9BE:    2286F1C3    JSR $C3F186         ■現在の名前と比較
C3/E9C2:    9006        BCC $E9CA           if(さっきと同じ名前){
C3/E9C4:    007E        BRK #$7E                ■なんじゃ 名前をかえないのか?
C3/E9C6:    19
C3/E9C7:    820101      BRL $EACB               goto 他にだれか;
                                            }

一度改名したキャラクターまたはふくろが、 元の名前を入力したかどうかを調べる。 キャラクターが主人公の場合、チェック用サブルーチンは何もしない。 元の名前と同じものが入力されていると判断したとき、神官のセリフがいつもと違う。 その後、名前を変更する。

C3/E9CA:    22DFF1C3    JSR $C3F1DF         ■オリジナルの名前かどうかチェック
C3/E9CE:    902B        BCC $E9FB           if(元の名前){
C3/E9D0:    0080        BRK #$80                ■ほう もとの名前に もどすと[AD]いうのじゃな。
C3/E9D2:    19
C3/E9D3:    22E980C3    JSR $C380E9             ■はい・いいえ
C3/E9D7:    9003        BCC $E9DC               if(いいえ){
C3/E9D9:    82A100      BRL $EA7D                   goto 他の名前に;
                                                }
C3/E9DC:    0081        BRK #$81                ■おお 命名神マリナンよ![AD][B2]の名を もとの
C3/E9DE:    19
C3/E9DF:    48          PHA 
C3/E9E0:    DA          PHX 
C3/E9E1:    5A          PHY 
C3/E9E2:    A9C608      LDA #$08C6              a = 08C6h;
C3/E9E5:    A20400      LDX #$0004              x = 0004h;
C3/E9E8:    A00200      LDY #$0002              y = 0002h;
C3/E9EB:    225BE0C6    JSR $C6E05B             ●??
C3/E9EF:    7A          PLY 
C3/E9F0:    FA          PLX 
C3/E9F1:    68          PLA 
C3/E9F2:    0082        BRK #$82                ■よし! おぬしの名は[AD][D8]に もどったぞ!
C3/E9F4:    19
C3/E9F5:    A20600      LDX #$0006              x = 0006h;
C3/E9F8:    82AC00      BRL $EAA7               goto commit のちょい先;
                                            }

次は「予約されている名前」との照合チェックだ。 キャラクターまたはふくろにこの名前をつけることはできない。 別の名前をつけるように神官に促されることになる。

C3/E9FB:    2214F2C3    JSR $C3F214         ■予約キャラ名かどうかチェック
C3/E9FF:    9006        BCC $EA07           if(carry){
C3/EA01:    007F        BRK #$7F                ■[D8]じゃな? ……むむっ[AD]命名神が その名は イカンと
C3/EA03:    19
C3/EA04:    827600      BRL $EA7D               goto 他の名前に?;
                                            }

次は仲間の名前との照合チェックだ。

C3/EA07:    22A7F2C3    JSR $C3F2A7         ■仲間と重複チェック
C3/EA0B:    9006        BCC $EA13           if(carry){
C3/EA0D:    0083        BRK #$83                ■[D8]じゃな…… おや?[AD]その名前の者が すでに
C3/EA0F:    19
C3/EA10:    826A00      BRL $EA7D               goto 他の名前に?;
                                            }

命名処理のハイライトであるチェック、 入力した名前と命名神の怒りを買う名前リストとの照合を行う。

C3/EA13:    22F6F2C3    JSR $C3F2F6         ■禁断の名前かどうかチェック
C3/EA17:    9039        BCC $EA52           if(carry){
C3/EA19:    0084        BRK #$84                ■[D8]じゃと…… おぬし[AD]本気で そのような名前を
C3/EA1B:    19
C3/EA1C:    22E980C3    JSR $C380E9             ■はい・いいえ
C3/EA20:    9002        BCC $EA24               if(いいえ){
C3/EA22:    8059        BRA $EA7D                   goto 他の名前に?;
                                                }
.label  命名神::怒りにふれても
C3/EA24:    0085        BRK #$85                ■命名神様の 怒りにふれても[AD]わしは しらんぞ!
C3/EA26:    19
C3/EA27:    22E980C3    JSR $C380E9             ■はい・いいえ
C3/EA2B:    9003        BCC $EA30               if(いいえ){
C3/EA2D:    824D00      BRL $EA7D                   goto 他の名前に?;
                                                }
C3/EA30:    0086        BRK #$86                ■……おお 命名神マリナンよ[AD]新たなる名 [D8]に[AD]神の祝福……うわっ!!
C3/EA32:    19
C3/EA33:    48          PHA 
C3/EA34:    DA          PHX 
C3/EA35:    5A          PHY 
C3/EA36:    A92A28      LDA #$282A              a = 282Ah;
C3/EA39:    A20400      LDX #$0004              x = 0004h;
C3/EA3C:    A00200      LDY #$0002              y = 0002h;
C3/EA3F:    225BE0C6    JSR $C6E05B             ●??
C3/EA43:    7A          PLY 
C3/EA44:    FA          PLX 
C3/EA45:    68          PLA 
C3/EA46:    A92A00      LDA #$002A              a = 002Ah;
C3/EA49:    2239F0C3    JSR $C3F039             ■効果音か
C3/EA4D:    0087        BRK #$87                ■見よ! いわんことでは ない!
C3/EA4F:    19
C3/EA50:    8052        BRA $EAA4               goto commit;
                                            }

チェックの最後は、入力した名前が 「同じ文字を 4 回繰り返すようなもの」であるかどうかを調べるものだ。 下のコードでわかるように、これは命名神の怒りを買う。

C3/EA52:    224AF3C3    JSR $C3F34A         ■「ああああ」タイプの名前かチェック
C3/EA56:    901C        BCC $EA74           if(carry){
C3/EA58:    0088        BRK #$88                ■[D8]じゃと…… おぬし[AD]名前というものを なめておるのか?
C3/EA5A:    19
C3/EA5B:    22E980C3    JSR $C380E9             ■はい・いいえ
C3/EA5F:    9011        BCC $EA72               if(いいえ){
C3/EA61:    0089        BRK #$89                    ■では 名をなめては おらぬが
C3/EA63:    19
C3/EA64:    22E980C3    JSR $C380E9                 ■はい・いいえ
C3/EA68:    9006        BCC $EA70                   if(いいえ){
C3/EA6A:    008A        BRK #$8A                        ■ならば ほかの名にすることじゃ。
C3/EA6C:    19
C3/EA6D:    8234FF      BRL $E9A4                       goto 名前入力;
                                                    }
C3/EA70:    80B2        BRA $EA24                   goto 怒りにふれても;
                                                }
C3/EA72:    80B0        BRA $EA24               goto 怒りにふれても;
                                            }

すべてのチェックをパスした後、神官がその名前でよいか確認する。 「いいえ」と答えれば、名前の入力に戻る。 「はい」だと、画面がフラッシュして、 神官が「名乗ることが許されたぞ」と言う。

C3/EA74:    0076        BRK #$76            ■うむ [B2]の名前を[AD][D8]に かえるのじゃな。
C3/EA76:    19
C3/EA77:    22E980C3    JSR $C380E9         ■はい・いいえ
C3/EA7B:    900E        BCC $EA8B           if(いいえ){
.label  命名神::他の名前に?
C3/EA7D:    007B        BRK #$7B                ■他の名前に かえるか?
C3/EA7F:    19
C3/EA80:    22E980C3    JSR $C380E9             ■はい・いいえ
C3/EA84:    9002        BCC $EA88               if(いいえ){
C3/EA86:    8043        BRA $EACB                   goto 他にだれか;
                                                }
C3/EA88:    82FCFE      BRL $E987               goto 新しい名前は?;
                                            }
C3/EA8B:    0077        BRK #$77            ■おお 命名神マリナンよ![AD]新たなる名 [D8]に[AD]神の祝福を!!
C3/EA8D:    19
C3/EA8E:    48          PHA 
C3/EA8F:    DA          PHX 
C3/EA90:    5A          PHY 
C3/EA91:    A9C608      LDA #$08C6          a = 08C6h;
C3/EA94:    A20400      LDX #$0004          x = 0004h;
C3/EA97:    A00200      LDY #$0002          y = 0002h;
C3/EA9A:    225BE0C6    JSR $C6E05B         ●??
C3/EA9E:    7A          PLY 
C3/EA9F:    FA          PLX 
C3/EAA0:    7A          PLY 
C3/EAA1:    0078        BRK #$78            ■よーし! これで [B2]は
C3/EAA3:    19

4.9.1.4. 決定

実際に名前が変更されるのは、神官のセリフの直後だ。 以下のコードから呼ばれているサブルーチンを解読することでわかったが、

  • 各キャラクターの名前の格納位置は、 $7E4025 構造体のインデックス 16h - 19h だ (1Ah#$AC をセットすると、ウィンドウ表示処理に不具合が生じる)。

  • ふくろの名前の格納位置は、 $7E3E98 から、文字コード #$AC が現れる直前までだ。

.label  命名神::commit
C3/EAA4:    A20600      LDX #$0006          // 入力した名前の文字コード (1 byte) を $70,X に assign 
                                            for(x = 0006h; x >=0; x -= 2){
C3/EAA7:    BD6D3B      LDA $3B6D,X
C3/EAAA:    9570        STA $70,X               $70,X = $7E3BD6,X;
C3/EAAC:    CA          DEX 
C3/EAAD:    CA          DEX
C3/EAAE:    10F7        BPL $EAA7           }
C3/EAB0:    AD4030      LDA $3040
C3/EAB3:    C90080      CMP #$8000
C3/EAB6:    D009        BNE $EAC1           if($7E3040 == 8000h){
C3/EAB8:    A27000      LDX #$0070              x = 0070h;
C3/EABB:    226679C4    JSR $C47966             ■$7E3E98,y = $00,x; for y in [0, 8)
C3/EABF:    800A        BRA $EACB               goto 他にだれか;
                                            }
C3/EAC1:    AD3E30      LDA $303E           a = $7E303E;
C3/EAC4:    224C50C4    JSR $C4504C         ■$7E4025 構造体 [16-19] = $70,X
C3/EAC8:    02FF70
.label  命名神::他にだれか
C3/EACB:    0079        BRK #$79            ■他に だれか 名前を
C3/EACD:    19
C3/EACE:    22E980C3    JSR $C380E9         ■はい・いいえ
C3/EAD2:    B003        BCS $EAD7           if(はい){
C3/EAD4:    82D4FD      BRL $E8AB               goto だれの?;
                                            }

4.9.1.5. 終了間際

特に変わったところはない。

.label  命名神::他にだれか
C3/EACB:    0079        BRK #$79            ■他に だれか 名前を
C3/EACD:    19
C3/EACE:    22E980C3    JSR $C380E9         ■はい・いいえ
C3/EAD2:    B003        BCS $EAD7           if(はい){
C3/EAD4:    82D4FD      BRL $E8AB               goto だれの?;
                                            }
.label  命名神::終了
C3/EAD7:    007A        BRK #$7A            ■そうか。名前をかえたくなったら[AD]いつでも 来るがよいぞ。
C3/EAD9:    19
C3/EADA:    AB          PLB 
C3/EADB:    C230        REP #$30
C3/EADD:    7A          PLY 
C3/EADE:    FA          PLX 
C3/EADF:    68          PLA 
C3/EAE0:    28          PLP 
C3/EAE1:    6B          RTL
@end

4.9.1.6. サブルーチン $C3F186 - 現在の名前と入力した名前との比較ルーチン

見落としてはいけないポイントは、 不定文字列データを表現する ID が存在するらしいということだ。 X レジスタにキャラクター ID をセットしてからすぐにサブルーチン $C44FA1 を呼ぶと、A/X/Y のどこかにその値が格納される。 このサブルーチンが取得する値は、文字列 ID の上限より大きい。

.routine  現在の名前と入力した名前との比較ルーチン
C3/F186:    08          PHP 
C3/F187:    C230        REP #$30
C3/F189:    48          PHA 
C3/F18A:    DA          PHX 
C3/F18B:    5A          PHY 
C3/F18C:    8B          PHB 
C3/F18D:    F47E7E      PEA $7E7E
C3/F190:    AB          PLB 
C3/F191:    AB          PLB 
C3/F192:    AD4030      LDA $3040
C3/F195:    C90080      CMP #$8000
C3/F198:    D005        BNE $F19F           if($7E3040 == 8000h){
C3/F19A:    A9C809      LDA #$09C8              a = 09C8h;  // ふくろの名前を表すための値
C3/F19D:    800A        BRA $F1A9               goto compare;
                                            }
C3/F19F:    AE3E30      LDX $303E           x = $7E303E;  // キャラクター ID
C3/F1A2:    22A14FC4    JSR $C44FA1         ■(02FEFF) a = キャラクタ x の現在の名前の文字列 ID
            02FEFF
.label  compare
C3/F1A9:    2246F1C3    JSR $C3F146         ■文字列 ID から文字列取得して $7E3000 に格納
C3/F1AD:    AD593B      LDA $3B59
C3/F1B0:    CD0030      CMP $3000           // 8 バイト長で比較
C3/F1B3:    D021        BNE $F1D6           if($7E3B59 == $7E3000){
C3/F1B5:    AD5B3B      LDA $3B5B
C3/F1B8:    CD0230      CMP $3002
C3/F1BB:    D019        BNE $F1D6
C3/F1BD:    AD5D3B      LDA $3B5D
C3/F1C0:    CD0430      CMP $3004
C3/F1C3:    D011        BNE $F1D6
C3/F1C5:    AD5F3B      LDA $3B5F
C3/F1C8:    CD0630      CMP $3006
C3/F1CB:    D009        BNE $F1D6
C3/F1CD:    AB          PLB 
C3/F1CE:    C230        REP #$30
C3/F1D0:    7A          PLY 
C3/F1D1:    FA          PLX 
C3/F1D2:    68          PLA 
C3/F1D3:    28          PLP 
C3/F1D4:    38          SEC                     // 名前は一致する
C3/F1D5:    6B          RTL                     return true;
                                            }
C3/F1D6:    AB          PLB 
C3/F1D7:    C230        REP #$30
C3/F1D9:    7A          PLY 
C3/F1DA:    FA          PLX 
C3/F1DB:    68          PLA 
C3/F1DC:    28          PLP 
C3/F1DD:    18          CLC                 // 名前は一致しない
C3/F1DE:    6B          RTL                 return false;
@end

4.9.1.7. サブルーチン $C3F1DF - オリジナルの名前かどうかチェック

紙面の都合上、逆アセンブル作業は読者への宿題とし、処理の解説の要点だけを述べる。

  • $7E3040 にキャラクター ID が格納された状態でサブルーチンがスタート。

  • ID == 0001h のとき、すなわち主人公のときは、CLC 状態で呼び出し元に戻る。

    • ID == 8000h のとき、すなわちふくろのときは、A レジスタに 00BFh をセット。 これは「ふくろ」の文字列 ID だ。

    • それ以外のときは、JSL $C92AB5 により、 $C8BD12 構造体の [00-01] から文字列 ID を取得。 A レジスタにセット。

  • JSL $C3F146 により、文字列 ID から文字列を取得して $7E3000 に格納。

  • サブルーチン $C3F186 における $C1F1A9 以降の処理へジャンプして、 [$7E3000, $7E3008) と [$7E3B59, $7E3B62) が一致するかどうかチェック。

4.9.1.8. サブルーチン $C3F214 - 予約キャラ名かどうかチェック

紙面の都合上、逆アセンブル作業は読者への宿題とし、処理の解説の要点だけを述べる。

  • 前半は、仲間キャラクターのオリジナル名のいずれかと一致していないかをチェックする。

    • For X in (0001h, 0052h) をキャラクター ID とする。 それぞれのオリジナルの名前を表す文字列 ID を $C8BD12[00-01] から取得、

      前項の要領で一致テスト。これをループ。

    • 一致するものが現れたら、SEC 状態にして呼び出し元へ戻る。

  • 後半は、イベントキャラクターの名前のいずれかと一致していないかをチェックする。

    • For X in [0000h, 001Dh) をイベントキャラクター名前 ID とし、 JSL $C92AB5 により、イベントキャラクター名前 ID 配列 $C58B2A から X の名前を表す文字列の ID を取得。

    • いつもの 8 バイト比較を行い、 マッチしたときに限り SEC して呼び出し元に戻す。

4.9.1.9. サブルーチン $C3F2A7 - 仲間の名前と重複しているかチェック

以下のようになっている。 「現在の名前の文字列 ID」を説明すると、 通常の文字列 ID の範囲より大きい値になっている。 サブルーチン $C3F146 はこのとき、 文字列を $FB8703 からではなく、 $7E4025 構造体の名前データを格納してあるアドレスから取得する。

.routine  仲間の名前とかぶっていないかチェック
C3/F2A7:    08          PHP 
C3/F2A8:    C230        REP #$30
C3/F2AA:    48          PHA 
C3/F2AB:    DA          PHX 
C3/F2AC:    5A          PHY 
C3/F2AD:    8B          PHB 
C3/F2AE:    F47E7E      PEA $7E7E
C3/F2B1:    AB          PLB 
C3/F2B2:    AB          PLB 
C3/F2B3:    221C2BC4    JSR $C42B1C         ●x = パーティ人数
            06FE
.label again
C3/F2B9:    CA          DEX                 --x;
C3/F2BA:    3034        BMI $F2F0           if(x < 0) goto 「ふくろ」と比較;
C3/F2BC:    22A14FC4    JSR $C44FA1         ■キャラクター x の現在の名前の文字列 ID を参照
            06FEFF
C3/F2C3:    2246F1C3    JSR $C3F146         ■文字列 ID から文字列を取得
C3/F2C7:    AD593B      LDA $3B59
C3/F2CA:    CD0030      CMP $3000           // 8 バイト長で比較
C3/F2CD:    D0EA        BNE $F2B9           if($7E3B59 != $7E3000) goto again;
C3/F2CF:    AD5B3B      LDA $3B5B
C3/F2D2:    CD0230      CMP $3002
C3/F2D5:    D0E2        BNE $F2B9
C3/F2D7:    AD5D3B      LDA $3B5D
C3/F2DA:    CD0430      CMP $3004
C3/F2DD:    D0DA        BNE $F2B9
C3/F2DF:    AD5F3B      LDA $3B5F
C3/F2E2:    CD0630      CMP $3006
C3/F2E5:    D0D2        BNE $F2B9
C3/F2E7:    AB          PLB 
C3/F2E8:    C230        REP #$30
C3/F2EA:    7A          PLY 
C3/F2EB:    FA          PLX 
C3/F2EC:    68          PLA 
C3/F2ED:    28          PLP 
C3/F2EE:    38          SEC                 // 仲間の誰かの名前とかぶる
C3/F2EF:    6B          RTL                 return true;
.label  「ふくろ」と比較
C3/F2F0:    A9C809      LDA #$09C8          // 文字列 ID 09C8h は「ふくろ」
C3/F2F3:    82B3FE      BRL $F1A9           goto compare;

4.9.1.10. サブルーチン $C3F2F6 - 禁断の名前かどうかチェック

サブルーチン $C3F2F6 を解読すると、 アドレス $C58AC8 に禁断名の ID の配列があることがわかる。

.routine  禁断の名前かどうかチェック
C3/F2F6:    08          PHP 
C3/F2F7:    C230        REP #$30
C3/F2F9:    48          PHA 
C3/F2FA:    DA          PHX 
C3/F2FB:    5A          PHY 
C3/F2FC:    8B          PHB 
C3/F2FD:    F47E7E      PEA $7E7E
C3/F300:    AB          PLB 
C3/F301:    AB          PLB 
C3/F302:    A23000      LDX #$0030          x = 0030h;  // 「ラスト」
.label again
C3/F305:    CA          DEX                 --x;
C3/F306:    3039        BMI $F341           if(x < 0) return false;
C3/F308:    22B52AC9    JSR $C92AB5         ■a = $C58AC8[x * 0002h]
            00
            0200
            C88AC5      // 禁断名の文字列 ID が格納されている配列
            0000
C3/F314:    2246F1C3    JSR $C3F146         ■文字列 ID から文字列取得
C3/F318:    AD593B      LDA $3B59
C3/F31B:    CD0030      CMP $3000           // 8 バイト長で比較
C3/F31E:    D0E5        BNE $F305           if($7E3B59 != $7E3000) goto again;
C3/F320:    AD5B3B      LDA $3B5B
C3/F323:    CD0230      CMP $3002
C3/F326:    D0DD        BNE $F305
C3/F328:    AD5D3B      LDA $3B5D
C3/F32B:    CD0430      CMP $3004
C3/F32E:    D0D5        BNE $F305
C3/F330:    AD5F3B      LDA $3B5F
C3/F333:    CD0630      CMP $3006
C3/F336:    D0CD        BNE $F305
C3/F338:    AB          PLB 
C3/F339:    C230        REP #$30
C3/F33B:    7A          PLY 
C3/F33C:    FA          PLX 
C3/F33D:    68          PLA 
C3/F33E:    28          PLP 
C3/F33F:    38          SEC                 // 入力は禁断の名前の一つである
C3/F340:    6B          RTL                 return true;
C3/F341:    AB          PLB 
C3/F342:    C230        REP #$30
C3/F344:    7A          PLY 
C3/F345:    FA          PLX 
C3/F346:    68          PLA 
C3/F347:    28          PLP 
C3/F348:    18          CLC                 // 入力は問題のない名前である
C3/F349:    6B          RTL                 return false;
@end

平仮名と片仮名の両方とも、命名神の怒りに触れるようになっている。 [7]

4.9.1.11. サブルーチン $C3F34A - 「ああああ」タイプかどうかチェック

アドレス $7E3B59 に選択キャラクターのための名前が格納されている。 サブルーチン $C3F34A は、この 4 文字の文字コードを比較するだけだ。

.routine 「ああああ」タイプの名前かチェック
C3/F34A:    08          PHP 
C3/F34B:    C230        REP #$30
C3/F34D:    48          PHA 
C3/F34E:    DA          PHX 
C3/F34F:    5A          PHY 
C3/F350:    8B          PHB 
C3/F351:    F47E7E      PEA $7E7E
C3/F354:    AB          PLB 
C3/F355:    AB          PLB 
C3/F356:    AD593B      LDA $3B59
C3/F359:    CD5B3B      CMP $3B5B           // 1 文字目と 2 文字目が違うか
C3/F35C:    D013        BNE $F371           if($7E3B59 != $7E3B5B) return false;
C3/F35E:    CD5D3B      CMP $3B5D           // 1 文字目と 3 文字目が違うか
C3/F361:    D00E        BNE $F371           if($7E3B59 != $7E3B5D) return false;
C3/F363:    CD5F3B      CMP $3B5F           // 1 文字目と 4 文字目が違うか
C3/F366:    D009        BNE $F371           if($7E3B59 != $7E3B5F) return false;
C3/F368:    AB          PLB 
C3/F369:    C230        REP #$30
C3/F36B:    7A          PLY 
C3/F36C:    FA          PLX 
C3/F36D:    68          PLA 
C3/F36E:    28          PLP 
C3/F36F:    38          SEC                 // すべて同じ文字
C3/F370:    6B          RTL                 return true;

C3/F371:    AB          PLB 
C3/F372:    C230        REP #$30
C3/F374:    7A          PLY 
C3/F375:    FA          PLX 
C3/F376:    68          PLA 
C3/F377:    28          PLP 
C3/F378:    18          CLC 
C3/F379:    6B          RTL                 return false;
@end

4.9.2. データ

データ量が少ないため、ここに直接記載する。

4.9.2.1. イベント用キャラクターの名前 ID 配列

重要なイベントキャラクターのすべての名前が定義されているわけではない。

イベントキャラクタ名 ID 配列 (2 バイト * 1Dh)
C5/8B2A:    8A09  // 00: ムドー
C5/8B2C:    7001  // 01: ターニア
C5/8B2E:    8B09  // 02: ランド
C5/8B30:    8C09  // 03: ビルデ
C5/8B32:    8D09  // 04: ルイーダ
C5/8B34:    8E09  // 05: マーズ
C5/8B36:    8F09  // 06: トム
C5/8B38:    9009  // 07: ジーナ
C5/8B3A:    9109  // 08: イリア
C5/8B3C:    9209  // 09: ホルス
C5/8B3E:    9309  // 0A: パノン
C5/8B40:    9409  // 0B: ミラルゴ
C5/8B42:    9509  // 0C: チャンプ
C5/8B44:    9609  // 0D: グラコス
C5/8B46:    9709  // 0E: ホック
C5/8B48:    9809  // 0F: サリイ
C5/8B4A:    9909  // 10: デュラン
C5/8B4C:    9A09  // 11: ゼニス
C5/8B4E:    9B09  // 12: フランコ
C5/8B50:    9C09  // 13: アクバー
C5/8B52:    9D09  // 14: トンヌラ
C5/8B54:    9E09  // 15: クリムト
C5/8B56:    9F09  // 16: マサール
C5/8B58:    A009  // 17: ムーア
C5/8B5A:    A109  // 18: ルビス
C5/8B5C:    A209  // 19: ラミアス
C5/8B5E:    A309  // 1A: セバス
C5/8B60:    A409  // 1B: オルゴー
C5/8B62:    A509  // 1C: エンデ

4.9.2.2. 禁断の名前 ID 配列

ふざけて入力されそうな単語の中から、 入力頻度のいかにも高そうなものを精選したリスト、 という印象を与える。

禁断の名前 (2 バイト * 31h)
C5/8AC8:    5B09  // 00: ちんこ
C5/8ACA:    5C09  // 01: きんたま
C5/8ACC:    5D09  // 02: ちんちん
C5/8ACE:    5E09  // 03: あほ
C5/8AD0:    5F09  // 04: ちんぽこ
C5/8AD2:    6009  // 05: へんたい
C5/8AD4:    6109  // 06: ちんぼ
C5/8AD6:    6209  // 07: ちかん
C5/8AD8:    6309  // 08: おめこ
C5/8ADA:    6409  // 09: まんこ
C5/8ADC:    6509  // 0A: おまんこ
C5/8ADE:    6609  // 0B: あそこ
C5/8AE0:    6709  // 0C: うんこ
C5/8AE2:    6809  // 0D: でべそ
C5/8AE4:    6909  // 0E: うんち
C5/8AE6:    6A09  // 0F: はなたれ
C5/8AE8:    6B09  // 10: おしっこ
C5/8AEA:    6C09  // 11: せっくす
C5/8AEC:    6D09  // 12: ばか
C5/8AEE:    6E09  // 13: おしり
C5/8AF0:    6F09  // 14: まぬけ
C5/8AF2:    7009  // 15: あなる
C5/8AF4:    7109  // 16: きちがい
C5/8AF6:    7209  // 17: チンコ
C5/8AF8:    7309  // 18: キンタマ
C5/8AFA:    7409  // 19: チンチン
C5/8AFC:    7509  // 1A: アホ
C5/8AFE:    7609  // 1B: チンポコ
C5/8B00:    7709  // 1C: ヘンタイ
C5/8B02:    7809  // 1D: チンボ
C5/8B04:    7909  // 1E: チカン
C5/8B06:    7A09  // 1F: オメコ
C5/8B08:    7B09  // 20: マンコ
C5/8B0A:    7C09  // 21: オマンコ
C5/8B0C:    7D09  // 22: アソコ
C5/8B0E:    7E09  // 23: ウンコ
C5/8B10:    7F09  // 24: デべソ
C5/8B12:    8009  // 25: ウンチ
C5/8B14:    8109  // 26: ハナタレ
C5/8B16:    8209  // 27: オシッコ
C5/8B18:    8309  // 28: セックス
C5/8B1A:    4D01  // 29: ばか
C5/8B1C:    8409  // 2A: オシリ
C5/8B1E:    8509  // 2B: マヌケ
C5/8B20:    8609  // 2C: アナル
C5/8B22:    8709  // 2D: キチガイ
C5/8B24:    8809  // 2E: すけべ
C5/8B26:    8909  // 2F: スケべ
C5/8B28:    7803  // 30: ラスト


[7] つまり、小池一夫風に「ん」を「ン」と書けば通る(e.g. ちンこ)。 これは、堀井雄二が小池一夫の門下生だという事実と関係があるのか─────ッ