pioneer0 ライブラリ コマンドリファレンス

Twitchell6(OSASK v4.8β)版
2004.12.27
編: I.Tak. <t40370@mail.ecc.u-tokyo.ac.jp>
Under terms of Kawaido License-01

目次


概要

これはOSASKのGUIGUI00仕様API, pioneer0ライブラリのコマンドを網羅的に扱う私製リファレンスです。自分でプログラムする際に参照しています。

主にアセンブラの使用者を対象にしていますが, guigui00.hのマクロ名, 関数名もそれなりに掲載しているので Cから呼び出す方も使えるかと思います。


予備知識

i.ライブラリコールの使い方

基本的には, コマンドをメモリ上に羅列し, 先頭のポインタをDS:EBXに代入して, ライブラリを呼び出します。ぐいぐい00仕様では, DSの値を起動時にシステムがセットしてくれるので, ユーザはEBXに代入するだけです。コマンド列の終端はコマンド列終了コマンドで指示します。

guigui00.hを使う場合, lib_execcmd0lib_execcmd1 がこの処理を肩代りします。

i.i.NASMで

以下のようにします。

mov ebx, work.lib_init
call 0xc7:0

i.ii.Cで

説明不要かも知れませんが。

static void* cmd[]={hoge,rage, ..., 0 /* eoc */};
lib_execcmd(&cmd);
lib_execcmd0(hoge, rage, ..., 0 /* eoc */);
lib_execcmd1(12+4*2, hoge, rage, buf, ..., 0 /* eoc */);

と書きます。配列を使う場合, 川合さんの例のように void*[] としてコマンドを定義するのが楽です。execcmd1の一つ目の引数は 12+4*n となっており, コマンド列のn番目の数値を返り値にします (この場合, hogeがn=0の位置)。

ii.slot

アプリケーションが自由に使えるスロット番号は, 0x200から0x3f0までの16の倍数です。スロットの競合・共有は許されません。

iii.セグメントセレクタ

セグメントセレクタを特に指定しない (させてもらえない) 場合はdsが使われる模様です。またライブラリは ds=ss=fs を仮定しているため, コードセグメントにコマンドを置くことは許されません。

セグメントセレクタは16ビットですが, 32ビットデータとして書くときは上位16ビットを0で埋めなければなりません。

iv.用語の違い (「ボックス」と「キャラクタセット, フォント」)

v.アプリ起動時のレジスタ

eax=ecx=edx=ebx=esp=ebp=esi=edi=0
cs=7
ds=ss=es=fs=0xf
gs=未定
eip=0
CF=PF=AF=ZF=SF=DF=OF=0

この値は保証されていて, 決め打ち可能です。
参考: [OSASK 2743] Re: ぐいぐいプログラミング質問
[OSASK 3035] エラー情報解説(1).

vi.参照した資料

最近はtestシリーズのドキュメントを読みつつ, pioneer0のソースを読んでこっそり変更されているところを探すという感じです。

不明瞭なところには「未詳」などと書いておきました。

なお同封の introlst.txt にintroシリーズの順序および概要とpack, testシリーズの概要を書いてあります。不明の点は自分でサンプルを読んでみてください (もちろん, 改善案は歓迎します)。コマンドごとの解説では説明しにくい全体の概念もあると思います。

vii.セグメントオフセット

ダブルワードにアラインしておくべきです (ポインタを4の倍数にしておく。速くなる)。さもないと, APIが下位の2bitsをフラグとして使うことが多いので誤作動の原因になります。


リファレンス


0x0000:コマンド列終了

コマンド
dd 0
機能

ライブラリはこのコマンドを実行すると, ユーザプログラムへ復帰します。その際, ebxとeflagsは保存されません。ebxは終了コマンドを指します。ほかのレジスタは保存されます。

例外として, 特別コマンドを使った場合はediがその影響を受けます。

バグ

昔のバージョンでは, シグナル待ちコマンド実行中にシグナルハンドラに分岐して, そこから戻ってコマンド終了となる場合はebxも保存されましたが, 今では修正されているそうです。


0x0004:ライブラリ初期化

コマンド
dd 4, work
guigui00.h
LIB_WORK* lib_init(work);
void lib_init_nm(work);
LIB_WORK* libb_init_am(work);
機能

ライブラリを初期化し, その時の時刻をシステムタイマの時間基点に設定し, シグナルハンドラマスク値を-1にします。ライブラリの他のコマンド (コマンド列終了を含む) を利用する前にこのコマンドを実行しなければなりません。

引数

workは256バイトの空き領域を指すセグメントオフセットです。4 の倍数でなければなりません。ここが4の倍数でない場合, それは特別コマンドだと見なされます。


0x0004.-1:特別モード終了

コマンド
dd -1
機能

特別コマンドを終了させ, ユーザプログラムに復帰します。

解説

初期化コマンドには特別モードがあり, ライブラリ初期化コマンドのシグネチャ dd 4 に続けて独自のコマンド列を埋め込むようになっています。初期化はされません。

ライブラリ初期化前に使用でき, その時は最後に特別終了を付けてコマンド終了の代わりとします。ライブラリ初期化の後は特別終了を使ってはいけません。特別終了ではebxの値が保証されません (保存するとは保証されない)。

コマンド列が特別コマンドで始まる場合, 後に繋げられるコマンドはライブラリ初期化だけです。


0x0004.-0x77:tek5伸長

コマンド
dd -0x77, size, src_ofs, 7
es:edi = 展開先ポインタ
機能

tek5データを伸長します。その後, ediは次の展開先を指します。

引数
size
伸長後のデータの長さで, 単位はバイトです。
src_ofs
圧縮データのセグメントオフセットです。
その他
スタックの空きが36KB以上必要です。コードセグメントのデータしか伸長できません (チェックされているので)。

0x0004.-0x7b:tek2伸長

コマンド
dd -0x7b, size, src_ofs, src_sel
es:edi = 展開先ポインタ
機能

tek2データを伸長します。その後, ediは次の展開先を指します。

引数
size
伸長後のデータの長さで, 単位はバイトです。
src_sel:src_ofs
圧縮データのポインタです。

0x0004.-0x7d:tek1伸長

コマンド
dd -0x7d, size, src_ofs, src_sel
es:edi = 展開先ポインタ
機能

tek1データを伸長します。その後, ediは次の展開先を指します。

引数
size
伸長後のデータの長さで, 単位はバイトです。
src_sel:src_ofs
圧縮データのポインタです。

0x0004.-0x7e:tek0伸長

コマンド
dd -0x7e, size, src_ofs, src_sel
es:edi = 展開先ポインタ
guigui00.h
const int lib_decodetek0(int size, int src_ofs, int src_sel, int dest_ofs, int dest_sel);
機能

tek0データを伸長します。その後, ediは次の展開先を指します。

引数
size
伸長後のデータの長さで, 単位はバイトです。
src_sel:src_ofs
圧縮データのポインタです。

0x0004.-0x7f:l2d3伸長

コマンド
dd -0x7f, size, src_ofs, src_sel
es:edi = 展開先ポインタ
guigui00.h
const int lib_decodel2d3(int size, int src_ofs, int src_sel, int dest_ofs, int dest_sel);
機能

l2d3データを伸長します。その後, ediは次の展開先を指します。

引数
size
伸長後のデータの長さで, 単位はバイトです。
src_sel:src_ofs
圧縮データのポインタです。

0x0004.-0xf:コードをデータセグメントにマッピング(?)

コマンド
dd -0xf, arg_ofs | flag
arg_ofs: dd stack_end, data_size, 0, data_ofs
機能

コードセグメントに配置されているデータ (セクション) を, データセグメントにマッピングします。

現在の実装は不明ですが, (4KBアラインされていない場合は最初にコピーを作って,) プロセス間で共有されるコピーオンライトなマッピングにするのではないかと。普通ですねえ。

引数
arg_ofs
パラメータ位置を指定します。必ず4バイトアラインに配置します。
flag
2ビットのオプションフラグです。マッピングなどが終了した後に読まれます。
0 次のサブコマンドに移ります。
1 ファンクション4 (ライブラリ初期化) を受け取ったことにして, stack_endへジャンプします (DS:stack_endには, ライブラリ初期化の引数 dd work を置く)。
2, 3 予約でしょう
stack_end
スタックの上端=データの転送位置です。 0 <= ESP && ESP < stack_end である場合, ESP未満のオフセットにあるメモリの内容は保証されません。メモリ確保のため, 破棄される可能性があります。
data_ofs
データ (セクション) のオフセット (CS内) です。
備考(?)
stack - data - heap - mmap という配置が想定されているようですが, stack_end = 0 として, data - stack - heap - mmap という配置でもなんら問題なく使えるのではないかと思えますね。ということは, コードセグメント全体をマッピングしてしまえば (自己書き換えはできないものの) 疑似フラット環境も実現できそうです。

0x0008.0:ライブラリ終了

コマンド
dd 8, 0
guigui00.h
void lib_close(0);
機能

ライブラリを終了します。現在はアプリもろともに終了します。

解説

すぐには終了しないため, このコマンドを実行した後もシグナルを受信する処理が必要です。


0x000c.0:コマンドジャンプ相対

コマンド
dd 0xc, 0, offset
機能

ライブラリのコマンドポインタに値を加えます。

引数
offset
バイト単位で, 基点はジャンプコマンドの先頭です。例えば, dd 0xc,0,0 というコマンドは無限ループになります。

0x000c.1:コマンドジャンプ位置

コマンド
dd 0xc, 1, offset
機能

ライブラリのコマンドポインタに値を代入します。

引数
offset
セグメントオフセット値です。これをライブラリのコマンドポインタのセグメントオフセットに代入します。

0x0010:シグナルハンドラ定義

コマンド
dd 0x10, offset, selector
guigui00.h
void lib_definesignalhandler(void (*lib_signalhandler)(struct LIB_SIGHNDLREG *));
機能

シグナルハンドラを定義します。

解説

シグナルが溜まると, ユーザプログラムの中でやっていることを中断してハンドラに分岐します。分岐時のスタックは以下のとおりです。セグメントレジスタの上位16bitが 0 になることは保証されません。

ESP+ 0 4 8 12 16 20 24 28 32 36 40 44 48 52 56
ES DS FS GS EDI ESI EBP 未定義 EBX EDX ECX EAX EIP CS EFLAGS

