;	私製ライブラリ・グラフィック篇
;	(c) MATSUUCHI Ryosuke in Dec,1992
;
;	ghvline.asm
;
;	1992. 7. 9(Thu)
;	1992. 7.16(Thu)
;	1992. 8. 2(Sun)
;	1992.12.28(Sun)

		public	ghline,gvline,_ghline,_gvline
		extrn	_gwrtreg:near
		extrn	__AddVramBase_edi	:near
		extrn	__SetVramSeg		:near
		extrn	__AddVramBase_ebx	:near
		extrn	__AddVramBase_esi	:near
		
		include	grplib.inc
		
		assume	cs:cseg, ds:dseg



dseg segment dword 'DATA'

		align 4

logop		dd	0

collist		dd	000000000h
		dd	011111111h
		dd	022222222h
		dd	033333333h
		dd	044444444h
		dd	055555555h
		dd	066666666h
		dd	077777777h
		dd	088888888h
		dd	099999999h
		dd	0aaaaaaaah
		dd	0bbbbbbbbh
		dd	0cccccccch
		dd	0ddddddddh
		dd	0eeeeeeeeh
		dd	0ffffffffh

Lmaskpat	dd	0ffffffffh
		dd	0fffffff0h
		dd	0ffffff00h
		dd	0fffff000h
		dd	0ffff0000h
		dd	0fff00000h
		dd	0ff000000h
		dd	0f0000000h
		dd	000000000h

Rmaskpat	dd	00000000fh
		dd	0000000ffh
		dd	000000fffh
		dd	00000ffffh
		dd	0000fffffh
		dd	000ffffffh
		dd	00fffffffh
		dd	0ffffffffh

vmask		dd	00000000fh
		dd	0000000f0h
		dd	000000f00h
		dd	00000f000h
		dd	0000f0000h
		dd	000f00000h
		dd	00f000000h
		dd	0f0000000h

dseg ends



cseg segment dword 'CODE'

;---------------------------------------------------------------
;	gvline : 垂直直線の描画
;		in  eax:x
;		    ebx:y1
;		    ecx:y2
;		    edx:col
;		    esi:logop
;
;	void gvline(int x, int y1,int y2,int col, int logop);
;---------------------------------------------------------------

		align 4

gvline		proc near
		push	ebx
		push	esi
		push	edi
		pushfd
		mov	eax,[esp+16+4]		;x
		mov	ebx,[esp+16+8]		;y1
		mov	ecx,[esp+16+12]		;y2
		mov	edx,[esp+16+16]		;col
		mov	esi,[esp+16+20]		;logop
		call	_gvline
		popfd
		pop	edi
		pop	esi
		pop	ebx
		ret
gvline		endp



		align 4

_gvline		proc near
		pushad
		push	es
		mov	edi,[_nowscrmod]
		cmp	di,2			;di の値により分岐
		jle	#end
		cmp	di,4
		jg	#1
		call	gvline16
		jmp	#end
#1:		cmp	di,8
		jg	#2
		call	gvline32a
		jmp	#end
#2:		cmp	di,11
		jg	#3
		call	gvline32b
		jmp	#end
#3:		cmp	di,14
		jg	#4
		call	gvline256
		jmp	#end
#4:		cmp	di,18
		jg	#end
		call	gvline32c
#end:		pop	es
		popad
		ret
_gvline		endp





;● VLINE のサブルーチン (16色 VLINE)
;----------------------------------------------------------------------------


gvline16	proc near
		mov	[logop],esi		;[logop]←logop
		cmp	ebx,ecx			;ebx←min(y1,y2)
		jc	#0			;ecx←max(y1,y2)
		xchg	ebx,ecx
