;Version corrigée le 27/10/2018 pour fonctionner dans la trame en mode d'émulation strict dans WinUAE (options "Cycle-exact (full)" et "Cycle-exact (memory access)" cochés dans le panneau de contrôle Settings / Hardware / Chipet) sur A1200 uniquement. ;Code auquel il faudrait rajouter le "StingRay's stuff" pour quitter et rétablir le système proprement. Voir "base.s" pour des explications. ;Copyright (c) 2017, Denis Duplan. All Rights Reserved. ;ETAPE 7 ;Version 6 stabilisée à un moment à quoi j'ai rajouté l'étoile de 1994.s sur des bitplanes supplémentaires. ;Je ne suis pas certain qu'il compile toujours bien. Par exemple, j'ai dû ajouter un move.l #0,scrollColumn (en tout début de programme ! alors que rien n'est censé modifier sa valeur) ;Attention : le nombre total de colonnes de pixels du text ne peut dépasser 2^32-1, soit 2^27-1 caractères (2^5 octets par caractères) ;Noter que pour gagner du temps sur A500, on a supprimé le double test du bit 14 de DMACONR pour attendre le Blitter. Pas très safe peut-être? ;L'ombre et le miroir fonctionnent différemment des version antérieures ;Noter que comme le cosinus est toujours < 1, les coordonnées limites SCROLL_Y et SCROLL_Y+SCROLL_DY-1 ne sont jamais atteintes par le scroll (d'où notamment une ligne vide, avec seulement de l'ombre, entre la dernière ligne du scroll et la première ligne du miroir) ;un truc de vérifié : si on change le modulo lors d'un wait ligne Y (correspondant à y de DIWSTRAT+offset) en ignorant l'abscisse alors cela affecte la ligne Y+1 DEBUGDISPLAYTIME=0 DEBUGDISPLAYCHAR=0 DEBUGDRAWLINE=0 ;---------- Directives ---------- SECTION yragael,CODE_C ;---------- Constantes ---------- ;Registres VPOSR=$004 VHPOSR=$006 INTENA=$09A INTENAR=$01C INTREQ=$09C INTREQR=$01E DMACON=$096 DMACONR=$002 BLTAFWM=$044 BLTALWM=$046 BLTAPTL=$052 BLTBPTH=$04C 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 BPL3PTH=$0E8 BPL3PTL=$0EA BPL4PTH=$0EC BPL4PTL=$0EE COLOR00=$180 COLOR01=$182 COLOR02=$184 COLOR03=$186 COP1LCH=$080 COPJMP1=$088 FMODE=$1FC ;Programme BLITTER=1 ;0=tracer au CPU 1=tracer au Blitter DISPLAY_DEPTH=4 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 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)), car ne pas oublier que ce le Blitter appelle DX, c'est max (|x2-x1|, |y2-y1|) LINE_DY=0 ;C'est le nombre de colonnes de la droite - 1 : LINE_DY=min (abs(15-0),abs(0,0)), car ne pas oublier que ce le Blitter appelle DY, c'est min (|x2-x1|, |y2-y1|) 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) SHADOW_DX=2 ;Compris entre 0 et 15 SHADOW_DY=2 TEXT_XOR=$3B TEXT_CHECKSUM=$12eda TEXT_CHECKSUM_LAMER=$7f6 STAR_DX=162 STAR_DY=162 STAR_X=(DISPLAY_DX-STAR_DX)>>1 ;Angle supérieur gauche STAR_Y=(MIRROR_Y-STAR_DY)>>1 ;Angle supérieur gauche STAR_SPEED=2 SCROLL_COLOR=$0FFF SCROLL_SHADOW_COLOR=$0777 STAR_COLOR=$0FF0 STAR_SHADOW_COLOR=$0770 MIRROR_COLOR=$000F MIRROR_SCROLL_COLOR=$000A MIRROR_STAR_COLOR=$0770 COPSIZE=34*4+28*4+4 ;Attention à modifier le code modifiant la Copper list (permutation circulaire des bitplanes) si la Copper list est modifiée ! ;---------- 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\@ btst #14,DMACONR(a5) bne _waitBlitter0\@ ;_waitBlitter1\@ ;désactivé pour optimiser : permet de passer sous la trame sur A500 ; btst #14,DMACONR(a5) ; bne _waitBlitter1\@ ENDM ;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 CHECKTEXT: MACRO movem.l d0-d1/a0-a1,-(sp) lea text,a0 clr.l d0 clr.l d1 _checkTextLoop\@ move.b (a0)+,d0 add.l d0,d1 eor.b #TEXT_XOR,d0 bne _checkTextLoop\@ cmp.l textChecksum,d1 beq _checkTextOK\@ move.l #TEXT_CHECKSUM_LAMER,textChecksum lea text,a0 lea textLamer,a1 _checkTextLamerLoop\@ move.b (a1)+,d0 move.b d0,(a0)+ eor.b #TEXT_XOR,d0 bne _checkTextLamerLoop\@ _checkTextOK\@ movem.l (sp)+,d0-d1/a0-a1 ENDM ;---------- Initialisations ---------- ;Empiler les registres movem.l d0-d7/a0-a6,-(sp) move.l #0,scrollColumn ;Pourquoi ? ;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 ;Idem pour les bitplanes (bitplaneX = deux bitplanes contigus pour les effacer en une fois, donc (DISPLAY_DX*DISPLAY_DY)>>2 octets) move.l #(DISPLAY_DX*DISPLAY_DY)>>2,d0 move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,bitplaneA move.l #(DISPLAY_DX*DISPLAY_DY)>>2,d0 move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,bitplaneB move.l #(DISPLAY_DX*DISPLAY_DY)>>2,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 ;Idem pour les coordonnées transformées des sommets de l'étoile move.l #20*4,d0 move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,coordinates ;Idem pour les colonnes de pixels du texte lea text,a0 _textsize: move.b (a0)+,d1 eor.b #TEXT_XOR,d1 bne _textsize move.l a0,d0 sub.l #text,d0 lsl.w #5,d0 ;16 colonnes de 16 pixels par caractère = 32 octets move.l d0,textColumnsSize move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,textColumns ;Idem pour les ordonnées possibles des colonnes de pixels du texte move.l #360<<1,d0 move.l #$10002,d1 movea.l $4,a6 jsr -198(a6) move.l d0,ordinates ;Couper le système movea.l $4,a6 jsr -132(a6) ;Couper les interruptions hardware et les DMA lea $DFF000,a5 move.w INTENAR(a5),intena move.w #$7FFF,INTENA(a5) move.w INTREQR(a5),intreq move.w #$7FFF,INTREQ(a5) move.w DMACONR(a5),dmacon move.w #$07FF,DMACON(a5) ;---------- Création de la Copper list ---------- movea.l copperlist,a0 ;Configuration de l'écran move.w #DIWSTRT,(a0)+ move.w #(DISPLAY_Y<<8)!DISPLAY_X,(a0)+ move.w #DIWSTOP,(a0)+ move.w #((DISPLAY_Y+DISPLAY_DY-256)<<8)!(DISPLAY_X+DISPLAY_DX-256),(a0)+ move.w #BPLCON0,(a0)+ move.w #(DISPLAY_DEPTH<<12)!$0200,(a0)+ move.w #BPLCON1,(a0)+ move.w #SHADOW_DX<<4,(a0)+ move.w #BPLCON2,(a0)+ move.w #0,(a0)+ move.w #DDFSTRT,(a0)+ DDFDELAY=9 ;Au dessus de 9 mais en dessous de 10 : le retard minimum qu'on doit se donner pour afficher les 320 pixels avant de sortir de DIWSTOP, ce qu'on peut visualiser en notant sur les 16 derniers pixels de la ligne disparaissent tant que DDFDELAY <= 9 ;quand on augmente DDFDELAY entre 26 et 25 on perd les premiers 16 pixels _DDFSTRT=(DISPLAY_X-DDFDELAY)>>1 ;on >>1 car on voit que dans DDFSTRT et DDFSTOP, on ne stocke pas le bit 0 _DDFSTOP=_DDFSTRT+((DISPLAY_DX-16)>>1) ;car si on lit par paquets de 16 pixels à partir de DISPLAY_X-DDFDELAY, la dernière fois qu'on lit sera avant le dernier paquet de 16 pixels ;cette formule est bien celle de AHRF : ddfstop=dffstrt+((dx/16)-1)/2 ;la seule chose qui reste à comprendre, c'est le délai :pourquoi une valeur minimale dans [9,10]? ; move.w #_DDFSTRT&$00FC,(a0)+ move.w #((DISPLAY_X-17)>>1)&$00FC,(a0)+ move.w #DDFSTOP,(a0)+ ; move.w #_DDFSTOP&$00FC,(a0)+ move.w #((DISPLAY_X-17+(((DISPLAY_DX>>4)-1)<<4))>>1)&$00FC,(a0)+ ;Ce qui revient ((DISPLAY_X-17+DISPLAY_DX-16)>>1)&$00FC si DISPLAY_DX est multiple de 16 move.w #BPL1MOD,(a0)+ move.w #0,(a0)+ move.w #BPL2MOD,(a0)+ move.w #0,(a0)+ ;Adresse des bitplanes move.w #BPL1PTL,(a0)+ move.l bitplaneA,d0 move.w d0,(a0)+ move.w #BPL2PTL,(a0)+ move.w d0,(a0)+ move.w #BPL1PTH,(a0)+ swap d0 move.w d0,(a0)+ move.w #BPL2PTH,(a0)+ move.w d0,(a0)+ move.w #BPL3PTL,(a0)+ swap d0 addi.l #DISPLAY_DY*(DISPLAY_DX>>3),d0 move.w d0,(a0)+ move.w #BPL4PTL,(a0)+ move.w d0,(a0)+ move.w #BPL3PTH,(a0)+ swap d0 move.w d0,(a0)+ move.w #BPL4PTH,(a0)+ move.w d0,(a0)+ ;Couleurs lea colors,a1 moveq #1,d1 lsl.w #DISPLAY_DEPTH,d1 IFNE DEBUGDISPLAYTIME move.w #$0188,(a0)+ ;COLOR04 pas utilisée pour neutraliser toute modification de COLOR00 par la Copper list sans modifier la structure de cette dernière move.w (a1)+,(a0)+ move.w #COLOR01,d0 subq.b #2,d1 ELSE move.w #COLOR00,d0 subq.b #1,d1 ENDC _colors: move.w d0,(a0)+ move.w (a1)+,(a0)+ addq.w #2,d0 dbf d1,_colors ;Comptabilité OCS avec AGA move.w #FMODE,(a0)+ move.w #$0000,(a0)+ ;Ombre et miroir move.w #((DISPLAY_Y+STAR_Y+SHADOW_DY-1)<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ move.w #BPL2MOD,(a0)+ move.w #-SHADOW_DY*(DISPLAY_DX>>3),(a0)+ move.w #((DISPLAY_Y+STAR_Y+SHADOW_DY)<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ move.w #BPL2MOD,(a0)+ move.w #0,(a0)+ move.w #BPLCON1,(a0)+ move.w #SHADOW_DX<<4,(a0)+ move.w #((DISPLAY_Y+MIRROR_Y-1)<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ move.w #BPL1MOD,(a0)+ move.w #-(DISPLAY_DX>>3),(a0)+ move.w #BPL2MOD,(a0)+ move.w #(SHADOW_DY-1)*(DISPLAY_DX>>3),(a0)+ move.w #((DISPLAY_Y+MIRROR_Y)<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ move.w #BPLCON1,(a0)+ move.w #$0000,(a0)+ move.w #BPL1MOD,(a0)+ move.w #-(DISPLAY_DX>>2),(a0)+ move.w #BPL2MOD,(a0)+ move.w #-(DISPLAY_DX>>2),(a0)+ lea mirrorColors,a1 moveq #1,d1 lsl.w #DISPLAY_DEPTH,d1 IFNE DEBUGDISPLAYTIME move.w #$0188,(a0)+ ;COLOR04 pas utilisée pour neutraliser toute modification de COLOR00 par la Copper list sans modifier la structure de cette dernière move.w (a1)+,(a0)+ move.w #COLOR01,d0 subq.b #2,d1 ELSE move.w #COLOR00,d0 subq.b #1,d1 ENDC _mirrorColors: move.w d0,(a0)+ move.w (a1)+,(a0)+ addq.w #2,d0 dbf d1,_mirrorColors ;Fin move.l #$FFFFFFFE,(a0) ;Activer la Copper list move.l copperlist,COP1LCH(a5) clr.w COPJMP1(a5) ;Rétablir les DMA 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,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 beq _fontPixelEmpty bset d4,d3 addq.b #1,d4 bset d4,d3 addq.b #1,d4 bra _fontNextPixel _fontPixelEmpty: addq.b #2,d4 _fontNextPixel: 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 ---------- ;Boucle principale ;********** DEBUGDISPLAYCHAR (start) ********** IFNE DEBUGDISPLAYCHAR ;Affichage de texte normal (font 16x16) attention ça affiche tout le texte sans passer à la ligne move.l bitplaneA,a0 move.w #SCROLL_Y,d0 lsl.w #5,d0 move.w #SCROLL_Y,d1 lsl.w #3,d1 add.w d1,d0 move.w #SCROLL_X,d1 lsr.w #3,d1 bclr #0,d1 add.w d1,d0 lea (a0,d0.w),a0 ;a0 = adresse du mot où doit commencer l'affichage du bitmap du caractère move.w #SCROLL_X,d1 and.w #$000F,d1 move.w #15,d0 sub.w d1,d0 ;d0 = bit dans ce mot où doit commencer l'affichage du bitmap du caractère lea text,a1 ;a1 = adresse du caractère courant _characters_loop: clr.w d1 move.b (a1)+,d1 ;d1 = caractère à afficher eor.b #TEXT_XOR,d1 beq _characters_end sub.b #$20,d1 lsl.w #5,d1 move.l font16,a2 lea (a2,d1.w),a2 ;a2 = adresse du bitmap du caractère move.w #16-1,d2 ;d2 = compteur de colonnes du bitmap _columns_loop: move.w (a2)+,d3 ;d3 = colonne du bitmap move.w #15,d4 ;d4 = bit courant de la colonne du bitmap (d3) move.l a0,a3 ;a3 = adresse du mot où afficher le bit courant (d4) de la colonne du bitmap (d3) _pixels_loop: btst d4,d3 beq _pixel_zero move.w (a3),d5 ;d5 = mot de l'affichage où le bit courant (d4) de la colonne du bitmap (d3) doit être affiché au bit courant (d0) bset d0,d5 move.w d5,(a3) _pixel_zero: lea 40(a3),a3 dbf d4,_pixels_loop subq.w #1,d0 bge _display_nooverflow move.w #15,d0 lea 2(a0),a0 _display_nooverflow: dbf d2,_columns_loop bra _characters_loop _characters_end: btst #6,$BFE001 bne _characters_end bra _loopEnd ENDC ;********** DEBUGDISPLAYCHAR (end) ********** ;********** DEBUGDRAWLINE (start) ********** IFNE DEBUGDRAWLINE ;on présume ici que LINE_DX > LINE_DY move.l bitplaneA,a4 moveq #15,d7 WAITBLIT move.l a4,BLTCPTH(a5) move.l a4,BLTDPTH(a5) 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 #$8001,BLTBDAT(a5) ;Motif 1000 0000 0000 0001 move.w #(LINE_OCTANT<<2)!$F041,BLTCON1(a5) ;BSH3-0=15, SIGN=1, OVF=0, SUD/SUL/AUL=octant, SING=0, LINE=1 move.w d7,d2 ror.w #4,d2 or.w #$0B4A,d2 move.w d2,BLTCON0(a5) ;ASH3-0=pixel, USEA=1, USEB=0, USEC=1, USED=1, LF7-0=AB+AC=$4A move.w #((LINE_DX+1)<<6)!$0002,BLTSIZE(a5) _debugDrawLineLoop: btst #6,$BFE001 bne _debugDrawLineLoop bra _loopEnd ENDC ;********** DEBUGDRAWLINE (end) ********** CHECKTEXT ;Précalcul de toutes les positions verticales lea sinus,a0 movea.l ordinates,a1 move.w #360-1,d0 _precomputeOrdinates: move.w (a0)+,d1 muls #(SCROLL_AMPLITUDE>>1),d1 swap d1 rol.l #2,d1 addi.w #SCROLL_Y+(SCROLL_AMPLITUDE>>1),d1 mulu #DISPLAY_DX>>3,d1 ;on s'ennuie pas à optimiser x*40=x*(2^5+2^3)... IFNE BLITTER ;Le Blitter trace les colonnes de bas en haut du fait de l'orientation du motif addi.w #LINE_DX*(DISPLAY_DX>>3),d1 ENDC move.w d1,(a1)+ dbf d0,_precomputeOrdinates ;Précalcul de toutes les colonnes de pixels du texte clr.l d1 lea text,a0 movea.l textColumns,a1 movea.l font16,a2 _precomputeColumnsCharLoop: clr.w d0 move.b (a0)+,d0 ;caractère à afficher eor.b #TEXT_XOR,d0 beq _precomputeColumnsEnd sub.b #$20,d0 lsl.w #5,d0 ;32 octets par caractère dans la police 16 lea (a2,d0.w),a3 ;adresse de la colonne courante du bitmap du caractère à afficher moveq #16-1,d0 _precomputeColumnsLinesLoop: move.w (a3)+,(a1)+ dbf d0,_precomputeColumnsLinesLoop addi.l #16,d1 bra _precomputeColumnsCharLoop _precomputeColumnsEnd: move.l d1,textNbColumns ;test d'affichage d'un char ; movea.l bitplaneA,a0 ; movea.l textColumns,a1 ; lea 32*26(a1),a1 ; moveq #16-1,d0 ;debug0: ; move.w (a1)+,(a0) ; lea DISPLAY_DX>>3(a0),a0 ; dbf d0,debug0 ;debug1: ; btst #6,$BFE001 ; bne debug1 ; bra _loopEnd ;Boucle principale ; move.l #0,scrollColumn ;Pourquoi ? _loop: ;Attendre que le faisceau d'électrons a terminé de tracer l'écran (ne marche que tant que l'exécution prend plus de temps qu'il n'en faut au faisceau pour reboucler sur la ligne 0) _waitVBL: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmpi.w #DISPLAY_Y+DISPLAY_DY,d0 blt _waitVBL IFNE DEBUGDISPLAYTIME move.w #$0F00,COLOR00(a5) ENDC ;Permuter circulairement les bitplanes move.l bitplaneA,d0 move.l bitplaneB,d1 move.l bitplaneC,d2 move.l d1,bitplaneA move.l d2,bitplaneB move.l d0,bitplaneC movea.l copperlist,a0 move.l d1,d0 move.l d1,d2 add.l #DISPLAY_DY*(DISPLAY_DX>>3),d2 move.w d0,9*4+2(a0) move.w d0,10*4+2(a0) move.w d2,13*4+2(a0) move.w d2,14*4+2(a0) swap d0 swap d2 move.w d0,11*4+2(a0) move.w d0,12*4+2(a0) move.w d2,15*4+2(a0) move.w d2,16*4+2(a0) ;Initialiser la boucle d'affichage du texte movea.l bitplaneB,a0 movea.l textColumns,a1 move.l textColumnsSize,d0 lea (a1,d0.l),a3 move.l scrollColumn,d0 lsl.l #1,d0 ;1 colonne = 1 mot lea (a1,d0.l),a1 movea.l ordinates,a2 move.w angle,d0 move.w #SCROLL_DX-1,d1 move.w #SCROLL_X,d2 lsr.w #3,d2 ;offset en octets de la colonne de l'écran bclr #0,d2 ;laquelle colonne doit être dans un mot (tout ça revient à lsr.w #4 puis lsl.w #1) IFNE BLITTER 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 ;Blitter : il lui faut le numéro du pixel dans le mot de l'écran move.w #SCROLL_X,d3 and.w #$000F,d3 ror.w #4,d3 or.w #$0B4A,d3 ELSE ;CPU : il lui faut le numéro du bit correspondant au pixel dans le mot de l'écran moveq #SCROLL_X,d4 and.w #$000F,d4 moveq #15,d3 sub.b d4,d3 ENDC ;A0 = bitplane ;A1 = colonnes de pixels du texte ;A2 = ordonnées ;A3 = adresse suivant celle de la dernière colonne de pixels du texte ;D0 = offset de l'ordonnée correspondant à l'angle dont le cosinus détermine l'ordonnée de la colonne de pixels courante ;D1 = compteur pour parcourir toutes les colonnes à tracer (SCROLL_DX colonnes) ;D2 = offset en octets du word contenant la colonne de pixels courante à l'écran ;D3 = numéro du pixel de la colonne courante dans le mot courant de l'écran pour BLT (au format requis pour BLTCON0) / numéro du bit de ce pixel (CPU) _writeLoop: ;Calculer l'adresse du mot du premier pixel de la colonne courante à l'écran move.w (a2,d0.w),d4 add.w d2,d4 lea (a0,d4.w),a4 ;Afficher la colonne de pixels courante du texte IFNE BLITTER ;Blitter : tracer la colonne en une fois ;on présume ici que LINE_DX > LINE_DY WAITBLIT move.l a4,BLTCPTH(a5) move.l a4,BLTDPTH(a5) move.w (a1)+,BLTBDAT(a5) move.w d3,BLTCON0(a5) ;ASH3-0=pixel, USEA=1, USEB=0, USEC=1, USED=1, LF7-0=AB+AC=$4A move.w #((LINE_DX+1)<<6)!$0002,BLTSIZE(a5) ELSE ;CPU : tracer la colonne bit à bit move.w (a1)+,d7 clr.b d6 moveq #LINE_DX,d5 ;boucle d'affichage des ligne (si on se fixait à 16 lignes, on pourrait remplacer le DBF par un BTST #4,D6 et ainsi gagner du temps) _pixel_loop: btst d6,d7 beq _pixelEmpty move.w (a4),d4 bset d3,d4 move.w d4,(a4) ;passer par D4 n'est sans doute pas plus optimal qu'un BSET D3,(A4) mais il faudrait que A4 donne l'adresse de l'octet et non du word... _pixelEmpty: lea 40(a4),a4 addq.b #1,d6 dbf d5,_pixel_loop ENDC ;A FAIRE tester la necessite de boucler le texte IFNE BLITTER ;Blitter : il lui faut le numéro du pixel dans le mot de l'écran addi.w #$1000,d3 bcc _pixelKeepWord addq.w #2,d2 _pixelKeepWord: ELSE ;CPU : il lui faut le numéro du bit correspondant au pixel dans le mot de l'écran subq.b #1,d3 bge _pixelKeepWord addq.w #2,d2 moveq #15,d3 _pixelKeepWord: ENDC ;Passer à la colonne suivante ou boucler sur la première cmp.l a1,a3 bne _nextColumnNoLoop movea.l textColumns,a1 _nextColumnNoLoop: ;Incrémenter l'angle subq.w #(SINE_SPEED_PIXEL<<1),d0 bge _anglePixelNoLoop addi.w #(360<<1),d0 _anglePixelNoLoop: dbf d1,_writeLoop ;Faire défiler le texte ;scrollChar = indice du 1er caractère affiché dans text ;scrollSpeed = vitesse du scroll en pixels (0 à 16) ;scrollPixel = indice de la 1ère colonne de pixels du 1er caractère affiché (0 à 15) move.l scrollColumn,d0 addq.l #SCROLL_SPEED,d0 cmp.l textNbColumns,d0 blt _scrollnoloop sub.l textNbColumns,d0 _scrollnoloop: move.l d0,scrollColumn ;Animer le sinus de l'image move.w angle,d0 subi.w #(SINE_SPEED_FRAME<<1),d0 bge _angleFrameNoLoop addi.w #(360<<1),d0 _angleFrameNoLoop: move.w d0,angle ;----- rotation Z ----- move.w angleStar,d0 subq.w #STAR_SPEED<<1,d0 bge Main_RotationZ move.w #(360-STAR_SPEED)<<1,d0 Main_RotationZ: move.w d0,angleStar ;----- calcul des coordonnees ----- movea.l coordinates,a0 lea points,a2 lea cosinus,a3 lea sinus,a4 lea (a3,d0.w),a3 lea (a4,d0.w),a4 rept 20 move.w (a2)+,d0 move.w (a2)+,d1 bsr Rotate_Z add.w #STAR_X+(STAR_DX>>1),d0 move.w d0,(a0)+ add.w #STAR_Y+(STAR_DY>>1),d1 move.w d1,(a0)+ endr ;----- trace les lignes ----- move.w #DISPLAY_DX>>3,BLTCMOD(a5) move.w #DISPLAY_DX>>3,BLTDMOD(a5) move.w #$8000,BLTAFWM(a5) ;A VOIR ! ; move.w #$0000,BLTALWM(a5) move.w #$8000,BLTADAT(a5) move.w #$FFFF,BLTBDAT(a5) ;motif droite movea.l coordinates,a3 lea lines,a2 movea.l bitplaneB,a0 lea DISPLAY_DY*(DISPLAY_DX>>3)(a0),a0 REPT 20 move.w (a2)+,d0 move.w 2(a3,d0.w),d1 move.w (a3,d0.w),d0 move.w (a2)+,d2 move.w 2(a3,d2.w),d3 move.w (a3,d2.w),d2 bsr DrawLine ENDR ;----- remplissage de surface ----- ;* FIX pour tenir dans la trame en cycle-exact * Remplir le rectangle englobant l'étoile IFNE STAR_X&$F STARRECT_LEFT=STAR_X&$FFF0 ELSE STARRECT_LEFT=STAR_X ENDC IFNE (STAR_X+STAR_DX)&$F STARRECT_RIGHT=((STAR_X+STAR_DX)&$FFF0)+16 ELSE STARRECT_RIGHT=STAR_X+STAR_DX ENDC STARRECT_DX=STARRECT_RIGHT-STARRECT_LEFT STARRECT_DY=STAR_DY STARRECT_X=STARRECT_LEFT STARRECT_Y=STAR_Y WAITBLIT move.w #(DISPLAY_DX-STARRECT_DX)>>3,BLTBMOD(a5) move.w #(DISPLAY_DX-STARRECT_DX)>>3,BLTDMOD(a5) move.w #%0000010111001100,BLTCON0(a5) move.w #%0000000000001010,BLTCON1(a5) movea.l bitplaneB,a0 lea (DISPLAY_DY+STARRECT_Y+STARRECT_DY)*(DISPLAY_DX>>3)-2-((DISPLAY_DX-STARRECT_DX)>>4)(a0),a0 move.l a0,BLTBPTH(a5) move.l a0,BLTDPTH(a5) move.w #(STARRECT_DX>>4)!(STARRECT_DY<<6),BLTSIZE(a5) ;* FIX pour tenir dans la trame en cycle-exact * Effacer le rectangle englobant (une bande) le sine scroll au Blitter ; WAITBLIT ; move.w #0,BLTDMOD(a5) ; move.w #$0000,BLTCON1(a5) ; move.w #$0100,BLTCON0(a5) ; movea.l bitplaneC,a0 ; lea SCROLL_Y*(DISPLAY_DX>>3)(a0),a0 ; move.l a0,BLTDPTH(a5) ; move.w #(DISPLAY_DX>>4)!(SCROLL_DY<<6),BLTSIZE(a5) ;* FIX pour tenir dans la trame en cycle-exact * Effacer le rectangle englobant (une bande) le sine scroll au CPU movea.l bitplaneC,a0 lea SCROLL_Y*(DISPLAY_DX>>3)(a0),a0 move.w #SCROLL_DY*(SCROLL_DX>>5)-1,d0 ;On peut y aller à grands coups de DWORD _clearSineScroll: move.l #0,(a0)+ dbf d0,_clearSineScroll ;* FIX pour tenir dans la trame en cycle-exact * Effacer le rectangle englobant l'étoile au Blitter ; WAITBLIT ; move.w #(DISPLAY_DX-STARRECT_DX)>>3,BLTDMOD(a5) ; move.w #$0000,BLTCON1(a5) ; move.w #$0100,BLTCON0(a5) ; move.l bitplaneC,a0 ; lea (DISPLAY_DY+STARRECT_Y)*(DISPLAY_DX>>3)+((DISPLAY_DX-STARRECT_DX)>>4)(a0),a0 ; move.l a0,BLTDPTH(a5) ; move.w #(STARRECT_DX>>4)!(STARRECT_DY<<6),BLTSIZE(a5) ;* FIX pour tenir dans la trame en cycle-exact * Effacer le rectangle englobant l'étoile au CPU movea.l bitplaneC,a0 lea (DISPLAY_DY+STARRECT_Y)*(DISPLAY_DX>>3)+((DISPLAY_DX-STARRECT_DX)>>4)(a0),a0 move.w #STARRECT_DY-1,d0 _clearStarDY: move.w #(STARRECT_DX>>4)-1,d1 _clearStarDX: move.w #0,(a0)+ dbf d1,_clearStarDX lea (DISPLAY_DX-STARRECT_DX)>>3(a0),a0 dbf d0,_clearStarDY 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 cmpi.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) ********** btst #6,$BFE001 bne _loop _loopEnd: WAITBLIT ;---------- Finalisations ---------- ;Couper les interruptions hardware et les DMA move.w #$7FFF,INTENA(a5) move.w #$7FFF,INTREQ(a5) move.w #$07FF,DMACON(a5) ;Rétablir les interruptions hardware et les DMA move.w dmacon,d0 bset #15,d0 move.w d0,DMACON(a5) move.w intreq,d0 bset #15,d0 move.w d0,INTREQ(a5) move.w intena,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,a1 move.l #256<<5,d0 movea.l $4,a6 jsr -210(a6) movea.l bitplaneA,a1 move.l #(DISPLAY_DX*DISPLAY_DY)>>2,d0 movea.l $4,a6 jsr -210(a6) movea.l bitplaneB,a1 move.l #(DISPLAY_DX*DISPLAY_DY)>>2,d0 movea.l $4,a6 jsr -210(a6) movea.l bitplaneC,a1 move.l #(DISPLAY_DX*DISPLAY_DY)>>2,d0 movea.l $4,a6 jsr -210(a6) movea.l copperlist,a1 move.l #COPSIZE,d0 movea.l $4,a6 jsr -210(a6) movea.l textColumns,a1 move.l textColumnsSize,d0 movea.l $4,a6 jsr -210(a6) movea.l coordinates,a1 move.l #20*4,d0 movea.l $4,a6 jsr -210(a6) ;Dépiler les registres movem.l (sp)+,d0-d7/a0-a6 rts ;*************** ROTATE Z *************** ;Entree: ; D0=X ; D1=Y ; D2=angle Z Rotate_Z: move.w (a3),d4 ;d4=cosZ swap d4 move.w (a4),d4 ;d4=cosZ:sinZ move.w d0,d2 ;d2=x muls d4,d0 swap d0 rol.l #2,d0 ;d0=xsinZ move.w d1,d3 muls d4,d3 swap d3 rol.l #2,d3 ;d3=ysinZ swap d4 ;d4=sinZ:cosZ muls d4,d2 swap d2 rol.l #2,d2 ;d2=xcosZ add.w d2,d3 ;d3=xcosZ+ysinZ muls d4,d1 swap d1 rol.l #2,d1 ;d1=ycosZ sub.w d0,d1 ;d1=ycosZ-xsinZ move.w d3,d0 ;d0=xcosZ+ysinZ rts ;*************** TRACE DE DROITES *************** ;Entree: ; A0=adresse bitplane ; D0=Xi ; D1=Yi ; D2=Xf ; D3=Yf ;A4,D5,D6 DrawLine: ;----- ordonnancement des points ----- cmp.w d1,d3 beq DrawLine_End bge DrawLine_UpDown exg d0,d2 exg d1,d3 DrawLine_UpDown: subq.w #1,d3 ;------ calcul adresse de depart de la droite ----- ;attention, suppose que DISPLAY_DX = 320 => x*40 = x*(32+8) = x*(2^5+2^3) moveq #0,d6 move.w d1,d6 move.w d1,d5 lsl.w #5,d6 lsl.w #3,d5 add.w d5,d6 ;d6=y1*nbre octets par ligne add.l a0,d6 ;+adresse depart bitplane moveq #0,d5 move.w d0,d5 lsr.w #3,d5 bclr #0,d5 add.l d5,d6 ;+x1/8 ;----- recherche de l'octant ----- moveq #0,d5 sub.w d1,d3 ;d3=Dy=y2-y1 bpl.b Dy_pos bset #2,d5 neg d3 Dy_pos: sub.w d0,d2 ;d2=Dx=x2-x1 bpl.b Dx_pos bset #1,d5 neg d2 Dx_pos: cmp.w d3,d2 ;Dx-Dy bpl.b DxDy_pos bset #0,d5 exg d3,d2 ;ainsi d3=Pdelta et d2=Gdelta DxDy_pos: add.w d3,d3 ;d3=2*Pdelta ;----- BLTCON0 ----- and.w #$F,d0 ror.w #4,d0 or.w #$B4A,d0 ;----- BLTCON1 ----- lea octants,a4 move.b (a4,d5.w),d5 lsl #2,d5 bset #0,d5 bset #1,d5 ;----- attente blitter ----- WAITBLIT ;----- BLTCON1, BLTBMOD, BLTAPTL, BLTAMOD ----- move.w d3,BLTBMOD(a5) sub.w d2,d3 bge.s DrawLine_NoBit bset #6,d5 DrawLine_NoBit: move.w d3,BLTAPTL(a5) sub.w d2,d3 move.w d3,BLTAMOD(a5) ;----- BLTSIZE ----- lsl #6,d2 add.w #66,d2 ;----- lancement blitter ----- move.w d5,BLTCON1(a5) move.w d0,BLTCON0(a5) move.l d6,BLTCPTH(a5) move.l d6,BLTDPTH(a5) move.w d2,BLTSIZE(a5) ;----- fin ----- DrawLine_End: rts ;---------- Données ---------- graphicslibrary: DC.B "graphics.library",0 EVEN font8: INCBIN "SOURCES:sinescroll/fontWobbly8x8x1.raw" EVEN text: DC.B $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $62, $69, $7a, $7c, $7a, $7e, $77, $1b, $59, $49, $52, $55, $5c, $41, $1b, $42, $5a, $1b, $5a, $1b, $54, $55, $5e, $1b, $4b, $52, $43, $5e, $57, $1b, $48, $52, $55, $5e, $1b, $48, $58, $49, $54, $57, $57, $1a, $1b, $68, $54, $49, $49, $42, $17, $1b, $55, $54, $1b, $a, $d, $43, $a, $d, $1b, $5d, $54, $55, $4f, $1b, $5a, $4d, $5a, $52, $57, $5a, $59, $57, $5e, $15, $1b, $72, $1b, $53, $5a, $5f, $1b, $4f, $54, $1b, $48, $4f, $49, $5e, $4f, $58, $53, $1b, $5a, $1b, $3, $43, $3, $1b, $54, $55, $5e, $17, $1b, $53, $5e, $55, $58, $5e, $1b, $52, $4f, $48, $1b, $4b, $52, $43, $5e, $57, $5e, $5f, $1b, $57, $54, $54, $50, $15, $15, $15, $1b, $7c, $49, $5e, $5e, $4f, $52, $55, $5c, $48, $1b, $5d, $54, $57, $57, $54, $4c, $15, $15, $15, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $68, $6f, $74, $69, $76, $6f, $69, $74, $74, $6b, $7e, $69, $1, $1b, $73, $54, $4c, $1b, $52, $48, $1b, $6b, $5a, $55, $41, $5e, $49, $1b, $79, $57, $52, $4f, $41, $1b, $5c, $54, $52, $55, $5c, $4, $1b, $78, $5a, $55, $1c, $4f, $1b, $4c, $5a, $52, $4f, $1b, $4f, $54, $1b, $4b, $57, $5a, $42, $1b, $4f, $53, $5e, $1b, $5c, $5a, $56, $5e, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $7f, $7a, $69, $70, $1b, $7e, $75, $6f, $69, $72, $7e, $68, $1, $1b, $7f, $54, $1b, $42, $54, $4e, $1b, $48, $4f, $52, $57, $57, $1b, $54, $4c, $55, $1b, $42, $54, $4e, $49, $1b, $7a, $56, $52, $5c, $5a, $1b, $a, $b, $b, $b, $4, $1b, $77, $54, $54, $50, $1b, $4e, $55, $5f, $5e, $49, $48, $52, $5f, $5e, $1b, $4f, $53, $5e, $1b, $57, $52, $5f, $1, $1b, $4f, $53, $5e, $49, $5e, $1b, $56, $5a, $42, $1b, $59, $5e, $1b, $4d, $5a, $57, $4e, $5a, $59, $57, $5e, $1b, $48, $52, $5c, $55, $5a, $4f, $4e, $49, $5e, $48, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $71, $6e, $75, $70, $72, $7e, $1, $1b, $75, $52, $58, $5e, $1b, $4f, $5e, $5a, $56, $1b, $4c, $54, $49, $50, $1b, $5f, $5e, $58, $54, $5f, $52, $55, $5c, $1b, $4f, $53, $5e, $1b, $7a, $7c, $7a, $1b, $49, $5e, $5c, $52, $48, $4f, $5e, $49, $48, $1a, $1b, $6f, $53, $54, $48, $5e, $1b, $5c, $4e, $42, $48, $1b, $5a, $4f, $1b, $78, $54, $56, $56, $54, $5f, $54, $49, $5e, $1b, $49, $5e, $5a, $57, $57, $42, $1b, $59, $5e, $57, $52, $5e, $4d, $5e, $5f, $1b, $55, $54, $59, $54, $5f, $42, $1b, $4c, $54, $4e, $57, $5f, $1b, $4f, $49, $42, $1b, $4f, $54, $1b, $56, $5e, $4f, $5a, $57, $1b, $59, $5a, $48, $53, $1b, $4f, $53, $5e, $1b, $58, $53, $52, $4b, $48, $5e, $4f, $4, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $78, $74, $69, $7e, $75, $6f, $72, $75, $1, $1b, $69, $5e, $56, $5e, $56, $59, $5e, $49, $52, $55, $5c, $1b, $4f, $53, $5e, $1b, $5d, $52, $49, $48, $4f, $1b, $4f, $52, $56, $5e, $1b, $72, $1b, $48, $5a, $4c, $1b, $5a, $55, $1b, $7a, $56, $52, $5c, $5a, $1b, $5c, $5a, $56, $5e, $15, $15, $15, $1b, $72, $4f, $1b, $4c, $5a, $48, $1b, $74, $59, $57, $52, $4f, $5e, $49, $5a, $4f, $54, $49, $1b, $49, $4e, $55, $55, $52, $55, $5c, $1b, $54, $55, $1b, $42, $54, $4e, $49, $48, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $73, $7e, $7a, $7f, $73, $6e, $75, $6f, $7e, $69, $1, $1b, $6f, $53, $5a, $55, $43, $1b, $5a, $5c, $5a, $52, $55, $1b, $5d, $54, $49, $1b, $4f, $53, $5e, $1b, $5f, $52, $48, $5a, $59, $57, $5e, $5f, $1b, $5a, $58, $58, $5e, $48, $48, $1a, $1b, $78, $54, $55, $5f, $5e, $56, $55, $5e, $5f, $1b, $78, $5e, $57, $57, $4, $1b, $79, $5e, $48, $4f, $1b, $5c, $5e, $49, $56, $5a, $55, $1b, $79, $79, $68, $1b, $5e, $4d, $5e, $49, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $76, $74, $75, $6f, $62, $1, $1b, $68, $4e, $58, $53, $1b, $5c, $49, $5e, $5a, $4f, $1b, $4f, $4e, $55, $5e, $48, $1b, $5d, $54, $49, $1b, $4f, $53, $5e, $1b, $58, $49, $5a, $58, $50, $4f, $49, $54, $48, $1a, $1b, $6c, $53, $5a, $4f, $1b, $5a, $1b, $4f, $5e, $5a, $56, $1b, $4c, $5e, $1b, $56, $5a, $5f, $5e, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $73, $7e, $7a, $6f, $73, $7e, $75, $1, $1b, $77, $54, $54, $50, $1b, $5a, $4f, $1b, $42, $54, $4e, $1a, $1b, $6c, $53, $5a, $4f, $1b, $5a, $1b, $4b, $5a, $52, $55, $4f, $59, $5a, $57, $57, $1b, $58, $53, $5a, $56, $4b, $52, $54, $55, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $76, $7a, $63, $72, $76, $72, $77, $72, $7e, $75, $1, $1b, $72, $1b, $5f, $54, $4e, $59, $4f, $1b, $42, $54, $4e, $1b, $4c, $52, $57, $57, $1b, $49, $5e, $5a, $5f, $1b, $4f, $53, $52, $48, $1b, $54, $55, $5e, $17, $1b, $59, $4e, $4f, $1b, $4c, $53, $5a, $4f, $5e, $4d, $5e, $49, $15, $15, $15, $1b, $72, $4f, $1b, $4c, $5a, $48, $1b, $5d, $4e, $55, $1b, $4f, $54, $1b, $58, $54, $5f, $5e, $1b, $4f, $53, $54, $48, $5e, $1b, $58, $49, $5a, $58, $50, $4f, $49, $54, $48, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $6f, $69, $72, $68, $6f, $7a, $75, $1, $1b, $62, $54, $4e, $1b, $4c, $5e, $49, $5e, $1b, $49, $52, $5c, $53, $4f, $1, $1b, $7a, $76, $74, $68, $1b, $52, $48, $1b, $77, $7a, $76, $74, $68, $1a, $1b, $7a, $68, $76, $1b, $49, $4e, $57, $5e, $41, $1a, $1b, $1b, $15, $54, $74, $54, $15, $1b, $1b, $7d, $72, $69, $7e, $78, $69, $7a, $78, $70, $7e, $69, $1, $1b, $73, $52, $17, $1b, $56, $5a, $55, $1a, $1b, $73, $54, $4b, $5e, $1b, $42, $54, $4e, $1c, $49, $5e, $1b, $55, $54, $4f, $1b, $59, $54, $49, $52, $55, $5c, $1b, $4f, $54, $1b, $5f, $5e, $5a, $4f, $53, $1b, $5a, $4f, $1b, $42, $54, $4e, $49, $1b, $59, $5a, $55, $50, $1a, $1b, $1b, $15, $54, $74, $54, $15, $3b EVEN textLamer: DC.B $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $1b, $62, $54, $4e, $1b, $5a, $49, $5e, $1b, $5a, $1b, $77, $7a, $76, $7e, $69, $1a, $3b EVEN textColumns: DC.L 0 textNbColumns: DC.L 0 textColumnsSize: DC.L 0 ordinates: DC.L 0 scrollColumn: DC.L 0 dmacon: DC.W 0 intena: DC.W 0 intreq: DC.W 0 textChecksum: DC.L TEXT_CHECKSUM angle: DC.W 0 copperlist: DC.L 0 font16: DC.L 0 bitplaneA: DC.L 0 bitplaneB: DC.L 0 bitplaneC: DC.L 0 sinus: DC.W 0, 286, 572, 857, 1143, 1428, 1713, 1997, 2280, 2563, 2845, 3126, 3406, 3686, 3964, 4240, 4516, 4790, 5063, 5334, 5604, 5872, 6138, 6402, 6664, 6924, 7182, 7438, 7692, 7943, 8192, 8438, 8682, 8923, 9162, 9397, 9630, 9860, 10087, 10311, 10531, 10749, 10963, 11174, 11381, 11585, 11786, 11982, 12176, 12365, 12551, 12733, 12911, 13085, 13255, 13421, 13583, 13741, 13894, 14044, 14189, 14330, 14466, 14598, 14726, 14849, 14968, 15082, 15191, 15296, 15396, 15491, 15582, 15668, 15749, 15826, 15897, 15964, 16026, 16083, 16135, 16182, 16225, 16262, 16294, 16322, 16344, 16362, 16374, 16382, 16384, 16382, 16374, 16362, 16344, 16322, 16294, 16262, 16225, 16182, 16135, 16083, 16026, 15964, 15897, 15826, 15749, 15668, 15582, 15491, 15396, 15296, 15191, 15082, 14968, 14849, 14726, 14598, 14466, 14330, 14189, 14044, 13894, 13741, 13583, 13421, 13255, 13085, 12911, 12733, 12551, 12365, 12176, 11982, 11786, 11585, 11381, 11174, 10963, 10749, 10531, 10311, 10087, 9860, 9630, 9397, 9162, 8923, 8682, 8438, 8192, 7943, 7692, 7438, 7182, 6924, 6664, 6402, 6138, 5872, 5604, 5334, 5063, 4790, 4516, 4240, 3964, 3686, 3406, 3126, 2845, 2563, 2280, 1997, 1713, 1428, 1143, 857, 572, 286, 0, -286, -572, -857, -1143, -1428, -1713, -1997, -2280, -2563, -2845, -3126, -3406, -3686, -3964, -4240, -4516, -4790, -5063, -5334, -5604, -5872, -6138, -6402, -6664, -6924, -7182, -7438, -7692, -7943, -8192, -8438, -8682, -8923, -9162, -9397, -9630, -9860, -10087, -10311, -10531, -10749, -10963, -11174, -11381, -11585, -11786, -11982, -12176, -12365, -12551, -12733, -12911, -13085, -13255, -13421, -13583, -13741, -13894, -14044, -14189, -14330, -14466, -14598, -14726, -14849, -14968, -15082, -15191, -15296, -15396, -15491, -15582, -15668, -15749, -15826, -15897, -15964, -16026, -16083, -16135, -16182, -16225, -16262, -16294, -16322, -16344, -16362, -16374, -16382, -16384, -16382, -16374, -16362, -16344, -16322, -16294, -16262, -16225, -16182, -16135, -16083, -16026, -15964, -15897, -15826, -15749, -15668, -15582, -15491, -15396, -15296, -15191, -15082, -14968, -14849, -14726, -14598, -14466, -14330, -14189, -14044, -13894, -13741, -13583, -13421, -13255, -13085, -12911, -12733, -12551, -12365, -12176, -11982, -11786, -11585, -11381, -11174, -10963, -10749, -10531, -10311, -10087, -9860, -9630, -9397, -9162, -8923, -8682, -8438, -8192, -7943, -7692, -7438, -7182, -6924, -6664, -6402, -6138, -5872, -5604, -5334, -5063, -4790, -4516, -4240, -3964, -3686, -3406, -3126, -2845, -2563, -2280, -1997, -1713, -1428, -1143, -857, -572, -286 cosinus: DC.W 16384, 16382, 16374, 16362, 16344, 16322, 16294, 16262, 16225, 16182, 16135, 16083, 16026, 15964, 15897, 15826, 15749, 15668, 15582, 15491, 15396, 15296, 15191, 15082, 14968, 14849, 14726, 14598, 14466, 14330, 14189, 14044, 13894, 13741, 13583, 13421, 13255, 13085, 12911, 12733, 12551, 12365, 12176, 11982, 11786, 11585, 11381, 11174, 10963, 10749, 10531, 10311, 10087, 9860, 9630, 9397, 9162, 8923, 8682, 8438, 8192, 7943, 7692, 7438, 7182, 6924, 6664, 6402, 6138, 5872, 5604, 5334, 5063, 4790, 4516, 4240, 3964, 3686, 3406, 3126, 2845, 2563, 2280, 1997, 1713, 1428, 1143, 857, 572, 286, 0, -286, -572, -857, -1143, -1428, -1713, -1997, -2280, -2563, -2845, -3126, -3406, -3686, -3964, -4240, -4516, -4790, -5063, -5334, -5604, -5872, -6138, -6402, -6664, -6924, -7182, -7438, -7692, -7943, -8192, -8438, -8682, -8923, -9162, -9397, -9630, -9860, -10087, -10311, -10531, -10749, -10963, -11174, -11381, -11585, -11786, -11982, -12176, -12365, -12551, -12733, -12911, -13085, -13255, -13421, -13583, -13741, -13894, -14044, -14189, -14330, -14466, -14598, -14726, -14849, -14968, -15082, -15191, -15296, -15396, -15491, -15582, -15668, -15749, -15826, -15897, -15964, -16026, -16083, -16135, -16182, -16225, -16262, -16294, -16322, -16344, -16362, -16374, -16382, -16384, -16382, -16374, -16362, -16344, -16322, -16294, -16262, -16225, -16182, -16135, -16083, -16026, -15964, -15897, -15826, -15749, -15668, -15582, -15491, -15396, -15296, -15191, -15082, -14968, -14849, -14726, -14598, -14466, -14330, -14189, -14044, -13894, -13741, -13583, -13421, -13255, -13085, -12911, -12733, -12551, -12365, -12176, -11982, -11786, -11585, -11381, -11174, -10963, -10749, -10531, -10311, -10087, -9860, -9630, -9397, -9162, -8923, -8682, -8438, -8192, -7943, -7692, -7438, -7182, -6924, -6664, -6402, -6138, -5872, -5604, -5334, -5063, -4790, -4516, -4240, -3964, -3686, -3406, -3126, -2845, -2563, -2280, -1997, -1713, -1428, -1143, -857, -572, -286, 0, 286, 572, 857, 1143, 1428, 1713, 1997, 2280, 2563, 2845, 3126, 3406, 3686, 3964, 4240, 4516, 4790, 5063, 5334, 5604, 5872, 6138, 6402, 6664, 6924, 7182, 7438, 7692, 7943, 8192, 8438, 8682, 8923, 9162, 9397, 9630, 9860, 10087, 10311, 10531, 10749, 10963, 11174, 11381, 11585, 11786, 11982, 12176, 12365, 12551, 12733, 12911, 13085, 13255, 13421, 13583, 13741, 13894, 14044, 14189, 14330, 14466, 14598, 14726, 14849, 14968, 15082, 15191, 15296, 15396, 15491, 15582, 15668, 15749, 15826, 15897, 15964, 16026, 16083, 16135, 16182, 16225, 16262, 16294, 16322, 16344, 16362, 16374, 16382 ;table des octants: y2-y1,x2-x1,Dx-Dy ;si <0 alors 0 si >=0 alors 1. Par exemple: ; y2-y1<0 donc 1 ; x2-x1<0 donc 1 ; Dx-Dy<0 donc 1 ;le code octant est donc le .b qui se trouve a l'adresse octant+111 octants: dc.b 4 ;000 y1Dy dc.b 0 ;001 y1x2 Dx>Dy dc.b 2 ;011 y1x2 Dxy2 x1Dy dc.b 1 ;101 y1>y2 x1y2 x1>x2 Dx>Dy dc.b 3 ;111 y1>y2 x1>x2 Dx