ここで積まれる値はハンドラから復帰する時の値 (ほぼそのまま分岐前の値) です。ハンドラに進入したときのレジスタの値はスタックにつまれている値とは等しくありません。分岐直前の値を参照したい場合は, スタックから読み込んでください。

ユーザプログラムがシグナルハンドラを定義して, かつシグナル待ちをしているときは, シグナルハンドラから復帰すると同時に待ちコマンドが終わります。

引数
selector:offset
シグナルハンドラのポインタです (普通はselector=7です)。

0x0014.0x10:ウィンドウ推奨最大サイズ取得

コマンド
dd 0x14,0x10,offset,selector
機能

シェル推奨 (実際はユーザ指定可能にするらしい) のウィンドウ最大サイズを取得します。別に無視しても構いませんが, 従ったほうがユーザフレンドリです。

引数
selector:offset
バッファのポインタです。そのバッファに dd x_max, y_max という形で書き込まれます。
余談
このコマンドにウィンドウデザインの取得が入るのだろうか。

0x0018.0x0f:シグナル・時間待ち

コマンド
dd 0x18, opt, signaldw, nest
または
dd 0x18, opt, signaldw, nest, t0,t1,t2
guigui00.h
void lib_waitsignal(int opt, int signaldw, int nest);
void lib_waitsignaltime(int opt, int signaldw, int nest, int t0, int t1, int t2);
機能

シグナルや時間基点を待ちます。シグナルが来ない状況では, 時間待ち・永眠コマンドとして使われます。

引数
opt
bit0〜bit3 に意味があり, bit4〜bit31は予約されています。予約のビットは必ず0にしておいてください。ビットは上位から順に解釈されます。
bit3 0 設定済みの時間基点をそのまま使う。
1 現在の時刻を時間起点にする。
bit2 0 timeフィールドはない。
1 timeフィールドが存在し, 時間基点にこれを加算する。
bit1-0 0 待たない。
1 シグナルが来るまで待つ。
2 この値は許されない。
3 シグナルか時間基点が来るまで待つ。
signaldw
受信したシグナルの量 (ダブルワード=32ビット単位) です。ライブラリはこの値を頼りにアプリケーションが処理したシグナルの量を判定します。
nest
ハンドラマスク値に加える値です。これでシグナルハンドラへの分岐の許可/不許可を制御します。

最初にライブラリが初期化されたとき, システム内部の「ハンドラマスク値」は-1に初期化されます。これが0の時にのみ, ハンドラへの分岐が起きます。したがって, 「シグナルハンドラ定義コマンド」でハンドラを定義した後, nestを1にした「シグナル待機コマンド」を実行しないとハンドラへの分岐はおきません。また, ハンドラを定義しないうちにハンドラマスク値を0にすると, シグナルが来たら暴走してしまいます。

ハンドラへ進入する際にハンドラマスク値は-1にされます。ハンドラ内でハンドラマスク値をいじらない限り, ハンドラへの再入はありません。

ビットではないので, nest = -1のコールを3回やったらnest = 1のコールも3回やらないと元には戻りません (nest = 3を1回でもいいが)。

初期のガイドでは, シグナルを定義せずに永眠コマンドとして使うときはnest = 1 にするように指示されていましたが, 今の推奨値は0です。初期のガイドの範囲でのライブラリを使用する場合においては, ライブラリのバージョンに関わりなく, 0でも1でも支障はありません。

time
このフィールドはコマンドの最後の96bit符号無し整数で, 単位は0x100000000分の1秒です。先に書く数値が下位であることに注意してください。例えば1.5秒を指定する場合は, t0 = 0x80000000; t1= 1; t2= 0; です。 100ミリ秒なら, t0= 0x1999999a; t1= 0; t1= 0; です。

0x0018.0x80:シグナルハンドラ終了

コマンド
dd 0x18, 0x80, signaldw, nest
guigui00.h
void lib_waitsignal(0x80, signaldw, nest);
機能

シグナルハンドラから復帰します。

解説

復帰時の値はスタックから読まれます。スタック上にふさわしいレジスタイメージがあれば, ハンドラの中でなくとも使ってかまいません。

シグナルがシグナルボックス中に残っていたら, ハンドラマスク値は再び-1になり, スタックはそのままでハンドラに再度分岐します。

ハンドラマスク値を分岐前の0に戻すため, 普通は nest = 1 にしてください。自動では戻りません。

Cではライブラリ関数にラッピングされているため, 単純にreturnしてください。


0x001c:ノーオペレーション

コマンド
dd 0x1c
機能

なにもしません。単に飛ばされます。


0x0020.0:ウィンドウオープン

コマンド
dd 0x20, window, slot, width, height
guigui00.h
struct LIB_WINDOW *lib_openwindow(struct LIB_WINDOW *window, int slot, int width, int height);
void lib_openwindow_nm(struct LIB_WINDOW *window, int slot, int width, int height);
struct LIB_WINDOW *lib_openwindow_am(struct LIB_WINDOW *window, int slot, int width, int height);
機能

ウィンドウを開きます。

解説

ウィンドウはスロットのある限り幾つでも開けます。ウィンドウが一つでも閉じられるとプロセスも終了するのがデフォルトなので, それは困るなら拡張ウィンドウオープンを使います。

引数
window
128バイトのバッファのセグメントオフセットです。ライブラリはこの値とスロットでウィンドウを識別します。
slot
スロット番号です。ウィンドウ一つにつきスロット一つ消費します。
width, height
ピクセル単位でのウィンドウの大きさです。周りに枠やウィンドウタイトルが追加されます。ウィンドウの幅は (タイトルの長さ)*8+80 以上でなければなりません。枠の幅は, 上が29ピクセルで左右下が8ピクセルです。えせタスクバーの高さはWin9Xデザインでは28ピクセルです。

0x0020.1:拡張ウィンドウオープン@pokon0.c,pioneer0.ask

コマンド
dd 0x20, window, slot|1|flag, width, height
dd 1 | signal_flags<<8, signal_base
dd x_ofs, y_ofs ;オプショナル
guigui00.h
struct LIB_WINDOW *lib_openwindow1(struct LIB_WINDOW *window, int slot, int width, int height, int signal_flags, int signal_base);
void lib_openwindow1_nm(struct LIB_WINDOW *window, int slot, int width, int height, int signal_flags, int signal_base);
struct LIB_WINDOW *lib_openwindow1_am(struct LIB_WINDOW *window, int slot, int width, int height, int signal_flags, int signal_base);
機能

ウィンドウを開き, 描画を自分で制御したり状態を取得するためにシグナルを要求します。ウィンドウの状態はAPIも把握しているので, 拡張オープンしたウィンドウにも便利なグラフィックボックスなどは使えます。

引数
heightまで
ウィンドウオープンと全く同じ意味のフィールドです。slot | flagを忘れないように。
flag
bit1を立てるとx_ofs,y_ofsが存在することになります。guigui00.hにはありません。
signal_flags
要求するシグナルの種類です。設定はそれぞれ1にすると有効で, 0にするとデフォルト通り自動処理になります。全ビットを0にすれば, 通常のウィンドウオープンと全く同じになります。

実際のシグナルの値は, signal_baseの値に増分値を加えたものです。

ビット 増分値 意味
bit0 +0 VRAMアクセス許可
+1 VRAMアクセス禁止
+2 ウィンドウ全体の描画
+3 ウィンドウ全体の差分描画
bit1 +4 ウィンドウ位置変更
bit2 +5 タイトルバーカラー変更
bit3 +6 ウィンドウクローズ要求
bit4 VRAMアクセスシグナル要/不要反転 (後載せサクサクじゃあ!)
bit5 +7 クローズ完了通知
bit6 +8 リサイズ(予約?)
bit7 増分値スケールビット。増分値が全て四倍になる。

ほとんどのシグナルの長さは4バイトですが, ウィンドウ位置変更シグナルはx座標の値とy座標の値が続いて12バイトのシグナルになります。タイトルバーカラー変更シグナルもステータス値が後続し8バイトのシグナルになります。カラー変更のステータス値は以下の通りです (これがあればVRAMシグナルは要らないという訳ではない)。

0 VRAMアクセス禁止色
1 非アクティブ色
3 アクティブ色

シグナルに対する応答方法は以下の表の通りです。具体的な処理はウィンドウ制御を参照してください。
シグナル名 通知義務 備考
ウィンドウ描画許可 なし 必ず再描画シグナルも来る
ウィンドウ描画禁止 受信完了
ウィンドウ全体の再描画 描画完了 描画禁止でも無視して描画
ウィンドウ全体の再描画(差分) 描画完了 とりあえず再描画と同じ
ウィンドウ位置変更 なし
タイトルバーカラー変更 なし 再描画も来ると思われる
ウィンドウクローズ要求 なし ウィンドウを閉じましょう
クローズ完了 なし 以降スロットの再利用可

x_ofs,y_ofs
ウィンドウ内の原点の位置をウィンドウ枠の左上からのオフセットで指定します。テキストボックスなどのコンポーネントはここを基準にして配置されますし, 描画の際もここが原点になります。
デバッグ
ウィンドウが表示される前にwinman0が止まってしまう
VRAMシグナルだけ欲しい場合のオプションは 0x10 です。0x11 はウィンドウ描画シグナルのみ欲しい場合です。ウィンドウ描画完了シグナルが来るまで, winman0は待ち続けます。
モジュールハンドル初期化などと干渉
ハンドル初期化完了などを待っている間も, ウィンドウの制御シグナルは容赦なくやって来ます。返事の必要なシグナルを無視すると, またwinman0が止まります。
ライブラリ終了する前に
ウィンドウを閉じておかないとまずいようです。
反応速度
重く遅い処理をする必要がある場合, シグナルハンドラを使わないと, 体感速度が大幅に低下することがあります (winman0がウィンドウ描画完了をひたすら待つようになっているため)。

0x0024.0:ウィンドウクローズ

コマンド
dd 0x24,0, window
guigui00.h
void lib_closewindow(0, window);
機能

ウィンドウを閉じます。

解説

ウィンドウはすぐ閉じるわけではないため, スロットを再利用するには拡張ウィンドウオープンを使って, 完了シグナルをもらう必要があります。

引数
window
ウィンドウオープンで指定したものと同じです。

0x0028.0x1011.テキストボックスオープン

