fastdiv=0;1

TPOLYS=#6000
;исходные координаты:
VTX3DI=TPOLYS+#500 ;,#300
VTX3DIH=VTX3DI/256
;координаты после поворота:
VTX3D=VTX3DI+#300 ;,#300
VTX3DH=VTX3D/256
VTX3DY=VTX3D+#100
VTX3DZ=VTX3D+#200

gschmap256=#0040
gschmaphgt=64;128
gschmapwid=64
gschmapend=#4000+gschmap256 

bigchmap=0
clipchmap=0;1
lambert=0
;lambert=32-16 ;gs
;lambertshr=3 ;8 страниц gspgtex
;lambertmax=7
brutemul=0;1 ;умножение сложением
incW=0 ;1=исключает выскакивание за текстуру, но дёргается
tmapnosp=1 ;можно EI (иначе полигоны в стеке, сканлайны в стеке - теоретически можно и там EI)

trimaxh=63

tmapclipwid=1 ;по таблице

singlepage=1

        MACRO setpgfast pg,pgaddr
        ENDM

        MACRO setpgafast pgaddr
        ENDM

       IF tmapnosp
        MACRO GETRPBC
        LD c,(IX+_ixpointer)
        LD b,(IX+_ixpointer+1)
_ixpointer=_ixpointer+2
        ENDM 
        MACRO GETRPDE
        LD e,(IX+_ixpointer)
        LD d,(IX+_ixpointer+1)
_ixpointer=_ixpointer+2
        ENDM 
        MACRO GETRPHL
        LD l,(IX+_ixpointer)
        LD h,(IX+_ixpointer+1)
_ixpointer=_ixpointer+2
        ENDM 
       ELSE 
        MACRO GETRPBC
        POP bc
        ENDM 
        MACRO GETRPDE
        POP de
        ENDM 
        MACRO GETRPHL
        POP hl
        ENDM 
       ENDIF 

;этот макрос рисует все полигоны
       MACRO DRAWPOLYS
        LD (DPOLSP),SP
        LD SP,tricallstack
        JP TRIPOP
tricallreter
DPOLSP=$+1
        LD SP,0
       ENDM 

       MACRO DBS addr,n,step
_=addr
       DUP n
        DB _
_=_+step
       EDUP 
       ENDM 
       MACRO JRS addr,n,step
_=addr
       DUP n
        JR _
_=_+step
       EDUP 
       ENDM 
       MACRO JPS addr,n,step
_=addr
       DUP n
        JP _
_=_+step
       EDUP 
       ENDM 

       IF tmapclipwid
ntexjp=22
ntexjr=14 ;jp+jr<=36
ntexfast=23
       ELSE 
ntexjp=20
ntexjr=15 ;<=17
ntexfast=16
       ENDIF 
trimaxl=ntexjp+ntexjr+ntexfast
        DISPLAY "trimaxl=",trimaxl

       MACRO INNERLOOPINC n
       DUP n
        LD HL,0
        ADD HL,BC
        LD A,(HL)
        LD (DE),A
        INC E
       EDUP 
       ENDM

       MACRO INNERLOOPDEC n
       DUP n
        LD HL,0
        ADD HL,BC
        LD A,(HL)
        LD (DE),A
        DEC E
       EDUP 
       ENDM

       MACRO MTEXTURERINC
        DS 255&(253-((ntexjp+ntexjr)*7)-$)
TEXTURERINCMAX
        INNERLOOPINC ntexjp+ntexjr
        JP TEXTURERINC
        DISPLAY $,"=#XX00"
       IF tmapclipwid==0
        DB 255&TEXTURERINCQ ;wid=0
        DB 255&TEXTURERINCQ ;wid=-1
       ENDIF 
TEXTURERINCJR
        JRS ntexjp*7+TEXTURERINCMAX,ntexjr,+7
TEXTURERINCJP
        JPS TEXTURERINCMAX,ntexjp,+7
TEXTURERINC
        INNERLOOPINC ntexfast-1
        LD A,(BC)
        LD (DE),A
TEXTURERINCQ
       IF tmapnosp
        ex af,af' 
        INC A
        JP NZ,EXATRILINE
       ENDIF 
        RET 
       IF tmapclipwid
        DS 255&(-$)
       ELSE 
        DS ($/256+1)*256-trimaxl-$
        DBS 255&TEXTURERINCJP,ntexjp,+3
        DBS 255&TEXTURERINCJR,ntexjr,+2
        DBS 255&TEXTURERINC0,ntexfast,+7
       ENDIF 
        DISPLAY $,"=#XX00"
       IF tmapclipwid