#0:		or	esi,esi			;演算指定が NORMAL でないなら
		jnz	#notNORMALmode		;分岐
	;
	;--- 演算指定が NORMAL の場合
	;
	;edi ← アドレス
		mov	esi,eax
		and	esi,0fffffff8h
		shr	esi,1
		mov	edi,ebx
		shl	edi,9
		add	edi,esi
		call	__AddVramBase_edi
	;割り込みの禁止
		cli
	;esi ← マスクパターン(どの４ビットを有効にするか)
		mov	esi,eax
		and	esi,7
		mov	esi,[vmask+esi*4]
	;描画処理
		call	__SetVramSeg		;es ← VRAM セレクタ
		sub	ecx,ebx			;ecx ← 縦方向の長さ
		inc	ecx
		mov	eax,[collist+edx*4]	;eax ← カラーデータ
		and	eax,esi
		not	esi			;マスクビット反転
		mov	ebx,512			;ebx ← アドレス増加分
		;---- まず､ 12 dot づつまとめて描画する
		sub	ecx,12
		jl	#200
			#201:
				rept 4
				 mov	edx,es:[edi]
				 and	edx,esi
				 or	edx,eax
				 mov	es:[edi],edx
				 mov	edx,es:[edi+ebx]
				 and	edx,esi
				 or	edx,eax
				 mov	es:[edi+ebx],edx
				 mov	edx,es:[edi+ebx*2]
				 and	edx,esi
				 or	edx,eax
				 mov	es:[edi+ebx*2],edx
				 lea	edi,[edi+ebx*2]	  ;edi ← edi + ebx*3
				 add	edi,ebx
				endm
				sub	ecx,12
			jge	#201
		#200:
		add	ecx,12
		;---- 残りを描画する(現在 ecx は 11 以下)
		or	ecx,ecx
		jz	#202
			rept 4
			 mov	edx,es:[edi]
			 and	edx,esi
			 or	edx,eax
			 mov	es:[edi],edx
			 dec	ecx
			 jz	#202
			 mov	edx,es:[edi+ebx]
			 and	edx,esi
			 or	edx,eax
			 mov	es:[edi+ebx],edx
			 dec	ecx
			 jz	#202
			 mov	edx,es:[edi+ebx*2]
			 and	edx,esi
			 or	edx,eax
			 mov	es:[edi+ebx*2],edx
			 dec	ecx
			 jz	#202
			 lea	edi,[edi+ebx*2]	  ;edi ← edi + ebx*3
			 add	edi,ebx
			endm
		#202:
	;割り込みの許可
		sti
		jmp	#end
	;
	;--- 演算指定が XOR の場合
	;
#notNORMALmode:
	;edi ← アドレス
		mov	esi,eax
		and	esi,0fffffff8h
		shr	esi,1
		mov	edi,ebx
		shl	edi,9
		add	edi,esi
		call	__AddVramBase_edi
	;eax ← カラーデータ & マスク
		mov	esi,eax			;esi ← マスクパターン
		and	esi,7
		mov	esi,[vmask+esi*4]
		mov	eax,[collist+edx*4]	;eax ← カラーデータ
		and	eax,esi
	;描画処理
		call	__SetVramSeg		;es ← vram セレクタ
		sub	ecx,ebx			;ecx ← 縦方向の長さ
		inc	ecx
		mov	ebx,512			;ebx ← アドレス増分
		lea	esi,[ebx+ebx*2]		;esi ← 3 回ごとのアドレス増分
		;---- まず､12 dot ずつまとめて描画する
		sub	ecx,12
		jl	#102
			#101:
				rept 4
				 xor	es:[edi      ],eax
				 xor	es:[edi+ebx  ],eax
				 xor	es:[edi+ebx*2],eax
				 add	edi,esi
				endm
				sub	ecx,12
			jge	#101
		#102:
		add	ecx,12
		;---- のこりを描画する
		or	ecx,ecx
		jz	#203
			rept 4
			 xor	es:[edi],eax
			 dec	ecx
			 jz	#203
			 xor	es:[edi+ebx],eax
			 dec	ecx
			 jz	#203
			 xor	es:[edi+ebx*2],eax
			 dec	ecx
			 jz	#203
			 add	edi,esi
			endm
		#203:
	;
	;おわり
	;
