;Codé par Denis Duplan pour Stash of Code (http://www.stashofcode.fr, stashofcode@gmail.com) en 2017. ;Ce(tte) oeuvre est mise à disposition selon les termes de la Licence (http://creativecommons.org/licenses/by-nc/4.0/) Creative Commons Attribution - Pas d’Utilisation Commerciale 4.0 International. ;Dans cette version : ; ;- A la moitié de la hauteur de l'écran, le Copper passe la couleur à rouge ($0F00) ;- Au dernier quart de la hauteur de l'écran, le Copper passe la couleur à noir ($0000) en déclenchant une interruption VERTB ;- Après la fin de la hauteur de l'écran, le hardware passe la couleur à bleu ($000F) en déclenchant une interruption VERTB ;- Au premier quart de la hauteur de l'écran, le CPU passe la couleur à vert ($00F0) en déclenchant une interruption VERTB ; ;Comme le gestionnaire d'interruption utilise un barillet (colors) pour modifier la couleur, la petite difficulté est de s'assurer qu'on active bien le Copper et la gestion des interruptions au bon moment pour que le scénario précédent soit déroulé correctement. Pour cela, il faut attendre la fin d'un VERTB et acquitter l'événement. ;---------- Directives ---------- SECTION yragael,CODE_C ;---------- Constantes ---------- ;Registres VPOSR=$004 INTENA=$09A INTENAR=$01C INTREQ=$09C INTREQR=$01E DMACON=$096 DMACONR=$002 COLOR00=$180 COP1LCH=$080 COPJMP1=$088 ;Programme DISPLAY_Y=$2C DISPLAY_DY=256 COPSIZE=4*4+4 ;---------- Initialisations ---------- ;Empiler les registres movem.l d0-d7/a0-a6,-(sp) ;StingRay's stuff lea graphicsLibrary,a1 movea.l $4,a6 jsr -408(a6) ;OpenLibrary () move.l d0,graphicsBase move.l graphicsBase,a6 move.l $22(a6),view movea.l #0,a1 jsr -222(a6) ;LoadView () jsr -270(a6) ;WaitTOF () jsr -270(a6) ;WaitTOF () jsr -228(a6) ;WaitBlit () jsr -456(a6) ;OwnBlitter () move.l graphicsBase,a1 movea.l $4,a6 jsr -414(a6) ;CloseLibrary () moveq #0,d0 ;Default VBR is $0 movea.l $4,a6 btst #0,296+1(a6) ;68010+? beq _is68000 lea _getVBR,a5 jsr -30(a6) ;SuperVisor () move.l d0,VBRPointer bra _is68000 _getVBR: movec vbr,d0 rte _is68000: ;Couper le système jsr -132(a6) ;Allouer de la mémoire en CHIP mise à 0 pour la Copper list move.l #COPSIZE,d0 move.l #$10002,d1 jsr -198(a6) move.l d0,copperlist ;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) ;Détourner les vecteurs d'interruption movea.l VBRPointer,a0 lea $64(a0),a0 lea vectors,a1 REPT 6 ;Les interruptions hardware génèrent des interruptions de niveau 1 à 6 correspondant aux vecteurs 25 à 30 pointant sur les adresses $64 à $78 move.l (a0),(a1)+ move.l #_rte,(a0)+ ENDR ;---------- Copper list ---------- move.l copperlist,a0 ;Attendre la moitié de la hauteur de l'écran move.w #((DISPLAY_Y+((2*DISPLAY_DY)>>2))<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ ;Passer la couleur à rouge ($0F00) move.w #COLOR00,(a0)+ move.w #$0F00,(a0)+ ;Attendre le dernier quart de la hauteur de l'écran move.w #((DISPLAY_Y+((3*DISPLAY_DY)>>2))<<8)!$0001,(a0)+ move.w #$FF00,(a0)+ ;Déclencher une interruption VERTB pour passer la couleur à noir ($0000) move.w #INTREQ,(a0)+ move.w #$8020,(a0)+ ;Fin move.l #$FFFFFFFE,(a0)+ ;---------- Programme principal ---------- ;Attendre la fin d'un VERTB pour être certain de l'ordre dans lequel les couleurs seront utilisées : VERTB par CPU, Copper, VERTB via Copper, VERTB par hardware _waitVERTB: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 bne _waitVERTB ;Acquitter le dernier événement VERTB pour éviter qu'il ne déclenche l'interruption niveau 3 du CPU move.w #$0020,INTREQ(a5) ;Activer l'interruption VERTB movea.l VBRPointer,a0 move.l #_VERTB,$6C(a0) move.w #$C020,INTENA(a5) ;INTEN=1, VERTB=1 ;Activer la Copper list move.l copperlist,COP1LCH(a5) clr.w COPJMP1(a5) move.w #$8280,DMACON(a5) ;DMAEN=1, COPEN=1 ;Boucle principale _loop: ;Attendre le premier quart de la hauteur de l'écran _wait0: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 cmpi.w #DISPLAY_Y+((1*DISPLAY_DY)>>2),d0 blt _wait0 ;Déclencher une interruption VERTB pour passer la couleur à vert ($00F0) move.w #$8020,INTREQ(a5) ;Attendre une ligne suivante _wait1: move.l VPOSR(a5),d0 lsr.l #8,d0 and.w #$01FF,d0 bne _wait1 ;Attendre la ligne 0 car le code prend moins de temps qu'il n'en faut au raster pour balayer les lignes DISPLAY_Y+DISPLAY_DY à 312 et donc reboucler sur la ligne 0 ;Tester la pression du bouton gauche de la souris btst #6,$BFE001 bne _loop ;---------- 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 vecteurs d'interruption movea.l VBRPointer,a0 lea $64(a0),a0 lea vectors,a1 REPT 6 move.l (a1)+,(a0)+ ENDR ;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) ;OpenLibrary () move.l d0,graphicsBase movea.l d0,a0 move.l 38(a0),COP1LCH(a5) clr.w COPJMP1(a5) ;StingRay's stuff movea.l view,a1 move.l graphicsBase,a6 jsr -222(a6) ;LoadView () jsr -462(a6) ;DisownBlitter () move.l graphicsBase,a1 movea.l $4,a6 jsr -414(a6) ;CloseLibrary () ;Rétablir le système jsr -138(a6) ;Libérer la mémoire movea.l copperlist,a1 move.l #COPSIZE,d0 jsr -210(a6) ;Dépiler les registres movem.l (sp)+,d0-d7/a0-a6 rts ;---------- Interruptions ---------- ;VERTB _VERTB: movem.l d0/a0,-(sp) ;Indispensable, mais à limiter aux registres modifiés ;Modifier la couleur 0 lea colors,a0 move.w (a0),COLOR00(a5) ;Cycler les couleurs move.w (a0),d0 move.w 2(a0),(a0)+ move.w 2(a0),(a0)+ move.w d0,(a0) ;Acquitter l'événement VERTB move.w #$0020,INTREQ(a5) movem.l (sp)+,d0/a0 ;Indispensable, mais à limiter aux registres modifiés rte ;Inhibition _rte: rte ;---------- Données ---------- graphicsLibrary: DC.B "graphics.library",0 EVEN graphicsBase: DC.L 0 view: DC.L 0 intena: DC.W 0 intreq: DC.W 0 dmacon: DC.W 0 VBRPointer: DC.L 0 vectors: BLK.L 6 copperlist: DC.L 0 colors: DC.W $00F0, $0000, $000F color: DC.w 3