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