これはOSASKのGUIGUI00仕様API, pioneer0ライブラリのコマンドを網羅的に扱う私製リファレンスです。自分でプログラムする際に参照しています。
主にアセンブラの使用者を対象にしていますが, guigui00.hのマクロ名, 関数名もそれなりに掲載しているので Cから呼び出す方も使えるかと思います。
基本的には, コマンドをメモリ上に羅列し, 先頭のポインタをDS:EBXに代入して, ライブラリを呼び出します。ぐいぐい00仕様では, DSの値を起動時にシステムがセットしてくれるので, ユーザはEBXに代入するだけです。コマンド列の終端はコマンド列終了コマンドで指示します。
guigui00.hを使う場合, lib_execcmd0
や lib_execcmd1
がこの処理を肩代りします。
以下のようにします。
mov ebx, work.lib_init
call 0xc7:0
説明不要かも知れませんが。
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の位置)。
アプリケーションが自由に使えるスロット番号は, 0x200から0x3f0までの16の倍数です。スロットの競合・共有は許されません。
セグメントセレクタを特に指定しない (させてもらえない) 場合はdsが使われる模様です。またライブラリは ds=ss=fs を仮定しているため, コードセグメントにコマンドを置くことは許されません。
セグメントセレクタは16ビットですが, 32ビットデータとして書くときは上位16ビットを0で埋めなければなりません。
ボックス
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).
最近はtestシリーズのドキュメントを読みつつ, pioneer0のソースを読んでこっそり変更されているところを探すという感じです。
不明瞭なところには「未詳」などと書いておきました。
なお同封の introlst.txt にintroシリーズの順序および概要とpack, testシリーズの概要を書いてあります。不明の点は自分でサンプルを読んでみてください (もちろん, 改善案は歓迎します)。コマンドごとの解説では説明しにくい全体の概念もあると思います。
ダブルワードにアラインしておくべきです (ポインタを4の倍数にしておく。速くなる)。さもないと, APIが下位の2bitsをフラグとして使うことが多いので誤作動の原因になります。
dd 0
ライブラリはこのコマンドを実行すると, ユーザプログラムへ復帰します。その際, ebxとeflagsは保存されません。ebxは終了コマンドを指します。ほかのレジスタは保存されます。
例外として, 特別コマンドを使った場合はediがその影響を受けます。
昔のバージョンでは, シグナル待ちコマンド実行中にシグナルハンドラに分岐して, そこから戻ってコマンド終了となる場合はebxも保存されましたが, 今では修正されているそうです。
dd 4, work
ライブラリを初期化し, その時の時刻をシステムタイマの時間基点に設定し, シグナルハンドラマスク値を-1にします。ライブラリの他のコマンド (コマンド列終了を含む) を利用する前にこのコマンドを実行しなければなりません。
workは256バイトの空き領域を指すセグメントオフセットです。4 の倍数でなければなりません。ここが4の倍数でない場合, それは特別コマンドだと見なされます。
dd -1
特別コマンドを終了させ, ユーザプログラムに復帰します。
初期化コマンドには特別モードがあり, ライブラリ初期化コマンドのシグネチャ dd 4 に続けて独自のコマンド列を埋め込むようになっています。初期化はされません。
ライブラリ初期化前に使用でき, その時は最後に特別終了を付けてコマンド終了の代わりとします。ライブラリ初期化の後は特別終了を使ってはいけません。特別終了ではebxの値が保証されません (保存するとは保証されない)。
コマンド列が特別コマンドで始まる場合, 後に繋げられるコマンドはライブラリ初期化だけです。
tek5データを伸長します。その後, ediは次の展開先を指します。
tek2データを伸長します。その後, ediは次の展開先を指します。
tek1データを伸長します。その後, ediは次の展開先を指します。
tek0データを伸長します。その後, ediは次の展開先を指します。
l2d3データを伸長します。その後, ediは次の展開先を指します。
コードセグメントに配置されているデータ (セクション) を, データセグメントにマッピングします。
現在の実装は不明ですが, (4KBアラインされていない場合は最初にコピーを作って,) プロセス間で共有されるコピーオンライトなマッピングにするのではないかと。普通ですねえ。
0 | 次のサブコマンドに移ります。 |
1 | ファンクション4 (ライブラリ初期化)
を受け取ったことにして, stack_end へジャンプします
(DS:stack_end には, ライブラリ初期化の引数 dd work
を置く)。 |
2, 3 | 予約でしょう |
0 <= ESP && ESP <
stack_end
である場合, ESP未満のオフセットにあるメモリの内容は保証されません。メモリ確保のため,
破棄される可能性があります。
ライブラリを終了します。現在はアプリもろともに終了します。
すぐには終了しないため, このコマンドを実行した後もシグナルを受信する処理が必要です。
ライブラリのコマンドポインタに値を加えます。
dd 0xc,0,0
というコマンドは無限ループになります。ライブラリのコマンドポインタに値を代入します。
シグナルハンドラを定義します。
シグナルが溜まると, ユーザプログラムの中でやっていることを中断してハンドラに分岐します。分岐時のスタックは以下のとおりです。セグメントレジスタの上位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 |
ここで積まれる値はハンドラから復帰する時の値 (ほぼそのまま分岐前の値) です。ハンドラに進入したときのレジスタの値はスタックにつまれている値とは等しくありません。分岐直前の値を参照したい場合は, スタックから読み込んでください。
ユーザプログラムがシグナルハンドラを定義して, かつシグナル待ちをしているときは, シグナルハンドラから復帰すると同時に待ちコマンドが終わります。
シェル推奨 (実際はユーザ指定可能にするらしい) のウィンドウ最大サイズを取得します。別に無視しても構いませんが, 従ったほうがユーザフレンドリです。
dd x_max, y_max
という形で書き込まれます。シグナルや時間基点を待ちます。シグナルが来ない状況では, 時間待ち・永眠コマンドとして使われます。
bit3 | 0 | 設定済みの時間基点をそのまま使う。 |
1 | 現在の時刻を時間起点にする。 | |
bit2 | 0 | timeフィールドはない。 |
1 | timeフィールドが存在し, 時間基点にこれを加算する。 | |
bit1-0 | 0 | 待たない。 |
1 | シグナルが来るまで待つ。 | |
2 | この値は許されない。 | |
3 | シグナルか時間基点が来るまで待つ。 |
最初にライブラリが初期化されたとき, システム内部の「ハンドラマスク値」は-1に初期化されます。これが0の時にのみ, ハンドラへの分岐が起きます。したがって, 「シグナルハンドラ定義コマンド」でハンドラを定義した後, nestを1にした「シグナル待機コマンド」を実行しないとハンドラへの分岐はおきません。また, ハンドラを定義しないうちにハンドラマスク値を0にすると, シグナルが来たら暴走してしまいます。
ハンドラへ進入する際にハンドラマスク値は-1にされます。ハンドラ内でハンドラマスク値をいじらない限り, ハンドラへの再入はありません。
ビットではないので, nest = -1のコールを3回やったらnest = 1のコールも3回やらないと元には戻りません (nest = 3を1回でもいいが)。
初期のガイドでは, シグナルを定義せずに永眠コマンドとして使うときはnest = 1 にするように指示されていましたが, 今の推奨値は0です。初期のガイドの範囲でのライブラリを使用する場合においては, ライブラリのバージョンに関わりなく, 0でも1でも支障はありません。
t0 =
0x80000000; t1= 1; t2= 0;
です。 100ミリ秒なら, t0= 0x1999999a; t1= 0;
t1= 0;
です。シグナルハンドラから復帰します。
復帰時の値はスタックから読まれます。スタック上にふさわしいレジスタイメージがあれば, ハンドラの中でなくとも使ってかまいません。
シグナルがシグナルボックス中に残っていたら, ハンドラマスク値は再び-1になり, スタックはそのままでハンドラに再度分岐します。
ハンドラマスク値を分岐前の0に戻すため, 普通は nest = 1
にしてください。自動では戻りません。
Cではライブラリ関数にラッピングされているため, 単純にreturnしてください。
なにもしません。単に飛ばされます。
ウィンドウを開きます。
ウィンドウはスロットのある限り幾つでも開けます。ウィンドウが一つでも閉じられるとプロセスも終了するのがデフォルトなので, それは困るなら拡張ウィンドウオープンを使います。
ウィンドウを開き, 描画を自分で制御したり状態を取得するためにシグナルを要求します。ウィンドウの状態はAPIも把握しているので, 拡張オープンしたウィンドウにも便利なグラフィックボックスなどは使えます。
実際のシグナルの値は, 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 | アクティブ色 |
シグナルに対する応答方法は以下の表の通りです。具体的な処理はウィンドウ制御を参照してください。
シグナル名 | 通知義務 | 備考 | |
ウィンドウ描画許可 | なし | 必ず再描画シグナルも来る | |
ウィンドウ描画禁止 | 受信完了 | ||
ウィンドウ全体の再描画 | 描画完了 | 描画禁止でも無視して描画 | |
ウィンドウ全体の再描画(差分) | 描画完了 | とりあえず再描画と同じ | |
ウィンドウ位置変更 | なし | ||
タイトルバーカラー変更 | なし | 再描画も来ると思われる | |
ウィンドウクローズ要求 | なし | ウィンドウを閉じましょう | |
クローズ完了 | なし | 以降スロットの再利用可 |
ウィンドウを閉じます。
ウィンドウはすぐ閉じるわけではないため, スロットを再利用するには拡張ウィンドウオープンを使って, 完了シグナルをもらう必要があります。
ウィンドウにテキストを表示するためのテキストボックスを貼り付けます。
各ビットに意味があります。
bit 0 | 0 | デフォルト背景色はシステム指定の色。backcolorは0。 |
1 | デフォルト背景色はbackcolor。 | |
bit 4 | 0 | 高さ16ピクセルのフォントセットを使う。 |
1 | 高さ8ピクセルのフォントセットを使う。 | |
bit12 | 0 | 普通のテキストボックス。 |
1 | タイトル用テキストボックス。ウィンドウごとに一つ必要。ウィンドウタイトルのテキストボックスはopt=0x1000でなければなりません。 |
大きさ 64 + width *height *8 バイトのバッファのセグメントオフセットです。
0から15の背景色です。
テキストボックスの大きさです。単位は8x16もしくは8x8ピクセルの半角キャラクタです。ここの指定に応じて, textboxが指し示すバッファの大きさも変化します。ウィンドウタイトルのwidthの最大値は (ウィンドウの幅/8 -10) です。heightは1です。
ウィンドウ内でのテキストボックス左上の座標でピクセル単位です。テキストボックスはウィンドウからはみ出してはいけません。今はxは8の倍数でないといけません。
ウィンドウオープンコマンドで指定したwindowの値です。
テキストボックスで使用するフォントセットのスロット番号を入れます。システムスロット0xc0には高さ16ピクセルのasciiフォントセットが入っています。ウィンドウタイトルにはこの0xc0を使わなければなりません。
テキストボックスとバッファを埋める初期値を入れます。asciiでは空白か0x00を入れてください。
ウィンドウに複数のテキストボックスを貼り付けるとき, テキストボックス及び枠が重なってはいけません。枠の幅は3ピクセルです。
テキストボックスをクローズするようです。
ウィンドウに画像を表示するグラフィックボックスをウィンドウに貼り付け, fillerの値で初期化します。
グラフィックボックスのバッファにデータを書き込み, フラッシュするとバッファの内容が画面に反映されます。フラッシュは要求した時の他にシステムの都合によって自動的に実行されます。
グラフィックボックスのデータは下位のバイトが左のピクセルに対応します。フォントに使うパターンとは逆です。
各ビットに意味があります。
bit0-11 | 0x001 | 予約(?) |
bit12 | 0 | バッファをfillerで埋める |
1 | 埋めない | |
bit13,14 | 0 | |
bit15 | 0 | オープン直後フラッシュする |
1 | しなくてもいい (するかも知れない) | |
bit16-31 | 0 | 予約 |
しなくてもいいがするかも知れないというのはつまり, このコマンドを実行する前にバッファの初期化をしておかないといけないということです。
64+width*height バイトのバッファのセグメントオフセットです。gbox+64以降の部分はグラフィックバッファなので自由に読み書きしてかまいません。4バイトアラインしておかないと, 一部のコマンドで問題になります。
グラフィックボックスとバッファを初期化する色です。バッファはバイト単位で構成されますが, 色は0から15の値でなければなりません。
グラフィックボックスの幅と高さです。ウィンドウをはみ出してはいけません。
グラフィックボックス左上のウィンドウ上での座標です。
ウィンドウオープン時に指定した値と同じです。
上とほぼ同じです。あれは4bppでしたがこちらは16, 32bppになります。このグラフィックボックスは線描やらの機能が (まだ) なく, フラッシュしかできません。
色深度と減色設定です。
bit0-2 | 色深度です。2で16bpp, 4で32bpp(実質24bpp) になります。 |
bit5 | 速度重視ビットです。これを1にすると, 減色 (test043では自動中間色表現と書かれている) する際に品質を落としてもいいから早くしてほしいという意味になります。 |
グラフィックバッファのビット配置は以下の通りです。
16bpp: | dw R<<11 | G<<5 | B |
32bpp: | db B, G, R, 0 |
バッファの一部が表示されるグラフィックボックスをウィンドウに貼りつけ, スクロール位置を(0,0)に初期化します。
各ビットに意味があります。
bit0-11 | 0x002 | |
bit12 | 0 | バッファをfillerで埋める |
1 | 埋めない | |
bit13,14 | 0 | |
bit15 | 0 | オープン直後フラッシュする |
1 | しなくてもいい (絶対しないわけではない) | |
bit16-31 | 0 | 予約 |
絶対フラッシュしないわけではないというのはつまり, このコマンドを実行する前にバッファの初期化をしておかないといけないということです。
ピクセル単位のバッファの大きさです。bwidth >= width かつ bheight >= height でなければなりません。
ピクセル単位の表示する大きさです。はみ出す分はスクロールさせると表示できます。
そのほかはスクロールなしと同じです。
グラフィックボックスをウィンドウに貼りつけます。
何に使うんだろう。ウィンドウをいったんクローズして, もう一度同じのをオープンした時に復元するためなんだろうか。でもテキストボックスにはこういう機能はないなあ。
OSASK V2.8からV4.0ではライブラリがハングアップします。
拡張オープンしたウィンドウを自前で制御するためのコマンドです。拡張オープンでないものはpioneerライブラリが同じように制御しています。
ビットごとに意味があり, 複数のビットを同時に1にできます。下位から順に解釈されます。
bit0 | ウィンドウの枠を描画しウィンドウを塗りつぶす。付加したコンポーネント (テキストボックスなど) は描画されない。タイトルは描画される。 |
bit1 | コンポーネントを描画。 |
bit2 | ウィンドウ塗りつぶしを抑制するオプション。 |
bit3 | コンポーネントの描画を差分描画にするオプション。このビットを1にすると, ウィンドウ塗りつぶしも抑制される。 |
bit8 | 描画禁止シグナルの受理をシステムに通知。 |
bit9 | 再描画完了をシステムに通知。 |
ウィンドウに指定した物と同じです。
テキストボックスとそのバッファに文字を書き込みます。
表示結果がテキストボックスをはみ出してはいけません。自動折り返しはしませんし, 改行コードは使えません。複数行に書き込むには, このコマンドを行数分だけ実行することになります。
各ビットに意味があります。
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はポインタフィールドを持つ。 |
半角キャラクタ単位でのテキストボックス内の位置です。指定された位置から文字は右へと表示されます。
テキストボックスオープンで指定したものと同じです。
文字色です。
背景色です。
ベース値フィールド (オプショナル), 文字列長フィールド, 文字列またはそのポインタフィールドからなります。それぞれのフィールドがあるなしはoptによります。書き方は以下のいずれかになりますが, guigui00.hでは base, offset の形式しか使えません。
baseは半角コードのベース値です。8/16ビット符号無し整数の c0,c1,c2,... にこの値を足した物が実際の半角コードになります。optによってはこのフィールドはありません。
lengthは表示する半角数です。実装では0=0x100000000とみなされます。
selector:offsetは表示する半角コード列のポインタです。optによってはこのフィールドはありません。
c0,c1,c2,...は半角コード列です。コマンドの長さは4バイトの倍数でなければならないので, 空きがあるときは0で埋めておいてください。
線・長方形を描く低レベルコマンドです。再描画を自分で指示してください。
ビットごとに以下の意味を持ちます。
bit4,5 | 00 | 線 |
01 | 長方形 | |
10 | 矩形塗りつぶし | |
bit6,7 | 00 | pset |
01 | and | |
10 | or | |
11 | xor |
他のビットは予約されています。0にしてください。
ウィンドウオープンで指定した物と同じです。-1を指定すると画面全体になりますが, そんなことをしてはいけません。
色です。0から15の値を指定します。
始点と終点のウィンドウ上での座標です。 x0 <= x1 && y0 <= y1 でないといけないようです。
文字を描画する低レベルコマンドです。再描画は自分で指示してください。
描画する文字列の左上の点のウィンドウ内での座標です。現在, 描画ルーチンの不備のためにxは8の倍数である必要があります。
32bit半角コードです。他の形式は使えません。
そのほかoptなどのパラメータは文字表示コマンド背景色付きと同じです。
画像を描画する低級コマンドです。再描画を自分で指示してください。
画像の色深度です。1,2,4がそれぞれ8bpp(実質は4bpp),16bpp,32bpp(実質は24bpp)に対応します。16bppと32bppでは, 代わりに 0x22, 0x24 を使うと高速モードになります (減色品質を落してでも速く処理されます。なお現在の実装では1割程度速くなりますが, 品質は段違いに悪くなるように見うけられます)。8bppに高速モードはありません。
ウィンドウオープンで指定したものと同じです。描画範囲がウィンドウをはみだしてはいけません。-1を指定すると画面全体になります。
描画する画像の左上の点のウィンドウ上での座標です。
その長方形の幅と高さです。0にしてはいけません。
ラインごとにスキップするバイト数です。普通は(データの幅)-(描画幅) の値をバイト単位で代入します。-(データの幅)-(描画幅) の値を代入してデータをさかさまに読ませるなどの仕掛けもできます。
画像データの転送開始位置のポインタです。ここを左上の頂点としてデータが読み込まれます。
画像を描画する低級コマンドです。ウィンドウ描画禁止中は描画しないのでグラフィックボックスのフラッシュに使われました。パラメータの意味は上と同じです。
専用のコマンドグラフィックボックスフラッシュが用意されたので, できればそっちを使うべきでしょう。このコマンドを使うと, そのウィンドウの全てのグラフィックボックスが"差分描画の必要あり"とされてしまいます。
一部のベータ版OSASKの暫定仕様のみ0x80000001を使いましたが, 今は使ってはいけません。
描画属性を指定します。
bit6,7 | 00 | pset |
01 | and | |
10 | or | |
11 | xor | |
bit15 | やや安全モード。ウィンドウ描画禁止中は描画しない。 |
ほかのビットは予約されているので0にしてください。
ウィンドウオープンで指定したものと同じです。-1にすると画面全体になります。
ここを左上として幅がwidth, 高さがheightの長方形が描画する全ての点を含まなければなりません。描画する点はこの(x,y)を原点とする座標を使います。
点の個数です。0は許されません。
点の構造体のポインタです。
struc point .x resd 1 .y resd 1 .color resd 1 endstruc
グラフィックボックスとそのバッファの両方に線を描画します。
長方形機能はまだありませんが予定されています。水平線や垂直線を書く場合は長方形塗りつぶしを使う方が速いはずです。
ビットごとに意味があります。
bit6,7 | 00 | pset (他は遅くなる可能性がある) |
01 | and | |
10 | or | |
11 | xor | |
bit15 | 非同期 (画面に描画しない) |
ほかのビットは予約されているので0にしてください。描画範囲がグラフィックボックスの表示範囲を越える場合は非同期ビットを指定しなければなりません。
グラフィックボックスオープンで指定したものと同じです。
線の色です。多分0から15でないといけません。
線の両端の座標です。bwidth*bheight の平面上の座標であり, この中に収まらなければなりません。なお bwidth, bheight とも65536未満でなければなりません。
グラフィックボックスの表示位置を変更 (スクロール) 及びフラッシュします。
グラフィックボックスオープンで指定したものと同じです。
表示する時に左上の原点となるデータのセグメントオフセットです。フラッシュするときに指定するものと同じです。普通はグラフィックボックスオープンで使ったbwidthを使って bufofs = gbox +64 +bwidth *vy +vx と計算されます。
左上の原点として表示される点のデータ内での座標です。
bwidth * bheight のデータの中から, (vx, vy)を原点として width * height の領域が新たな表示領域となります。
グラフィックボックス内の表示位置変更 (スクロール) をし, バッファ内で使用前使用後の差分を計算して差分フラッシュします。現在の表示内容とそこに対応する画像データが一致していなければ正しく差分ができません (多分。しかしそれを逆に利用することもできるはず)。
前半のパラメータは上と同じです。
差分を作るためのバッファのセグメントオフセットです。((width +tmpskip) * height)バイトの大きさが必要です。
一時バッファのラインスキップの長さです。とりあえず0にしておけば問題ありませんが, width + tmpskip が4の倍数になるように設定すると高速化が期待できます。
差分転送に使われる透明色です。4bitモードなので, 16のままで問題ありません。
グラフィックボックスの一部の領域をフラッシュします。8, 16, 32bppに対応しています。スクロールには対応していません。
画像の色深度と描画モードです。1,2,4がそれぞれ8bpp (実質は4bpp), 16bpp,32bpp (実質は24bpp) に対応します。16bppと32bppでは, 代わりに 0x22, 0x24 を使うと高速モードになります (減色品質を落してでも速く処理されます。なお現在の実装では1割程度速くなりますが, 品質は段違いに悪くなるように見うけられます)。8bppに高速モードはありません。
グラフィックボックスオープン時に指定したバッファです。
描画する画像の左上の点のグラフィックボックス上での座標です。
その長方形の幅と高さです。0にしてはいけません。
グラフィックボックスとそのバッファに点を打ちます。
各ビットに意味があります。線描と同じですが。
bit6,7 | 00 | pset |
01 | and | |
10 | or | |
11 | xor | |
bit15 | 非同期 (画面に描画しない) |
ほかのビットは予約されているので0にしてください。描画範囲がグラフィックボックスの表示範囲を越える場合は非同期ビットを指定しなければなりません。
グラフィックボックスオープンで指定したものと同じです。
描画範囲の左上の座標と幅と高さです。座標はグラフィックボックス内座標で, 単位はピクセルです。この描画範囲が全ての点を含まなければなりません。
点の数です。実装では0=0x100000000として扱われます。
描画用点データのポインタです。点の座標は描画範囲の左上を原点として作ってください。内部形式です。
シグナルを受信するシグナルボックスを定義します。
バイト単位でのシグナルボックスの大きさです。下位二ビットは予約されており, 0でなければなりません。最低でも16はないと処理できないと思われます。効率を考えると256以上は必要でしょう。
シグナルボックスのセグメントオフセットです。下位二ビットは予約されており, 0でなければなりません。
シグナル終了番号であり, 0です (0じゃなくてもいいみたいだけど)。シグナル列の終端にはこの値が書き込まれます。この値はシグナルではありません。
巻き戻しシグナルのシグナル番号です。このシグナルは長さフィールドが後続し, 8バイトになります。しかし受信量としては長さフィールドに指定された長さを通知してください。
キー入力などのイベントとアプリが受け取るシグナルとの対応を定義します。将来は先取りされてコマンド実行前からシグナルが定義されていることになるようです。したがって, 定義前からシグナルが来る可能性を考えてプログラムしてください。
タイマーイベントが起きたときのシグナルを定義します。このシグナルはウィンドウではなくタスクに送られます。
タイマーのスロット番号です。
要求するシグナルです。
キーボードからの文字入力に対してシグナルを定義します。
定義するシグナル数-1 です。numが1以上の時, signalおよびletterは1づつ増える連続した値が割り当てられます。4096以上は指定できません。
シグナルを定義する文字です。指定可能な値は, 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 ↓ |
さらに, 文字の特定のビットを立てると拡張定義になります。拡張定義では同じ文字でもキーの左右が区別されたりします。英字は大文字を使いますが, 記号は同じキーに書いてあるののどちらでもかまいません。
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 |
定義したいシグナル (群) の先頭の値を入れます。
ウインドウオープンで指定したものと同じです。そのウィンドウがアクティブのときのみ, 指定されたイベントに応じたシグナルが発生します。
マウスの低レベルな (GUIボタンとかではない) シグナルを定義します。
呼び出し順序が重要で, 座標とボタンのシグナルを定義する場合, 必ず座標シグナルを先に定義しなければなりません。そうしないと, 多分シグナルの順番が狂うのでしょう。
signalの前の1はシグナルの長さだろう。マウス座標のシグナルにはこれを3にするんじゃないのか? と思う人もいるかもしれませんが, そこは常に1です。
シグナルの種類です。
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の順で, それぞれウィンドウの左上を原点とします。ウィンドウ内というのは枠の上を含みますから, ウィンドウ内と指定しても負の座標値が来る可能性があります。
座標シグナルは, ボタンプレス/リリース位置が分かる程度に送られて来ます。座標シグナルにボタンシグナルが続くことを前提にしてはいけません。また, 感度を必要以上に高くするのは無駄ですから避けてください。
シェルとの約束として, シグナルの通知が一通り済んだらこのダミーコマンドを実行します。
シグナルを自分に送ります。疑似マルチスレッドライブラリで使われています。
送るシグナルの数です。
シグナルの列です。
シグナル列のポインタです。
どちらも長いシグナルとして扱われ, 途中にrewindが挟まることはありません。
タイマーをユーザーで設定できるようにします。このコマンドを実行しないとタイマー設定はできません。
標準タイマーを指定した場合, 時間基点に関する設定はそのまま引き継がれます。オープン直後のタイマーは停止しています。
オープンしていたタイマーをシステムに返しスロットを開放します。
クローズ後は, そのタイマーに対する設定はできません。また, 再度オープンすることもできますが, 古い設定は保存されません。
タイマーをクローズする前にタイマーを停止しておいてください。
タイマーとして使っていたスロットの番号です。三つのうちの最初の一つを指定します。
タイマーを止めます。
下のタイマー設定と同じコマンドですが, bit0とbit1が排他的なため敢えて分けています。
タイマーは停止状態にあるときは指定した時刻になってもシグナルを発しません。また各種の設定のためには停止状態にする必要があります。
タイマーを止めてもタイマーの時間基点はそのままです。従って,
今から十秒後にタイマーシグナル設定
という操作をすると(3)から十三秒以内にタイマーシグナルが来ることになります。私はハマりました。
タイマー設定を行ないます。タイマーは時間基点を過ぎるとタイマーシグナルを発します (時間基点が過去の場合, すぐにシグナルを発するようです)。タイマーが活動中のときは設定できません。タイマーを止めてからにしてください。
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 | タイマーを始動しません。 |
タイマー間の設定を行ないます。
slot1のタイマーの時間基点が (slot0の時間基点)+(t2:t1:t0) になります。時間の形式について詳しくはシグナル待機コマンドを見てください。
(slot1の時間基点)-(slot0の時間基点) の値を取得します。
最後の12バイトはパラメータではなくバッファです。ここに
dd t0,t1,t2
といういつもの形式で差が書き込まれます。形式について詳しくはシグナル待機コマンドを見てください。
伸長コマンドのヘッダです。後にサブコマンドを続けて書くようになっています。
サブコマンドの終端です。何もしないでユーザプログラムに復帰させる場合は
dd 0x7c /* 伸長コマンド開始 */
dd 0x00 /* サブコマンド終了 */
dd 0x00 /* コマンド終了
*/
となります。tek0データを展開したい場合は
dd 0x7c /* 伸長コマンド開始 */
dd -7, dofs /* 書き込み先を指定 */
dd -0x7e,
len, ofs, sel /* 展開サブコマンド */
dd 0x00 /* サブコマンド終了 */
dd 0x00 /* コマンド終了
*/
となります。
伸長サブコマンドはEDIの値を変えますが, 終了サブコマンドによって, 呼び出し時の値に戻されます。
書き込み先のセグメントオフセットを指定します (セレクタはES固定です)。デフォルトはAPIコール時のEDIです。
読み込み開始位置 + 圧縮データの大きさ を明示します。
selector:offset
にあるl2d3データを伸長し, lengthバイト書き込みます。終了後,
伸長データの終端が次の書き込み先になります。
selector:offset
にあるtek5データを伸長し, lengthバイト書き込みます。終了後,
伸長データの終端が次の書き込み先になります。
selector:offset
にあるtek2データを伸長し, lengthバイト書き込みます。終了後,
伸長データの終端が次の書き込み先になります。
selector:offset
にあるtek1データを伸長し, lengthバイト書き込みます。終了後,
伸長データの終端が次の書き込み先になります。
selector:offset
にあるtek0データを伸長し, lengthバイト書き込みます。終了後,
伸長データの終端が次の書き込み先になります。
サウンドトラックを割り当てるスロット番号です。サウンドトラックはスロットを一つ使います。
サウンドトラックを閉じ, スロットを開放します。
サウンドトラックのスロット番号です。
ブザーを制御します。
サウンドトラックのスロット番号です。周期が cycle/0x100000000 の音が出ます。 cycleを0にすると消音されます。周期は周波数の逆数です。
専用度 | 用途 | 備考 | |
4 | タスク固有 | 一時データ, スタック | 非公式 |
8 | ユーザ固有 | 設定や個人的記録の保存 | |
12 | マシン固有 | インストール, ユーザ共通データ | |
16 | ネット固有 | アクセスカウンタ (?) | まだ無い |
スロット番号です。スロットを一つ使います。
スロットをモジュールハンドルとして初期化し, どこに移動させるかはシェルに任せます。大抵の場合, シェルは人間の指示を仰ぎます。アプリ専用ではないファイルにアクセスするにはこのコマンドでシェルに (人間に) お伺いを立てなければなりません。
複数の外部モジュールにアクセスしたければ, それらのモジュールを収めたディレクトリを渡すよう説明書で指示することになります。
サブコマンドのポインタです。
このコマンドは手抜きにより完了するまで再実行できません。
番号です。コマンドラインからの操作等を可能にするため, ファイルごとに別々の番号を振ってください。
完了通知用シグナルの番号です。これがそのまま返ってきたら成功で, これに1から15を足したシグナルが返ってきたら失敗です。失敗したスロットは最挑戦するか諦めるかしてください。
スロットsrcslotのモジュールハンドルをスロットdestslotに複写します。一つのモジュールの複数の部分を別々にマッピングしたい場合はこのコマンドを使えということのようです。
適当なサンプルがありませんし, たぶん機能そのものがまだありません (あるのか?)。
モジュールハンドルを指定のファイルまたはディレクトリに移動させます。この操作の前にハンドルがディレクトリに移動していなければなりません。そのディレクトリの中を検索します。
使用回数に制限がありましたがdanielでは解消されたそうです。
ビット1が強制ビットで, これを1にしておくとモジュールが存在しない場合新しく作られます。
モジュールハンドルとして初期化したスロットです。
サブコマンドのポインタです。
ファイルまたはディレクトリの名前です。隙間を0x20の空白で埋め,
`.'も書いてascii大文字12文字でなければなりません。
例:"MYSRC01 .CC " 日本語や韓国語は使えません
(未詳。test016.c>必ず大文字で, 12文字)。
完了通知用シグナルの番号です。これがそのまま返ってきたら成功で, これに1から15を足したシグナルが返ってきたら失敗です。
適当なサンプルがありません。そもそも使えるのか不明。
多分モジュールを作るのでしょうが, どんなタグが必要か, すでにモジュールがある場合はどうなるのか, などは不明です。 ……タグを書き換えるコマンドはまだ無いのかなぁ。
モジュールの一部をメモリ空間のモジュールマッピング領域にマッピングします。
モジュールハンドルのスロットです。一つのハンドルで複数箇所にマッピングしてはいけません。
マッピングする最大の長さです。0は許されません (あるいは0x100000000と同義でしょう)。4096の倍数です。長い場合はこの長さでマッピングを打ち切ります。モジュールが短い場合はそれに合わせて短くマッピングされます。マッピングされていないところにアクセスしてはいけません。
マッピングするメモリ領域のポインタです。マッピングする領域が重なってはいけません。
モジュール内のマッピング開始位置です。4096の倍数です。
モジュールのマッピング属性です。属性を変えるにはマッピングし直します。
5 | 書き込み不能 |
7 | 書き込み可能 |
マッピングを解除し, 再マッピングやリサイズできるようにします。
解除する領域の先頭ポインタです。
解除する範囲の長さです。
適当なサンプルがありません。
モジュールハンドルとして初期化したスロットでしょう。
8バイトのバッファのポインタでしょう。
モジュールの大きさを取得します。
モジュールハンドルとして初期化したスロットです。
バッファのポインタです。16バイト使います。実際には先頭4バイトがモジュールの大きさで, 12バイトほど残ってますけど, OSASKではファイルサイズを128bitまで取るようです。一応。
適当なサンプルがありません。
モジュールの名前が取得できるらしい。だまされることもあるのだろう。
ユーザ定義フォントをスロットに割り当てます。
フォントというのは字形 (gryph) の集合です (個々の字形はフォントの一部であってフォントそのものではない。等幅フォント可変幅フォントという言葉の意味を考えれば当然でしょう)。
OSASKにおいては, フォントを定義するのにスロットを一つ, フォントの一部をフォントセットにマッピングするのにまた一つ使います。
フォントを割り当てるスロットです。
割り当てる半角フォントの数です。
実際のパターンのポインタです。半角一つにつき8x16=16バイトのパターンが要ります。ビット配列は 0x43 が □■□□□□■■ と画面に映るようになっています。上位ビットが左になり, カラーフォントやグラフィックボックスとは逆です。
コマンド終了後はその領域をどうしようと構いません。
高さが半分, すなわち8x8のフォントを定義します。一つのパターンが8x8=8バイトで構成されるほかは上と同じです。
高さが半分, すなわち8x8のカラーフォントを定義します。一つのパターンは8x8 x16色=32バイトで構成されます。その他は上と同じです。
パターンは上位のバイトが右の方のピクセルになります。一バイトのうちでは, 下位ニブルが左のピクセルで, 上位ニブルが右のピクセルです。
slotにシステム定義のANKフォントを割り当てます。現在, IBMターミナルフォントに似たフォントが入っており, ANKのK (カナ) は影も形もありません。
slotにシステム定義の半高ANKフォントを割り当てます。
これは高さが半分の縮小フォントではありません。各字形が上下に半分づつ定義されており, 例えば, 0x64は'2'の上半分で0x65は'2'の下半分です ('2'のasciiコードは0x32です)。全角字形を半角二つで作るのと同じノリです。
廃止されました。init.ask@OSASK V2.1,V2.2にて死亡確認。
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に付属していた日本語フォントは一部に誤りがあります。
適当なサンプルがありません。
フォントを割り当てたslotを開放? そのフォントを使ったフォントセットは多分使えなくなるのでしょう。
フォントが持つ字形を32ビットの半角コード空間にマッピングし, フォントセットとして実際に使える状態にします。
雰囲気としては, フォント=モジュール, フォントセット定義=マッピング, というところでしょうか。
フォントセットとなるスロットです。一度割り当てるごとにスロットを一つ使います。
例外として, OSASK自動拡張フォントを割り当てると勝手にスロットを四つ使います。またOSASK自動拡張フォントを使うときは, num,src,dest に 0x1000000,0,0 が指定されたものとみなされます。観念してその指定をしなければなりません。
フォントスロットです。高さの違うフォントを混ぜてはいけません。カラーと二色のフォントは混在可能です。
マッピングする字形の数です。
貼りつける字形のフォント内の先頭番号です。
半角コードの先頭番号です。
フォントセットの終端を定義します。これを定義するとフォントセットが確定します。
slotにはフォントセットとして使う最後のスロットの次のスロットを指定します。
シフトJISで書かれた文字列をOSASK自動拡張フォント向けにデコードします。
変換結果の長さで, 単位はダブルワードです。
シフトJISの文字列のポインタです。
変換結果を入れるバッファのポインタです。 dlen+1ダブルワード程度まで確保しておく必要があります。
JIS X 0201 及びJIS X 0213-1 +NEC+MS のフォントの位置です。と言っても, 一バイト文字の初めの文字は0x00で, 終わりの文字は0xffです。互換のフォントを自作するなどの場合, 開始位置に注意してください。
シングルシフトを使わない (日本語で言えば, いわゆる半角カナや JIS補助漢字あるいは2000JIS第二面を使わない) EUC文字列を, OSASK自動拡張フォント向けにデコードします。
C0:0x20:G0:0x7f:C1:0xa0 (要するに0x00から0xa0) の範囲の一バイト文字用半角フォントの位置です。0x9700がasciiのフォントで, 0x4e00が JIS X 0201 のフォントです。SJISと同じく, 94文字集合ではなく一バイト集合として扱われます。
G1の94^2文字集合のフォント位置です。0x400が JIS X 0213-1 で, 0x5000が KS C 5601-1987 (KS X 1001) です。
シングルシフトもデコードできるEUCデコーダです。
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の空白がどうなるかは忘れました。
それぞれG0からG4のフォントの位置です。
適当な解説がありません。ソースを斜めに読んで推測しますが, LDTにエントリを追加するだけです。マッピングしたDLLに実行可能属性を付けるために使われます。
作るセグメントのセレクタです。bit0-2が予約されていて, 0にしないといけません。例にならって0x200以降を使うべきでしょう。実際に実行/アクセスするときには7を足してセレクタとします (LDTかつリング3なので)。
アクセス権限です。DLLとして実行するなら, 0x40fa か 0xc0fa を与えておけば間違いありません。前者ではセグメントリミットがバイト単位になりますが, 後者ではページ (4KB) 単位になります。
は新しいセグメントの大きさ-1の値です。20bitの値であり, arのGビット (粒度ビット。0x8000) によって単位が異なります (G=0ならバイト単位, G=1なら4KB単位)。
新しくセグメントとなるメモリの, 現在のポインタです。 bselもbit0-2が予約されていて, 0にしないといけません。
グラフィックボックスとそのバッファに線を引きます。長方形機能は予定されていません。
ビットごとに以下の機能を持ちます。
bit6,7 | 00 | pset (他は遅くなる可能性がある) |
01 | and | |
10 | or | |
11 | xor | |
bit15 | 非同期 (グラフィックボックスバッファのみ書き込み) |
他のビットは予約されています。0にしてください。
グラフィックボックスのオープンで指定したものと同じてす。
描画範囲の左上の座標と幅と高さです。座標はグラフィックボックス内座標で, 単位はピクセルです。この描画範囲が全ての点を含まなければなりません。これがグラフィックボックスの表示範囲を越える場合は非同期を指定しなければなりません。
線の数です。0は許されません。
描画用線データのポインタです。座標は描画範囲の左上を原点として作ってください。内部形式です。一般的な形式から内部への変換には線データ変換を使います。
一般的な (と思われる) 形式の線データを複数線描が要求する内部形式 (点々形式) に変換します。
線の数です。
元のデータのポインタです。
変換後のデータのポインタです。 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; };
描画色で, 0から15までの値です。
線を複数描画する低級コマンドです。再描画は自分でする必要があります。
描画属性を指定します。
bit6,7 | 00 | pset |
01 | and | |
10 | or | |
11 | xor | |
bit15 | やや安全モード。ウィンドウ描画禁止中は描画しない。 |
ほかのビットは予約されているので0にしてください。
ウィンドウオープンで指定したものと同じです。-1にすると画面全体になります。
(x,)を左上として幅width, 高さheightの長方形が, 描画する全ての点を含まなければなりません。描画する線はこの(x,y)を原点とします。
線の数です。0は許されません。
線の構造体 (内部形式) へのポインタです。
グラフィックボックスに文字列を描画します。フォントパターンの取得にも使えます。
ビット毎に意味がありますが, 未実装が多いようです。
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 | バッファのみに書き込み,グラフィックボックスには何もしない。 |
グラフィックボックスオープンで与えたものと同じです。8bpp専用です。
グラフィックボックスの中でのピクセル単位の座標値です。描画結果がグラフィックボックスをはみ出さない限り, (xが8の倍数であるなどの) 制限はありません (その分低速です)。
文字色と背景色です。
使用するフォントセットのスロットです。
上のコマンドとほぼ同じですが, グラフィックボックスとは関係ないバッファに書き込めます。
上とほぼ同じですが, 当然bit15は無効になるようです。
書き込むバッファのポインタです。
バッファの幅です。負の値も許されます。
乱数を取得する。これを種として自分で乱数列を作るとよい。
第三パラメータはパラメータではなく, バッファです。ここに32ビット乱数が書き込まれます。
モジュールの大きさを変えます。対象のモジュールを事前にアンマッピングしておかなければなりません。
モジュールハンドルのスロットです。
変更後の大きさです。モジュールの最後の部分に追加・削除することによって大きさが変わります。
現状では, モジュールを大きくするとフロッピーのファイルがサルベージできます。読み込むのが遅いのでゼロクリアにした方がセキュリティとか速さの面でいいと思うんですが。
完了シグナルです。これがそのまま返ってきたら成功で, 1から15を足したシグナルが返ってきたら失敗です。完了シグナルが来るまでこのコマンドを実行してはならない手抜きがあると思われます。
アプリを作っていて, 「絶対OSASKのバグだ! 俺のせいじゃない!」と思ったら, ソースを読んでみましょう。
0x0128, 0x3240 /* winman0 */ + 6, 0x7f000005, 0x0048, EAX, [DS:0x000c], cmd[0], cmd[4]というのを取り上げると, 左から順に, tapiのコマンド, tapi用送信先+長さ, pioneer用送信先 (ユーザアプリ) +長さ, winman0 が受け取るシグナル……, と読みます。
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