1: 2007-01-23 (火) 12:01:45 |
現: 2024-01-06 (土) 22:39:09 |
| int p; | | int p; |
| char reza; | | char reza; |
| + | |
| struct FIFO32 timerfifox; | | struct FIFO32 timerfifox; |
| struct TIMER *timerx; | | struct TIMER *timerx; |
| int timerbuf[128]; | | int timerbuf[128]; |
| + | |
| fifo32_init(&timerfifox,128,timerbuf,0); | | fifo32_init(&timerfifox,128,timerbuf,0); |
| + | |
| timerx = timer_alloc(); | | timerx = timer_alloc(); |
| timer_init(timerx,&timerfifox,128); | | timer_init(timerx,&timerfifox,128); |
| timer_settime(timerx,100); | | timer_settime(timerx,100); |
- | | + | |
- | | + | |
| + | |
| //3秒待ち | | //3秒待ち |
| for(;;){ | | for(;;){ |
| p = fifo32_get(&timerfifox); | | p = fifo32_get(&timerfifox); |
| if (counter == 0){break;} | | if (counter == 0){break;} |
| + | |
| if( p == 128 ){ | | if( p == 128 ){ |
| sprintf(s, "Wait %dSec...\n",counter); | | sprintf(s, "Wait %dSec...\n",counter); |
| io_sti(); | | io_sti(); |
| } | | } |
| + | |
| io_sti(); | | io_sti(); |
| + | |
| //0x03f4のチェック | | //0x03f4のチェック |
| sprintf(s, "Check 0x03f4"); | | sprintf(s, "Check 0x03f4"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| cons_newline(cons); | | cons_newline(cons); |
| + | |
| char a; | | char a; |
| a = io_in8(0x03f4);a = a & 0x11; | | a = io_in8(0x03f4);a = a & 0x11; |
| cons_newline(cons); | | cons_newline(cons); |
| } | | } |
| + | |
| //コマンドの送信 | | //コマンドの送信 |
| sprintf(s, "Start command send..."); | | sprintf(s, "Start command send..."); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| cons_newline(cons); | | cons_newline(cons); |
- | | + | |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x07); | | io_out8(0x03f5, 0x07); |
| sprintf(s, "Send 0x03f5 [0x07]\n"); | | sprintf(s, "Send 0x03f5 [0x07]\n"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| + | |
| io_out8(0x03f5, 0x00); | | io_out8(0x03f5, 0x00); |
| sprintf(s, "Send 0x03f5 [0x00]\n"); | | sprintf(s, "Send 0x03f5 [0x00]\n"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| //--------------------------------------- | | //--------------------------------------- |
- | | + | |
| + | |
| //DMAの初期化 | | //DMAの初期化 |
| io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */ | | io_out8(0x00d6, 0xc0); /* マスタのch0をカスケードモードに */ |
| io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */ | | io_out8(0x00c0, 0x00); /* スレーブのDMAを許可 */ |
| io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */ | | io_out8(0x000a, 0x06); /* マスタのch2のDMAをマスク */ |
| + | |
| //読み込み用にセットアップ | | //読み込み用にセットアップ |
| //モード設定:デマンド・アドレス増加方向・メモリへの書き込み・ch2 | | //モード設定:デマンド・アドレス増加方向・メモリへの書き込み・ch2 |
| io_out8(0x0005, 0xff); | | io_out8(0x0005, 0xff); |
| io_out8(0x0005, 1 * 2 - 1); | | io_out8(0x0005, 1 * 2 - 1); |
- | | + | |
| + | |
| /* メモリ番地の設定 */ | | /* メモリ番地の設定 */ |
| io_out8(0x0004, 0x000a0000 & 0xff); | | io_out8(0x0004, 0x000a0000 & 0xff); |
| io_out8(0x0004, (0x000a0000 >> 8) & 0xff); | | io_out8(0x0004, (0x000a0000 >> 8) & 0xff); |
| io_out8(0x0081, (0x000a0000 >> 16) & 0xff); | | io_out8(0x0081, (0x000a0000 >> 16) & 0xff); |
- | | + | |
| + | |
| io_out8(0x000a, 0x02); /* マスタのch2のDMAをマスク解除 */ | | io_out8(0x000a, 0x02); /* マスタのch2のDMAをマスク解除 */ |
| + | |
| //読み込み用のFDCコマンド発行! | | //読み込み用のFDCコマンド発行! |
| // (FDCへのコマンド送信開始)(FATの情報を) | | // (FDCへのコマンド送信開始)(FATの情報を) |
| + | |
| //E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF] (INT) | | //E6] [H<<2] [C] [H] [S] [02] [12] [01] [FF] (INT) |
| //: [ST0] [ST1] [ST2] [C] [H] [S] [02] | | //: [ST0] [ST1] [ST2] [C] [H] [S] [02] |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0xE6); | | io_out8(0x03f5, 0xE6); |
| sprintf(s, "Send [E6],"); | | sprintf(s, "Send [E6],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x00<<2); | | io_out8(0x03f5, 0x00<<2); |
| sprintf(s, "[0x00<<2],"); | | sprintf(s, "[0x00<<2],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x01); | | io_out8(0x03f5, 0x01); |
| sprintf(s, "[0x01],"); | | sprintf(s, "[0x01],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x00); | | io_out8(0x03f5, 0x00); |
| sprintf(s, "[0x00],"); | | sprintf(s, "[0x00],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x01); | | io_out8(0x03f5, 0x01); |
| sprintf(s, "[0x01],"); | | sprintf(s, "[0x01],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x02); | | io_out8(0x03f5, 0x02); |
| sprintf(s, "[0x02],"); | | sprintf(s, "[0x02],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x12); | | io_out8(0x03f5, 0x12); |
| sprintf(s, "[0x12],"); | | sprintf(s, "[0x12],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0x01); | | io_out8(0x03f5, 0x01); |
| sprintf(s, "[0x01],"); | | sprintf(s, "[0x01],"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0x80 ){} | | while(io_in8(0x03f4) & 0xC0 != 0x80 ){} |
| io_out8(0x03f5, 0xFF); | | io_out8(0x03f5, 0xFF); |
| sprintf(s, "[0xFF]\n"); | | sprintf(s, "[0xFF]\n"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| // (FDCが実行) | | // (FDCが実行) |
| + | |
| //3秒待ち | | //3秒待ち |
| counter=3; | | counter=3; |
| p = fifo32_get(&timerfifox); | | p = fifo32_get(&timerfifox); |
| if (counter == 0){break;} | | if (counter == 0){break;} |
| + | |
| if( p == 128 ){ | | if( p == 128 ){ |
| sprintf(s, "Wait %dSec...\n",counter); | | sprintf(s, "Wait %dSec...\n",counter); |
| io_sti(); | | io_sti(); |
| } | | } |
| + | |
| io_sti(); | | io_sti(); |
- | | + | |
| + | |
| // (FDCからのINT) | | // (FDCからのINT) |
| sprintf(s, "Come on! INT!\n"); | | sprintf(s, "Come on! INT!\n"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| // (FDCからリザルトステータス読み取り) | | // (FDCからリザルトステータス読み取り) |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "[ST0]&0xC0=%X,",reza & 0xC0); | | sprintf(s, "[ST0]&0xC0=%X,",reza & 0xC0); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "ST1=%X,",reza); | | sprintf(s, "ST1=%X,",reza); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "ST2=%X,",reza); | | sprintf(s, "ST2=%X,",reza); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "[C]=%X,",reza); | | sprintf(s, "[C]=%X,",reza); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "[H]=%X,",reza); | | sprintf(s, "[H]=%X,",reza); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| sprintf(s, "[S]=%X\n",reza); | | sprintf(s, "[S]=%X\n",reza); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| + | |
| while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} | | while(io_in8(0x03f4) & 0xC0 != 0xC0 ){} |
| reza = io_in8(0x03f5); | | reza = io_in8(0x03f5); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| //------------------------------------------- | | //------------------------------------------- |
| + | |
| //マスタのch2のDMAをマスク */ | | //マスタのch2のDMAをマスク */ |
| io_out8(0x000a, 0x06); | | io_out8(0x000a, 0x06); |
- | | + | |
- | | + | |
| + | |
| char *vvv; | | char *vvv; |
| vvv = 0x000a0000; | | vvv = 0x000a0000; |
| + | |
| for(;;){ | | for(;;){ |
| vvv++; | | vvv++; |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
| } | | } |
| + | |
| sprintf(s, "End...\n"); | | sprintf(s, "End...\n"); |
| cons_putstr0(cons, s); | | cons_putstr0(cons, s); |
- | | + | |
- | | + | |
| + | |
| timer_free(&timerx); | | timer_free(&timerx); |
| return; | | return; |
| } | | } |
| /*---------------------*/ | | /*---------------------*/ |
| + | |
| + | さて、じゃ、なんで前はうまくいかなかったのか?ってことだけど、 |
| + | --送信コマンドを間違えていた <バカ |
| + | --DMAの設定をイマイチ理解していない |
| + | |
| + | まず、送信コマンド。2のコード見てもらえばわかるよね?。間違ってます・・・orz |
| + | |
| + | |
| + | さて、次にもう一個。DMACの設定部分。 |
| + | |
| + | Kタンのサンプルで一番解らなかったのが、 |
| + | |
| + | io_out8(0x0005, 0xff); io_out8(0x0005, セクタ数 * 2 - 1); /* バイト数の設定 */ |
| + | io_out8(0x0004, 番地 & 0xff); io_out8(0x0004, (番地 >> 8) & 0xff); |
| + | io_out8(0x0081, (番地 >> 16) & 0xff); /* メモリ番地の設定 */ |
| + | |
| + | この、セクタ数や番地のこと。 |
| + | |
| + | これ、よーく考えてみて初めて意味がわかった。まず、io_out8ってことは、''全てのデータは8bit''だということ! |
| + | |
| + | そう。8bit。0x00〜0xFF(十進数で256) までしか設定できないわけ。 |
| + | |
| + | 「え?それじゃ、セクター(512)を設定したり、バッファのメモリ番地を0x000a0000に設定したりはできないの!?」 |
| + | |
| + | と、こういう話になりますね?。 |
| + | |
| + | ここらへんのレジスタは特殊で、同じレジスタに連続で2回とか書き込むと16bitや20bitと解釈してくれるという。エラク特殊な形なんですねぇ〜。(なーーんだ!) |
| + | |
| + | だから、もう一度上のサンプルを良く見ると、こんなふうに割れませんか? |
| + | |
| + | /* バイト数の設定 */ |
| + | io_out8(0x0005, 0xff); |
| + | io_out8(0x0005, セクタ数 * 2 - 1); |
| + | |
| + | /* メモリ番地の設定 */ |
| + | io_out8(0x0004, 番地 & 0xff); |
| + | io_out8(0x0004, (番地 >> 8) & 0xff); |
| + | io_out8(0x0081, (番地 >> 16) & 0xff); |
| + | |
| + | そう。こうやって、一見無意味に複数回書き込んでいるのがまさにそれなんです。 |
| + | |
| + | ''さらに!!''。セクタ数や番地の後ろにあるヘンテコな計算式。これは、8bit以上になる各数値を自動的に8bitに切り出してくれる計算式なんですねぇ〜。 |
| + | |
| + | じゃ、たとえば、セクターを一つだけ。DMAバッファを0x000a0000番地にして読み込みを行いたいとしましょう。 |
| + | |
| + | セクター1個は通常512バイト。16進数にすると、0x0200になるよね。で、OS-Wikiの資料によると、 |
| + | |
| + | データ転送はDMAのTC(ターミナルカウント)に依存しており、この仕様のために、カウント値は実際の転送量-1をセットする。 |
| + | |
| + | とのことなので、ここは 0x0200 - 1 = 0x01FF をセットします。 |
| + | |
| + | ほらね!!! |
| + | io_out8(0x0005, 0xFF); |
| + | io_out8(0x0005, 0x01); <- セクタ数(1個) * 2 - 1 = 1なので。 |
| + | |
| + | 同じくDMAバッファのメモリ番地の設定。DMAバッファは仕様上、0x00ffffff以下でないと設置できません。よーく見て。最大は0xffffffでしょ? つまり、8bit三回分だよね? |
| + | |
| + | 今回の例。0x0a0000を設置したいとした場合、こうなる! |
| + | |
| + | io_out8(0x0004, 0x00); <- 0x0a0000 & 0xff = 0 |
| + | io_out8(0x0004, 0x00); <- (0x0a0000 >> 8) & 0xff = 0 |
| + | io_out8(0x0081, 0x0a); <- (0x0a0000 >> 16) & 0xff = 0a |
| + | |
| + | ほらね。こういう書式になるわけ。ちょっと値を複雑にしてみるともっと解るよ。 |
| + | |
| + | 例:0xa1b2c3 番地を設定したい場合 |
| + | |
| + | io_out8(0x0004, 0xc3); <- 0xa1b2c3 & 0xff = c3 |
| + | io_out8(0x0004, 0xb2); <- (0xa1b2c3 >> 8) & 0xff = b2 |
| + | io_out8(0x0081, 0xa1); <- (0xa1b2c3 >> 16) & 0xff = a1 |
| + | |
| + | これでもう、解ったでしょ〜? (^^ |