#include "pset.h" /* インラインアセンブラを使うため */ void _asm_pset(char *); void pset(int x, int y, int c) { _asm_pset( "\t cmp ax, 224 \n" "\t jnc _skip \n" "\t cmp bx, 144 \n" "\t jnc _skip \n" ); _asm_pset( /* 破壊するレジスタを退避 */ "\t push ax \n" /* 最適化で利用される場合があるので */ "\t push bx \n" "\t push cx \n" "\t push es \n" "\t push di \n" "\t push dx \n" ); _asm_pset( /* マスクをゲット */ "\t mov di, ax \n" "\t and di, 7 \n" "\t mov dl, cs:[di +mask_data] \n" "\t mov dh, dl \n" ); #ifdef FAST_PSET _asm_pset( /* アドレス計算開始 */ "\t and ax, 0fff8h \n" "\t add bx, bx \n" "\t mov bx, cs:[bx +offset_table] \n" "\t add bx, ax \n" "\t add bx, bx \n" ); #else /* FAST_PSET */ _asm_pset( /* アドレス計算開始 */ "\t and ax, 0fff8h \n" "\t add ax, bx \n" /* 先に加えておけばBXを潰せる */ "\t shr bx, 1 \n" "\t shr bx, 1 \n" "\t and bx, 0fffeh \n" "\t mov bx, cs:[bx +offset_table] \n" "\t add bx, ax \n" "\t add bx, bx \n" ); #endif /* FAST_PSET */ _asm_pset( /* 書きこみ先のデータを読み込む */ /* VRAMアドレスのオフセット? */ #ifndef PSET_TEST "\t mov ax, 0200h \n" /* テストするときはesを更新しない */ "\t mov es, ax \n" #endif "\t mov ax, es:[bx] \n" "\t or ax, dx \n" ); _asm_pset( /* 書きこむ値の処理 */ "\t and cx, 3 \n" "\t jz _skip_calc \n" "\t jp _skip_write \n" ); _asm_pset( /* 書きこむ色が0でない場合 */ "\t add cx, 00feh \n" "\t and cx, 0101h \n" "\t add cx, 7f7fh \n" "\t xor cx, 8080h \n" "\t and dx, cx \n" ); _asm_pset( /* 書きこみ実行 */ "_skip_calc:\n" "\t xor ax, dx \n" "_skip_write:\n" "\t mov es:[bx], ax \n" /* 破壊したレジスタを復帰 */ "\t pop dx \n" "\t pop di \n" "\t pop es \n" "\t pop cx \n" "\t pop bx \n" "\t pop ax \n" ); _asm_pset( /* これで終わり */ "_skip:\n" "\t ret \n" ); _asm_pset( /* こんなところにデータ定義が */ "mask_data:\n" "\t db 80h, 40h, 20h, 10h, 08h, 04h, 02h, 01h\n" ); #ifdef FAST_PSET _asm_pset("offset_table:\n"); /* y座標オフセットテーブル */ _asm_pset("\t dw 0, 1, 2, 3, 4, 5, 6, 7 \n"); _asm_pset("\t dw 224, 225, 226, 227, 228, 229, 230, 231 \n"); _asm_pset("\t dw 448, 449, 450, 451, 452, 453, 454, 455 \n"); _asm_pset("\t dw 672, 673, 674, 675, 676, 677, 678, 679 \n"); _asm_pset("\t dw 896, 897, 898, 899, 900, 901, 902, 903 \n"); _asm_pset("\t dw 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127 \n"); _asm_pset("\t dw 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351 \n"); _asm_pset("\t dw 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1575 \n"); _asm_pset("\t dw 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799 \n"); _asm_pset("\t dw 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 \n"); _asm_pset("\t dw 2240, 2241, 2242, 2243, 2244, 2245, 2246, 2247 \n"); _asm_pset("\t dw 2464, 2465, 2466, 2467, 2468, 2469, 2470, 2471 \n"); _asm_pset("\t dw 2688, 2689, 2690, 2691, 2692, 2693, 2694, 2695 \n"); _asm_pset("\t dw 2912, 2913, 2914, 2915, 2916, 2917, 2918, 2919 \n"); _asm_pset("\t dw 3136, 3137, 3138, 3139, 3140, 3141, 3142, 3143 \n"); _asm_pset("\t dw 3360, 3361, 3362, 3363, 3364, 3365, 3366, 3367 \n"); _asm_pset("\t dw 3584, 3585, 3586, 3587, 3588, 3589, 3590, 3591 \n"); _asm_pset("\t dw 3808, 3809, 3810, 3811, 3812, 3813, 3814, 3815 \n"); #else /* FAST_PSET */ _asm_pset("offset_table:\n"); /* y座標オフセットテーブル */ _asm_pset("\t dw 0, 216, 432, 648, 864, 1080, 1296, 1512 \n"); _asm_pset("\t dw 1728, 1944, 2160, 2376, 2592, 2808, 3024, 3240 \n"); _asm_pset("\t dw 3456, 3672 \n"); #endif /* FAST_PSET */ } /* 以前のやつ */ #ifdef OLD_PSET_CODE void pset(int x, int y, int c) { _asm_pset( "\t cmp ax, 224 \n" "\t jnc _skip \n" "\t cmp bx, 144 \n" "\t jnc _skip \n" ); _asm_pset( /* 破壊するレジスタを退避 */ "\t push ax \n" /* 最適化で利用される場合があるので */ "\t push bx \n" "\t push cx \n" "\t push es \n" "\t push di \n" "\t push dx \n" ); _asm_pset( /* アドレスを計算 */ "\t mov di, ax \n" "\t and di, 0fff8h \n" "\t mov dx, bx \n" "\t and dx, 7 \n" "\t add di, dx \n" ); _asm_pset( /* ここから28倍 */ "\t and bx, 0fff8h \n" "\t mov dx, bx \n" "\t shl dx, 5 \n" "\t add bx, bx \n" "\t add bx, bx \n" "\t sub dx, bx \n" "\t add di, dx \n" "\t add di, di \n" /* アドレス計算終わり。 */ ); _asm_pset( /* マスクをゲット */ "\t mov bx, ax \n" "\t and bx, 7 \n" "\t add bx, bx \n" "\t add bx, mask_data \n" "\t mov bx, cs:[bx] \n" ); _asm_pset( /* 書きこみ先のデータを読み込む */ /* VRAMアドレスのオフセット? */ "\t mov ax, 0200h \n" /* テストするときはesを更新しない */ #ifndef PSET_TEST "\t mov es, ax \n" #endif "\t mov ax, es:[di] \n" "\t or ax, bx \n" ); _asm_pset( /* 書きこむ値の処理 */ "\t or cx, cx \n" "\t jz _skip_calc \n" ); _asm_pset( /* 書きこむ色が0でない場合 */ "\t add cx, 00feh \n" "\t and cx, 0101h \n" "\t add cx, 7f7fh \n" "\t xor cx, 8080h \n" "\t and bx, cx \n" ); _asm_pset( /* 書きこみ実行 */ "_skip_calc:\n" "\t xor ax, bx \n" "\t mov es:[di], ax \n" "\t jmp _end_pset \n" ); _asm_pset( /* こんなところにデータ定義が */ "mask_data:\n" "\t dw 8080h, 4040h, 2020h, 1010h, 0808h, 0404h, 0202h, 0101h\n" ); _asm_pset( /* 終了処理 */ "_end_pset:\n" ); _asm_pset( /* 破壊したレジスタを復帰 */ "\t pop dx \n" "\t pop di \n" "\t pop es \n" "\t pop cx \n" "\t pop bx \n" "\t pop ax \n" ); _asm_pset( /* これで終わり */ "_skip:\n" ); } #endif /* OLD_PSET_CODE */