#end:
		ret
gvline16	endp


;● VLINE のサブルーチン (３万色 VLINE [256*512ドットモード])
;----------------------------------------------------------------------------


gvline32a	proc near
		cmp	ebx,ecx			;ebx←min(y1,y2)
		jc	#1			;ecx←max(y1,y2)
			xchg	ebx,ecx
		#1:
	;es:edi ← アドレス
		mov	edi,ebx
		shl	edi,9
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画の準備
		mov	ax,dx		;ax ← カラーデータ
		and	ax,7fffh
		sub	ecx,ebx		;ecx ← 長さ
		inc	ecx
		mov	ebx,512		;ebx ← アドレスの増分
		lea	edx,[ebx+ebx*2]	;edx ← アドレスの増分(3ライン分)
	;描画
		call	gvline32_sub
	;おわり
		ret
gvline32a	endp


;● VLINE のサブルーチン (３万色 VLINE [512*256ドットモード])
;----------------------------------------------------------------------------


gvline32b	proc near
		cmp	ebx,ecx			;ebx←min(y1,y2)
		jc	#1			;ecx←max(y1,y2)
			xchg	ebx,ecx
		#1:
	;es:edi ← アドレス
		mov	edi,ebx
		shl	edi,10
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画の準備
		mov	ax,dx		;ax ← カラーデータ
		and	ax,7fffh
		sub	ecx,ebx		;ecx ← 長さ
		inc	ecx
		mov	ebx,1024	;ebx ← アドレスの増分
		lea	edx,[ebx+ebx*2]	;edx ← アドレスの増分(3ライン分)
	;描画
		call	gvline32_sub
	;おわり
		ret
		ret
gvline32b	endp


;● VLINE のサブルーチン (256色 VLINE)
;----------------------------------------------------------------------------


gvline256	proc
		;★まだ作ってないよーん
		ret
gvline256	endp


;● VLINE のサブルーチン (３万色 VLINE [512*512ドットモード])
;----------------------------------------------------------------------------


gvline32c	proc
		cmp	ebx,ecx			;ebx←min(y1,y2)
		jc	#1			;ecx←max(y1,y2)
			xchg	ebx,ecx
		#1:
	;es:edi ← アドレス
		mov	edi,ebx
		shl	edi,10
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画の準備
		mov	ax,dx		;ax ← カラーデータ
		and	ax,7fffh
		sub	ecx,ebx		;ecx ← 長さ
		inc	ecx
		mov	ebx,1024	;ebx ← アドレスの増分
		lea	edx,[ebx+ebx*2]	;edx ← アドレスの増分(3ライン分)
	;描画
		call	gvline32_sub
	;おわり
		ret
gvline32c	endp


;● ３万色 VLINE のサブルーチン
;----------------------------------------------------------------------------


		align 4

gvline32_sub	proc near
		;
		;3万色モードの縦ライン･ 実際の描画を行うサブルーチン
		;
		;	in  es:edi  アドレス
		;	    ecx     長さ
		;	    ax      カラーデータ
		;	    ebx     1ライン分のアドレス増分
		;	    edx     3ライン分のアドレス増分
		;	    esi     演算指定
		;
		cmp	esi,0
		jnz	#1

			;---- NORMAL drawing
			sub	ecx,12
			jl	#4
				#3:
					rept 4
					 mov	es:[edi],ax
					 mov	es:[edi+ebx],ax
					 mov	es:[edi+ebx*2],ax
					 add	edi,edx
					endm
					sub	ecx,12
				jge	#3
			#4:
			add	ecx,12
			je	#5
				rept 4
				 mov	es:[edi],ax
				 dec	ecx
				 jz	#5
				 mov	es:[edi+ebx],ax
				 dec	ecx
				 jz	#5
				 mov	es:[edi+ebx*2],ax
				 dec	ecx
				 jz	#5
				 add	edi,edx
				endm
			#5:
			jmp	#2
		#1:

			;---- XOR drawing
			sub	ecx,12
			jl	#7
				#8:
					rept 4
					 xor	es:[edi],ax
					 xor	es:[edi+ebx],ax
					 xor	es:[edi+ebx*2],ax
					 add	edi,edx
					endm
					sub	ecx,12
				jge	#8
			#7:
			add	ecx,12
			je	#9
				rept 4
				 xor	es:[edi],ax
				 dec	ecx
				 jz	#9
				 xor	es:[edi+ebx],ax
				 dec	ecx
				 jz	#9
				 xor	es:[edi+ebx*2],ax
				 dec	ecx
				 jz	#9
				 add	edi,edx
				endm
			#9:
		#2:
		ret
