INT 13h (AH=41h)
そういうわけで、拡張 INT 13h を、実際に使ってみる。
やはり、実際に動かしてみるってのは、大事な事だ。
調べただけで理解したつもりでいても、大抵、やってみたらダメな事が多い。
いや、これは、頭の良い人なら違うのかもしれないけれど、少なくとも、僕の場合は、そうだ。
今回も、動くまでに、理解不足だった点や勘違いしている点が発覚した。
そういうわけで、とりあえず、コードは、こんな感じ。
; 拡張INT13H サポートチェック MOV AX, 0x4100 MOV BX, 0x55AA MOV CX, 0x0000 MOV DX, 0x0080 ; DL=ドライブ番号(0x80=HDD) INT 13h ; キャリーフラグチェック JNC chkbx MOV SI, biosngmsg CALL puts JMP fin chkbx: ; BXチェック CMP BX, 0xAA55 JE chkcl MOV SI, installngmsg CALL puts JMP fin chkcl: ; CLチェック CALL putregs chkok: MOV SI, okmsg CALL puts
入力するパラメータに関しては、問題なかった。
しかし、戻り値に関しては、随分と問題があった。
まず、キャリーがオンの場合は、BIOS自身が未サポート。
そんなサービス番号は知らないって事だ。
で、キャリーがオフの場合でも、安心してはいけない。
BXレジスタに [0xAA55] が戻される事になっている。
ここで、一つ、勘違いをしていた。
BXレジスタの入力は、[0x55AA]で、
BXレジスタの戻りは、[0xAA55]だ。
上位と下位が入れ替わっている点に注意が必要だ。
同じ値が返ってくるわけじゃないらしい。
何だか、とっても、いやらしい感じだ。
誰が決めた仕様だか知らないけれど、なかなかに、手が込んでいる。苦笑
そして、CLレジスタ(実際は、CXレジスタ全部?)は、各ビットをフラグとして使用しているので、
使用したい拡張サービスを含むフラグを調べる必要があって、
単純に、CL == 0x01 とか比較してしまうと、アウトだったりする。
CL & 0x01 とかして != 0x00 を調べる手順になるのかな?
また、AHレジスタには、メジャーバージョンが、DHレジスタには、拡張バージョンが戻されるらしい。
参考までに、実機で確認した数値は...
AX=0x3000 BX=0xAA55 CX=0x0005 DX=0x0080
となった。
CXのbit1がオフであるが、対象がATA-HDDであるわけなので、当然である。
bit1の意味する内容は、取り外し可能なドライブ制御機能である。
なるほど... <勝手に納得
ちなみに、HDの仮想イメージを作成し、QEMUでも試してみた。
一応、ちょっと驚きであったが、QEMUでも、拡張 INT 13h に、対応している模様。
流石だ...