旧THE-BBL掲示板
もうあまり必要性がないので凍結しました。

[Returns to a topicAll  1-  Newest 50
K氏のheboOSをまねてみる
1 名前:hideyosi 2004/9/22 17:32  
OSASKのK(川合氏)が、OS作成に関するチュートリアルを公開している。ふむふむ。なになに?

あいかわらずKは口がうまい!

なんだか出来そうな気がしてくるじゃねーかよ! そんなわけで、思いつくまま体験をばしてみたり。

参考:
http://community.osdev.info/index.php?FirstStep

51 Re: feelさんへ  名前:hideyosi 2004/10/2 19:08  
>公開するのは全然構いません

わー。ありがとうございます!うれしいです。

>ここにソース載せたほうがいいですかね?それともリンクがいいですか?

feelさんが一番楽な方法で。(なにしろこっちはお願いする立場ですから (^^) )

たとえば、私にメールなどで送っていただいたりして頂ければ、
私のほうでHTMLに変換するなりさせて頂きますが。
ん? あ、そか。YARMAさんとこにあるのか。
YARMAさんとこから頂いて、とりあえず当方で公開なり研究なり。
っということでよろしいですか?

あ、あと、ライセンスなんですが。KL-01でいいですか?ほかになにかご希望とか?










52 Re: feelさんへ  名前:hideyosi 2004/10/2 19:15  
>>49
YARMAさんごめんなさい。表示が乱れてしまうので、
勝手ながら、元のメッセージを編集しました。
なにとぞご理解を。  ペコ m(_ _)m


53 Re: feelさんへ  名前:feel 2004/10/2 19:33  
私はライセンスとかはどうでもいいのでそちらにお任せします
一番最近のやつを渡したいので後でメールで送らせていただきます
ただ、今製作用のPCにOS入れてないのでちょっと待って下さい
それまでは古いほうでも見てて下さい
どちらもあまり誇れませんが・・・

54 Re: feelさんへ  名前:hideyosi 2004/10/2 19:54  
feelさん、気持ちよくご了承をしてくださり、ほんとうにありがとうございます。

>一番最近のやつを渡したいので後でメールで送らせていただきます

いやもう、ほんとにお暇な時にでも。楽しみに待たせて頂きます。

>私はライセンスとかはどうでもいいのでそちらにお任せします

了解いたしました。あ、でも、KL-01は、あとでいつでもライセンスの変更が容認されているライセンスですので、なにかありましたらいつでもご一報くださいね。

>どちらもあまり誇れませんが・・・

とんでもありません! 謹んで勉強させて頂きます。

55 Re: feelさんへ  名前:feel 2004/10/2 21:01  
良し、OK
Mandrakeインストール完了
で、さっきのメアドで送らせていただきます
で、もしものときの保険
http://jp.y42.briefcase.yahoo.co.jp
/bc/sutekata/lst?.dir=/&.view=
こちらにもおいておきます

56 Re: feelさんへ  名前:feel 2004/10/3 18:15  
コメント追加
リンクのみとさせていただきます
http://jp.y42.briefcase.yahoo.co.jp
/bc/sutekata/lst?.dir=/&.view=
前書いたやつと同じです
ああ、適当なこと書いてるかも・・・

57 Re: K氏のheboOSをまねてみる  名前:I.Tak. 2004/10/7 12:19  
独り言Wikiの NASK/文法 につっこみ! 誰もつっこまないのか……?

>MOV AX, AL
サイズの違う代入はできません。符号あり/なしの問題があるので,
MOVZX AX, AL ; 符号無し拡張
MOVSX DX, CL ; 符号付き拡張
を使います。

>MOV [0x100],[0x200]
MOVではメモリ間コピーはできません。

>MOV [0x100], 0x1F
メモリの大きさを指定してください。byteで書くべきところにwordで書いたら大変ですよ!

>ADD AL, AX
>SUB AL, AX
サイズの違う演算は(略

>JMP [0x400] ;「セグメント値+400」番地にジャンプし、実行を始める
こいつは "オフセット0x400からオフセット値(リアルモードではwordサイズ)を読み込んでそこへジャンプ" します。
ブラケット[]で囲ってあるのは LEA 以外全てメモリアクセスをするのです。
オフセット0x400 へのジャンプは単に JMP 0x400 とします。

>LOOP ; CXレジスタがゼロになっていない限り、指定したアドレスにジャンプする。
CXから1を引いて, 0にならない限り, 指定のオフセットへジャンプします。……が, ジャンプできる距離が -128〜127 と狭いので注意。

>LOOP [0x200]
LOOPはメモリからジャンプ先を読み込むことができません。必ずラベルを指定します。

>CALL
サブルーチン処理にジャンプする前に, 戻る場所のオフセット値をスタックに積みます。
RETで戻れるのはそういうカラクリなのです。


アドレスは必ずセグメントとオフセットの組で指定するものですが, セグメントから出る気がなければ, アドレス=オフセットで話は通じます
気合と余裕がありあまっていれば, Intelのマニュアルの中巻 (インストラクションマニュアル) を眺めてみると面白いかもしれませんよ。

58 Re: K氏のheboOSをまねてみる  名前: -- K 2004/10/7 12:48  
>誰もつっこまないのか……?

 あれはhideyosiさんによるhideyosiさんのためのメモだと思っているので、うわーわからん、もうどうしたらいいだー、「誰か教えて」というまでは、あれこれ言わないほうがいいと僕は思って、言いませんでした。

 理解には段階があって、今のうちから符号付き拡張・符号なし拡張をどうこういっても、かえってhideyosiさんは混乱しちゃうんじゃないかなあ。現段階としては何も分からなかった状態から、代入はMOV、加算はADD、減算はSUB、とかが把握できていることが快挙なので。英語で言えば基本動詞が理解できて、前置詞の細かい規則や、この言い回しはCPUの都合でできるとかできないとかは、ちょっとつらいのではないかと。

59 Re: K氏のheboOSをまねてみる  名前:I.Tak. 2004/10/7 16:05  
hideyosiさんが混乱しかねないというのは分かります。
しかし, ちょっとNASKを動かせば分かる間違いを公開したまま, というのはやはりどうかと思うのですよ。これがNASKの文法だ! というページですし……

60 Re: K氏のheboOSをまねてみる  名前:hideyosi 2004/10/7 18:19  
>しかし, ちょっとNASKを動かせば分かる間違いを公開したまま

いや、まったくI.Tak.さんのおっしゃる通りです。いろいろとやってメモしている真っ最中になんやかやと大忙しになってしまい、実験や検証をしないままけっこうそのまんまになってます。えらい粗相で、おはずかしいです。

いま、ちょっと忙しくて手がつけられません。とりあえず「勉強中、合ってないとこあり!」的なコメントを付加しておきます。


>NASKの文法だ! というページですし……

おっしゃるとおりです。私のポカだけならまだしも、これを見たどなたかが勘違いでもしてしまっては大変です。


>誰もつっこまないのか……?

>あれこれ言わないほうがいいと僕は思って、言いませんでした。

お二人のお気遣い、とてもありがたいと思っています。

しかし、いずれにしても、今ちょっとまったく動けない状態でして。(今夜が峠なんですよねぇ。明日になれば・・・)

恐縮ですが、今しばらくのご猶予を。

61 Re: K氏のheboOSをまねてみる  名前:YARMA 2004/10/7 18:51  
>しかし、いずれにしても、今ちょっとまったく動けない状態でして。(今夜が峠なんですよねぇ。明日になれば・・・)

もとはといえば結局僕が起こしたことがきっかけでこんなことになっちゃったんだよなぁ・・・
このプロジェクトを復活させようとしているhideyosiさんに本当に申し訳ない。こんな馬鹿な僕ですが、できる限り(これからは通りすがりとして)足手まといにならない程度に活動しようと思っています。本当にありがとう。

62 nask  名前: -- K 2004/10/7 20:28  
>hideyosiさんが混乱しかねないというのは分かります。
>しかし, ちょっとNASKを動かせば分かる間違いを公開したまま,
>というのはやはりどうかと思うのですよ。これがNASKの文法だ!
>というページですし……

 確かにその意味はわかります。つまり他の人が見るかもしれないわけで、正しくない情報はいかんということですよね。

 僕としては、hideyosiさんが「間違っている可能性あり」って明記してくれるそうなので、それで十分だと思っています(まあ無くてもいいかなとは思っていますが)。

 このWikiはhideyosiさんしか書けなくなっていて、つまり正しいよりよい情報を集めるということよりも、単にhideyosiさんのワークスペースを公開しちゃっただけ、に思うのです(確か最初にWikiを作ったときにも、自分の頭の整理のために作ったと書いていたような気がしますし)。

 間違いが気になるのは分かりますが、それならせめて、「○○という記述はやってみたけどうまく動かなかったよ」くらいの、障害報告程度でとめておくことはできないでしょうか。次々と正解を示すことは、かえってhideyosiさんがつらくなってしまうと思うんです。さらに、このスレッドをゆっくり追いかけてアセンブラを勉強する人が今後出てくるかもしれませんし、そんな人のためにも、hideyosiさんが自分のペースで学習できるように、協力していただけないでしょうか。

 もちろん、当のhideyosiさんがお手上げでhelpを求めたときは、その部分についての正解を示すことはとてもよいと思います(まあそのときも、できるだけ新しい知識に触れないようにしたいですが)。

63 Re: nask  名前: -- K 2004/10/7 20:39  
追伸:

 ちなみに僕は、書き間違いについても、できればhideyosiさんが自分で気がついてほしいと思っています。これでいけると思っていたけど、実はやってみたらうまくいかなかった、そんな過程でまたかしこくなっていくわけで。そういう過程をスキップさせてしまうことは、効率がいいかもしれませんが、なかなか身につかない結果になったりします。

 hideyosiさんが自分でなんとかがんばろうとしている間は、できる限りノーヒントでいましょうよ。頼まれもしないのにあれこれいうのは、控えめで。

 もしちゃんとしたnaskのサイトを作りたければ、それはI.Tak.さんや僕などが別途作ればいいと思うんです。hideyosiさんは、自分の学習のためにあのWikiを作ったのであって、他の人が満足するようなマニュアルを作ろうとはしていないと思うんです(もちろん、最後にはあのサイトは立派なマニュアルになるのかもしれませんが)。その辺の意図を汲んであげてほしいんです。

64 Re: nask  名前:I.Tak. 2004/10/8 14:21  
考えてみると, 確かにお節介が過ぎたようです。IntelなりNASMなりのマニュアルに誘導するだけで十分だったと反省しています。
検索などで一部のページのみを見られることもありますから, hideyosiさんがSOSを出すまで完全に放置しようとは思いませんが (←NASKユーザとしての一種のファン意識), 生暖かく見守ることにします。

65 Re: nask  名前:hideyosi 2004/10/9 15:35  
>考えてみると, 確かにお節介が過ぎたようです。

えーー! そんなぁ! そんなこといわずに、お節介焼いてください!


>NASKユーザとしての一種のファン意識

いやいやいや!これはよーく解りますよ。たしかにあのまんまじゃ、「おい知ってるか?ガンダムってさ、ロボットで、合体するんだぜ?」って言われてるよーなもんですもんね。

おかげさまで、例の件はほとんど片付きました。いよいよアセンブラのお勉強再開です。どうぞ、生暖かくと言わず、サイリックスのCPUの如く見守ってくださいませ。 m( )m

66 Re: nask  名前:hideyosi 2004/10/9 15:39  
さーて。それではオゲンキョ再開。

KタンやI.Tak.さんのおかげで、キーボードの乗っ取りはできるようになった。

こんどは、その乗っ取った後の処理をかんがえなくちゃ。
一番最初にしなくちゃいけないのが、「なんのキーが押されたか?」という処理。

えーと・・・・どこいらへんから手をつけようかな???

67 Re: nask  名前:MiSt 2004/10/9 19:27  
THE-BBLからは退会しましたが、
このPJの様子を時々見守らせてもらっております。
で、
http://konoxos.client.jp/src/1.0/a4/000004/shell.asm
に、昔の16bitKONOXのシェルソースがあります。(NASMですが)

参考程度にどうぞ。

68 Re: nask  名前:MiSt 2004/10/9 19:27  
ちなみに上のshell.asmはリアルで動作します。

では、失礼します。

69 Re: nask  名前:feel 2004/10/9 22:39  
確か
MOV AH,00H
INT 16H
で、ALにコードが出力されたような気がします
ここで使うのかどうかは分かりませんが・・・

http://lrs.fmi.uni-passau.de/support/doc/
interrupt-57/INT.HTM
こことか見ると良いかもしれません

70 Re: nask  名前:YARMA 2004/10/10 10:12  
↑このページどっかで見たことがあるな・・・

あ、そだ、THE-BBLのWikiにあったあった。
たしか、昔破壊したページで今は「過去の遺跡」に納められてたっけw
あ、でも、もう「お袋」は抹消して、バックアップにしか残ってないやぁ

(「お袋」とは?・・・昔Wikiにあった掲示板。今は通りすがり3の意見により、破壊済み。Ofukuro has already been clashed.(←英文あってるか気にしないでください。

で、「お袋」に.oOo.氏が

ここには初めて書き込みます。 参考に→ http://www.ctyme.com/
intr/int.htm -- .oOo.? 2004-08-24 (火) 00:56:48

と、・・・あれ、アドレスが違うぞ?まぁ、ぃぃゃ気にしない

71 Re: nask  名前:hideyosi 2004/10/11 20:37  
えーっと。なになに?
アセンブラでは、周辺機器との入出力には、「IN・OUT」命令を使うと・・・。

周辺機器はいっぱいある。(キーボードだったりディスプレイだったり・・・)この場合、「どの周辺機器のデータを持ってくる?」という指定が必要になるな。

なにしろアセンブラだから、きっと8ビットとか16ビットの番号が振ってあって、ある程度決め打ちになっていると思われる。
こういうのの一覧表ってあるのかな?

72 Re: nask  名前:hideyosi 2004/10/11 20:41  
うーん・・・・これなのかなぁ?

http://community.osdev.info/index.php?cmd=read&page=%28AT%29iomap

・・・ん? ある入門書に、入出力の実験には、システムスピーカーが最適とある。えーっと。システムスピーカーの番号は・・・・

え” 0061番!? あっれー? OS Wikiのデータだと、「システムステータス」となっているぞ???

73 BEEP  名前: -- K 2004/10/11 20:47  
これをみれば、もしかしたら分かるかな?

http://community.osdev.info/index.php?(PIT)8254

というか、つまり、システムポートというところがあって、
それはI/Oポートの0x0061番で、そこにはいろんな機能があって、
その一つがBEEP制御なのです。

74 Re: BEEP  名前:hideyosi 2004/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 2004/10/11 23:04  
わー! わかった!!!! ORだ!!!

76 Re: BEEP  名前: -- K 2004/10/11 23:19  
もしうまくいかなかったら、

http://community.osdev.info/index.php?(PIT)8254

の下のほうにある「ものぐさなひとのために」を参考にしてください。

77 Re: BEEP  名前:hideyosi 2004/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 2004/10/11 23:58  
キーボードの押されたキーの取得。

なになに? 押しっぱなしなのか、話したのかとかの判断もあるのか・・・うわー。こりゃ大変かもしれないぞ!?

まあいいや。とにもかくにも、まずは取得してみる実験だ。

えーっと。「A」のキーが押されると、1Eが帰ってくるはず。
そうすると、たとえば、例の割り込み先に、

1、I/Oポート 0x0060 を読め!
2、読み込んできたデータを、0〜6に絞れ。
3、絞ったデータがもし 1E だったら、「A」が押されている。画面にAを書け!

・・・みたいな、こんな感じのコードを書けばいいのか!

79 Re: BEEP  名前: -- K 2004/10/12 0:14  
>押しっぱなしなのか、話したのかとかの判断もあるのか・・・

キーボードは結局ただのスイッチです。
スイッチが、 off→on になることをメイク(make)といいます。
逆に、 on→off になることをブレイク(break)といいます。

ということで、もし0x7fでANDしてしまうと、押したときも離したときもAが出ると思います(つまり1度おすと2つ出る)。

80 Re: BEEP  名前:hideyosi 2004/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コマンドを使うのかな???






81 割り込み処理  名前: -- K 2004/10/14 23:52  
 おめでとうございます!

>これを実行し、「一回目」のキーボタンがAなら、ちゃんとAを表示していますが、それ以降は無反応になってしまいます。

 いや、それでよいのです。なぜ無反応になってしまったかというと、割り込み処理が完了したことを、CPUにしか知らせてないからです。

 くわしいことは、

  http://community.osdev.info/index.php?(PIC)8259A

をじっくりと見てください(特に最後の「ものぐさなあなたのために」を見逃さないように)。

82 Re: 割り込み処理  名前:hideyosi 2004/10/16 15:45  
ふむ!?

Kタンのhttp://community.osdev.info/index.php?(PIC)8259Aをジックリと読んでみた。
・・・むずかしくてわかりません・・・(T∀T)

しかし、そんなぼくらのために(ヲレだけかも)「ものぐさ」というセクションがあった。

ようするにはこういうことらしい。
●割り込みは、CPUの機能だが、その割り込みの発生・CPUへの発注・関所を行うLSIがあるらしい。
●このLSIは、キーボードなどから信号が来ると、割り込み信号を作って、CPUに「おい!割り込みがきたぞー!」と知らせ、CPUでは割り込みが発生する。
●CPU(アセンブラのプログラム部)では、割り込み時に必要な処理は行う。で、その処理が終わったら、IRETで戻ってくる。(つまり、CPUとしては、割り込みは終了している)
●問題は、さっきのLSI。この時点では、まだ、「割り込みがキタゾー!」のまんま。つまり、次の割り込みは待たされている
●つまり、このLSIにも、「CPUとしては、割り込み処理はもう終わったよ。次の割り込みを受け付けていいよ。たのむね」と、教えてあげなくてはいけないらしい。

そのためのコードが、これらしい。

AL = 割り込み番号 + 0x60; OUT(0x20, AL);

83 Re: 割り込み処理  名前:hideyosi 2004/10/16 16:15  
うーーーん・・・
AL = 割り込み番号 + 0x60; OUT(0x20, AL);
これはどういうことだろう。こういうことなのかな???

-----------------------------------------

[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

;そうでなかったら、割り込みから戻る
JMP INTEND


;文字を表示するルーチン
MOJIPRINT:
MOV AL,0x41
MOV AH,0x0e
INT 0x10

JMP INTEND


;割り込み後は、この処理をしないと戻れない
INTEND:
MOV AL,0x09
ADD AL,0x60
MOV DX,0x20
OUT DX,AL

IRET

;-----------------------------------------------------
;---- これがないと、暴走しちゃうぞ! -------------
;-----------------------------------------------------
;MS-DOS終了
INT 0x20

-----------------------------------------

・・・ところが、これだとうまくいかないんだよねぇ。なんでだろう????

84 Re: 割り込み処理  名前:hideyosi 2004/10/16 16:22  
っはっはぁぁぁぁ。
なるほどぉ!
この場合の「割り込み番号」って、IRQ番号を使うんだぁ!
えーっと、キーボードのIRQって・・・・1か!

つまり、こうするわけか?

-----------------------------------------

[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

;そうでなかったら、割り込みから戻る
JMP INTEND


;文字を表示するルーチン
MOJIPRINT:
MOV AL,0x41
MOV AH,0x0e
INT 0x10

JMP INTEND


;割り込み後は、この処理をしないと戻れない
INTEND:
MOV AL,0x01 ;キーボードの割り込み(IRQ)
ADD AL,0x60 ;その番号に、60を足した値
MOV DX,0x20
OUT DX,AL

IRET

;-----------------------------------------------------
;---- これがないと、暴走しちゃうぞ! -------------
;-----------------------------------------------------
;MS-DOS終了
INT 0x20

-----------------------------------------

おぉぉ!!! うまくいったぞ!!!!
逆にKタンの懸念どおり、一回押せば2回Aが出てしまうってのもちゃんと?再現。

よぉぉぉぉし!!!!!!!うまくいったぞ!!!

85 Re: 割り込み処理  名前:hideyosi 2004/10/16 19:16  
さてさて。この実験用のショボイコードも、けっこういろいろと
できるようになってきた。
これを、とにもかくにもOSっぱく見えるところまで仕上げてみよう。
そのためには、

1、プロンプトを表示してみよう
2、例の、一回押すと二個文字がでる現象をなんとかする
3、キーボードからの文字をちゃんと認識できるようにする
4、一個ぐらい、コマンドを実装したいなぁ(clsとか)

そんなわけで、まずは2から手をつけよう。

86 Re: 割り込み処理  名前:hideyosi 2004/10/16 22:04  
まず、キーボードからやってくる、「押されたキー信号」は、
0〜6までがキーを示す値。で、最後の7bit目が、「押したのか・離したのか」をあらわします。
今現在、私のコードでは、押して一回、離して一回と割り込みを処理してしまっていますので、一回キーを押すと二回「A」が表示されます。
「キーが離されたときだけ」という反応をすれば、OKなのではと考えました。

今現在はこういうコード。

---------------------------------------------------
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

;そうでなかったら、割り込みから戻る
JMP INTEND
-----------------------------------------------------

これを、こうしてみたらどうだろ?

------------------------------------------------------
IINT09:
;押されたキーは何かを調べる
;IN命令で、押されたキーの値を取得
MOV DX,0x60
IN AL,DX

;持ってきた値を一時、AHに複製する
MOV AH,AL
;AHに複製した値の7ビット目だけを摘出
AND AH,0x80
;もし、この結果の値が00000000すなわち0x0なら、
;キーは「押された」となるはず。ここで条件分岐
CMP AH,0x0

;なにもせずに割り込みを終了する
JE INTEND

;違うなら、キーは「離されて」いる。
;持ってきた値の7ビットだけを抽出
AND AL,0x7F ;二進数 01111111 でANDSする

;もしその値が1Eだったら、Aボタンが押されている
CMP AL,0x1E

;上のCPM命令によってキャリーフラブが変化している。
;同じならZFが1,CFが0になっている
;もしそうなら、文字表示ルーチンをコールする

JE MOJIPRINT

;そうでなかったら、割り込みから戻る
JMP INTEND
---------------------------------------------------------

さて。これでうまくいくかな???


87 Re: 割り込み処理  名前:hideyosi 2004/10/16 22:09  
うはははは! いよーし!! うまくいったぞ!! (^^)

次は、A以外のキーも反応できるようにしょう!

88 Re: 割り込み処理  名前:hideyosi 2004/10/16 23:50  
うーーーん・・・・
押されたキーと、ASCIIのキーコード。なんらかの法則性があるかと思って眺めていたんだけど、まったく関連性がないや・・・
なんらかの計算ルーチンでなんとかなるかと思っていたが、甘かった・・・・
やっぱ、基本的には「絨毯爆撃」で分岐を書くしかないのかなぁ・・・

89 Re: 割り込み処理  名前:hideyosi 2004/10/18 1:01  
いろいろと考えてみたんだけど、やっぱほかにいい方法がみつからないや。もういいや!絨毯爆撃で!

・・・ってなわけで、キーボードの割り込み部分はこういうふうになった。

-------------------------------------------
;もしその値が1Eだったら、Aボタンが押されている
CMP AL,0x1E

;上のCPM命令によってキャリーフラブが変化している。
;同じならZFが1,CFが0になっている
;もしそうなら、文字表示ルーチンをコールする
JE APRINT


CMP AL,0x30 ;Bが押されている
JE BPRINT

CMP AL,0x2E ;Cが押されている
JE CPRINT




CMP AL,0x15 ;Yが押されている
JE YPRINT

CMP AL,0x2C ;Zが押されている
JE ZPRINT


;そうでなかったら、割り込みから戻る
JMP INTEND




;文字ごとにコードをセットする
APRINT:
MOV AL,0x41
JMP MOJIPRINT

BPRINT:
MOV AL,0x42
JMP MOJIPRINT



YPRINT:
MOV AL,0x59
JMP MOJIPRINT

ZPRINT:
MOV AL,0x5A
JMP MOJIPRINT




;文字を表示するルーチン
MOJIPRINT:
MOV AH,0x0e
INT 0x10

JMP INTEND
----------------------------------------------

で、コンパイル。
おぉぉ!!! 文字がいろいろと表示できる!けっこうたのしいぞ!!

今回はとりあえず、ABC・・・XYZまでだけにしておこう。他のキーやShiftとかはちょっと後回し。

・・・でも、ENTERキーだけは、なんとかそれらしく動作させたいなぁ。



90 キーコード変換  名前: -- K 2004/10/18 14:04  
>おぉぉ!!! 文字がいろいろと表示できる!けっこうたのしいぞ!!

 おめでとうございます。

>いろいろと考えてみたんだけど、やっぱほかにいい方法がみつからないや。もういいや!絨毯爆撃で!

 ちょっとだけヒントを書くことにしようかな。

 アセンブラでもCでも同じことですが、この手のコードをifのかたまりやswitchのかたまりで書くのは良くないことです。C言語であれば、

 static char table[] = {
  0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', '\b', '\t',
  'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', '\n', 0, 'A', 'S',
  'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
  'B', 'N', 'M', ',', '.', '/', 0, '*'
     (以下略)
 };

とやっておいて、 j = table[i]; とでもすれば、一発でキーコードから文字コードにできます。

 おなじことをnaskですることもちろんできて、

; ALには0x1eなどのコードが既に入っているとする。

  MOV BH,0
  MOV BL,AL
  MOV AL,[BX+table]

; これでもうALには文字コードが入っている。たくさんのCMP+JEにさようなら。

; 以下はプログラムではなくデータなので間違って実行しないような位置におく

table:
  DB 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 8, 9
  DB 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 10, 0, 'A', 'S'
  DB 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V'
  DB 'B', 'N', 'M', ',', '.', '/', 0, '*'
     (以下略)

 僕の書いた意味が理解できたら使ってみてください。
理解できなければ今のままCMP+JEで書くほうがいいと思います。
MOVしか使ってないので、努力すれば理解できるのではないかと思って書いてみました。

 ちなみに、'A'などの表現が見慣れないかもしれませんが、これは0x41のことです。 MOV AL,'A' とかもできます。

91 Re: キーコード変換  名前:hideyosi 2004/10/18 23:21  
ENTERキーの処理。
まず、ENTERキーの分岐をおきます。これは簡単。

------------------------------
;ENTER キー
CMP AL,0x1C ;Zが押されている
JE ENTERPRINT
--------------------------------

で、このENTERPRINTってラベル以下にコードを書けば出来上がり・・・

------------------------------------------------
ENTERPRINT:
;BIOSでカーソル位置を設定
MOV AH,0x02
MOV BH,0x0
MOV DL,0
MOV DH,Y座標
INT 0x10

JMP INTEND
-----------------------------------------------

・・・・あれれ? この場合、Y座標の値ってどうするんだ?

順当に考えると、「現在のY座標+1」ってことだよね?
むむむ?? 「現在の座標」って、どうやって求めるんだろう?
さっそくいろいろと調べてみた。
なになに? 0040:0050hがそうだって???
うむむむ??? どうもよくわからないや。こりゃ、実験しかないか!?




92 Re: キーコード変換  名前:hideyosi 2004/10/18 23:34  
うーん・・・0040:0050hという表現。これまでのパターンだと、これは、セグメント:オフセットのパターンではないかなぁ?

そうすると、この0040:0050hという場所の値を読み出すには

-------------------------------------------
MOV AX,0x40
MOV ES,AX ; ESを0040にする。
MOV AX,WORD[ES:0x50]
ーーーーーーーーーーーー---------------

こういうコードになるのかな???

93 Re: キーコード変換  名前:hideyosi 2004/10/19 1:06  
だあぁぁぁぁぁぁ!!!!!

にゃんだよクソ!!! ちゃんとBIOSにあるぢゃん!

ってことで、こういうコードを追加して、目的の動作をしました。

-------------------------------------------
ENTERPRINT:
;現在のカーソルの位置を取得(Y座標のみ)
MOV BH,0x0
MOV AH,0x03
INT 0x10

;BIOSでカーソル位置を設定
MOV AH,0x02
MOV BH,0x0
MOV DL,0
INC DH ;上で取得した行位置+1
INT 0x10

JMP INTEND
-------------------------------------------------------

94 Re: キーコード変換  名前:hideyosi 2004/10/19 3:32  
上の状態だと、カーソルが最下行に行っちゃうと、固まったようになって画面が動かなくなっちゃう。
で、こんなコードに変更。

----------------------------------------
ENTERPRINT:
;現在のカーソルの位置を取得(Y座標のみ)
MOV BH,0x0
MOV AH,0x03
INT 0x10

INC DH ;上で取得した行位置+1

CMP DH,0x19

;もし、最下行だったらロールアップ
JE ENTERPRINTLUP

;そうじゃなかったら、普通にカーソル移動

JMP ENTERPRINTNML


ENTERPRINTLUP:
;ロールアップ。まず、ロールアップをする
MOV AL,0x01
MOV BH,0x0F
MOV CH,0x01
MOV CL,0x0
MOV DH,0x18
MOV DL,0x4F
MOV AH,0x06
INT 0x10

;カーソルを最下行にセット
MOV DH,0x18
JMP ENTERPRINTNML


ENTERPRINTNML


;BIOSでカーソル位置を設定
MOV AH,0x02
MOV BH,0x0
MOV DL,0

INT 0x10

JMP INTEND
--------------------------------------------------

おーー! まるでエディタの如く、最下行でロールアップするぞ!?

95 プロンプトの搭載  名前:hideyosi 2004/10/19 21:21  
なんか、「見た目だけ」とはいえ、だんだんMS-DOSっぽくなってきて楽しいなぁ・・・。
そんなわけで、プロンプトを搭載してみよう。
これはそうむずかしくない。まず、テキスト画面を一旦クリアする。
で、プロンプトを表示する。
さらに、Enterキーが押されたら、とりあえず無条件でプロンプトを表示させると。

-------------------------------------------------
ENTERPRINTNML


;BIOSでカーソル位置を設定
MOV AH,0x02
MOV BH,0x0
MOV DL,0

INT 0x10

CALL PROMPTPRINT

JMP INTEND




PROMPTPRINT:
;BIOSコールで文字列を表示
MOV AH,0x13
MOV AL,0x01
MOV BH,0x0
MOV BL,0x0F
MOV CX,0x07
;本来はここで、DLとDHで座標を指定するが、これは変わらないので
;いらないと思う
MOV BP,pmsg
INT 0x10
RET


;プロンプトの文字列
pmsg DB "THEBBL>"

-------------------------------------------------------






・・・・ぶははははは!!! できたできたー!





96 リリース!(ごっこ)  名前:hideyosi 2004/10/19 22:58  
さーてと!!
とりあえず、キリがいいので、この私のOS(は?)を、リリースして
みよう。

hideyOS Ver 0.01ってことで。(笑

http://thebbl.hideyosi.com/age/hdOS001.lzh

・・・みなさんに笑って頂いてナンボですから・・・ (T∀T)

あ、あと、これまでのソースは、こちらから直で見られます。
アドヴァイスなんかしてみようなんて方は、是非・・・(^^;)

http://thebbl.hideyosi.com/age/test11.nas.txt


97 Re: リリース!(ごっこ)  名前: -- K 2004/10/19 23:13  
 早速楽しんでいます。.COMは374バイトで、Win2000のDOS窓でも動いています。

 ささやかな要望を。キーを離したときに入力されるというのは、ちょっと脱力系なので、できれば押したときに入力されてほしいです。

 あと、BackSpaceの処理が追加されたら、もっとそれっぽいかも!

 さらに、最初に"hideyOS Ver 0.01"みたいなメッセージがあったらいいなあ。

 それでは。

98 Re: リリース!(ごっこ)  名前:hideyosi 2004/10/19 23:22  
>早速楽しんでいます。

ぐはぁ!!! よりによって、Kタンが試している!?
魚影〜!!! ゴロゴロゴロ・・・・ <恥ずかしくてのたうちまわっている

>できれば押したときに

・・・あ” 
そっかぁ。そいえば、押してときの動作って、やってみたことないなぁ。さっとくためしてみよう。


さて、ほいだば、Ver 0.02に向けてガンバロ!
Ver0.02では、まず、キーボードの処理をなんとかする。Kタンにアドヴァイスしてもらった書き方の理解と勉強。当然、BSやShiftなんかの処理も搭載したいなぁ。

あと、とりあえず、なんらかのコマンドを搭載したい。たとえば、clsとか、rebootとか。

あと、現在は画面関係はみんなBIOSにたよっているけど、これをなんとかできないか実験してみよう。


99 Re: リリース!(ごっこ)  名前:feel 2004/10/19 23:49  
試しました
しっかり動きますね
私も頑張りたいと思います
頑張って下さい
家のウイルス対策ソフト(NOD32)が過剰反応してビビりましたが
何ともなくてよかったよかった

明日から修学旅行だぁ〜
京都へ台風と戦いに行ってきます
そしたらまた頑張ります

300 Re: リリース!(ごっこ)  名前:hideyosi 2004/10/20 22:35  
feelさんどもです〜

>家のウイルス対策ソフト(NOD32)が過剰反応してビビりましたが

ぐはぁ!!!
やっぱ、BIOSやらを呼んでいるからかな??

>明日から修学旅行だぁ〜
>京都へ台風と戦いに行ってきます

え”〜・・・よりによって・・・・
なんつーか、今回もまたエラク巨大な台風。せっかくの京都。楽しめるといいんですがねぇ。(あー!私も京都イキテー!)

さて、先日、ごっことは言え、いったんキリがいいということでリリースをして、かつ、バージョン番号も振ってみました。
そんなわけで、ここの番号もまたキリがいいっつーことで、このスレを一旦閉じます。(かなりながーくなってしまったので)

Ver 0.02に向けて、新しいスレ。「OSを作れたらいいねぇPart2」を立てます。
[Returns to a topicAll BACK100 NEXT100 Newest 50
BluesBB ©Sting_Band