非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

X68000(30)

インラインアセンブラの中からグローバル変数を参照するように変更しました。

楕円の弧を描画する関数を作成しました。これは実行速度が遅いので改善する必要があります。これは IOCS コールでもできるのですが、そのようなものは IOCS を使うものも作成しようと思います。

グローバル変数の定義

// インラインアセンブラで使うためのグローバル変数の定義
int16_t g_color;
int32_t g_x1, g_y1, g_x2, g_y2, g_w, g_h, g_rx, g_ry;
int32_t g_start_angle, g_sweep_angle;
int32_t g_r, g_hbyw, g_end_angle, g_sc1, g_sc2, g_sc3, g_sc4, g_page;
uint8_t g_mx, g_my, g_font_size, g_rotation;
char g_text[MAX_DRAW_TEXT];
int32_t g_gsize = 0;        // グラフィックス領域の幅 0: 512x512, 1: 1024x1024
int32_t g_gaddr = 0xc00000; // グラフィックス用メモリーの先頭のアドレス

ピクセルを描画する関数(インラインアセンブラ)

グローバル変数を参照するように変更しました。

asm(
    "pset_only_a:\n\t"
    "movem.l  %d0-%d2/%a0, -(%sp)\n\t"
    "move.l   20(%sp), %d1\n\t"
    "move.l   24(%sp), %d2\n\t"
    "movea.l  %d1, %a0\n\t"
    "adda.l   %d1, %a0\n\t"  // a0 = x1 * 2
    "moveq.l  #10, %d0\n\t"
    "add.l    g_gsize, %d0\n\t"
    "lsl.l    %d0, %d2\n\t"  // d2 = y1 * 1024(2048)
    "adda.l   %d2, %a0\n\t"  // a0 = x1 * 2 + y1 * 1024(2048)
    "adda.l   g_gaddr, %a0\n\t" // a0 = 0xc00000 + x1 * 2 + y1 * 1024(2048)
    "move.w   28(%sp), %d0\n\t"
    "move.w   %d0, (%a0)\n\t"
    "movem.l  (%sp)+, %d0-%d2/%a0\n\t"
    "rts\n\t"
);

線を描画する関数(インラインアセンブラの関数を呼び出す関数)

グローバル変数を参照するように変更しました。

void drawlinex(int x1, int y1, int x2, int y2, COLORREF color)
{
    asm(
        "move.l   %0, g_x1\n\t"
        "move.l   %1, g_y1\n\t"
        "move.l   %2, g_x2\n\t"
        "move.l   %3, g_y2\n\t"
        "move.w   %4, g_color\n\t"
        "clr.l	  -(%%sp)\n\t"
        "dc.w	  0xff20\n\t"      // _SUPER (スーパーバイザーモードへ)
        "move.l   %%d0, (%%sp)\n\t"

        "move.w   g_color, -(%%sp)\n\t"
        "move.l   g_y2, -(%%sp)\n\t"
        "move.l   g_x2, -(%%sp)\n\t"
        "move.l   g_y1, -(%%sp)\n\t"
        "move.l   g_x1, -(%%sp)\n\t"
        "move.l   #0, -(%%sp)\n\t"
        "jsr     drawlinex_a\n\t"
        "add.l    #22,%%sp\n\t"

        "dc.w	  0xff20\n\t"      // _SUPER (スーパーバイザーモードから戻る)
        "addq.l   #4, %%sp\n\t"
        :
        : "r"(x1), "r"(y1), "r"(x2), "r"(y2), "r"(color) // 入力
        : "d0"                                           // 使用するレジスタ
        );
}

以下の関数をコンパイラの出力から作成しました。

現在の位置を初期化する関数・現在の位置から線を描画する関数(インラインアセンブラ)

asm(
    "drawlineinitx_a:\n\t"
    "moveq #-1,%d0\n\t"
    "move.l %d0,direct_draw_x\n\t"
    "rts\n\t"
);
asm(
    "drawlinetox_a:\n\t"
    "move.l %d4,-(%sp)\n\t"
    "move.l %d3,-(%sp)\n\t"
    "move.l 16(%sp),%d4\n\t"
    "move.l 20(%sp),%d3\n\t"
    "move.l direct_draw_x,%d0\n\t"
    "jmi dltxL113\n\t"
    "move.l 24(%sp),-(%sp)\n\t"
    "move.l %d3,-(%sp)\n\t"
    "move.l %d4,-(%sp)\n\t"
    "move.l direct_draw_y,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "move.l 32(%sp),-(%sp)\n\t"
    "jsr drawlinex_a\n\t"
    "lea (24,%sp),%sp\n\t"
    "dltxL113:\n\t"
    "move.l %d4,direct_draw_x\n\t"
    "move.l %d3,direct_draw_y\n\t"
    "move.l (%sp)+,%d3\n\t"
    "move.l (%sp)+,%d4\n\t"
    "rts\n\t"
);

