;	私製ライブラリ・グラフィック篇
;	(c) MATSUUCHI Ryosuke in Dec,1992 - Jan,1993
;
;	gblkcpy.asm
;		領域指定による VRAM・VRAM間 ／ VRAM・メモリ間コピー
;
;	1992.12.29(Tue)
;	1993. 1. 4(Mon)

		public	_gblkcpy, gblkcpy
		public	_gputblk, gputblk

		extrn	_gwrtreg:near
		extrn	__SetVramSeg:near, __AddVramBase_ebx:near
		extrn	__getpadrs:near
		extrn	__getpscrmod:near

		include	grplib.inc

		assume	cs:cseg, ds:dseg


dseg segment dword 'DATA'

s_linesize	dd	0	;転送元の画面の１ラインのバイト数
d_linesize	dd	0	;転送先の画面の１ラインのバイト数
_xcnt		dd	0
_ycnt		dd	0
_op		dd	0	;演算指定

		;各画面モードの１ラインのバイト数
_scrlsiz	dd	0,320,320
		dd	512,512			;モード３〜４（１６色）
		dd	512,512,512,512		;モード５〜８（３万色）
		dd	1024,1024,1024		;モード９〜11（３万色）
		dd	1024,1024,1024		;モード12〜14（256色）
		dd	1024,1024,1024,1024	;モード15〜18（３万色）

_para		dd	0,0,0,0,0,0,0,0,0,0,0

dseg ends


cseg segment dword 'CODE'

;---------------------------------------------------------------
;	_ggetblk : 画面→メモリのブロック転送
;		in  eax : パラメータ配列へのポインタ
;	※パラメータ配列：
;		+ 0 DW  buf
;		+ 4 DW  dx
;		+ 8 DW  dy
;		+12 DW  xlen
;		+16 DW  ylen
;		+20 DW  operation
;	void gputblk(buf, dx,dy,xlen,ylen,operation)
;---------------------------------------------------------------


;---------------------------------------------------------------
;	_gputblk : メモリ→画面のブロック転送
;		in  eax : パラメータ配列へのポインタ
;	※パラメータ配列：
;		+ 0 DW  buf
;		+ 4 DW  dx
;		+ 8 DW  dy
;		+12 DW  xlen
;		+16 DW  ylen
;		+20 DW  operation
;	void gputblk(buf, dx,dy,xlen,ylen,operation)
;---------------------------------------------------------------


_gputblk	proc
		pushfd
		pushad
		push	es
		push	fs
		mov	ebp,eax
		mov	ax,ds
		mov	fs,ax
		;転送先の画面の１ラインのバイト数を調べる
		mov	eax,[_wrtpage]
		call	__getpscrmod
		mov	ebx,[_scrlsiz+eax*4]
		mov	[d_linesize],ebx
		push	eax
		;[_xcnt],[_ycnt]を設定
		mov	eax,[ebp+12]
		mov	[_xcnt],eax
		mov	eax,[ebp+16]
		mov	[_ycnt],eax
		mov	eax,[ebp+20]
		mov	[_op],eax
		;es:edi に転送先アドレスを設定
		mov	eax,[_wrtpage]
		mov	ebx,[ebp+4]
		mov	ecx,[ebp+8]
		call	__getpadrs
		mov	es,ax
		mov	edi,ebx
		;ds:esi に転送元アドレスを設定
		mov	esi,[ebp+0]
		;画面モードごとに分岐
		pop	eax
		cmp	eax,4
		jg	#1
			call	_gputblk_16	;モード０〜４
			jmp	#2
		#1:
		cmp	eax,11
		jg	#3
			mov	eax,[ebp+12]
			add	eax,eax
			mov	[s_linesize],eax
			call	_gblkcpy_32k	;モード５〜11
			jmp	#2
		#3:
		cmp	eax,14
		jg	#4
			call	_gputblk_256	;モード12〜14
			jmp	#2
		#4:
			mov	eax,[ebp+12]
			add	eax,eax
			mov	[s_linesize],eax
			call	_gblkcpy_32k	;モード15〜
		#2:
		pop	fs
		pop	es
		popad
		popfd
		ret
_gputblk	endp



gputblk		proc
		irpc	cnt,<012345>
		 mov	eax,[esp+4+cnt*4]
		 mov	[_para+cnt*4],eax
		endm
		lea	eax,[_para]
		call	_gputblk
		ret
gputblk		endp



_gputblk_16	proc
		ret
_gputblk_16	endp


_gputblk_256	proc
		ret
_gputblk_256	endp


