;	'VIEW1.EXP' command for native-mode
;	run386 VIEW
	.386p

SIZE_X	equ	256
SIZE_Y	equ	240
MOVE_X	equ	4
MOVE_Y	equ	4

CODE	segment
	assume	cs:CODE
	org 0

MAIN	proc
	pusha
	sub	esp,256*1024	;vram buffer をstackに作る
	mov	ebp,esp
	
	mov	ax,120h		;vramをセーブ
	mov	fs,ax
	mov	ax,ss
	mov	es,ax
	mov	ecx,256*1024/4
	mov	edi,ebp
	mov	esi,0
	cld
	rep movs	DWORD PTR [edi],DWORD PTR fs:[esi]
	
	sub	esp,1536	;EGB buffer をstackに作る
	
	push	ss		;graphicのinitialize
	pop	gs
	mov	edi,esp
	mov	ecx,1536
	mov	ah,0
	push	0110h
	pop	fs
	call	PWORD PTR fs:[20h]
	
	mov	ah,01h		;page = 0 を画面mode 5
	mov	al,0
	mov	dx,5
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;表示位置を真ん中に
	mov	al,0
	mov	dx,64
	mov	bx,0
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;拡大率を設定
	mov	al,2
	mov	dx,2
	mov	bx,2
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;表示の大きさを設定
	mov	al,3
	mov	dx,256
	mov	bx,240
	call	PWORD PTR fs:[20h]
	
	mov	ah,06h		;表示の設定
	mov	al,1
	mov	edx,1
	call	PWORD PTR fs:[20h]
	
	push	0120h		;初期値の設定
	pop	es
	mov	edi,0
	
	call	dsp
	call	chg_scr
	
#looptop:			;メインループ
	
	mov	ah,41h		;ジョイスティックを読む
	mov	dh,0
	call	pword ptr fs:[80h]
	mov	ds:[JOYDAT],dl
	
	cmp	dl,0ffh		;何も押していない
	je	#looptop
	
	mov	eax,ds:[SIN1]	;横の移動量を計算
	mov	ebx,SIZE_X/32*256
	mul	ebx
	shrd	eax,edx,8
	mov	ds:[GX],eax
	
	mov	eax,ds:[COS1]	;縦の移動量を計算
	mov	ebx,SIZE_X/32*256
	mul	ebx
	shrd	eax,edx,7
	mov	ds:[GY],eax
	
	test	ds:[JOYDAT],02h
	jne	#not_down
	
	cmp	ds:[TH],64	;下移動｡4つに場合分け
	jae	#down_2
	
	mov	eax,ds:[GX]
	sub	ds:[CNX],eax
	mov	eax,ds:[GY]
	add	ds:[CNY],eax
	jmp	#not_down
	
#down_2:
	cmp	ds:[TH],128
	jae	#down_3
	
	mov	eax,ds:[GX]
	sub	ds:[CNX],eax
	mov	eax,ds:[GY]
	sub	ds:[CNY],eax
	jmp	#not_down
	
#down_3:
	cmp	ds:[TH],192
	jae	#down_4
	
	mov	eax,ds:[GX]
	add	ds:[CNX],eax
	mov	eax,ds:[GY]
	sub	ds:[CNY],eax
	jmp	#not_down
	
#down_4:
	mov	eax,ds:[GX]
	add	ds:[CNX],eax
	mov	eax,ds:[GY]
	add	ds:[CNY],eax
	
#not_down:
	test	ds:[JOYDAT],01h
	jne	#not_up
	
	cmp	ds:[TH],64	;上移動｡4つに場合分け
	jae	#up_2
	
	mov	eax,ds:[GX]
	add	ds:[CNX],eax
	mov	eax,ds:[GY]
	sub	ds:[CNY],eax
	jmp	#not_up
	
#up_2:
	cmp	ds:[TH],128
	jae	#up_3
	
	mov	eax,ds:[GX]
	add	ds:[CNX],eax
	mov	eax,ds:[GY]
	add	ds:[CNY],eax
	jmp	#not_up
	
#up_3:
	cmp	ds:[TH],192
	jae	#up_4
	
	mov	eax,ds:[GX]
	sub	ds:[CNX],eax
	mov	eax,ds:[GY]
	add	ds:[CNY],eax
	jmp	#not_up
	
#up_4:
	
	mov	eax,ds:[GX]
	sub	ds:[CNX],eax
	mov	eax,ds:[GY]
	sub	ds:[CNY],eax
	
