OS自作入門 / 2008/08/29 (Fri) / 編集 |
31 void init_palette(void)
32 { 33 static unsigned char table_rgb[16 * 3] = {
34 0x00, 0x00, 0x00, /* 0:黒 */
35 0xff, 0x00, 0x00, /* 1:明るい赤 */
(中略)
50 };
51 set_palette(0, 15, table_rgb);
でもって[OS-Wiki]VGAのビデオDAコンバータんとこにある「パレットのアクセスの手順」によると
57 void set_palette(int start, int end, unsigned char *rgb)
58 {
59 int i, eflags;
60 eflags = io_load_eflags(); /* 割り込み許可フラグの値を記録する */ 61 io_cli(); /* 許可フラグを0にして割り込み禁止にする */
62 io_out8(0x03c8, start);//パレット番号を設定
63 for (i = start; i <= end; i++) {
64 io_out8(0x03c9, rgb[0] / 4);//パレットの色を設定
65 io_out8(0x03c9, rgb[1] / 4);
66 io_out8(0x03c9, rgb[2] / 4);
67 rgb += 3;
68 }
69 io_store_eflags(eflags); /* 割り込み許可フラグを元に戻す */
70 return;
71 }
でパレットの設定ができるらしい、ちなみにio_out8()は「portに繋がっている装置にdataを出力する」というものらしい。 読み出しは0x03c7にパレット番号を書き込み、0x03c9を3回読み込むとRGBの順番で出力されるんだとか
この後
20 p = (char *) 0xa0000; /* 番地を代入 */
21
22 for (i = 0; i <= 0xffff; i++) {
23 p[i] = i & 0x0f;
24 }
とするとディスプレイに縞模様が出力されるらしい!なんでやねん!?
まぁ先日の記事を後で修正しておくので「なぜVRAMに書き込む事になるのか?」はそこ参照(大雑把にいうと「*(p+i)==p[i]」だから)、縞模様になるのはパレットで「色番号0は黒」とか設定してあるから「p[i] = i & 0x0f;(VRAM=色番号)」でVRAMに色番号0から15までを交互に代入することによって縞模様になる、たぶん。(変数名をvramにすればわかりやすいんじゃね?とか思ったがなぜpのままなんだろう?)
PR
OS自作入門 / 2008/08/27 (Wed) / 編集 |
制約:レジスタはEAX,ECX,EDXしか使えない(他はC言語自身が使うから)
サンプルコードから抜粋(*NASKの構文です)
[FORMAT "WCOFF"] ; オブジェクトファイルを作るモード
[INSTRSET "i486p"] ; 486の命令まで使いたいという記述
[BITS 32] ; 32ビットモード用の機械語を作らせる
[FILE "naskfunc.nas"] ; ソースファイル名情報
GLOBAL _write_mem8
[SECTION .text] ; void write_mem8(int addr, int data);
;;addr番地にdataを書き込む _write_mem8:
MOV ECX,[ESP+4] ; [ESP+4]にaddrが入っているのでそれをECXに読み込む
MOV AL,[ESP+8] ; [ESP+8]にdataが入っているのでそれをALに読み込む
MOV [ECX],AL
RET
つまり、[ESP+4*x]番地に関数の第x引数が保存されてるらしい。ここで「INSTRSET "i486p"」というのは「i486モードで作る」という意味で、これがないとECXの意味がかわってしまうらしい。(詳しくは本を読んでねw)
あ、もちろん関数の宣言(GLOBALのとこ)も忘れちゃダメ
でもってC言語側からの使い方例
void write_mem8(int addr, int data);
(中略)
for (i = 0xa0000; i <= 0xaffff; i++) {
write_mem8(i, 15); /* MOV BYTE [i],15 */
}
関数の宣言は忘れずに、ちなみにいうと上の関数は「画面を白に染める」という意味、なぜかというと0xa0000~0xaffffはVRAMの領域で、「15」ってのは「白」という意味だかららしい、へぇ〜
でもって返り値のある関数ではEAXに入っている値が返り値になるらしい
_test: ;int test(int data) MOV EAX,[ESP+4] RET
とすると「test(5)」としたときの返り値は「5」になるらしい
サンプルコードから抜粋(*NASKの構文です)
[FORMAT "WCOFF"] ; オブジェクトファイルを作るモード
[INSTRSET "i486p"] ; 486の命令まで使いたいという記述
[BITS 32] ; 32ビットモード用の機械語を作らせる
[FILE "naskfunc.nas"] ; ソースファイル名情報
GLOBAL _write_mem8
[SECTION .text] ; void write_mem8(int addr, int data);
;;addr番地にdataを書き込む _write_mem8:
MOV ECX,[ESP+4] ; [ESP+4]にaddrが入っているのでそれをECXに読み込む
MOV AL,[ESP+8] ; [ESP+8]にdataが入っているのでそれをALに読み込む
MOV [ECX],AL
RET
つまり、[ESP+4*x]番地に関数の第x引数が保存されてるらしい。ここで「INSTRSET "i486p"」というのは「i486モードで作る」という意味で、これがないとECXの意味がかわってしまうらしい。(詳しくは本を読んでねw)
あ、もちろん関数の宣言(GLOBALのとこ)も忘れちゃダメ
でもってC言語側からの使い方例
void write_mem8(int addr, int data);
(中略)
for (i = 0xa0000; i <= 0xaffff; i++) {
write_mem8(i, 15); /* MOV BYTE [i],15 */
}
関数の宣言は忘れずに、ちなみにいうと上の関数は「画面を白に染める」という意味、なぜかというと0xa0000~0xaffffはVRAMの領域で、「15」ってのは「白」という意味だかららしい、へぇ〜
でもって返り値のある関数ではEAXに入っている値が返り値になるらしい
_test: ;int test(int data) MOV EAX,[ESP+4] RET
とすると「test(5)」としたときの返り値は「5」になるらしい
OS自作入門 / 2008/08/26 (Tue) / 編集 |
とりあえず、Makefileで引っかかったのでメモ
copyコマンドとdelコマンドはUNIXには存在しない
#COPY = copy
#DEL = del
COPY = cp
DEL = rm
Windowsのコピーコマンドはファイルの合併もできるらしいがUNIXのcpではできないので以下
#haribote.sys : asmhead.bin bootpack.hrb Makefile
# copy /B asmhead.bin+bootpack.hrb haribote.sys
haribote.sys : asmhead.bin bootpack.hrb Makefile
cat asmhead.bin bootpack.hrb > haribote.sys
runも書き換えなきゃならんらしいが、リモートログイン(CUI)したLinux上でqemuを使うつもりはないので試してはいない
#run :
# $(MAKE) img
# $(COPY) haribote.img ..¥z_tools¥qemu¥fdimage0.bin
# $(MAKE) -C ../z_tools/qemu
run :
../z_tools/make.exe img
qemu -m 32 -localtime -std-vga -fda haribote.img
run :
$(MAKE) img
qemu -m 32 -localtime -std-vga -fda haribote.img
パッチの作り方
diff -u だめなMakefile 正常なMakefile > パッチ.patch
patch -b パッチを当てたいMakefile パッチ.patch
copyコマンドとdelコマンドはUNIXには存在しない
#COPY = copy
#DEL = del
COPY = cp
DEL = rm
Windowsのコピーコマンドはファイルの合併もできるらしいがUNIXのcpではできないので以下
#haribote.sys : asmhead.bin bootpack.hrb Makefile
# copy /B asmhead.bin+bootpack.hrb haribote.sys
haribote.sys : asmhead.bin bootpack.hrb Makefile
cat asmhead.bin bootpack.hrb > haribote.sys
runも書き換えなきゃならんらしいが、リモートログイン(CUI)したLinux上でqemuを使うつもりはないので試してはいない
#run :
# $(MAKE) img
# $(COPY) haribote.img ..¥z_tools¥qemu¥fdimage0.bin
# $(MAKE) -C ../z_tools/qemu
run :
../z_tools/make.exe img
qemu -m 32 -localtime -std-vga -fda haribote.img
run :
$(MAKE) img
qemu -m 32 -localtime -std-vga -fda haribote.img
パッチの作り方
diff -u だめなMakefile 正常なMakefile > パッチ.patch
patch -b パッチを当てたいMakefile パッチ.patch