|
ザビタン開発日記
10月 19 (金曜日) 2007
|
16:10
|
FDアクセス:IRQ06
|
|
おっとっと! 忘れてた! これが大事な概念。
- FDDはFDDコントローラに対してコマンドを送信して動かす
- しかし返事が返ってくるのがとても遅い・・・
- なので、割り込み(IRQ06)にお知らせがくる
- そうでないとCPUとかに比べて遅すぎるので
こういうことですな。まずは割り込みの処理を設置しないと・・・
dsctbl.cに割り込みを設置する。
/*ここ。IRQ6。フロッピーからのお返事
set_gatedesc(idt + 0x26, (int) asm_inthandler26, 2 * 8, AR_INTGATE32);
naskfunc.nas内に反応する関数を設置と・・・(P234を参考)
_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というファイルを追加。内容は
#include
#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;
}
こんなところかな・・・
おぉぉっと! bootpac.hに今回設置した各関数を追加し、Makefileとかも直さないと・・・
おっしゃ! とにもかくにもコンパイルは通ったみたいだぞ!??
あとはinthandler26関数でtesttaskのfifoにデータを送信するように
すればいいはず。ええと・・・どうしようかな??
リビジョン19
|
15:55
|
FDアクセス:最初
|
|
ふむふむ・・・
まずはDMACの初期化かぁ・・・
これは最初にやっておけばよさそうなのでタスクのforループの前でやってしまったほうがいいかな。
とりあえずはこんなソースを置いてみる・・・
void test_task(struct SHEET *sheet){
struct TASK *task = task_now();
struct TIMER *timer1 = timer_alloc();
int i;
int fifodata;
char s[40];
int counter;
counter = 0;
//====== DMAの初期化===============
io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */
io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */
io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */
for(;;){
counter++;
if ( counter >100000 ){counter=0;}
io_cli();
if (fifo32_status(&task->fifo) ==0){
io_sti();
}
else{
fifodata = fifo32_get(&task->fifo);
io_sti();
sprintf(s, "fifo=%05d", fifodata);
putfonts8_asc_sht(sheet,20,16*4,COL8_008484,COL8_FFFFFF,s,10);
//========== キーボードだった場合の処理 ========
if (256 <= fifodata && fifodata <=511){
fifodata=fifodata-256;
sprintf(s, "ASCII=%02x", fifodata);
putfonts8_asc_sht(sheet,20,16*5,COL8_008484,COL8_FFFFFF,s,8);
}
}
sprintf(s, "counter=%05d", counter);
putfonts8_asc_sht(sheet,20,16*3,COL8_000000,COL8_FFFFFF,s,13);
}
}
あとはこのキーボードに反応してコマンドを送れるようにしてみる・・・
まずは「1」が押されたら読み込みコードを実行するって感じかな・・・
|
12:11
|
FDDを読み書きしたい!
|
|
さてさて!
オイラが今一番やりたいのがこれ!
以前も結構やってたんだけど挫折しますた・・・ orz
タスク設置で気をよくしたもんで、再び無謀な挑戦〜
さて、FDDをコントロールするにはタスクを独立させたほうがいいという
アドバイスをKタンがしていますなぁ。そういうわけで、さっそく
やってみることにします。
あ”・・・ こないだのタスクバーもどき、testtaskなんて名前で設置されてるね(汗
まずはこれらの名前変更から・・・
リビジョン17
さてさて!
そしたら、この時計タスクの最初とほぼ同じような感じのタスクを設置・・・
よし!!! できたーー!
リビジョン18
ではでは、いよいよこのあたらしいtesttask内でFDDアクセスにチャレンジ!!!
パクリ参考元 ここ〜
|
01:57
|
完成! いっちょリリースするか!!
|
|
わははは! でけたーーー!
よーし。じゃあこれを Ver.0.01とでもしてリリースと行きますか。
リビジョン16
|
00:05
|
特別なシート
|
|
今回作ったtesttaskウィンドゥ。見た目の描画をタスクバー風に
するのはわりと簡単。
でも、これ、見た目にかかわらずウィンドゥの移動やxボタンが効いてしまうんだよなぁ・・・
このシートだけは特殊なので、if文で判断させてはじいてみよう。
まずはbootpac.hのsheet構造体にパラメータ用の変数を追加してと。
お!? パラメータの分岐部で、クローズボタンの処理発見!
ここあわせてなかったな。ついでに修正・・・っと。
お!? タイトルバー部のアクティブ非アクティブの部分も邪魔だな。
条件分岐追加・・・っと。
|
10月 18 (木曜日) 2007
|
23:00
|
時計完成
|
|
時計でけたーーーー!
━━━━━━(゜∀゜)━━━━━━
まだ処理や修正がショボ〜い時計だけど、とにもかくにも時計、
そしてそれを管轄するタスクが完成した!!!
さ〜て・・・どうしよう?
ふとおもったんだけど、この時計タスク&ウィンドゥそのものを、
タスクバーとして配置しちゃだめかな???
リビジョン14
|
17:47
|
バグ?
|
|
あっれえぇぇぇぇ???
正常に動作してるのに、ずーっと動かしてるとqemuが落ちるなぁ?
なんでーー?
(こういうのは大抵、メモリなんだよなぁ)
・・・メモリ関係をいいかげんに写したツケかな・・・・
ちょっとチェック(というか、復習)してみよう。
:
//メモリの定義??
struct MEMMAN *testmemman = (struct MEMMAN *) MEMMAN_ADDR;
:
//このシートに書きこめるよう、バッファを確保する。
//大きいのでmemman_allocを使う(画素分)
unsigned char *testbuf=(unsigned char *) memman_alloc_4k(testmemman,400*200);
:
//このタスクで使うfifoバッファを確保する
int *testfifo = (int *) memman_alloc_4k(testmemman,128*8);
//タスクのレジスタを初期化
testtask->cons_stack = memman_alloc_4k(testmemman,64*1024);
testtask->tss.esp = testtask->cons_stack + 64 * 1024 - 12;
//タスクの実行関数のアドレスを当て込む
testtask->tss.eip = (int) &test_task;
:
//タスクが持つfiroに当て込みを行う
fifo32_init(&testtask->fifo, 128, testfifo, testtask);
あやしいのはたぶんこの辺・・・
えっと・・・まずはここ。
//メモリの定義??
struct MEMMAN *testmemman = (struct MEMMAN *) MEMMAN_ADDR;
これはいらないでしょう!
メモリマネージャはひとつで十分のはず。わざわざ別のを作る必要はないはず。
これもあやしいなぁ。
//このタスクで使うfifoバッファを確保する
int *testfifo = (int *) memman_alloc_4k(testmemman,128*8);
fifoの各データはint型のはず。int fifobuf[128] と同じだけのメモリが欲しければ128*4じゃないか? (intは4バイトだから)
おぉ!!!!!
この状態で約2時間動かしたけど落ちないぞ!??(^^
とりあえず暫定的にこれで大丈夫つーーーことで!!
リビジョン13
|
16:21
|
キーデータ等を受け取れるように2
|
|
わかったーーーーー━━━━━━(゜∀゜)━━━━━━ !!!!!
やっぱりそうかP501。完全に見落としてたよ!
//テストウィンドゥ
//メモリの定義??
struct MEMMAN *testmemman = (struct MEMMAN *) MEMMAN_ADDR;
//まず下敷きをもらってくる
struct SHEET *testsht = sheet_alloc(shtctl);
//このシートに書きこめるよう、バッファを確保する。
//大きいのでmemman_allocを使う(画素分)
unsigned char *testbuf=(unsigned char *) memman_alloc_4k(testmemman,400*200);
//このバッファをtestwin下敷きで使用できるように当て込む
sheet_setbuf(testsht,testbuf,400,200,-1);
//バッファにウィンドゥを作成する
make_window8(testbuf,400,200,"testwin",0);
//新しいタスクを作るため、taskmanからタスクをもらってくる
struct TASK *testtask = task_alloc();
//このタスクで使うfifoバッファを確保する
//ここで確保しておかないとダメ。タスク内部では
//セグメントがずれちゃうから(char buf[128]と同じ意味)
int *testfifo = (int *) memman_alloc_4k(testmemman,128*8);
//タスクのレジスタを初期化
testtask->cons_stack = memman_alloc_4k(testmemman,64*1024);
testtask->tss.esp = testtask->cons_stack + 64 * 1024 - 12;
//タスクの実行関数のアドレスを当て込む
testtask->tss.eip = (int) &test_task;
testtask->tss.es = 1 * 8;
testtask->tss.cs = 2 * 8;
testtask->tss.ss = 1 * 8;
testtask->tss.ds = 1 * 8;
testtask->tss.fs = 1 * 8;
testtask->tss.gs = 1 * 8;
//これは実行関数に渡す引数(引数 *sheetを渡す)
*((int *) (testtask->tss.esp + 4)) = (int) testsht;
//最後に、sheetからでもタスクが解るようにsheet構造体にこのタスクを当て込む
testsht->task = testtask;
//タスクを走らせる
task_run(testtask, 2, 2); /* level=2, priority=2 */
//タスクが持つfiroに当て込みを行う
fifo32_init(&testtask->fifo, 128, testfifo, testtask);
//===========================================================
結局はこういうことだった。
メインであるtask_aはキーボードデータを受け取る。しかしその
データは複数のウィンドゥ(タスク)のどれに転送したらいいのか
わからない。そこで、key_winという変数によって、今一番上の
状態(アクティブ?)に
なっているsheetを記憶しておく。
そのシートを管轄しているタスクのfifoに転送しようとするわけ。
sheet構造体内部に、「俺はxxタスクさんの子分だよ!」という
値がある。ここに親分の名前(タスク)を当てておかないと
いけない。
これが当たっていれば親分がわかる。その親分の別の子分(そのタスクのfifo)にデータが送られる。
これが抜けてたんだね!!!
よーーし!
いよいよ時計にチャレンジ!
リビジョン12
|
14:19
|
キーデータ等を受け取れるように
|
|
えーーーっと! これかなぁ?P501。
|
13:30
|
タスク再設置でけた
|
|
実験用のタスクを設置することができたぞ!!
とりあえずこんなの。
:
:
//テストウィンドゥ
//=============================
//メモリの定義??
struct MEMMAN *testmemman = (struct MEMMAN *) MEMMAN_ADDR;
//まず下敷きをもらってくる
struct SHEET *testsht = sheet_alloc(shtctl);
//このシートに書きこめるよう、バッファを確保する。
//大きいのでmemman_allocを使う(画素分)
unsigned char *testbuf=(unsigned char *) memman_alloc_4k(testmemman,400*200);
//このバッファをtestwin下敷きで使用できるように当て込む
sheet_setbuf(testsht,testbuf,400,200,-1);
//バッファにウィンドゥを作成する
make_window8(testbuf,400,200,"testwin",0);
//新しいタスクを作るため、taskmanからタスクをもらってくる
struct TASK *testtask = task_alloc();
//このタスクで使うfifoバッファを確保する
int *testfifo = (int *) memman_alloc_4k(testmemman,128*4);
//タスクのレジスタを初期化
testtask->cons_stack = memman_alloc_4k(testmemman,64*1024);
testtask->tss.esp = testtask->cons_stack + 64 * 1024 - 12;
//タスクの実行関数のアドレスを当て込む
testtask->tss.eip = (int) &test_task;
testtask->tss.es = 1 * 8;
testtask->tss.cs = 2 * 8;
testtask->tss.ss = 1 * 8;
testtask->tss.ds = 1 * 8;
testtask->tss.fs = 1 * 8;
testtask->tss.gs = 1 * 8;
//これは実行関数に渡す引数(引数 *sheetを渡す)
*((int *) (testtask->tss.esp + 4)) = (int) testsht;
// *((int *) (testtask->tss.esp + 8)) = memtotal;
//タスクを走らせる
task_run(testtask, 2, 2); /* level=2, priority=2 */
//タスクが持つfiroに当て込みを行う
fifo32_init(&testtask->fifo, 128, testfifo, testtask);
:
:
void test_task(struct SHEET *sheet){
struct TASK *task = task_now();
struct TIMER *timer1 = timer_alloc();
int i;
char s[20];
int counter = 0;
timer_init(timer1,&task->fifo,10);
timer_settime(timer1,1000);
for(;;){
counter++;
if (counter > 100000){counter = 0;}
io_cli();
if (fifo32_status(&task->fifo) ==0){
io_sti();
}
else{
i = fifo32_get(&task->fifo);
io_sti();
}
sprintf(s,"counter=%06d",counter);
putfonts8_asc_sht(sheet,32,32,COL8_008484,COL8_FFFFFF,s,14);
}
}
や〜っとタスク設置のパターンを把握できた〜・・・
でもこれ、まだ問題があるんだよね。このtesttaskウィンドゥにキーボードデータがいくと(キーを押したりすると)
フリーズして画面が壊れちゃう・・・
これはたぶん、task_aのfifoが受け取ったキーデータの行き先とかの
処理をなんにもしてないせいだと思うんだけど、どこだったっけ・・・
リビジョン11
|
|