現在の位置から楕円の弧を描画する関数(インラインアセンブラ)

asm(
    "drawarctox_a:\n\t"
    "lea (-36,%sp),%sp\n\t"
    "movem.l #7966,-(%sp)\n\t"
    "move.l 76(%sp),%d7\n\t"
    "move.l 88(%sp),%d6\n\t"
    "move.l 92(%sp),%d5\n\t"
    "move.l 104(%sp),%a5\n\t"
    "move.l %d6,%d3\n\t"
    "jpl datxL128\n\t"
    "addq.l #1,%d3\n\t"
    "datxL128:\n\t"
    "asr.l #1,%d3\n\t"
    "add.l 80(%sp),%d3\n\t"
    "move.l %d5,%d0\n\t"
    "jpl datxL129\n\t"
    "addq.l #1,%d0\n\t"
    "datxL129:\n\t"
    "asr.l #1,%d0\n\t"
    "add.l 84(%sp),%d0\n\t"
    "move.l %d0,44(%sp)\n\t"
    "move.l 96(%sp),%d4\n\t"
    "move.l %d4,%a6\n\t"
    "add.l 100(%sp),%a6\n\t"
    "lea __floatsidf,%a4\n\t"
    "lea __muldf3,%a3\n\t"
    "datxL126:\n\t"
    "move.l %d6,-(%sp)\n\t"
    "jsr (%a4)\n\t"
    "move.l %d0,%a0\n\t"
    "move.l %d1,%a1\n\t"
    "move.l %a0,52(%sp)\n\t"
    "move.l %a1,56(%sp)\n\t"
    "move.l %d5,(%sp)\n\t"
    "jsr (%a4)\n\t"
    "addq.l #4,%sp\n\t"
    "move.l %d0,%a0\n\t"
    "move.l %d1,%a1\n\t"
    "move.l %a0,56(%sp)\n\t"
    "move.l %a1,60(%sp)\n\t"
    "cmp.l %a6,%d4\n\t"
    "jlt datxL127\n\t"
    "move.l %a6,-(%sp)\n\t"
    "jsr (%a4)\n\t"
    "lea __muldf3,%a3\n\t"
    "move.l #-266631570,(%sp)\n\t"
    "move.l #1074340345,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1080459264,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr __divdf3\n\t"
    "lea (16,%sp),%sp\n\t"
    "move.l %d0,%a0\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %a0,-(%sp)\n\t"
    "move.l %a0,44(%sp)\n\t"
    "move.l %d1,48(%sp)\n\t"
    "jsr cos\n\t"
    "addq.l #8,%sp\n\t"
    "move.l %d0,%d4\n\t"
    "move.l %d1,%d5\n\t"
    "move.l 36(%sp),%a0\n\t"
    "move.l 40(%sp),%a1\n\t"
    "move.l %a1,-(%sp)\n\t"
    "move.l %a0,-(%sp)\n\t"
    "jsr sin\n\t"
    "addq.l #8,%sp\n\t"
    "move.l %a5,88(%sp)\n\t"
    "move.l 60(%sp),-(%sp)\n\t"
    "move.l 60(%sp),-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1071644672,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (16,%sp),%sp\n\t"
    "lea __fixdfsi,%a4\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a4)\n\t"
    "addq.l #8,%sp\n\t"
    "move.l 44(%sp),%d1\n\t"
    "sub.l %d0,%d1\n\t"
    "move.l %d1,84(%sp)\n\t"
    "move.l 52(%sp),-(%sp)\n\t"
    "move.l 52(%sp),-(%sp)\n\t"
    "move.l %d5,-(%sp)\n\t"
    "move.l %d4,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1071644672,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "move.l %d1,(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a4)\n\t"
    "addq.l #8,%sp\n\t"
    "add.l %d3,%d0\n\t"
    "move.l %d0,80(%sp)\n\t"
    "move.l %d7,76(%sp)\n\t"
    "movem.l (%sp)+,#30968\n\t"
    "lea (36,%sp),%sp\n\t"
    "jra drawlinetox_a\n\t"
    "datxL127:\n\t"
    "move.l %d4,-(%sp)\n\t"
    "jsr (%a4)\n\t"
    "move.l #-266631570,(%sp)\n\t"
    "move.l #1074340345,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1080459264,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr __divdf3\n\t"
    "lea (16,%sp),%sp\n\t"
    "move.l %d0,%a0\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %a0,-(%sp)\n\t"
    "move.l %a0,44(%sp)\n\t"
    "move.l %d1,48(%sp)\n\t"
    "jsr cos\n\t"
    "addq.l #8,%sp\n\t"
    "move.l %d0,%d2\n\t"
    "move.l %d2,%d0\n\t"
    "move.l %d0,64(%sp)\n\t"
    "move.l %d1,68(%sp)\n\t"
    "move.l 36(%sp),%a0\n\t"
    "move.l 40(%sp),%a1\n\t"
    "move.l %a1,-(%sp)\n\t"
    "move.l %a0,-(%sp)\n\t"
    "jsr sin\n\t"
    "addq.l #4,%sp\n\t"
    "move.l %a5,(%sp)\n\t"
    "move.l 64(%sp),-(%sp)\n\t"
    "move.l 64(%sp),-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1071644672,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (16,%sp),%sp\n\t"
    "lea __fixdfsi,%a0\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "move.l %a0,48(%sp)\n\t"
    "jsr (%a0)\n\t"
    "addq.l #8,%sp\n\t"
    "move.l 48(%sp),%d1\n\t"
    "sub.l %d0,%d1\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l 60(%sp),-(%sp)\n\t"
    "move.l 60(%sp),-(%sp)\n\t"
    "move.l 84(%sp),-(%sp)\n\t"
    "move.l 84(%sp),-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "clr.l (%sp)\n\t"
    "move.l #1071644672,-(%sp)\n\t"
    "move.l %d1,-(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "jsr (%a3)\n\t"
    "lea (12,%sp),%sp\n\t"
    "move.l %d1,(%sp)\n\t"
    "move.l %d0,-(%sp)\n\t"
    "move.l 52(%sp),%a0\n\t"
    "jsr (%a0)\n\t"
    "addq.l #8,%sp\n\t"
    "move.l %d0,%a0\n\t"
    "pea (%a0,%d3.l)\n\t"
    "move.l %d7,-(%sp)\n\t"
    "jsr drawlinetox_a\n\t"
    "addq.l #5,%d4\n\t"
    "lea (16,%sp),%sp\n\t"
    "jra datxL126\n\t"
);

