misc/m256test.s
;========================================================================================
;  m256test.s
;  Copyright (C) 2003-2026 Makoto Kamada
;
;  This file is part of the XEiJ (X68000 Emulator in Java).
;  You can use, modify and redistribute the XEiJ if the conditions are met.
;  Read the XEiJ License for more details.
;  https://stdkmd.net/xeij/
;========================================================================================

;----------------------------------------------------------------
;  m256test.x
;	768x512ドット256色モードの画面に画像を描きます。
;	m256.xを常駐させてから実行します。
;	>m256.x -e11
;	>m256test.x
;----------------------------------------------------------------

	.include	control2.mac
	.include	crtc.equ
	.include	doscall.mac
	.include	fefunc.mac
	.include	iocscall.mac
	.include	misc.mac
	.include	push2.mac
	.include	vicon.equ

	supervisormode

;画面モードを確認する
	moveq.l	#7,d0
	and.b	CRTC_MODE_BYTE,d0
	subq.b	#1,d0
	if	ne
		pushstr	<'画面モードが違います',13,10>
		DOS	_PRINT
		addq.l	#4,sp
		goto	usermode_exit
	endif

;パレットを設定する
	lea.l	VICON_GPALET,a2
	move.w	#0,(a2)+		;0は黒
	move.l	#(0<<16)|(31<<8)|21,d1	;h=0,s=31,v=21
	move.l	#1<<16,d2		;h=1
	move.w	#192-1,d3
	for	d3
		IOCS	_HSVTORGB
		move.w	d0,(a2)+
		add.l	d2,d1			;h++
	next

;リングを描く
d2XH	reg	d4
d2XL	reg	d5			;2*x  -2*384~2*383
d3YH	reg	d6
d3YL	reg	d7			;3*y  -3*256~3*255
a2X	reg	a2			;2*x  -2*384~2*383
a3Y	reg	a3			;3*y  -3*256~3*255
aP0	reg	a4			;ページ0  左1/3 中1/3  -2*384~2*127
aP1R	reg	a5			;ページ1右半分  中1/3  -2*128~2*127
aP1L	reg	a6			;ページ1左半分  右1/3  2*128~2*383
	lea.l	-16(sp),sp
	lea.l	$00C00000+2*384,aP0
	lea.l	$00C80200+2*128,aP1R
	lea.l	$00C80000-2*128,aP1L
;Y方向のループ 上→下
	movea.l	#3*255,a3Y		;a3Y=3*y  3*255→-3*256
	do
		move.l	a3Y,d0			;d0=3*y
		FPACK	__LTOD			;d0d1=3*y
		move.l	d0,d3YH
		move.l	d1,d3YL			;d3Y=3*y
	;X方向のループ 左→右
		movea.l	#-2*384,a2X		;a2X=2*x  -2*384→2*383
		do
			move.l	a2X,d0			;d0=2*x
			FPACK	__LTOD			;d0d1=2*x
			move.l	d0,d2XH
			move.l	d1,d2XL			;d2X=2*x
		;絶対値(の2乗)を求める
		;	move.l	d2XH,d0
		;	move.l	d2XL,d1			;d0d1=2*x
			jbsr	squ			;d0d1=(2*x)^2
			move.l	d0,d2
			move.l	d1,d3			;d2d3=(2*x)^2
			move.l	d3YH,d0
			move.l	d3YL,d1			;d0d1=3*y
			jbsr	squ			;d0d1=(3*y)^2
			FPACK	__DADD			;d0d1=(2*x)^2+(3*y)^2
			FPACK	__DTOL			;d0=(2*x)^2+(3*y)^2
			ifor	<cmp.l #250*250,d0>,lo,<cmp.l #750*750,d0>,hi	;範囲外
			;範囲外のパレットは0
				clr.w	d0			;d0=palet
			else				;範囲内
			;偏角を0~2*piの範囲で求める
				move.l	d3YH,d0
				move.l	d3YL,d1			;d0d1=3*y
				move.l	d2XH,d2
				move.l	d2XL,d3			;d2d3=2*x
				jbsr	atan2			;d0d1=atan2(3*y,2*x)=t  -pi~pi
				FPACK	__DTST			;t<=>0
				if	lt			;t<0  -pi~0
					move.l	d0,d2
					move.l	d1,d3			;d2d3=t
					move.l	#2,d0
					FPACK	__LTOD			;d0d1=2
					FPACK	__NPI			;d0d1=2*pi
					FPACK	__DADD			;d0d1=t+2*pi  pi~2*pi
				endif
			;偏角をパレット1~192に変換する
				move.l	d0,d2
				move.l	d1,d3			;d2d3=0~2*pi
				move.l	#2,d0
				FPACK	__LTOD			;d0d1=2
				FPACK	__NPI			;d0d1=2*pi
				exg.l	d0,d2
				exg.l	d1,d3			;d0d1=0~2*pi,d2d3=2*pi
				FPACK	__DDIV			;d0d1=0~1
				move.l	d0,d2
				move.l	d1,d3			;d2d3=0~1
				move.l	#192,d0
				FPACK	__LTOD			;d0d1=192
				FPACK	__DMUL			;d0d1=0~192
				FPACK	__DTOL			;d0=0~192
				if	<cmp.w #191,d0>,hi
					clr.w	d0			;d0=0~191
				endif
				addq.w	#1,d0			;d0=1~192
			endif
		;グラフィック画面に書き込む
			if	<cmpa.l #2*127,a2X>,le	;-2*384~2*127
				move.w	d0,(aP0,a2X.l)		;左1/3 中1/3
				if	<cmpa.l #-2*128,a2X>,ge	;-2*128~2*127
					move.w	d0,(aP1R,a2X.l)		;中1/3
				endif
			else				;2*128~2*383
				move.w	d0,(aP1L,a2X.l)		;右1/3
			endif
			addq.l	#2,a2X
		while	<cmpa.l #2*383,a2X>,le
		lea.l	2*512(aP0),aP0
		lea.l	2*512(aP1R),aP1R
		lea.l	2*512(aP1L),aP1L
		subq.l	#3,a3Y
	while	<cmpa.l #-3*256,a3Y>,ge
	lea.l	16(sp),sp

