前回の続き。
1つの数字から指定した範囲のビットを抜き出したり、上書きしなくてはならないのだが、いちいち処理を書いていては大変。
昔ならGOSUBで処理を飛ばして、値を直接書き換えるのだろうけど、そうすると、全くつぶしが利かないプログラムになってしまう。
そこで、将来的に他のプログラムでも使えるように、関数で作ることにした。さらに、別ファイルに分けておいて、includeして使うようにした。
まずは関数を作成する。HSPではモジュールというもので、関数群を定義できる。
と言っても中に書くのは、HSPの各命令なので、サブルーチンを書くのと大差は無い。
違うのは、引数と呼ばれる、関数に与える変数を指定して、処理した値を返却すること。
プログラム言語の関数と呼ばれるものはだいたいこの形になるし、標準で用意されているものと変わらない。
#moduleで始まり、#globalで終わるようにすると、モジュールとなる。
変数のスコープがグローバルなHSPだけど、モジュール内の変数のスコープはモジュール内になる。
ここがサブルーチンとの違いの一つ。
関数を定義するには#defcfunc文を使う。
1つ目は、値を取得する関数を作った。取得するのは割と簡単。
指定したビット桁数の部分だけを1にした、「マスク」を作る。
そして、元の値とマスクのAND(論理積)を取れば、指定した桁の値だけが残る。
あとは、それを一番右端になるまで右シフトする。
こんな感じ。
ただ、どのフラグがどのビット桁数から格納されていて、何ビットなのかを覚えてないといけない。
こんなのはやってられないので、右から順に、項目が何ビットなのか、右から数えて何ビット目から始まるのかを配列変数にべた書きしたw
べた書きとはいえ、取得も、セットも同じなので、モジュール内で共通で使えるモジュール変数として定義したかったのだが、配列をセットする方法がわからず断念。
2か所に同じものを書く羽目に…動けばいいのだw
#defcfunc get_spOpt int p1,int p2 ;ESI_OPTIONの整数値から項目の値を取り出す関数 ;p1 ESI_OPTIONの値 ;p2 OPTIONに設定する項目番号 ;項目定義(できるならモジュール変数にしたいのだが…) dim Optbit,5 ;各値のビット数 Optbit=3,3,3,1,3 dim Optbitpos,5 ;各値が右から何ビット目から始まるか Optbitpos=0,3,6,9,10 ;マスクパターンを生成する maskp=0 masknum=1 for i,0,Optbit(p2) maskp=maskp+masknum masknum=masknum*2 next ;項目が始まるビット数まで左シフト maskp=maskp << Optbitpos(p2) ;マスクして、必要な項目の値部分を取り出す fun_ret = p1 & maskp ;通常の数値として読めるように、右シフトして桁数を合わせる fun_ret = fun_ret >> Optbitpos(p2) return fun_ret