コマンド
dd 0x28, opt, textbox, backcolor, width,height, x,y, window, fontset, filler
guigui00.h
(LIB_TEXTBOX*) lib_opentextbox(opt, textbox, backcolor, width, height, x, y, window, charset, filler);
void lib_opentextbox_nm(opt, textbox, backcolor, width, height, x, y, window, charset, filler);
(LIB_TEXTBOX*) lib_opentextbox_am(opt, textbox, backcolor, width, height, x, y, window, charset, filler);
機能

ウィンドウにテキストを表示するためのテキストボックスを貼り付けます。

引数
opt

各ビットに意味があります。

bit 0 0 デフォルト背景色はシステム指定の色。backcolorは0。
1 デフォルト背景色はbackcolor。
bit 4 0 高さ16ピクセルのフォントセットを使う。
1 高さ8ピクセルのフォントセットを使う。
bit12 0 普通のテキストボックス。
1 タイトル用テキストボックス。ウィンドウごとに一つ必要。ウィンドウタイトルのテキストボックスはopt=0x1000でなければなりません。
textbox

大きさ 64 + width *height *8 バイトのバッファのセグメントオフセットです。

backcolor

0から15の背景色です。

width, height

テキストボックスの大きさです。単位は8x16もしくは8x8ピクセルの半角キャラクタです。ここの指定に応じて, textboxが指し示すバッファの大きさも変化します。ウィンドウタイトルのwidthの最大値は (ウィンドウの幅/8 -10) です。heightは1です。

x,y

ウィンドウ内でのテキストボックス左上の座標でピクセル単位です。テキストボックスはウィンドウからはみ出してはいけません。今はxは8の倍数でないといけません。

window

ウィンドウオープンコマンドで指定したwindowの値です。

fontset

テキストボックスで使用するフォントセットのスロット番号を入れます。システムスロット0xc0には高さ16ピクセルのasciiフォントセットが入っています。ウィンドウタイトルにはこの0xc0を使わなければなりません。

filler

テキストボックスとバッファを埋める初期値を入れます。asciiでは空白か0x00を入れてください。

ウィンドウに複数のテキストボックスを貼り付けるとき, テキストボックス及び枠が重なってはいけません。枠の幅は3ピクセルです。


0x002c.テキストボックスクローズ

コマンド
dd 0x2c,0,textbox
guigui00.h
void lib_closetextbox(0, textbox);
機能

テキストボックスをクローズするようです。


0x0030.グラフィックボックスオープン・スクロールなし @test012.c

コマンド
dd 0x30, opt, gbox,1,filler,width,height,x,y,window
guigui00.h
(LIB_GRAPHBOX*) lib_opengraphbox(opt, gbox, 1, filler, width, height, x, y, window)
void lib_opengraphbox_nm(opt, gbox, 1, filler, width, height, x, y, window)
(LIB_GRAPHBOX*) lib_opengraphbox_am(opt, gbox, 1, filler, width, height, x, y, window)
機能

ウィンドウに画像を表示するグラフィックボックスをウィンドウに貼り付け, fillerの値で初期化します。

グラフィックボックスのバッファにデータを書き込み, フラッシュするとバッファの内容が画面に反映されます。フラッシュは要求した時の他にシステムの都合によって自動的に実行されます。

グラフィックボックスのデータは下位のバイトが左のピクセルに対応します。フォントに使うパターンとは逆です。

引数
opt

各ビットに意味があります。

bit0-11 0x001 予約(?)
bit12 0 バッファをfillerで埋める
1 埋めない
bit13,14 0
bit15 0 オープン直後フラッシュする
1 しなくてもいい (するかも知れない)
bit16-31 0 予約

しなくてもいいがするかも知れないというのはつまり, このコマンドを実行する前にバッファの初期化をしておかないといけないということです。

gbox

64+width*height バイトのバッファのセグメントオフセットです。gbox+64以降の部分はグラフィックバッファなので自由に読み書きしてかまいません。4バイトアラインしておかないと, 一部のコマンドで問題になります。

filler

グラフィックボックスとバッファを初期化する色です。バッファはバイト単位で構成されますが, 色は0から15の値でなければなりません。

width,height

グラフィックボックスの幅と高さです。ウィンドウをはみ出してはいけません。

x,y

グラフィックボックス左上のウィンドウ上での座標です。

window

ウィンドウオープン時に指定した値と同じです。


0x0030.0x27.16bpp,32bppグラフィックボックスオープン @test043

コマンド
dd 0x30, opt, gbox,mode,filler,width,height,x,y,window
guigui00.h
(LIB_GRAPHBOX*) lib_opengraphbox(opt, gbox, mode, filler, width, height, x, y, window)
void lib_opengraphbox_nm(opt, gbox, mode, filler, width, height, x, y, window)
(LIB_GRAPHBOX*) lib_opengraphbox_am(opt, gbox, mode, filler, width, height, x, y, window)
機能

上とほぼ同じです。あれは4bppでしたがこちらは16, 32bppになります。このグラフィックボックスは線描やらの機能が (まだ) なく, フラッシュしかできません。

引数
mode

色深度と減色設定です。

bit0-2 色深度です。2で16bpp, 4で32bpp(実質24bpp) になります。
bit5 速度重視ビットです。これを1にすると, 減色 (test043では自動中間色表現と書かれている) する際に品質を落としてもいいから早くしてほしいという意味になります。

グラフィックバッファのビット配置は以下の通りです。

16bpp: dw R<<11 | G<<5 | B
32bpp: db B, G, R, 0

0x0030.2.グラフィックボックスオープン・スクロールあり@test017.c

コマンド
dd 0x30, opt,gbox,1,0,bwidth,bheight,width,height,x,y,window
guigui00.h
(LIB_GRAPHBOX*) lib_opengraphbox2(opt, gbox, 1, filler, bwidth, bheight, width, height, x,y, window);
void lib_opengraphbox2_nm(opt, gbox, 1, filler, bwidth, bheight, width, height, x,y, window);
(LIB_GRAPHBOX*) lib_opengraphbox2_am(opt, gbox, 1, filler, bwidth, bheight, width,height, x,y, window);
機能

バッファの一部が表示されるグラフィックボックスをウィンドウに貼りつけ, スクロール位置を(0,0)に初期化します。

引数
opt

各ビットに意味があります。

bit0-11 0x002
bit12 0 バッファをfillerで埋める
1 埋めない
bit13,14 0
bit15 0 オープン直後フラッシュする
1 しなくてもいい (絶対しないわけではない)
bit16-31 0 予約

絶対フラッシュしないわけではないというのはつまり, このコマンドを実行する前にバッファの初期化をしておかないといけないということです。

bwidth,bheight

ピクセル単位のバッファの大きさです。bwidth >= width かつ bheight >= height でなければなりません。

width,height

ピクセル単位の表示する大きさです。はみ出す分はスクロールさせると表示できます。

そのほかはスクロールなしと同じです。


0x0030.0.既存グラフィックボックスオープン

コマンド
dd 0x30, opt, gbox
機能

グラフィックボックスをウィンドウに貼りつけます。

何に使うんだろう。ウィンドウをいったんクローズして, もう一度同じのをオープンした時に復元するためなんだろうか。でもテキストボックスにはこういう機能はないなあ。


0x0034.グラフィックボックスクローズ

コマンド
dd 0x34, opt, gbox
機能

OSASK V2.8からV4.0ではライブラリがハングアップします。


0x0038.なし


0x003c.0x33.ウィンドウ制御 (ソース上でかけ離れている)

コマンド
dd 0x3c, opt, window
guigui00.h
void lib_controlwindow(opt, window);
機能

拡張オープンしたウィンドウを自前で制御するためのコマンドです。拡張オープンでないものはpioneerライブラリが同じように制御しています。

引数
opt

ビットごとに意味があり, 複数のビットを同時に1にできます。下位から順に解釈されます。

bit0 ウィンドウの枠を描画しウィンドウを塗りつぶす。付加したコンポーネント (テキストボックスなど) は描画されない。タイトルは描画される。
bit1 コンポーネントを描画。
bit2 ウィンドウ塗りつぶしを抑制するオプション。
bit3 コンポーネントの描画を差分描画にするオプション。このビットを1にすると, ウィンドウ塗りつぶしも抑制される。
bit8 描画禁止シグナルの受理をシステムに通知。
bit9 再描画完了をシステムに通知。
window

ウィンドウに指定した物と同じです。


0x0040.0x051.テキストボックス文字列書き込み

コマンド
dd 0x40, opt, x,y, textbox, color, backcolor, STRING
gugui00.h
void lib_putstring0(opt|0x4000, x,y, textbox, color, backcolor, length, &str);
void lib_putstring1(opt|0x4000, x,y, textbox, color, backcolor, base, length, &str);
/* optのbit14を立てておりポインタのみ使える。*/ void lib_putstring_ASCII(int opt, int x_pos, int y_pos, struct LIB_TEXTBOX *textbox, int color, int backcolor, const char *str);
void lib_putstring_SJIS0(int opt, int x_pos, int y_pos, struct LIB_TEXTBOX *textbox, int color, int backcolor, const char *str);
/* EUCがない! */
機能

テキストボックスとそのバッファに文字を書き込みます。

表示結果がテキストボックスをはみ出してはいけません。自動折り返しはしませんし, 改行コードは使えません。複数行に書き込むには, このコマンドを行数分だけ実行することになります。

引数
opt

各ビットに意味があります。

bit 0 0 背景色はテキストボックスのデフォルト。backcolorは0。
1 背景色はbackcolor。
bit 1 0 フォントは二色。
1 フォントはカラー。colorもbackcolorも0。

タイトル用テキストボックスに書き込む場合, optのこれらのビットが0でなければなりません。

テキストボックスに二色とカラーのフォントを混ぜて表示するには, コマンドを複数回呼ぶことになります。

bit12,13 00 STRINGにbaseフィールドはない。文字列は32ビット形式。
01 STRINGにbaseフィールドがある。文字列はbase+符号無し8ビット形式。
10 STRINGにbaseフィールドがある。文字列はbase+符号無し16ビット形式。
11 32ビット形式でしょう。サンプルがありませんが。
bit14 0 STRINGは半角コード列フィールドを持つ。
1 STRINGはポインタフィールドを持つ。
x,y

半角キャラクタ単位でのテキストボックス内の位置です。指定された位置から文字は右へと表示されます。

textbox

テキストボックスオープンで指定したものと同じです。

color

文字色です。

backcolor

