rotatebegin=$
;было в среднем 750t на вершину, включая матрицу
;(без матрицы 652t, включая вход =125/8=16t, т.е. без входа 636t/вершина)
;(матрица=1702t по трём осям, 404 по двум осям)
;(но надо учитывать построение засечек 6156t - сделать 15 засечек вместо 31 и пропустить одну таблицу из 9?)
;(230t процедура деления, включая call-ret(27), jr(12), shift(32), add(7) =78t)
;(голое деление ~152t)
;т.е. всё, кроме процедуры деления, составляет около 176t
;[-3t за счёт add a,d вместо константы (возвращено назад для засечек)]
;-35t за счёт rangeshift одним джампом
;-17t за счёт squash только в range0
;-24t за счёт MATRIXDIV2 (весь сдвиг засунуть в матрицу невыгодно - слишком часто считать матрицу даже при отсортированных объектах)
;DIVBYTAB примерно 450t (431..474) на вершину (ROTVERTEX2), не считая матрицу

XADD=xbase;#c0
YADD=ybase;#80;#c0

;_reg=0 ;0=A, 1=B, 2=C, 3=D, 4=E, 5=H, 6=L

	macro LDREG value
	if _isx
_=#ff&(value+XADD)
	else
_=#ff&(value+YADD)
	endif
	if _reg==0
	ld a,_
	endif
	if _reg==1
	ld b,_
	endif
	if _reg==2
	ld c,_
	endif
	if _reg==3
	ld d,_
	endif
	if _reg==4
	ld e,_
	endif
	if _reg==5
	ld h,_
	endif
	if _reg==6
	ld l,_
	endif
	endm

	macro LDREGA
	if _reg==0
	;ld a,a
	endif
	if _reg==1
	ld b,a
	endif
	if _reg==2
	ld c,a
	endif
	if _reg==3
	ld d,a
	endif
	if _reg==4
	ld e,a
	endif
	if _reg==5
	ld h,a
	endif
	if _reg==6
	ld l,a
	endif
	endm

	macro DECREG
	if _k==-1
	INCREG
	else
	if _reg==0
	dec a
	endif
	if _reg==1
	dec b
	endif
	if _reg==2
	dec c
	endif
	if _reg==3
	dec d
	endif
	if _reg==4
	dec e
	endif
	if _reg==5
	dec h
	endif
	if _reg==6
	dec l
	endif
	endif
	endm

	macro INCREG
	if _k==1
	DECREG
	else
	if _reg==0
	inc a
	endif
	if _reg==1
	inc b
	endif
	if _reg==2
	inc c
	endif
	if _reg==3
	inc d
	endif
	if _reg==4
	inc e
	endif
	if _reg==5
	inc h
	endif
	if _reg==6
	inc l
	endif
	endif
	endm


;a/b->a
	macro DODIVBYTAB
	 if _isx
	;inc h;ld h,t1divz/256
	ld l,e;b
	ld d,(hl) ;1/z, потом используется в ~_isx
	inc h
	sub d
	ld l,a ;a-b
	add a,d
	add a,d
	ld c,a ;a+b
;a-b = -#6b..#70
	ld a,(hl) ;-sqrsigned (bit9=1, bit8=1, bit7=1)
	inc h
	ld l,c ;a+b
