CPC Rulez
https://cpcrulez.fr/forum/

Question sur le Gate Array
https://cpcrulez.fr/forum/viewtopic.php?f=4&t=5586
Page 1 sur 2

Auteur :  majikeyric [ 06 Sep 2015, 18:01 ]
Sujet du message :  Question sur le Gate Array

Salut,

Je continue mon immersion dans le monde CPC/Z80,

J'ai fait une petite routine qui change les couleurs de la palette en adressant directement le Gate Array,
je voulais savoir qu'est-ce qui fait que les couleurs sont effectives pendant surement 1 balayage écran
et qu'ensuite elles repassent aux anciennes valeurs ?

Je pensais qu'il fallait désactiver une interruption (en $0038) mais apparemment ce n'est pas ça... (ou je m'y suis mal pris...).

Merci de votre aide :)

Auteur :  Megachur [ 06 Sep 2015, 19:16 ]
Sujet du message :  Re: Question sur le Gate Array

majikeyric a écrit :
Salut,

Je continue mon immersion dans le monde CPC/Z80,

J'ai fait une petite routine qui change les couleurs de la palette en adressant directement le Gate Array,
je voulais savoir qu'est-ce qui fait que les couleurs sont effectives pendant surement 1 balayage écran
et qu'ensuite elles repassent aux anciennes valeurs ?

Je pensais qu'il fallait désactiver une interruption (en $0038) mais apparemment ce n'est pas ça... (ou je m'y suis mal pris...).

Merci de votre aide :)


effectivement, le firmware restaure les couleurs à chaque vbl (à la première interruption si ma mémoire est bonne...)

normalement pour désactiver les interruptions il faut coder :

Code :
di
ld hl,(&0039) ; si on veut conserver l'ancienne addresse d'interruption sachant qu'il y a &c3 en &38 ce qui correspond à l'instruction jump &xxxx
ld (save_adr_int),hl ; on mets de côté sinon, ces deux lignes sont inutiles !
ld hl,&c9fb
ld (&0038),hl
ei

sachant que
&fb = ei
&c9 = ret
et c'est ce qui va se trouver en &0038

Auteur :  AsT [ 06 Sep 2015, 21:05 ]
Sujet du message :  Re: Question sur le Gate Array

@Megachur : si tu veux te synchroniser sur les halt, alors ton explication est la bonne sinon un simple DI résout le problème.

Code :
          Di ; Disable Interruption
          ld bc,#7F10 ; b=#7f (Gate Array port) c=Border (#10)
          ld a,#54      ; a=Colour black
          out (c),c      ; Select Border
          out (c),a      ; Select Ink
loop    Jr loop


Voilà pour ton problème.

Auteur :  majikeyric [ 07 Sep 2015, 07:35 ]
Sujet du message :  Re: Question sur le Gate Array

Effectivement avec un simple Disable Interrupt cela fonctionne :)

Dans un premier temps je n'arrivais pas à voir la différence car dans ma boucle principale j'appellais le vecteur : MC_WAIT_FLYBACK pour me synchroniser avec la VBL.
Apparemment cet appel doit re-lancer les interruptions car les couleurs étaient aussi ré-initialisée.

Pourquoi la solution de Megachur ne fonctionne pas ?
Il y a des interruptions qui ont un autre point d'entrée qu'en $0038 ?
Et si on passe en IM1 cela ne devrait pas être le cas ?

Auteur :  Overflow [ 07 Sep 2015, 08:29 ]
Sujet du message :  Re: Question sur le Gate Array

