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 に、対応している模様。
流石だ...