;a+b = #11..#ec (или ..#7f???)
;(при DIVMAX=#49) #11..#b5
	add a,(hl) ;sqrpos (bit9="L>=#b6?", bit8=L7? (с #b6? опять 0)) ;при _divisor=17 другие числа

	else ;~_isx

	dec h
	sub d ;1/z заранее посчитано в _isx
	ld l,a ;a-b
	add a,d ;1/z заранее посчитано в _isx
	add a,d ;1/z заранее посчитано в _isx
	ld d,a ;a+b
;a-b = -#6b..#70
	ld a,(hl) ;-sqrsigned (bit9=1, bit8=1)
	inc h
	ld l,d ;a+b
;a+b = #11..#ec (или ..#7f???)
;(при DIVMAX=#49) #11..#b5
	add a,(hl) ;sqrpos (bit9="L>=#b6?", bit8=L7? (с #b6? опять 0)) ;при _divisor=17 другие числа
	 endif ;~_isx
	 ;rl l
	 ;jp p,$+3+2
	 ;ld a,127
	srl a ;лишний бит точности
	srl a ;лишний бит точности для 4x4
	;srl a ;лишний бит точности для 4x4
	endm

;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


	macro DIV8NEG div8posaddr,div8_128addr
_k=-1
	; or a
	;jp p,div8pos
	if DIVCHECKOVERFLOW
	if DIVCHECKOVERFLOW==2
	;урезание делимого до DIVMAX
	cp #ff&(-DIVMAX)
	jr nc,$+4
	ld a,#ff&(-DIVMAX)
	else
	;отработка переполнения для отрицательных
	add a,e;b
	jr c,$+2+1+2 +1 ;+2 ;CY: |a|<b
	add a,e;b
	jr nc,div8_128addr ;CY: |a|<2*b
	 ;jr z,div8_128addr ;|a|=2*b
	sub e;b
	sub e;b
	endif
	endif

	neg
	DODIVBYTAB
	cpl;neg
	if _isx
	add a,XADD+1
	else
	add a,YADD+1
	endif
	LDREGA
	endm ;DIV8NEG


	macro DIV8POS div8posaddr,div8_127addr
_k=1
	if DIVCHECKOVERFLOW
	if DIVCHECKOVERFLOW==2 ;урезание делимого до DIVMAX
	cp DIVMAX
	jr c,$+4
	ld a,DIVMAX
	else ;отработка переполнения для положительных
	sub e;b
	jr c,$+2+1+2 ;CY: a<b
	cp e;b
	jr nc,div8_127addr ;CY: a<2*b
	add a,e;b
	endif
	endif
	
	DODIVBYTAB
	if _isx
	add a,XADD
	else
	add a,YADD
	endif
	LDREGA
	endm ;DIV8POS

;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&77

;----------- X
_isx=1
_reg=2 ;C ;0=A, 1=B, 2=C, 3=D, 4=E, 5=H, 6=L
div8xinch
	inc h ;for DIVBYTAB
;a=-127..+127
div8x
         sra a;xor a ;z=0
rangeshiftpatch=$+1
	jr $+2
;rangeshiftrange0
	if MATRIXDIV2==0
	 sra a ;объект половинного размера
	 sra c
	 sra b;e
	endif
;a=-63..+63
zspaceshift=$+1
	add a,#40;d
	ld e,a;b,a
;squash range0 only
rotatesquashcp=$+1
	 cp MINZ;#30 ;#30 для range0 ;#10 или лучше не надо для range1 (#28(minZ)-#18(maxz)=#10)
	 jp p,div8xnosquash
	 ld e,MINZ;b,MINZ;#30 ;сплющивание по Z+z
	 jp div8xnosquash
rangeshiftjrbase=$-(rangeshiftpatch+1)
	dup rangeshiftmax
	sra a ;z
	sra c ;x
	sra b;e ;y
	edup
	if MATRIXDIV2==0
	 sra a ;объект половинного размера
	 sra c
	 sra b;e
	endif
;a=-63..+63
zspaceshift2=$+1
	add a,#40;d
	ld e,a;b,a
;squash range0 only
;rotatesquashcp=$+1
;	 cp MINZ;#30 ;#30 для range0 ;#10 или лучше не надо для range1 (#28(minZ)-#18(maxz)=#10)
;	 jp p,div8xnosquash
;	 ld e,MINZ;b,MINZ;#30 ;сплющивание по Z+z
div8xnosquash
	 ld a,c ;x
xspaceshift=$+1
	add a,0
;a/b => a
;f=флаги после сложения двух знаковых
;+-8/+7 => +-1.6 (т.е. можно перспективу в удвоенном створе экрана, но реально зависит от делителя - при b=255 будет только один створ экрана)
;для правильного деления надо a < 2*b (иначе надо формировать переполнение)
	jp po,div8xposjp ;pe=переполнение
;S=9-й бит результата инверсный
	jp m,div8xpos
div8xneg
	DIV8NEG div8xpos,div8x_128
	jp div8y
div8x_128
	;inc h;ld h,t1divz/256
	ld l,e;b ;z
	ld d,(hl) ;1/z, потом используется в ~_isx
	ld h,trotsqrpos/256
	LDREG 128 ;ld a,128
	jp div8y
div8x_127
	;inc h;ld h,t1divz/256
	ld l,e;b ;z
	ld d,(hl) ;1/z, потом используется в ~_isx
	ld h,trotsqrpos/256
	LDREG 127 ;ld a,127
	jp div8y
div8xposjp
;S=9-й бит результата
	jp m,div8xneg
div8xpos
	DIV8POS div8xpos,div8x_127
	jp div8y

;---------- Y
_isx=0
_reg=1 ;B
;a=-127..+127
div8y
	ld a,b;e ;y
yspaceshift=$+1
	add a,0
;a/b => a
;f=флаги после сложения двух знаковых
;+-8/+7 => +-1.6 (т.е. можно перспективу в удвоенном створе экрана, но реально зависит от делителя - при b=255 будет только один створ экрана)
;для правильного деления надо a < 2*b (иначе надо формировать переполнение)
	jp po,div8yposjp ;pe=переполнение
;S=9-й бит результата инверсный
	jp m,div8ypos
div8yneg
	DIV8NEG div8ypos,div8y_128
	ret
div8y_128
	LDREG 128 ;ld a,128
	ret
div8y_127
	LDREG 127 ;ld a,127
	ret
div8yposjp
;S=9-й бит результата
	jp m,div8yneg
div8ypos
	DIV8POS div8ypos,div8y_127
	ret


;######################################################

	macro CALLDIVX val
	ld h,t1divz/256
;a=x=-127..+127
	call div8x
	endm

	MACRO ASDECreg reg
	if reg==0
	dec b
	endif
	if reg==1
	dec d
	endif
	if reg==2
	dec e
	endif
	endm

	MACRO ASINCreg reg
	if reg==0
	inc b
	endif
	if reg==1
	inc d
	endif
	if reg==2
	inc e
	endif
	endm

	MACRO AS reg
;-sz/0/+sz
	ASDECreg reg
	jp m,$+4
	add a,(hl)
	ASINCreg reg
	jp p,$+4
	sub (hl)
	INC L
	ENDM 
;по идее тут надо умножать, но для куба хватит взять +-значение повёрнутой оси

	macro ROTATEBEGIN
	ld (sortobjnexthl),sp
	ld sp,vertbufend
	endm

;-----------------------------

	display "rotate size=",$-rotatebegin
