ページへ戻る

− Links

 印刷 

guide​/wintro0002 のバックアップソース(No.4) :: OSASK計画

osaskwiki:guide/wintro0002 のバックアップソース(No.4)

« Prev[4]  Next »[5]
* wiki版のintroシリーズ no.0002
-(by [[K]], 2004.12.15)
-これはC言語でもASKAでもnaskでもとにかくごちゃまぜでintroしてしまおうというこころみ。
--これは[[guide/wintro0001]]の続きなので、それを読んでない人はそれを読んでね。
---最初から読みたい人は[[guide/ASKA]]や[[guide/nask]]からどうぞ。
--C言語をやる人はintroaを読むといいでしょう。ここのプログラムは、introaと同一内容です。
-質問とか感想とかはこめんと欄にレッツゴー。

*** countdown
-C版:"cntdwnc1.c" [osa_dir2では 617バイト]
 /* "cntdwnc1.c":countdwnをC言語で記述した例 */
 /*  stack:4k malloc:1k */

 #include <guigui00.h>

 #define AUTO_MALLOC    0

 void setdec3(int i, char *s);

 void OsaskMain()
 {
     struct LIB_WINDOW *window;
     struct LIB_TEXTBOX *wintitle, *textbox;
     int count;
     static char msg[] = "000";

     /* ライブラリ初期化 */
     lib_init(AUTO_MALLOC);

     /* ウィンドウオープン */
     window = lib_openwindow(AUTO_MALLOC, 0x0200, 18 * 8, 1 * 16);
     wintitle = lib_opentextbox(0x1000, AUTO_MALLOC, 0, 8, 1,  0, 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");

     /* メインループ */
     for (;;) {
         for (count = 100; count > 0; count--) {
             setdec3(count, msg);
             lib_putstring_ASCII(0x0000, 0, 0, textbox, 0, 0, msg);
             lib_waitsignaltime(0x0007, 0, 0, 0, 1, 0); /* 1秒待つ */
         }
         lib_putstring_ASCII(0x0000, 0, 0, textbox, 0, 0, "GO!");
         lib_waitsignaltime(0x0007, 0, 0, 0, 10, 0); /* 10秒待つ */
     }
 }

 void setdec3(int i, char *s)
 /* 注意:このルーチンでは、0~999までしか扱えない */
 {
     s[0] = '0' + i / 100; i %= 100;
     s[1] = '0' + i /  10;
     s[2] = '0' + i %  10;
     if (s[0] == '0') {
         s[0] = ' ';
         if (s[1] == '0')
             s[1] = ' ';
     }
     return;
 }


-ASKA版:"cntdwna1.ask" [osa_dir2では 249バイト]
 /* "cntdwna1.ask":countdwnをASKAで記述した例 */
 /*  stack:4k malloc:0k */
 segment CODE(USE32, PARA); default(code == CODE); asmout("[FILE 'cntdwna1.ask']");
 asmout("GLOBAL _OsaskMain");

 void setdec3(); /* EAXをDS:ESIに書き込む */

 void _OsaskMain()
 {
     asmout("MOV EBX,data.init"); CALL(0xc7, 0);

     for (;;) {
         unsigned int count == EAX;
         count = 100;
         do {
             asmout("MOV EBX,data.putnum");
             LEA(ESI, [EBX + 36]);
             setdec3();
             CALL(0xc7, 0);
             count--;
         } while (!= 0);
         asmout("MOV EBX,data.putgo");
         CALL(0xc7, 0);
     }
 }

 void setdec3()
 {
     char *s == DS:ESI;
     PUSH(EDX);
     PUSH(ECX);
     PUSH(EAX);
     EDX = 0;
     ECX = 10;
     DIV(ECX); /* EDX:EAX / ECX = EAX ... EDX */
     DIV(CL);  /* AX / CL = AL ... AH */
     EAX |= 0x3030; /* '00' */
     DL |= 0x30;
     if (AL == 0x30) {
         AL = 0x20; /* ' ' */
         if (AH == 0x30)
             AH = 0x20;
     }
     s[0] = AL;
     s[1] = AH;
     s[2] = DL;
     POP(EAX);
     POP(ECX);
     POP(EDX);
     return;
 }

 asmout("[SECTION .data]");

 void data()
 {
     ALIGNB(4);
 init:
     asmout("DD 0x0004, data.work"); /* lib_init */
     asmout("DD 0x0020, data.window, 0x0200, 18 * 8, 1 * 16"); /* lib_openwindow */
     asmout("DD 0x0028, 0x1000, data.wintitle, 0, 8, 1, 0, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */
     asmout("DD 0x0028, 0x0000, data.textbox, 0, 3, 1, 56, 0, data.window, 0x00c0, 0"); /* lib_opentextbox */
     asmout("DD 0x0040, 0x1000, 0, 0, data.wintitle, 0, 0, 0, 8, 'cntdwna1'"); /* lib_putstring1 */
     DD(0x0000); /* end of functions */
 putnum:
     asmout("DD 0x0040, 0x1000, 0, 0, data.textbox,  0, 0, 0, 3, '000'"); /* lib_putstring1 */
     DD(0x0018, 0x0007, 0, 0, 0, 1, 0); /* lib_waitsignaltime */
     DD(0x0000); /* end of functions */
 putgo:
     asmout("DD 0x0040, 0x1000, 0, 0, data.textbox,  0, 0, 0, 3, 'GO!'"); /* lib_putstring1 */
     DD(0x0018, 0x0007, 0, 0, 0, 10, 0); /* lib_waitsignaltime */
     DD(0x0000); /* end of functions */

     ALIGNB(8);
 work:
     RESB(256); /* func_initに必要な256バイトのワークエリア */
 window:
     RESB(128); /* ウィンドウ構造体 */
 wintitle:
     RESB(64); /* テキストボックス構造体 */
     RESB(64);  /* 8x1文字分 (8 * 1 * 8) */
 textbox:
     RESB(64); /* テキストボックス構造体 */
     RESB(24);  /* 3x1文字分 (3 * 1 * 8) */
 }


-''以下未完成''

-nask版:"cntdwnn1.nas" [osa_dir2では バイト]
 ; "cntdwnn1.nas":countdwnをnaskで記述した例
 ;  stack:4k malloc:0k

 [FORMAT "WCOFF"]
 [INSTRSET "i486p"]
 [OPTIMIZE 1]
 [OPTION 1]
 [BITS 32]
 [FILE "cntdwnn1.nas"]

 [SECTION .text]
     GLOBAL _OsaskMain

 _OsaskMain:
     MOV  EBX,init
     CALL 0xc7:0
 .mainloop:
     MOV  EAX,100
 .countloop:
     MOV  EBX,putnum
     LEA  ESI,[EBX+36]
     CALL setdec3
     CALL 0xc7:0
     DEC  EAX
     CMP  AL,16
     JNZ  .countloop
     MOV  EBX,putgo
     CALL 0xc7:0
     JMP  .mainloop

 setdec2:
     PUSH EDX
     PUSH ECX
     PUSH EAX
     XOR  EDX,EDX
     MOV  ECX,10
     DIV  ECX
     DIV  CL
     OR   EAX,'00'
     OR   DL,'0'
     CMP  AL,'0'
     JNE  .skip
     MOV  AL,' '
     CMP  AH,'0'
     JNE  .skip
     MOV  AH,' '
 .skip:
     MOV  [ESI+0],AL
     MOV  [ESI+1],AH
     MOV  [ESI+2],DL
     POP  EAX
     POP  ECX
     POP  EDX
     RET
 ;;;
 [SECTION .data]
     ALIGNB 4
 init:
     DD 0x0004, work ; lib_init
     DD 0x0020, window, 0x0200, 20 * 8, 8 * 16 ; lib_openwindow
     DD 0x0028, 0x1000, wintitle, 0, 7, 1, 0, 0, window, 0x00c0, 0 ; lib_opentextbox
     DD 0x0028, 0x0001, textbox, 0, 20, 8, 0, 0, window, 0x00c0, 0 ; lib_opentextbox
     DD 0x0040, 0x1000, 0, 0, wintitle, 0, 0, 0,  7, 'colorn1' ; lib_putstring1
     DD 0x0000 ; end of functions
 putstr:
     DD 0x0040, 0x1000, 0, 0, textbox,  0, 0, 0, 8, 'color   ' ; lib_putstring1
     DD 0x0000 ; end of functions
 sleep:
     DD 0x0018, 0x0001, 0, 0 ; lib_waitsignal
     DD 0x0000 ; end of functions

     ALIGNB 8
 work:
     RESB 256 ; func_initに必要な256バイトのワークエリア
 window:
     RESB 128 ; ウィンドウ構造体
 wintitle:
     RESB  64 +  7 * 1 * 8; テキストボックス構造体(7x1文字分)
 textbox:
     RESB  64 + 20 * 8 * 8; テキストボックス構造体(20x8文字分)


*** 説明
-概要:
--このプログラムは、ウィンドウを一つ開き、そのウィンドウに16色のメッセージを表示するだけのプログラムです。
--このプログラムを通じて、テキストに色を付ける方法と、数字表示の方法について説明します。
--OSASKでは、printf()やitoa()などの便利な関数がまだ用意されていません。したがっ
て、残念なことに数字を表示するのは少し面倒です。今回はitoaの代わりにsetdec2()という関数を作ってみました。
--これくらいの規模の例になると、CとASKAとnaskの文法の違いが出てきますので、見比べてみるのも面白いかもしれません。どれでもいいのですので、好きな言語を活用してください。

-APIの説明:

--lib_opentextbox(opt, textbox, backcolor, x_size, y_size, x_pos, y_pos, window, charset, init_char) :
---ウィンドウにテキストボックスを貼ります。optの値は、0と0x1000しか紹介していませんでしたが、実は1も使えます。optに1を指定すると、テキストボックスに外枠が付きます。また、背景色が選べるようになり、それはbackcolorで指定します。それ以外はoptに0を指定した場合と全く同様です。なお、この枠がウィンドウをはみ出たり他の表示と重なったりしないようにしてください。

--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のままでかまいません。

-''以上未完成''

*** おまけ
-次回(no.0003)はキー入力を少しやります。これで、キー入力を反映できるようになるでしょう。
-読んでいる人が追いつけないほど先に進んでもしょうがないので、こめんと欄でリクエストきたら次回を書き始めます。

* こめんと欄
#comment

« Prev[4]  Next »[5]