#not_up:
	test	ds:[JOYDAT],04h
	jne	#not_left
	
	sub	ds:[TH],2	;左回転
	
#not_left:
	test	ds:[JOYDAT],08h
	jne	#not_right
	
	add	ds:[TH],2	;右回転
	
#not_right:
	test	ds:[JOYDAT],10h
	jne	#not_a
				;画面を縮小
	mov	ax,word ptr ds:[ZM]
	mov	bx,0110h
	mul	bx
	shrd	ax,dx,8
	mov	word ptr ds:[ZM],ax
	cmp	word ptr ds:[ZM],0F00h
	jle	#not_a
	mov	ds:[ZM],0F00h
	
#not_a:
	test	ds:[JOYDAT],20h
	jne	#not_b
				;画面を拡大
	mov	ax,word ptr ds:[ZM]
	mov	bx,00f0h
	mul	bx
	shrd	ax,dx,8
	mov	word ptr ds:[ZM],ax
	cmp	word ptr ds:[ZM],0011h
	jg	#not_b
	mov	ds:[ZM],0011h
	
#not_b:
	test	ds:[JOYDAT],80h
	jne	#not_select
	
	jmp	#exit		;終了
	
#not_select:
	test	ds:[JOYDAT],40h
	jne	#not_run
	
	mov	ds:[ZM],0100h	;初期値に設定
	mov	ds:[TH],0
	mov	ds:[CNX],(SIZE_X/2)*00800000h
	mov	ds:[CNY],(SIZE_Y/2)*01000000h
	
#not_run:
	
	call	dsp		;1画面を描画
	call	chg_scr		;画面を切替え
	
	jmp	#looptop
	
#exit:
	mov	edi,esp		;TBIOS用にbufferのpointer
	push	0110h		;とsegmentをセット
	pop	fs
	
	mov	ah,01h		;page = 0 を画面mode 10
	mov	al,0
	mov	dx,10
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;表示位置を戻す
	mov	al,0
	mov	dx,0
	mov	bx,0
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;拡大率を戻す
	mov	al,2
	mov	dx,2
	mov	bx,2
	call	PWORD PTR fs:[20h]
	
	mov	ah,02h		;表示の大きさを戻す
	mov	al,3
	mov	dx,320
	mov	bx,240
	call	PWORD PTR fs:[20h]
	
	mov	ah,06h		;表示の設定
	mov	al,1
	mov	edx,3
	call	PWORD PTR fs:[20h]
	
	mov	ax,120h		;vramのデータを戻す
	mov	es,ax
	mov	ax,ss
	mov	fs,ax
	mov	ecx,256*1024/4
	mov	edi,0
	mov	esi,ebp
	cld
	rep movs	DWORD PTR [edi],DWORD PTR fs:[esi]
	
	add	esp,1536	;EGB buffer を開放
	add	esp,256*1024	;vram buffer を開放
	
	popa
	mov	ah,4Ch
	int	21h
MAIN	endp

dsp	proc
	call	tri		;SIN､COS を設定
	
	mov	ax,ds:[COS]	;拡大率を考慮してX座標の
	mov	bx,ds:[ZM]	;1ドット分の変化量を求める
	mul	bx
	mov	word ptr ds:[COS1+2],dx
	mov	word ptr ds:[COS1+0],ax
	shl	eax,16
	shld	edx,eax,16
	mov	ds:[DDX],edx
	
	mov	ax,ds:[SIN]	;拡大率を考慮してY座標の
	mov	bx,ds:[ZM]	;1ドット分の変化量を求める
	mul	bx
	mov	word ptr ds:[SIN1+2],dx
	mov	word ptr ds:[SIN1+0],ax
	shl	eax,16
	shld	edx,eax,17
	mov	ds:[DDY],edx
	
				;左上の座標を求める
	mov	eax,ds:[COS1]
	mov	ebx,SIZE_X/2*256
	mul	ebx
	shrd	eax,edx,8
	mov	ds:[XCOS],eax
	
	mov	eax,ds:[SIN1]
	mov	ebx,SIZE_X/2*256
	mul	ebx
	shrd	eax,edx,8
	mov	ds:[XSIN],eax
	
	mov	eax,ds:[COS1]
	mov	ebx,SIZE_Y/2*256
	mul	ebx
	shrd	eax,edx,8
	mov	ds:[YCOS],eax
	
	mov	eax,ds:[SIN1]
	mov	ebx,SIZE_Y/2*256
	mul	ebx
	shrd	eax,edx,8
	mov	ds:[YSIN],eax
	
	mov	eax,ds:[CNX]
	mov	ds:[GX],eax
	mov	eax,ds:[CNY]
	mov	ds:[GY],eax
	
				;符号で4つに場合分けする
	cmp	ds:[TH],63
	jbe	case1
	
	cmp	ds:[TH],127
	jbe	case2
	
	cmp	ds:[TH],191
	jbe	case3
	
	jmp	case4
