;		32K色ムービ転送 
;		DATA → BUFFER → VRAM
;		VSYNC 同期タイプ( vccount.objとのリンクが必要 )
;		1992 1/14  Hiroshi TODA
;

	.386p


	extrn	VSYNC_counter	:	dword



work	struc
			;para area
data	dd	?		; DATA アドレス
buffer	dd	?		; BUFFER アドレス
mode	dd	?		; bit0:VRAMページ(0or1)
				; bit1:move_box参照VRAMページ(0or1)
wt1	dd	?		; wait

;work areaパラメータの後にワークエリアをつける（カッコ悪いが高速処理のため）

pg	dd	?		; page		（dataのヘッダ内容のコピー）
dsize	dd	?		; size
ox	dw	?		; 表示位置 (x)dw, (y)dw
oy	dw	?
wt2	dw	?		; wait
lp	dw	?		; loop
dummy	dd	?
sound1	dd	?		; sound data
sound2	dd	?
sound3	dd	?

pcmadd	dd	?		; pcm data address 転送情報(0なら無し)
pcmch	dd	?		; ch
pcmsize	dd	?		; size

endadd	dd	?		;
ckofst	dw	?		; offset ckeck
num1	dw	?		; 個数1
num2	dw	?		;     2
num3	dw	?		;     3

count1	dw	?		; work area
count2	dw	?

	; 以上 19 dword

work	ends

cseg	segment	dword public use32 'CODE'
	assume	cs:cseg,ds:cseg

;int move32(int para[])
;char *work
;int para[] = { dataアドレス, bufferアドレス, mode, wait }
;出力 = next data アドレス

	public	move32_vsync
	db	'move32_vsync',12
move32_vsync	proc	near
	push	ebp
	mov	ebp,esp
	push	esi
	push	edi
	push	ebx
	mov	ebx,[ebp+8]		; ebx = para のアドレス
	mov	edx,[ebx].buffer	; buffer -> edx
	mov	esi,[ebx].data		; data -> esi
	mov	ax,[ebx].ox		; 1つ手前の絵のoffset情報を確保
	add	ax,[ebx].oy		; pre move の処理の時に補正
	je	move00
	mov	ax,1
move00:	mov	[ebx].ckofst,ax
	lea	edi,[ebx].pg		; data header 転送 転送先->edi
	cld
	mov	ecx,8
	rep	movsd			; data trans(header=32bit)
	mov	dword ptr [ebx].pcmadd,0	; pcm 情報 clear
	mov	eax,[ebx].dsize		; data end -> eax
	add	eax,esi
	mov	[ebx].endadd,eax
	cmp	eax,esi
	je	move12
	lodsw
	mov	[ebx].num1,ax
	cmp	ax,0
	je	move12
move01:	lodsw			; 各種処理ルーチン呼び出しループ
	push	esi
	cmp	ax,1222H		; stosw type1
	jne	move02
	call	storew
	jmp	move10
move02:	cmp	ax,2222H		; movsw
	jne	move03
	call	movew
	jmp	move10
move03:	cmp	ax,0222H		; stosw type0
	jne	move04
	call	stosw0
	jmp	move10
move04:	cmp	ax,1422H		; stosd type1
	jne	move05
	call	stored
	jmp	move10
move05:	cmp	ax,2422H		; movsd
	jne	move06
	call	moved
	jmp	move10
move06:	cmp	ax,3010H		; move box ( 16*16 )
	jne	move07
	call	mvbx16
	jmp	move10
move07:	cmp	ax,3110H		; move all box ( 16*16*300 )
	jne	move08
	call	mvbxall_16
	jmp	move10
move08:	cmp	ax,0F000H		; pcm data 転送
	jne	move10
	call	pcmtr
	jmp	move10
move10:	pop	esi
	lodsd
	add	esi,eax
	dec	word ptr [ebx].num1
	jne	move01
move12:	push	es			; esをスタックに退避
	mov	ax,104h			; es=VRAMセグメントレジスタ
	mov	es,ax
	xor	edi,edi
	test	byte ptr [ebx].mode,1
	je	move13
	mov	edi,40000h		; es:[edi]=vram