gvline32_sub	endp



;---------------------------------------------------------------
;	ghline : 水平直線の描画
;		in  eax:x1
;		    ebx:x2
;		    ecx:y
;		    edx:col
;		    esi:logop
;
;	void ghline(int x1,int x2,int y1,int col,int logop);
;---------------------------------------------------------------



		align 4

ghline		proc near
		push	ebx
		push	edi
		push	esi
		pushfd
		mov	eax,[esp+16+4]		;x1
		mov	ebx,[esp+16+8]		;x2
		mov	ecx,[esp+16+12]		;y
		mov	edx,[esp+16+16]		;col
		mov	esi,[esp+16+20]		;logop
		call	_ghline
		popfd
		pop	esi
		pop	edi
		pop	ebx
		ret
ghline		endp



		align	4

_ghline		proc near
		pushad
		push	es
		cmp	eax,ebx			;eaxに左端,ebxに右端
		jb	#0
		xchg	eax,ebx
#0:		mov	edi,[_nowscrmod]	;画面モードにより分岐
		cmp	di,2
		jle	#end
		cmp	di,4
		jg	#1
		call	ghline16
		jmp	#end
#1:		cmp	di,8
		jg	#2
		call	ghline32a
		jmp	#end
#2:		cmp	di,11
		jg	#3
		call	ghline32b
		jmp	#end
#3:		cmp	di,14
		jg	#4
		call	ghline256
		jmp	#end
#4:		cmp	di,18
		jg	#end
		call	ghline32c
#end:		pop	es
		popad
		ret
_ghline		endp





;● HLINE のサブルーチン (16色モード)
;----------------------------------------------------------------------------


ghline16	proc near
		pushad
		;
		mov	[logop],esi
		cmp	eax,ebx
		jb	#0
		xchg	eax,ebx
#0:		mov	esi,eax			;x1,x2 が同じ dword 内に		
		and	esi,0fffffff8h		;あるかどうか調べる
		mov	edi,ebx
		and	edi,0fffffff8h
		cmp	esi,edi
		jnz	#1
		;
		;	//// x1,x2 が同じdword内にある場合の処理
		;
		shl	ecx,9			;ecx に VRAM のアドレスを入れる
		mov	esi,eax
		and	esi,0fffffff8h
		shr	esi,1
		add	esi,ecx
		call	__AddVramBase_esi
		mov	ecx,esi
		mov	edi,eax			;esi にマスクパターンを入れる
		and	edi,000000007h
		mov	esi,[Lmaskpat+edi*4]
		mov	edi,ebx
		and	edi,000000007h
		and	esi,[Rmaskpat+edi*4]
		mov	edx,[collist+edx*4]	;edx にカラーデータを入れる
		and	edx,esi
		mov	eax,[logop]		;eax に演算指定を入れる
		push	es			;es 保存
		call	__SetVramSeg		;es に VRAM のセレクタを入れる
		or	eax,eax			;演算指定により分岐する
		jnz	#2
		mov	eax,es:[ecx]
		not	esi
		and	eax,esi
		or	eax,edx
		mov	es:[ecx],eax
		jmp	#4
