;Programme Arnaud.68000 - 2020-11
;Rotation objets filaire 3D
;
;assembleur : ASMTwo
;
;References :
;Reprise architecture (init hardware, copperlist, ombre et miroir) :
;source : Yragael pour Stash of Code (http://www.stashofcode.fr) en 2017.
;
;contient le fichier Font8 :
;https://www.stashofcode.fr/code/coder-un-sine-scroll-sur-amiga/sinescroll.zip
;
;
;

SECTION Arn,CODE_C

DEBUGDISPLAYTIME=0 ;affiche le debug
BLITTER=1 ;Tracer pour le scroll au 0=CPU 1=Blitter, non fonctionnel pour le moment
EffacerBitPlaneCache=1
CTR=1 ;permet de compter le nombre de boucle d'attente du blitter

AffLigneBlitter=1 ;affiche le tracé des lignes au blitter
AffObjet3D=1 ;Affiche l'objet 3D

;Config animation Objet 3D
;Angles au depart
InitAngleAx=20
InitAngleAy=35
InitAngleAz=10
;Incrément des axes
PasAngleAX=1
PasAngleAY=1
PasAngleAZ=0
;position du centre objet
offsetX=160 ;min 87, maxi 232
offsetZ=87 ;mini 87, maxi 168 87=sqr(50^2+50^2+50^2) coin max (50,50,50)

;Registres

VPOSR=$004
VHPOSR=$006
INTENA=$09A
INTENAR=$01C
INTREQ=$09C
INTREQR=$01E
DMACON=$096
DMACONR=$002
BLTAFWM=$044
BLTALWM=$046
BLTAPTH=$050
BLTAPTL=$052
BLTCPTH=$048
BLTDPTH=$054
BLTAMOD=$064
BLTBMOD=$062
BLTCMOD=$060
BLTDMOD=$066
BLTADAT=$074
BLTBDAT=$072
BLTCON0=$040
BLTCON1=$042
BLTSIZE=$058
DIWSTRT=$08E
DIWSTOP=$090
BPLCON0=$100
BPLCON1=$102
BPLCON2=$104
DDFSTRT=$092
DDFSTOP=$094
BPL1MOD=$108
BPL2MOD=$10A
BPL1PTH=$0E0
BPL1PTL=$0E2
BPL2PTH=$0E4
BPL2PTL=$0E6
COLOR00=$180
COLOR01=$182
COLOR02=$184
COLOR03=$186
COP1LCH=$080
COPJMP1=$088
FMODE=$1FC

;Programme

DISPLAY_DEPTH=2
DISPLAY_DX=320
DISPLAY_DY=256
DISPLAY_X=$81
DISPLAY_Y=$2C
SCROLL_DX=DISPLAY_DX
SCROLL_X=(DISPLAY_DX-SCROLL_DX)>>1
SCROLL_DY=100
SCROLL_AMPLITUDE=SCROLL_DY-16 ;SCROLL_DY-16 donne l'amplitude des ordonnées possibles du scroll : [0,SCROLL_DY-16]
;SCROLL_DY doit être pair pour centrer le scroll sur DISPLAY_DY qui est pair
;Donc SCROLL_DY-16 est pair
;Les ordonnées sont calculées par (A>>1)*sin ce qui donne des valeurs dans [-A,A] quand A est pair et dans [-A+1,A+1] quand A est impair
;Ici A=SCROLL_DY-16 donc A est pair : pas de correction à apporter
SCROLL_Y=(DISPLAY_DY-SCROLL_DY)>>1
;SCROLL_SPEED=2
SCROLL_COLOR=$0FFF
SINE_SPEED_FRAME=5
SINE_SPEED_PIXEL=1
LINE_DX=15 ;C'est le nombre de lignes de la droite - 1 : LINE_DX=max (abs(15-0),abs(0,0))
LINE_DY=0 ;C'est le nombre de colonnes de la droite - 1 : LINE_DY=min (abs(15-0),abs(0,0))
LINE_OCTANT=1
MIRROR_Y=SCROLL_Y+SCROLL_DY ;Ordonnée de la ligne à laquelle débute le miroir (le WAIT pour modifier BPL1MOD a lieu une ligne avant)
MIRROR_COLOR=$000A
MIRROR_SCROLL_COLOR=$000F
SHADOW_DX=2 ;Compris entre 0 et 15
SHADOW_DY=2
SHADOW_COLOR=$0777

SCROLL_POS_Y=162
SCROLL_SPEED=1

;COPSIZE=18*4+14*4+4

;---------- Macros ----------

;Attendre le Blitter. Quand la seconde opérande est une adresse, BTST ne permet de tester que les bits 7-0 de l'octet pointé, mais traitant la première opérande comme le numéro du bit modulo 8, BTST #14,DMACONR(a5) revient à tester le bit 14%8=6 de l'octet de poids fort de DMACONR, ce qui correspond bien à BBUSY...

WAITBLIT: MACRO
_waitBlitter0\@
IFNE CTR
add.l #1,BltCTR
ENDC
btst #14,DMACONR(a5)
bne _waitBlitter0\@
_waitBlitter1\@
IFNE CTR
add.l #1,BltCTR
ENDC
btst #14,DMACONR(a5)
bne _waitBlitter1\@
IFNE CTR
sub.l #2,BltCTR
ENDC
ENDM

;Contrôle de l'intégrité du texte afficher.
;Attention au contexte dans lequel la macro est utilisée,
;car elle peut modifier la longueur du texte initial
;(qui doit être au moins aussi long que "You are a LAMER!"
;sous peine d'écraser des données)
;et donc embrouiller le code qui était en train de le parcourir

;---------- Initialisations ----------

;Empiler les registres

movem.l d0-d7/a0-a6,-(sp) *** NIV1

;Allouer de la mémoire en CHIP mise à 0 pour la Copper list

move.l #COPSIZE,d0
move.l #$10002,d1
movea.l $4,a6
jsr -198(a6)
move.l d0,copperlist_PTR
;calcul du pointeur BitPlanes de la copperList
add.l #CplBitPlanes-CopListDataStart,d0
move.l d0,Copperlist_BitPlanes_PTR

;Allouer de la mémoire en CHIP mise à 0 pour les bitplanes

move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
move.l #$10002,d1
movea.l $4,a6
jsr -198(a6)
move.l d0,bitplaneA

move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
move.l #$10002,d1
movea.l $4,a6
jsr -198(a6)
move.l d0,bitplaneB

move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
move.l #$10002,d1
movea.l $4,a6
jsr -198(a6)
move.l d0,bitplaneC

;Idem pour la police de caractères

move.l #256<<5,d0 move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,Font16_PTR ;Couper le système movea.l $4,a6 jsr -132(a6) ;Couper le hardware lea $dff000,a5 move.w INTENAR(a5),intena_PTR move.w #$7FFF,INTENA(a5) move.w INTREQR(a5),intreq_PTR move.w #$7FFF,INTREQ(a5) move.w DMACONR(a5),dmacon_PTR move.w #$07FF,DMACON(a5) ;---------- Création et activation de la Copper list ---------- RecopierAdresseBplVersCpl: ;copie les adresse des 2 premiers bitplanes dans copperlist moveq #2-1,d1 move.l #bitplaneA,a0 move.l #CplBitPlanes,a1 ;adresse de CplBitPlanes add.l #2,a1 .l: move.l (a0)+,d0 ;adresse du pitplane move.w d0,(a1) ;poids faible swap d0 add.l #4,a1 move.w d0,(a1) ;poids fort add.l #4,a1 dbf d1,.l ;transferer la copperlist en Chip move.l #COPSIZE/4-1,d0 move.l #CopListDataStart,a0 move.l copperlist_PTR,a1 .l2: move.l (a0)+,(a1)+ dbf d0,.l2 ;Activer la Copper list move.l copperlist_PTR,COP1LCH(a5) clr.w COPJMP1(a5) move.w #$83C0,DMACON(a5) ;DMAEN=1, COPEN=1, BPLEN=1, COPEN=1, BLTEN=1 ;---------- Création d'une police 16x16 à partir d'une police 8x8 ---------- ;Préparer les données de la police (1er octet = suite des bits 7 des 8 lignes / octets du caractère, 2ème octet = suite des bits 6 des 8 lignes / octets du caractère, etc. : rotation de -90°). Noter qu'au Blitter il faudra donc tracer les colonnes de la dernière à la première ligne du fait de l'orientation du motif (il faudrait lui appliquer une symétrie d'axe Y avant pour tracer de la première à la dernière ligne) lea font8,a0 move.l Font16_PTR,a1 move.w #256-1,d0 _fontLoop: moveq #7,d1 ; _fontLineLoop: clr.w d5 clr.w d3 clr.w d4 _fontColumnLoop: move.b (a0,d5.w),d2 ; btst d1,d2 ;on teste le bit D1 beq _fontPixelEmpty bset d4,d3 ; addq.b #1,d4 bset d4,d3 addq.b #1,d4 bra _fontPixelNext _fontPixelEmpty: addq.b #2,d4 _fontPixelNext: addq.b #1,d5 btst #4,d4 beq _fontColumnLoop move.w d3,(a1)+ move.w d3,(a1)+ dbf d1,_fontLineLoop lea 8(a0),a0 dbf d0,_fontLoop ;---------- Boucle principale ---------- ;A1=PTR sur le .w de la colonne du car 16x16 ;A5=$DFF000 ;A4=adresse du caractère du texte à afficher ;D7=position de la colonne à afficher 0..15 clr.w D7 _loop: IFNE CTR move.l BltCTR,BltWait move.l #0,BltCtr ENDC ;Attendre que le faisceau d'électrons a terminé de tracer l'écran ;D0 = ctr de boucle _waitVBL: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmp.w #DISPLAY_Y+DISPLAY_DY,d0 blt _waitVBL ;Registres à ne pas modifier ;A1,A4,A5,D7 IFNE DEBUGDISPLAYTIME move.w #$0F00,COLOR00(a5) ENDC ;Permuter circulairement les bitplanes ;Registres à ne pas modifier ;A1,A4,A5,D7 move.l bitplaneA,d0 move.l bitplaneB,d1 move.l bitplaneC,d2 move.l d1,bitplaneA ;Bitplane Affiché move.l d2,bitplaneB ;Bitplane en construction move.l d0,bitplaneC ;Bitplane en effacement ;D0,D1,D2 libérés ;A1,A4,A5,D7 gardés ;ecriture des adresses bitplane dans la copperlist movea.l Copperlist_BitPlanes_PTR,a0 move.w d1,2(a0) move.w d1,10(a0) swap d1 move.w d1,6(a0) move.w d1,14(a0) ;A1,A4,A5,D7 gardés ; ;Afficher le sine scroll (d0 doit être l'offset du sinus de l'angle courant) ; WAITBLIT ; move.w #4*(LINE_DY-LINE_DX),BLTAMOD(a5) ; move.w #4*LINE_DY,BLTBMOD(a5) ; move.w #DISPLAY_DX>>3,BLTCMOD(a5)
; move.w #DISPLAY_DX>>3,BLTDMOD(a5)
; move.w #(4*LINE_DY)-(2*LINE_DX),BLTAPTL(a5)
; move.w #$FFFF,BLTAFWM(a5)
; move.w #$FFFF,BLTALWM(a5)
; move.w #$8000,BLTADAT(a5)
; move.w #(LINE_OCTANT<<2)!$F041,BLTCON1(a5) ;BSH3-0=15, SIGN=1, OVF=0, SUD/SUL/AUL=octant, SING=0, LINE=1

;ecriture d'un texte 8x8
;A1,A4,A5,D7 ne pas modifier
;A0,A2,A3,D0 utilisés

*** CALCUL 3D ********************************
*
*
IFNE AffObjet3D

Calcul3D:

movem.l d0-d7/a0-a6,-(sp)

;Angles de visualisation
move.l #0,a4
move.l #0,a5
move.l #0,a6

;Increment angle aX
move.w AngleAx,a4
add.w #PasAngleAX,a4 ;increment
cmp.w #360,a4
blo PasModuloIncrementAx
sub.w #360,a4
PasModuloIncrementAx:
move.w a4,AngleAx

;Increment angle aY
move.w AngleAY,a5
add.w #PasAngleAY,a5 ;+increment
cmp.w #360,a5
blo PasModuloIncrementAy
sub.w #360,a5
PasModuloIncrementAy:
move.w a5,AngleAy

;Increment angle aZ
move.w AngleAz,a6
add.w #PasAngleAZ,a6 ;increment
cmp.w #360,a6
blo PasModuloIncrementAz
sub.w #360,a6
PasModuloIncrementAz:
move.w a6,AngleAz

;calage table en mots donc angle*2
add.w a5,a5
add.w a4,a4

;on calcule les points de la table
CalculerEnsemblePointsXYZ:
lea Points,a0
lea PointsCalcules,a1
lea CosinusTbl,A2
lea SinusTbl,A3

move.w #(FinPoints-Points)/6-1,d7

BoucleCalculerEnsemblePointsXYZ:
clr.l D0
clr.l d1
clr.l d2
clr.l d5
clr.l d6

move.w (A0)+,d0 ;rho
move.w (A0)+,d1 ;teta
move.w (A0)+,d2 ;z

;ajout angle à TETA
add.w a6,d1
cmp.w #360,d1
blo PasModuloIncrementTeta
sub.w #360,d1
PasModuloIncrementTeta:

bsr CalculerXYZ

add.w #offsetX,d4 ;emplacement ecran
add.w #offsetZ,d1

move.w d4,(A1)+ ;x
move.w d0,(A1)+ ;y
move.w d1,(A1)+ ;z
dbf d7,BoucleCalculerEnsemblePointsXYZ
FinCalculerEnsemblePointsXYZ:

bra FinCalcul3D

CalculerXYZ:
;Entree : D0=rho plan xy, D1=Teta+aZ xy, D2=Z
; D3=aX, D4=aY
; A2=ptrTableCOS, A3=ptrTableSIN
;Sortie : D0=x, D1=z, D2=y
;Interne:

;************************
;utilisé : d0=rho, d1=aZ, d2=Z, a2=cos, a3=sin, A4=aX, A5=aY

add.w d1,d1 ;table TRIGO de mots, donc angle*2

;************************
;rotation axe Z (plan XY)
;x1=rho*cos(teta+aZ) ;d5=cos(d1), d5=d0*d5
;y1=rho*sin(teta+aZ) ;d1=sin(d1), d1=d0*d1

move.w (a2,d1),d5
muls d0,d5 ;d5=x1
lsr.l #7,d5
lsr.l #7,d5

move.w (a3,d1),d1
muls d0,d1 ;d1=y1
lsr.l #7,d1
lsr.l #7,d1

;************************
;utilisé : d1=y1, d2=Z, d5=x1, a2=cos, a3=sin, A4=aX, A5=aY
;************************
;rotation axe X (plan YZ) ;D4=cos(A4), d3=sin(A4)
;y2=y1*cos(aX)-z*sin(ax) ;d0=D4, d0=d1*d0, d6=d3, d6=d2*d6, d0=d0-d6
;z1=y1*sin(aX)+z*cos(aX) ;d3=d1*d3, d4=d2*d4, d3=d3+d4

;moveq #0,d4
;moveq #0,d3

move.w (a2,A4),d4 ;a4=cos(aX)
move.w (a3,A4),d3 ;d3=sin(ax)

move.w d4,d0 ;c
move.w d3,d6 ;s

muls d1,d0 ;y1*cos
muls d2,d6 ;z*sin
sub.l d6,d0 ;y2=y1*cos-z*sin
lsr.l #7,d0
lsr.l #7,d0

muls d1,d3 ;y*sin
muls d2,d4 ;z*cos
add.l d4,d3 ;z1=y*sin+z*cos
lsr.l #7,d3
lsr.l #7,d3

;************************
;utilisé : d0=y2, d3=z1, d5=x1, a2=cos, a3=sin, A5=aY
;************************
;rotation axe Y (plan ZX) ;d6=cos(A5), d4=sin(A5)
;z2=z1*cos(aY)-x1*sin(aY) ,d1=d6, d1=d3*d1, d2=d4, d2=d5*d2, d1=d1-d2
;x2=z1*sin(aY)+x1*cos(aY) ;d6=d5*d6, d4=d3*d4, d4=d6+d4

moveq #0,d4
moveq #0,d6

move.w (a2,A5),d6 ;cos(aY)
move.w (a3,A5),d4 ;sin(aY)

move.w d6,d1
move.w d4,d2

muls d3,d1 ;z1*cos
muls d5,d2 ;x1*sin
sub.l d2,d1 ;z2=z1*cos-x1*sin
lsr.l #7,d1
lsr.l #7,d1

muls d3,d4 ;z1*sin
muls d5,d6 ;x1*cos
add.l d6,d4 ;x2=x1*cos+z1*sin
lsr.l #7,d4
lsr.l #7,d4

;************************
;utilisé : d0=y2, d1=z2, d4=x2

rts

AngleAx: dc.w InitAngleAx
AngleAy: dc.w InitAngleAy
AngleAz: dc.w InitAngleAz

Points: ;coords Sphériques : rho (longeur) plan xy , Teta (Az), z
P:
; rho,Teta,z ;x,y,z
P01: dc.w 70,45,-50 ;50,50,-50
P02: dc.w 70,45,50 ;50,50,50
P03: dc.w 70,135,50 ;-50,50,50
P04: dc.w 70,225,50 ;-50,-50,50
P05: dc.w 70,225,-50 ;-50,-50,-50
P06: dc.w 70,315,-50 ;50,-50,-50
P07: dc.w 70,315,50 ;50,-50,50
P08: dc.w 70,135,-50 ;-50,50,-50
P09: dc.w 50,90,50 ;0,50,50
P10: dc.w 50,0,50 ;50,0,50
P11: dc.w 70,45,0 ;50,50,0
FinPoints:
dc.w $FFFF,$FFFF,$FFFF ;fin de liste

Lignes:
dc.w P03-P,P04-P
dc.w P04-P,P07-P
dc.w P04-P,P05-P
dc.w P05-P,P06-P
dc.w P06-P,P07-P
dc.w P01-P,P06-P
dc.w P05-P,P08-P
dc.w P08-P,P01-P
dc.w P08-P,P03-P
* dc.w P07-P,P01-P
* dc.w P03-P,P01-P
* dc.w P03-P,P07-P
dc.w P03-P,P09-P
dc.w P07-P,P10-P
dc.w P01-P,P11-P
dc.w P10-P,P11-P
dc.w P11-P,P09-P
dc.w P09-P,P10-P

FinLignes:

PointsCalcules:
;x.b, y.b, z.b
ds.b (FinPoints-Points)

;----- Tables Trigo -----
SinusTbl:
dc.w 0,285,571,857,1142,1427,1712,1996,2280,2563 ;Sin(0) ou Cos(-90)
dc.w 2845,3126,3406,3685,3963,4240,4516,4790,5062,5334 ;Sin(10) ou Cos(-80)
dc.w 5603,5871,6137,6401,6663,6924,7182,7438,7691,7943 ;Sin(20) ou Cos(-70)
dc.w 8191,8438,8682,8923,9161,9397,9630,9860,10086,10310 ;Sin(30) ou Cos(-60)
dc.w 10531,10748,10963,11173,11381,11585,11785,11982,12175,12365 ;Sin(40) ou Cos(-50)
dc.w 12550,12732,12910,13084,13254,13420,13582,13740,13894,14043 ;Sin(50) ou Cos(-40)
dc.w 14188,14329,14466,14598,14725,14848,14967,15081,15190,15295 ;Sin(60) ou Cos(-30)
dc.w 15395,15491,15582,15668,15749,15825,15897,15964,16025,16082 ;Sin(70) ou Cos(-20)
dc.w 16135,16182,16224,16261,16294,16321,16344,16361,16374,16381 ;Sin(80) ou Cos(-10)
CosinusTbl:
dc.w 16384,16381,16374,16361,16344,16321,16294,16261,16224,16182 ;Sin(90) ou Cos(0)
dc.w 16135,16082,16025,15964,15897,15825,15749,15668,15582,15491 ;Sin(100) ou Cos(10)
dc.w 15395,15295,15190,15081,14967,14848,14725,14598,14466,14329 ;Sin(110) ou Cos(20)
dc.w 14188,14043,13894,13740,13582,13420,13254,13084,12910,12732 ;Sin(120) ou Cos(30)
dc.w 12550,12365,12175,11982,11785,11585,11381,11173,10963,10748 ;Sin(130) ou Cos(40)
dc.w 10531,10310,10086,9860,9630,9397,9161,8923,8682,8438 ;Sin(140) ou Cos(50)
dc.w 8191,7943,7691,7438,7182,6924,6663,6401,6137,5871 ;Sin(150) ou Cos(60)
dc.w 5603,5334,5062,4790,4516,4240,3963,3685,3406,3126 ;Sin(160) ou Cos(70)
dc.w 2845,2563,2280,1996,1712,1427,1142,857,571,285 ;Sin(170) ou Cos(80)
dc.w 0,-286,-572,-858,-1143,-1428,-1713,-1997,-2281,-2564 ;Sin(180) ou Cos(90)
dc.w -2846,-3127,-3407,-3686,-3964,-4241,-4517,-4791,-5063,-5335 ;Sin(190) ou Cos(100)
dc.w -5604,-5872,-6138,-6402,-6664,-6925,-7183,-7439,-7692,-7944 ;Sin(200) ou Cos(110)
dc.w -8193,-8439,-8683,-8924,-9162,-9398,-9631,-9861,-10087,-10311 ;Sin(210) ou Cos(120)
dc.w -10532,-10749,-10964,-11174,-11382,-11586,-11786,-11983,-12176,-12366 ;Sin(220) ou Cos(130)
dc.w -12551,-12733,-12911,-13085,-13255,-13421,-13583,-13741,-13895,-14044 ;Sin(230) ou Cos(140)
dc.w -14189,-14330,-14467,-14599,-14726,-14849,-14968,-15082,-15191,-15296 ;Sin(240) ou Cos(150)
dc.w -15396,-15492,-15583,-15669,-15750,-15826,-15898,-15965,-16026,-16083 ;Sin(250) ou Cos(160)
dc.w -16136,-16183,-16225,-16262,-16295,-16322,-16345,-16362,-16375,-16382 ;Sin(260) ou Cos(170)
dc.w -16384,-16382,-16375,-16362,-16345,-16322,-16295,-16262,-16225,-16183 ;Sin(270) ou Cos(180)
dc.w -16136,-16083,-16026,-15965,-15898,-15826,-15750,-15669,-15583,-15492 ;Sin(280) ou Cos(190)
dc.w -15396,-15296,-15191,-15082,-14968,-14849,-14726,-14599,-14467,-14330 ;Sin(290) ou Cos(200)
dc.w -14189,-14044,-13895,-13741,-13583,-13421,-13255,-13085,-12911,-12733 ;Sin(300) ou Cos(210)
dc.w -12551,-12366,-12176,-11983,-11786,-11586,-11382,-11174,-10964,-10749 ;Sin(310) ou Cos(220)
dc.w -10532,-10311,-10087,-9861,-9631,-9398,-9162,-8924,-8683,-8439 ;Sin(320) ou Cos(230)
dc.w -8193,-7944,-7692,-7439,-7183,-6925,-6664,-6402,-6138,-5872 ;Sin(330) ou Cos(240)
dc.w -5604,-5335,-5063,-4791,-4517,-4241,-3964,-3686,-3407,-3127 ;Sin(340) ou Cos(250)
dc.w -2846,-2564,-2281,-1997,-1713,-1428,-1143,-858,-572,-286 ;Sin(350) ou Cos(260)
dc.w -1,285,571,857,1142,1427,1712,1996,2280,2563 ;Sin(360) ou Cos(270)
dc.w 2845,3126,3406,3685,3963,4240,4516,4790,5062,5334 ;Sin(370) ou Cos(280)
dc.w 5603,5871,6137,6401,6663,6924,7182,7438,7691,7943 ;Sin(380) ou Cos(290)
dc.w 8191,8438,8682,8923,9161,9397,9630,9860,10086,10310 ;Sin(390) ou Cos(300)
dc.w 10531,10748,10963,11173,11381,11585,11785,11982,12175,12365 ;Sin(400) ou Cos(310)
dc.w 12550,12732,12910,13084,13254,13420,13582,13740,13894,14043 ;Sin(410) ou Cos(320)
dc.w 14188,14329,14466,14598,14725,14848,14967,15081,15190,15295 ;Sin(420) ou Cos(330)
dc.w 15395,15491,15582,15668,15749,15825,15897,15964,16025,16082 ;Sin(430) ou Cos(340)
dc.w 16135,16182,16224,16261,16294,16321,16344,16361,16374,16381 ;Sin(440) ou Cos(350)

FinCalcul3D:
movem.l (sp)+,d0-d7/a0-a6

ENDC
*
*
*** FIN CALCUL 3D ***************************

*** TRACER AU BLITTER ********************************
*
*
IFNE AffLigneBlitter
movem.l d0-d7/a0-a6,-(sp)
;clr.l d7
clr.l d0/d6

WAITBLIT
move.w #40,BLTCMOD(A5) ;=largeur du plan de pixel en octets
move.w #40,BLTDMOD(A5) ;=largeur du plan de pixel en octets
move.w #$8000,BLTADAT(A5)
move.w #$FFFF,BLTBDAT(A5) :texture de la droite, $FFFF = pleine
move.w #$FFFF,BLTAFWM(A5) ;=$FFFF
move.w #$FFFF,BLTALWM(A5) ;=$FFFF
lea TableOctant(pc),a0

move.l bitplaneB,A1 ;A1 et A2 utilisés comme copie dans la boucle

;tracé de l'objet 3D
IFNE AffObjet3D ************************** TRACER OBJET 3D
lea PointsCalcules,a3 ******* DEBUG
lea Lignes,a4

move.w #((FinLignes-Lignes)/4)-1,d7
BoucleTracer3D:
moveq.l #0,d0
moveq.l #0,d1
moveq.l #0,d2
moveq.l #0,d3

move.w (a4)+,d3 ;offset 1er point
move.w (a3,d3),d0 ;x1
move.w 4(a3,d3),d1 ;y1 (z)

move.w (a4)+,d3 ;offset 2eme point
move.w (a3,d3),d2 ;x2
move.w 4(a3,d3),d3 ;y2 (z)

bsr _TracerLigne

dbf d7,BoucleTracer3D

;tracé des axes de rotation
IFNE DEBUGDISPLAYTIME ************************** DEBUG

lea CosinusTbl,a3
lea SinusTbl,A4

lea AngleAx,a6

moveq.l #3-1,d7
BoucleAffAngles:
move.l #290,d0 ;x1
move.l #30,d1 ;y1
move.l #20,d4 ;rayon

;ajout du pas y
moveq.l #0,d5
move.w d7,d5
muls #40,d5
add.w d5,d1

moveq.l #0,d5
move.w (a6)+,d5 ;angle AX, AY, AZ
add.w d5,d5 ;angle table

move.w (a3,d5),d2 ;attention adressage pair
muls d4,d2
lsr.l #7,d2
lsr.l #7,d2 ;x2
add.l d0,d2

move.w (a4,d5),d3 ;attention adressage pair
muls d4,d3
lsr.l #7,d3
lsr.l #7,d3 ;y2
add.l d1,d3

bsr _TracerLigne

dbf d7,BoucleAffAngles

ENDC ************************** FIN DEBUG

movem.l (sp)+,d0-d7/a0-a6

bra _FinTracerBlitter

; a: dc.l 0
; x1: dc.l 0
; y1: dc.l 0
; x2: dc.l 0
; y2: dc.l 0

ENDC ************************** FIN TRACE OBJET 3D

_TracerLigne:
; ------------------------------
; BIT# BLTCON0 BLTCON1
; ---- ------- -------
; 15 START3 TEXTURE3
; 14 START2 TEXTURE2
; 13 START1 TEXTURE1
; 12 START0 TEXTURE0
; 11 1 0
; 10 0 0
; 09 1 0
; 08 1 0
; 07 LF7 0
; 06 LF6 SIGN
; 05 LF5 0 (Reserved)
; 04 LF4 SUD
; 03 LF3 SUL
; 02 LF2 AUL
; 01 LF1 SING
; 00 LF0 LINE(=1) = LINE DRAW

;---- Calculer Octant ----
;Arguments (d0=x1,d1=y1,d2=x2,d3=y2)
;utilisés : d4,a0,a1
;d0..d4,A0

moveq.l #0,d4 ;4 cycles
sub.w d1,d3 ;d3=dy=y2-y1
bpl.b y2_sup_y1
bset #2,d4 ;8 cycles
neg.w d3 ;d3=abs(dy)
y2_sup_y1:
sub.w d0,d2 ;d2=dx=x2-x1
bpl.b x2_sup_x1
bset #1,d4
neg.w d2 ;d2=abs(dx)
x2_sup_x1:
cmp.w d3,d2 ;D3=dy vs D2=dx
bpl.b dX_sup_dY
bset #0,d4
exg d2,d3
dX_sup_dY:

move.b (a0,d4),d5 ;octant dans D5

;d3=dy=petit delta
;d2=dx=GRAND DELTA

;---- Adresse de départ ----
;D0=x1, D1=y1
;d2=dx, d3=dY

move.l a1,a2 ;BitplaneB ;4 cycles

ror.l #4,d0 ;move upper four bits into hi word
add.w d0,d0 ;d0=d0*2
add.l d0,a2 ;bitplaneB+x1/8
;l'adressage étant sur 24 bits les 4 bits HI n'influent pas

;d1=y1
;36 cycles
lsl.w #3,d1 ;d1=y1*8
add.w d1,a2 ;A2=bitplaneB+(x1/8)+y1*8
add.w d1,d1 ;d1=y1*16
add.w d1,d1 ;d1=y1*32
add.l d1,a2 ;a2=bitplaneB+(x1/8)+y1*40 = adresse de départ

moveq.l #0,d6 ;clr.l d6 ;,d1

;d3=dY
add.w d3,d3 ;d3=dy*2
add.w d3,d3 ;d3=dy*4 ;;lsl.w #2,d3 ;10 cycles
move.w D3,D4 ;D4=4*dy
move.w d2,d1 ;d1=d2=dX
add.w d1,d1 ;lsl.w #1,d1 ;D1=2*dx

WAITBLIT
move.w d3,BLTBMOD(A5) ;=4*dy
sub.w d1,D3 ;d3=4*dy - 2*dx
roxl.w #7,D6 ;si D3<0, placer le bit SIGN à 1 dans BLTCON1

move.l d3,BLTAPTH(A5) ;=4*dY-2*dX,

add.w d1,d1 ;lsl.w #1,d1 ;D1=2*2*dx
sub.w D1,D4 ;d4=4*dy-4*dx
move.w d4,BLTAMOD(A5) ;=4*dy-4*dx

swap d0
or.w d6,D0
or.w #$0BCA,D0

move.w d0,BLTCON0(A5) ;bits 15,14,13,12 = point de départ de la droite
;bit 11,10,9,8 = %1011
;bit 7..0 = $CA
or.w D6,D5 ;%xxxx000000xxxx01

;bset #1,D5 ;pour tracer un seul pt par ligne
;l'inscrire directement dans Tableoctant pour éviter une instruction

move.l a2,BLTCPTH(A5) ;adresse du point de départ de la droite
move.l a2,BLTDPTH(A5) ;idem
move.w d5,BLTCON1(A5) ;bits 15,14,13, 12 = point de départ de la droite
;bits 11..7 = %00000
;bit 6 = 1 si 4*dY-2*dX<0 ;bit 5 = 0 ;bits 4,3,2 = code Octant ;bit 1 = 1, 1 point par ligne ;bit 0 = 1 mode tracé de droite add.w #$01,d2 ;dx+1 lsl.w #6,d2 ;(dx+1)*64 ; 20 cycles add.w #$02,d2 ;(dx+1)*64+2 move.w d2,BLTSIZE(A5) ;c'est parti = (dX+1)*64+2 rts TableOctant: ;3 premiers bits=octant, bit1 = 1 si 1 pt /ligne, bit 0=1 mode tracé de ligne dc.b %10001 dc.b %00001 dc.b %10101 dc.b %01001 dc.b %11001 dc.b %00101 dc.b %11101 dc.b %01101 even ENDC ** ** **** FIN TRACE AU BLITTER ******************* IFNE CTR BltWait: dc.l 0 BltCtr: dc.l 0 ENDC _FinTracerBlitter: *** Effacer le bitplane caché ************************ IFNE EffacerBitPlaneCache WAITBLIT move.w #0,BLTDMOD(a5) move.w #$0000,BLTCON1(a5) move.w #%0000000100000000,BLTCON0(a5) move.l bitplaneC,BLTDPTH(a5) move.w #(DISPLAY_DX>>4)!(DISPLAY_DY<<6),BLTSIZE(a5) ENDC IFNE DEBUGDISPLAYTIME move.w #$00F0,COLOR00(a5) ENDC ;********** DEBUGDISPLAYTIME (start) ********** ;affiche en décimal le nombre de lignes écoulées depuis la fin de l'écran (depuis la ligne DISPLAY_Y+DISPLAY_DY incluse) ;la trame se termine en DISPLAY_Y+DISPLAY_DY-1 ;le temps est donc compté en nombre de ligne à partir de DISPLAY_Y+DISPLAY_DY incluse IFNE DEBUGDISPLAYTIME movem.l d0-d2/a0-a3,-(sp) clr.w d0 move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmp.w #DISPLAY_Y+DISPLAY_DY,d0 bge _timeBelowBitplanes ;on est passé en haut de l'écran add.w #1+312-(DISPLAY_Y+DISPLAY_DY-1),d0 ;312 est la ligne la plus basse que peut trace le faisceau d'électrons bra _timeDisplayCounter _timeBelowBitplanes: ;on est toujours en bas de l'écran sub.w #DISPLAY_Y+DISPLAY_DY-1,d0 _timeDisplayCounter: ;=>d0.w = # de lignes prises par les calculs à afficher
and.l #$0000FFFF,d0
moveq #0,d1
moveq #3-1,d2
_timeLoopNumber:
divu #10,d0 ;=> d0=reste:quotient de la division de d0 sur 32 bits
swap d0
add.b #$30-$20,d0 ;code ASCII de "0" moins l'offset de début dans font8 ($20)
move.b d0,d1
lsl.l #8,d1
clr.w d0
swap d0
dbf d2,_timeLoopNumber
divu #10,d0 ;=> d0=reste:quotient de la division de d0 sur 32 bits
swap d0
add.b #$30-$20,d0 ;code ASCII de "0" moins l'offset de début dans font8 ($20)
move.b d0,d1
;=> d1 : suite des 4 offset ASCII dans la police des 4 chiffres à afficher, mais en sens inverse (ex: 123 => "3210")
lea font8,a0
movea.l bitplaneB,a1
moveq #4-1,d0
_timeLoopDisplay:
clr.w d2
move.b d1,d2
lsl.w #3,d2
lea (a0,d2.w),a2
move.l a1,a3
moveq #8-1,d2
_timeLoopDisplayChar:
move.b (a2)+,(a3)
lea DISPLAY_DX>>3(a3),a3
dbf d2,_timeLoopDisplayChar
lea 1(a1),a1
lsr.l #8,d1
dbf d0,_timeLoopDisplay
movem.l (sp)+,d0-d2/a0-a3
ENDC

;********** DISPLAYTIME (end) **********

;Tester la pression du bouton gauche de la souris

btst #6,$bfe001
bne _loop

_loopEnd:
WAITBLIT

;---------- Finalisations ----------

exit:

;Couper le hardware

move.w #$7FFF,INTENA(a5)
move.w #$7FFF,INTREQ(a5)
move.w #$07FF,DMACON(a5)

;Rétablir le hardware

move.w dmacon_PTR,d0
bset #15,d0
move.w d0,DMACON(a5)
move.w intreq_PTR,d0
bset #15,d0
move.w d0,INTREQ(a5)
move.w intena_PTR,d0
bset #15,d0
move.w d0,INTENA(a5)

;Rétablir la Copper list

lea graphicslibrary,a1
movea.l $4,a6
jsr -408(a6)
move.l d0,a1
move.l 38(a1),COP1LCH(a5)
clr.w COPJMP1(a5)
jsr -414(a6)

;Rétablir le système

movea.l $4,a6
jsr -138(a6)

;Libérer la mémoire

movea.l Font16_PTR,a1
move.l #256<<5,d0 movea.l $4,a6 jsr -210(a6) movea.l bitplaneA,a1 move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
movea.l $4,a6
jsr -210(a6)
movea.l bitplaneB,a1
move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
movea.l $4,a6
jsr -210(a6)
movea.l bitplaneC,a1
move.l #(DISPLAY_DX*DISPLAY_DY)>>3,d0
movea.l $4,a6
jsr -210(a6)
movea.l copperlist_PTR,a1
move.l #COPSIZE,d0
movea.l $4,a6
jsr -210(a6)

;Dépiler les registres

movem.l (sp)+,d0-d7/a0-a6
rts

;---------- Données ----------

graphicslibrary:
DC.B "graphics.library",0
EVEN
font8:
;source zip ici :
;https://www.stashofcode.fr/code/coder-un-sine-scroll-sur-amiga/sinescroll.zip
INCBIN "sources:sinescroll/font8.fnt" ;32 à 127
EVEN

TEXT_POS: dc.l 0
dmacon_PTR: DC.w 0
intena_PTR: DC.w 0
intreq_PTR: DC.w 0
scrollColumn: DC.W 0
scrollChar: DC.W 0
angle: DC.W 0
copperlist_PTR: DC.L 0
Copperlist_BitPlanes_PTR: dc.l 0
Font16_PTR: DC.L 0
bitplaneA: DC.L 0
bitplaneB: DC.L 0
bitplaneC: DC.L 0

********************* COPPER LIST *********************

CopListDataStart:
;Configuration de l'écran
dc.w DIWSTRT,(DISPLAY_Y<<8)!DISPLAY_X
dc.w DIWSTOP,((DISPLAY_Y+DISPLAY_DY-256)<<8)!(DISPLAY_X+DISPLAY_DX-256)
dc.w BPLCON0,(DISPLAY_DEPTH<<12)!$0200
dc.w BPLCON1,SHADOW_DX<<4 dc.w BPLCON2,0 dc.w DDFSTRT,((DISPLAY_X-17)>>1)&$00FC
dc.w DDFSTOP,((DISPLAY_X-17+(((DISPLAY_DX>>4)-1)<<4))>>1)&$00FC ;Ce qui revient ((DISPLAY_X-17+DISPLAY_DX-16)>>1)&$00FC si DISPLAY_DX est multiple de 16
dc.w BPL1MOD,0
dc.w BPL2MOD,0

;Adresse des bitplanes

CplBitPlanes:
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL2PTL,0
dc.w BPL2PTH,0

;Couleurs

IFNE DEBUGDISPLAYTIME
dc.w $0186,0 ;COLOR04 pas utilisée, pour neutraliser de manière quelconque la modification de COLOR00...
ELSE
dc.w COLOR00,0
ENDC
dc.w COLOR01,SCROLL_COLOR
dc.w COLOR02,SHADOW_COLOR
dc.w COLOR03,SCROLL_COLOR

;Comptabilité ECS avec AGA

dc.w FMODE,$0000

;Ombre et miroir

dc.w ((DISPLAY_Y+SCROLL_Y+SHADOW_DY-1)<<8)!$0001,$FF00 dc.w BPL2MOD,-SHADOW_DY*(DISPLAY_DX>>3)

dc.w ((DISPLAY_Y+SCROLL_Y+SHADOW_DY)<<8)!$0001,$FF00
dc.w BPL2MOD,0
dc.w BPLCON1,SHADOW_DX<<4

dc.w ((DISPLAY_Y+MIRROR_Y-1)<<8)!$0001,$FF00 dc.w BPL1MOD,-(DISPLAY_DX>>3)
dc.w BPL2MOD,(SHADOW_DY-1)*(DISPLAY_DX>>3)

dc.w ((DISPLAY_Y+MIRROR_Y)<<8)!$0001,$FF00 dc.w BPLCON1,$0000 dc.w BPL1MOD,-(DISPLAY_DX>>2)
dc.w BPL2MOD,-(DISPLAY_DX>>2)

IFNE DEBUGDISPLAYTIME
dc.w $0188,MIRROR_COLOR ;COLOR04 pas utilisée, pour neutraliser de manière quelconque la modification de COLOR00...
ELSE
dc.w COLOR00,MIRROR_COLOR
ENDC

dc.w COLOR03,MIRROR_SCROLL_COLOR
;Fin
dc.l $FFFFFFFE
dc.l $00c0ffEE
CopListDataEnd:

COPSIZE=CopListDataEnd-CopListDataStart