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

[Returns to a topicAll  1-  Newest 50
OSを作れたらいいねぇPart2
1 名前:hideyosi 2004/10/20 22:37  
前スレ
 K氏のheboOSをまねてみる

なんでPart2なんだよ!?
 世の中そういうもんです。

えー。まーそんなわけで、前スレがながーくなっちゃったので、新スレっつーことで。

heboOSベースのOSモドキ、「hideyOS Ver 0.02」に向けて、新たにお勉強しましょうーっつーことで。

まずはキー反応のタイミング  名前:hideyosi 2004/10/24 9:45  
さてさて。まずは、キーボードのボタンの反応。
いままでは、キーを「離した」時に反応するようにしてあった。
(これは深い意味はありません。なんとなくでした)
該当部分はここ。

--------------------------------------------------------
;乗っ取ったキーボード割り込み部分
IINT09:

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


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

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

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

ここを、10000000、すなわち0x80だった時に反応すればいいように
すればいいわけだね。

CMP AH,0x80

コンパイルしてと・・・

お!? 確かに、なんか反応がよくなったぞ!? 

続いてキー判定部  名前:hideyosi 2004/10/24 10:07  
前回のコード。
私は、キーボードスイッチと文字コードとの対応を、CMP、JEで、だーーーっと書いた。まあ、あれでも動くから問題ないっちゃぁないんだけど、なんかカコワルイし、書くのも大変。
そんなのを晒していたら、Kタンがこんな参考コードをくれた。

---------------------------------------------------------
; 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, '*'
     (以下略)
---------------------------------------------------------

・・・ふーむ・・・
これをそのまんまパクるのも、まあありだけど、ちょっとオベンキョしてみよう。

;この時点で、例えばAボタンが押されている。つまり、
;ALには0x1eが入っているとする。
  MOV BH,0 ;BHに0を代入
  MOV BL,AL ;BLに、ALの内容をコピー。
         ;?すると、BXは、0x001e となるのか?

  MOV AL,[BX+table]
;ふむむ・・・ここら辺りがよくわからないなぁ・・・

まあいいや。とりあえず、一旦これを動かしてみよう。

・・・・・あれえぇぇぇぇぇ!?

なんか、メチャクチャな文字が表示されるぞ!? 

Re: 続いてキー判定部  名前:名無しさん 2004/10/24 10:37  
うーーーん・・・・
どうもおかしいけど、ちょっとだけ解って来たことがある。
この状態だと、たしかにメチャクチャな文字が表示されるが、
一定の法則があるようだ。たとえば、テンキーを123456789
と押すと、OPQKLMGHIを表示する。っということは、キースイッチ
の値とアスキーコードの対応に、一定のズレがあるわけか。

ええと。テンキーのキースイッチ値が・・・

4F,50,51,4B,4C,4D,47,48,49 ;これね。で、アスキーコードが
4F,50,51,4B,4C,4D,47,48,49 ;・・・・あれれ????

なんだこれ? キースイッチの値が直接反映されているだけじゃん!?
そうすると、変換部分にミスがあるのか???

Re: 続いてキー判定部  名前:名無しさん 2004/10/24 10:46  
あはははははは!!!!!!! ぎょひーーー!!!!

・・・・原因はここでした。

----------------------------------------------------------
;持ってきた値の7ビットだけを抽出
AND AL,0x7F ;二進数 01111111 でANDSする

; ALには0x1e(A)などのキースイッチの値が入る
MOV BH,0
MOV BL,AL
MOV AL,[BX+KEYTABLE] ;この処理で、ALには、文字コードが入っている

JMP MOJIPRINT ;実際に文字を表示する処理
----------------------------------------------------------

MOV BH,0 とかの部分。なんと、MOVとBHの間が、タブではなく、全角スペースでした・・・・・・。つまり、

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

の部分が、動いてなかったと!!!!!!
うぎゃーー!ハズカスイ・・・・・

えーーーっと!!!! では、気を取り直して・・・・(T∀T)

Re: 続いてキー判定部  名前:名無しさん 2004/10/24 11:16  
こんな実験をしてみた。

-------------------------------------------
;文字コードとキースイッチコードの対応表
KEYTABLE:
DB '0','1','2','3'

; 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, '*'
-----------------------------------------------

例の、
MOV BH,0
MOV BL,AL
MOV AL,[BX+KEYTABLE]
の部分の理解。
この状態で、キーを押す。ESCキー。ESCキーのキースイッチ値は、
0x01。で、[BX+KEYTABLE]とかの場合は、KEYTABLEはラベルとなる。
ラベルは、ある特定のアドレスを文字に見立てただけなので、
実際にはアドレスに変換されるはず。(じゃ、仮に0x0200番地だと仮定してみる。)

MOV BH,0
MOV BL,AL

これによって、ESCキーが押された場合には、BXレジスタは、0x0001になる。で、

MOV AL,[BX+KEYTABLE]

とやると、実際には、

MOV AL,[0x0001+0x0200]

というようなことになる。で、実際の0x0201番地っていうのが、

DB '0','1','2','3'

この二番目の要素。すなわち、「1」のアスキーコードになると・・・・
なるほどなるほど!!!! わかってきたぞ!!!!
そうすると、例えば、一覧表をちゃんとした状態で、

MOV AL,[BX+KEYTABLE+1]

なんてイタヅラをすると、全てのキーが一個づつずれるなんてこともできると!あと、
MOV BH,0
MOV BL,AL
これは、そもそもアドレス(オフセット値)を指定するんだから、
16bitが必要なのでこうしているわけね。

??? じゃ、なんでBXレジスタなのか?

これは、「お作法で BX はメモリアドレスの指定に」ということなのかなぁ・・・・

仮にだけど、これをワザとDXレジスタでやってみるとどうなるかな???

・・・・あれれれ! コンパイルエラーになっちゃった。やっぱ、単純にお作法だけじゃなくて、こういう手のアドレス指定は、BXを使うもののようだね。

Re: 続いてキー判定部  名前: -- K 2004/10/24 12:06  
>??? じゃ、なんでBXレジスタなのか?

 もっともな疑問ですね。

 16bitモードでは、メモリアドレス指定に許させるレジスタの組み合わせが少ししかありません。

 定数
 BX + 定数
 BX + SI + 定数
 BX + DI + 定数
 BP + 定数
 BP + SI + 定数
 BP + DI + 定数
 SI + 定数
 DI + 定数

 それぞれで、定数部分は0であってももちろん構いませんので、[BX]という指定ももちろん可能です。

 今回の目的ではBX、BP、SI、DIのどれでもOKなのですが、その中でBXだけがBLとBHに分けられるので、BXを使ってみました。

 それでは。

NASKのバグ??  名前:hideyosi 2004/10/24 12:43  
こんなのを見つけた。
-------------------------------------------------------
DB 'A', 'S','D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ''','`', 0, '\'
-------------------------------------------------------

これの後ろから3番目。'A'とかと同じ調子で、’を当てたかったので
こういうふうに書いてみた。まあ、今から考えると、あきらかにおかしな
書き方なんだけど、これがあると、NASKが異常終了してします。

あ、ちなみに、

-------------------------------------------------------
DB 'A', 'S','D', 'F', 'G', 'H', 'J', 'K', 'L', ';', 0x27,'`', 0, '\'
-------------------------------------------------------

これで問題はないんだけのね。(^^;)

Re: 続いてキー判定部  名前:hideyosi 2004/10/24 12:57  
さーてと。キーコードの変換テーブルは

------------------------------------------------
;文字コードとキースイッチコードの対応表。英字キーボード
KEYTABLE:
; 0 , 01 ,・・・・・
DB 0 , 0 , '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, 9

; 10, 11,・・・・・
DB 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']', 10, 0

; 1E, 1F,・・・・・
DB 'A', 'S','D', 'F', 'G', 'H', 'J', 'K', 'L', ';', 0x27,'`', 0, '\'

; 2C, 2D,・・・・・
DB 'Z', 'X', 'C', 'V','B', 'N', 'M', ',', '.', '/', 0

; 37 ,38,・・・・
DB '*' , 0,0x20,0,0,0,0,0,0,0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+'

; 4F , 50,・・・・
DB '1' , '2' , '3','0','.'

; 54,55,・・・・
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

; 73,74,・・・・
DB 0,0,0,0,0,0,0,0,0,0,'\'

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

とりあえずこれでOKみたいだぞ!?

ほいだば、特殊キーやShiftなんかの処理を追加・・・と。

10 Shiftとか  名前:hideyosi 2004/10/24 20:23  
ATのキーボードは、通常は、組み合わせて使うキーは以下だけ。

●Shift
●ALT
●Control

これらのキーは、押せば押され、離せば離される。<なにいってんだろ・・・
考え方としてはこういうことだなぁ。

●あるエリアに、「今押されているか?」を記憶する場所を確保
●押されればそこは1とかになり、離されると0とかになる。
●各キーボードテーブルに、このあるエリアの判定も加える。

えーっと。ShiftやCtrlが押された場合は、ANDして・・・・
ん????

・・・考えてみれば、これらって、全部で6個しかない・・・・

よし!じゃ!

まず、キー状態格納用のエリアを作る

---------------------------------
SSHIFT:
DB 0
SALT:
DB 0
SCTRL:
DB 0
--------------------------------

で、判定部分をこんなふうに改造。

---------------------------------
IINT09:

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

;Shiftの判定。押されているか離されているかはもう
;定数で判定しちゃえ!

;離されている場合。
CMP AL,0x2A
JE SHIFTON

;押されている場合。
CMP AL,0xAA
JE SHIFTOFF

;同じく右側も。
;離されている場合。
CMP AL,0x36
JE SHIFTON

;押されている場合。
CMP AL,0xB6
JE SHIFTOFF

;持ってきた値を一時、AHに複製する
MOV AH,AL
--------------------------------------------

さらに、ジャンプ部分を設置。

--------------------------------------------
SHIFTON:
MOV BX,[SSHIFT]
MOV [BX],0x01

JMP INTEND

SHIFTOFF:
MOV BX,[SSHIFT]
MOV [BX],0x0

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

あとは、テーブル判定部分を設置すればOKのはず!

11 Re: Shiftとか  名前:hideyosi 2004/10/24 20:26  
・・・・あっれぇぇ?
コンパイルエラーだ!?
どうも、
MOV [BX],0x0
こういうのがまずいらしい。ええっと・・・この場合は・・・

12 Re: Shiftとか  名前:hideyosi 2004/10/24 20:30  
うーむ。どうも、メモリに直接値を入れるのはまずいようだ。
そこで、

-----------------------------------------------------
SHIFTON:
MOV BX,[SSHIFT]
;この段階ではもうキーの値はいらない。
;壊れてしまってもOK
MOV AL,0x01
MOV [BX],AL

JMP INTEND

SHIFTOFF:
MOV BX,[SSHIFT]
;この段階ではもうキーの値はいらない。
;壊れてしまってもOK
MOV AL,0x0
MOV [BX],AL

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

一旦ALレジスタに代入してから値をセットしてみよう。

お!? コンパイルエラーは収まったぞ!?

13 Re: Shiftとか  名前:hideyosi 2004/10/24 20:50  
さらに、Shiftキー判定部分と、テーブルを追加。

-------------------------------------------------------;乗っ取ったキーボード割り込み部分
IINT09:

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

;Shiftの判定。押されているか離されているかはもう
;定数で判定しちゃえ!

;離されている場合。
CMP AL,0x2A
JE SHIFTON

;押されている場合。
CMP AL,0xAA
JE SHIFTOFF

;同じく右側も。
;離されている場合。
CMP AL,0x36
JE SHIFTON

;押されている場合。
CMP AL,0xB6
JE SHIFTOFF




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

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



;持ってきた値の7ビットだけを抽出
AND AL,0x7F ;二進数 01111111 でANDする

;Shiftが押されているかどうか判定
MOV AH,[SSHIFT]

CMP AH,0x0
JE SHIFTONPRINT

CMP AH,0x01
JE SHIFTOFFPRINT



SHIFTONPRINT:
; ALには0x1e(A)などのキースイッチの値が入る
MOV BH,0
MOV BL,AL

MOV AL,[BX+KEYTABLESHIFTON] ;この処理で、ALには、文字コードが入っている

JMP MOJIPRINT ;実際に文字を表示する処理


SHIFTOFFPRINT:
; ALには0x1e(A)などのキースイッチの値が入る
MOV BH,0
MOV BL,AL

MOV AL,[BX+KEYTABLESHIFTOFF] ;この処理で、ALには、文字コードが入っている

JMP MOJIPRINT ;実際に文字を表示する処理

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

テーブル

----------------------------------------------------------
;文字コードとキースイッチコードの対応表。英字キーボード、ShiftOFF
KEYTABLESHIFTOFF:
; 0 , 01 ,・・・・・
DB 0 , 0 , '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, 9

; 10, 11,・・・・・
DB 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '{', '}', 10, 0

; 1E, 1F,・・・・・
DB 'a', 's','d', 'f', 'g', 'h', 'j', 'k', 'l', ':','"','~', 0, '|'

; 2C, 2D,・・・・・
DB 'z', 'x', 'c', 'v','b', 'n', 'm', '<', '>', '?', 0

; 37 ,38,・・・・
DB '*' , 0,0x20,0,0,0,0,0,0,0,0,0,0,0,0,0,'7','8','9','-','4','5','6','+'

; 4F , 50,・・・・
DB '1' , '2' , '3','0','.'

; 54,55,・・・・
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

; 73,74,・・・・
DB 0,0,0,0,0,0,0,0,0,0,'\'

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

よし! コンパイルエラーもないぞ! いっけえぇぇぇぇ!!

・・・・・・・だめじゃん・・・・orz

うーーーん。どこがまずいのかな? ひとつづつ検証してみよう。

14 Re: Shiftとか  名前: -- K 2004/10/24 21:29  
> MOV [BX],0x0

 MOV BYTE [BX],0x0

と書けばOKです。もちろんAL経由でも、プログラムが長くなる以上の害はありませんが。

15 Re: Shiftとか  名前:hideyosi 2004/10/24 21:39  
>と書けばOKです。

あぁぁぁぁ!!! いっけねぇ!! そっか!?
BXは16ビットなんだから、ちゃんとそう宣言しなくちゃいけんと!

・・・これ、前にもひっかかったじゃねーかよ!
だめだなぁ・・・・ (T∀T)

16 Re: Shiftとか  名前: -- K 2004/10/24 23:12  
ついでに言うと、

MOV BYTE [SSHIFT],0x0

で全く問題ありません。これだとALもBXもつかわずに済みます。

17 Re: Shiftとか  名前:hideyosi 2004/11/3 18:54  
さーてと!

オベンキョ再開。Shiftキーがなんで全然反応しないんだろう?

まずは、Shifの判定部分にちゃんと飛んでいるかどうか。SHIFTONのラベル以下に文字表示のルーチンでも叩きこんで、調べてみる。


===========================================================
SHIFTON:
MOV BX,[SSHIFT]
;この段階ではもうキーの値はいらない。
;壊れてしまってもOK
MOV AL,0x01
MOV [BX],AL

MOV AL,0x41
MOV AH,0x0e
INT 0x10



JMP INTEND

SHIFTOFF:
MOV BX,[SSHIFT]
;この段階ではもうキーの値はいらない。
;壊れてしまってもOK
MOV AL,0x0
MOV [BX],AL

MOV AL,0x42
MOV AH,0x0e
INT 0x10



JMP INTEND
===========================================================

・・・・うーむ。ちゃんとSHIFTを押すと、ABと表示される。つまり、ちゃんとここへは飛んできているんだ。








18 Re: Shiftとか  名前:hideyosi 2004/11/3 19:02  
うーん。もしかして、ここのところかな?

================================================
MOV BX,[SSHIFT]
;この段階ではもうキーの値はいらない。
;壊れてしまってもOK
MOV AL,0x0
MOV [BX],AL
===============================================

MOV BX,[SSHIFT]。これはつまり、アドレス指定に用いられるBXレジスタに、ラベル「SSHIFT」のアドレスを代入している。

・・・この場合、BXだから16bitだし、また、ラベルで置換されるアドレスも、オフセットながら通常は16bit。

問題はこれ。

MOV [BX],AL

・・・もしかして、BYTEを使うのかな???


19 Re: Shiftとか  名前:I.Tak. 2004/11/4 8:50  
NASK/NASMの文法では, []がついてるのは (LEAを除いて)
*全てメモリアクセス* です。BXにSSHIFTのアドレスを
入れるのなら
MOV BX, SSHIFT
としませう。このへんMASMと違うので, そういう解説を
読んでるなら要注意ですよ?

20 Re: Shiftとか  名前:名無しさん 2004/11/8 23:22  
キタ━━━━━━(゜∀゜)━━━━━━!!!!!!!!

I.Tak.さんの指摘がドンピシャ!!!!

一気にうまくいきましたぁぁぁぁあ!!!

よーーし! あとは、簡単なコマンドを搭載してみて、それを0.01としてリリース予定だぁぁ!!!

>このへんMASMと違うので, そういう解説を
>読んでるなら要注意ですよ?

・・・つか、ちょっと一旦、naskの使い方を整理してみたほうがいいかなぁ。(私自身のためと、naskを使ってみたいという人のために)

21 Re: Shiftとか  名前:名無しさん 2004/12/12 22:21  
さて、あまりいつまでもお休みしてられないので、ちょこっとづつでも手をいれてかなくちゃ。

現在、大まかな強化機能が出来上がってくれた。さあ、いよいよ、コマンドの搭載である。

現状の作り(ベターっとアセンブラで書いてある)では、どうせ本当の意味でのコマンドは搭載できないので、「コマンドっぽい」って感じでまず実装。

考え方としては、どこかにコマンド格納用のエリア(バッファっていうのかな?)を確保し、最後に打たれたEnterから、新しく打たれたEnterまでを格納する。

まずは、そんなところから始めてみよう。

この場合、すぐに思いつくのが、アセンブラのコード上で、DBとかを使ってエリアを作っておいて、そのラベルをプログラム上から参照するという方法。これはすぐに出来そうだが、これだと実行時にしか使わない、無意味なデータエリアがOS本体のファイルサイズに反映されることになる。別にこのOSは、OSASKみたいにサイズのこだわっているわけじゃないが、チトあまりにも無駄っぽいような。

・・・うーん、でも、とりあえずはいいや。まずはこの、おもいっきしベタな方法をとにもかくにも実装してみよう。
[Returns to a topicAll NEXT100 Newest 50
BluesBB ©Sting_Band