背景色です。

STRING

ベース値フィールド (オプショナル), 文字列長フィールド, 文字列またはそのポインタフィールドからなります。それぞれのフィールドがあるなしはoptによります。書き方は以下のいずれかになりますが, guigui00.hでは base, offset の形式しか使えません。

  1. dd length, c0,c1,c2,...
  2. dd base, length
    db c0,c1,c2,...
  3. dd base, length
    dw c0,c1,c2,...
  4. dd length, offset, selector
  5. dd base, length, offset, selector

baseは半角コードのベース値です。8/16ビット符号無し整数の c0,c1,c2,... にこの値を足した物が実際の半角コードになります。optによってはこのフィールドはありません。

lengthは表示する半角数です。実装では0=0x100000000とみなされます。

selector:offsetは表示する半角コード列のポインタです。optによってはこのフィールドはありません。

c0,c1,c2,...は半角コード列です。コマンドの長さは4バイトの倍数でなければならないので, 空きがあるときは0で埋めておいてください。


0x0044.0xf0.線・長方形描画

コマンド
dd 0x44, opt, window, color, x0,y0, x1,y1
guigui00.h
void lib_drawline(opt, window, color, x0, y0, x1, y1);
機能

線・長方形を描く低レベルコマンドです。再描画を自分で指示してください。

引数
opt

ビットごとに以下の意味を持ちます。

bit4,5 00
01 長方形
10 矩形塗りつぶし
bit6,7 00 pset
01 and
10 or
11 xor

他のビットは予約されています。0にしてください。

window

ウィンドウオープンで指定した物と同じです。-1を指定すると画面全体になりますが, そんなことをしてはいけません。

color

色です。0から15の値を指定します。

(x0,y0),(x1,y1)

始点と終点のウィンドウ上での座標です。 x0 <= x1 && y0 <= y1 でないといけないようです。


0x0048.1.文字列描画

コマンド
dd 0x48,1, window, fontset, x, y, color, back_color, length, c0,c1,...
機能

文字を描画する低レベルコマンドです。再描画は自分で指示してください。

引数
(x,y)

描画する文字列の左上の点のウィンドウ内での座標です。現在, 描画ルーチンの不備のためにxは8の倍数である必要があります。

c0, c1, ...

32bit半角コードです。他の形式は使えません。

そのほかoptなどのパラメータは文字表示コマンド背景色付きと同じです。


0x004c.0x27.画像描画

コマンド
dd 0x4c,mode, window, x,y, width,height, skip, offset,selector
guigui00.h
void lib_putblock1(window, x,y, width,height, skip, offset); /* mode=1固定 */
機能

画像を描画する低級コマンドです。再描画を自分で指示してください。

引数
mode

画像の色深度です。1,2,4がそれぞれ8bpp(実質は4bpp),16bpp,32bpp(実質は24bpp)に対応します。16bppと32bppでは, 代わりに 0x22, 0x24 を使うと高速モードになります (減色品質を落してでも速く処理されます。なお現在の実装では1割程度速くなりますが, 品質は段違いに悪くなるように見うけられます)。8bppに高速モードはありません。

window

ウィンドウオープンで指定したものと同じです。描画範囲がウィンドウをはみだしてはいけません。-1を指定すると画面全体になります。

(x,y)

描画する画像の左上の点のウィンドウ上での座標です。

width,height

その長方形の幅と高さです。0にしてはいけません。

skip

ラインごとにスキップするバイト数です。普通は(データの幅)-(描画幅) の値をバイト単位で代入します。-(データの幅)-(描画幅) の値を代入してデータをさかさまに読ませるなどの仕掛けもできます。

selector:offset

画像データの転送開始位置のポインタです。ここを左上の頂点としてデータが読み込まれます。


0x004c.0x8027.画像描画やや安全 (グラフィックボックスフラッシュ)

コマンド
dd 0x4c,0x8000|mode, window, x,y, width,height, skip, offset,selector
guigui00.h
void lib_flushgraphbox(opt, window, x,y, width,height, skip, offset);
機能

画像を描画する低級コマンドです。ウィンドウ描画禁止中は描画しないのでグラフィックボックスのフラッシュに使われました。パラメータの意味は上と同じです。

専用のコマンドグラフィックボックスフラッシュが用意されたので, できればそっちを使うべきでしょう。このコマンドを使うと, そのウィンドウの全てのグラフィックボックスが"差分描画の必要あり"とされてしまいます。

一部のベータ版OSASKの暫定仕様のみ0x80000001を使いましたが, 今は使ってはいけません。


0x0050.0x80c0.点描複数

コマンド
dd 0x50,opt,window, x,y, width,height, num, offset,selector
guigui00.h
void lib_drawpoints1(opt, window, x,y, width,height, num, offset);
機能
点を複数描画する低レベルコマンドです。再描画の指示は自分でしてください。
引数
opt

描画属性を指定します。

bit6,7 00 pset
01 and
10 or
11 xor
bit15 やや安全モード。ウィンドウ描画禁止中は描画しない。

ほかのビットは予約されているので0にしてください。

window

ウィンドウオープンで指定したものと同じです。-1にすると画面全体になります。

(x,y),(width,height)

ここを左上として幅がwidth, 高さがheightの長方形が描画する全ての点を含まなければなりません。描画する点はこの(x,y)を原点とする座標を使います。

num

点の個数です。0は許されません。

selector:offset

点の構造体のポインタです。

struc point
.x	resd 1
.y	resd 1
.color	resd 1
endstruc

0x0054.0x80c0.グラフィックボックス線描 @test014.c

コマンド
dd 0x54, opt, gbox, color, x0,y0, x1,y1
guigui00.h
void lib_drawline0(opt, gbox, color, x0,y0, x1,y1);
void lib_drawpoint0(opt, gbox, color, x,y); /* x0=x1=x, y0=y1=y */
機能

グラフィックボックスとそのバッファの両方に線を描画します。

長方形機能はまだありませんが予定されています。水平線や垂直線を書く場合は長方形塗りつぶしを使う方が速いはずです。

引数
opt

ビットごとに意味があります。

bit6,7 00 pset (他は遅くなる可能性がある)
01 and
10 or
11 xor
bit15 非同期 (画面に描画しない)

ほかのビットは予約されているので0にしてください。描画範囲がグラフィックボックスの表示範囲を越える場合は非同期ビットを指定しなければなりません。

gbox

グラフィックボックスオープンで指定したものと同じです。

color

線の色です。多分0から15でないといけません。

(x0,y0), (x1,y1)

線の両端の座標です。bwidth*bheight の平面上の座標であり, この中に収まらなければなりません。なお bwidth, bheight とも65536未満でなければなりません。


0x0058.0x2001.グラフィックボックススクロール @test018.c

コマンド
dd 0x58,0x2001,gbox,bufofs,vx,vy
guigui00.h
void lib_putblock02001(gbox, bufofs, vx,vy);
機能

グラフィックボックスの表示位置を変更 (スクロール) 及びフラッシュします。

引数
gbox

グラフィックボックスオープンで指定したものと同じです。

bufofs

表示する時に左上の原点となるデータのセグメントオフセットです。フラッシュするときに指定するものと同じです。普通はグラフィックボックスオープンで使ったbwidthを使って bufofs = gbox +64 +bwidth *vy +vx と計算されます。

(vx,vy)

左上の原点として表示される点のデータ内での座標です。

bwidth * bheight のデータの中から, (vx, vy)を原点として width * height の領域が新たな表示領域となります。


0x0058.0x3001.グラフィックボックス差分スクロール @test017.c

コマンド
dd 0x58,0x3001,gbox,buf,vx,vy, tmpofs, tmpskip, 16
guigui00.h
void lib_putblock03001(gbox, buf, vx,vy, tmpofs, tmpskip, tcol0);
機能

グラフィックボックス内の表示位置変更 (スクロール) をし, バッファ内で使用前使用後の差分を計算して差分フラッシュします。現在の表示内容とそこに対応する画像データが一致していなければ正しく差分ができません (多分。しかしそれを逆に利用することもできるはず)。

引数

前半のパラメータは上と同じです。

tmpofs

差分を作るためのバッファのセグメントオフセットです。((width +tmpskip) * height)バイトの大きさが必要です。

tmpskip

一時バッファのラインスキップの長さです。とりあえず0にしておけば問題ありませんが, width + tmpskip が4の倍数になるように設定すると高速化が期待できます。

最後の16 (tcol0)

差分転送に使われる透明色です。4bitモードなので, 16のままで問題ありません。


0x0058.0x4027.グラフィックボックスフラッシュ

コマンド
dd 0x58,0x4000|mode,gbox,x,y,width,height
機能

グラフィックボックスの一部の領域をフラッシュします。8, 16, 32bppに対応しています。スクロールには対応していません。

引数
mode

画像の色深度と描画モードです。1,2,4がそれぞれ8bpp (実質は4bpp), 16bpp,32bpp (実質は24bpp) に対応します。16bppと32bppでは, 代わりに 0x22, 0x24 を使うと高速モードになります (減色品質を落してでも速く処理されます。なお現在の実装では1割程度速くなりますが, 品質は段違いに悪くなるように見うけられます)。8bppに高速モードはありません。

gbox

グラフィックボックスオープン時に指定したバッファです。

(x,y)

描画する画像の左上の点のグラフィックボックス上での座標です。

width,height

その長方形の幅と高さです。0にしてはいけません。


0x005c.0x80c0.グラフィックボックス点描複数 @test025.c

コマンド
dd 0x5c, opt,gbox, x,y, width,height, num,offset,selector
guigui00.h
void lib_drawpoints0(opt, gbox, x,y, width,height, num, offset);
機能

グラフィックボックスとそのバッファに点を打ちます。

引数
opt

各ビットに意味があります。線描と同じですが。

bit6,7 00 pset
01 and
10 or
11 xor
bit15 非同期 (画面に描画しない)

ほかのビットは予約されているので0にしてください。描画範囲がグラフィックボックスの表示範囲を越える場合は非同期ビットを指定しなければなりません。

gbox

グラフィックボックスオープンで指定したものと同じです。

(x,y),(width,height)

描画範囲の左上の座標と幅と高さです。座標はグラフィックボックス内座標で, 単位はピクセルです。この描画範囲が全ての点を含まなければなりません。

num

点の数です。実装では0=0x100000000として扱われます。

selector:offset