;---------------------------------------------------------------
;	_gblkcpy : ブロックコピー
;		in  eax : パラメータ配列へのポインタ
;	※パラメータ配列：
;		+ 0 DW  sx
;		+ 4 DW  sy
;		+ 8 DW  xlen
;		+12 DW  ylen
;		+16 DW  spage
;		+20 DW  dx
;		+24 DW  dy
;		+28 DW  dpage
;		+32 DW  operation
;	void gblkcpy(sx,sy,xlen,ylen,sp,dx,dy,dp, op)
;---------------------------------------------------------------



_gblkcpy	proc	near
		pushfd
		pushad
		push	ds
		push	es
		push	fs
		mov	ebp,eax
		;fs ←現在の ds
		mov	ax,ds
		mov	fs,ax
		;[_xcnt], [_ycnt]の設定
		mov	eax,[ebp+8]
		mov	[_xcnt],eax
		mov	eax,[ebp+12]
		mov	[_ycnt],eax
		mov	eax,[ebp+32]
		mov	[_op],eax
		;転送元／先の画面の１ラインのバイト数を調べる
		mov	eax,fs:[ebp+16]
		call	__getpscrmod
		mov	ebx,fs:[_scrlsiz+eax*4]
		mov	fs:[s_linesize],ebx
		mov	eax,fs:[ebp+28]
		call	__getpscrmod
		mov	ebx,fs:[_scrlsiz+eax*4]
		mov	fs:[d_linesize],ebx
		push	eax
		;es:edi に転送先アドレスを設定
		mov	eax,[ebp+28]
		mov	ebx,[ebp+20]
		mov	ecx,[ebp+24]
		call	__getpadrs
		mov	es,ax
		mov	edi,ebx
		;ds:esi に転送元アドレスを設定
		mov	eax,[ebp+16]
		mov	ebx,[ebp+0]
		mov	ecx,[ebp+4]
		call	__getpadrs
		mov	ds,ax
		mov	esi,ebx
		;画面モードごとに分岐
		pop	eax
		cmp	eax,4
		jg	#1
			call	_gblkcpy_16	;モード０〜４
			jmp	#2
		#1:
		cmp	eax,11
		jg	#3
			call	_gblkcpy_32k	;モード５〜11
			jmp	#2
		#3:
		cmp	eax,14
		jg	#4
			call	_gblkcpy_256	;モード12〜14
			jmp	#2
		#4:
			call	_gblkcpy_32k	;モード15〜
		#2:
		pop	fs
		pop	es
		pop	ds
		popad
		popfd
		ret
_gblkcpy	endp



gblkcpy		proc
		irpc	cnt,<012345678>
		 mov	eax,[esp+4+cnt*4]
		 mov	[_para+cnt*4],eax
		endm
		lea	eax,[_para]
		call	_gblkcpy
		ret
gblkcpy		endp



_gblkcpy_16	proc
		ret
_gblkcpy_16	endp


_gblkcpy_256	proc
		ret
_gblkcpy_256	endp


;---------------------------------------------------------------
;	_gblkcpy_32k : ブロックコピー・３万色モードの場合
;		in	fs		データセグメントのセレクタ
;			[_xcnt]		Ｘ方向のドット数
;			[_ycnt]		Ｙ方向のドット数
;			es:edi		転送先の基準アドレス
;			ds:esi		転送元の基準アドレス
;			[d_linesize]	転送先の１ラインのバイト数
;			[s_linesize]	転送元の１ラインのバイト数
;			[_op]		演算指定
;---------------------------------------------------------------


_gblkcpy_32k	proc
		mov	eax,[_op]
		or	eax,eax
		jne	#2
			mov	ebx,fs:[_ycnt]
			#1:
				or	ebx,ebx
				jz	#0
				mov	ecx,fs:[_xcnt]
				push	edi
				push	esi
				rep movsw
				pop	esi
				pop	edi
				add	edi,fs:[d_linesize]
				add	esi,fs:[s_linesize]
				dec	ebx
			jmp	#1
			#0:
			jmp	#3
		#2:
		cmp	eax,128	;TPSET
		jne	#4
			mov	ebx,fs:[_ycnt]
			#3001:
				or	ebx,ebx
				jz	#3002
				mov	ecx,fs:[_xcnt]
				push	edi
				push	esi
				#3003:
					or	ecx,ecx
					jz	#3004
					dec	ecx
					lodsw
					or	ax,ax
					jz	#3005
						stosw
						jmp	#3003
					#3005:
						add	edi,2
				jmp	#3003
				#3004:
				pop	esi
				pop	edi
				add	edi,fs:[d_linesize]
				add	esi,fs:[s_linesize]
				dec	ebx
			jmp	#3001
			#3002:
			jmp	#3
		#4:


		#3:
		ret
_gblkcpy_32k	endp



cseg ends

end
