このエントリーをはてなブックマークに追加
スポンサーリンク

タイマーBIOS

タイマーBIOS

タイマードライバーは、内臓のタイマーで55ミリ秒ごとにINT 08Hを発生させてタイムをカウントしています。また、同時にINT 1CHも発生させています。INT 1CHは割り込みベクタアドレスの先頭にRTIが書かれており、通常は何もしません。INT 1CHの割り込みベクタアドレスを書き換える事で独自のタイマー割り込み処理を作る事もできます。

INT 08Hでは、メモリーアドレス0040H:006CH〜0040H:006FHの32ビットのエリアを使ってカウントアップしています。午前0時ちょうどを0とし、翌日の午前0時になると再び0になります。MS-DOSではこの値から現在の時刻を計算しています。

また、24時間以上経過すると、24時間フラグ0040H:0070Hが1になります。

INT 1AH

タイマードライバーに対しては、パラメーターをセットした後、INT 1AH割り込みを発行する事で呼び出す事ができます。J-3100独自の拡張命令については、「このファンクションはDCGA専用です」という注意書きがあります。
AH=00H 内部タイマーリード
入力 出力
AH 00H AL 24時間フラグ
CX:DX タイマー値
内臓のタイマーを読みます。午前0時0分0秒から、なん55ミリ秒(時×65543 + 分×1092 + 秒×18.2)経過したかがセットされます。ALレジスタには24時間フラグがセットされます。

具体的には、
 AL に 0040H:0070H
 CX に0040H:006EH〜0040H:006FH
 DX に0040H:006CH〜0040H:006DH
の値がレジスタにセットされます。
AH=01H 内部タイマーセット
入力 出力
AH 01H
CX:DX タイマー値
内臓のタイマーを変更します。24時間オーバーの値(0018H:00AFH以上の値)を設定しないようにしてください。また、内臓タイマーを変更した時は、リアルタイムクロックも変更しないと、リアルタイムクロックと内臓クロックの示す時刻が合わなくなります。
AH=02H リアルタイムクロックの読み込み
入力 出力
AH 02H CH 時
CL 分
DH 秒
DL サーマータイム
  00Hなし
  01Hあり

CF=1でリアルタイムクロックなし
リアルタイムクロックを読み込みます。時刻はBCD形式で読み込まれます。
BCD形式
BCDとは、Binary-coded decimal の略で4ビットで10進数の1桁を表す方式です。この形式で19表すときは19Hとなります。このままでは25になってしまうので、変換が必要です。

BCD形式から16進数への変換は、上位4ビットは4回右シフト(SHR)、下位4ビットは15(00001111)とANDを取って抽出して、(上位4ビット×10)+下位4ビットで変換できると思います。*1

16進数からBCD形式への変換は、上の桁は10で割った商、下の桁は10で割った余りで抽出して、まず上の桁をセットして4回左シフト(SHL)してから下の桁とORを取れば変換できると思います。*1

*1 「思います」というのは、実を言うと全然検証しておりませんで、正しいかどうかは各自で確認してください。
AH=03H リアルタイムクロックの設定
入力 出力
AH 03H
CH 時
CL 分
DH 秒
DL サーマータイム
  00Hなし
  01Hあり
リアルタイムクロックを設定します。時刻はBCD形式でセットします。

内臓タイマーと同時に設定しないと、リアルタイムクロックと内臓クロックの示す時刻が合わなくなります。MS-DOS配下では、できる限りBIOSで直接クロックを操作せずに、MS-DOS割り込み(AH=2DH、INT 21H)を使ってください。
AH=04H 日付のリード
入力 出力
AH 04H CH 年(の上2桁)
CL 年(の下2桁)
DH 月
DL 日
CF=1でリアルタイムクロックなし
リアルタイムクロックを読み込みます。日付はBCD形式で読み込まれます。
AH=06H セットアラーム
入力 出力
AH 06H
CH 時
CL 分
DH 秒
CF=0 正常終了
CF=1 既にセットされている
このファンクションはDCGA専用です。アラームをBCD形式でセットします。設定した時刻になると、INT 4AHが発生します。

という事は、割り込みが発生した時にはINT 4AHの割り込みベクタアドレスに、ちゃんと割り込み処理ルーチンが常駐してないといけません。でないと、設定時刻になると暴走します。(というウイルスを仕込むつもりなら話は別ですが) INT 4AH割り込みの最後はIRETで終わらせてください。
AH=07H リセットアラーム
入力 出力
AH 07H
このファンクションはDCGA専用です。AH=06Hでセットしたアラームを解除します。

MS-DOS割り込み INT 21H

BIOSで内臓タイマーを操作すると、リアルタイムクロックとの値が不一致になる可能性があり、またBCD形式に変換しなければならなかったりと、いささか面倒です。そこで、MS-DOS環境下ではできる限り直接BIOSを操作せずにMS-DOS割り込みを使用してください。

MS-DOS割り込みを使うためには、以下のパラメーターをセットした後、INT 21Hを発行します。
AH=2AH 日付のリード
入力 出力
AH 2AH AL 曜日
CX 年
DH 月
DL 日
リアルタイムクロックを読み込みます。MS-DOSの方でちゃんとBCD形式を16進数に変換してくれます。また、曜日を計算してALレジスタにセットしてくれます。(0=日曜日、6=土曜日)
AH=2BH 日付のセット
入力 出力
AH 2BH
CX 年
DH 月
DL 日
AL エラーステータス
 00H 正常終了
 FFH 日付が正しくない
リアルタイムクロックを設定します。 BCD形式で設定しなければならないBIOSに比べ、 16進数で指定できるので、MS-DOS割り込みを使った方が設定が格段に楽です。 ただし、1980年〜2038年までしか設定できません。 これは、大抵の32ビットシステムでは2038年までしか日付を扱うことができないためです。
AH=2CH 時刻のリード
入力 出力
AH 2CH CH 時
CL 分
DH 秒
DL ミリ秒
現在時刻を読みます。MS-DOSの方でちゃんとBCD形式を16進数に変換してくれます。また、内臓タイマーを読んでミリ秒をDLレジスタにセットしてくれます。
AH=2DH 時刻のセット
入力 出力
AH 2DH
CH 時
CL 分
DH 秒
DL ミリ秒
現在時刻を設定します。16進数で指定できるのと、リアルタイムクロックと内臓タイマーの両方を矛盾しないように設定してくれるので楽です。

というように、MS-DOS配下ではBIOSを直接操作するよりDOS割り込みを使った方が全然楽ですので、DOS割り込みを使いましょう。じゃあLinux配下ではどうするんだ?という方がいるかもしれませんが、Linux配下の開発環境では標準でclock_settime、clock_gettime、time、等の関数が用意されているので、特にBIOSを直接操作する必要もないと思います。

参考文献
『J-3100解析ハンドブック』 1989年 土屋勝著 ナツメ社
『DOS/Vテクニカル・リファレンス・マニュアル』 1993年 芦達剛著 ソフトバンク
『J-3100シリーズ・テクニカルマニュアル』 1994年 南部武彦著 ソフトバンク
『ATOK読本』 1994年 山田祥平 ジャストシステム
『東芝パソコンハンドブック94年版』 平成6年3月1日
スポンサーリンク