FC版未来神話ジャーヴァスは、ギルド内のバトルで負けると名声値が 1 下がり(ただし負にはならない)、さらに自軍の兵力が以下のように変化する:

  • 敗北後の名声値が 0 の場合、全ユニットの兵力が 0 になる。
  • 敗北後の名声値が 0 でない場合、志願兵、傭兵、グルカ兵の兵力が変動する。

後者のケースは本来「志願兵、傭兵、グルカ兵の兵力がそれぞれ 3/4 になる」仕様だったと思われるが、バグにより実際にはこれらの兵力が激増することがある。 なお、この現象は 2019 年には既に発見されていた模様。

このバグには以下の 2 つの誤りが関係している:

  • 兵力減少ルーチン内の計算ミス
  • 兵力減少ルーチンを呼び出す際の引数渡しのミス

まず兵力減少ルーチン ($F1DD) について述べる。このルーチンはバトルで負けた際に志願兵/傭兵/グルカ兵それぞれについて呼び出されている。コードを以下に示す:

;;; バトルに負けた際の兵力「減少」の計算。
; 引数
;       A       元の兵力上位
;       X       元の兵力下位
;
; 戻り値
;       A       結果の兵力上位
;       X       結果の兵力下位
L_F1DD:
        ; quarter = (元の値) / 4
        ; half    = (元の値) / 2
@quarter := $F0
@half := $F2
        stx     @quarter
        sta     @quarter+1
        stx     @half
        sta     @half+1
        .repeat 2
                lsr     @quarter+1
                ror     @quarter
        .endrepeat
        lsr     @half+1
        ror     @half

        ; XXX: ここで本来は quarter + half を返したかったのだろうが、実際には全く違う計算になっている。
        ; 戻り値下位は add((元の兵力上位), quarter & 0xFF) となる。
        ; 戻り値上位は adc(X, quarter >> 8) となる。
        clc
        adc     @quarter
        sta     @half
        tax
        adc     @quarter+1
        sta     @half+1

        rts

XXX コメントにある通り、このコードは元の兵力の 3/4 を返さない。たとえば元の兵力が 255 なら結果の兵力は 16191 となる。

XXX の箇所の計算式は、元の兵力を とおくと以下のように整理できる:

たとえば Rust では以下のように書ける:

fn decrease_force(f: u16) -> u16 {
    (f / 256 + f / 4).wrapping_mul(257)
}

兵力減少ルーチンについては以上だが、話はこれで終わりではなく、実際に志願兵 0 人、傭兵 255 人の状態でこのバグを試すと傭兵は 0 人になる。これは上記ルーチンの呼び出し側の引数渡しにもミスがあることが原因。呼び出し側のコード ($F175) を以下に示す:

force_irregular := $0411 ; 志願兵の兵力 (u16le)
force_mercenary := $0413 ; 傭兵の兵力 (u16le)
force_gurkha    := $0415 ; グルカ兵の兵力 (u16le)

L_F175:
        ; 志願兵の兵力減少処理。
        lda     force_irregular+1
        ldx     force_irregular
        jsr     L_F1DD
        sta     force_irregular+1
        stx     force_irregular

        ; 傭兵の兵力減少処理。
        lda     force_mercenary+1
        stx     force_mercenary ; XXX: stx は ldx の typo!
        jsr     L_F1DD
        sta     force_mercenary+1
        stx     force_mercenary

        ; グルカ兵の兵力減少処理。
        lda     force_gurkha+1
        ldx     force_gurkha
        jsr     L_F1DD
        sta     force_gurkha+1
        stx     force_gurkha

XXX コメントにある通り、傭兵については ldx とすべきところを stx と typo している。 つまり、傭兵の「元の兵力」は上位バイトのみが正しく、下位バイトは志願兵の変化後の兵力の下位バイトがそのまま引き継がれる。これによる兵力の変化例をいくつか示す:

  • 志願兵 0 人、傭兵 255 人なら志願兵は 0 人のままで、傭兵の「元の兵力」は 0 となり、傭兵は 0 人に変化する。
  • 志願兵 0 人、傭兵 256 人以上 511 人以下なら志願兵は 0 人のままで、傭兵の「元の兵力」は 256 となり、傭兵は 16705 人に変化する。
  • 志願兵 255 人、傭兵 0 人なら志願兵は 16191 人に変化し、これにより傭兵の「元の兵力」は 63 となり、傭兵は 3855 人に変化する。