K氏のheboOSをまねてみる

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コマンドを使うのかな???







1-

BluesBB ©Sting_Band