線を描画する関数をコンパイルした結果をインラインアセンブラに取り込んだものを作成しました。「関数電卓コマンド版(3) - 非専門的シンギュラリティー研究所」の乗算・除算のコードを使っています。そのままでは動かなかったので変数をスタックで渡さず変数の領域を確保してそこに値を設定する方法に変更しました。正しいやり方とは思えませんがいったんこれで良いものとします。
2025年にやることではないとは思うのですが、サンプルが探しても見つからないので自分で作っていきます。IOCS ではできないこともあるのでやっておくと後で役に立つ予定です。
コンパイルした結果を修正した関数
// 変数をスタックで渡さず変数の領域を確保してそこに値を設定する方法に変更 asm( "dlx36: dc.l 0\n\t" "dlx40: dc.l 0\n\t" "drawlinex_a:\n\t" "move.l dlxx1, %d4\n\t" // d4 = x1 "move.l dlxy1, %d3\n\t" // d3 = y1 "move.l dlxx2, %d1\n\t" // d1 = x2 "move.l dlxy2, %d0\n\t" // d0 = y2 "move.w dlxcolor, %a4\n\t" // a4 = color "move.l %d1, %d5\n\t" // d5 = x2 "sub.l %d4, %d5\n\t" // d5 = x2 - x1 "move.l %d0, %a3\n\t" // a3 = y2 "sub.l %d3, %a3\n\t" // a3 = y2 - y1 "move.l %a3, %d6\n\t" // d6 = y2 - y1 "jpl dlxL4\n\t" // y2 - y1 >= 0 "neg.l %d6\n\t" // d6 = -(y2 - y1) "dlxL4:\n\t" "move.l %d5, %d2\n\t" // d2 = x2 - x1 "jpl dlxL5\n\t" // x2 - x1 >= 0 "neg.l %d2\n\t" // d2 = -(x2 - x1) "dlxL5:\n\t" "lea shift_multiply_a, %a5\n\t" // shift_multiply_aのアドレスをa5に設定 "cmp.l %d6, %d2\n\t" // y2 - y1 と x2 - x1 を比較 "jle dlxL3\n\t" // y2 - y1 <= x2 - x1 の場合 "tst.l %d5\n\t" // x2 - x1 が0かどうかをチェック "jlt dlxL13\n\t" // x2 - x1 < 0 の場合 "moveq #1, %d7\n\t" // d7 = 1 "dlxL6:\n\t" "move.l %d1, -(%sp)\n\t" // スタックにx2を保存 "move.l %d7, -(%sp)\n\t" // スタックにd7を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, dlx36\n\t" // スタックにy2を保存 "move.l %d4, -(%sp)\n\t" // スタックにx1を保存 "move.l %d7, -(%sp)\n\t" // スタックにd7を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, %d6\n\t" // d6 = y2 - y1 の結果を保存 "move.l %a3, -(%sp)\n\t" // スタックにy2 - y1を保存 "move.l %d7, -(%sp)\n\t" // スタックにd7を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, dlx40\n\t" // スタックにx2 - x1の結果を保存 "sub.l %a3, %a3\n\t" // a3 = y2 - y1 の結果を0にする "move.l #0xc00000, %a5\n\t" // GraMemのアドレスをa5に設定 "lea shift_divide_a, %a6\n\t" // shift_divide_aのアドレスをa6に設定 "dlxL7:\n\t" "cmp.l dlx36, %d6\n\t" // スタックのy2とd6を比較 "jlt dlxL8\n\t" // y2 < d6 の場合 "dlxL2:\n\t" "rts\n\t" // 戻り値を返す "dlxL13:\n\t" "moveq #-1, %d7\n\t" // d7 = -1 "jra dlxL6\n\t" // dlxL6にジャンプ "dlxL8:\n\t" "move.l %d5, -(%sp)\n\t" // スタックにx2 - x1を保存 "move.l %a3, -(%sp)\n\t" // スタックにy2 - y1を保存 "jsr (%a6)\n\t" // shift_divide_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "add.l %d3, %d0\n\t" // d0 = y2 - y1 + y1 "moveq #9, %d1\n\t" // d1 = 9 "lsl.l %d1, %d0\n\t" // d0 = (y2 - y1 + y1) * 512 "add.l %d4, %d0\n\t" // d0 = x1 + (y2 - y1 + y1) * 512 "add.l %d0, %d0\n\t" // d0 = x1 + (y2 - y1 + y1) * 512 * 2 "move.w %a4, (%a5, %d0.l)\n\t" // GraMemに色を設定 "add.l %d7, %d4\n\t" // x1 = x1 + d7 "addq.l #1, %d6\n\t" // d6 = y2 - y1 + 1 "add.l dlx40, %a3\n\t" // y2 - y1 = y2 - y1 + x2 - x1 "jra dlxL7\n\t" // dlxL7にジャンプ "dlxL3:\n\t" "cmp.w #0, %a3\n\t" // y2 - y1 が0かどうかをチェック "jlt dlxL14\n\t" // y2 - y1 < 0 の場合 "moveq #1, %d6\n\t" // d6 = 1 "dlxL9:\n\t" "move.l %d0, -(%sp)\n\t" // スタックにy2を保存 "move.l %d6, -(%sp)\n\t" // スタックにd6を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, dlx36\n\t" // スタックにy2を保存 "move.l %d3, -(%sp)\n\t" // スタックにy2 - y1を保存 "move.l %d6, -(%sp)\n\t" // スタックにd6を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, %d7\n\t" // d7 = y2 - y1 の結果を保存 "move.l %d5, -(%sp)\n\t" // スタックにx2 - x1を保存 "move.l %d6, -(%sp)\n\t" // スタックにd6を保存 "jsr (%a5)\n\t" // shift_multiply_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d0, dlx40\n\t" // スタックにx2 - x1の結果を保存 "moveq #9, %d0\n\t" // d0 = 9 "lsl.l %d0, %d6\n\t" // d6 = (y2 - y1 + y1) * 512 "move.l %d3, %d5\n\t" // d5 = y2 - y1 "lsl.l %d0, %d5\n\t" // d5 = (y2 - y1 + y1) * 512 "moveq #0, %d3\n\t" // d3 = 0 "move.l #0xc00000, %a5\n\t" // GraMemのアドレスをa5に設定 "lea shift_divide_a, %a6\n\t" // shift_divide_aのアドレスをa6に設定 "dlxL10:\n\t" "cmp.l dlx36, %d7\n\t" // スタックのy2とd7を比較 "jge dlxL2\n\t" // y2 >= d7 の場合 "move.l %a3, -(%sp)\n\t" // スタックにy2 - y1を保存 "move.l %d3, -(%sp)\n\t" // スタックにd3を保存 "jsr (%a6)\n\t" // shift_divide_aを呼び出す "addq.l #8, %sp\n\t" // スタックを8バイト戻す "move.l %d5, %d1\n\t" // d1 = x2 - x1 の結果を保存 "add.l %d4, %d1\n\t" // d1 = x1 + (y2 - y1 + y1) * 512 "add.l %d1, %d0\n\t" // d0 = x1 + (y2 - y1 + y1) * 512 * 2 "add.l %d0, %d0\n\t" // d0 = x1 + (y2 - y1 + y1) * 512 * 2 * 2 "move.w %a4, (%a5, %d0.l)\n\t" // GraMemに色を設定 "addq.l #1, %d7\n\t" // d7 = y2 - y1 + 1 "add.l dlx40, %d3\n\t" // y2 - y1 = y2 - y1 + x2 - x1 "add.l %d6, %d5\n\t" // d5 = y2 - y1 + (y2 - y1 + y1) * 512 "jra dlxL10\n\t" // dlxL10にジャンプ "dlxL14:\n\t" "moveq #-1, %d6\n\t" // d6 = -1 "jra dlxL9\n\t" // dlxL9にジャンプ );
上記の関数を呼び出すための関数
// 変数をスタックで渡さず変数の領域を確保してそこに値を設定する方法に変更 void drawlinex(int x1, int y1, int x2, int y2, COLORREF color) { asm( "move.l %0, dlxx1\n\t" "move.l %1, dlxy1\n\t" "move.l %2, dlxx2\n\t" "move.l %3, dlxy2\n\t" "move.w %4, dlxcolor\n\t" "clr.l -(%%sp)\n\t" "dc.w 0xff20\n\t" // _SUPER (スーパーバイザーモードへ) "move.l %%d0, (%%sp)\n\t" "movem.l %%d0-%%d7/%%a0-%%a6, -(%%sp)\n\t" // レジスタを保存 "jsr drawlinex_a\n\t" "movem.l (%%sp)+, %%d0-%%d7/%%a0-%%a6\n\t" // レジスタを復元 "dc.w 0xff20\n\t" // _SUPER (スーパーバイザーモードから戻る) "addq.l #4,%%sp\n\t" "jmp dlxexit\n\t" "dlxx1: dc.l 0\n\t" "dlxy1: dc.l 0\n\t" "dlxx2: dc.l 0\n\t" "dlxy2: dc.l 0\n\t" "dlxcolor: dc.w 0\n\t" "dlxexit:\n\t" : : "r"(x1), "r"(y1), "r"(x2), "r"(y2), "r"(color) // 入力 : "d0" // 使用するレジスタ ); }




