comment $
	ARTemis (Graphic Editor for FM-TOWNS)
	(c) MATSUUCHI Ryosuke 1992,1993

	geasm.asm

  ルーチン一覧:

				ws_segment
				ws_pokew
				ws_peekw

				viewscr_down
				viewscr_sub

				xmemcpy
				xymemcpy
				xyzoommemcpy

				graypset
				graypset_list
				_graypset
				_graypset_list
				_graypset_sub

				MEMstoreword
				MEMstoreword_xor
$

				public	xmemcpy, xymemcpy, graypset, _graypset, _graypset_sub, graypset_list
				public	viewscr_sub,viewscr_down
				public	ws_segment, ws_pokew, ws_peekw
				public	MEMstoreword_xor, MEMstoreword
				public	pict_makeicon32k
				public	pict_makeicon16
				public	makeHLSgradline
				extrn	_wrtpage:dword, _nowscrmod:dword

				assume cs:cseg, ds:cseg

dseg segment

	oldint24p	dw	0
				dd	0
	oldint24r	dd	0

	wk0			dd	0
	wk1			dd	0
	wk2			dd	0

dseg ends


cseg segment

.comment @

;----------------------------------------------------------------------
;void ARTsetint24H(void)
;----------------------------------------------------------------------


__int24Hhandle	proc
				
				iret
				
__int24Hhandle	endp


ARTsetint24H	proc
				mov		ax,2502h	; INT 24h のネイティブ割り込みベクタを得る
				mov		cl,24h
				int		21h
				mov		ax,es
				mov		[oldint24p],ax
				mov		[oldint24p+4],ebx
				mov		ax,2503h	; INT 24h のリアル割り込みベクタを得る
				mov		cl,24h
				int		21h
				mov		[oldint24r],ebx
				mov		ax,2506h	; INT 24h の割り込みを常にネイティブで受ける
				mov		cl,24h
				mov		ax,cs
				mov		ds,ax
				mov		
				
ARTsetint24H	endp

;----------------------------------------------------------------------
;void ARTresetint24H(void)
;----------------------------------------------------------------------

@

;----------------------------------------------------------------------
;void pict_makeicon32k(char *grpbuf, int xlen, int ylen, char *bitbuf)
;----------------------------------------------------------------------