move13:	mov	eax,dword ptr [ebx].ox	; read offset
	or	eax,eax
	je	move0L			; offset == 原点 -> move0F

	mov	esi,[ebx].buffer	; ds:[esi]=buffer
	xor	ecx,ecx
	mov	ax,[ebx].ox
	and	eax,0FFFFh
	shl	ax,1
	add	esi,eax			; esi += x*2
	mov	ax,[ebx].oy
	imul	eax,eax,640
	add	esi,eax			; esi += y*640
	mov	ax,320
	sub	ax,[ebx].ox
	jbe	move0L		; error スクロールしない
	shr	ax,1
	mov	[ebx].count1,ax		; count1 = (320 - x)/2
	mov	ax,[ebx].ox
	shr	ax,1
	mov	[ebx].count2,ax		; count2 = x/2
	jc	move0C

	mov	dx,240		; x偶数
	sub	dx,[ebx].oy		; dx = 240 - y
	jbe	move0L		; error スクロールしない
move0A:	mov	cx,[ebx].count1
	rep	movsd
	sub	esi,640			; esi 320dot back
	mov	cx,[ebx].count2
	rep	movsd
	add	esi,640			; esi 320dot go
	add	edi,384			; edi += 384
	dec	dx
	jne	move0A
	mov	esi,[ebx].buffer	; ds:[esi]=buffer 処理その２
	mov	ax,[ebx].ox
	and	eax,0FFFFh
	shl	ax,1
	add	esi,eax			; esi += x*2
	mov	dx,[ebx].oy		; dx = y
	or	dx,dx
	je	move0M			; ループは0
move0B:	mov	cx,[ebx].count1
	rep	movsd
	sub	esi,640			; esi 320dot back
	mov	cx,[ebx].count2
	rep	movsd
	add	esi,640			; esi 320dot go
	add	edi,384			; edi += 384
	dec	dx
	jne	move0B
	jmp	move0M

move0C:	mov	dx,240		; x奇数
	sub	dx,[ebx].oy		; dx = 240 - y
	jbe	move0L		; error スクロールしない
move0D:	mov	cx,[ebx].count1
	rep	movsd
	movsw
	sub	esi,640			; esi 320dot back
	mov	cx,[ebx].count2
	rep	movsd
	movsw
	add	esi,640			; esi 320dot go
	add	edi,384			; edi += 384
	dec	dx
	jne	move0D
	mov	esi,[ebx].buffer	; ds:[esi]=buffer 処理その２
	mov	ax,[ebx].ox
	and	eax,0FFFFh
	shl	ax,1
	add	esi,eax			; esi += x*2
	mov	dx,[ebx].oy		; dx = y
	or	dx,dx
	je	move0M			; ループは0
move0E:	mov	cx,[ebx].count1
	rep	movsd
	movsw
	sub	esi,640			; esi 320dot back
	mov	cx,[ebx].count2
	rep	movsd
	movsw
	add	esi,640			; esi 320dot go
	add	edi,384			; edi += 384
	dec	dx
	jne	move0E
	jmp	move0M

move0L:	mov	esi,[ebx].buffer	; ds:[esi]=buffer
	xor	ecx,ecx
	mov	edx,240
move14:	mov	cl,160			; vram 転送
	rep	movsd
	add	edi,384
	dec	edx
	jne	move14

move0M:	xor	ecx,ecx
	mov	cx,[ebx].wt2		; wait
	add	ecx,[ebx].wt1
move0N:	mov	eax,VSYNC_counter	; read vsync_counter
	sub	eax,ecx
	je	move20
	jb	move0N
	shr	ecx,1
	cmp	eax,ecx
	jbe	move20
	mov	eax,ecx
move20:	mov	VSYNC_counter,eax

move21:	mov	dx,0448h		; 0448h
	mov	al,1
	out	dx,al
	mov	dx,044Ah		; 044ah
	mov	eax,[ebx].mode		; プライオリティ
	and	eax,01h
	out	dx,al
	pop	es			; esを元に戻す
	mov	eax,[ebx].endadd	; eaxに終了アドレス
	pop	ebx
	pop	edi
	pop	esi
	mov	esp,ebp
	pop	ebp
	ret
move32_vsync	endp