;todo со сдвигом вм.TRINEGWIDTH
        DB 255&TEXTURERINCQ
        DBS 255&TEXTURERINCQ-2,ntexfast,-7
        DBS (ntexjr-1)*2+(255&TEXTURERINCJR),ntexjr,-2
        DBS (ntexjp-1)*3+(255&TEXTURERINCJP),ntexjp,-3
        DS 128-trimaxl,255&TEXTURERINCJP
        DS 127,255&TEXTURERINCQ
        DISPLAY $,"=#XX00!"
       ENDIF ;tmapclipwid
       ENDM 

       MACRO MTEXTURERDEC
        DS 255&(253-((ntexjp+ntexjr)*7)-$)
TEXTURERDECMAX
        INNERLOOPDEC ntexjp+ntexjr
        JP TEXTURERDEC
        DISPLAY $,"=#XX00"
       IF tmapclipwid==0
        DB 255&TEXTURERDECQ ;wid=0
        DB 255&TEXTURERDECQ ;wid=-1
       ENDIF 
TEXTURERDECJR
        JRS ntexjp*7+TEXTURERDECMAX,ntexjr,+7
TEXTURERDECJP
        JPS TEXTURERDECMAX,ntexjp,+7
TEXTURERDEC
        INNERLOOPDEC ntexfast-1
        LD A,(BC)
        LD (DE),A
TEXTURERDECQ
       IF tmapnosp
        ex af,af' 
        INC A
        JP NZ,EXATRILINE
       ENDIF 
        RET 
       IF tmapclipwid
        DS 255&(-$)
       ELSE 
        DS ($/256+1)*256-trimaxl-$
        DBS 255&TEXTURERDECJP,ntexjp,+3
        DBS 255&TEXTURERDECJR,ntexjr,+2
        DBS 255&TEXTURERDEC,ntexfast,+7
       ENDIF 
        DISPLAY $,"=#XX00"
       IF tmapclipwid
