2006.04.01)発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです)↑やりかた(基本)まず以下のような関数を考えます。これはCMOSメモリと呼ばれる領域を読み込むための関数です。CMOSメモリには主にBIOSの設定情報が記録されていますが、ここにRTC(リアルタイムクロック)の情報もあります。io_in8(0x71);}そしてCMOSメモリの以下の領域は、RTCになっています。RTC部分はRTC回路によって自動的に更新されています。年の上2桁ここで注意があります。このRTCの情報は16進数で表示すると普通に見えるようになっています。・・・どういうことかというと、たとえば秒の値が0x12の場合、これは12秒を意味しているのであって、18秒を意味しているのではありません。このような表現方法をBCDといいます。以上のすべての内容はBCDで表現されていますので、取り扱いには注意してください。BCDの数値を表示するだけなら、sprintfで%02Xを使えばいいでしょう。↑まともに使うにはこれだけでうまくいきそうに思えるかもしれませんが、実はダメです。プログラムが読み出し中にRTCの書き換えが起きることがときどきあって、それに遭遇すると、「12:34:59」の次が「12:34:00」になってしまったりします。いう場合はもう一度読むと「12:35:00」という正しい値が読み出せます。この書き換え中の読み出しによる問題を避けるためには、「2度読み」というテクニックを使います。上記7バイトを読んで変数に記録しておき、さらにもう一回上記7バイトを読んで先ほど読んだ値と同じかどうかを確認するのです。同じ値が読めればOKですが、値が違えばどちらかの読み出し結果が更新中のものだった可能性があるので、もう一度やり直します。2度読みの代わりに、1度しか読まずに前回取得の時刻と比較して、値が明らかにおかしければ読み込みなおすという方法もあります。これはかなり頭の良い方法といえますが、現在時刻の予測値が必要で、予測値があるのならそもそもRTCを読む必要があるのか少々疑問です(RTCはそれほど高速な回路ではないので、RTCを使わないで済むならそのほうが処理が高速になる)。まあOSが管理している内部時計の調節のためになら、2度読み以外の方法も使えるかもしれません。機種によってはときどきとんでもない値が2度連続で出てきます。秒が0xffなどです。そんな場合はもう一度読み直すべきです。2度読みによって取得できた秒や分が0x59以下であるかどうかとか(秒に関しては0x60もごくまれにありえますが:うるう秒のときに)、1のくらいが9以下であるかどうかなど、いろいろテストしておかしかったら2度読みをやり直すようにプログラムするといいでしょう。....}↑おまけ(時刻の取得だけじゃなくて設定もするぞ!)時刻表示したり時刻を利用するようなOSになると、時刻が狂っていて困ることがあるかもしれません。そんなときに再起動してBIOSや他のOSを使って時刻を設定するのはちょっとかっこ悪いかもしれません。そんなときはどうせなら自作OSで時刻設定もしてしまいましょう!まずはCMOSメモリに書き込む方法から。return;}これを使って秒から書き込んでいきます。設定しようとしているとしましょう。実はRTCが03:59:59で、あとほんの一瞬で秒が増えそうだとします。そんなときに時から書いていると、時を書いたところでRTCの時刻更新が始まって、13:00:00になり、そこへ分と秒を書いて結局13:34:56というとんでもない時間になってしまうかもしれないからです。秒から書いた場合、56を書いた時点でこの先3秒は分や時が更新されることは無いわけで、ゆっくりと分や時を設定できるというわけです。秒から書くにしても、たまにRTCとアクセスが衝突してうまく書き込めていなかった、なんていう場合があるので、書き込みの直後に上記の方法でRTCを読み出して設定値どおりかどうかを確認したほうがいいでしょう。確認するなら時から書いてもいいじゃないかと思うかもしれませんし、実はそのとおりなのですが(笑)、秒から書くほうが(設定が59秒でない限り)設定中に繰り上がり更新が発生する確率が減って(=設定が初回で成功する確率が上がって)、いいのではないかと思います。突き詰めると、まず最初に秒を0にしてそれから時から設定していけば、1分以内に設定が終わる限り時刻更新に悩まされることはありません。CMOSへの書き込みを一度増やしてまでこの問題を深刻に考えてもしょうがない気がするので、やはり秒から設定&確認で十分だと思います。要素の順番が逆なのと、配列の要素が7個しかないのに8までアクセスしようとしています。これだと無限ループ&配列外参照でまずいです。14:40:46ご指摘ありがとうございます。16:20:48サンプルソースが欲しいです。09:14:24上記以上のサンプルソースが必要だというのは、ちょっと疑問です。本当に本を最後まで読みましたか?このページは冒頭にあるように「読み終わった人」のためのものです。09:53:50既にお気づきかも知れませんが、「適当に作ったプログラム例」の呼び出し側関数(printtime)において、sprintfのフォーマット(時刻部分)に「X」が足りませんね。02:01:49おっとそのとおりでした。ご指摘ありがとうございました。08:47:46あの、Xの位置が違うと思います。13:03:55%02Xは16進2桁の数字を出力するためですよ。5とか1桁で%Xだと「5」になりますが、%02Xだと「05」になります。14:38:12再度修正しておきました。