このメールは、以下の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回の ループとなる。 --以上です。--