dsp	endp

case1	proc
	mov	eax,ds:[XCOS]
	sub	ds:[GX],eax
	mov	eax,ds:[YSIN]
	add	ds:[GX],eax
	
	mov	eax,ds:[XSIN]
	shl	eax,1
	sub	ds:[GY],eax
	mov	eax,ds:[YCOS]
	shl	eax,1
	sub	ds:[GY],eax
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	shl	ecx,1
	mov	ds:[DDY1],ecx
	shr	edx,1
	mov	ds:[DDX1],edx
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	
	mov	ds:[LOPCNT1],240
	
	align	4
#l1:
	mov	ds:[LOPCNT2],256
	
	align	4
#l2:					;ここが最小ループ
	xor	eax,eax			;
	shld	eax,ebx,8		;
	shld	eax,esi,9		;
	mov	ax,[ebp+eax*2]		;
	stosw				;
	add	esi,ecx			;
	add	ebx,edx			;
					;
	dec	DWORD PTR ds:[LOPCNT2]	;
	jne	short #l2		;
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	sub	esi,ds:[DDX1]
	add	ebx,ds:[DDY1]
	mov	ds:[GY],ebx
	mov	ds:[GX],esi
	
	dec	DWORD PTR ds:[LOPCNT1]
	jne	#l1
	
	ret
case1	endp

case2	proc
	mov	eax,ds:[XCOS]
	add	ds:[GX],eax
	mov	eax,ds:[YSIN]
	add	ds:[GX],eax
	
	mov	eax,ds:[XSIN]
	shl	eax,1
	sub	ds:[GY],eax
	mov	eax,ds:[YCOS]
	shl	eax,1
	add	ds:[GY],eax
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	shl	ecx,1
	mov	ds:[DDY1],ecx
	shr	edx,1
	mov	ds:[DDX1],edx
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	
	mov	ds:[LOPCNT1],240
	
	align	4
#l1:
	mov	ds:[LOPCNT2],256
	
	align	4
#l2:
	xor	eax,eax
	shld	eax,ebx,8
	shld	eax,esi,9
	mov	ax,[ebp+eax*2]
	stosw
	sub	esi,ecx
	add	ebx,edx
	
	dec	DWORD PTR ds:[LOPCNT2]
	jne	short #l2
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	sub	esi,ds:[DDX1]
	sub	ebx,ds:[DDY1]
	mov	ds:[GY],ebx
	mov	ds:[GX],esi
	
	dec	DWORD PTR ds:[LOPCNT1]
	jne	#l1
	
	ret
case2	endp

case3	proc
	mov	eax,ds:[XCOS]
	add	ds:[GX],eax
	mov	eax,ds:[YSIN]
	sub	ds:[GX],eax
	
	mov	eax,ds:[XSIN]
	shl	eax,1
	add	ds:[GY],eax
	mov	eax,ds:[YCOS]
	shl	eax,1
	add	ds:[GY],eax
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	shl	ecx,1
	mov	ds:[DDY1],ecx
	shr	edx,1
	mov	ds:[DDX1],edx
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	
	mov	ds:[LOPCNT1],240
	
	align	4
#l1:
	mov	ds:[LOPCNT2],256
	
	align	4
#l2:
	xor	eax,eax
	shld	eax,ebx,8
	shld	eax,esi,9
	mov	ax,[ebp+eax*2]
	stosw
	sub	esi,ecx
	sub	ebx,edx
	
	dec	DWORD PTR ds:[LOPCNT2]
	jne	short #l2
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	add	esi,ds:[DDX1]
	sub	ebx,ds:[DDY1]
	mov	ds:[GY],ebx
	mov	ds:[GX],esi
	
	dec	DWORD PTR ds:[LOPCNT1]
	jne	#l1
	
	ret
case3	endp