#2:		xor	es:[ecx],edx
#4:		pop	es			;es 復帰
		jmp	#end
#1:		;
		;	//// x1,x2が違うdword 内にある時の処理
		;
	;es←VRAMセレクタ
		call	__SetVramSeg
	;ecx←アドレス
		shl	ecx,9
		mov	esi,eax
		and	esi,0fffffff8h
		shr	esi,1
		add	esi,ecx
		call	__AddVramBase_esi
		mov	ecx,esi
	;x1 が dword 境界じゃない(x1%8!=0) 時､左端の処理
		mov	esi,eax
		and	esi,7h
		jz	#100
			mov	esi,[Lmaskpat+esi*4]	;esi:マスクパターン
			mov	edi,[collist+edx*4]	;edi:カラーデータ
			and	edi,esi
			push	ebx			;ebx(x2)保存
			mov	ebx,[logop]		;ebx:演算指定
			or	ebx,ebx
			jnz	#101
				mov	ebx,es:[ecx]	;PSET演算
				not	esi
				and	ebx,esi
				or	ebx,edi
				mov	es:[ecx],ebx
				jmp	#102
			#101:
				xor	es:[ecx],edi	;XOR演算
			#102:
			pop	ebx			;ebx(x2)復帰
			add	ecx,4			;アドレス補正
			and	eax,0fffffff8h		;x1 補正
			add	eax,8
		#100:

	;メイン処理
	;	reg	eax:左端座標
	;		ebx:右端座標
	;		ecx:アドレス
	;		edx:カラーコード
	;		[logop]:演算指定

		mov	esi,[logop]
		or	esi,esi
		jnz	#201
			;PSET 演算 --- stosd のために eax,es,edi,ecxを設定
			push	eax
			push	ecx
			mov	edi,ecx			;edi ← アドレス
			mov	ecx,ebx			;ecx ← 繰り返し回数
			inc	ecx
			sub	ecx,eax
			shr	ecx,3
			mov	eax,[collist+edx*4]	;eax ← カラーデータ
			mov	esi,ecx			;繰り返し回数の保存
			cld
			rep stosd
			pop	ecx
			pop	eax
			mov	ecx,edi			;アドレスの更新
			lea	eax,[esi*8+eax]		;x1 の更新
			jmp	#202
		#201:	;XOR 演算 --- loop 命令のために ecx を設定
			push	ecx
			mov	edi,ecx			;edi←アドレス
			mov	ecx,ebx			;ecx←繰り返し回数
			inc	ecx
			sub	ecx,eax
			shr	ecx,3
			or	ecx,ecx
			jz	#203
				mov esi,[collist+edx*4]	;esi:カラーデータ
				lea	eax,[ecx*8+eax]	;x1 の更新
				#205:
					xor	es:[edi],esi
					add	edi,4
				loop #205
			#203:
			pop	ecx
			mov	ecx,edi			;アドレスの更新
		#202:
	
	;右端の処理
	
		cmp	eax,ebx
		jg	#301
			mov	esi,ebx			;esi←マスクパターン
			and	esi,7
			mov	esi,[Rmaskpat+esi*4]
			mov	edi,[collist+edx*4]	;edi←カラーデータ
			and	edi,esi
			mov	eax,[logop]		;eax:logop
			or	eax,eax
			jnz	#302
				mov	eax,es:[ecx]	;PSET演算の時
				not	esi
				and	eax,esi
				or	eax,edi
				mov	es:[ecx],eax
				jmp	#303
			#302:
				xor	es:[ecx],edi	;XOR演算の時
			#303:
		#301:
#end:
		popad
		ret
ghline16	endp


;● HLINE のサブルーチン (３万色モード [256*512ドット])
;----------------------------------------------------------------------------