;	stosw ( dataをそのつど指定するタイプ )

stosw0	proc	near
	push	ebx			; ebx 保存
	lodsd				; data長 skip
	cmp	eax,0
	je	#sto06
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#sto06
#sto02:	lodsw				; offset
	shl	eax,16
	mov	edx,[ebx].buffer	; buffer-address
	add	edx,eax			; offset + buffer-address -> edx
	lodsw			; num3
	cmp	ax,0
	je	#sto05
	mov	bx,ax
#sto03:	lodsw				; address
	movzx	edi,ax
	add	edi,edx			; add offset
	xor	eax,eax			; count
	lodsb
	cmp	al,4
	ja	#sto0B			; 4個以下は特別扱い
	mov	ecx,eax
	lodsw
	rep	stosw
	dec	bx
	jne	#sto03
	jmp	#sto0C
#sto0B:	cmp	al,0ffH
	jne	#sto04
	lodsw
	cmp	ax,0ffffH
	jne	#sto04
	lodsd
#sto04:	mov	ecx,eax
	mov	eax,[esi].(-2)		; eax = ax + ax << 16
	lodsw
	shr	ecx,1
	rep	stosd
	jnc	#sto0A
	stosw
#sto0A:	dec	bx
	jne	#sto03
#sto0C:	mov	ebx,[esp]		; ebx戻し
#sto05:	dec	word ptr [ebx].num2
	jne	#sto02
#sto06:	pop	ebx
	ret
stosw0	endp

;	stosw ( 最初にdataを指定するタイプ )

storew	proc	near
	push	ebx			; ebx 保存
	push	eax
	lodsd				; data長 skip
	cmp	eax,0
	je	#sto07
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#sto07
#sto01:	mov	eax,[esi].(-2)		; eax = ax + ax << 16
	lodsw
	mov	[esp],eax		; data 保存
	lodsw			; num3
	mov	[ebx].num3,ax
	cmp	ax,0
	je	#sto06
#sto02:	lodsw				; offset
	shl	eax,16
	mov	edx,[ebx].buffer	; buffer-address
	add	edx,eax			; offset + buffer-address -> edx
	lodsw			; num4
	cmp	ax,0
	je	#sto05
	mov	bx,ax
#sto03:	lodsw				; address
	movzx	edi,ax
	add	edi,edx			; add offset
	xor	eax,eax			; count
	lodsb
	cmp	al,4
	ja	#sto0B			; 4個以下は特別扱い
	mov	ecx,eax
	mov	eax,[esp]
	rep	stosw
	dec	bx
	jne	#sto03
	jmp	#sto0C
#sto0B:	cmp	al,0ffH
	jne	#sto04
	lodsw
	cmp	ax,0ffffH
	jne	#sto04
	lodsd
#sto04:	mov	ecx,eax
	mov	eax,[esp]		; data
	shr	ecx,1
	rep	stosd
	jnc	#sto0A
	stosw
#sto0A:	dec	bx
	jne	#sto03
#sto0C:	mov	ebx,[esp].4		; ebx戻し
#sto05:	dec	word ptr [ebx].num3
	jne	#sto02
#sto06:	dec	word ptr [ebx].num2
	jne	#sto01
#sto07:	pop	eax
	pop	ebx
	ret
storew	endp

stored	proc	near
	push	ebx
	push	eax
	lodsd				; data長 skip
	cmp	eax,0
	je	#sto07
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#sto07
#sto01:	lodsd
	mov	[esp],eax		; data 保存
	lodsw			; num3
	mov	[ebx].num3,ax
	cmp	ax,0
	je	#sto06
#sto02:	lodsw				; offset
	shl	eax,16
	mov	edx,[ebx].buffer	; buffer-address
	add	edx,eax			; offset + buffer-address -> edx
	lodsw			; num4
	cmp	ax,0
	je	#sto05
	mov	bx,ax
#sto03:	lodsw				; address
	movzx	edi,ax
	add	edi,edx			; add offset
	xor	eax,eax			; count
	lodsb
	cmp	al,0ffH
	jne	#sto04
	lodsw
	cmp	ax,0ffffH
	jne	#sto04
	lodsd
