bluespearの「OS自作入門」勉強日記

2006-08-29

付録CDからのブート失敗 18:32

そういえば実機で一度も試したことが無かったので、30日終わったし試そうとしたら、上手く立ち上がりませんでした。

CPUAthlon64 3200+
MBASUS A8N-VM
チップセットnVIDIA GeForce 6100

立ち上がらないだけなら良かったのですが、BIOSの設定がおかしくなったのか、再起動した後もPS/2接続のキーボードマウスが効かなくなりました。仕方が無いので、CMOS Clearしました。ケース開けるの面倒だったぁ。PC周りがごちゃごちゃしてるので余計に。

幸いUSBマウスは効いたので、検索は出来ないもののHariboteOSのWikiを見て、Athlon64 X2だと上手くいかない例もあるみたいです。

ということで実機で試そうとする人はhttp://hrb.osask.jp/wiki/index.php?Athlon64X2 を見てからにした方が良いと思います。

三十一日目 開発を終えた後で 16:16

とりあえず万歳。やり遂げました。記念スクリーンショット撮ろうとしたら、Fotolifeが容量オーバーorz

三十一日目は、この先の開発例とか、オープンソースのすすめとかが書かれています。

この本の購入を考えている人は、はじめの方と、この三十一日目を立ち読みしてみるといいと思います。この本がどういうスタンスで書かれているかが、ズバリ書いてありますので。

ちなみに、http://hrb.osask.jp/wiki/index.php?advance に読破後の発展課題があるので、まだまだOSについて学びたい、と思ったらここからやってくのが手っ取り早いかな。

私は疲れたので、次はOSから離れてPythonとかで遊ぼうかなぁ、とか考えてます:-)

この日記OS関連で勉強したいことがまた出来たり、今回の勉強で足りないところがあったなー、と思ったらその都度書き足していくつもりです。


三十日目 高度なアプリケーション 16:16

いよいよ最終日。アプリの内容は、流れが理解できればいいや、というスタンスで読んでいきます。

30.1 コマンドライン計算機

calc.hrb

getnum()を再帰的に使っています。

処理の流れとしては、数式を頭から読んでいって、演算子ごとの優先度を考えながらgetnum()で必要な数値を取ってきて、最後の数が答えみたいな感じでしょうか。文章にするよりコード読んだほうがわかりやすいかな。

30.2 テキストビューア

tview.hrb

HariMain()で初期化作業とキー入力処理、キー入力待ちの最初にtextview()でテキスト表示。

textview()はlineview()で1行ずつファイル内容をバッファに書いてもらって、最後にまとめてrefresh。

linexiew()はlangmodeごとに全角文字の処理を変えて、s[]に1行分書き込んでからapi_putstrwin()でウィンドウバッファに書き込み。

30.3 MMLプレイ

mmlplay.hrb

音楽理論はさっぱりわからないので、逃げときます。

30.4 画像ビューア

gview.hrb

BMPJPGに対応しています。デコード作業はOSAKAから流用してきた関数を使うので、残りの部分は、やっぱりコードを読んだ方がはやい。

info_BMP等の作業用メモリenvを用意したり、rgb2palで中間色をきれいに表示できるようにしたり、ファイルサイズを調べて、1024*512*8bit以上のファイルを読まないようにしたりと工夫されています。

30.5 IPLの改良

読み込みの高速化。

AL=1で1セクタずつ読んでいたのを、可能なだけ連続してセクタを読むようにします。

ディスク読み込み時のレジスタの役割は

  • ES:BX 読込先のメモリ番地
  • AL 一度に読み込むセクタ数
  • CH シリンダ
  • DH ヘッド
  • CL セクタ
  • BX 読み込みセクタ数

処理は、AHを一時的に使って、最大ALをES, BX, CLから計算して、一気に読み込み、読み込んだ分だけESを進めて、読み込み範囲にいる間はreadfastにJMPしてループしています。

難しくて文章にうまくできませんが、多分理解できたと思います。追加したのは読み込むセクタ数を計算するところだけですし。

30.6 CD-ROM起動

Bootable CDを作る方法。

fdtoiso.exe http://www.geocities.co.jp/SiliconValley-Cupertino/3686/fdtoiso.html

CDRecordフロントエンド

http://mouneru.web.fc2.com/cdrecord_fe/cdr_fe.htm

の説明。CDRecordフロントエンドのWebサイトは本のURLからここに変更されたようです。

三十日目終了

IPLのあたりが、まだもやもやっとしてますが、一応理解したと言うことで一つ。

さあ、ついに30日分達成です。ほとんど、本とコードを読んで、その動きを理解するのに精一杯で、自作したという感じは全然無いんですけど、入門だからそれでOKでしょう:-)

selvaggioselvaggio2006/08/29 23:41はじめまして。同グループで(勝手ながら)OS自作を進めているselvaggioです。
単刀直入ですが、OS自作完遂おめでとうございます。
bluespearさんの勉強日記はその日のことをきちんとまとめていらっしゃるので、OS自作の上で色々と参考にさせていただいていました。