描画用点データのポインタです。点の座標は描画範囲の左上を原点として作ってください。内部形式です。


0x0060.シグナルボックスオープン

コマンド
dd 0x60, length, sigbox, eos, rewind
guigui00.h
int* lib_opensignalbox(bytes, signalbox, eos, rewind);
void lib_opensignalbox_nm(bytes, signalbox, eos, rewind);
int* void lib_opensignalbox_am(bytes, signalbox, eos, rewind);
機能

シグナルを受信するシグナルボックスを定義します。

引数
length

バイト単位でのシグナルボックスの大きさです。下位二ビットは予約されており, 0でなければなりません。最低でも16はないと処理できないと思われます。効率を考えると256以上は必要でしょう。

sigbox

シグナルボックスのセグメントオフセットです。下位二ビットは予約されており, 0でなければなりません。

eos

シグナル終了番号であり, 0です (0じゃなくてもいいみたいだけど)。シグナル列の終端にはこの値が書き込まれます。この値はシグナルではありません。

rewind

巻き戻しシグナルのシグナル番号です。このシグナルは長さフィールドが後続し, 8バイトになります。しかし受信量としては長さフィールドに指定された長さを通知してください。


0x0064.なし


0x0068.シグナル定義

機能

キー入力などのイベントとアプリが受け取るシグナルとの対応を定義します。将来は先取りされてコマンド実行前からシグナルが定義されていることになるようです。したがって, 定義前からシグナルが来る可能性を考えてプログラムしてください。


0x0068.0x10.タイマーシグナル定義

コマンド
dd 0x68, 0, 0x0010, slot, 0, 1, signal, 0
guigui00.h
void lib_definesignal1p0(0, 0x0010, slot, 0, signal);
機能

タイマーイベントが起きたときのシグナルを定義します。このシグナルはウィンドウではなくタスクに送られます。

引数
slot

タイマーのスロット番号です。

signal

要求するシグナルです。


0x0068.0x100.文字入力シグナル定義

コマンド
dd 0x68, num, 0x0100, letter, window, 1, signal, 0
guigui00.h
void lib_definesignal1p0(num, 0x0100, letter, window, signal);
機能

キーボードからの文字入力に対してシグナルを定義します。

引数
num

定義するシグナル数-1 です。numが1以上の時, signalおよびletterは1づつ増える連続した値が割り当てられます。4096以上は指定できません。

letter

シグナルを定義する文字です。指定可能な値は, 0x20〜0x7eのasciiコードと以下の0x80に始まるコントロールコードです。

0x80 ESC 0xb0 SCROLL LOCK 0xdc 親指左
0x81 PF1 0xb1 NumLock 0xdd 親指右
: 0xb2 CAP
0x94 PF20 0xb3 0xe0 取消
0x9a EXT1 0xb4 SHIFT 0xe1 実行
0x9b EXT2 0xb5 CTRL 0xe2 かな漢字
0xb6 ALT 0xe3 000
0xa0 RETURN 0xb7 0xe4 漢字辞書
0xa1 後退 0xb8 COPY, PrintScreen 0xe5 単語抹消
0xa2 TAB 0xe6 単語登録
0xa3 0xba BREAK 0xe7 英字
0xa4 挿入 0xbb SYSREQ 0xe8 英小文字/カタカナ
0xa5 削除
0xa6 HOME 0xc0 Windows 0xf8 親指左 および 右
0xa7 END 0xc1 Menu
0xa8 前行
0xa9 次行 0xd0 半角/全角
0xd1 無変換
0xac ← 0xd2 変換
0xad → 0xd3 ひらがな
0xae ↑ 0xd4 カタカナ
0xaf ↓
※おおむねFMTOWNS親指シフトキーボードのキートップの文字を採用しています。

さらに, 文字の特定のビットを立てると拡張定義になります。拡張定義では同じ文字でもキーの左右が区別されたりします。英字は大文字を使いますが, 記号は同じキーに書いてあるののどちらでもかまいません。

bit12,13 01 拡張1 (親指左)
10 拡張2 (親指右)
bit14,15 00 メイク (押下)
01 ブレイク (開放)
10 リメイク (自動リピート)

また拡張入力ではCAPやシフトなどが無視されます。これを区別するには以下の数値をORします。たとえば 'A' | 0x1000 | NOCAP だと, 'A'と書いてあるキーをCAPしていない時にメイクしたらシグナル, SHIFTやALTやCTRLは無視, という指定になります。

NOCAP 0x00040000
CAP 0x04040000
NOSHIFT 0x00100000
SHIFT 0x10100000
NOCTRL 0x00200000
CTRL 0x20200000
NOALT 0x00400000
ALT 0x40400000
signal

定義したいシグナル (群) の先頭の値を入れます。

window

ウインドウオープンで指定したものと同じです。そのウィンドウがアクティブのときのみ, 指定されたイベントに応じたシグナルが発生します。


0x0068.0x200.低レベルマウスシグナル

コマンド
dd 0x68, 0, 0x0200, code, window, 1, signal, 0
guigui00.h
void lib_definesignal1p0(0, 0x0200, code, window, signal);
機能

マウスの低レベルな (GUIボタンとかではない) シグナルを定義します。

解説

呼び出し順序が重要で, 座標とボタンのシグナルを定義する場合, 必ず座標シグナルを先に定義しなければなりません。そうしないと, 多分シグナルの順番が狂うのでしょう。

signalの前の1はシグナルの長さだろう。マウス座標のシグナルにはこれを3にするんじゃないのか? と思う人もいるかもしれませんが, そこは常に1です。

引数
code

シグナルの種類です。

bit 0-3 0x0 左ボタン /ウィンドウ内での座標(感度0,1,2)
0x1 右ボタン /ウィンドウを出る(感度0,1,2)
0x2 中ボタン /ウィンドウ内外での座標(感度0,1,3)
bit 4-7 0x1 座標
0x2 プレス
0x3 リリース
bit 8-11 0x0 予約でしょう。
bit12-15 0x0 感度0:クリック時のみ座標値を送信
0x1 感度1:クリックとドラッグ中に送信
0x2 感度2:ウィンドウ内で常に送信
0x3 感度3:常に送信

感度はウィンドウ毎に統一しておく必要があります。

コード 0x??10(ウィンドウ内座標),0x??11(ウィンドウ脱出) のシグナルと 0x??12(ウィンドウ内外) のシグナルは排他的です。

コード 0x?010, 0x?012 のシグナルは後に座標値が続いて12バイトのシグナルになります。座標値はx,yの順で, それぞれウィンドウの左上を原点とします。ウィンドウ内というのは枠の上を含みますから, ウィンドウ内と指定しても負の座標値が来る可能性があります。

座標シグナルは, ボタンプレス/リリース位置が分かる程度に送られて来ます。座標シグナルにボタンシグナルが続くことを前提にしてはいけません。また, 感度を必要以上に高くするのは無駄ですから避けてください。


0x0068.0.シグナル定義終端

コマンド
dd 0x68, 0,0,0,0,0,0
guigui00.h
void lib_definesignal0p0(0, 0, 0, 0);
解説

シェルとの約束として, シグナルの通知が一通り済んだらこのダミーコマンドを実行します。


0x006c.シグナルを自分に送る

コマンド
dd 0x006c, num<<2, sig0,sig1,...
または
dd 0x006c, (num<<2)|1, offset,selector
機能

シグナルを自分に送ります。疑似マルチスレッドライブラリで使われています。

引数
num

送るシグナルの数です。

sig0,sig1,...

シグナルの列です。

selector:offset

シグナル列のポインタです。

どちらも長いシグナルとして扱われ, 途中にrewindが挟まることはありません。


0x0070.タイマーオープン

コマンド
dd 0x70, slot
guigui00.h
void lib_opentimer(slot);
機能

タイマーをユーザーで設定できるようにします。このコマンドを実行しないとタイマー設定はできません。

解説

標準タイマーを指定した場合, 時間基点に関する設定はそのまま引き継がれます。オープン直後のタイマーは停止しています。

引数
slot
タイマーに使うスロットです。標準タイマーのslotである0x01c0を指定する場合, タイマークローズを実行するまでシグナル待機コマンド の時間に関する指定は全て使えません。タイマーは指定されたslotだけではなく, 続く二つを合わせて計三つのslotを使います。


0x0074.タイマークローズ

コマンド
dd 0x74, slot
guigui00.h
void lib_closetimer(slot);
機能

オープンしていたタイマーをシステムに返しスロットを開放します。

解説

クローズ後は, そのタイマーに対する設定はできません。また, 再度オープンすることもできますが, 古い設定は保存されません。

タイマーをクローズする前にタイマーを停止しておいてください。

引数
slot

タイマーとして使っていたスロットの番号です。三つのうちの最初の一つを指定します。


0x0078.1.タイマー停止

コマンド
dd 0x78,1,slot
guigui00.h
void lib_settimer(1, slot);
機能

タイマーを止めます。

解説

下のタイマー設定と同じコマンドですが, bit0とbit1が排他的なため敢えて分けています。

タイマーは停止状態にあるときは指定した時刻になってもシグナルを発しません。また各種の設定のためには停止状態にする必要があります。

タイマーを止めてもタイマーの時間基点はそのままです。従って,

  1. 今から十秒後にタイマーシグナル設定
  2. やっぱやめ
  3. 時間基点に三秒足して再始動

という操作をすると(3)から十三秒以内にタイマーシグナルが来ることになります。私はハマりました。


0x0078.0x32.タイマー設定

コマンド
dd 0x78, opt, slot
または
dd 0x78, opt, slot, t0,t1,t2
guigui00.h
void lib_settimer(opt, slot);
void lib_settimertime(opt, slot, t0, t1, t2);
機能

タイマー設定を行ないます。タイマーは時間基点を過ぎるとタイマーシグナルを発します (時間基点が過去の場合, すぐにシグナルを発するようです)。タイマーが活動中のときは設定できません。タイマーを止めてからにしてください。

引数
opt

bit1,4,5に意味があり, bit0,2,3,6〜31は予約されています。必ず0にしておいてください。

上位のbitから解釈されます。複数のbitを1にすることで, 複数の設定が一度に可能です。

