1: 2007-01-21 (日) 11:32:43 |
2: 2007-01-21 (日) 14:28:34 |
| | | |
| はりぼてをAドライブ(起動)、そして今は亡き?Bドライブに適当なFDイメージを用意して、これを読んでみる実験〜。 | | はりぼてをAドライブ(起動)、そして今は亡き?Bドライブに適当なFDイメージを用意して、これを読んでみる実験〜。 |
| + | |
| + | *とりあえず一回体当たり! [#e4650372] |
| + | はりぼてWikiに[[こんなページ:http://hrb.osask.jp/wiki/index.php?advance%2FFDC]]があるので参考にしてなんかやってみよう。 |
| + | |
| + | ええと?なになに? |
| + | |
| + | -FDCへはコマンドを送信して制御する |
| + | -コマンドを送っても遅いのでIRQ-06でお返事がくるまで待つ |
| + | |
| + | なるほどなるほど。 |
| + | とりあえず現在はコンソールはシステム側で動いていたはず。コンソールに適当なコマンドを搭載して実験するのがよさそうですね。 |
| + | |
| + | ・・・おっと!その前に、IRQ-06の割り込みが発生したらなにかさせないと。 |
| + | |
| + | これまでのパターンだと、こういう手の割り込みの信号はFIFOバッファに積んでメインルーチンに監視させるってパターンだったよね? |
| + | |
| + | ええと。現在、キーボードやマウスの割り込みはどこでどうやって制御しているんだっけ・・・ |
| + | |
| + | ***まずはIDT [#cd689a3e] |
| + | 割り込みを使えるようにするためには、IDTを設定しなくちゃいけない。まずはdsctbl.cに、IRQ6を登録してみよう。ちなみに現在は・・・・ |
| + | |
| + | load_idtr(LIMIT_IDT, ADR_IDT); |
| + | |
| + | /* IDTの設定 */ |
| + | set_gatedesc(idt + 0x0c, (int) asm_inthandler0c, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x0d, (int) asm_inthandler0d, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60); |
| + | |
| + | これは5日目と6日目にやった状態とほぼ同じかな?。とりあえずここいらへんをもう一度読んでみた。 |
| + | |
| + | うむむ。けっこう忘れてるなぁ。そうか。IRQ番号とINT番号はピタっと対応していない。(P130参照)_0x20しないといけないんだっけね。 |
| + | |
| + | えーっと?そうすると、こうだよね? |
| + | |
| + | |IRQ|INT|通常用途|h |
| + | |0|0x20|タイマー| |
| + | |1|0x21|キーボード| |
| + | |2|0x22|aaaa| |
| + | |3|0x23|aaaa| |
| + | |4|0x24|aaaa| |
| + | |5|0x25|aaaa| |
| + | |6|0x26|aaaa| |
| + | |7|0x27|aaaa| |
| + | |8|0x28|aaaa| |
| + | |9|0x29|aaaa| |
| + | |10|0x2A|aaaa| |
| + | |11|0x2B|aaaa| |
| + | |12|0x2C|マウス| |
| + | |13|0x2D|aaaa| |
| + | |14|0x2E|aaaa| |
| + | |15|0x2F|aaaa| |
| + | |
| + | 12日目からタイマー割り込みを後付けで導入しているので、ここらへんの手法を参考に実装してみまそー! |
| + | |
| + | まず''とりあえず''IDTテーブルを書き換えちゃう。 |
| + | |
| + | load_idtr(LIMIT_IDT, ADR_IDT); |
| + | |
| + | /* IDTの設定 */ |
| + | set_gatedesc(idt + 0x0c, (int) asm_inthandler0c, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x0d, (int) asm_inthandler0d, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x20, (int) asm_inthandler20, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); |
| + | /*ここ。IRQ6。フロッピーからのお返事 |
| + | set_gatedesc(idt + 0x26, (int) asm_inthandler26, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32); |
| + | set_gatedesc(idt + 0x40, (int) asm_hrb_api, 2 * 8, AR_INTGATE32 + 0x60); |
| + | |
| + | さてこれだけじゃダメ。asm_inthandler26という関数(正確には番地ね)を設置してやらないといけない。これはnaskfunc.nas内に置かれている。P234を参考に実装。(とは言ってもほぼ丸写しでOKかな。) |
| + | |
| + | _asm_inthandler26: |
| + | PUSH ES |
| + | PUSH DS |
| + | PUSHAD |
| + | MOV EAX,ESP |
| + | PUSH EAX |
| + | MOV AX,SS |
| + | MOV DS,AX |
| + | MOV ES,AX |
| + | CALL _inthandler26 |
| + | POP EAX |
| + | POPAD |
| + | POP DS |
| + | POP ES |
| + | IRETD |
| + | |
| + | |
| + | 独立させておいたほうがよさそうなので、fd.cというファイルを追加した。内容はとりあえずなにもしない関数を設置。(これもP234を参照した) |
| + | |
| + | void inthandler26(int *esp) |
| + | { |
| + | return; |
| + | } |
| + | |
| + | さて。このままうっかりメイクしておもいっきりエラーを吐かれてしまった。(笑 |
| + | 分割コンパイルしているのだ。ちゃんとbootpac.cに新関数を書いておかないとね。 |
| + | |
| + | よーし! OK。とりあえず設置は完了したぞ。じゃまず、この割り込みがやってきたらどうするか実装してみようかな。 |
| + | |
| + | まずはやっぱり、ここへ来てもあの手法が一番簡単で確実だよね。P137のキーボードのコードを表示するやつ。 |
| + | |
| + | struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; |
| + | unsigned char data, s[4]; |
| + | io_out8(PIC0_OCW2, 0x61); /* IRQ-01受付完了をPICに通知 */ |
| + | data = io_in8(PORT_KEYDAT); |
| + | |
| + | sprintf(s, "%02X", data); |
| + | boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); |
| + | putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s); |
| + | |
| + | return; |
| + | |
| + | これをほぼそのままパクッて設置してみよう。 |
| + | |
| + | ちなみに、これがちゃんと現在でも稼動するかどうかあやしいのでキーボードのほうにも設置。(確認のため) |
| + | |
| + | void inthandler21(int *esp) |
| + | { |
| + | int data; |
| + | io_out8(PIC0_OCW2, 0x61); /* IRQ-01受付完了をPICに通知 */ |
| + | data = io_in8(PORT_KEYDAT); |
| + | fifo32_put(keyfifo, data + keydata0); |
| + | |
| + | /*実験部分*/ |
| + | struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; |
| + | unsigned char s[4]; |
| + | |
| + | sprintf(s, "%02X", data); |
| + | boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); |
| + | putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s); |
| + | /*-------------------*/ |
| + | |
| + | return; |
| + | } |
| + | |
| + | よーし!OK。この手法はまだちゃんと使えるようだね。じゃ、これと同じように、FDからの割り込みが来た場合も反応できるようにしておこう。 |
| + | |
| + | fd.c |
| + | |
| + | /* フロッピー関係 */ |
| + | |
| + | #include <stdio.h> |
| + | #include "bootpack.h" |
| + | |
| + | void inthandler26(int *esp) |
| + | /* FDコントローラからの割り込み */ |
| + | { |
| + | |
| + | /*実験部分*/ |
| + | io_out8(PIC0_OCW2, 0x66); /* IRQ-06受付完了をPICに通知 */ |
| + | |
| + | struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; |
| + | unsigned char s[4]; |
| + | |
| + | sprintf(s, "%02X", data); |
| + | boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); |
| + | putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FF00FF, s); |
| + | /*-------------------*/ |
| + | |
| + | |
| + | return; |
| + | } |
| + | |
| + | よしよし! 無事コンパイルできたな。たぶんこれで、IRQ-6から割り込み(FDのコマンド結果)がくれば受信できるはずだ。 |
| + | |
| + | |
| + | **コマンドを送ってみよう [#g01cffbc] |
| + | さて、じゃ、コマンドを送信してみたいんだけど、どうすればいいかな??はりぼてWikiには、 |
| + | |
| + | まず io_in8(0x03f4) & 0x11 の値が0になるのを待ちます |
| + | |
| + | とあるけど、これ、どういう意味だろう?? |
| + | |
| + | [[OS-Wiki:http://community.osdev.info/index.php?(FDC)765A]]にも資料があるな。 |
| + | ん????。読み出したデータのおのおののビットに意味があるの??。つーことは、0X11って 10001でしょ?。 「&」って、読み出したデータをand演算しろってこと? |