majikeyric a écrit :
Pourquoi la solution de Megachur ne fonctionne pas ?
Il y a des interruptions qui ont un autre point d'entrée qu'en $0038 ?
Et si on passe en IM1 cela ne devrait pas être le cas ?
C'est une super question.
Par défaut en IM1 oui le point d'entrée est en #38.
Ceci dit, tu continues à conserver et appeler les vecteurs systèmes;
ces vecteurs systèmes switchent la ROM basse (celle de #0000 à #3FFF,
c'est là que tu vas trouver la plupart des routines systèmes hors basic);
si jamais ton interruption arrive pendant que cette ROM basse est sélectionnée,
ce qu'on trouve en #38 c'est la ROM et pas ce que t'as modifié en RAM;
et donc il s'y trouve en #38 le JP habituel vers l'interruption standard du système.
:eng:
Pour faire simple, je suggère:
soit tu conserves le système sans le modifier (1),
soit tu supprimes complètement le système (2).
Explicitement:
(1) changer le mode et couleurs par CALL #BC0E #BC32, ton wait VSYNC par #BD19 etc
(2) oui sans système fais des OUT(7Fxx) pour changer le mode et la couleur, ré-écris #BD19 etc

Auteur :  majikeyric [ 07 Sep 2015, 10:51 ]
Sujet du message :  Re: Question sur le Gate Array

OK! je comprends le problème du switch du block 0, merci pour les infos Overflow :D

par contre, je ne comprends pas pourquoi ça ne fonctionne pas (en évitant d'appeler les vecteurs systèmes après) :

Code :
            di
            im 1
            ld hl,$c9fb
            ld ($0038),hl
            ei


Le traitement de toutes les interruptions arrivant devraient être schinté or mes couleurs sont quand même ré-initialisées.

Auteur :  AsT [ 07 Sep 2015, 12:33 ]
Sujet du message :  Re: Question sur le Gate Array

Di=disable interruption
Ei=enable interruption
.....
Quand tu remets le Ei, tu réautorises les interruptions d'où le problème.

Auteur :  Overflow [ 07 Sep 2015, 12:53 ]
Sujet du message :  Re: Question sur le Gate Array

majikeyric a écrit :
(...)en évitant d'appeler les vecteurs systèmes après (...) les interruptions arrivant devraient être schinté or mes couleurs sont quand même ré-initialisées.
Je tente: ok, tu n'appelles aucun vecteur système, donc quelquechose doit switcher la ROM basse. C'est par exemple le cas si tu reviens au basic (tentative avec la boule de cristal: tu LOADes en #6000, puis call #6000 avec RET final et "Ready" du Basic à la fin?). C'est sinon un test rigolo ( (c) Madram de visu en 2001) à faire direct sous basic: INK 0,1,3:SPEED INK 5,5 puis POKE &38,&C9 et çà clignote encore!? comprendre ça et le reste viendra tout seul.

Retour à ton code: y'a quoi ensuite? si c'est LOOP JR LOOP çà marchera; tu dois avoir autre chose derrière...

Pour avancer sinon, les breakpoints dans Winape (à défaut de watchpoints). On sait sur 6128 qu'en #38 c'est JP #B941. Place donc un BREAK en #B941 et zyeute comment ce fut appelé et l'état de la ROM basse, activée ou non.

Auteur :  majikeyric [ 07 Sep 2015, 13:19 ]
Sujet du message :  Re: Question sur le Gate Array

AsT a écrit :
Quand tu remets le Ei, tu réautorises les interruptions d'où le problème.


Non car toutes les interruptions arrivant en $0038 ne font qu'exécuter une EI et un RET et donc pas de re-init par le firmware des couleurs (enfin normalement).

Auteur :  majikeyric [ 07 Sep 2015, 13:32 ]
Sujet du message :  Re: Question sur le Gate Array

Overflow a écrit :
Retour à ton code: y'a quoi ensuite? si c'est LOOP JR LOOP çà marchera; tu dois avoir autre chose derrière...

y a uniquement de la manip de l'écran avec affichage d'un sprite et un 'JP .loop'
je mets le source:

Code :
                        org      $4000
start
                        ld      a,0
                        call   SCR_SET_MODE


                        di               ;; disable interrupts
                        im 1
                        ld hl,$c9fb         ;; install interrupt handler (EI:RET)
                        ld ($0038),hl      ;; (&0038 is IM1 interrupt vector)
                        ei               ;; enable interrupts
                        

                        ld      d,16
                        ld      hl,palette
                        ld      bc,$7f00
.loop0
                        out      (c),c         ; select color register
                        ld      a,(hl)
                        out      (c),a         ; write inkr color

                        inc      hl
                        inc      c            ; color register suivant
                        
                        dec      d
                        bne      .loop0

                        
.loop                     ld      a,(sprite_y)
                        ld      l,a
                        ld      h,0
                        add      hl,hl
                        ld      bc,offset_y_bitmap
                        add      hl,bc
                        ld      bc,(hl)
                        ld      hl,bc
                        
                        ld      a,(sprite_x)
                        srl      a
                        ld      c,a
                        ld      b,0
                        add      hl,bc            
                        ld      (._bitmap+1),hl         ; hl pointe sur le premier octet de la bitmap où blitter le sprite
                        
                        ld      a,(sprite_i)
                        ld      l,a
                        ld      h,0
                        add      hl,hl               ; ix2
                        
                        ld      de,hl               ; -> sauve hl
                        
                        ld      bc,spr_dimensions
                        add      hl,bc
                        ld      a,(hl)               ;largeur_en_octets
                        ld      (._largeur_en_octets+1),a
                        inc      hl
                        ld      a,(hl)               ;hauteur
                        ld      (._hauteur+1),a
                        
                        ld      hl,de               ; resto hl <-
                        
                        add      hl,hl               ; ix4
                        add      hl,hl               ; ix8
                        
                        ld      a,(sprite_x)
                        and      a,1
                        beq      .finsi05
                        ld      bc,4
                        add      hl,bc
                        ld      a,(._largeur_en_octets+1)
                        inc      a
                        ld      (._largeur_en_octets+1),a
.finsi05                  
                        ld      bc,spr_ptr
                        add      hl,bc
                        ld      a,(hl)
                        ld      (._sprite+1),a
                        inc      hl
                        ld      a,(hl)
                        ld      (._sprite+2),a
                        inc      hl
                        ld      a,(hl)
                        ld      (._mask+2),a
                        inc      hl
                        ld      a,(hl)
                        ld      (._mask+3),a

._sprite                  ld      hl,$ffff         ; sprite
._mask                     ld      ix,$ffff         ; mask - instruction avec ix sur 4 octets!
._bitmap                  ld      de,$ffff         ; background
                        
._hauteur                  ld      b,$ff            ; nb de lignes
.repeter05                  push   bc
                        push   de
                        
._largeur_en_octets            ld      b,$ff            ; nb octets par ligne = 8 pixels
.repeter10                  
                        ld      a,(de)
                        and      (ix)
                        or      (hl)
                        ld      (de),a                        
                        inc      de
                        inc      hl
                        inc      ix
                        djnz   .repeter10
                        
                        pop      de
                        
                        ld      a,d
                        add      a,$08
                        ld      d,a
                        bcc      .finsi10
                        
                        ld      a,e         ;4
                        add      a,$50      ;7
                        ld      e,a         ;4
                        ld      a,d         ;4
                        adc      a,$c0      ;7
                        ld      d,a         ;4
                        
.finsi10                  pop      bc
                        djnz      .repeter05

                        ld      a,(sprite_x)
                        cp      32
                        bne      .finsi13
                        ld      a,0
.finsi13                        
                        inc      a
                        ld      (sprite_x),a
                        
                        ld      a,(sprite_y)
                        cp      200-8
                        bne      .finsi15
                        ld      a,255
.finsi15                        
                        inc      a
                        ld      (sprite_y),a

                        jp      .loop

                        padorg $4100

nb_sprites_en_bank      =      1
spr_dimensions         =      $
spr_ptr               =      spr_dimensions         +   (nb_sprites_en_bank*2)

                        binary   "sprv.bin"
palette                     binary "sprv_inkr.pal"

sprite_x                  byte   0
sprite_y                  byte   0                        
sprite_i                  byte   0                        

offset_y_bitmap
y=0
                        dup 200
                        word ( $c000 + ((y%8)*$0800) + ((y/8)*80) )
y=y+1
                        edup


Overflow a écrit :
Pour avancer sinon, les breakpoints dans Winape (à défaut de watchpoints). On sait sur 6128 qu'en #38 c'est JP #B941. Place donc un BREAK en #B941 et zyeute comment ce fut appelé et l'état de la ROM basse, activée ou non.

Je vais y jeter un oeil!

Auteur :  majikeyric [ 07 Sep 2015, 13:41 ]
Sujet du message :  Re: Question sur le Gate Array

Alors j'ai trouvé quelque chose !

Ce code je l'exécute par l'intermédiaire d'un snapshot SNA que j'envoie dans WinAPE.

Si j'exécute le code à partir d'un DSK (RUN"..."), ça fonctionne comme il faut : la nouvelle palette reste bien.

Je pense que par défault mon SNA à la ROM basse d'activée non ? c'est un snapshot du prompt au démarrage de l'ordi dans lequel j'ajoute mon code pour l'exécuter.

le RUN doit faire quelque chose au niveau de la config mémoire aussi non ?

Auteur :  Overflow [ 07 Sep 2015, 14:12 ]
Sujet du message :  Re: Question sur le Gate Array

majikeyric a écrit :
mon SNA à la ROM basse d'activée non ?
A toi de le vérifier, comme un exercice d'utilisation de Winape, car Winape a ces informations et bien d'autres: rom/ram sélectionnées, palette, registres du crtc,...

majikeyric a écrit :
le RUN doit faire quelque chose au niveau de la config mémoire aussi non ?
Oui. Pour preuve: un programme binaire peut être chargé et démarrer disons en #1000, donc quand tu le RUNnes forcément on déselectionne toutes les ROMs (basse, haute) avant le JP vers l'entrée du programme en #1000 dans l'exemple.

Auteur :  TotO [ 07 Sep 2015, 14:14 ]
Sujet du message :  Re: Question sur le Gate Array

Si je m'abuse, lorsqu'on fait un RUN d'un fichier binaire le FW passe l'écran en bleu. (comme un BORDER 1:INK 0,1)
Pour contourner cela, il faut faire un loader BASIC.

Auteur :  AsT [ 07 Sep 2015, 14:20 ]
Sujet du message :  Re: Question sur le Gate Array

Si tu veux que ça fonctionne avec ton sna, ton changement de palette doit avoir lieu durant ta boucle (.loop). Voilà, sinon c'est normal que ca ne fonctionne pas dans ce cas la.
Si tu avais dans l'idée de faire des splitrasters, supprime bien le "ei"

Auteur :  majikeyric [ 07 Sep 2015, 15:27 ]
Sujet du message :  Re: Question sur le Gate Array

Mon SNA avait effectivement la rom basse activée :twisted:

J'en ai re-fait un propre full RAM pour pouvoir y injecter mon code et me trouver dans la même situation que si on faisait un RUN "code.bin"

Page 1 sur 2 Le fuseau horaire est UTC+1 heure
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/