[osask 6834] BOARD:98 版のバグについて

このメールは、以下のOSASK-ML投稿フォームから書き込まれた内容です。
http://hideyosi.zive.net/~hideyosi_m/osask_ml/

お名前: Junkie98

FD直接ブート型の98版OSASK(Ver4.3)を、手元の実機(PC-9801NX/C 14.6M-RAM)で
起動したところ、動作しませんでした。OS実行イメージの逆アセンブル結果と、
公開されているソースコードを調べたところ、大きく見て2つの問題点がありま
した。


[問題点1]
 メモリが14.6Mバイト実装されている場合、16Mバイト以上のアドレス空間に対
しても、一旦書き込んだデータを読み出す方法によるメモリチェックを行なって
いる。しかし、1993年付近を境として、それより古い機種では、CPUが386DXや486
の場合であっても、アドレス線は24ビットしかデコードされていない。このため
16Mバイト以上の空間への書き込みが、実際には下位側16Mバイトの部分に対して
行われ、結果としてOS実行イメージは破壊、起動不能となる。

[対策1]
 98では、電源投入直後の自己診断によって得られたメモリ容量がワークエリア
に残される(ただし、DOSのHIMEM.SYSなどプロテクトメモリマネージャが常駐した
場合、メモリを確保したことを示すために、このワークエリアをクリアする)。
下位側の容量は、物理アドレス401Hに128Kバイトを単位としたバイト値で、上位
側は594H、595Hに1Mバイトを単位としたワード値で記録されているので、OS側で
のチェックは廃止し、これらの値を参照するのが良いと思われる。
OS内の該当部分に即して書けば、下位側は
  MOVZX ECX,BYTE PTR ES:[0401H]
  SHL   ECX,17 ;これは最初の1Mバイトを含むので、ADD ECX,1MBは不要
上位側は
  MOVZX ECX,WORD PTR ES:[0594H]
  SHL   ECX,20
によって、それぞれバイト単位の容量が得られる。また、設定メニューに「16M
システム空間」がある機種の場合、このワークにも設定内容が反映される。
 なお、上位側容量の595Hに関しては、サードパーティ製の拡張ボード上のROM
が何かの値を書き込むという情報がある。が、どうもV30時代の計測用ボードに
限った話のようなので、無視するというのも一つの方法かもしれない(こんなも
のは、たぶんNEC純正OSでも対応不可)。


[問題点2]
 PICのレジスタ操作によって割り込みをマスク後にキーボードをリセットし、
このリセットの結果として送られるキーコードの受信を保留したまま、PICの再
設定をしている。このため、CAPSキーのロックなど、キーボードのリセット後に
キーコードが発生する状況下では、「割り込みが保留中である」という情報が
PICから失われる一方で、割り込み自体は処理されないままとなり、ハンドラを
含めたキーボードインターフェース全体がデッドロック状態となる。また、この
現象はキーボードのみに限らず、「PICのマスク」から「PICの再設定」までの間
に割り込みが発生するような事象があれば、他のインターフェースに関しても、
デッドロック状態を引き起こす可能性がある。


[対策2]
 通常のDOSなどの環境のもとで、ダイレクトI/Oによるキーボードリセットを行
なってもデッドロックに至らないのは、すでに設定済みとなっているキーボード
割り込みハンドラが、発生するキーコードを受信するからである。したがって、
OSASK内部でも、割り込みハンドラの設定を行ない、割り込みを許可したあとで、
キーボードリセットを発行すれば、現在のキーロックの状態をも取得できるよう
になり、好都合と思われる。
 なお、IDTの初期化、PICの再設定のために割り込みを停止している間に発生す
る事象に対しては、CPU、PICなどの受け付け側によるマスクではなく、割り込み
発生側(キーボードなら8251)でマスクを行なうとよい。この場合、キーボードの
リセットは、単にキーボードのみを対象とし(8251はリセットしない)、また、リ
セット中にも受信割り込みを禁止しないでおく(コマンド値として、3AHではなく
3EHを使用)。そして、リセット完了以前に受信されたキーコードは無視し、完了
後のデータのみを使用すればよい。
 さらに、8251に関しては、全般にリカバリ時間が不足気味のように思われる。
このチップでは、入力されるバスクロック周期の数倍〜十数倍のリカバリ時間が
必要とされる。また、本体側でキーコード受信が完了したことを、キーボードが
確実に検出するための時間も、かなり必要である。この点で、OUT命令の直後と、
IN命令の直前には、それぞれ40μs前後のウェイトを入れるのがよい。OUT 5FH,AL
は、機種別のばらつきを入れた最小値が0.7μsほどなので、回数にすれば57回の
ループとなる。


--以上です。--


ML番号でジャンプ
ML単語検索