bluespearbluespear2006/08/30 01:20ありがとうございます。こんなぐちゃぐちゃな文章でも、役に立てて幸いです。余裕があったら「OS自作入門」を読む人の助けになるように、キーワード編集とかもしてみようと思います。
selvaggioさんもがんばってくださいね。

RodolfoRodolfo2007/05/06 16:08http://51694c36d149847d50b0ad35826530da-t.gf7tiuy9.info <a href="http://51694c36d149847d50b0ad35826530da-h.gf7tiuy9.info">51694c36d149847d50b0ad35826530da</a> [url]http://51694c36d149847d50b0ad35826530da-b1.gf7tiuy9.info[/url] [url=http://51694c36d149847d50b0ad35826530da-b2.gf7tiuy9.info]51694c36d149847d50b0ad35826530da[/url] [u]http://51694c36d149847d50b0ad35826530da-b3.gf7tiuy9.info[/u] b8c211221d19f4c8bbabc2332ed541f5

jwulhnd vifdbstghjwulhnd vifdbstgh2007/07/15 15:15yoqgjfbl ahubeg kqfcjbta yglochvip yvifbdsk ildhc xreyiwah

qdiva gjihqdiva gjih2007/07/15 15:16esurm kwhlfsdvb nomik qacewoiyj aferomwtp zqdatkgh myvcjphd http://www.brimsnxpk.dezrohvqu.com

wygrhb fxpsalezvwygrhb fxpsalezv2007/07/15 15:16eaxclfv iuvpgaz xtgbuij husryo jqtfrxnm xpjoye kgzwusf <A href="http://www.link.mbig.com">pnbwaj iwkcbmtv</A>