#sto04:	mov	ecx,eax
	mov	eax,[esp]		; data
	rep	stosd
	dec	bx
	jne	#sto03
	mov	ebx,[esp].4		; ebx戻し
#sto05:	dec	word ptr [ebx].num3
	jne	#sto02
#sto06:	dec	word ptr [ebx].num2
	jne	#sto01
#sto07:	pop	eax
	pop	ebx
	ret
stored	endp

movew	proc	near
	push	ebx
	lodsd				; data長 skip
	cmp	eax,0
	je	#mov06
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#mov06
#mov01:	lodsw				; offset
	shl	eax,16
	mov	edx,[ebx].buffer	; buffer-address
	add	edx,eax			; offset + buffer-address -> edx
	lodsw			; num3
	cmp	ax,0
	je	#mov05
	mov	bx,ax
#mov02:	lodsw				; address
	movzx	edi,ax
	add	edi,edx			; add offset
	xor	eax,eax			; count
	lodsb
	cmp	al,4
	ja	#mov0B			; 4個以下は特別扱い
	mov	ecx,eax
	rep	movsw
	dec	bx			; なりふり構わない
	jne	#mov02
	jmp	#mov0C
#mov0B:	cmp	al,0ffH
	jne	#mov03
	lodsw
	cmp	ax,0ffffH
	jne	#mov03
	lodsd
#mov03:	mov	ecx,eax
	shr	ecx,1
	rep	movsd
	jnc	#mov04
	movsw
#mov04:	dec	bx
	jne	#mov02
#mov0C:	mov	ebx,[esp]
#mov05:	dec	word ptr [ebx].num2
	jne	#mov01
#mov06:	pop	ebx
	ret
movew	endp

moved	proc	near
	push	ebx
	lodsd				; data長 skip
	cmp	eax,0
	je	#mov06
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#mov06
#mov01:	lodsw				; offset
	shl	eax,16
	mov	edx,[ebx].buffer	; buffer-address
	add	edx,eax			; offset + buffer-address -> edx
	lodsw			; num3
	cmp	ax,0
	je	#mov05
	mov	bx,ax
#mov02:	lodsw				; address
	movzx	edi,ax
	add	edi,edx			; add offset
	xor	eax,eax			; count
	lodsb
	cmp	al,0ffH
	jne	#mov03
	lodsw
	cmp	ax,0ffffH
	jne	#mov03
	lodsd
#mov03:	mov	ecx,eax
	rep	movsd
#mov04:	dec	bx
	jne	#mov02
	mov	ebx,[esp]
#mov05:	dec	word ptr [ebx].num2
	jne	#mov01
#mov06:	pop	ebx
	ret
moved	endp

mvbx16	proc	near
	lodsd				; data長 skip
	cmp	eax,0
	je	#mov05
	lodsw			; num2
	mov	[ebx].num2,ax
	cmp	ax,0
	je	#mov05
	test	byte ptr [ebx].ckofst,01h	; 原点補正を考慮
	je	#mov0A
	call	ckofst0
	mov	ax,104h		; fs = 104h vram selector
	mov	fs,ax
	mov	eax,esi		; 例外的に eax がポインター
	test	byte ptr [ebx].mode,02h
	je	#mov03		; 補正有り -> vram逆
	jmp	#mov01
#mov0A:	mov	ax,104h		; fs = 104h vram selector
	mov	fs,ax
	mov	eax,esi		; 例外的に eax がポインター
	test	byte ptr [ebx].mode,02h
	jne	#mov03
#mov01:	mov	edi,[eax]		; 画面0に前の絵が残ってる
	mov	esi,[eax+4]		; short int x, y
	shl	si,7
	shr	esi,6
	add	eax,8
	add	edi,[ebx].buffer
	mov	edx,16
#mov02:	mov	ecx,8
	rep	movs dword ptr [edi],fs:[esi]	; dword 転送
	add	edi,608
	add	esi,992
	dec	edx
	jne	#mov02
	dec	word ptr [ebx].num2
	jne	#mov01
	mov	esi,eax
	jmp	#mov05
#mov03:	mov	edi,[eax]		; 画面1に前の絵が残ってる
	mov	esi,[eax+4]		; short int x, y
	shl	si,7
	shr	esi,6
	add	esi,40000h	; 画面1
	add	eax,8
	add	edi,[ebx].buffer
	mov	edx,16