;todo со сдвигом вм.TRINEGWIDTH
        DB 255&TEXTURERDECQ-2
        DS 128,255&TEXTURERDECQ
        DS 128-trimaxl,255&TEXTURERDECJP
        DBS 255&TEXTURERDECJP,ntexjp,+3
        DBS 255&TEXTURERDECJR,ntexjr,+2
        DBS 255&TEXTURERDEC,ntexfast-1,+7
        DISPLAY $,"=#XX00!"
       ENDIF ;tmapclipwid
       ENDM 

       MACRO PATCHV vaddr
        IF ((vaddr-_)&#8000)!=0 ;<0 ;IFN _V-_<1&1 ;texturerq-2-6
        ADD HL,DE ;пропускаем первый
        ENDIF 
        LD (vaddr),HL
       ENDM

       MACRO PATCHU uaddr
        IF ((uaddr-_)&#8000)!=0 ;<0 ;IFN _U-_<1&1 ;texturerq-2-6
        ADD HL,DE ;пропускаем первый
        ENDIF 
        LD A,H
        LD (uaddr),A
       ENDM

       MACRO PATCHVUCODE texturer,texturerq,texturermax,system
_=texturerq-2-6
_V=_
_V2=system+253-6
__=texturer
___=texturermax

       ;DUP (trimaxl+3)/4 ;62/4=15
       ; include "patchvu.asm"
        ;IF ((_U-___)&#8000)==0 ;>=0 ;IF0 _U-___<1&1 ;texturermax
        ;EXX 
        ;INC B
        ;RET Z
        ;ENDIF 
       ;EDUP 
       ;ret

        include "patchvu.asm"
        
       ENDM 
       
        DS 255&(-$)
INCSYSTEM
        MTEXTURERINC 
        DISPLAY "TEXTURERINC=",TEXTURERINC
PATCHVUINC
        PATCHVUCODE TEXTURERINC,TEXTURERINCQ,TEXTURERINCMAX,INCSYSTEM
        DISPLAY "patchVUINCend=",$
        DS 255&(-$)
DECSYSTEM
        MTEXTURERDEC 
        DISPLAY "TEXTURERDEC=",TEXTURERDEC
PATCHVUDEC
        PATCHVUCODE TEXTURERDEC,TEXTURERDECQ,TEXTURERDECMAX,DECSYSTEM
        DISPLAY "patchVUDECend=",$

;правый треугольник
;  1
;4/>2  - строка W (самая широкая)
;3
;левый треугольник
;   1
;2</4 - строка W (самая широкая)
;  3
;макс 63x63

;LX или (IX+12) = t*2 ;используется в VU....
;t=абстрактная координата в текстуре в точке 4
;t=64*H12/H13 неточно
;t=0.5+H12*dUV13 точно (6.0=6.0*6.8)
;деления в dU,dV нужны, чтобы узнать шаг, с которым
;за W проходов мы погасим расстояние до бордюра текстуры (0.5)
;это +-t или +-(texarea-t) - поэтому t считается без бордюра

;+-7.8=+-6.0(+-HHHHHH0)/6.0(00LLLLLL)

;l/-h -> de
        MACRO DIVHLTOHL
        xor a
        sub l
        ld l,h ;<0
        call FDIVB ;HL(SGN)=A(SGN)/L  S=SIGN
        ENDM

;qqqq: c6/fe = 1d50
;log:  c6/fe = e(97-08) = e(8f) = -e12a = 1ed6
;калькулятор: 3a00/2 = 1d00
;глюки были на треугольнике с H12=0 из-за t>#100 (расширил таблицу div4)

;l<0
;FASTDIV 8/8=8.8
;HL(SGN)=A(SGN)/L  S=SIGN
FDIVB
        if fastdiv
        ;push af
        ;xor a
        ;sub l
        ;ld l,a
        ;pop af
        ld e,l
        ld l,a ;signed
;+-l/e -> hl (+-6.0/6.0 -> +-6.8)
        ld h,divlog/256
        ld a,(hl) ;log(l)
        ld l,e ;unsigned
        sub (hl) ;log(e)
        ld l,a ;log (l/e)
        inc h
        ;ld h,divexp/256
        ld a,(hl) ;exp(log(l/e)) = l/e
        inc h
        ld h,(hl)
        ld l,a ;hl=l/e
        xor a
        sub l
        ld l,a
        sbc a,h
        sub l
        ld h,a
        ret
;qqqq
        else
        
        LD H,TBLOG2/256
	 jp p,FDIVBNEG ;CY нельзя для вычитания знаковых
        LD E,(HL)
        INC H
        LD D,(HL)
        LD L,A
        LD A,(HL)
        DEC H
        ADD A,8
        LD L,(HL)
        LD H,A
        SBC HL,DE ;=LOG(A/L)
        JP P,DIVC1
DIVCZ   LD HL,0 ;LOG<0 => результат <1 =0
        RET 
DIVC1
        LD A,H
        LD H,TB2X/256
        LD L,(HL)
        LD H,1
        cp 8 ;SUB 8
	 cpl
        JR NC,DIVC2
	 add a,8
        LD ($+4),A
        JR NZ,$
       DUP 7
        ADD HL,HL
       EDUP 
        LD L,H
	ld H,0
        RET 
DIVC2
	 add a,#10
        LD ($+4),A
        JR NZ,$
       DUP 7
        ADD HL,HL
       EDUP 
        RET 

FDIVBNEG
	NEG
        LD E,(HL)
        INC H
        LD D,(HL)
        LD L,A
        LD A,(HL)
        DEC H
        ADD A,8
        LD L,(HL)
        LD H,A
        SBC HL,DE ;=LOG(A/L)
        JP M,DIVCZ ;LOG<0 => результат <1 =0
        LD A,H
        LD H,TB2X/256
        LD L,(HL)
        LD H,1
        CP 8
	 cpl
        JR NC,DIVCN2
	 add a,8
        LD ($+4),A
        JR NZ,$
       DUP 7
        ADD HL,HL
       EDUP 
        LD A,h
        CPL 
        LD L,A
        ld h,-1
        INC HL
        RET 
DIVCN2
	 add a,#10
        LD ($+4),A
        JR NZ,$
       DUP 7
        ADD HL,HL
       EDUP 
        XOR A
        SUB L
        LD L,A
        SBC A,H
        SUB L
        LD H,A
        RET 
        endif ;~fastdiv

        if 1==1
        MACRO DIVHLTOHLDE
        DIVHLTOHL
        LD d,h
        ld e,l ;dU
        ENDM
        MACRO LDDIVHL
        LD HL,0
        DIVHLTOHL
        ENDM
        MACRO DIVHL_LSBTOA
        DIVHLTOHL
        ld a,l
        ENDM
        MACRO DIVHL_LSBTOC
        DIVHLTOHL
        ld c,l
        ENDM
        MACRO DIVHL_HSBTOA
        ld a,h
        ENDM
        
         else ;таблица деления в страничке
        
        MACRO DIVHLTOHLDE
        LD E,(HL) ;
        INC L     ;
        LD D,(HL) ;из pgdiv
        LD H,D
        ld L,E ;dU
        ENDM
        MACRO LDDIVHL
        LD HL,(0)
        ENDM
        MACRO DIVHL_LSBTOA
        LD A,(HL)
        ENDM
        MACRO DIVHL_LSBTOC
        LD C,(HL)
        ENDM
        MACRO DIVHL_HSBTOA
        INC L
        LD A,(HL)
        ENDM
        endif
        
;умножение +-6.0=6.0*+-7.8 (A=A~*HL)

       MACRO TRIMULLOOP
       ;LOCAL 
        LD D,H
        ld E,L ;HL=DE для старшей единицы
        ADD A,A
        jr nc,5f;_ADD5
        ADD A,A
        jr nc,4f;_ADD4
        ADD A,A
        jr nc,3f;_ADD3
        ADD A,A
        jr nc,2f;_ADD2
        ADD A,A
        jr nc,1f;_ADD1
        ADD A,A
        jr nc,0f;_ADD0
       ;A=0
        JP 9f;_ADDQ
5;_ADD5   
        ADD HL,HL
        ADD A,A
        jr c,$+3
        ADD HL,DE
4;_ADD4   
        ADD HL,HL
        ADD A,A
        jr c,$+3
        ADD HL,DE
3;_ADD3   
        ADD HL,HL
        ADD A,A
        jr c,$+3
        ADD HL,DE
2;_ADD2   
        ADD HL,HL
        ADD A,A
        jr c,$+3
        ADD HL,DE
1;_ADD1   
        ADD HL,HL
        ADD A,A
        jr c,$+3
        ADD HL,DE
0;_ADD0 ;
       ;A=0
        RL L ;правильное округление
        ADC A,H
9;_ADDQ ;
       ;ENDL 
       ENDM 

;0=bc
;1=de
;2=hl
       MACRO SUBHIGH ra,rb
       IF ra==0
        ld a,b
       ELSE
       IF ra==1
        ld a,d
       ELSE
        ld a,h
       ENDIF
       ENDIF
       IF rb==0
        sub b
       ELSE
       IF rb==1
        sub d
       ELSE
        sub h
       ENDIF
       ENDIF
       ENDM

       MACRO SUBLOW ra,rb
       IF ra==0
        ld a,c
       ELSE
       IF ra==1
        ld a,e
       ELSE
        ld a,l
       ENDIF
       ENDIF
       IF rb==0
        sub c
       ELSE
       IF rb==1
        sub e
       ELSE
        sub l
       ENDIF
       ENDIF
       ENDM
;0=bc
;1=de
;2=hl
       MACRO TRISORT r1,r2,r3
        SUBHIGH r3,r1
        JP Z,TRIQ ;H13=0 ;РАННИЙ ВЫХОД!!!
        LD (mH13),A
        LD (mH13_),A
       IF debug
        CP #C0
        jr c,$
       ENDIF 
        SUBLOW r3,r1
        ;ADD A,A
        LD (l13SLA),A
        SUBHIGH r2,r1
        LD (mH12),A ;0..-63
       IF brutemul
        ADD A,64 ;64..1
        LD (MULJRH12),A
       IF debug
        CP 65
        jr nc,$
       ENDIF 
       ELSE  ;~brutemul
        DEC A ;-1..-64
       IF debug
        CP -64
        jr c,$
       ENDIF 
        ADD A,A
        ADD A,A
        ex af,af' 
       ENDIF 
      SUBHIGH r1,r2 ;0..63
      ;ADD A,A
      LD (H12SLA),A
        SUBLOW r2,r1
        LD (l12),A
        if fastdiv
        ld (l12_2),a
        endif
        ;ADD A,A
        LD (l12SLA),A
        SUBHIGH r3,r2
        LD H,A
       IF debug
        jr z,$+6
        CP #C0
        jr c,$
       ENDIF 
        SUBLOW r3,r2
        ;ADD A,A
        LD L,A
        LD (mHl23),HL ;+22t невыгодно на невидимых
;B,C,D,E,H,L: A>B>C: POP BC,DE,HL: BC:A,DE:B,HL:C
;D,E,H,L,B,C: B>C>A: POP HL,BC,DE: BC:B,DE:C,HL:A
;H,L,B,C,D,E: C>A>B: POP DE,HL,BC: BC:C,DE:A,HL:B
_ixpointer=_sortixpointer
       ENDM
       
       MACRO TRISORTPATCH retcode
        LD (VU1),BC ;todo HL
        LD A,C
        SUB E
        LD (U12),A
        LD A,B
        SUB D
        LD (V12),A
        LD A,C
        SUB L
        ;ADD A,A
        LD (mU13SLA),A ;-126..+126
        LD A,B
        SUB H
        ;ADD A,A
        LD (mV13SLA),A ;-126..+126
        LD A,retcode
        LD (triret),A
       ENDM 

trivert
       dw #c055
       dw #c325
       dw #e544
tridata
       dw trivert
       dw trivert+2
       dw trivert+4
       dw #c080
       dw #c0bf
       dw #ffbf

       
TRIQ
       IF tmapnosp==0
TRIQSP=$+1
        LD SP,0
       ENDIF 
       
       ;ret
       
TRIPOP
       IF tmapnosp
        POP IX
        LD A,HX
       ELSE 
        POP HL
        LD A,H
       ENDIF 
        OR A
        RET Z
TRI
TRIIX
_ixpointer=12
        GETRPHL
        push hl
_ixpointer=0
;сортируем вершины A,B,C (с параметрами X,Y,U,V) по Y
;результат (вершины 1,2,3 с параметрами)
;в определённых фиксированных адресах
;H13=Y3-Y1 - если 0, то ВЫХОД
;l13=X3-X1
;H12=Y2-Y1, l12=X2-X1
;H23=Y3-Y2, l23=X3-X2
       IF tmapnosp
        if 1==1
        GETRPHL
        ld c,(hl)
        inc hl
        ld b,(hl)
        GETRPHL
        ld e,(hl)
        inc hl
        ld d,(hl)
        GETRPHL
        LD a,(HL)
        inc hl
        LD h,(HL)
        ld l,A
        ld a,h
        else
        LD H,VTX3DY/256
        LD L,(IX)
        LD B,(HL)
        DEC H
        LD C,(HL)
        LD L,(IX+2)
        LD E,(HL)
        INC H
        LD D,(HL)
        LD L,(IX+4)
        LD A,(HL)
        DEC H
        LD L,(HL)
        LD H,A
        endif
       ELSE 
        LD (TRIQSP),SP
        LD SP,HL
        POP HL
        LD B,(HL)
        DEC H
        LD C,(HL)
        POP HL
        LD D,(HL)
        DEC H
        LD E,(HL)
        POP HL
        LD A,(HL)
        DEC H
        LD L,(HL)
        LD H,A
       ENDIF 

;bc=yx1
;de=yx2
;hl=yx3
;в стеке (или ix) vu1,vu2,vu3,[pg]

_sortixpointer=6
        CP D
        JP C,TRIsortDH ;D>H
        CP B
        JP C,TRIsortBHD ;B>H>=D
        LD A,D ;H>=B,D
        CP B
        jr c,TRIsortHBD ;H>=B>D
        LD (YX1),HL
        TRISORT 2,1,0;H,L,D,E,B,C
        GETRPHL
        GETRPDE
        GETRPBC
        TRISORTPATCH #FA
        JP TRIsortQ
TRIsortHBD ;
        LD (YX1),HL
        TRISORT 2,0,1;H,L,B,C,D,E
        GETRPDE
        GETRPHL
        GETRPBC
        TRISORTPATCH #F2
        JP TRIsortQ
TRIsortBHD ;
        LD (YX1),BC
        TRISORT 0,2,1;B,C,H,L,D,E
        GETRPBC
        GETRPHL
        GETRPDE
        TRISORTPATCH #FA
        JP TRIsortQ
TRIsortDH ;
        CP B
        jr nc,TRIsortDHB ;D>H>=B
        LD A,D ;H<B,D
        CP B
        JP C,TRIsortBDH ;B>D>H
        LD (YX1),DE
        TRISORT 1,0,2;D,E,B,C,H,L
        GETRPDE
        GETRPBC
        GETRPHL
        TRISORTPATCH #FA
        JP TRIsortQ
TRIsortDHB ;
        LD (YX1),DE
        TRISORT 1,2,0;D,E,H,L,B,C
        GETRPHL
        GETRPBC
        GETRPDE
        TRISORTPATCH #F2
        JP TRIsortQ
TRIsortBDH ;
        LD (YX1),BC
        TRISORT 0,1,2;B,C,D,E,H,L
        GETRPBC
        GETRPDE
        GETRPHL
        TRISORTPATCH #F2
TRIsortQ
        if fastdiv
        ld a,(X1)
l12_2=$+1
        add a,0
        ld (X2),a
        endif

       if tmapnosp
        ;GETRPHL
        ;push hl
       endif 
        setpgfast zxpgdiv,curpg
l13SLA=$+1
mH13=$+2
        LDDIVHL ;dXL=l13/H13 (+-7.8=+-6.0/6.0)
       IF brutemul
        ex de,hl 
        LD HL,#80 ;правильное округление
MULJRH12=$+1
        JR $
        DUP 64
        ADD HL,DE
        EDUP 
        LD A,H
;A=A~*DE
       ELSE 
        ex af,af' ;H12 обработанный для MUL
        LD C,A
        TRIMULLOOP ;DE=HL, A=A~*HL
       ENDIF 
;можно без умножений:
;1/t=H13/H12=+1.0..+oo
;W=l12-l13/(1/t)
;mH13SLAp1=$+1
;H12=$+2 ;а если 0? тогда нужен результат -63!!! но dV,dU кривые
;LD A,(0) ;A=-1..-63 (проверено)
;LD (it),A
;l13SLAp1=$+1
;it=$+2
;LD A,(0)
l12=$+1
        SUB 0 ;A=-W ;W=l12-H12*dXL (+-6.0=6.0*+-7.8)
;-1..1 может дать сканлайн <0
triret=$
        JP P,TRIQ
        JP P,TRILEFT ;левый треугольник
       IF incW
        DEC A ;|W| на 1 больше, т.к. точность XR-XL равна +-1
       ENDIF 
       ex af,af' 
       IF tmapclipwid==0
        LD A,#3D ;dec a
        LD (TRINEGWIDTH),A
       ENDIF 
        LD HL,X1 ;R (ломаный край, физически правый)
        LD A,(HL)
        DEC (HL)
      ;LD A,(X1) ;дает дырки
        LD (XL1),A ;не будем рисовать правую сторону
        LD A,PATCHVUDEC/256
        JP TRILEFTQ
TRILEFT ;левый треугольник
        ;JP C,TRIQ
       JP Z,TRIQ
       IF incW
        CPL ;|W| на 1 больше, т.к. точность XR-XL равна +-1
       ELSE 
        NEG 
       ENDIF 
       ex af,af' 
       IF tmapclipwid==0
        LD A,#2F ;cpl
        LD (TRINEGWIDTH),A
       ENDIF 
        LD A,(X1) ;R (ломаный край, физически левый)
       IF tmapclipwid==0
        DEC A ;чтобы cpl вместо neg
       ENDIF 
        LD (XL1),A
        LD A,PATCHVUINC/256
TRILEFTQ
        LD (patchvujp+1),A
        DEC A ;TEXTURERINC/DEC
        LD (texturerH),A
        LD (dXL),DE ;HL выше невыгодно для невидимых
mH23=$+2
mHl23=$+1
        LDDIVHL ;dXR23=l23/H23 (+-7.8=+-6.0/6.0)
        LD (dXR23),HL ;+22t в TRISORT невыгодно для невидимых
mU13SLA=$+1
mH13_=$+2
        LD HL,0
         push hl
        DIVHL_LSBTOA
        LD (du13),A
        DIVHL_HSBTOA
        LD (dU13),A
         pop hl
mV13SLA=$+1
        LD L,0
         push hl
        DIVHL_LSBTOA
        LD (dv13),A
        DIVHL_HSBTOA
        LD (dV13),A
         pop hl
H12SLA=$+1
        LD L,0
        ;LD C,(HL) ;
        ;INC L     ;
        ;LD A,(HL) ;H12/H13=0..#100 (через texarea зашкаливает)
        DIVHL_LSBTOC
        DIVHL_HSBTOA
        ADD A,tdiv4/256
        LD B,A
        LD A,(mV13SLA)
         add a,a
        ADD A,A
        LD L,A
        SBC A,A
        LD H,A ;HL=-252..+252
        LD A,(BC) ;t=0..63,CPL,*4
        TRIMULLOOP ;A*HL
V12=$+1
        SUB 0
        ;ADD A,A
        LD L,A
        EXX 
        LD A,(mU13SLA)
         add a,a
        ADD A,A
        LD L,A
        SBC A,A
        LD H,A ;HL=-252..+252
         EXX 
        LD A,(BC)
         EXX 
        TRIMULLOOP ;A*HL
U12=$+1
        SUB 0
        ;ADD A,A
        LD L,A
;A'=-W
;L=2*(U2-U4)=2*((U2-U1)-(U3-U1)*t)
;L'=2*(V2-V4)=2*((V2-V1)-(V3-V1)*t)
;PATCHVU
       ex af,af' ;-W
        LD H,A
        ;LD E,(HL) ;
        ;INC L     ;
        ;LD D,(HL) ;из pgdiv
        ;LD H,D,L,E ;dU
         ex af,af'
        DIVHLTOHLDE
         ex af,af'
       INC H
       DEC H ;ADD HL,DE не дает флаг знака
        EXX 
        LD H,A
        ;LD E,(HL) ;
        ;INC HL    ;
        ;LD D,(HL) ;из pgdiv
        ;LD H,D,L,E ;dV
         ex af,af'
        DIVHLTOHLDE
         ex af,af'
       JP P,$+4
       DEC H ;компенсация паразитного V++ при dU<0
;последний вывод не патчим - там ld a,(bc)
;на всякий случай патчим на 1 пиксель больше, чем W
;(которое само с запасом 1 пиксель)
;потому что ошибка XL + ошибка XR + ошибка деления*H12 = .5+.5+?
;H=-1..-4: B=-1
;H=-5..-8: B=-2
        RRA 
        RRA 
        OR #C0
        LD B,A
patchvujp=$+1
       IF tmapnosp
        CALL PATCHVUINC;DEC
       ;JP TRIDRAW
       ELSE 
        JP PATCHVUINC;DEC
       ENDIF 

       MACRO BIGCHMAPCORR
       IF bigchmap|clipchmap
        JP P,TRILINEnEXTRAY
        LD D,gschmapend/256-1
        LD A,HX
        XOR #80
        LD HX,A
        EXX 
        LD A,H
        XOR #80
        LD H,A
        EXX 
TRILINEnEXTRAY ;
       ENDIF 
       ENDM 

TRIDRAW
l12SLA=$+1
mH12=$+2
        LDDIVHL ;dXR12=l12/H12 (+-7.8=+-6.0/6.0)
        ex de,hl
       IF lambert
        GETRPHL ;normal vector
        LD A,(HL) ;Y
        SUB lambert
        DUP lambertshr
        SRA A
        EDUP 
        JP P,$+4
        XOR A
        CP lambertmax
        jr c,$+4
        LD A,lambertmax
        ADD A,gspgtex*257<1
        RRCA 
        GSSETPGA
       ELSE 
       IF singlepage
        IF tmapnosp
        LD A,(IX+_ixpointer+1)
_ixpointer=_ixpointer+2
        ELSE 
        POP AF ;pgtex
        ENDIF 
        setpgafast curpg
       ENDIF
       ENDIF 
dXL=$+1
        LD BC,0
XL1=$+2
        LD HL,#80 ;Xleft+1 (левый), Xleft (правый)
        EXX 
YX1=$+1
X1=$+1
Y1=$+2
        LD DE,0
       IF bigchmap|clipchmap
       RES 7,D
       BIT 6,D
       jr z,TRIDRAWnEXTRAY
        RES 6,D
        LD A,E
        XOR #80
        LD E,A
        EXX 
        LD A,H
        XOR #80
        LD H,A
        EXX 
TRIDRAWnEXTRAY ;
       ENDIF 
        LD HX,E ;Xright (левый), Xright-1 (правый)
        LD LX,#80 ;чтобы одинаковые рёбра рисовались одинаково
VU1=$+1
        LD BC,0
        LD IY,#8080
        LD A,(mH12)
        IF tmapnosp
        OR A
        ELSE 
        ADD A,A
        ENDIF 
        jr z,TRIDRAW120 ;H12=0
       IF tmapnosp
        ex af,af' 
        CALL TRISCANGO
        JP TRIDRAW23
       ELSE 
        LD L,A
        LD H,TRISTACK12/256
        LD SP,HL
        JP TRISCANGO
       ENDIF 

TRIDRAW120
        EXX 
        LD DE,(dXR23)
        EXX 
        LD A,(mH23)
       IF tmapnosp
        ex af,af' 
        LD A,(l12)
        ADD A,HX
        LD HX,A ;Xright
        CALL TRISCANGO
        JP TRIQ
       ELSE 
        ADD A,A
        LD L,A
        LD H,TRISTACK23/256
        LD SP,HL
        LD A,(l12)
        ADD A,HX
        LD HX,A ;Xright
        JP TRISCANGO
       ENDIF 

TRIQ_   JP TRIQ
TRIDRAW23
        LD A,(mH23)
        IF tmapnosp
        OR A
        ELSE 
        ADD A,A
        ENDIF 
        jr z,TRIQ_ ;H23=0
        EXX 
dXR23=$+1
        LD DE,0
        LD LX,#80 ;чтобы одинаковые рёбра рисовались одинаково
               ;надо для надёжности HX=X2 (левый), X2-1 (правый)
        if fastdiv
X2=$+2
        ld hx,0
        endif
        EXX 
       IF tmapnosp
        LD HL,TRIQ
        PUSH HL
EXATRILINE
        ex af,af' 
       ELSE 
        LD L,A
        LD H,TRISTACK23/256
        LD SP,HL
       ENDIF 

TRILINE
;цикл и вход (для нижней части полигона)
        DEC D ;Y
        BIGCHMAPCORR
TRISCANGO
;вход (для верхней части полигона)
        EXX 
        ADD IX,DE ;Xright (левый), Xright-1 (правый)
        ADD HL,BC ;Xleft+1 (левый), Xleft (правый)
        LD A,H
        EXX 
        LD E,HX ;Xright
       SUB E ;A=-1..63 (левый), -63..1 (правый)
      IF tmapclipwid==0
TRINEGWIDTH=$
       CPL ;(левый), DEC A (правый)
       ;RET Z ;ширина=0 в 10% случаев (11t вм. 55t)
      IF debug
     SUB 2
     CP -(trimaxl+2)
     jr c,$
     ADD A,2
      ENDIF 
      ENDIF 
        LD L,A
texturerH=$+1
        LD H,0;'TEXTURERINC;DEC
        LD L,(HL)
        LD A,LY
du13=$+1
        SUB 0
        LD LY,A
        LD A,C
dU13=$+1
        SBC A,0
        LD C,A
        LD A,HY
dv13=$+1
        SUB 0
        LD HY,A
        LD A,B
dV13=$+1
        SBC A,0
        LD B,A
       IF tmapclipwid
        DEC H
       ENDIF 
        JP (HL) ;TEXTURERINC;DEC

      IF tmapnosp==0
        DISPLAY "до 1-го выравнивания адреса: ",$
;l=254 для высоты 1 (сразу выход)
        DS 255&(256-(2*trimaxh)-$)
TRISTACK12
       DUP trimaxh-1
        DW TRILINE
       EDUP 
        DW TRIDRAW23
        DISPLAY "TRISTACK12=",TRISTACK12

;l=254 для высоты 1 (сразу выход)
        DS 255&(256-(2*trimaxh)-$)
TRISTACK23
       DUP trimaxh-1
        DW TRILINE
       EDUP 
        DW TRIQ
        DISPLAY "TRISTACK23=",TRISTACK23
      ENDIF ;~tmapnosp

        DISPLAY $
        DS 255&(-$)
tdiv4
_=0
       DUP 64
        DS 4,(255-_)*4
_=_+1
       EDUP 
        ds 2;DB 0;(255-63)*4 ;H12/H13=0..#100
 
	BEGIN256 512
TBLOG2
	ds 512 ;log2(X)
	END256
	
	BEGIN256 256
TB2X
	ds 256 ;(2^X)-1 (0<X<1)
	END256

	BEGIN256 512
divexp
	incbin "divexp"
	END256
	
	BEGIN256 256
divlog
	incbin "divlog"
	END256