case4	proc
	mov	eax,ds:[XCOS]
	sub	ds:[GX],eax
	mov	eax,ds:[YSIN]
	sub	ds:[GX],eax
	
	mov	eax,ds:[XSIN]
	shl	eax,1
	add	ds:[GY],eax
	mov	eax,ds:[YCOS]
	shl	eax,1
	sub	ds:[GY],eax
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	shl	ecx,1
	mov	ds:[DDY1],ecx
	shr	edx,1
	mov	ds:[DDX1],edx
	
	mov	ecx,ds:[DDX]
	mov	edx,ds:[DDY]
	
	mov	ds:[LOPCNT1],240
	
	align	4
#l1:
	mov	ds:[LOPCNT2],256
	
	align	4
#l2:
	xor	eax,eax
	shld	eax,ebx,8
	shld	eax,esi,9
	mov	ax,[ebp+eax*2]
	stosw
	add	esi,ecx
	sub	ebx,edx
	
	dec	DWORD PTR ds:[LOPCNT2]
	jne	short #l2
	
	mov	ebx,ds:[GY]
	mov	esi,ds:[GX]
	add	esi,ds:[DDX1]
	add	ebx,ds:[DDY1]
	mov	ds:[GY],ebx
	mov	ds:[GX],esi
	
	dec	DWORD PTR ds:[LOPCNT1]
	jne	#l1
	
	ret
case4	endp

tri	proc		;三角関数をセットする
	mov	al,ds:[TH]
	cmp	al,128
	jb	#l1
	sub	al,128
#l1:
	cmp	al,64
	jbe	#l2
	sub	al,128
	neg	al
#l2:
	movzx	ax,al
	movzx	eax,ax
	mov	bx,ds:[TRI_TBL+eax*2]
	mov	ds:[SIN],bx
	mov	al,ds:[TH]
	add	al,64
	cmp	al,128
	jb	#l3
	sub	al,128
#l3:
	cmp	al,64
	jbe	#l4
	sub	al,128
	neg	al
#l4:
	movzx	ax,al
	movzx	eax,ax
	mov	bx,ds:[TRI_TBL+eax*2]
	mov	ds:[COS],bx
	ret
tri	endp

chg_scr	proc
	cmp	ds:[scr_pg],0
	je	#l1
	
	mov	edi,00000h
	mov     dx,0440h
        mov     al,17
        out     dx,al
        mov     dx,0442h
        mov     ax,8000h
        out     dx,ax
	mov	ds:[scr_pg],0
	ret
#l1:
	mov	edi,20000h
	mov     dx,0440h
        mov     al,17
        out     dx,al
        mov     dx,0442h
        mov     ax,0
        out     dx,ax
	mov	ds:[scr_pg],1
	ret
chg_scr	endp

CODE	ends


DATA	segment
	assume	ds:DATA
	align 4
CNX	dd	(SIZE_X/2)*00800000h
CNY	dd	(SIZE_Y/2)*01000000h
XSIN	dd	0
XCOS	dd	0
YSIN	dd	0
YCOS	dd	0
SIN	dw	0
COS	dw	0
SIN1	dd	0
COS1	dd	0
GX	dd	0
GY	dd	0
DDX	dd	0
DDY	dd	0
LOPCNT1 dd	0
LOPCNT2 dd	0
DDX1	dd	0
DDY1	dd	0
scr_pg	dd	0
TRI_TBL	dw	0000h,0324h,0648h,096Bh,0C8Ch,0FABh,12C8h,15E2h
	dw	18F9h,1C0Ch,1F1Ah,2224h,2528h,2827h,2B1Fh,2E11h
	dw	30FCh,33DFh,36BAh,398Dh,3C57h,3F17h,41CEh,447Bh
	dw	471Dh,49B4h,4C40h,4EC0h,5134h,539Bh,55F6h,5843h
	dw	5A82h,5CB4h,5ED7h,60ECh,62F2h,64E9h,66CFh,68A7h
	dw	6A6Eh,6C24h,6DCAh,6F5Fh,70E3h,7255h,73B6h,7505h
	dw	7642h,776Ch,7885h,798Ah,7A7Dh,7B5Dh,7C2Ah,7CE4h
	dw	7D8Ah,7E1Eh,7E9Dh,7F0Ah,7F62h,7FA7h,7FD9h,7FF6h
	dw	8000h
JOYDAT	db	0
TH	db	0
ZM	dw	0100h
credit	db	'Copy right T.Higashi 1990'
DATA	ends


STACK	segment stack
	assume	ss:STACK
	db	300000 dup(?)
STACK	ends

	end	MAIN
