|
71:Re: nask hideyosi 10/11 20:37 えーっと。なになに? アセンブラでは、周辺機器との入出力には、「IN・OUT」命令を使うと・・・。 周辺機器はいっぱいある。(キーボードだったりディスプレイだったり・・・)この場合、「どの周辺機器のデータを持ってくる?」という指定が必要になるな。 なにしろアセンブラだから、きっと8ビットとか16ビットの番号が振ってあって、ある程度決め打ちになっていると思われる。 こういうのの一覧表ってあるのかな? 72:Re: nask hideyosi 10/11 20:41 うーん・・・・これなのかなぁ? http://community.osdev.info/index.php?cmd=read&page=%28AT%29iomap ・・・ん? ある入門書に、入出力の実験には、システムスピーカーが最適とある。えーっと。システムスピーカーの番号は・・・・ え” 0061番!? あっれー? OS Wikiのデータだと、「システムステータス」となっているぞ??? 73:BEEP -- K 10/11 20:47 これをみれば、もしかしたら分かるかな? http://community.osdev.info/index.php?(PIT)8254 というか、つまり、システムポートというところがあって、 それはI/Oポートの0x0061番で、そこにはいろんな機能があって、 その一つがBEEP制御なのです。 74:Re: BEEP hideyosi 10/11 22:31 >というか、つまり、システムポートというところがあって、 >それはI/Oポートの0x0061番で、そこにはいろんな機能があって、 >その一つがBEEP制御なのです。 ・・・あぁぁぁぁぁ!!! なるほどぉ!!! つまり、0061番のI/Oポートは、それ1つで「BEEP」だとか、「xxx」とかの機能をもっているんじゃなくて、そのビットひとつ1つに意味があるのか!!! ・・・うへぇ! じゃ、0061番地に単純に0x○○を代入するのはまずいのか!!!! だって、他のビットがなにか意味をもっている場合、そいつを勝手に書き換えちゃうと、なんか勝手に動作とかしちゃうじゃないか! うむむむ・・・・ ってことは、0061番地の、一ビット目と2ビット目だけを、1にしなきゃいけないわけだ。 ・・・うはぁ! もしかして、「ビットシフト」とかなんとかをやらなくちゃいけないの??? ひえー・・・。まーた別の勉強しなくちゃ・・・(T∀T) 75:Re: BEEP hideyosi 10/11 23:04 わー! わかった!!!! ORだ!!! 76:Re: BEEP -- K 10/11 23:19 もしうまくいかなかったら、 http://community.osdev.info/index.php?(PIT)8254 の下のほうにある「ものぐさなひとのために」を参考にしてください。 77:Re: BEEP hideyosi 10/11 23:45 そんなわけで、こういうコードを書いた。 これで、ビープは鳴り出した。一応成功である。 なんか突っ込みあったら・・・(もっといい方法とか) --------------------------------------------- [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;----------------------------------------------------- ;-------- 実験部分 ---------------------- ;IN・OUTは、DXレジスタに、対象となるI/Oアドレスを ;入れてから行う。今回は0x0061 MOV DX,0x61 ;まず、現在の0x0061の内容を一旦持ってくる IN AL,DX ;持ってきた内容の内、一番目と2番目のビットだけ、1に ;する。そのためには、 00000011 すなわち、0x03で、 ;持ってきた内容にORをかける。こうすると、一番目と ;二番目だけが1になり、あとはそのまんま変化しない。 OR AL,0x03 ;出来上がった内容を、再び0x0061番地に書き戻す。 OUT DX,AL ;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20 ---------------------------------------------------------- 78:Re: BEEP hideyosi 10/11 23:58 キーボードの押されたキーの取得。 なになに? 押しっぱなしなのか、話したのかとかの判断もあるのか・・・うわー。こりゃ大変かもしれないぞ!? まあいいや。とにもかくにも、まずは取得してみる実験だ。 えーっと。「A」のキーが押されると、1Eが帰ってくるはず。 そうすると、たとえば、例の割り込み先に、 1、I/Oポート 0x0060 を読め! 2、読み込んできたデータを、0〜6に絞れ。 3、絞ったデータがもし 1E だったら、「A」が押されている。画面にAを書け! ・・・みたいな、こんな感じのコードを書けばいいのか! 79:Re: BEEP -- K 10/12 00:14 >押しっぱなしなのか、話したのかとかの判断もあるのか・・・ キーボードは結局ただのスイッチです。 スイッチが、 off→on になることをメイク(make)といいます。 逆に、 on→off になることをブレイク(break)といいます。 ということで、もし0x7fでANDしてしまうと、押したときも離したときもAが出ると思います(つまり1度おすと2つ出る)。 80:Re: BEEP hideyosi 10/14 22:27 さて。そんなわけで、私はとりあえずこんなコードを書いてみた。 ------------------------------------ [BITS 16] [OPTIMIZE 1] [OPTION 1] [INSTRSET "8086"] [FORMAT "BIN"] ORG 0x100 ;----------------------------------------------------- ;--- こっから上は、MS-DOSの.COMを作る時の ------------ ;----おまじないだと思ってくれい! ------------ ;----------------------------------------------------- ;-------- 実験部分 ---------------------- ;BIOSのキー入力を乗っ取る MOV AX,0 MOV ES,AX ; ESを0にする。 MOV WORD[ES:0x09*4+0],IINT09 MOV WORD[ES:0x09*4+2],CS MOV AX,DS MOV ES,AX ; ESをもとにもどす。 JMP MAINLLP ;メインループへジャンプ ;メインのループ部分 MAINLLP: JMP MAINLLP ;乗っ取ったキーボード割り込み部分 IINT09: ;押されたキーは何かを調べる ;IN命令で、押されたキーの値を取得 MOV DX,0x60 IN AL,DX ;持ってきた値の7ビットだけを抽出 AND AL,0x7F ;二進数 01111111 でANDSする ;もしその値が1Eだったら、Aボタンが押されている CMP AL,0x1E ;上のCPM命令によってキャリーフラブが変化している。 ;同じならZFが1,CFが0になっている ;もしそうなら、文字表示ルーチンをコールする JE MOJIPRINT ;そうでなかったら、割り込みから戻る IRET ;文字を表示するルーチン MOJIPRINT: MOV AL,0x41 MOV AH,0x0e INT 0x10 IRET ;----------------------------------------------------- ;---- これがないと、暴走しちゃうぞ! ------------- ;----------------------------------------------------- ;MS-DOS終了 INT 0x20 ----------------------------------------- ちなみにこれは、「一部成功一部アカン」でした。 これを実行し、「一回目」のキーボタンがAなら、ちゃんとAを表示していますが、それ以降は無反応になってしまいます。 ・・・っということは、「押されたのがAじゃなかった場合」の処理に問題があるのでしょう。えとえと。こういうのって、どうやってデバッグするのかな? もしかして、DEBUGコマンドを使うのかな??? |