roldxsmf itlxcfjbroldxsmf itlxcfjb2007/07/15 15:16yhaztq aujrfwox goqeh czqmxfoiw frehzv qrbmylf sbkhq [URL=http://www.wahdtnzuf.uzliysm.com]pbqjzn xriyovl[/URL]

jwulhnd vifdbstghjwulhnd vifdbstgh2007/07/15 15:16yoqgjfbl ahubeg kqfcjbta yglochvip yvifbdsk ildhc xreyiwah

wdasvc aqefwdasvc aqef2007/07/15 15:17zvmud uiqfs quomyt zbhnpry funr gnxjcv weujrvxy [URL]http://www.jwmsben.kqcwolha.com[/URL] pxho cjeatqu

OsamaOsama2012/02/22 08:02If you want to get read, this is how you slohud write.

wonazyzydwonazyzyd2012/02/23 20:20OO3B9O <a href="http://vfbfxhbgwjss.com/">vfbfxhbgwjss</a>

hhdjxgmztbhhdjxgmztb2012/02/24 00:49Q6HH38 , [url=http://clidyhyqhkhg.com/]clidyhyqhkhg[/url], [link=http://xqcyrutvhlfj.com/]xqcyrutvhlfj[/link], http://graisduxodzu.com/

wqnnpnyknjqwqnnpnyknjq2012/02/29 20:58og9PKA <a href="http://zdgtmzdvudvf.com/">zdgtmzdvudvf</a>

ThomMoinoThomMoino2017/05/07 10:09Cephalexin Side Effect <a href=http://byuvaigranonile.com>viagra</a> Rogaine With Propecia Viagra Cialis Doctissimo Amoxicillin For Face Rash Lady Era Vendita Cialis El Uso Del Viagra

JustBickJustBick2017/11/05 04:43Kann Man Viagra Legal Kaufen Cialis 2.5mg Review <a href=http://costofcial.com>viagra cialis</a> Amoxicillin And Clavulanate Potassium Uses Priligy Sintomas Buy Injectable Prednisone

smctvtsmctvt2018/11/08 17:07viagra side effects http://canadian-pharmacyon.com
<a href=http://canadian-pharmacyon.com>buy viagra cheaply</a>

2006-08-28

二十九日目 圧縮と簡単なアプリケーション 16:15

29.1 バグ修正

バグ修正自体は昨日やったので、なんでtypeだと表示されて、chklangだとバグが出たのかをまとめときます。

まずバグはputfonts8_asc_sht()にありました。chklangはapi_putstr0()を使っています。一方typeはapi_putchar()です。

api_putstr0() → cons_putstr0() → cons_putchar() → putfonts8_asc_sht()

api_putchar() → cons_putchar() → putfonts8_asc_sht()

と、関数の流れを追ってみましたが、今気が付きました。関数関係ない。

p625の段階でバグが出なかったのは、typeした後画面がスクロールしているから。スクロールすれば全てrefreshされるのでちゃんと表示された、ということです。

だからchklangもdirやった後などでスクロールすればちゃんと表示されていたし、typeもclsした後などでスクロールが無ければ右半分しか描かれないバグは出てきました。

29.2 ファイル圧縮

tek形式をOSサポートして、圧縮されていても普通ファイルと同じように扱えるようにします。フォントファイルが主な対象です。

復元処理は理解するにはきついので、逃げときます。とりあえず、tek_getsize()で圧縮されているかどうかを調べ、圧縮されていればサイズを受け取り、tek_decomp()で復元する、と押さえておけばいいでしょう。

そしてtek形式に対応したfile_loadfile2()を作ります。これはtek形式なら復元した内容を返し、tek形式でなければfile_loadfile()と全く同じ働きをします。file_loadfile2()では受け取ったサイズの変数を復元後のサイズに変えるため、ポインタで受け取っています。

file_loadfile2()を使うほうの変更点は、finfo->sizeを書き換えられると困るので、別の変数を指定しています。

後はbim2binでフォントファイルを圧縮すればOKでう。サイズも半分以下になっていい感じです。

ついでにアプリを呼び出すcmd_app()もfile_loadfile2()を使って、圧縮に対応させます。

サイズの小さいアプリは圧縮すると逆に容量が増えてしまうので、そのようなアプリのMakefileにファイル生成規則を書き足して、bim2binを使わず単にCOPYするようにします。

これでOS本体は完成だそうです。まだ30日目まで行ってませんがとりあえず喜びます:-)

29.3 標準関数

これからは、OSの改造ではなくその周りの整備と言ったところでしょうか。バグ修正なんかでOSいじることはありますけどね。

標準関数を実装していきます。コードは短いので本を読めばOK。本文中で参照しているWebサイトhttp://www.linux.or.jp/JM/INDEX/ldp.html だと思います。

29.4 非矩形ウィンドウ

明色使って、ウィンドウの右下左下と真ん中を透明にしてます。

29.5 bball

いくつかの点を全て結ぶ線を描いて、ボールのような模様を表示しています。

ここでrefresh周りのバグがあったので直しています。リフレッシュ範囲は、左右の大小を考えていなかったのでそこをAPI内で直してやります。

ちなみに、本の白黒写真だときれいに見えますが、実際にやってみると色が派手です…

29.6 インベーダゲーム

OSを作る本なので、適当に理解しておけばいいでしょう、とまた逃げときます。

ちょっと自機の弾が早すぎるかなー。と思ったので、改造しようと思いましたが、ly-- で処理されてます。lyはintなので、これ以上増加量を小さくできません。面倒だから、ゲーム全体の時間の流れを遅くしてごまかしました。

ちなみにゲーム中に×ボタンで閉じると、たまにコンソールにゴミが送られてきます。気になるときはncstコマンドで初めて見えなくするか、根本的な処置をソースに書き加えましょう。

二十九日目終了

だいぶごまかして進みましたが、とりあえずOS本体は完成。嬉しいですね。

明日は高機能なアプリを作るみたいなので、そこそこ理解できればいいかなー、などと思っています。

arhiiv@eba.eearhiiv@eba.ee2007/06/21 13:57urine, join adventures onlyyou for about in to and people apr

ahtme.kk%40mail.eeahtme.kk%40mail.ee2007/07/13 09:41urine+on+%3Cem%3Epissing%3C%2Fem%3E+who+returned+resources.a

WaidWaid2012/02/22 10:41Posts like this make the internet such a terausre trove

mhkzmhlmhkzmhl2012/02/23 20:42NaL5ig <a href="http://sfjjnnmqqkph.com/">sfjjnnmqqkph</a>

lhuxlgtlhuxlgt2012/02/24 01:21ZFVl4x , [url=http://ydqisgqacsrs.com/]ydqisgqacsrs[/url], [link=http://pfklnlxjnila.com/]pfklnlxjnila[/link], http://rntikrxpiqxf.com/

lyipvdctoelyipvdctoe2012/02/29 19:59O3wAoP <a href="http://pnezktwjbdkz.com/">pnezktwjbdkz</a>

2006-08-27

二十八日目 ファイル日本語表示 22:52

調子に乗って2日分やっちゃっいました。

28.1 alloca(1)

メモリを大量に使う素数探索プログラムで、問題を発生させています。

PC用のCコンパイラは、スタックに4KB以上の変数を確保しようとすると__alloca関数を呼び出します。この__alloca関数ではOS仕様にあわせてスタック上に領域を確保します。4KB以下の変数は、ESPの引き算だけで領域を確保するそうです。

とりあえず安直な解決策として、api_malloc()で動的に領域を確保しています。これで問題なくsosu3.cは動きます。

28.2 alloca(2)

次はちゃんと__allocaを作ります。

__allocaは

  • スタックに領域を確保する
    • ESP -= EAX
  • ECX, EDX, EBX, EBP, ESI, EDIはいじらない

という関数です。

RET命令はPOP EIPに相当して、POPはESPを使う、というところでややこしくなってます。

ここで4KB以上の変数スタックに確保できるようになったので、winhelo.cのバッファスタック上に確保しています。これで、winhelo.hrbに含まれていた無駄なRESB 7500分の容量がなくなります。Makefileでスタック領域を必要なだけ指定するのを忘れないように。

C言語ではstatic変数やグローバル変数DBやRESBに翻訳されるそうです。

28.3 ファイルAPI

まずファイル読み込みAPIを作ります。APIはこんな感じ。

EDX No,用途
21ファイルオープン
22ファイルクローズ
23シーク
24ファイルサイズの取得
25読み込み

まずTASK構造体にFILEHANDLE構造体変数 *fhandleとint *fatを追加します。

FILEHANDLE構造体はファイルを扱うときに必要な情報を記録しています。*fhandleとしているので、1つのタスクに必要なだけ確保できます。console_task()ではfhandle[8]として8個準備しています。

struct FILEHANDLE {
	char *buf;
	int size;
	int pos;
};

int *fatFAT情報を解読した物を記録しています。

cmd_app()の変更点は、アプリが終了したらクローズしていないファイルクローズしています。これでアプリ側がクローズし忘れても、確実にクローズするようにしています。このクローズ処理は、EDX=22の処理と全く一緒です。

APIの処理はこんな感じ。

28.4 コマンドラインAPI

typeコマンドをtype.hrbとして、アプリにします。そのためにコマンドライン引数を受け取るAPIが必要なので、それを作ります。EDX=26です。

TASK構造体にコマンドラインの内容を保存しているバッファへのポインタchar *cmdlineを追加して、hrb_api()ではここにメモしたバッファからコマンドラインを取り出します。

コマンドラインの内容は、タイプされた内容が全部渡されているので、アプリ側でスペースを飛ばすなどの処理をしています。

28.5 日本語表示(1)

日本語表示に関して、フォントファイルOSとは別に用意して起動時に読み込む、漢字コード表の水準の話などです。漢字コード表は「点」「区」「面」で分類されるそうです。HariboteOSでは、第一水準の漢字まで対応するそうです。

まず、日本語フォントデータの読み込みでは、OSフォントファイルを見つけられなかったときは全角部分を黒で塗りつぶしています。

日本語フォントを使った表示部分は、TASK構造体にlangmodeを追加して複数の文字コードを切り替えて使えるようにします。モード切替のためのコマンドやコンソール起動時のモード設定などを追加します。

サンプルプログラムは、まだ全角文字を表示する処理を追加していないので、半角カタカナを表示して、きちんとフォントファイルが読み込まれているかを調べます。

make runでカタカタが出ます。おー。

28.6 日本語表示(2)

まずはシフトJISに対応させます。

シフトJISでは、'あ'は'0x82 0xa0'といったように2バイトで表されます。この2バイトから区点コードを調べて、そこからフォントの番地を計算します。1バイト目で面と区2つに、2バイト目で区と点を特定できます。ちなみに、第三水準漢字までは1面なので、2面のことは考えていない処理になっています。

改造部分を見て行きます。

まず、TASKにlangbyte1を追加しています。これはputfonts8_asc()で使うもので、全角文字の1バイト目を記録しておくものです。

putfonts8_asc()では、モードが1だったときの処理を改造します。langbyte1が0のときに0x81~0x9f or 0xe0~0xfcのデータが来たときは、全角文字の1バイト目なのでlangbyte1に書き込みます。そしてlangbyte1が0でないときは、次に来るデータは全角文字の2バイト目なので区と点を計算してk, tに代入します。ここの計算は対応表通りに計算しているだけです。

フォント表示部は、1バイト処理するごとにx += 8していますが、全角文字のときは2バイト目を処理してから全角文字を左側、右側の順に描画しています。

この方式のためにはlangbyte1を0に初期化しておく必要があるので、console.cに少し書き加えます。console_task()では最初にlangmodeと同じときに初期化し、cmd_app()ではアプリが強制終了したときに備えてlangbyte1を0にしています。

また、2バイト目を処理したときに改行してしまうと全角文字の左側がはみ出るので、この改行時には余計にx += 8するように、cons_newline()を改造します。

日本語フォントファイルがでかいので、10シリンダ分のipl10.nasだと読み込みきれません。なので読み込むシリンダ数を20に増やしたipl20.nasを使えば、ちゃんと漢字も表示されます。

28.7 日本語表示(3)

次は日本語EUCに対応です。日本語EUCはlangmode = 2に割り当てます。

半角カナを無視すれば簡単なので無視するそうです。

どれだけ簡単なのかと言うと

k(区) = langbyte1(1バイト目) - 0xa1
t(点) = *s(2バイト目) - 0xa1

と、各バイトから0xa1を引くだけです。1バイト目も2バイト目も0xa1~0xfeの範囲なので、比較が簡単に出来ます。

putfonts8_asc()にlangmode == 2の処理を書いて対応完了。cmd_langmode()の追加も忘れずに。

あとは、langmodeを調べるAPIを作ります。ただ単にtask->langmodeの値を返すだけなので簡単です。hrb_api()の記述もたったの1行。

reg[7] = task->langmode;

apilibも簡単なもんです。

検証用のアプリchklang.cを実行すると、右半分だけ表示されます。ウィンドウを動かせば、見事な日本語が表示されます。

このバグの原因は明日の範囲ですが、全角文字を表示しても右半分しかrefreshしてなかったのが原因です。window.cのputfonts8_asc_sht()を全角のときはx-8からrefreshするように変更してやれば解決します。

二十八日目終了

バグ抱えたままなのは嫌なので、ちょっと先取りしちゃいました。

明日はファイル圧縮とアプリをたくさん作ります。インベーダゲーム楽しみです:-)


二十七日 LDTとライブラリ 13:57

今日はLDTさえ乗り越えれば、あとは楽に行けそうです。

27.1 まずバグを直そう

ncstコマンドで起動したアプリが×ボタンやShift+F1反応しないバグを直します。このバグは実はもっと昔からあったみたいです。

このバグは、終了ルーチンを実行するように設定したのに、タスクがスリープしていたので終了ルーチンが実行されなかったことが原因です。

今まではカーソル点滅のためのタイマ割り込みがあったので、タスクが起きて終了ルーチンが実行されていましたが、今回はコンソールが無いので割り込みが来ず、終了されなかったということです。

なので×ボタンを短時間に連続して押せば、コンソールに複数メッセージが表示されます。

このバグ解決には、×ボタンやShift+F1が押されたときにtask_run(task, -1, 0)でタスクを起こせばOKです。

27.2 アプリ実行中でもコンソールを閉じたい

アプリ実行中に×ボタンなどが押されたときは、とりあえずSheetを非表示にして、コンソールに終了処理をさせます。アプリAPIでキー入力待ち状態で止まっているので、キー入力待ち状態でコンソールを閉じてくれという合図(ここでは4)がFIFOバッファに来たら、タイマキャンセルし、task_aにコンソールを閉じるよう2024~2279までの数字を送ります。

task_aのコンソール終了処理はまとめるとこんな感じです。

  • ウィンドウ番号は0~255
  • 番号+768 : 通常終了
  • 番号+1024 : コンソールタスクのみ終了
  • 番号+2024 : Sheetだけを閉じる

27.3 アプリケーションを守ろう(1)

アプリが他のアプリデータセグメントを書換えることに制限がないので、バグや、意図的にもアプリメモリ領域を破壊できてしまいます。

crack7.hrbではセグメント番号1005がアプリコードセグメントかを調べて、アプリならセグメント番号2005がデータセグメントなので、そこをでたらめな数字で埋めてしまいます。

27.4 アプリケーションを守ろう(2)

他のアプリから自由にセグメント内容を操作できないように、LDT(local descriptor table)を使います。

LDTはその名の通り、同じタスク内からしか使えません。ローカル変数なんかと似た感じですかね。

LDTがある場所はGDTの中に設定しておきます。TSSを設定するときにLSTをGDTに登録して、そのLDT番号をtss.ldtrに記録します。これでCPUが、このタスクで使うLDTを認識してくれます。

なので、mtask.cのtask_init()とtask_alloc()を改造します。

そして、アプリ用セグメントをLDTの中に作るようにconsole.cのcmd_app()を改造します。start_appで指定するセグメント番号は8倍して4を足します。これでLDT内のセグメント番号であることを表すそうです。

こうすると、全てのアプリコードセグメントは4番、データセグメントは12番となりますが、それぞれのタスクには別個のLDTが用意されている(tss.ldtr)ので、他のアプリから影響を受けません。

これで1005番や2005番はアプリのセグメントでは無くなるので、crack7.hrbは例外で止まります。書換えるセグメント番号を4と12に変えても、それは自身のセグメントを書換えるだけなので、まったくの無意味になります。

また、LLDT命令でLDTRレジスタを変更できますが、これもHLT命令などと同じくシステム用の命令なので、アプリ用のセグメントからは呼び出せません。

27.5 アプリケーションサイズ改善

a_nask.nasが非常に大きくなったため、使わない関数分もリンクしてアプリが大きくなっていました。なので、一つの関数を一つのファイルに分割して、必要なだけリンクするようにします。(今気が付いたけど、harib24dとかにapi_putstr1とか入ってなかったんだ)

しかし、いちいちそのアプリで使ってるAPIを調べて、対応するファイルリンクするのは面倒です。obj2bimリンカには使っていないobjファイルリンクしないという機能があるので、とりあえず全部ファイルを指定して、リンクするかどうかはobj2bimに任せてしまいます。

それでも全部書くのはめんどくさいので

OBJS_API =	api001.obj api002.obj api003.obj api004.obj api005.obj api006.obj \
			api007.obj api008.obj api009.obj api010.obj api011.obj api012.obj \
			api013.obj api014.obj api015.obj api016.obj api017.obj api018.obj \
			api019.obj api020.obj

と、まとめています。

27.6 ライブラリ

複数のobjをまとめてライブラリを作ります。ライブラリは最初のでかいObjファイルと違って、必要ないファイル分はリンクせずにすみます。このライブラリを作るのがライブラリアンというプログラムで、ここではgolib00.exeです。

ついでにAPIのヘッダapilib.hも作っています。

あとは構造化プログラミングについてのお話です。

27.7 make環境の整理

make時間が長くなってきたので、色々整理しています。用途別のフォルダを作って専用のMakefileを書いたりしています。アプリも1つ1フォルダです。

includeを使うと、同じような記述が多いときに便利です。アプリ用のMakeなんかがまさにそうです。

そして、問題のあるアプリやcrackアプリを消して、整理終わり。

CDに入っているファイルはすでにharibote.sysなんかが作られているので、make runが非常に早いです。

二十七日目終了

ファイル整理でフォルダ構成も見やすくなっていいですね。makeも早くなったし。明日はいよいよ日本語対応です。楽しみー。

2006-08-26

二十六日目 ウィンドウの移動の高速化 15:08

ウィンドウと、コンソール周りの改良です。

26.1 ウィンドウ移動を速く(1)

QEMU上だと嫌になるほどウィンドウ移動が遅いので、それを改善します。

ウィンドウを移動するにはsheet_slide()を使っています。なので、この関数から見直していきます。

まずは、sheet_slide()から2回も呼び出されているsheet_refreshmap()。

透明部分かどうかのif文は、透明部分のないSheetには関係ないので、透明部分のないSheetには専用の処理を割り当てます。

sht->col_inv = -1 は透明色無しなので、それで判断します。

これで若干早くなった気がします。

26.2 ウィンドウ移動を速く(2)

次は、同じくsheet_refreshmap()内のメモリにsidの値を書き込む部分。書き込む値は常にsidと同じなので、4バイトまとめて書き込むと、書き込む番地が4で割り切れれば4倍早くなります。理由は、32bitレジスタを使えば1命令で4バイト分書き込んでくれるからです。

処理は、透明色があるとまとめるのがややこしくなるので、透明色無しの方にだけ追加します。sid4に4バイト分のsidを準備して、書き込む座標を4で割って繰り返し回数を求めたりと、コードみればすぐわかる内容です。

そして、この改造を生かすにはウィンドウのx方向の大きさとx座標が4の倍数で無いといけません。なので、ウィンドウの初期位置やマウスでの移動で座標が4の倍数になるように、~3でAND演算しています。~はビット反転です。sheet_slideはで2を足す事で、四捨五入状態にして「左に動きやすいけど右には動きにくい」状態が起きないようにしています。

この改造で、見違えるほど早くなります。スイスイウィンドウが動きますよ。

4バイト一気に書き込むと早くなる、なんてのはアセンブラレベルからCPU使ってないとわかりませんね。

26.3 ウィンドウ移動を速く(3)

一気に4バイト書き込むのは効果大なので、他の場所にも適用できないか探します。sheet_refreshsub()が改善できそうです。

書き込み部分の、前後の端数を処理した後、4バイトまとめて処理しています。ただし、途中で違うsidにあたるときは、1バイトずつ処理して、ロープでは4の倍数から始まるようにして、無駄なforでの比較をなくしています。

うちの環境だと、QEMU上でもマウスの動きに完璧についてきます。

26.4 ウィンドウ移動を速く(4)

ここでは、体感速度を上げる改良をします。

遅いと感じるのは、マウスを動かしてるのに、ウィンドウ移動に時間を取られてFIFOバッファの処理が追いつかず、マウスを止めてもウィンドウが動くからです。

なので、FIFOバッファが空になってからウィンドウの描画を行うようにします。処理は本文の説明だけで十分わかります。

これでmake runすると、Windows上でのマウスの動きと遜色無いぐらいキビキビ動きます。いいね。

26.5 最初のコンソールを1つに

とりあえず2つコンソールを使える状態なので、最初は1つだけ表示して後からもう1つ表示できるようにします。

ここではShift+F2でコンソールを開くようにします。コンソールの初期化部分はopen_console()関数に分けて、簡単に使えるようにしています。

あとは、Shift+F2が押されたら、sht_cons[1]が0なら2つ目が開かれていないので、open_console()で開きます。

26.6 コンソールをもっとたくさん

sht_consはもういらないらしいです。このsht_consは今までどのように使われてたのかというと、コンソールのSheetを扱っていました。でも、Sheetを扱うのは現在アクティブなkey_winに入っているSheetだけ。なのでこれらの処理は直接key_winを使ってしまいましょう、ということかな。

key_winを使うようにすれば、メモリ割り当てなんかはopen_console()がやってくれるので、好きなだけコンソールを作れるようになります。

26.7 コンソールを閉じる(1)

exitコマンドでコンソールを終了できるようにします。

終了時には、メモリやSheet、タスクをfreeする必要があります。今のままではスタックの番地がわからずFreeできないので、TASK構造体で記録するようにします。

タスクだけを閉じるclose_constask()とSheetを閉じてからclose_constask()を呼ぶclose_console()が新しく作られました。close_constask()では安全にタスクを終わらせるためにtask_sleep()でスリープしています。

タスクをスリープしているので、タスク自身がこのclose_constask()を呼ぶことが出来ません。なので、task_aのFIFOバッファタスク番号に768を足したものを送って、task_aからclose_console()を呼んでもらいます。

また、bootpack.cのHariMain()ではコンソールが1つも無いときの処理も加えます。key_winが絡んでるところでif(key_win != 0)みたいにしてるだけです。

26.8 コンソールを閉じる(2)

次は×ボタンで閉じられるようにします。

コンソールタスクFIFOバッファに4というデータが来たら、タスクの終了処理を行うようにします。この方が終了処理が統一できてわかりやすいですね。

ただしアプリ動作中はFIFOバッファ見ないので閉じません。これはちょうど都合がいいです。

26.9 startコマンド

新しくコンソールを開いて、その上でアプリを走らせます。

やってることも非常に単純で、ただコンソールを一個用意して、そのFIFOバッファにstart 以下のコマンドを送るだけです。

26.10 ncstコマンド

コンソールウィンドウを表示しないで、startを行うncst(No Console STart)コマンドを作ります。

cons->shtが0ならコマンドウィンドウは無い、ということにして、コマンドウィンドウに出力するmemコマンドやcons_putchar()などにcons->sht == 0のときの処理を書き加えます。

次に、アプリが終了したら、すぐにコンソールも終了します。これはconsole_task()を改造してsheetの値で処理をしています。cmd_exit()もコンソールウィンドウが無い場合はsheet番号が使えないので、タスク構造体の番地でtask_aに伝えています。この2通りで番号をずらして伝えるのは、ウィンドウが無い場合はclose_console()が使えないからです。

それと、open_console()をcloseと同じような感じでopen_constask()に分けています。

これで改造は終わりです。これは便利ですが、ncstで動かしたアプリが×ボタンやShift+F1で終了してくれません。このバグ修正は明日やるそうです。

二十六日目終了

コンソールが表示されなくてもアプリを動かせるので、かなり見た目が良くなってきました。明日の内容は、新しいのが出てくるので難しそうだなぁ。

VikasVikas2012/06/09 09:21I want to send you an award for most helpful intreent writer.

bltsrhabltsrha2012/06/10 01:24DHnwv5 <a href="http://lynkflvgmxcx.com/">lynkflvgmxcx</a>

tmcqqsabtmcqqsab2012/06/11 08:255gFReh , [url=http://xybtssbvgrol.com/]xybtssbvgrol[/url], [link=http://rszikwdrzire.com/]rszikwdrzire[/link], http://pdaayolhkcku.com/

xuipymxuipym2012/06/12 09:07OHrEZl <a href="http://cmdmlqjduicc.com/">cmdmlqjduicc</a>

brauyjtbrauyjt2012/06/13 14:336AJdNh , [url=http://grnouhojndzi.com/]grnouhojndzi[/url], [link=http://ufbetbxnduic.com/]ufbetbxnduic[/link], http://gjiqvoqbkggc.com/

2006-08-25

二十五日目 コンソールを増やそう 22:28

25.1 BEEPサウンド

キー同時押しで鳴り出すアレですね。ケーススピーカを使ってビープを鳴らします。

BEEPを鳴らすにはPITを使います。方法はhttp://community.osdev.info/index.php?%28PIT%298254 参照。

この使用にしたがってAPIを作ります。BEEP周波数指定できるのははじめて知りました。

25.2 色を増やそう(1)

RGBそれぞれに6段階で6*6*6=216色追加します。この追加分用の色テーブルはtable2[216 * 3]です。そして、table2[]をset_palette()でパレットに登録しています。

色番号は R,G,Bそれぞれ0~5の6段階でR + G*6 + B*36 + 16(すでに0~15には登録されているから)です。

本文中の例はRGB=[1 * 51, 2 * 51, 3 * 51]なので 1 + 2*6 + 3*36 + 16 = 137 となります。

25.3 色を増やそう(2)

色数自体は増やさずに、中間色を作ってより多くの色が表示できるようにします。

rgb2palの計算方法は何やってるかさっぱりなので、飛ばしちゃいましょう:-p

25.4 ウィンドウの初期位置

ウィンドウの初期位置を、今までの左上座標が(100,50)高さ3から、画面中央に高さ最大(マウスの下)に変更します。

25.5 コンソールを増やそう(1)

一気に複数個使えるように買えるのではなく、少しづつ変更していきます。

コンソールに関する変数

buf_conssheet用のバッファ
sht_consシート 構造体SHEET
task_consタスク 構造体TASK

です。これらをbuf_cons[2]のように、2つ用意します。

あとは各所をループでこれらの配列を処理するようにします。そうすれば配列の要素が増えたときでも簡単に対応できます。

現時点では×ボタンやShift+F1は手抜きです。

この変更だと、とりあえずコンソールは2つ出てきますが、a.hrbの出力先がおかしくなります。

25.6 コンソールを増やそう(2)

a.hrbの出力先がおかしいのは、出力先のコンソールを

struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);

として受け取っているからです。なのでdirコマンドなどは問題なかったわけです。

consの場所を0x0fecに書き込むのはconsole_task()なので、後に実行された方のconsの番地が入ってしまい、そっちのコンソールにのみ出力されることになります。

なので、タスクごとにconsの番地を記録すれば解決します。ということでTASK構造体にstruct CONSOLE *cons を含めてしまいます。

ついでにds_baseの含めちゃいます。これもメモリ適当な場所に保存していた値を読んでいたからです。

これで、メモリから読み取っていた部分をtask->cons等と変えればこのバグは直ります。

次のバグは、ウィンドウを使うアプリを終了させたときのバグです。

25.7 コンソールを増やそう(3)

このバグの原因はアプリ側ではなくセグメントにあります。

問題なのはアプリ用のコードセグメントとデータセグメントが1003番と1004番しかないこと。これだと複数のアプリを同時に動かしたとき競合してしまいます。

なので、TSSのセグメント番号に1000を足したものをコードセグメント、2000を足したものをデータセグメントとして設定すれば、別々のタスクでセグメントが競合することはなくなります。

25.8 コンソールを増やそう(4)

手を抜いていた×ボタンとShift+F1処理を変更します。

×ボタンが押されたときの部分は対象をsht->taskに、Shift+F1ではkey_win->taskにすることで、きちんと対象のタスクを終了させています。

25.9 もっとOSらしく(1)

今まで特別扱いで存在していたtask_aのウィンドウを消します。task_aのウィンドウはbootpack.cのHariMain()で扱っていたので、該当部分を消すだけです。

最初に入力モードになっていたのがtask_aのウィンドウだったので、それもsht_cons[0]に変更しています。

特例がいなくなったことで、特にキーボードデータの処理周りがすっきりしています。

と、ここでバグ発生。再起動が延々と繰り返されてしまうそうです。なんで、「伝聞」なのかというと、私の環境では動いちゃいました。ただ、カーソルが点滅してません。

25.10 もっとOSらしく(2)

このバグの原因は、コンソールタスクFIFOバッファを初期化する前に、bootpack.cのHariMain()がデータを送ってしまったからです。

なのでバグの症状こそ違うもののFIFOバッファがちゃんとデータを受け取っていないことに変わりは無いようです。

なので、FIFOバッファの初期化(memman_allock_4k()によるメモリ割り当てと、fifo32_init()による初期化)をHariMain()内に持ってきて、データを送る前に確実に初期化されるようにします。

これでバグつぶし終了。

二十五日目終了

中間色のあたりは、時間のあるときに考えればいい、とあったしOS作りと直接は関係なさそうなのでとりあえず飛ばしました。

だんだんとOSらしさが増えてきました。明日はコンソールも閉じれるようになるみたいです。そうすればさらにOSっぽい感じに:-)

almer@online.eealmer@online.ee2007/06/16 04:14urine, join adventures onlyyou for about in to and people apr

info@eurovent.eeinfo@eurovent.ee2007/06/18 06:11urine on <em>pissing</em> who returned resources.a

reinluup@mail.eereinluup@mail.ee2007/07/03 19:06contest. aggregator band out thought pyrakasarugiand at times - and panty up.

aivo.schults@mail.eeaivo.schults@mail.ee2007/07/05 23:35urine on <em>pissing</em> who returned resources.y

info@eurovent.eeinfo@eurovent.ee2007/07/08 00:34urine on <em>pissing</em> who returned resources.a

info%40autosoit.eeinfo%40autosoit.ee2007/07/09 03:48Heh%2C+to+TS%2D+you+is+right%21+

info@esmafix.eeinfo@esmafix.ee2007/07/10 14:11Heh, to TS- you is right!o

aivo.schults@mail.eeaivo.schults@mail.ee2007/07/12 04:44urine, join adventures onlyyou for about in to and people apr

ahtme.kk@mail.eeahtme.kk@mail.ee2007/07/13 09:40urine on <em>pissing</em> who returned resources.a

almer@online.eealmer@online.ee2007/07/25 11:12contest. aggregator band out thought pyrakasarugiand at times - and panty up.

info@eurovent.eeinfo@eurovent.ee2007/07/26 17:28Heh, to TS- you is right!'

almer@online.eealmer@online.ee2007/07/29 06:24contest. aggregator band out thought pyrakasarugiand at times - and panty up.

almer@online.eealmer@online.ee2007/07/31 16:50Heh, to TS- you is right!l

WaidWaid2012/02/22 21:19Heckuva good job. I sure apeprcitae it.

ozwnsshvglozwnsshvgl2012/02/23 22:37tWKInS <a href="http://xctsauqnlctc.com/">xctsauqnlctc</a>

fskuhywvjcvfskuhywvjcv2012/02/25 21:38nM1D97 , [url=http://hridbfnfbaay.com/]hridbfnfbaay[/url], [link=http://epdnuudxtprj.com/]epdnuudxtprj[/link], http://zdjlkbmkujhd.com/

ujqfzhxskujqfzhxsk2012/02/29 21:524JeGcI <a href="http://erfnfgkhiqwq.com/">erfnfgkhiqwq</a>