bit5 1 現在の時刻が時間基点になります。
0 時間基点に影響しません。
bit4 1 timeフィールド (t0,t1,t2) が存在しその値が時間基点に加えられる。
0 時間基点に影響しません。
bit2,3 インターバルモードに関する設定であり, 廃止されました。
bit1 1 タイマーが活動状態になり, 設定された時刻にシグナルを発します。
0 タイマーを始動しません。
(t0,t1,t2)
加算する時間です。形式について詳しくはシグナル待機コマンドを見てください。


0x0078.0x81.タイマー時間差設定

コマンド
dd 0x78,0x81, slot0, slot1, t0,t1,t2
機能

タイマー間の設定を行ないます。

解説

slot1のタイマーの時間基点が (slot0の時間基点)+(t2:t1:t0) になります。時間の形式について詳しくはシグナル待機コマンドを見てください。


0x0078.0x82.タイマー時間差取得 @test030.c

コマンド
dd 0x78, 0x82, slot0, slot1, 0,0,0
機能

(slot1の時間基点)-(slot0の時間基点) の値を取得します。

解説

最後の12バイトはパラメータではなくバッファです。ここに

dd t0,t1,t2

といういつもの形式で差が書き込まれます。形式について詳しくはシグナル待機コマンドを見てください。


0x007c.圧縮データ伸長

コマンド
dd 0x7c
解説

伸長コマンドのヘッダです。後にサブコマンドを続けて書くようになっています。


0x007c.0.サブコマンド終了

コマンド
dd 0
解説

サブコマンドの終端です。何もしないでユーザプログラムに復帰させる場合は

dd 0x7c /* 伸長コマンド開始 */
dd 0x00 /* サブコマンド終了 */
dd 0x00 /* コマンド終了 */

となります。tek0データを展開したい場合は

dd 0x7c /* 伸長コマンド開始 */
dd -7, dofs /* 書き込み先を指定 */
dd -0x7e, len, ofs, sel /* 展開サブコマンド */
dd 0x00 /* サブコマンド終了 */
dd 0x00 /* コマンド終了 */

となります。

伸長サブコマンドはEDIの値を変えますが, 終了サブコマンドによって, 呼び出し時の値に戻されます。


0x007c.-7.書き込み先指定

コマンド
dd -7, offset
機能

書き込み先のセグメントオフセットを指定します (セレクタはES固定です)。デフォルトはAPIコール時のEDIです。


0x007c.-9.読み込みリミット指定

コマンド
dd -9, limit
機能

読み込み開始位置 + 圧縮データの大きさ を明示します。


0x007c.-0x7f.l2d3データ伸長

コマンド
dd -0x7f, length, offset, selector
機能

selector:offsetにあるl2d3データを伸長し, lengthバイト書き込みます。終了後, 伸長データの終端が次の書き込み先になります。


0x007c.-0x77.tek5データ伸長

コマンド
dd -0x77, length, offset, selector
機能

selector:offsetにあるtek5データを伸長し, lengthバイト書き込みます。終了後, 伸長データの終端が次の書き込み先になります。


0x007c.-0x7b.tek2データ伸長

コマンド
dd -0x7b, length, offset, selector
機能

selector:offsetにあるtek2データを伸長し, lengthバイト書き込みます。終了後, 伸長データの終端が次の書き込み先になります。


0x007c.-0x7d.tek1データ伸長

コマンド
dd -0x7d, length, offset, selector
機能

selector:offsetにあるtek1データを伸長し, lengthバイト書き込みます。終了後, 伸長データの終端が次の書き込み先になります。


0x007c.-0x7e.tek0データ伸長

コマンド
dd -0x7e, length, offset, selector
機能

selector:offsetにあるtek0データを伸長し, lengthバイト書き込みます。終了後, 伸長データの終端が次の書き込み先になります。


0x0080.0.サウンドトラックオープン

コマンド
dd 0x80, slot, 0
guigui00.h
void lib_opensoundtrack(slot);
機能
サウンドトラック (ブザー) をオープンします。
引数
slot

サウンドトラックを割り当てるスロット番号です。サウンドトラックはスロットを一つ使います。


0x0084.サウンドトラッククローズ

コマンド
dd 0x84, slot
機能

サウンドトラックを閉じ, スロットを開放します。

引数
slot

サウンドトラックのスロット番号です。


0x0088.なし


0x008c.サウンドトラック制御

コマンド
dd 0x8c, slot, cycle
guigui00.h
void lib_controlfreq(slot, cycle);
機能

ブザーを制御します。

引数
slot

サウンドトラックのスロット番号です。周期が cycle/0x100000000 の音が出ます。 cycleを0にすると消音されます。周期は周波数の逆数です。


0x0090.なし


0x0094.なし


0x0098.なし


0x009c.なし


0x00a0.0x1c.モジュールハンドル初期化アプリ @music01d.ask

コマンド
dd 0xa0, opt, slot
guigui00.h
void lib_initmodulehandle(opt, slot);
void lib_initmodulehandle0(opt, slot);
機能
スロットをモジュールハンドルとして初期化し, アプリ専用ディレクトリの一つに移動させます。
解説
アプリは起動時に一連の専用ディレクトリを与えられます。分類に沿ってディレクトリを使い分けてください。
引数
opt
専用度 用途 備考
4 タスク固有 一時データ, スタック 非公式
8 ユーザ固有 設定や個人的記録の保存
12 マシン固有 インストール, ユーザ共通データ
16 ネット固有 アクセスカウンタ (?) まだ無い
slot

スロット番号です。スロットを一つ使います。


0x00a0.0xe0.モジュールハンドル初期化シェル @introc/tviewc00.c

コマンド
dd 0xa0,0xe0,slot,28,offset,selector
guigui00.h
void lib_initmodulehandle1(int slot, int num, int sig); /* サブコマンドを含む */
機能

スロットをモジュールハンドルとして初期化し, どこに移動させるかはシェルに任せます。大抵の場合, シェルは人間の指示を仰ぎます。アプリ専用ではないファイルにアクセスするにはこのコマンドでシェルに (人間に) お伺いを立てなければなりません。

複数の外部モジュールにアクセスしたければ, それらのモジュールを収めたディレクトリを渡すよう説明書で指示することになります。

引数
selector:offset

サブコマンドのポインタです。

このコマンドは手抜きにより完了するまで再実行できません。


0x00a0.-0xff.モジュールハンドル初期化シェルのサブコマンド

コマンド
dd -0xff, num, -0xfe,2,0x7f000001, signal, 0
引数
num

番号です。コマンドラインからの操作等を可能にするため, ファイルごとに別々の番号を振ってください。

signal

完了通知用シグナルの番号です。これがそのまま返ってきたら成功で, これに1から15を足したシグナルが返ってきたら失敗です。失敗したスロットは最挑戦するか諦めるかしてください。


0x00a4.なし


0x00a8.モジュールハンドル複写 (未詳)

コマンド
dd 0xa8,opt,destslot,srcslot
機能

スロットsrcslotのモジュールハンドルをスロットdestslotに複写します。一つのモジュールの複数の部分を別々にマッピングしたい場合はこのコマンドを使えということのようです。

適当なサンプルがありませんし, たぶん機能そのものがまだありません (あるのか?)。


0x00ac.モジュールハンドル移動8.3 @go9/drv_osa/osamain.c

コマンド
dd 0xac,opt,slot,40,offset,selector
guigui00.h
void lib_steppath0(int opt, int slot, const char *name, int sig); /* サブコマンドとセット */
機能

モジュールハンドルを指定のファイルまたはディレクトリに移動させます。この操作の前にハンドルがディレクトリに移動していなければなりません。そのディレクトリの中を検索します。

使用回数に制限がありましたがdanielでは解消されたそうです。

引数
opt

ビット1が強制ビットで, これを1にしておくとモジュールが存在しない場合新しく作られます。

slot

モジュールハンドルとして初期化したスロットです。

selector:offset

サブコマンドのポインタです。


0x00ac.-0xfd.モジュールハンドル移動8.3のサブコマンド @test016.c

コマンド
dd -0xfd,12
db name
dd -0xfe,2,0x7f000001,signal,0
引数
name