#mov04:	mov	ecx,8
	rep	movs dword ptr [edi],fs:[esi]	; dword 転送
	add	edi,608
	add	esi,992
	dec	edx
	jne	#mov04
	dec	word ptr [ebx].num2
	jne	#mov03
	mov	esi,eax
#mov05:	ret
mvbx16	endp

mvbxall_16 proc	near
	lodsd				; data長 skip
	cmp	eax,0
	je	#mov07
	test	byte ptr [ebx].ckofst,01h	; 原点補正を考慮
	je	#mov0A
	call	ckofst0
	mov	ax,104h		; fs = 104h vram selector
	mov	fs,ax
	mov	eax,esi		; 例外的に eax がポインター
	test	byte ptr [ebx].mode,02h
	je	#mov03		; 補正有り -> vram逆
	jmp	#mov0B
#mov0A:	mov	ax,104h		; fs = 104h vram selector
	mov	fs,ax
	mov	eax,esi		; 例外的に eax がポインター
	test	byte ptr [ebx].mode,02h
	jne	#mov03
#mov0B:	mov	edx,[ebx].buffer	; 画面0に前の絵が残ってる
	mov	dword ptr [ebx].count1,edx
	push	dword ptr 15
#mov00:	push	dword ptr 20
	mov	edi,dword ptr [ebx].count1
#mov01:	mov	esi,[eax]		; short int x, y
	shl	si,7
	shr	esi,6
	add	eax,4
	mov	edx,16
#mov02:	mov	ecx,8
	rep	movs dword ptr [edi],fs:[esi]	; dword 転送
	add	edi,608
	add	esi,992
	dec	edx
	jne	#mov02
	sub	edi,10208		; edi : 640*16 - 32 back
	dec	dword ptr [esp]
	jne	#mov01
	add	esp,4
	add	dword ptr [ebx].count1,10240
	dec	dword ptr [esp]
	jne	#mov00
	add	esp,4
	mov	esi,eax
	jmp	#mov07
#mov03:	mov	edx,[ebx].buffer	; 画面1に前の絵が残ってる
	mov	dword ptr [ebx].count1,edx
	push	dword ptr 15
#mov04:	push	dword ptr 20
	mov	edi,dword ptr [ebx].count1
#mov05:	mov	esi,[eax]		; short int x, y
	shl	si,7
	shr	esi,6
	add	esi,40000h	; 画面1
	add	eax,4
	mov	edx,16
#mov06:	mov	ecx,8
	rep	movs dword ptr [edi],fs:[esi]	; dword 転送
	add	edi,608
	add	esi,992
	dec	edx
	jne	#mov06
	sub	edi,10208		; edi : 640*16 - 32 back
	dec	dword ptr [esp]
	jne	#mov05
	add	esp,4
	add	dword ptr [ebx].count1,10240
	dec	dword ptr [esp]
	jne	#mov04
	add	esp,4
	mov	esi,eax
#mov07:	ret
mvbxall_16 endp

; offset 空いたvramで原点に補正

ckofst0	proc	near
	push	esi
	push	es			; esをスタックに退避
	mov	ax,104h			; es=VRAMセグメントレジスタ
	mov	es,ax
	xor	edi,edi
	test	byte ptr [ebx].mode,2
	jne	off01
	mov	edi,40000h		; es:[edi]=vram
off01:	mov	esi,[ebx].buffer	; ds:[esi]=buffer
	xor	ecx,ecx
	mov	edx,240
off02:	mov	cl,160			; vram 転送
	rep	movsd
	add	edi,384
	dec	edx
	jne	off02
	pop	es
	pop	esi
	ret
ckofst0 endp

pcmtr	proc	near
	lodsd				; data長 skip
	add	eax,esi
	push	eax			; eax 終了アドレス
	lodsd				; ch
	mov	[ebx].pcmch,eax
	lodsd				; 転送data size
	mov	[ebx].pcmsize,eax
	mov	[ebx].pcmadd,esi	; data address
	pop	esi
	ret
pcmtr	endp

cseg	ends
	end