楕円の弧を描画する関数(インラインアセンブラ)

asm(
    "drawarcx_a:\n\t"
    "moveq #-1,%d0\n\t"
    "move.l %d0,direct_draw_x\n\t"
    "jra drawarctox_a\n\t"
);

楕円の弧を描画する関数(インラインアセンブラの関数を呼び出す)

グローバル変数を参照しています。これは実行速度が遅いです。

void drawarcx(int x1, int y1, int w, int h, int start_angle, int sweep_angle, COLORREF color) {
    asm(
        "move.l   %0, g_x1\n\t"
        "move.l   %1, g_y1\n\t"
        "move.l   %2, g_w\n\t"
        "move.l   %3, g_h\n\t"
        "move.l   %4, g_start_angle\n\t"
        "move.l   %5, g_sweep_angle\n\t"
        "move.w   %6, g_color\n\t"
        "clr.l	  -(%%sp)\n\t"
        "dc.w	  0xff20\n\t"      // _SUPER (スーパーバイザーモードへ)
        "move.l   %%d0, (%%sp)\n\t"

        "move.w   g_color, -(%%sp)\n\t"
        "move.l   g_sweep_angle, -(%%sp)\n\t"
        "move.l   g_start_angle, -(%%sp)\n\t"
        "move.l   g_h, -(%%sp)\n\t"
        "move.l   g_w, -(%%sp)\n\t"
        "move.l   g_y1, -(%%sp)\n\t"
        "move.l   g_x1, -(%%sp)\n\t"
        "move.l   #0, -(%%sp)\n\t"
        "jsr      drawarcx_a\n\t"
        "add.l    #30,%%sp\n\t"

        "dc.w	  0xff20\n\t"      // _SUPER (スーパーバイザーモードから戻る)
        "addq.l   #4, %%sp\n\t"
        :                        // 出力
        : "r"(x1), "r"(y1), "r"(w), "r"(h), "r"(start_angle), "r"(sweep_angle), "r"(color) // 入力
        : "d0"                   // 使用するレジスタ
        );
}