お久しぶりです。
OS14日目、無事できました。
今回は「中間地点の後処理」といった感じでしょうか。
具体的には
・解像度UP
・キー入力対応
の2つですね。
解像度が大きくなるだけでもOS感がグッとアップ。うーん、感慨深い。
しかし、ここまでたどり着くまでにいくつか山を越えねばなりませんでした。
ソースを貼り忘れていましたw
こちらです。
まずはこの有様。
いやいや、この展開は早すぎるでしょ…
harib11dを参考に、VESAのファンクションを呼び出しただけなのに…
とりあえず冷静に。
確かVRAMのアドレスを変えていた。うん。そこでミスってる可能性が大きい。
0xe0000000から0x000a0000に戻してみよう。
なんですかこれはー!
調べてみると、0x000a0000のVRAM(VGAのVRAM?)は64KBしかないらしい。
うーむ。表現が稚拙というか不正確というか…。そこはお許しを。(できれば指摘してほしいな…)
【参考】
サポートウィキ:advance/QEMUVGA
それはおいといて、どうにかしてVRAMのアドレスってBIOSから取得できないのかなー
と思っていたら…
OS-Wiki:VESA
これこれ!これだよ!
参考にさせていただきながら苦労してソースを書き上げてコンパイル。
おおー!成功だ。
と思っていたら、同じ事を続きのharib11eでやっていた。なんかすごい疲労感…
でも、OS自作本ではアドレス0xe0000000でうまくいっているのに、なぜ僕の環境では
ブラックスクリーンなんだ。何がいけないんだ。
そこで、BIOSで取得したVRAMのアドレスを表示してみた。
それが最初のスクリーンショットだけどね。
0xf0000000…なぜだ…。
しかし調べてもよくわからない。Mona OSではVRAMのアドレスが0xf0000000になっている(?)
らしいが。
まあ、この課題はひとまず置いておこう。
そしてもうひとつバグが。
sprintf関数がおかしい。
適当に書いたのがいけないんだ!と過去の自分に愚痴ってもどうしようもないので、
書きなおした。バグはint2hex関数にあり。
lib.c
// 数値を16進数文字列に変換する
// flag: 大文字なら1, 小文字なら0
void int2hex(char *s, int value, int flag) {
int zero = 0; // 0以外の桁が出たかどうか
int filter = 0x0f; // 16進数で1桁だけ抽出するフィルタ
int i, n;
// 16進数のアルファベット
char alphabet = flag ? 'A' : 'a';
// 16進数はint型で最大8桁
for(i = 0; i < 8; i++) {
n = value >> (7-i)*4;
if(!zero && n != 0) zero = 1; // 初めて0以外の桁が現れたとき
else if(!zero) continue; // 0以外の桁が現れていないとき
// 桁が10~15なら'A'~'F'に変換
if((n & filter) >= 10) {
*s++ = alphabet + (n & filter) - 10;
} else {
// '0'~'9'に変換
*s++ = '0' + (n & filter);
}
}
*s = '\0';
}
これでOK。
こんな僕でも、なんとか14日目、中間地点に辿り着くことができました。
(1年近くかかってる気がするけどね!)
ここまででも、既にOSについていろいろ学べた気がします。
GDT、IDT、割り込み、なかなかヘビーな内容もありましたが、OS自作本の
解説とネット上の有志の方々による情報で乗り越えられました。
ここからマルチタスクやAPIなどに入っていき、特にシステムコールなどは
非常に実装したい気分ではあるんですが、如何せん受験勉強片手だと荷が重い。。。
この記事の内容も、2週間前にはもうできていたんですが、記事を書く時間もなく。
前々から言っていたとおり、この辺でいったんOSはお休みしようと思います。
もっと落ち着いてから、ゆっくりと再開するつもりです。
PR
COMMENT
No Title
URLを直接指定したらダウンロード出来たのですが。
で、UbuntuのQEMUで試しましたが、VRAMのアドレスが0xFD000000になってました。
VirtualBoxでも試しましたが、こちらは0xE0000000になってました。
Re:No Title
VRAMは、とするとホスト側の環境に左右されちゃうってことですかねえ。
もう少し調べてみましょうか。
他のテスト環境がなかったので、大変ありがたいです!