ghline32a	proc near
	;es:edi ← アドレス
		mov	edi,ecx
		shl	edi,9
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画
		sub	ebx,eax		;ecx ← 長さ
		inc	ebx
		mov	ecx,ebx
		mov	eax,edx		;eax ← カラーデータ
		and	eax,7fffh
		or	esi,esi		;演算指定により分岐
		jnz	#1
			;---- NORMAL
			rep stosw
			jmp	#2
		#1:	;---- XOR
			sub	ecx,16
			jl	#3
				#4:
					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
					xor	es:[edi+16],ax
					xor	es:[edi+18],ax
					xor	es:[edi+20],ax
					xor	es:[edi+22],ax
					xor	es:[edi+24],ax
					xor	es:[edi+26],ax
					xor	es:[edi+28],ax
					xor	es:[edi+30],ax
					add	edi,32
					sub	ecx,16
				jge	#4
			#3:
			add	ecx,16
			jz	#6
				rept 4
				 xor	es:[edi],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+2],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+4],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+6],ax
				 dec	ecx
				 jz	#6
				 add	edi,8
				endm
			#6:
		#2:
	;おわり
		ret
ghline32a	endp


;● HLINE のサブルーチン (３万色モード [512*256ドット])
;----------------------------------------------------------------------------


ghline32b	proc near
	;es:edi ← アドレス
		mov	edi,ecx
		shl	edi,10
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画
		sub	ebx,eax		;ecx ← 長さ
		inc	ebx
		mov	ecx,ebx
		mov	eax,edx		;eax ← カラーデータ
		and	eax,7fffh
		or	esi,esi		;演算指定により分岐
		jnz	#1
			;---- NORMAL
			rep stosw
			jmp	#2
		#1:	;---- XOR
			sub	ecx,16
			jl	#3
				#4:
					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
					xor	es:[edi+16],ax
					xor	es:[edi+18],ax
					xor	es:[edi+20],ax
					xor	es:[edi+22],ax
					xor	es:[edi+24],ax
					xor	es:[edi+26],ax
					xor	es:[edi+28],ax
					xor	es:[edi+30],ax
					add	edi,32
					sub	ecx,16
				jge	#4
			#3:
			add	ecx,16
			jz	#6
				rept 4
				 xor	es:[edi],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+2],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+4],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+6],ax
				 dec	ecx
				 jz	#6
				 add	edi,8
				endm
			#6:
		#2:
	;おわり
		ret
ghline32b	endp


;● HLINE のサブルーチン (256色モード)
;----------------------------------------------------------------------------


ghline256	proc
		;★まだ作ってないよーん
		ret
ghline256	endp


;● HLINE のサブルーチン (３万色モード [512*512ドット])
;----------------------------------------------------------------------------


ghline32c	proc
	;es:edi ← アドレス
		mov	edi,ecx
		shl	edi,10
		add	edi,eax
		add	edi,eax
		call	__AddVramBase_edi
		call	__SetVramSeg
	;描画
		sub	ebx,eax		;ecx ← 長さ
		inc	ebx
		mov	ecx,ebx
		mov	eax,edx		;eax ← カラーデータ
		and	eax,7fffh
		or	esi,esi		;演算指定により分岐
		jnz	#1
			;---- NORMAL
			rep stosw
			jmp	#2
		#1:	;---- XOR
			sub	ecx,16
			jl	#3
				#4:
					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
					xor	es:[edi+16],ax
					xor	es:[edi+18],ax
					xor	es:[edi+20],ax
					xor	es:[edi+22],ax
					xor	es:[edi+24],ax
					xor	es:[edi+26],ax
					xor	es:[edi+28],ax
					xor	es:[edi+30],ax
					add	edi,32
					sub	ecx,16
				jge	#4
			#3:
			add	ecx,16
			jz	#6
				rept 4
				 xor	es:[edi],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+2],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+4],ax
				 dec	ecx
				 jz	#6
				 xor	es:[edi+6],ax
				 dec	ecx
				 jz	#6
				 add	edi,8
				endm
			#6:
		#2:
	;おわり
		ret
ghline32c	endp



cseg ends

end
