6: 2005-01-24 (月) 22:02:09 [6] | 現: 2024-01-08 (月) 12:58:56 k-tan[7] [8] | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | * wiki版のintroシリーズ no.0002 | + | TITLE:x |
+ | * wiki版のintroシリーズ no.0002 [#k58fd08c] | ||
-(by [[K]], 2004.12.15) | -(by [[K]], 2004.12.15) | ||
-これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 | -これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。 | ||
--これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。 | --これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。 | ||
- | ---最初から読みたい人は[[guide/ASKA]]や[[guide/nask]]からどうぞ。 | + | ---最初から読みたい人は[[guide/C]]や[[guide/ASKA]]や[[guide/nask]]からどうぞ。 |
--C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 | --C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。 | ||
-質問とか感想とかはこめんと欄にレッツゴー。 | -質問とか感想とかはこめんと欄にレッツゴー。 | ||
- | *** countdown | + | *** countdown [#v307e891] |
- | -C版:"cntdwnc1.c" [osa_dir2では 617バイト] | + | -C版:"cntdwnc1.c" [tolset08では 538バイト] |
+ | //-C版:"cntdwnc1.c" [osa_dir2では 617バイト] | ||
/* "cntdwnc1.c":countdwnをC言語で記述した例 */ | /* "cntdwnc1.c":countdwnをC言語で記述した例 */ | ||
/* stack:4k malloc:1k */ | /* stack:4k malloc:1k */ | ||
+ | |||
#include <guigui00.h> | #include <guigui00.h> | ||
+ | |||
#define AUTO_MALLOC 0 | #define AUTO_MALLOC 0 | ||
+ | |||
void setdec3(int i, char *s); | void setdec3(int i, char *s); | ||
+ | |||
void OsaskMain() | void OsaskMain() | ||
{ | { | ||
Line 24: | Line 26: | ||
int count; | int count; | ||
static char msg[] = "000"; | static char msg[] = "000"; | ||
+ | |||
/* ライブラリ初期化 */ | /* ライブラリ初期化 */ | ||
lib_init(AUTO_MALLOC); | lib_init(AUTO_MALLOC); | ||
+ | |||
/* ウィンドウオープン */ | /* ウィンドウオープン */ | ||
window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16); | window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16); | ||
Line 33: | Line 35: | ||
textbox = lib_opentextbox(0x0000, AUTO_MALLOC, 0, 3, 1, 56, 0, window, 0x00c0, 0); | textbox = lib_opentextbox(0x0000, AUTO_MALLOC, 0, 3, 1, 56, 0, window, 0x00c0, 0); | ||
lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "cntdwnc1"); | lib_putstring_ASCII(0x0000, 0, 0, wintitle, 0, 0, "cntdwnc1"); | ||
+ | |||
/* メインループ */ | /* メインループ */ | ||
for (;;) { | for (;;) { | ||
Line 45: | Line 47: | ||
} | } | ||
} | } | ||
+ | |||
void setdec3(int i, char *s) | void setdec3(int i, char *s) | ||
/* 注意:このルーチンでは、0~999までしか扱えない */ | /* 注意:このルーチンでは、0~999までしか扱えない */ | ||
Line 59: | Line 61: | ||
return; | return; | ||
} | } | ||
+ | |||
- | + | -ASKA版:"cntdwna1.ask" [tolset08では 219バイト] | |
- | -ASKA版:"cntdwna1.ask" [osa_dir2では 249バイト] | + | //-ASKA版:"cntdwna1.ask" [osa_dir2では 249バイト] |
/* "cntdwna1.ask":countdwnをASKAで記述した例 */ | /* "cntdwna1.ask":countdwnをASKAで記述した例 */ | ||
/* stack:4k malloc:0k */ | /* stack:4k malloc:0k */ | ||
segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'cntdwna1.ask']"); | segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'cntdwna1.ask']"); | ||
asmout("GLOBAL _OsaskMain"); | asmout("GLOBAL _OsaskMain"); | ||
+ | |||
void setdec3(); /* EAXをDS:ESIに書き込む */ | void setdec3(); /* EAXをDS:ESIに書き込む */ | ||
+ | |||
void _OsaskMain() | void _OsaskMain() | ||
{ | { | ||
asmout("MOV EBX,data.init"); CALL(0xc7, 0); | asmout("MOV EBX,data.init"); CALL(0xc7, 0); | ||
+ | |||
for (;;) { | for (;;) { | ||
unsigned int count == EAX; | unsigned int count == EAX; | ||
Line 87: | Line 90: | ||
} | } | ||
} | } | ||
+ | |||
void setdec3() | void setdec3() | ||
{ | { | ||
Line 113: | Line 116: | ||
return; | return; | ||
} | } | ||
+ | |||
asmout("[SECTION .data]"); | asmout("[SECTION .data]"); | ||
+ | |||
void data() | void data() | ||
{ | { | ||
Line 134: | Line 137: | ||
DD(0x0018, 0x0007, 0, 0, 0, 10, 0); /* lib_waitsignaltime */ | DD(0x0018, 0x0007, 0, 0, 0, 10, 0); /* lib_waitsignaltime */ | ||
DD(0x0000); /* end of functions */ | DD(0x0000); /* end of functions */ | ||
+ | |||
ALIGNB(8); | ALIGNB(8); | ||
work: | work: | ||
Line 147: | Line 150: | ||
RESB(24); /* 3x1文字分 (3 * 1 * 8) */ | RESB(24); /* 3x1文字分 (3 * 1 * 8) */ | ||
} | } | ||
+ | |||
- | + | -nask版:"cntdwnn1.nas" [tolset08では 219バイト] | |
- | -nask版:"cntdwnn1.nas" [osa_dir2では 251バイト] | + | //-nask版:"cntdwnn1.nas" [osa_dir2では 249バイト] |
; "cntdwnn1.nas":countdwnをnaskで記述した例 | ; "cntdwnn1.nas":countdwnをnaskで記述した例 | ||
; stack:4k malloc:0k | ; stack:4k malloc:0k | ||
+ | |||
[FORMAT "WCOFF"] | [FORMAT "WCOFF"] | ||
[INSTRSET "i486p"] | [INSTRSET "i486p"] | ||
Line 159: | Line 163: | ||
[BITS 32] | [BITS 32] | ||
[FILE "cntdwnn1.nas"] | [FILE "cntdwnn1.nas"] | ||
+ | |||
[SECTION .text] | [SECTION .text] | ||
GLOBAL _OsaskMain | GLOBAL _OsaskMain | ||
+ | |||
_OsaskMain: | _OsaskMain: | ||
MOV EBX,init | MOV EBX,init | ||
Line 174: | Line 178: | ||
CALL 0xc7:0 | CALL 0xc7:0 | ||
DEC EAX | DEC EAX | ||
- | CMP AL,16 | ||
JNZ .countloop | JNZ .countloop | ||
MOV EBX,putgo | MOV EBX,putgo | ||
CALL 0xc7:0 | CALL 0xc7:0 | ||
JMP .mainloop | JMP .mainloop | ||
+ | |||
setdec3: | setdec3: | ||
PUSH EDX | PUSH EDX | ||
Line 204: | Line 207: | ||
POP EDX | POP EDX | ||
RET | RET | ||
+ | |||
[SECTION .data] | [SECTION .data] | ||
ALIGNB 4 | ALIGNB 4 | ||
Line 222: | Line 225: | ||
DD 0x0018, 0x0007, 0, 0, 0, 10, 0 ; lib_waitsignaltime | DD 0x0018, 0x0007, 0, 0, 0, 10, 0 ; lib_waitsignaltime | ||
DD 0x0000 ; end of functions | DD 0x0000 ; end of functions | ||
+ | |||
ALIGNB 8 | ALIGNB 8 | ||
work: | work: | ||
Line 232: | Line 235: | ||
textbox: | textbox: | ||
RESB 64 + 3 * 1 * 8; テキストボックス構造体(3x1文字分) | RESB 64 + 3 * 1 * 8; テキストボックス構造体(3x1文字分) | ||
+ | |||
- | + | *** 説明 [#wd8c3e0c] | |
- | *** 説明 | + | |
- | -''以下未完成'' | + | |
-概要: | -概要: | ||
- | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに16色のメッセージを表示するだけのプログラムです。 | + | --このプログラムは、ウィンドウを一つ開き、そのウィンドウに1秒おきに数字を表示していくだけのプログラムです。 |
- | --このプログラムを通じて、テキストに色を付ける方法と、数字表示の方法について説明します。 | + | --このプログラムを通じて、一定時間タスクをスリープさせる方法を説明します。 |
- | --OSASKでは、printf()やitoa()などの便利な関数がまだ用意されていません。したがっ | + | --OSASKでは、アプリケーションが一定の時間を待つために、空のループをまわしたり、時刻を取得して比較を繰り返すようなことはしません。できないというわけではありませんが、CPUタイムの浪費につながりますから、もったいないです。したがって、所定の手続きを踏んで、時間が来るまでタスクをスリープさせます。 |
- | て、残念なことに数字を表示するのは少し面倒です。今回はitoaの代わりにsetdec2()という関数を作ってみました。 | + | |
- | --これくらいの規模の例になると、CとASKAとnaskの文法の違いが出てきますので、見比べてみるのも面白いかもしれません。どれでもいいのですので、好きな言語を活用してください。 | + | |
-APIの説明: | -APIの説明: | ||
+ | --lib_waitsignaltime(opt, signaldw, nest, time0, time1, time2) : | ||
+ | ---タスクを一定時間スリープさせます。optには、0x7か0xfを指定できます。signaldwとnestは0にしてください。time0~time2の設定方法は、以下のようにしてください。まず、設定したい時間間隔を秒で表します。その整数部をtime1に書き込みます。もし、32bitで書ききれないのでしたら(そんなに長く待つことがあるのかどうかは分かりませんが)、time2に上位32bitを入れてください(time1だけで収まれば、time2はもちろん0です)。つまり、最大で5千万年くらいまでは指定できます(でも今のバージョンでは上位数ビットが生かされないかもしれないのでせいぜい数百万年くらいにしてください・・・笑)。また、秒単位では細かな制御には向かないでしょう。そこで、小数部に2^32を乗じた値をtime0に設定します。これで1ns(ナノ秒)よりも細かい単位で指定できることになります。実際はハードウェアの都合によりこの96bitの精度が完全に生かされるとは限りませんが、しかし限界まで生かす努力はします。 | ||
+ | ---optに0xfを指定した場合、この関数をコールした時刻から指定された時間だけ待った後にタスクは目覚めます。一方、optに0x7を指定した場合は、既に設定されている時間基点から指定された時間だけ待った後にタスクが目覚めます。時間基点というのは、タスクが起動した時刻のことですが、lib_waitsignaltime()でスリープすると目覚めた時刻が新しい時間基点にセットされます。今回のサンプルのようにできるだけ「秒」を意識するなら、optに0xfを指定するよりは0x7を指定する方がふさわしいでしょう。なぜなら、目覚めた直後にすぐにスリープするわけではなく、文字表示などをするからです。 | ||
+ | ---この処理を1ns以下に終えることは期待できませんから、0xfを指定すれば徐々にこの誤差が累積されることになります。0x7ならそういうことは原理的にありません。これで誤差が出る場合にはOSかハードウェアの問題であり、アプリケーションの問題ではありません。目的に応じて使い分けましょう。 | ||
+ | ---本来はこの関数は一定時間待つためのものではありません。時限付きシグナル待ちというもので、シグナルがくれば時刻に達していなくてもタスクはスリープから回復してしまいます。しかし今のところシグナルを一切扱っていないので、事実上、純粋な時間待ちの処理として利用できます。 | ||
+ | ---この時間間隔指定ですが、少なくとも10ミリ秒以上はあってほしいです。これは何も10ミリ秒単位であることを要請しているわけでありません。11.52ミリ秒などでもかまいません。また頻繁に繰り替えすことがないのなら、10ミリ秒を下回ってもかまいません。将来のOSASKでは、連続して何度も10ミリ秒以下の指定をした場合、OS側で強制的に10ミリ秒間間隔に補正される可能性があります。現在のOSASKでは、OSの動作が不安定になります。ですからやってはいけません。 | ||
- | --lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) : | + | *** まとめ [#o7f1dd60] |
- | ---ウィンドウにテキストボックスを貼ります。optの値は、0と0x1000しか紹介していませんでしたが、実は1も使えます。optに1を指定すると、テキストボックスに外枠が付きます。また、背景色が選べるようになり、それはbackcolorで指定します。それ以外はoptに0を指定した場合と全く同様です。なお、この枠がウィンドウをはみ出たり他の表示と重なったりしないようにしてください。 | + | -これで時間を細かく制御できるようになるはずです。時間とともに表示を操作すれば動きのある表示(アニメーション)ができるでしょう。ここまでのところではテキストしか扱えないので、テキストアニメーションしかできませんが。それでも、少しは遊べるはずです。もねさんがすぐに「msg00」や「msg01」を作ったのもうなずけます。 |
- | + | -精密な時間制御が比較的簡単にできることはOSASKアプリの特徴の一つです。他のOSよりも簡単にマスターできることでしょう。 | |
- | --lib_putstring_ASCII(opt, x_pos, y_pos, textbox, color, backcolor, str) : | + | |
- | ---colorc1.cでは使われていませんが、optに1を指定することにより、この関数でもbackcolorが有効になります。これは文字の背景色を文字単位で指定するものです。ちなみにスペースを表示した場合、backcolorで指定した色の四角形が表示されます。 | + | |
- | ---ASKA/naskのlib_putstring1も全く同様で、optの最下位ビットを1にすると、backcolorに0以外を指定できるようになります。 | + | |
- | + | ||
- | *** まとめ | + | |
- | -これで、テキストボックスを使った表示は一通りできるようになったはずです。許される範囲であちこちを改造して、把握してください。この程度のことなら、決して難しくないと感じていただけるはずです。 | + | |
- | -なお、C版でテキストボックスを広げる際には、malloc領域が不足する可能性があるので、malloc:オプションの値を大きくしてやってください。ASKA/naskでは、テキストボックス構造体のサイズを間違えなければ、mallocは0kのままでかまいません。 | + | |
- | + | ||
- | -''以上未完成'' | + | |
- | *** おまけ | + | *** おまけ [#tca81632] |
-次回(no.0003)はキー入力を少しやります。これで、キー入力を反映できるようになるでしょう。 | -次回(no.0003)はキー入力を少しやります。これで、キー入力を反映できるようになるでしょう。 | ||
- | -読んでいる人が追いつけないほど先に進んでもしょうがないので、こめんと欄でリクエストがきたら次回を書き始めます。 | + | -続編はこちら → [[guide/wintro0003]] |
- | * こめんと欄 | + | * こめんと欄 [#z2bc8102] |
-遅くなりましたが、リクエストします。このページのAPIの説明に"lib_waitsignaltime"が無いよぅ。 -- ''nika'' SIZE(10){2005-01-24 (月) 18:29:50} | -遅くなりましたが、リクエストします。このページのAPIの説明に"lib_waitsignaltime"が無いよぅ。 -- ''nika'' SIZE(10){2005-01-24 (月) 18:29:50} | ||
-リクエストありがとうございます。今月中にこのページを完成できるように、努力します。・・・ので気長にお持ちください。 -- [[K]] SIZE(10){2005-01-24 (月) 22:02:08} | -リクエストありがとうございます。今月中にこのページを完成できるように、努力します。・・・ので気長にお持ちください。 -- [[K]] SIZE(10){2005-01-24 (月) 22:02:08} | ||
+ | -とりあえずこのページはできました。次のページは2週間後くらいまでに書き上げるくらいのペースで準備します。 -- [[K]] SIZE(10){2005-01-25 (火) 23:31:17} | ||
+ | -お疲れ様です。気長にお待ちしています。 -- ''nika'' SIZE(10){2005-01-25 (火) 23:52:43} | ||
+ | -tolset08対応&nask版のバグフィクス(17の次がGO!になっていた)。 -- [[K]] SIZE(10){2005-01-29 (土) 21:07:25} | ||
#comment | #comment |
(This host) = http://osask.net