usermode_exit:
	usermode
	DOS	_EXIT

;atan2(y,x)
;<d0d1.d:y
;<d2d3.d:x
;>d0d1.d:atan2(y,x)
atan2:
	push	d2-d7			;d0d1=y,d2d3=x
	moveq.l	#0,d6
	FPACK	__DTST			;y<=>0
	if	gt			;0<y
		moveq.l	#1,d6
	elif	lt			;y<0
		moveq.l	#-1,d6			;d6=sgn(y)
		FPACK	__DNEG			;d0d1=abs(y)
	endif
	move.l	d0,d4
	move.l	d1,d5			;d4d5=abs(y)
	move.l	d2,d0
	move.l	d3,d1			;d0d1=x
	moveq.l	#0,d7
	FPACK	__DTST			;x<=>0
	if	gt			;0<x
		moveq.l	#1,d7
	elif	lt			;x<0
		moveq.l	#-1,d7			;d7=sgn(x)
		FPACK	__DNEG			;d0d1=abs(x)
	endif
	if	<tst.l d6>,eq		;y==0
		if	<tst.l d7>,eq		;y==0 && x==0
			move.l	#$7FFFFFFF,d0
			move.l	#$FFFFFFFF,d1	;d0d1=nan
		elif	gt			;y==0 && 0<x
			moveq.l	#0,d0
			moveq.l	#0,d1			;d0d1=0
		else				;y==0 && x<0
			FPACK	__PI			;d0d1=pi
		endif
	elif	<tst.l d7>,eq		;y!=0 && x==0
		FPACK	__PI			;d0d1=pi
		FPACK	__DDIVTWO		;d0d1=pi/2
		if	<tst.l d6>,lt		;x==0 && y<0
			FPACK	__DNEG			;d0d1=-pi/2
		endif
	else				;y!=0 && x!=0
		move.l	d4,d2
		move.l	d5,d3			;d2d3=abs(y)
		FPACK	__DCMP			;abs(x)<=>abs(y)
		if	ge			;abs(y)<=abs(x)
			exg.l	d0,d2
			exg.l	d1,d3			;d0d1=abs(y),d2d3=abs(x)
			FPACK	__DDIV			;d0d1=abs(y)/abs(x)
			FPACK	__ATAN			;d0d1=atan(abs(y)/abs(x))
		else				;abs(x)<abs(y)
			FPACK	__DDIV			;d0d1=abs(x)/abs(y)
			FPACK	__ATAN			;d0d1=atan(abs(x)/abs(y))
			move.l	d0,d2
			move.l	d1,d3			;d2d3=atan(abs(x)/abs(y))
			FPACK	__PI			;d0d1=pi
			FPACK	__DDIVTWO		;d0d1=pi/2
			FPACK	__DSUB			;d0d1=pi/2-atan(abs(x)/abs(y))
		endif
		if	<tst.l d7>,lt		;x<0
			move.l	d0,d2
			move.l	d1,d3			;d2d3=t
			FPACK	__PI			;d0d1=pi
			exg.l	d0,d2
			exg.l	d1,d3			;d0d1=t,d2d3=pi
			FPACK	__DSUB			;d0d1=t-pi
		endif
		if	<cmp.l d6,d7>,ne	;sgn(x)!=sgn(y)
			FPACK	__DNEG			;d0d1=-t
		endif
	endif
	pop
	rts

;squ(x)
;<d0d1.d:x
;>d0d1.d:x^2
squ:
	push	d2-d3
	move.l	d0,d2
	move.l	d1,d3
	FPACK	__DMUL
	pop
	rts