pict_makeicon32k proc
				cld
				pushfd							;+
				push	ebx						;++
				push	esi						;+++
				push	edi						;++++
				mov 	ax,es					; es := ds
				push	eax						;+++++
				mov 	ax,ds
				mov 	es,ax
				#para0 equ 4+20
				mov 	edi,[esp+#para0]		; edi : outputbuf-pointer
				mov 	esi,[esp+#para0+12] 	; esi : bitbuf-pointer
				mov 	ebx,[esp+#para0+8]		; ebx : y-counter(down)
				or		ebx,ebx
				jz		#loopend0
				#looptop0:
					mov 	ecx,[esp+#para0+4]	; ecx : x-counter(down)
					push	esi					;++++++
					#looptop1:
						mov 	dl,[esi]		; dl := bit pattern
						rept 4
						 sub	eax,eax
						 rol	dl,1
						 sbb	eax,0
						 sub	ax,ax
						 rol	dl,1
						 sbb	ax,0
						 rol	eax,16
						 not	eax
						 stosd
						 sub	ecx,2
						 jz 	#loopend1
						 jc 	#loopend1
						endm
						inc 	esi
					jmp #looptop1
					#loopend1:
					pop 	esi					;+++++
					mov 	ecx,[esp+#para0+4]	; ecx := (xlen+7)/8
					add 	ecx,7
					shr 	ecx,3
					add 	esi,ecx
					dec 	ebx
				jnz 	#looptop0
				#loopend0:
				pop 	eax						;++++
				mov 	es,ax
				pop 	edi						;+++
				pop 	esi						;++
				pop 	ebx						;+
				popfd							;
				ret
pict_makeicon32k endp


;----------------------------------------------------------------------
;void pict_makeicon16(char *grpbuf, int xlen, int ylen, char *bitbuf)
;----------------------------------------------------------------------


pict_makeicon16	proc
				;レジスタ退避
				pushfd
				push	ebx
				push	esi
				push	edi
				mov		ax,es
				push	eax
				mov		ax,ds
				mov		es,ax
				#para equ 4+20
				;
				mov		edi,[esp+#para]
				mov		esi,[esp+#para+12]
				mov		ebx,[esp+#para+8]			;ebx := y-counter(down)
				or		ebx,ebx
				jz		#loopend1
				#looptop1:
					mov		ecx,[esp+#para+4]		;ecx := x-counter(down)
					push	esi
					#looptop0:
						sub		eax,eax
						mov		dl,[esi]
						rept 4
							sub		dh,dh
							rol		dl,1
							sbb		dh,0
							and		dh,00eh
							or		al,dh
							sub		dh,dh
							rol		dl,1
							sbb		dh,0
							and		dh,0e0h
							or		al,dh
							ror		eax,8
						endm
						not		eax
						stosd
						sub		ecx,8
						jz		#loopend0
						jc		#loopend0
						inc		esi
					jmp	#looptop0
					#loopend0:
					pop		esi
					mov		ecx,[esp+#para+4]
					add		ecx,7
					shr		ecx,3
					add		esi,ecx
					dec	ebx
				jnz	#looptop1
				#loopend1:
				;レジスタ復帰
				pop		eax
				mov		es,ax
				pop		edi
				pop		esi
				pop		ebx
				popfd
				ret
pict_makeicon16	endp


;---------------------------------------------------------------
;void ws_segment(int seg)
;void ws_pokew(int ofs, int data)
;int  ws_peekw(int ofs)
;---------------------------------------------------------------


ws_segment		proc
				mov 	eax,[esp+4]
				mov 	fs,ax
				ret
ws_segment		endp


ws_pokew		proc
				mov 	eax,[esp+4]
				mov 	ecx,[esp+8]
				mov 	fs:[eax],cx
				ret
ws_pokew		endp


ws_peekw		proc
				sub 	eax,eax
				mov 	ecx,[esp+4]
				mov 	ax,fs:[eax]
				ret
ws_peekw		endp


;---------------------------------------------------------------
;void viewscr_down(char *d_adrs, char *s_adrs, char *cmd)
;---------------------------------------------------------------

viewscr_down	proc
				pushfd
				push	ebx
				push	esi
				push	edi
				cld
#para	equ 	4*4+4
				mov 	edi,[esp+#para]
				mov 	esi,[esp+#para+4]
				mov 	edx,[esp+#para+8]
				mov 	eax,80000000h
				xor 	ecx,ecx
				#6:
						mov 	cl,ds:[edx]
						inc 	edx
						jmp 	[#jmptbl+ecx*4]
				#5:
				pop 	edi
				pop 	esi
				pop 	ebx
				popfd
				ret
#shift4bit:
				shr 	ebx,4
				jmp 	#6
#shift8bit:
				shr 	ebx,8
				jmp 	#6
#shift12bit:
				shr 	ebx,12
				jmp 	#6
#shift16bit:
				shr 	ebx,16
				jmp 	#6
#shift20bit:
				shr 	ebx,20
				jmp 	#6
#shift24bit:
				shr 	ebx,24
				jmp 	#6
#store4bit:
				shrd	eax,ebx,4
				jnc 	#6
				mov 	ds:[edi],eax
				add 	edi,4
				mov 	eax,80000000h
				jmp 	#6
#store8bit:
				shrd	eax,ebx,8
				jnc 	#6
				mov 	ds:[edi],eax
				add 	edi,4
				mov 	eax,80000000h
				jmp 	#6
#store12bit:
				shrd	eax,ebx,12
				jnc 	#6
				mov 	ds:[edi],eax
				add 	edi,4
				mov 	eax,80000000h
				jmp 	#6
#getnewDW:
				mov 	ebx,ds:[esi]
				add 	esi,4
				jmp 	#6

#jmptbl 		dd		#5,#store4bit,#shift4bit,#getnewDW
				;		0	1		   2		  3
				dd		#shift8bit,#shift12bit,#shift16bit
				;		 4			5			6
				dd		#store8bit,#store12bit,#shift20bit,#shift24bit
				;		 7			8			9			 10

viewscr_down	endp



;---------------------------------------------------------------
;void viewscr_sub(d_seg, d_adrs, char *s_adrs, char *cmd)
;---------------------------------------------------------------


viewscr_sub 	proc
				pushfd
				push	ebx
				push	esi
				push	edi
				mov 	bx,es
				push	ebx
				cld
#para	equ 	4*5+4
				mov 	eax,[esp+#para]
				mov 	es,ax
				mov 	edi,[esp+#para+4]
				mov 	esi,[esp+#para+8]
				mov 	edx,[esp+#para+12]
				mov 	eax,80000000h
				#6:
						xor 	ecx,ecx
						mov 	cl,ds:[edx]
						inc 	edx
						jmp 	[#jmptbl+ecx*4]
						
						
;						cmp 	cl,2			;転送元 DW を右４ビットシフト
;						jnz 	#0
;								shr 	ebx,4
;								jmp 	#1
;						#0:
;						cmp 	cl,1			;[転送元DW:転送先DW]を右４ビットシフト
;						jnz 	#2
;								shrd	eax,ebx,4
;								jnc 	#3
;										stosd
;										mov 	eax,80000000h
;								#3:
;								jmp 	#1
;						#2:
;						cmp 	cl,3			;転送元DW を新たに読み込む
;						jnz 	#4
;								xchg	eax,ebx
;								lodsd
;								xchg	eax,ebx
;								jmp 	#1
;						#4:
;								jmp 	#5				;終了
;						#1:
;						inc 	edx
;				jmp 	#6


				#5:
				pop 	ebx
				mov 	es,bx
				pop 	edi
				pop 	esi
				pop 	ebx
				popfd
				ret


#shift4bit:
				shr 	ebx,4
				jmp 	#6
#store4bit:
				shrd	eax,ebx,4
				jnc 	#6
				stosd
				mov 	eax,80000000h
				jmp 	#6

#getnewDW:
				xchg	eax,ebx
				lodsd
				xchg	eax,ebx
				jmp 	#6

#jmptbl 		dd		#5,#store4bit,#shift4bit,#getnewDW




viewscr_sub 	endp



;---------------------------------------------------------------
;void xmemcpy(d_seg, d_adrs, s_seg, s_adrs, length)
;---------------------------------------------------------------


xmemcpy 		proc
				pushfd							;フラグ保存
				cld
				push	ecx 					;ecx 保存
				push	esi 					;esi 保存
				push	edi 					;edi 保存
				mov 	cx,es					;es 保存
				push	ecx
				mov 	cx,ds					;ds 保存
				push	ecx
#para			equ 	((4*6)+4)
				mov 	ecx,ss:[esp+#para]		;es ← d_seg
				mov 	es,cx
				mov 	edi,ss:[esp+#para+4]	;edi ← d_adrs
				mov 	ecx,ss:[esp+#para+8]	;ds ← s_seg
				mov 	ds,cx
				mov 	esi,ss:[esp+#para+12]	;esi ← s_adrs
				mov 	ecx,ss:[esp+#para+16]	;ecx ← length
				mov 	eax,ecx 				;eax ← ecx (カウンタ保存)
				shr 	ecx,2
				or		ecx,ecx
				jz		#0
				rep movsd
#0: 			mov 	ecx,eax
				and 	ecx,3
				jz		#1
				rep movsb
#1: 			pop 	ecx 					;ds 復帰
				mov 	ds,cx
				pop 	ecx 					;es 復帰
				mov 	es,cx
				pop 	edi 					;edi 復帰
				pop 	esi 					;esi 復帰
				pop 	ecx 					;ecx 復帰
				popfd							;フラグ復帰
				ret
xmemcpy 		endp



;---------------------------------------------------------------
;void xymemcpy( d_seg, d_adrs, s_seg, s_adrs, x_cnt, y_cnt,
;				  0 	 1		 2		3		4		5
;				d_y_adrs_add, s_y_adrs_add
;					  6 			7
;---------------------------------------------------------------

xymemcpy		proc
				pushfd							;フラグ,edi,esi,ds,esを保存
				push	edi
				push	esi
				mov 	ax,ds
				push	eax
				mov 	ax,es
				push	eax
#para	equ 	4+20
				cld
				mov 	eax,[esp+#para] 		;es:edi ← 転送先アドレス
				mov 	es,ax
				mov 	edi,[esp+#para+4]
				mov 	eax,[esp+#para+8]		;ds:esi ← 転送元アドレス
				mov 	ds,ax
				mov 	esi,[esp+#para+12]
				mov 	edx,[esp+#para+20]		;edx ← Y 方向カウンタ
				#0:
						or		edx,edx
						jz		#1
						mov 	ecx,[esp+#para+16]		;ecx ← X 方向カウンタ
						push	edi
						push	esi
						push	ecx
						shr 	ecx,2					;まず 4 バイトづつ転送
						rep movsd
						pop 	ecx
						and 	ecx,11b
						rep movsb						;残りの0〜3バイトを転送
						pop 	esi
						pop 	edi
						add 	edi,[esp+#para+24]		;転送先アドレス増加
						add 	esi,[esp+#para+28]		;転送元アドレス増加
						dec 	edx
				jmp 	#0
				#1:
				pop 	eax 					;フラグ,edi,esi,ds,esを復帰
				mov 	es,ax
				pop 	eax
				mov 	ds,ax
				pop 	esi
				pop 	edi
				popfd
				ret
xymemcpy		endp


xyzoommemcpy	proc


				
				lodsd							;ebx ← 転送元データ
				mov 	ebx,eax
				mov 	eax,00000001h			;eax ← 転送先データ
				mov 	ch,8					;ch ← 転送元・ニブルカウンタ
				mov 	cl,2					;cl ← 縮小カウンタ


				dec 	cl
				jnz 	#3
						mov 	cl,2
						shld	eax,ebx,4
						jnc 	#1
								stosd
								mov 	eax,00000001h
						#1:
						jmp 	#4
				#3:
						shl 	ebx,4
				#4:
				dec 	ch
				jnz 	#2
						mov 	ch,8
						xchg	eax,ebx
						lodsd
						xchg	eax,ebx
				#2:



				ret
xyzoommemcpy	endp


				align	4

gray			dd		0
pageadr 		dd		0
rgb1			dd		0
				dd		0
				dd		0
rgb0			dd		0
				dd		0
				dd		0
rgb_			dd		0
				dd		0
				dd		0
score			dd		0
				dd		0
				dd		0
score_q 		dd		0
color			dd		0
vramsel 		dd		0


graypset		proc
				push	ebx
				push	esi
				push	edi
				pushfd
				mov 	eax,[esp+16+4]
				mov 	ebx,[esp+16+8]
				mov 	ecx,[esp+16+12]
				mov 	edx,[esp+16+16]
				call	_graypset
				popfd
				pop 	edi
				pop 	esi
				pop 	ebx
				ret
graypset		endp


graypset_list	proc
		;void graypset_list(struct {int x,y,col,gray} *listp);
				push	ebx
				push	esi
				push	edi
				pushfd
				mov 	eax,[esp+16+4]
				call	_graypset_list
				popfd
				pop 	edi
				pop 	esi
				pop 	ebx
				ret
graypset_list	endp


_graypset		proc
;		in eax:x ebx:y ecx:color edx:gray
				push	es
				mov 	edi,[_nowscrmod]
				cmp 	edi,10
				jne 	#mode_not10
						;★mode 10
						mov 	di,104h 		;es ← VRAM セレクタ
						mov 	es,di
						mov 	[pageadr],0
						cmp 	[_wrtpage],0
						je		#0
								mov 	[pageadr],40000h
						#0:
						call	_graypset_sub
						jmp 	#endcase_mode
				#mode_not10:
				cmp 	edi,17
				jne 	#endcase_mode
						;★mode 17
						mov 	di,10ch 		;es ← VRAM セレクタ
						mov 	es,di
						mov 	[pageadr],0
						call	_graypset_sub
				#endcase_mode:
				pop 	es
				ret
_graypset		endp


_graypset_list	proc
		;in  eax:リストへのポインタ
		;	 (リスト要素:  x,y,col,gray    終端:gray=0ffffffffh)

				push	es

				mov 	esi,[_nowscrmod]
				cmp 	esi,10
				jne 	#mode_not10
						;★mode 10
						mov 	si,104h
						mov 	es,si
						mov 	[pageadr],0
						cmp 	[_wrtpage],0
						je		#2
								mov 	[pageadr],40000h
						#2:
						jmp 	#endcase_mode
				#mode_not10:
						;★mode 17
						mov 	si,10ch
						mov 	es,si
						mov 	[pageadr],0
				#endcase_mode:

				mov 	esi,eax
				#0:
						mov 	eax,[esi]
						mov 	ebx,[esi+4]
						mov 	ecx,[esi+8]
						mov 	edx,[esi+12]
						cmp 	edx,0ffffffffh
						je		#1
						push	esi
						call	_graypset_sub
						pop 	esi
						add 	esi,16
				jmp 	#0
				#1:

				pop 	es
				ret

_graypset_list	endp


_graypset_sub	proc

;		in eax:x, ebx:y, ecx:color, edx:gray(0..256)
;		   [pageadr], es(VRAM selector)

				mov 	[gray],edx
				mov 	[color],ecx
				mov 	edi,[_nowscrmod]
				cmp 	edi,10
				je		#graypset_32K
				cmp 	edi,17
				je		#graypset_32K

#graypset_16:
				cmp 	edx,0
				je		#end
		;アドレス計算→ ebx
				shl 	ebx,9			;ebx := (y*512 + x/2) & 0xfffffffc;
				mov 	edi,eax
				shr 	edi,1
				add 	ebx,edi
				and 	ebx,0fffffffch
				add 	ebx,[pageadr]
		;マスク算出→ eax、カラーシフト→ edx
				mov 	ecx,eax
				and 	ecx,111b
				shl 	ecx,2
				mov 	eax,1111b
				shl 	eax,cl
				mov 	edx,[color]
				and 	edx,1111b
				shl 	edx,cl
		;ドット書き込み
				mov 	edi,es:[ebx]
				not 	eax
				and 	edi,eax
				not 	eax
				or		edi,edx
				mov 	es:[ebx],edi
				jmp 	#end

#graypset_32K:
		;アドレス計算→ ebx
				shl 	ebx,10			;ebx := y*1024 + x*2 + [pageadr]
				add 	ebx,eax
				add 	ebx,eax
				add 	ebx,[pageadr]
		;濃度の特例により分岐
				cmp 	edx,256
				je		#gray256
				cmp 	edx,0
				je		#end
		;(濃度 1..255 による描画)
		;目的色の三原色を抽出
				mov 	eax,ecx 		;eax ← 目的色
				and 	eax,1fh
				mov 	[rgb1+8],eax	;blue
				shr 	ecx,5			;目的色を右に5ビットシフト
				mov 	eax,ecx
				and 	eax,1fh
				mov 	[rgb1],eax		;red
				shr 	ecx,5
				mov 	eax,ecx
				and 	eax,1fh
				mov 	[rgb1+4],eax	;green
		;元色の三原色を抽出
				mov 	cx,es:[ebx]
				mov 	eax,ecx
				and 	eax,1fh
				mov 	[rgb0+8],eax	;blue
				shr 	ecx,5
				mov 	eax,ecx
				and 	eax,1fh
				mov 	[rgb0],eax		;red
				shr 	ecx,5
				mov 	eax,ecx
				and 	eax,1fh
				mov 	[rgb0+4],eax	;green
		;各原色についての評価値を計算
				mov 	ecx,0
				#0:
						mov 	eax,[rgb0+ecx*4]		;score = abs(rgb0-rgb1)
						sub 	eax,[rgb1+ecx*4]
						jnc 	#1
								neg 	eax
						#1:
						mov 	[score+ecx*4],eax
						inc 	ecx
						cmp 	ecx,3
				jl		#0
		;評価基準値の決定 (評価値が全て同じの場合は特例処理)
				mov 	eax,[score]
				cmp 	eax,[score+4]
				jne 	#2
				cmp 	eax,[score+8]
				jne 	#2
					;(評価値がすべて同じの場合)
					;評価値←元色の原色値  ,   評価基準値←評価値の最小値
						mov 	eax,[rgb0]
						mov 	[score],eax
						mov 	ecx,[rgb0+4]
						mov 	[score+4],ecx
						cmp 	eax,ecx
						jle 	#3
								mov 	eax,ecx
						#3:
						mov 	ecx,[rgb0+8]
						mov 	[score+8],ecx
						cmp 	eax,ecx
						jle 	#4
								mov 	eax,ecx
						#4:
						jmp 	#5
				#2:
					;(評価値がすべて同じではない場合)
					;評価基準値←評価値の最大値
						mov 	eax,[score]
						mov 	ecx,[score+4]
						cmp 	eax,ecx
						jge 	#6
								mov 	eax,ecx
						#6:
						mov 	ecx,[score+8]
						cmp 	eax,ecx
						jge 	#7
								mov 	eax,ecx
						#7:
				#5:
				mov 	[score_q],eax
		;描画色の決定
				mov 	ecx,0
				#8:
						mov 	eax,[rgb0+ecx*4]
						cmp 	eax,[rgb1+ecx*4]
						jne 	#9
								mov 	[rgb_+ecx*4],eax
								jmp 	#10
						#9:
								mov 	edx,[score+ecx*4]
								cmp 	edx,[score_q]
								jne 	#11
										cmp 	eax,[rgb1+ecx*4]
										mov 	eax,0
										jge 	#12
												mov 	eax,255
										#12:
										jmp 	#13
								#11:
										mov 	eax,128
								#13:
								push	eax 	;補正値の保存
								mov 	eax,[rgb1+ecx*4]
								mov 	edx,[gray]
								mul 	edx 	;edx:eax := edx * eax
								mov 	edi,eax
								mov 	eax,[rgb0+ecx*4]
								mov 	edx,[gray]
								neg 	edx
								add 	edx,256
								mul 	edx 	;edx:eax := edx * eax
								add 	eax,edi
								pop 	edx
								add 	eax,edx
								shr 	eax,8
								cmp 	eax,[rgb0+ecx*4]
								jne 	#20
										mov 	edx,[rgb0+ecx*4]
										cmp 	edx,[rgb1+ecx*4]
										jg		#21
										je		#22
												inc 	eax
												jmp 	#22
										#21:
												dec 	eax
										#22:
								#20:
								mov 	[rgb_+ecx*4],eax
						#10:
						inc 	ecx
						cmp 	ecx,3
				jl		#8
		;描画
				mov 	eax,[rgb_+4]
				shl 	eax,5
				or		eax,[rgb_]
				shl 	eax,5
				or		eax,[rgb_+8]
				and 	eax,7fffh
				mov 	es:[ebx],ax
				jmp 	#end
#gray256:
		;濃度256(混合無し)による描画
				and 	ecx,7fffh
				mov 	es:[ebx],cx
#end:
				ret

#debugpset:
				mov 	ecx,[color]
				mov 	es:[ebx],cx
				ret

_graypset_sub	endp


;------------------------------------------------------------------
;	 ワード単位・メモリアクセスルーチン群
;------------------------------------------------------------------

;void MEMstoreword_xor(int seg, char *top_adrs, int data, int cnt)
;void MEMstoreword(int seg, char *top_adrs, int data, int cnt)

MEMstoreword	proc
				mov 	ax,es
				push	eax
				push	ebx
				push	edi
				pushfd
				cld
				mov 	eax,[esp+4+16]			;seg
				mov 	es,ax
				mov 	edi,[esp+4+16+4]		;top_adrs
				mov 	eax,[esp+4+16+8]		;data
				mov 	ecx,[esp+4+16+12]		;cnt
				or		ecx,ecx
				jz		#0
				rep stosw		;[ES:DI]:=AX,DI+=2, repeat until CX=0
#0: 			popfd
				pop 	edi
				pop 	ebx
				pop 	eax
				mov 	es,ax
				ret
MEMstoreword	endp

MEMstoreword_xor proc
				mov 	ax,es
				push	eax
				push	ebx
				push	edi
				pushfd
				cld
				mov 	eax,[esp+4+16]			;seg
				mov 	es,ax
				mov 	edi,[esp+4+16+4]		;top_adrs
				mov 	eax,[esp+4+16+8]		;data
				mov 	ecx,[esp+4+16+12]		;cnt
				;８ワードずつ処理
				mov 	ebx,ecx
				shr 	ebx,3
				#2:
						or		ebx,ebx
						jz		#1
						xor 	es:[edi   ],ax
						xor 	es:[edi+ 2],ax
						xor 	es:[edi+ 4],ax
						xor 	es:[edi+ 6],ax
						xor 	es:[edi+ 8],ax
						xor 	es:[edi+10],ax
						xor 	es:[edi+12],ax
						xor 	es:[edi+14],ax
						add 	edi,16
						dec 	ebx
				jmp 	#2
				#1:
				;のこりの０〜７ワードを処理
				and 	ecx,7
				#3:
						or		ecx,ecx
						jz		#4
						xor 	es:[edi],ax
						inc 	edi
						inc 	edi
						dec 	ecx
				jmp 	#3
				#4:
				;後処理
				popfd
				pop 	edi
				pop 	ebx
				pop 	eax
				mov 	es,ax
				ret
MEMstoreword_xor endp


;---------------------------------------------------------------
;	makeHLSgradline(char *gbuf,len,r1,g1,b1,rr,gr,br)
;		HLS 三角形描画時のグラデーション作成補助ルーチン
;
;	gbuf からの len ドット分を、始点色(r1,g1,b1), 傾き(rr,gr,br)
;	のグラデーションで埋める
;	r1,g1,b1,rr,gr,br は10ビット固定小数点数。
;		for (i=0; i<l; i++, sr+=sr_r,sg+=sg_r,sb+=sb_r)
;			gbuf[i] = GRB(sg>>DECIMAL,sr>>DECIMAL,sb>>DECIMAL);
;---------------------------------------------------------------

makeHLSgradline	proc
				pushfd
				push	ebx
				push	edi
				push	esi
				#para equ 20
				mov		edi,ss:[esp+#para+0]
				mov		esi,ss:[esp+#para+4]
				mov		ebx,ss:[esp+#para+12]
				mov		ecx,ss:[esp+#para+8]
				mov		edx,ss:[esp+#para+16]
				mov		eax,ss:[esp+#para+24]
				mov		ds:[wk0],eax
				mov		eax,ss:[esp+#para+20]
				mov		ds:[wk1],eax
				mov		eax,ss:[esp+#para+28]
				mov		ds:[wk2],eax
				inc		esi
				#1:
					dec		esi
					jz		#0
					sub		eax,eax
					ror		ebx,10		;G
					add		ax,bx
					rol		ebx,10
					shl		eax,5
					ror		ecx,10		;R
					add		ax,cx
					rol		ecx,10
					shl		eax,5
					ror		edx,10		;B
					add		ax,dx
					rol		edx,10
					mov		[edi],ax
					add		edi,2
					add		ebx,ds:[wk0]	;G:=G+dG
					add		ecx,ds:[wk1]	;R:=R+dR
					add		edx,ds:[wk2]	;B:=B+dB
				jmp		#1
				#0:
				pop		esi
				pop		edi
				pop		ebx
				popfd
				ret
makeHLSgradline	endp


cseg ends

end
