はじめに
X68kのメーカー純正のソフトウェアの不具合をまとめてみました。環境を構築するとき、あるいはプログラミングなどで、参考になると思います。
ソフトウェアのバージョンを明記していないものは、その不具合の発生条件を満たすことができるすべてのバージョンに不具合があることを意味しています。
目次
Human68kの不具合
●サブディレクトリ内のファイルが増えたときファイルなどが壊れることがある
症状
MOやハードディスクなどの64MB以上のパーティションで、サブディレクトリの中のファイル数が増えたとき、パーティション内のごく一部のファイルやディレクトリが破壊されることがある。
発生条件
サブディレクトリのファイル数が増えてディレクトリ情報を記録するためのセクタを追加するとき、そのサブディレクトリがパーティション内で論理セクタ番号の上位16ビットが0以外で下位16ビットが0に近いセクタに配置されていて、直後のセクタが別のファイルやディレクトリで使用中だったとき、直後のセクタを使用していたファイルやディレクトリが破壊される。
不具合を故意に露顕させる手順の例(230MBのMOの場合)
(0) TwentyOne.xが常駐してない環境であること。
(1) 230MBのMOをFORMAT.Xでフォーマットし、217MBの領域を確保する。システムは転送しない(ここでDRIVE.Xで確認すると、「1セクタあたりのバイト数」が1024、「データ領域の先頭セクタ番号」が237になっている)。
(2) ルートディレクトリにサイズが65299KBのファイルを1個作る。
(3) ルートディレクトリにサブディレクトリを 1 個作る。
(4) ルートディレクトリに中身が0の並びでサイズが512バイト程度のファイルを1個作る。
(5) (3)で作ったサブディレクトリの中に適当なファイルを126個作る。
(6) (3)で作ったサブディレクトリの中に127個目のファイルを作ると、(4)で作ったファイルの中身が破壊される(127個目のファイルのディレクトリ情報が(4)で作ったファイルの中に書き込まれてしまう)。
原因
ディレクトリ内のファイルやサブディレクトリの数が増えてディレクトリ情報が現在使用しているセクタに入り切らなくなると、ディレクトリの延長が行われる。直後のセクタが未使用ならばそこを使うことになるが、直後のセクタが使用中だった場合は未使用のセクタを探してそこに新しいディレクトリ情報を書き込まなければならない。
ルートディレクトリの情報を書き込める領域は個々のパーティションの中で特定の場所に限られているので、ディレクトリを延長するときは必ず直後のセクタが使用される(ルートディレクトリのための領域が一杯になったらエラー)。
Human68kの中のディレクトリの延長を行うルーチンは、新しいディレクトリ情報を書き込むセクタを番号を決定する際に、ルートディレクトリかどうかの判定を「セクタ番号の下位16ビットがデータ領域の先頭のセクタ番号未満かどうか」で行っており、上位16ビットを無視してしまっている。ところが、例えば論理セクタのサイズが1セクタ=1024バイトならばパーティションの先頭から64MB進んだ辺りに「セクタ番号の上位16ビットが0以外で下位16ビットがデータ領域の先頭のセクタ番号(230MBのMOならば237)未満になっている領域」が存在し、その領域内でサブディレクトリを延長しようとしたときにルートディレクトリの延長と誤認して無条件に直後のセクタに新しいディレクトリ情報を書き込んでしまうのだ。直後のセクタがファイルやディレクトリとして使用中ならば、そのデータが破壊されることになる。
対策
TwentyOne.x Ver 1.21以降を常駐する。TwentyOne.xがメモリ上のHumanにパッチを当ててルートディレクトリかどうかの判定を「セクタ番号の下位32ビットがデータ領域の先頭のセクタ番号未満かどうか」に修正してくれる。
メモ
TwentyOne.xを常駐していればデータが破壊されることはなくなるが、代わりに、前述の「バグを起こす手順」で126個目のファイルを書いた段階で、「サブディレクトリ内の'.'と'..'のエントリが二重に記録される」という症状が出るようだ(TwentyOne.x Ver 1.36cで確認)。実害はないが、サブディレクトリの構造としては間違っていると思われる。
●エラー$000Dが発生する
症状
X68030やXellent30の030モードで「エラー($000D)が発生しました」という白帯のエラーメッセージが表示され、プログラムの中止を余儀なくされる。
発生条件
X68030またはXellent30で浮動小数点コプロセッサ(拡張ボードを除く)を装着しており、030モード(使用中のMPUがMC68030)で、CONFIG.SYSにPROCESS=の指定があって、複数のスレッドが動作していて、少なくとも1つスレッドがコプロセッサ命令(浮動小数点命令)を使用している(gccで-m68881スイッチを指定してコンパイルしたプログラムなど)とき。
原因
Human68kのTimer-D割り込みによるスレッド切り替えルーチンではMC68030の「コプロセッサ命令途中割り込み」の存在が考慮されておらず、コプロセッサ命令の実行途中にも関わらずスレッドを切り替えてしまうことがある。コプロセッサ命令の実行途中にスレッドが切り替わると、MPUとコプロセッサの間の通信に支障をきたし、コプロセッサプロトコル違反(エラー$000D)が発生する。
浮動小数点コプロセッサをFLOAT4.Xを介してのみ使用している場合は、コプロセッサ命令がすべてスーパーバイザモードで使用されることになるのでコプロセッサ命令の実行中にスレッドが切り替わることはなく、コプロセッサプロトコル違反は発生しない。gccで-m68881スイッチを指定してコンパイルされたプログラムではユーザモードでコプロセッサ命令が使用されるため、そのようなプログラムを実行したときに他に動作中のスレッドがあると不具合が露顕する。
●サブのメモリ管理を使用すると暴走することがある
症状
サブのメモリ管理下で常駐したプロセスがサブのメモリ管理を開放した後に破壊されて暴走する。
発生条件
_S_PROCESSを使ってサブのメモリ管理を構築し、その内部でプログラムを常駐させ、_S_MFREEを使ってそのサブのメモリ管理を開放したとき。
原因
_S_MFREEでサブのメモリ管理を開放するとき、サブのメモリ管理下の常駐プロセスはメインのメモリ管理下に移ることになっているが、移行が正しく行われていない。具体的には、メモリ管理ポインタをサブからメインへ出る方向にだけ繋いでおり、メインからサブへ入る方向に繋いでいない。このため、サブのメモリ管理下で常駐したプロセスがメインのメモリ管理に組み込まれず、次回の_EXECなどで常駐部分が破壊される。
●X形式の実行ファイルのメモリアロケーションモードが一部機能していない
症状
X形式の実行ファイルのヘッダ4バイト目にあるメモリアロケーションモードの指定が期待通りに解釈されない。
$00 … 最大ブロックから確保
$01 … 必要最小ブロックから確保
$02 … 上位アドレスから確保
$01の「必要最小ブロックから確保」のコードが間違っており、$01が効かなくなっている。
メモ
この機能は未公開なので不具合と言うとやや語弊があるが、コードがおかしいことは間違いない。
以下の不具合は正確な発生条件が不明ですが、報告があったものです。
●仮想ディレクトリの展開に失敗することがある
仮想ドライブと仮想ディレクトリの実装の仕方そのものに無理があるとも言えます。
ROM(IPL/IOCS)の不具合
●電卓を使うと実行中のプログラムが誤動作することがある
発生条件
IOCS _B_KEYINP/_B_KEYSNS/_DENSNSを跨いでD3レジスタを使用しているプログラムで、電卓を使用したとき。
原因
電卓の処理でD3レジスタが破壊されるにも関わらず、IOCS _B_KEYINP/_B_KEYSNS/_DENSNSでD3レジスタが保護されていないため。
対策
KeyWitch.xを組み込むことでIOCS _B_KEYINP/_B_KEYSNS/_DENSNSでD3レジスタが保護されるようになる。
●IOCS _VDISPSTの1回目の割り込みのタイミングがおかしい
症状
IOCS _VDISPSTで垂直同期信号による割り込みルーチンを設定したとき、1回目の割り込みだけ、設定した割り込み間隔と関係のないタイミングで発生する。特にハードウェアリセットの後、初めてIOCS _VDISPSTを使用したときは、1回目の割り込みが発生するまでに4秒以上かかることがある。
原因
IOCS _VDISPSTがTimer-Aのカウンタを止めずにTimer-Aのカウントを変更しているため。
解説
ハードウェアリセットによってTimer-Aのカウンタは0(=256)に初期化され、IPL ROMのプログラムがTimer-Aをイベントカウントモード(垂直同期信号をカウントするモード)で初期化する。つまり、起動直後からTimer-Aは垂直同期信号をカウントしており、IOCSレベルで操作している限りはTimer-Aのカウンタは止まることがない(割り込みを止めてもカウンタは動き続けている)。Timer-Aを含むMFPのタイマは、動作中に新しいカウントを設定しても現在のカウントがオーバーフローするまでは現在のカウントを継続する仕様になっている。IOCS _VDISPSTはTimer-Aのカウンタを止めずに指定されたカウントをTimer-Aのカウンタに設定しているので、割り込み間隔を短く設定してもその時点でカウンタが大きな値になっていると1回目の割り込みが発生するまでに時間がかかり、最悪の場合4秒以上かかることがある。逆に、IOCS _VDISPSTで割り込み間隔を長く設定してもその時点でカウンタが0に近い値になっていると1回目の割り込みが早く発生してしまう。
●音源ドライバが誤動作することがある
発生条件
ROM version 1.3で起動時にチャイムを鳴らしたとき($00ED0091=$01でリセット)。
原因
起動時にチャイムを鳴らすとFM音源が初期化されていない状態で起動してしまうため、組み込み時にFM音源が初期化されていることを前提にしている音源ドライバが誤動作することがある。
●グラフィック関係のIOCSコールがリバースモードになったままになる
発生条件
IOCS _DRAWMODE($B0、拡張マニュアルに記述されているので未公開ではない)を、現在のモードを知るために-1を指定して使用したとき。
原因
IOCS _DRAWMODEの不具合。1回でも-1を指定するとリバースモードを解除できなくなる。
●ROM version 1.1で_MS_PATSTが正常に機能しない
対策
IOCS.Xを使用する。
●IOCS _MS_LIMITでY方向の範囲を1007までしか設定できない
●その他
・メインメモリが9MBのとき起動時に「09MB」と表示される
・ROM version 1.3の起動メッセージの「Memory Managiment Unit(MMU)」にスペルミスがある
FASTIO.Xの不具合
●デバイスドライバとして登録すると正常に動作しない
発生条件
FASTIO.X v1.00をデバイスドライバとして登録したとき。
原因
FASTIO.X v1.00をデバイスドライバとして登録すると、本来拡張しなければならないIOCSコール(B_WRITE/B_READ/B_FORMAT/B_EJECT)を拡張しない。この結果、IOCSコールに関する拡張機能(安全対策)が無効になる。
対策
コマンドラインで登録する。
●デバイスドライバとして登録するとき「バッファーサイズが正しくありません」と表示されて登録できないことがある
発生条件
FASTIO.X v1.00をデバイスドライバとして登録したとき。FASTIO.Xよりも手前にデバイスドライバを多く登録すると発生しやすい。
原因
デバイスドライバの末尾のアドレスが$00200000を超えないようになっているため。
対策
コマンドラインで登録する。
ASK68K.SYSの不具合
●SHIFT、CTRL、OPT.1の各キーが押されたままの状態になってしまうことがある
発生条件
ASK68K.SYS v3.01を使用しているとき、IOCS _B_KEYINPを使用するアプリケーションを実行するとSHIFT、CTRL、OPT.1のキーが内部でロックされた状態になることがある。
原因
ASK68K.SYS v3.01のSHIFT、CTRL、OPT.1の判定方法が、IOCS _B_KEYINPを他のアプリケーションが使用しないことを前提にしているため。
対策
ASK68K.SYS v3.02を使用する。KeyWitch.xなどのフリーウェアでも対策されている。
●ローマ字入力でL/M/R/V/W/Yを重ねて「っ」を入力できない
発生条件
ASK68K.SYS v3.01/v3.02を使用しているとき。フロントプロセッサを起動している状態では、ローマ字入力でL/M/R/V/W/Yを重ねても「っ」を入力できない。また、フロントプロセッサを起動していない状態でローマ字入力でL/M/R/V/W/Yを重ねると、その後のローマ字かな変換がおかしくなる。
例えば「ふっるーい」などの伝統的でない口語の日本語を入力しようとした場合。
対策
KeyWitch.xで対策されている。
●フロントプロセッサを起動するとINSキーのLEDが消えてしまう
発生条件
ASK68K.SYS v3.01/v3.02を使用しているとき、INSキーのLEDが点灯している状態でフロントプロセッサを起動したとき。
対策
KeyWitch.xで対策されている。
●機能名ZENKAKUの機能がローマ字無変換になっている
発生条件
ASK68K.SYS v3.01/v3.02を使用しているとき。
対策
KeyWitch.xで全角変換にすることができる。
HISTORY.Xの不具合
●ファイル名をTABキーで補完できないことがある
発生条件
HISTORY.X v1.10で確認。ディレクトリ名に拡張子を付けただけのファイルが存在するとき、そのディレクトリの中にあるファイルのファイル名をTABキーで補完できない。
COPYALL.Xの不具合
●動作と表示が一致しないことがある
BIND.Xの不具合
●バインドファイルの作成に失敗することがある
発生条件
BIND.X v1.00。仮想ディレクトリを使っているとき、バインドファイルを作るドライブと環境変数tempの指しているドライブのドライブ名が同じで実体が異なっている場合に、バインドファイルの生成に失敗する。
原因
ドライブ名が同じ場合はDOS _RENAMEだけでファイルを移動しようとしているため。
対策
環境変数tempに別のドライブ名のパスを設定する。
SPEED.Xの不具合
●メニュー画面でビット長を設定できないことがある
発生条件
RSDRV.SYS v2.02上でSPEED.X v2.10で確認。メニュー画面で、フロー制御をRTS、ビット長を5または7に設定すると、ビット長が6または8になってしまう。
対策
コマンドラインで
>SPEED B7 RTS
のように指定する。
ED.Xの不具合
●[EOF]が2つ表示されることがある
発生条件
ED.X v1.03で確認。[EOF]が画面最下行に表示されているとき、[EOF]の位置にカーソルを移動してからCTRL+M、CTRL+Zと入力すると、[EOF]が2行表示される。
メモ
実害はない。
FORMAT.Xの不具合
●メニューでフォーマットしたフロッピーディスクから起動できない
発生条件
FORMAT.Xのメニューで2.30と表示されるものでフロッピーディスクをフォーマットすると、そのフロッピーディスクがシステムディスクとして使用できない。
対策
コマンドラインでドライブ名を指定してフォーマットする。または、メニューで2.31と表示されるものを使う。
CACHE.Xの不具合
●キャッシュの状態を設定できないことがある
発生条件
COMMAND.X上で
>CACHE ON >NUL
のようにON/OFFの直後にスペースを入れて記述したとき、I/Dを指定しなければキャッシュの制御が行われない。
対策
ON/OFFの後にスペースを入れずに使うか、I/Dでキャッシュの種類を明記する。
SCD.Xの不具合
SCD.X(ソースコードデバッガ)には不具合がたくさんあります。
バージョンを明記していないものは、SCD.X v3.00とv3.01に共通の不具合です。
SCD.Xのほとんどの不具合は
SCD060.Xで修正されています。
●逆アセンブル結果と共にメモリ内容を表示するとき実効アドレスを間違える
発生条件
プレデクリメントモードのとき、または、フルフォーマットのベースレジスタまたはインデックスレジスタがサプレスされているとき。
インデックスレジスタの指定があるとき(v3.00のみ)。
●逆アセンブルするときPFLUSH/PLOAD/PTESTのイミディエイトオペランドの表示を間違える
症状
逆アセンブルするとき、PFLUSH/PFLUSHSの1番目および2番目のイミディエイトオペランドと、PLOADR/PLOADW/PTESTR/PTESTWの1番目のイミディエイトオペランドの表示が間違っている。
●FNOP/FBcc/FSAVE/FRESTORE/FBRAを正しく逆アセンブルできない
発生条件
SCD.X v3.00。
原因
FTRAPccの逆アセンブル用の文字列が欠落しているため。
●FDBcc/PDBccのオフセットの計算を間違える
症状
アセンブルするときは正しい値よりも2大きいオフセットを出力し、逆アセンブルするときは正しい値よりも2小さいアドレスを表示する。
●コンソールモードでテキスト画面の使用状態を変更してしまう
原因
フルスクリーンモードで!コマンドでシェルを呼び出すとき、その前後でテキスト画面の使用状態を変更するが、これがコンソールモードでも機能してしまっているため。
●例外スタックフレームを正しく表示できないことがある
原因
デバッグ中のプログラムがSCD.Xが与えたユーザスタックエリアをそのままスーパーバイザスタックエリアとして使用していると、例外が発生したときにその例外スタックフレームがSCD.X自身によって破壊されてしまい、例外スタックフレームの内容が正しく表示されないことがある。
●拡張子が.SYSの実行ファイルをロードできない
原因
強制的に.X形式でロードするためのモードの指定が間違っているため。
●アセンブルするときPTRAPcc #immにオペランドサイズを明記しないとオペランドなしのコードを出力する
●その他
・逆アセンブルするときTTnレジスタのサイズがワードになる
・STOP命令のサイズに.Bや.Lを指定してもアセンブルできてしまう
・NOPなどにサイズを指定してもエラーにならない
・Xコマンドのコマンド名と汎用以外のレジスタ名の間にスペースがあるとエラーになる
・Xコマンドで汎用以外のレジスタに設定する値をコマンドラインに書くとき、レジスタ名と設定値の区切りの判断の仕方がおかしい
・ベクタ$3D〜$3Fを復元しない
・例外発生時の浮動小数点レジスタの保護を行う部分のFSAVE/FRESTOREがキャンセルされている(v3.00のみ)。
・レジスタの一覧表示でDFCの表示がSFCの値になっている
辞書メンテ.Xの不具合
●辞書変換や辞書マージでハングアップすることがある
発生条件
SX-WINDOW v3.1に付属している「辞書メンテ.X」で、先頭の4文字が共通で5文字目以降が異なる読みの単語を大量に含んでいる辞書を生成しようとしたとき。
原因
ASK68K.SYS v3.0xの辞書はページの見出しが4文字しかなく、「ページ先頭の単語は異なるが見出しが同じ」というページが複数できてしまう場合の辞書メンテの処理がおかしい。ASK68K.SYS v2.xxの辞書のページの見出しは8文字なので、ASK68K.SYS v2.xx用からASK68K.SYS v3.0x用への辞書変換に失敗する。
対策
該当する単語を減らす。
XCのライブラリの不具合
●IOCTRLFDCTL()が正常に動作しない
発生条件
IOCTRLFDCTL()を使用しているプログラムをコンパイルし、XCのライブラリ(NewKitを除く)をリンクしたとき。XCのライブラリのv2.00にはこの不具合がある。v2.11(NewKit)では修正されている。
原因
ライブラリのコードが間違っている。
_IOCTRLFDCTL::
move.l 12(sp),-(sp)
move.w 10(sp),-(sp) ←14(sp),-(sp)が正しい
move.w 12(sp),-(sp)
move.w #13,-(sp)
DOS _IOCTRL
lea.l 10(sp),sp
rts
●IOCTRLRTSET()が正常に動作しない
発生条件
IOCTRLRTSET()を使用しているプログラムをコンパイルし、XCのライブラリ(NewKitを含む)をリンクしたとき。XCのライブラリv2.00とv2.11(NewKit)のいずれにもこの不具合がある。
原因
ライブラリのコードが間違っている。
_IOCTRLRTSET::
move.w 10(sp),-(sp)
move.w 8(sp),-(sp)
move.w #17,-(sp) ←#11,-(sp)が正しい
DOS _IOCTRL
addq.l #6,sp
rts
X-BASICの不具合
●配列変数に定数データ列を代入できない
症状
マニュアルには明記されていないが、配列変数に定数データ列をまとめて代入できる場所とできない場所がある。
発生条件
BASIC.X v2.02で、for〜next、repeat〜until、while〜endwhile、switch〜endswitchの内側(func〜endfuncのトップレベルを除く)およびif〜then〜else〜でスキップされるほうのブロックで、配列変数に定数データ列をまとめて代入できない。
対策
ぺけ-BASICを使う。
CV.Xの不具合
●.X→.Rの変換で必要な警告を出さない
メモ
仕様バグ。警告すべきときに警告しない。
発生条件
CV.X v2.00で、.X→.Rの変換で、実行開始位置が先頭でない場合、および、bss+stackセクションのサイズが0でない場合に、警告を出さない。
●エラーメッセージが間違っている
発生条件
CV.X v2.00で、text+dataのサイズが0の.Xファイルを処理しようとすると、「メモリが不足です」というメッセージが表示される。