ファイルまたはディレクトリの名前です。隙間を0x20の空白で埋め, `.'も書いてascii大文字12文字でなければなりません。
例:"MYSRC01 .CC " 日本語や韓国語は使えません (未詳。test016.c>必ず大文字で, 12文字)。

signal

完了通知用シグナルの番号です。これがそのまま返ってきたら成功で, これに1から15を足したシグナルが返ってきたら失敗です。


0x00b0.モジュール作成 (未詳)

コマンド
dd 0xb0,opt,dirslot,mdlslot,tagdir,alocsize, tag,...,-1
機能

適当なサンプルがありません。そもそも使えるのか不明。

多分モジュールを作るのでしょうが, どんなタグが必要か, すでにモジュールがある場合はどうなるのか, などは不明です。 ……タグを書き換えるコマンドはまだ無いのかなぁ。


0x00b4.なし


0x00b8.なし


0x00bc.なし


0x00c0.0.モジュールマッピング @introc/tviewc00.c

コマンド
dd 0xc0,0,slot,len,offset,selector,(moffset)|(attr)
guigui00.h
void lib_mapmodule(0, slot, attr, len, offset, moffset);
機能

モジュールの一部をメモリ空間のモジュールマッピング領域にマッピングします。

引数
slot

モジュールハンドルのスロットです。一つのハンドルで複数箇所にマッピングしてはいけません。

len

マッピングする最大の長さです。0は許されません (あるいは0x100000000と同義でしょう)。4096の倍数です。長い場合はこの長さでマッピングを打ち切ります。モジュールが短い場合はそれに合わせて短くマッピングされます。マッピングされていないところにアクセスしてはいけません。

selector:offset

マッピングするメモリ領域のポインタです。マッピングする領域が重なってはいけません。

moffset

モジュール内のマッピング開始位置です。4096の倍数です。

attr

モジュールのマッピング属性です。属性を変えるにはマッピングし直します。

5 書き込み不能
7 書き込み可能

0x00c4.モジュールマッピング解除 (未詳) @beditc00.c

コマンド
dd 0xc4,0,len,offset,selector
guigui00.h
void lib_unmapmodule(0, size, addr);
機能

マッピングを解除し, 再マッピングやリサイズできるようにします。

引数
selector:offset

解除する領域の先頭ポインタです。

len

解除する範囲の長さです。


0x00c8.-0xfe.モジュール種別取得 (未詳)

コマンド
dd 0xc8,-0xfe,slot,8,offset,selector
機能

適当なサンプルがありません。

引数
slot

モジュールハンドルとして初期化したスロットでしょう。

selector:offset

8バイトのバッファのポインタでしょう。


0x00c8.-0xfd.モジュールサイズ取得 (未詳) @introc/tviewc00.c

コマンド
dd 0xc8,-0xfd,slot,16,offset,selector
guigui00.h
const int lib_readmodulesize(int slot);
機能

モジュールの大きさを取得します。

引数
slot

モジュールハンドルとして初期化したスロットです。

selector:offset

バッファのポインタです。16バイト使います。実際には先頭4バイトがモジュールの大きさで, 12バイトほど残ってますけど, OSASKではファイルサイズを128bitまで取るようです。一応。


0x00cc.なし


0x00d0.-0x100.モジュールタグリスト (未詳)

コマンド
dd 0xd0,-0x100,slot,buflen,ofs
機能

適当なサンプルがありません。

モジュールの名前が取得できるらしい。だまされることもあるのだろう。


0x00d4.なし


0x00d8.なし


0x00dc.なし


0x00e0.1.フォント定義 @introc/fnttstc0.c

コマンド
dd 0xe0,1,slot,num,offset,selector
guigui00.h
void lib_loadfont(1, slot, num, offset);
機能

ユーザ定義フォントをスロットに割り当てます。

解説

フォントというのは字形 (gryph) の集合です (個々の字形はフォントの一部であってフォントそのものではない。等幅フォント可変幅フォントという言葉の意味を考えれば当然でしょう)。

OSASKにおいては, フォントを定義するのにスロットを一つ, フォントの一部をフォントセットにマッピングするのにまた一つ使います。

引数
slot

フォントを割り当てるスロットです。

num

割り当てる半角フォントの数です。

selector:offset

実際のパターンのポインタです。半角一つにつき8x16=16バイトのパターンが要ります。ビット配列は 0x43 が □■□□□□■■ と画面に映るようになっています。上位ビットが左になり, カラーフォントやグラフィックボックスとは逆です。

コマンド終了後はその領域をどうしようと構いません。


0x00e0.2.半高フォント定義 @introc/hlftstc0.c

コマンド
dd 0xe0,2,slot,num,offset,selector
guigui00.h
void lib_loadfont(2, slot, num, offset);
機能

高さが半分, すなわち8x8のフォントを定義します。一つのパターンが8x8=8バイトで構成されるほかは上と同じです。


0x00e0.4.半高カラーフォント定義 @introc/hlfcolc0.c

コマンド
dd 0xe0,4,slot,num,offset,selector
guigui00.h
void lib_loadfont(4, slot, num, offset);
機能

高さが半分, すなわち8x8のカラーフォントを定義します。一つのパターンは8x8 x16色=32バイトで構成されます。その他は上と同じです。

パターンは上位のバイトが右の方のピクセルになります。一バイトのうちでは, 下位ニブルが左のピクセルで, 上位ニブルが右のピクセルです。


0x00e0.0x80000001.システムANKフォント読み込み @introc/fnttstc0.c

コマンド
dd 0xe0,0x80000001,slot
guigui00.h
void lib_loadfont0(0x80000001, slot);
機能

slotにシステム定義のANKフォントを割り当てます。現在, IBMターミナルフォントに似たフォントが入っており, ANKのK (カナ) は影も形もありません。


0x00e0.0x80000002.システム半高ANKフォント読み込み @introc/fnttstc0.c

コマンド
dd 0xe0,0x80000002,slot
guigui00.h
void lib_loadfont0(0x80000002, slot);
機能

slotにシステム定義の半高ANKフォントを割り当てます。

これは高さが半分の縮小フォントではありません。各字形が上下に半分づつ定義されており, 例えば, 0x64は'2'の上半分で0x65は'2'の下半分です ('2'のasciiコードは0x32です)。全角字形を半角二つで作るのと同じノリです。


0x00e0.0xc0000011.システムJIS+MSフォント読み込み

コマンド
dd 0xe0,0xc0000011,slot,1,sig
解説

廃止されました。init.ask@OSASK V2.1,V2.2にて死亡確認。


0x00e0.0xc0ffffff.OSASK自動拡張フォント読み込み @tviewc05.c

コマンド
dd 0xe0,0xc0ffffff,0,1,signal
guigui00.h
void lib_loadfont1(0xc0ffffff, 0, sig); /* マクロはslotと書いてあるが予約 */
機能

OSASK自動拡張フォントをシステムスロット0x21に割り当てます。

割り当てが成功するとsignalに指定したシグナルが返ってきます。失敗したら1から15を足したシグナルが返ってきます。

ところで普段韓国語フォントのファイルが無くても, 日本語フォントが読み込まれるだけで成功したことになっているようですが, これは今のシェルではとにかく成功を返すそうです。フォントを後から読み込ませると表示が正しくなるんだそうで。

半角コード 文字集合 半角数 字形 備考
-------------- --------------------------- ------- ---- -------------
0x0400〜0x4907 JIS X 0213 第一面 94*94*2 全角 一部Verで不備
0x4908〜0x4bf7 NEC拡張の第89区〜第92区相当 94* 4*2 全角 準備中
0x4bf8〜0x4d6f 予約 94* 2*2 空白ではない
0x4d70〜0x4da7 MS拡張 第115区相当の28点 28*2 全角 準備中
0x4da8〜0x4dbf 予約 12*2 空白ではない
-------------- --------------------------- ------- ---- -------------
0x4dc0〜0x4dff 予約 64 空白ではない
0x4e00〜0x4eff JIS X 0201 MS +NEC拡張 256 半角 0~|がMS
0x4f00〜0x4fff 予約 256 空白ではない
-------------- --------------------------- ------- ---- -------------
0x5000〜0x9507 KS C 5601 (KS X 1001) 94*94*2 全角
0x9508〜0x967f 予約 94* 2*2 全角
-------------- --------------------------- ------- ---- -------------
0x9680〜0x96ff 予約 128 空白ではない
0x9700〜0x97ff ascii (……は7ビットだが) 256 半角

NEC半角文字は2バイトコードで表現されるものもあるらしい。「NEC半角」という言葉には注意しよう。

0x000000〜0xffffffの中で表に無い文字はすべて予約です。空白が入っていると仮定してはいけません。

バグ

OSASK v1.9からv2.2に付属していた日本語フォントは一部に誤りがあります。


0x00e4.0.フォント開放 (未詳)

コマンド
dd 0xe4,0,slot
解説

適当なサンプルがありません。

フォントを割り当てたslotを開放? そのフォントを使ったフォントセットは多分使えなくなるのでしょう。


0x00e8.フォントセット定義

コマンド
dd 0xe8,0,slotd,slots,num,src,dest
guigui00.h
void lib_makecharset(0, slotd, slots, num, src, dest);
機能

フォントが持つ字形を32ビットの半角コード空間にマッピングし, フォントセットとして実際に使える状態にします。

雰囲気としては, フォント=モジュール, フォントセット定義=マッピング, というところでしょうか。

引数
slotd

フォントセットとなるスロットです。一度割り当てるごとにスロットを一つ使います。

例外として, OSASK自動拡張フォントを割り当てると勝手にスロットを四つ使います。またOSASK自動拡張フォントを使うときは, num,src,dest に 0x1000000,0,0 が指定されたものとみなされます。観念してその指定をしなければなりません。

slots

フォントスロットです。高さの違うフォントを混ぜてはいけません。カラーと二色のフォントは混在可能です。

num

マッピングする字形の数です。

src

貼りつける字形のフォント内の先頭番号です。

dest

半角コードの先頭番号です。


0x00e8.0.フォントセット終端

コマンド
dd 0xe8,0,slot,0,0,0,0
guigui00.h
void lib_makecharset(0, slot, 0, 0, 0, 0);
機能

フォントセットの終端を定義します。これを定義するとフォントセットが確定します。

slotにはフォントセットとして使う最後のスロットの次のスロットを指定します。


0x00ec.1.シフトJISデコード @test024.c

コマンド
dd 0xec,1,dlen,srcofs,srcsel,destofs,destsel, 0x400,0x4e00
guigui00.h
lib_wsjis2gg00jpn0(dlen, srcofs, destofs, 0x400, 0x4e00);
機能

シフトJISで書かれた文字列をOSASK自動拡張フォント向けにデコードします。

引数
dlen

変換結果の長さで, 単位はダブルワードです。

srcsel:srcofs

シフトJISの文字列のポインタです。

destsel:destofs

変換結果を入れるバッファのポインタです。 dlen+1ダブルワード程度まで確保しておく必要があります。

0x400, 0x4e00

JIS X 0201 及びJIS X 0213-1 +NEC+MS のフォントの位置です。と言っても, 一バイト文字の初めの文字は0x00で, 終わりの文字は0xffです。互換のフォントを自作するなどの場合, 開始位置に注意してください。


0x00ec.2.EUCデコード文字集合2

コマンド
dd 0xec,2,dlen,srcofs,srcsel,destofs,destsel,b0,b1
guigui00.h
void lib_seuc2gg00(dlen, srcofs, destofs, b0, b1);
機能

シングルシフトを使わない (日本語で言えば, いわゆる半角カナや JIS補助漢字あるいは2000JIS第二面を使わない) EUC文字列を, OSASK自動拡張フォント向けにデコードします。

引数
b0

C0:0x20:G0:0x7f:C1:0xa0 (要するに0x00から0xa0) の範囲の一バイト文字用半角フォントの位置です。0x9700がasciiのフォントで, 0x4e00が JIS X 0201 のフォントです。SJISと同じく, 94文字集合ではなく一バイト集合として扱われます。

b1

G1の94^2文字集合のフォント位置です。0x400が JIS X 0213-1 で, 0x5000が KS C 5601-1987 (KS X 1001) です。


0x00ec.3.EUCデコード文字集合4

コマンド
dd 0xec,opt,dlen,srcofs,srcsel,destofs,destsel,b0,b1,b2,b3
機能

シングルシフトもデコードできるEUCデコーダです。

引数
opt

G0からG3が何文字集合であるか指定します。

bit0-15 3
bit16,17 G0の指示
bit18,19 G1の指示
bit20,21 G2の指示
bit22,23 G3の指示
指示
00 1バイト集合
01 94^2集合
10 予約
11 予約

他のビットは予約です。0にしてください。

G0に94^2集合を割り当てる場合に0x20の空白がどうなるかは忘れました。

b0〜b3

それぞれG0からG4のフォントの位置です。


0x00f0.セグメント作成 (未詳) @music01d.ask

コマンド
dd 0xf0,opt,sel,ar,limit,ofs,bsel
機能

適当な解説がありません。ソースを斜めに読んで推測しますが, LDTにエントリを追加するだけです。マッピングしたDLLに実行可能属性を付けるために使われます。

引数
sel

作るセグメントのセレクタです。bit0-2が予約されていて, 0にしないといけません。例にならって0x200以降を使うべきでしょう。実際に実行/アクセスするときには7を足してセレクタとします (LDTかつリング3なので)。

ar

アクセス権限です。DLLとして実行するなら, 0x40fa か 0xc0fa を与えておけば間違いありません。前者ではセグメントリミットがバイト単位になりますが, 後者ではページ (4KB) 単位になります。

limit

は新しいセグメントの大きさ-1の値です。20bitの値であり, arのGビット (粒度ビット。0x8000) によって単位が異なります (G=0ならバイト単位, G=1なら4KB単位)。

bsel:ofs

新しくセグメントとなるメモリの, 現在のポインタです。 bselもbit0-2が予約されていて, 0にしないといけません。


0x00f4.なし


0x00f8.なし


0x00fc.なし


0x0100.なし


0x0104.なし


0x0108.0x80c0.グラフィックボックス線描複数 @test015.c

コマンド
dd 0x108,opt,gbox,x,y,width,height,num,offset,selector
guigui00.h
void lib_drawlines0(opt, gbox, x,y, width,height, num, offset);
機能

グラフィックボックスとそのバッファに線を引きます。長方形機能は予定されていません。

引数
opt

ビットごとに以下の機能を持ちます。

bit6,7 00 pset (他は遅くなる可能性がある)
01 and
10 or
11 xor
bit15 非同期 (グラフィックボックスバッファのみ書き込み)

他のビットは予約されています。0にしてください。

gbox

グラフィックボックスのオープンで指定したものと同じてす。

(x,y), (width,height)

描画範囲の左上の座標と幅と高さです。座標はグラフィックボックス内座標で, 単位はピクセルです。この描画範囲が全ての点を含まなければなりません。これがグラフィックボックスの表示範囲を越える場合は非同期を指定しなければなりません。

num

線の数です。0は許されません。

selector:offset

描画用線データのポインタです。座標は描画範囲の左上を原点として作ってください。内部形式です。一般的な形式から内部への変換には線データ変換を使います。


0x010c.0.線データ変換 @test015.c

コマンド
dd 0x10c,0,num,srcofs,srcsel,destofs,destsel
guigui00.h
void lib_convlines(0, num, srcofs, destofs);
機能

一般的な (と思われる) 形式の線データを複数線描が要求する内部形式 (点々形式) に変換します。

引数
num

線の数です。

srcsel:srcofs

元のデータのポインタです。

destsel:destofs

変換後のデータのポインタです。 srcsel:srcofsと同じにしてもかまいません。しかし, destofs = srcofs +4 とかいうのはマズイ上書きの例です。

変換元の形式 (変換後もデータの長さは同じ)

struc LINE
.x0	resd 1
.y0	resd 1
.x1	resd 1
.y1	resd 1
	resd 1
.color	resd 1
endstruc
struct LINE{
  int x0, y0, x1, y1, rsv, color;
};
color

描画色で, 0から15までの値です。


0x0110.0x80c0.線描複数

コマンド
dd 0x110,opt,window,x,y,width,height,num,offset,selector
guigui00.h
void lib_drawlines1(opt, window, x,y, width,height, num, offset);
機能

線を複数描画する低級コマンドです。再描画は自分でする必要があります。

引数
opt

描画属性を指定します。

bit6,7 00 pset
01 and
10 or
11 xor
bit15 やや安全モード。ウィンドウ描画禁止中は描画しない。

ほかのビットは予約されているので0にしてください。

window

ウィンドウオープンで指定したものと同じです。-1にすると画面全体になります。

(x,y), (width,height)

(x,)を左上として幅width, 高さheightの長方形が, 描画する全ての点を含まなければなりません。描画する線はこの(x,y)を原点とします。

num

線の数です。0は許されません。

selector:offset

線の構造体 (内部形式) へのポインタです。


0x0114.0.グラフィックボックス文字列描画

コマンド
dd 0x114, opt, x, y, gbox, col, bcol, fontset, STRING
機能

グラフィックボックスに文字列を描画します。フォントパターンの取得にも使えます。

引数
opt

ビット毎に意味がありますが, 未実装が多いようです。

bit0-7 0x00 高さ16ピクセルのモノクロフォントで,psetです。
bit8,9 01 詳細は不明。カラーモード1 (8bpp) と思われる。
bit10 0 予約 (col無効化らしい)
bit11 0 予約 (bcol無効化らしい)
bit12,13 00 ストリングは32bit base無し
01 ストリングは8bit base付き
02 ストリングは16bit base付き
test038のコメントでは11で32ビット形式が使えるとありますが未実装です。
bit14 1 ポインタ式のSTRING
bit15 0 グラフィックボックスおよびバッファに書き込む。
1 バッファのみに書き込み,グラフィックボックスには何もしない。
gbox

グラフィックボックスオープンで与えたものと同じです。8bpp専用です。

x,y

グラフィックボックスの中でのピクセル単位の座標値です。描画結果がグラフィックボックスをはみ出さない限り, (xが8の倍数であるなどの) 制限はありません (その分低速です)。

col,bcol

文字色と背景色です。

fontset

使用するフォントセットのスロットです。

STRING
文字列の長さとbaseとポインタです。
dd len,offset,selector
または
dd base,len,offset,selector
base無しとbase付きの場合で異なります。

バグ
OSASK v4.2 以前ではバグがあり, コンポーネントチェーンが破壊される場合があります。OSASK v4.3で修正されました。

0x0114.0xff.メモリ文字列描画

コマンド
dd 0x114, opt, offset,selector, (width<<8)|0xff, col, bcol, fontset, STRING
機能

上のコマンドとほぼ同じですが, グラフィックボックスとは関係ないバッファに書き込めます。

引数
opt

上とほぼ同じですが, 当然bit15は無効になるようです。

selector:offset

書き込むバッファのポインタです。

width

バッファの幅です。負の値も許されます。


0x0118.0.乱数取得 @test029.c

コマンド
dd 0x118,0, 0
guigui00.h
int lib_getrandseed();
機能

乱数を取得する。これを種として自分で乱数列を作るとよい。

第三パラメータはパラメータではなく, バッファです。ここに32ビット乱数が書き込まれます。


0x011c.なし


0x0120.0.モジュールサイズ変更 @resizer0.c

コマンド
dd 0x120,0, slot, size, 1, signal
guigui00.h
void lib_resizemodule(0, slot, size, sig);
機能

モジュールの大きさを変えます。対象のモジュールを事前にアンマッピングしておかなければなりません。

引数
slot

モジュールハンドルのスロットです。

size

変更後の大きさです。モジュールの最後の部分に追加・削除することによって大きさが変わります。

現状では, モジュールを大きくするとフロッピーのファイルがサルベージできます。読み込むのが遅いのでゼロクリアにした方がセキュリティとか速さの面でいいと思うんですが。

signal

完了シグナルです。これがそのまま返ってきたら成功で, 1から15を足したシグナルが返ってきたら失敗です。完了シグナルが来るまでこのコマンドを実行してはならない手抜きがあると思われます。


付録

APIの実行を追い掛けてみよう

アプリを作っていて, 「絶対OSASKのバグだ! 俺のせいじゃない!」と思ったら, ソースを読んでみましょう。

  1. まずユーザプログラムから far call されると, pioneer0.ask は初期化を始めます。ソフト割り込みを禁止し, スロット 0x01f0 を使ってワークエリアのポインタを読みこみます。最初のコマンドが初期化コマンドだと, 読み込みは初期化コマンドの中でされます。
  2. [ds:ebx] からコマンドを読みこみ, 適当に GUGUI統合 shell call をします。 0x0017:0x00000000 への far call は init.ask に繋がります (コールゲートというやつですかね)。
  3. init.ask の GUIGUI_shellcall に飛びこみます。ここでも [gs:ebp] からコマンドを読みながら実行していきます。
  4. tapi_sel への far call がよく出てきます。これは /* コマンドシグナル云々 */ と書いてあったらまず間違いなく winman0 へのシグナル送信です。そのコマンドの中に 0x7f000000 + N, hoge, rage, ... というくだりがあり, 0x7f000000 + N 以降の N 個のdwordが winman0 が実際に受けとるシグナルになります。一例として
    0x0128, 0x3240 /* winman0 */ + 6, 0x7f000005, 0x0048, EAX, [DS:0x000c], cmd[0], cmd[4]
    というのを取り上げると, 左から順に, tapiのコマンド, tapi用送信先+長さ, pioneer用送信先 (ユーザアプリ) +長さ, winman0 が受け取るシグナル……, と読みます。
  5. シグナルを送信したりしてコマンドが終わったらreturnします。以下マルチタスク。
  6. winman0 の中では, シグナルを受信するループでほとんどの処理がされます。しかし別なシグナルを待たないといけない処理はジョブとしてキューに入れられ, 後回しになります。
  7. pokon にシグナルを送りつけたり描画したりウィンドウを管理したり色々な処理がされます。

bim2bin4v以降での圧縮特例

bim2bin4vにオプションrjc:1を与えると, マシン語の圧縮率を上げるため, 相対ジャンプと以下の初期化シーケンスが認識・変換されます (曖昧さを排除するため, 厳密に指定しています)。

    MOV  ESP,CS:[byte EDX+0x20]
    PUSH byte 0x21
    JMP  short skip
    DD   'GUIGUI00'
    DD   mmarea, mmarea_size,0,0
    DD   stack_size, data_size, 0, section..data.start
skip:				
    PUSH byte -0xf
    PUSH byte 4
.cal:
    MOV  EBX,ESP
    CALL 0xc7:0
    ADD	 ESP, byte 12

ダンプは以下のようになります。

0000 : 2E 8B 62 20 6A 21 EB 28 47 55 49 47 55 49 30 30
0010 : 省略
0020 : 省略
0030 : 6A F1 6A 04 89 E3 9A 00 00 00 00 C7 00 83 C4 0C