/* * * シンプルライブラリなしで、逐次処理的なプログラムを書くサンプル * */ #include /**************************************************************************** * アプリケーションごとに変更する必要のない部分 ****************************************************************************/ void app_proc(); void app_exit(); void yield(); int main(); typedef struct _CONTEXT { int r0, r1, r2, r3; int* sp; } CONTEXT; static CONTEXT system_context; /* システムコンテキスト保存用 */ static CONTEXT user_context; /* ユーザーコンテキスト保存用 */ void pceAppInit() { /* ユーザーコンテキストを初期化します。 */ user_context.sp = (int*)0x1C00; /* 1000〜1C00:ユーザースタック */ /* 1C00〜2000:システムスタック */ *--user_context.sp = (int)app_exit; /* main()が制御を返した時に呼ばれる関数 */ *--user_context.sp = (int)main; /* アプリケーションのエントリポイント */ } void pceAppProc(int count) { /* yield()とスタックフレームの構成を合わせる必要があるので、 * 引数なしの関数を経由します。 */ app_proc(); } void pceAppExit() { /* 何もしません。 */ } void app_proc() { asm(" ; システムコンテキストを退避します。 xld.w %r7, system_context ld.w [%r7]+, %r0 ld.w [%r7]+, %r1 ld.w [%r7]+, %r2 ld.w [%r7]+, %r3 ld.w %r4, %sp ld.w [%r7]+, %r4 ; ユーザーコンテキストを復元します。 xld.w %r7, user_context ld.w %r0, [%r7]+ ld.w %r1, [%r7]+ ld.w %r2, [%r7]+ ld.w %r3, [%r7]+ ld.w %r4, [%r7]+ ld.w %sp, %r4 "); } void app_exit() { asm(" ; システムコンテキストを復元します。 xld.w %r7, system_context ld.w %r0, [%r7]+ ld.w %r1, [%r7]+ ld.w %r2, [%r7]+ ld.w %r3, [%r7]+ ld.w %r4, [%r7]+ ld.w %sp, %r4 ; 終了要求を発行します。 ld.w %r12, %r10 xcall pceAppReqExit "); } void yield() { asm(" ; ユーザーコンテキストを退避します。 xld.w %r7, user_context ld.w [%r7]+, %r0 ld.w [%r7]+, %r1 ld.w [%r7]+, %r2 ld.w [%r7]+, %r3 ld.w %r4, %sp ld.w [%r7]+, %r4 ; システムコンテキストを復元します。 xld.w %r7, system_context ld.w %r0, [%r7]+ ld.w %r1, [%r7]+ ld.w %r2, [%r7]+ ld.w %r3, [%r7]+ ld.w %r4, [%r7]+ ld.w %sp, %r4 "); } /**************************************************************************** * アプリケーションごとに変更する部分(サンプル) ****************************************************************************/ unsigned char vbuff[DISP_X * DISP_Y]; /* 仮想VRAM */ int main() { int x, y; /* 初期化を行います。 */ pceLCDDispStop(); pceLCDSetBuffer(vbuff); pceAppSetProcPeriod(1000 / 30); pceLCDDispStart(); /* キャラクタの初期位置。 */ x = y = 0; /* 左上から右上へ移動。 */ while(x < DISP_X - 5) { /* キャラクタ表示。 */ memset(vbuff, 0, sizeof vbuff); pceFontPut(x, y, 'A'); x += 2; pceLCDTrans(); /* システム処理。 */ yield(); } x = DISP_X - 5; /* 右上から右下へ移動。 */ while(y < DISP_Y - 10) { /* キャラクタ表示。 */ memset(vbuff, 0, sizeof vbuff); pceFontPut(x, y, 'A'); y += 2; pceLCDTrans(); /* システム処理。 */ yield(); } y = DISP_Y - 10; /* 右下から左下へ移動。 */ while(x > 0) { /* キャラクタ表示。 */ memset(vbuff, 0, sizeof vbuff); pceFontPut(x, y, 'A'); x -= 2; pceLCDTrans(); /* システム処理。 */ yield(); } x = 0; /* 左下から左上へ移動。 */ while(y > 0) { /* キャラクタ表示。 */ memset(vbuff, 0, sizeof vbuff); pceFontPut(x, y, 'A'); y -= 2; pceLCDTrans(); /* システム処理。 */ yield(); } y = 0; return 0; }