2014年1月24日金曜日

ぺけ-BASICの外部関数のバグについて&ぺけ-BASIC v0.02.002

X-BASIC for iOSの元になったぺけ-BASICは、外部関数にもバグがいるようです(教えていただきました)。

X-BASIC for iOSは、本体こそぺけ-BASICのソースを解析した結果を元に作っていますが、外部関数はX-BASIC/68の仕様を元に完全に一から書き上げたので、気がつきませんでした。

関数名 dskf()
バグ 大容量メディアに対して使った場合、リターン値が正しくないことがある。
詳細 この関数はDOSコールの_DSKFREの返す値を
使用可能なクラスタ数.w * クラスタ当りのセクタ数.w * セクタ当りのバイト数.w
と乗算してリターン値を作っていますが、ここで使っている68000の命令がすべてmulu.w =.w*.w->.l演算であるため、3つ目の乗算で.lで得られた値の.w部分のみ使ってしまい、 このバグが発生します。
要するに、使用可能なクラスタ数.w * クラスタ当りのセクタ数.w が16ビットで収まらない ような大容量デバイスに対して使用すると、バグります。
iOS版での状況 iOS版には存在しない関数です。

関数名 fread()/fwrite()
バグ リターン値が、X-BASIC/68は読み書き出来た「要素数」であるのに対し、 ぺけ-BASICではバイト数が返ってきています。
詳細 これはDOS _READ/_WRITEのリターン値をそのまま返しているためで、 リターン値を要素サイズで割る処理が抜けています。
iOS版での状況 iOS版は/68と同じく要素数を返します。 ちなみに、Cの関数であるfread()/fwrite()も要素数を返します。

これら3つの外部関数とfloat変数の初期化バグ、および一部エラーが発生した時に OSがトラップを発生させるバグを修正したぺけ-BASICを一応作りましたので、ご入用の方は、「こちら」からどうぞ。

2014/01/26追記:
このバージョンで、68000機上で「未宣言変数があると落ちる」と言う報告をいただいています。
(68030では発生しないらしい。)
この問題は、オリジナル版をうちの環境でアセンブルした物でも発生するので、開発環境の差異による問題かもしれません。現在調査中です。しばらくお待ちください。
(直せない可能性も有り。)

2014/01/27追記:
どうやらこの問題はオリジナルからあるようです(と言うか、オリジナルでも発生しました)。
ワークエリアが足りない時も落ちます。
なので、私の追加した部分以外にも調査の手を広げる必要があるので、さらに時間がかかりそうです。(今余り時間が取れないので。というか、食が足りてなくてやる気が出ない方が強いかも。
差し入れ絶賛募集中。酒類も可^_^;)

2014/01/27追記2:
とか書きながら、ビール飲みつつ解析してたらバグを突き止められて修正。
ご褒美、絶賛受付中(^_^;)

2014/01/31追記:
まだトラップが発生するという報告があります。
68030では発生せず68000だけということですが、当方では68000でも発生せず原因不明です。

2014/02/05追記:
問題はBASIC本体側ではなく、FM音源ドライバを組み込んでいないのにMUSIC.FNCを組み込んでいたためわかりました。と言うことで、ここの公開版は問題なしです。
でも、起動時や正常終了時にはエラーが発生せず、エラー時のみ引っかかるのかは、さらなる解析が必要そう。