1

Voilà, tout est dans le titre, y a des routines qui marchent bien et qui sont pas trop grosses ? J'ai un peu la flemme de me plonger dedans, donc si qqun a, tant mieux ^^

(c pour Formula0, qui avait une vieille routine pourrie de double-buffering qui marchait que sur HW1)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

2

Bah, je crois qu'en bidouillant les grays (juste le header) de TIGCC tu as facilement du triple buffering.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

3

J'oubliais : plans consécutifs obligatoires trigic

(de préférence aussi les buffers différents consécutifs, ce serait un peu chiant à changer, même si là ça n'aurait pas d'impact sur la performance)


S'il n'y a pas autre chose que les grays de TIGCC, je sens que ça va être pour moi l'occasion d'implémenter les plans consécutifs dans GTC en forkant les grays de TIGCC happy (en plus ça doit gagner pas mal de place sur la routine tongue)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

4

bah les plans sont consécutifs avec TIGCC. Par contre pour les buffers consécutifs, tu peux avoir que les deux backbuffers de consécutifs (sinon faudrait modifier la routine de grays en elle même)
Mais c quoi l'intérêt du triple buffering sur HW2 ?
Sur HW1 je pense que je vois (éviter les clignottements sans utiliser GrayWaitNSwitches(2), donc sans perte de vitesse), mais sur HW2 ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

5

GoldenCrystal
: bah les plans sont consécutifs avec TIGCC

Non, tu dois te tromper, qd Kevin est sur une position, il y reste happy A moins que ça soit différent en double buffering ? (mais j'ai des doutes)

Et la pénalité en performance si j'utilisais des plans non consécutifs serait assez impressionnante (probablement plus de 15% plus lent)
Par contre pour les buffers consécutifs, tu peux avoir que les deux backbuffers de consécutifs (sinon faudrait modifier la routine de grays en elle même)

Parce que l'allocation du backbuffer en double buffering se fait indépendamment de la routine de gray ? (j'ai jamais utilisé)
Mais c quoi l'intérêt du triple buffering sur HW2 ? Sur HW1 je pense que je vois (éviter les clignottements sans utiliser GrayWaitNSwitches(2), donc sans perte de vitesse), mais sur HW2 ?

Aucun, mais je préfère perdre 7ko de RAM plutôt que de me prendre la tête sur un double ou triple buffering selon le HW.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

6

Pollux
:
GoldenCrystal
: bah les plans sont consécutifs avec TIGCC

Non, tu dois te tromper, qd Kevin est sur une position, il y reste happy A moins que ça soit différent en double buffering ? (mais j'ai des doutes)
Bah il me semble que au moins sur HW2, les plans sont consécutifs... (HW1 c impossible puisqu'il utilise LCD_MEM pour un des deux plans)
Et la pénalité en performance si j'utilisais des plans non consécutifs serait assez impressionnante (probablement plus de 15% plus lent)
A ce point ? Y'a peut-être un grosse optimisation à faire pour mon mode7 dans ce cas cheeky
Par contre pour les buffers consécutifs, tu peux avoir que les deux backbuffers de consécutifs (sinon faudrait modifier la routine de grays en elle même)
Parce que l'allocation du backbuffer en double buffering se fait indépendamment de la routine de gray ? (j'ai jamais utilisé)
oui
Mais c quoi l'intérêt du triple buffering sur HW2 ? Sur HW1 je pense que je vois (éviter les clignottements sans utiliser GrayWaitNSwitches(2), donc sans perte de vitesse), mais sur HW2 ?
Aucun, mais je préfère perdre 7ko de RAM plutôt que de me prendre la tête sur un double ou triple buffering selon le HW.
Mwé c vrai...

Enfin, en bidouillant bien les gris de TIGCC, y'a moyen d'avoir tout ce dont tu as besoin sans trop te prendre la tête... Il te suffit juste de prendre le header et de l'accomoder selon ta volonté happy
Par exemple, redéfinir GrayOn pour qu'après l'initialisation standard, le(s) plan(s) alloué(s) soi(en)t libéré(s) et d'allouer tes 3 buffers d'un coup en modifiant les variables globales (tout cela en désactivant temporairement l'int 1 bien sûr)
Et le reste, ben c'est assez trivial je pense smile
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

7

GoldenCrystal
:
Pollux
:
GoldenCrystal
: bah les plans sont consécutifs avec TIGCC

Non, tu dois te tromper, qd Kevin est sur une position, il y reste happy A moins que ça soit différent en double buffering ? (mais j'ai des doutes)
Bah il me semble que au moins sur HW2, les plans sont consécutifs... (HW1 c impossible puisqu'il utilise LCD_MEM pour un des deux plans)

Oui, que sur HW2 -- d'ailleurs, c'est rigolo de voir à quel point le mieux (et encore, c discutable roll) est l'ennemi du bien : l'argument de Kevin est que ça pénaliserait les HW1 en leur faisant perdre 3k de RAM, et là tu proposes purement et simplement d'interdire les HW1 happy
Et la pénalité en performance si j'utilisais des plans non consécutifs serait assez impressionnante (probablement plus de 15% plus lent)
A ce point ? Y'a peut-être un grosse optimisation à faire pour mon mode7 dans ce cas cheeky

Bah, ça dépend du nb de registre que tu utilises. Tu tournes à combien de fps ? (et combien de cycles par pixel sans tout ce qui va autour ? -- setup de chaque ligne, des tiles...)
Par contre pour les buffers consécutifs, tu peux avoir que les deux backbuffers de consécutifs (sinon faudrait modifier la routine de grays en elle même)
Parce que l'allocation du backbuffer en double buffering se fait indépendamment de la routine de gray ? (j'ai jamais utilisé)
oui

oki... ça doit être bof niveau taille, ça ^^
Mais c quoi l'intérêt du triple buffering sur HW2 ? Sur HW1 je pense que je vois (éviter les clignottements sans utiliser GrayWaitNSwitches(2), donc sans perte de vitesse), mais sur HW2 ?
Aucun, mais je préfère perdre 7ko de RAM plutôt que de me prendre la tête sur un double ou triple buffering selon le HW.
Mwé c vrai...

Enfin, en bidouillant bien les gris de TIGCC, y'a moyen d'avoir tout ce dont tu as besoin sans trop te faire chier... Il te suffit juste de prendre le header et de l'accomoder selon ta volonté happy
Par exemple, redéfinir GrayOn pour qu'après l'initialisation standard, le(s) plan(s) alloué(s) soi(en)t libéré(s) et d'allouer tes 3 buffers d'un coup en modifiant les variables globales (tout cela en désactivant temporairement l'int 1 bien sûr)
Et le reste, ben c'est assez trivial je pense smile

Oué ben je crois que je suis bon pour une modification bourrine de GrayOn smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

8

(Attention, c'est un hack non supporté par la TIGCC Team) (et Kevin va gueuler dès qu'il va lire ce que j'ai proposé)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

9

bah, je suis ouvert à toute proposition, même celle de Kevin s'il en a de meilleures happy

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

10

Ca sert a quoi le triple buffering sur TI a part perdre de la RAM ?

11

désolé de ne rien y connaître en niveaux de gris, mais c'est quoi le triple buffering ?
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

12

Même question que Flanker.
Il me semble que ça permet d'accélérer pas mal les niveaux de gris.

Je crois que Jackosking avait fait une routine, sinon, Thibaut en a fait une (qu'il utilise pour GraphX).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

13

Vous connaissez le double buffering ?

14

non plus
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

15

Je laisse tomber alors.

16

double buffering = travailler sur 2 buffers d'ecran au lieu d'un, non ?
avatar
納 豆パワー!
I becamed a natto!!!1!one!

17

Moi je sais, ça consiste à utiliser deux buffers. On écrit dans l'un pendant que l'autre est affiché à l'écran, puis on inverse les rôles, ça permet de ne pas avoir de clignotements.
J'ai bon ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

18

Sauf si je suis complètement HS:

En double buffering, tu écris dans un buffer pendant que tu affiches le deuxième, et tu échanges les deux quand tu as fini de dessiner. Cependant, tu es obligé d'attendre que la frame affichée dans celui affiché justement ait été recopiée à l'écran par la routine de nvgavant de faire le changement pour éviter le scintillement. D'où un perte de temps, puisque tu ne peux pas commencer à traiter une nouvelle image tant que l'échange n'a pas été fait. Le triple buffering est la même chose mais avec trois buffers, et ça permet de ne pas perdre ce temps là.
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

19

C'est ce à quoi je pensais, mais la copie d'une image n'est pourtant pas longue, si ?
Ah oui, c'est vrai qu'il faut que la copie soit synchronisée avec le rafraichissement de l'écran pour pas avoir de scintillements non plus, donc elle peut prendre du temps.
OK.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

20

Font chier ces HW2 quand même sad
Ça aurait été plus simple avec le système des HW1, non ?
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

21

oui, pour les nvg, seulement ça bouffe une partie de la bande passante du bus car l'écran lit la ram en permanence
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

22

Sasume, Ximoon > merci pour les explications
avatar
<<< Kernel Extremis©®™ >>> et Inventeur de la différence administratif/judiciaire ! (©Yoshi Noir)

<Vertyos> un poil plus mais elle suce bien quand même la mienne ^^
<Sabrina`> tinkiete flan c juste qu'ils sont jaloux que je te trouve aussi appétissant

23

Sauf qu'il suffit de bien se debrouiller dans ton code et tu n'en as pas besoin.

24

la derniere version d'XLib gere le triple buffering avec plan consecutif que ce soit sur HW1,2 ou 3. Suffit de faire un simple hack de tigcc. De plus On avait externalisé la routine pour copier l'ecran (recopie 1/2 du lcd), de telle maniere qu'on pouvait aussi l'utiliser pour XCpyLPlanToGPlanL etc... enfin pour le gain en vitesse, c non negligeable.
Pollux, je pense sincerement que t'en a pour pas plus d'1/3h pour modifier la routine de tigcc.
A noter qu'on gagne aussi en taille du programme puisque la partie des movem.. qui prend pas mal est externalisé...

25

j'ai un vieux code affreux..
Provient du code TIGCC modifié par XTeam.. donc sous la licence de TIGCC... ] | [hide].data      .xdef XGrayOn,XGrayOff,__XD_plane,__XL_plane,__Xgray_handle,__Xgray_hw_type      .xdef __Xswitch_cnt,__Xgray_old_int1_hw1,__Xgray_old_int1_hw2      .xdef __Xgray_sync_n_count,__Xgray_plane_index      .xdef __Xgray_dbl_offset,__XL_plane2,__XD_plane2      .xdef XPatch .even   XPatch:      move.l __Xgray_used_mem,%a0      move.l %a0,__XL_plane      add    #0xf00,%a0      move.l %a0,__XD_plane      rts                         | Now HW1 & HW2 have the same GPlan.       XGrayOn:      movem.l  %d2-%d7/%a2-%a6,-(%a7)      lea      (__Xswitch_cnt,%pc),%a0       | reset plane switch counter to 0      move.l   #0,(%a0)      bsr.s    __Xgray_check_hw_version      | evaluate HW version and store it      lea      (__Xgray_hw_type,%pc),%a0      move.w   %d0,(%a0)      bsr      __Xgray_init_mem              | allocate and initialize memory      movem.l  (%a7)+,%d2-%d7/%a2-%a6      move.w   (__Xgray_handle,%pc),%d0      bne      __Xgray_init_handler          | jump to interrupt handler setup if                                            | memory was allocated correctly      moveq    #0x0,%d0                     | otherwise return 0 (GrayOn failed)      rts __Xgray_check_hw_version:                    | find the Hw version : return d0.w = 0 for HW1 .ifdef ALWAYS_HW2_TESTING      bra.s __Xalways_hw2_proceed .endif      move.l   0xc8,%d0      and.l    #0x600000,%d0          | get the ROM base      move.l   %d0,%a0      moveq    #0,%d0      move.l   260(%a0),%a1           | get pointer to the hardware param block      add.l    #0x10000,%a0      cmp.l    %a0,%a1                | check if the HW parameter block is near      bcc.s    __Xgray_patches_for_hw1 | if it is too far, it is HW1      cmp.w    #22,(%a1)              | check if the parameter block contains HW      bls.s    __Xgray_patches_for_hw1 | if it is too small, it is HW1      cmp.l    #1,22(%a1)             | check the hardware version      beq.s    __Xgray_patches_for_hw1 | if not 1, it is HW2 (or an unknown HW)     |--------------------------------------------------------------------------     | check for VTI (trick suggested by Julien Muchembled)     |--------------------------------------------------------------------------      trap     #12         | enter supervisor mode. returns old (%sr) in %d0.w      move.w   #0x3000,%sr | set a non-existing flag in %sr (but keep s-flag)      swap     %d0         | save %d0.w content in upper part of %d0      move.w   %sr,%d0     | get %sr content and check for non-existing flag      btst     #12,%d0     | this non-existing flag can only be set on the VTI      beq.s    __Xgray_hw2type_detected  | flag not set -> no VTI     |--------------------------------------------------------------------------     | HW1 detected     |--------------------------------------------------------------------------      swap     %d0          | restore old %sr content and return 0      move.w   %d0,%sr      moveq    #0,%d0     |--------------------------------------------------------------------------     | patches code for HW1 version     |     | necessary memory == 2 plane + 8 Bytes == 7688     |     | the additionally 8 bytes are necessary for rounding later to a multiple     | of 8     |-------------------------------------------------------------------------- __Xgray_patches_for_hw1:      lea (__Xgray_size_to_allocate,%pc),%a0      move.w #0x1e08,(%a0)      move.w #0xf00,(__Xgray_size_to_add-__Xgray_size_to_allocate,%a0)      rts     |--------------------------------------------------------------------------     | HW2 detected     |-------------------------------------------------------------------------- __Xgray_hw2type_detected:      swap     %d0         | restore old %sr content and set return to 1      move.w   %d0,%sr .ifdef ALWAYS_HW2_TESTING __Xalways_hw2_proceed: .endif      moveq    #1,%d0     |--------------------------------------------------------------------------     | patches code for HW2 version     |     | necessary memory == 2 planes + 8 Bytes == 7688     |     | the additionally 8 bytes are necessary for rounding later to a multiple     | of 8     |--------------------------------------------------------------------------      lea      (__Xgray_size_to_allocate,%pc),%a0      move.w   #0x1e08,(%a0)      move.w   #0xf00,(__Xgray_size_to_add - __Xgray_size_to_allocate,%a0)      rts __Xgray_hw_type:    | stores HW type (0==HW1 or VTI  1==HW2)      .word 0 |============================================================================== | Interrupt 1 handler for HW1 |============================================================================== __Xgray_int1_handler_hw1:      movem.l  %d0/%a0,-(%a7)     |--------------------------------------------------------------------------     | Load skip counter and increment it (count = (count+1)&0x3). Skip any     | further operation if count is 1, 2 or 3. This means that every 4th call     | of the INT1 handler is a candidate for a plane switch     |--------------------------------------------------------------------------      lea      (__Xgray_skipcount,%pc),%a0      addq.b   #1,(%a0)      andi.b   #0x3,(%a0)+            | IMPORTANT: a0 points now to __Xgray_phase!      bne.s    __Xgray_proceed_old     |--------------------------------------------------------------------------     | to evaluate which plane we use counter __Xgray_phase. This counter     | performs the following counting 8->4->0->8.     | 0 will use D_plane pointer     | 4 will use L_plane pointer     | (8 will be skipped, so it stays at D_plane)     |--------------------------------------------------------------------------      move.w   (%a0),%d0      subq.w   #4,%d0                  | subtract 4 from phase counter      bcc.s    __Xgray_store            | not negative -> don't reset      moveq    #0x8,%d0                | reset phase counter to 8 __Xgray_store:      move.w   %d0,(%a0)               | store new phase counter value      cmp.b    #8,%d0      beq.s    __Xgray_proceed_old      | for value 8 we do nothing (dark plane                                       | stays active)      lea (__XD_plane,%pc),%a0     |--------------------------------------------------------------------------     | doublebuffer extension ... add content of __Xgray_dbl_offset to %d0     |--------------------------------------------------------------------------      add.w  (__Xgray_dbl_offset-__XD_plane,%a0),%d0      suba.w %d0,%a0      move.l   (%a0),%d0               | load the address of this plane      lsr.l    #3,%d0                  | reduce to address / 8      move.w   %d0,0x600010            | set new plane startaddress      lea      (__Xswitch_cnt,%pc),%a0  | increment switch count      addq.l   #1,(%a0) __Xgray_proceed_old:      movem.l  (%a7)+,%d0/%a0     |--------------------------------------------------------------------------     |  JUMP to previous installed interrupt handler     |--------------------------------------------------------------------------      .word    0x4ef9                  | "JMP address" opcode __Xgray_old_int1_hw1:      .long    0x00000000              | address of old int1 gots stored here __Xgray_dummy1:                           | NOT used yet (just for alignment)      .byte    0x00 |------------------------------------------------------------------------------ | __Xgray_skipcount is a one byte counter which performs the following counting: | 3 -> 0 -> 1 -> 2 -> 3 |------------------------------------------------------------------------------ __Xgray_skipcount:      .byte    0x03 __Xgray_phase:      .word    0x04                    | performs: 4->0->8->4 __Xswitch_cnt:      .long    0x00000000 |============================================================================== | INTERNAL: allocates memory | | modifies: __Xgray_handle |           __Xgray_used_mem |           __XL_plane | | Note: __XD_plane will not be changed by this function! (will be set by |                                                        __Xgray_init_handler) |============================================================================== __Xgray_init_mem:      lea      (__Xgray_handle,%pc),%a5            | if __Xgray_handle is not 0      tst.w    (%a5)                              | we have already allocated      bne.s    __Xgray_init_return                 | memory -> out here     |--------------------------------------------------------------------------     | HeapAllocHigh(HW1=3848 bytes or HW2=7688 bytes)     |--------------------------------------------------------------------------      movea.l  0xc8,%a0      lea      (0x248,%a0),%a0      .word    0x4878                       | opcode of "PEA #value" __Xgray_size_to_allocate:                      | the size gets patched !!      .word    0x1e08      movea.l  (%a0),%a2      jsr      (%a2)      addq.w   #4,%a7      move.w   %d0,(%a5)+                   | store handle in handle variable      beq.s    __Xgray_init_return           | alloc failed (handle=0) -> out here      clr.w    (%a5)                        | clears __Xgray_dbl_offset     |--------------------------------------------------------------------------     | HeapDeref(__Xgray_handle)     |--------------------------------------------------------------------------      move.w   %d0,-(%a7)      movea.l  0xc8,%a0      lea      (0x258,%a0),%a0      movea.l  (%a0),%a2      jsr      (%a2)      addq.l   #2,%a7     |--------------------------------------------------------------------------     | align memory address to next 8-byte boundary and store address in     | __Xgray_used_mem     |     | for HW1: __XL_plane gets set to the same address as __Xgray_used_mem     | for HW2: __XL_plane gets set to __Xgray_used_mem + 0xf00     |--------------------------------------------------------------------------      move.l   %a0,%d0      addq.l   #7,%d0      andi.b   #0xF8,%d0      lea      (__Xgray_used_mem,%pc),%a0      move.l   %d0,(%a0)      .word    0x0680              | opcode of "ADDI.L #value,%a0"      .word    0x0000 __Xgray_size_to_add:      .word    0x0F00              | gets patched (HW1:0 HW2:0x0f00)      move.l   %d0,(__XL_plane - __Xgray_used_mem,%a0) __Xgray_init_return:      rts |------------------------------------------------------------------------------ | handle to allocated memory used by grayscale |------------------------------------------------------------------------------ __Xgray_handle:      .word    0 |------------------------------------------------------------------------------ | DOUBLEBUFFER extension |------------------------------------------------------------------------------ __Xgray_dbl_offset: | has to be directly AFTER __Xgray_handle!!      .word    0 __XL_plane2:      .long    0x0 __XD_plane2:      .long    0x0 |------------------------------------------------------------------------------ | pointer to light plane | HW1: same as __Xgray_used_mem | HW2: __Xgray_used_mem + 0xf00 |------------------------------------------------------------------------------ __XL_plane:      .long    0x00004c00 |------------------------------------------------------------------------------ | pointer to dark plane (set by __Xgray_init_handler) | HW1: 0x4c00 | HW2: same as __Xgray_used_mem |------------------------------------------------------------------------------ __XD_plane:      .long    0x00004c00 |------------------------------------------------------------------------------ | pointer to allocated memory ALIGNED to 8-byte boundary |------------------------------------------------------------------------------ __Xgray_used_mem:      .long    0x00004c00 |------------------------------------------------------------------------------ | This variable is very hard to describe. Indeed this isn't one variable, | but two variables combined in one. | | Description will be added later .... |------------------------------------------------------------------------------ __Xgray_sync_n_count:      .word    0x0000 |------------------------------------------------------------------------------ | holds the index of the plane which should be drawn next (NOTE: this label | is never addressed directly, but indirectly from label __Xgray_sync_n_count. | So don't move it do somewhere else!) |------------------------------------------------------------------------------ __Xgray_plane_index:      .word    0x0000 |============================================================================== | Interrupt 1 handler for HW2 | | port 70001D (bit 7) is used to synchronized to the LCD hardware. Here are the | docs of this port (taken from Johan Eilert's j89hw.txt) | | $70001D RW ($06) |     :7      Toggles every FS (every time the LCD restarts at line 0) |     :6-4     - |     :3      Battery checker bit B (? ???) |     :2      ? (set) |     :1      Screen enable (clear this bit to shut down LCD) |     :0      Battery checker bit A (? enable $600000:2) |          (AMS:) The battery checker bits must both be set (AB=11) prior to |          checking the voltage level with $600000:2.  Then, after use, bit B |          must be cleared (AB=10) while the battery trig hardware settles to |          the "rest" voltage value (%111).  Finally, both bits should be |          cleared. |============================================================================== __Xgray_int1_handler_hw2:      move.w   %sr,-(%a7)                | save content of status register on stack      move.w   #0x2700,%sr               | disable ALL interrupts (no one should                                         | interrupt us ...)      movem.l  %d0-%d7/%a0-%a6,-(%a7) __Xgray_startagain:      moveq    #0x0,%d1      lea      (__Xgray_sync_n_count,%pc),%a0      move.w   (%a0),%d0      bne.s    __Xgray_copy_first_or_sec  | there is a third of the plane left to                                         | copy -> do it now!      move.l   (%a0),%d0 .ifdef ALWAYS_HW2_TESTING      move.b   %d0,%d1      eor.b    #0x80,%d1 .else      move.b   0x70001D,%d1              | get flipping bit      eor.b    %d0,%d1      bpl      __Xgray_to_oldint          | not flipped yet -> proceed to previous                                         | installed int handler .endif      eor.l    %d1,(%a0)                 | store new flip "bit" and reset the                                         | work left status     |--------------------------------------------------------------------------     | NOTE: if we detect a pageflip we start our copying work with the lowest     |       third. this way it will not interfere with the LCD hardware refresh     |     | The 3 thirds are copied in the following order:     |     | last third -> first third -> second third     |--------------------------------------------------------------------------      move.w   #0xA00,%d0 __Xgray_copy_next_third:      addq.w   #1,(%a0)+      bra.s    __Xgray_perform_copying __Xgray_copy_first_or_sec:     |--------------------------------------------------------------------------     | if __Xgray_sync_n_count == 1 -> copy first third of screen     | otherwise -> set __Xgray_sync_n_count to 0 and copy second third of screen     |--------------------------------------------------------------------------      subq.w   #1,%d0      beq.s    __Xgray_copy_next_third      clr.w    (%a0)+      move.w   #0x500,%d0             | setup to copy second third of screen __Xgray_perform_copying:      move.b   (%a0),%d1              | fetch index of plane to draw next      beq      __Xgray_update_index    | skip index 0 -> stay at darkplane     |--------------------------------------------------------------------------     | If we'll come here we will copy 1 third of the screen from a specific     | plane to the video buffer at 0x4c00. Register D0 holds the offset of     | which third should be copied and register D1 contains the "index" of the     | "source" plane     |     | index = 0 -> darkplane (skipped, will not come here!)     | index = 4 -> darkplane     | index = 8 -> lightplane     |     | Due to the fact that the indices are cycled from 8 down to 0 the skipped     | index 0 causes the darkplane to stay active twice as long as the light     | plane.     |     | The copying is performed in a kind of "hardcore" style by using 13     | registers. This way 52 Bytes are copied with a single instruction.     |--------------------------------------------------------------------------     |--------------------------------------------------------------------------     | doublebuffer extension ... add content of __Xgray_dbl_offset to %d0     |--------------------------------------------------------------------------      add.w    (__Xgray_dbl_offset,%pc),%d1      neg.w    %d1      movea.l  (__Xgray_used_mem,%pc,%d1.w),%a0      lea      0x4C00,%a1      adda.w   %d0,%a0      adda.w   %d0,%a1            jsr     XCpyPlan     |--------------------------------------------------------------------------     | evaluate if there is still a third of the screen to copy or if we     | should proceed to the next plane     |-------------------------------------------------------------------------- __Xgray_update_index:      lea      (__Xgray_sync_n_count,%pc),%a0      move.w   (%a0)+,%d0      beq      __Xgray_startagain          | no third left to copy -> check again                                          | the pageflip bit if yet a pageflip                                          | had occured      subq.w   #1,%d0      bne.s    __Xgray_to_oldint           | if there is "copy work" left ->                                          | don't modify the plane to display      lea      (__Xswitch_cnt,%pc),%a1     | increment switch count here, because      addq.l   #1,(%a1)                   | a complete page was drawn if we come here      subq.b   #4,(%a0)                   | cycle __Xgray_plane_index by decrementing      bcc.s    __Xgray_to_oldint           | it and wrap around to 8 if negative.      move.b   #0x8,(%a0) __Xgray_to_oldint:      movem.l  (%a7)+,%d0-%d7/%a0-%a6      move.w   (%a7)+,%sr                 | restore content of status register     |--------------------------------------------------------------------------     |  JUMP to previous installed interrupt handler     |--------------------------------------------------------------------------      .word    0x4ef9                     | opcode of "JMP address" instruction __Xgray_old_int1_hw2:      .long    0x00000000 |============================================================================== | INTERNAL: initialize grayscale handler |============================================================================== __Xgray_init_handler:      lea      (__XL_plane,%pc),%a0      move.w   #0x3BF,%d1      move.w   (__Xgray_hw_type,%pc),%d0      tst.w    %d0      beq.s    __Xgray_init_hw1_handler     |--------------------------------------------------------------------------     | HW2 specific initializations:     |     | (1) set __XD_plane to __Xgray_used_mem     | (2) copy content of 0x4c00 to darkplane     | (3) "backup" old INT1 handler in __Xgray_old_int1_hw2 (the address part     |     of a JUMP address instruction at the end of the HW2 int handler)     | (4) install our own INT1 HW2 handler     |--------------------------------------------------------------------------      movea.l  (__Xgray_used_mem,%pc),%a1      move.l   %a1,(0x4,%a0)               | set __XD_plane      movea.w  #0x4C00,%a0      move.w   %d1,%d0 __Xgray_cpy_d_plane:      move.l   (%a0)+,(%a1)+      dbf      %d0, __Xgray_cpy_d_plane      lea      (__Xgray_int1_handler_hw2,%pc),%a0     | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!     | the following command should be unnecessary; I commented it out (TOM)     | (__XL_plane should be already set by __Xgray_init_mem)     | !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      |move.l   %a1,(__XL_plane - __Xgray_int1_handler_hw2,%a0)      move.l   0x64,(__Xgray_old_int1_hw2 - __Xgray_int1_handler_hw2,%a0)      bra.s    __Xgray_init_proceed     |--------------------------------------------------------------------------     | HW1 specific initializations:     |     | (1) "backup" old INT1 handler in __Xgray_old_int1_hw1 (the address part     |     of a JUMP address instruction at the end of the HW1 int handler)     | (2) install our own INT1 HW1 handler     |-------------------------------------------------------------------------- __Xgray_init_hw1_handler:      move.l   (%a0),%a1      lea      (__Xgray_int1_handler_hw1,%pc),%a0      move.l   0x64,(__Xgray_old_int1_hw1 - __Xgray_int1_handler_hw1,%a0) __Xgray_init_proceed:      move.l   %a0,0x40064 __Xgray_clr_l_plane:     |--------------------------------------------------------------------------     | clear light plane (done for both HW types)     |--------------------------------------------------------------------------      clr.l    (%a1)+      dbf      %d1, __Xgray_clr_l_plane     |--------------------------------------------------------------------------     | PortSet(__XD_plane,239,127)     |--------------------------------------------------------------------------      move.l   #0xEF007F,-(%a7)      move.l   (__XD_plane,%pc),-(%a7)      movea.l  0xC8,%a0      lea      (0x688,%a0),%a0      movea.l  (%a0),%a1      jsr      (%a1)      addq.w   #8,%a7 __Xgray_ok:      lea (__XL_plane,%pc),%a0      lea (__XL_plane2,%pc),%a1      move.l (%a0)+,(%a1)+        | copy __XL_plane to __XL_plane2      move.l (%a0)+,(%a1)+        | copy __XD_plane to __XD_plane2      moveq    #0x1,%d0      rts |============================================================================== |  EXPORTED: GrayOff function (turn grayscales off) |            NOTE: ALWAYS returns 1 !! |============================================================================== XGrayOff:      movem.l  %a2-%a3,-(%a7)      lea      (__Xgray_handle,%pc),%a3      tst.w    (%a3)      beq      __Xgray_off_out                   | no handle? -> nothing to do      move.w   (__Xgray_hw_type,%pc),%d0      tst.w    %d0      beq.s    __Xgray_hw1_cleanup     |--------------------------------------------------------------------------     | cleanup for HW2 calcs     |--------------------------------------------------------------------------      move.l   (__Xgray_old_int1_hw2,%pc),0x40064   | restore old INT1 handler      movea.l  (__XD_plane,%pc),%a1      movea.w  #0x4C00,%a0      move.w   #0x3BF,%d0                   | copy content of darkplane to 0x4c00 __Xgray_dark2lcd:      move.l   (%a1)+,(%a0)+      dbf      %d0, __Xgray_dark2lcd      bra.s    __Xgray_continue_cleanup     |--------------------------------------------------------------------------     | cleanup for HW1 calcs (on HW1 0x4c00 is used as darkplane. We haven't to     | set it)     |-------------------------------------------------------------------------- __Xgray_hw1_cleanup:      move.w   #0x980,0x600010                    | restore used plane to 0x4c00      move.l   (__Xgray_old_int1_hw1,%pc),0x40064  | restore old INT1 handler __Xgray_continue_cleanup:      lea      (__XL_plane,%pc),%a0  | restore plane pointers to 0x4c00 for sure      move.l   #0x04c00,(%a0)+      move.l   #0x04c00,(%a0)+      move.l   #0x04c00,(%a0)     |--------------------------------------------------------------------------     | HeapFree(__Xgray_handle)     |--------------------------------------------------------------------------      movea.l  0xc8,%a0      lea      (0x25c,%a0),%a0      move.w   (%a3),-(%a7)      move.l   (%a0),%a2      jsr      (%a2)      addq.l   #2,%a7     |--------------------------------------------------------------------------     | PortRestore()     |--------------------------------------------------------------------------      movea.l  0xc8,%a0      lea      (0x68c,%a0),%a0      move.l   (%a0),%a2      jsr      (%a2)      clr.l    (%a3)                     | 0->handle AND(!!) 0->__Xgray_dbl_offset      lea      (__Xgray_sync_n_count,%pc),%a0      clr.l    (%a0) __Xgray_off_out:      movem.l  (%a7)+,%a2-%a3      jbra     __Xgray_ok | ############################################################################# |  Revision History | ############################################################################# | | $Log: gray.s,v $ | Revision 3.10 2002/04/05 11:34:23  tnussb | (1) Resets now __XD_plane2,__XL_plane2 and __Xgray_dbl_offset at end of GrayOn() |     to make sure nothing happens if doublebuffer macros get called without |     setting a buffer first. Nevertheless NO program should call one of the |     doublebuffer macros without setting a buffer previously. | (2) Some further size optimizations. Now the size is exactly as long as |     without before the integration of doublebuffering. Quite smart, isn't it? |     More functionality, some minor drawbacks fixed and no increase in size ... | (3) Changed return value of GrayOff() function to void. | | Revision 3.9  2002/04/04 18:50:36  tnussb | first working version of internal doublebuffer support (not checked on | real calcs yet, but on the VTI) | | Revision 3.8  2002/04/04 16:39:05  tnussb | Debug version checked in previously. This one is the correct one. | | Revision 3.7  2002/04/04 16:35:20  tnussb | (1) documentation of HW2 interrupt handler heavily extended | (2) HW2: plane switch counting fixed (was incremented too often previously) | (3) global ALWAYS_HW2_TESTING added which can be used to force the use of |     HW2 grayscales. Now the HW2 grayscales can be tested on the VTI if |     this global is defined. Of course this will flicker extremely, because |     the VTI doesn't simulate port 70001D, but its still better than no |     testing possibility. | (4) don't trashes %sr on HW2 anymore (restores previous setting) | (5) This version was tested on a real HW1 and a real HW2 calc. It works. |     (Thanx to Sebastian Reichelt and stoopid guy) | | Revision 3.6  2002/04/04 11:58:19  tnussb | (1) size optimizations | (2) unnecessary cleanup removed from GrayOff() | (3) interrupt handler for HW1 rewritten (uses now plane pointer directly) | (4) "heavily" documented | | Revision 3.5  2002/04/04 11:54:39  tnussb | (1) exports __Xgray_old_int1_hw1 and __Xgray_old_int1_hw2. this way it is |     possible to modify them after grayscales are turned on | (2) comments changed to GNU Assembler style | [NOTE: CVS time and date doesn't fit to real implementation data] | | Revision 3.0  2002/04/04 11:50:56  tnussb | grayscale support used for TIGCC up to version v0.93 | [NOTE: CVS time and date doesn't fit to real implementation data
| Assembly Source File | Created 13/08/2003; 02:48:36 .data      .xdef XCpyPlan .even | Externalisation de la routine de gray | source: a0 | destination: a1 | detruit: a0 - a6 |          d0 - d7 :p virtual_pc:      dc.l     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0       XCpyPlan:      movem.l      %d0-%d7/%a2-%a6,-(%a7)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x34,%a1)  | size of this instruction: 6 bytes      movem.l  (%a0)+,%d0-%d7/%a2-%a6      | size of this instruction: 4 bytes      movem.l  %d0-%d7/%a2-%a6,(0x68,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x9C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0xD0,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x104,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x138,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x16C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x1A0,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x1D4,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x208,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x23C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x270,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x2A4,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x2D8,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x30C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x340,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x374,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x3A8,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x3DC,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x410,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x444,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x478,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x4AC,%a1)      movem.l  (%a0)+,%d0-%d7      movem.l  %d0-%d7,(0x4E0,%a1)      movem.l      (%a7)+,%d0-%d7/%a2-%a6      rts      [/hide]

26

Sasume> euh non, au contraire, c les HW1 qui posent pb... sur HW2, au moment où tu viens d'échanger les plans, la copie du plan actuel a déjà été entièrement lue (l'interruption ne se fait pas en parallèle de l'exécution du prog) et le plan suivant sera le plan que tu veux afficher. Alors que sur HW1, quand tu viens d'échanger les plans, l'écran est toujours en train d'afficher le vieux buffer, donc au moment où tu le modifies, ça clignote... En gros sans triple buffering sur HW1 tu dois attendre 1 frame ou 2 suivant que l'écran en cours d'affichage est celui de poids fort ou de poids faible.

PpHd> ouéé, tu veux bien optimiser mon code pour gagner 50000 cycles par frame ? c'est gentil bisoo (ou alors il faudra que tu m'expliques ce que c'est que "mal se débrouiller")

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

27

bon bug de yaronet?

28

 (%a7)+,%d0-%d7/%a2-%a6      rts      [hide]pas plus d'une source par post... | Assembly Source File | Created 13/08/2003; 02:48:36 .data      .xdef XCpyPlan .even | Externalisation de la routine de gray | source: a0 | destination: a1 | detruit: a0 - a6 |          d0 - d7 :p virtual_pc:      dc.l     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0       XCpyPlan:      movem.l      %d0-%d7/%a2-%a6,-(%a7)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x34,%a1)  | size of this instruction: 6 bytes      movem.l  (%a0)+,%d0-%d7/%a2-%a6      | size of this instruction: 4 bytes      movem.l  %d0-%d7/%a2-%a6,(0x68,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x9C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0xD0,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x104,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x138,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x16C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x1A0,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x1D4,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x208,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x23C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x270,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x2A4,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x2D8,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x30C,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x340,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x374,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x3A8,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x3DC,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x410,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x444,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x478,%a1)      movem.l  (%a0)+,%d0-%d7/%a2-%a6      movem.l  %d0-%d7/%a2-%a6,(0x4AC,%a1)      movem.l  (%a0)+,%d0-%d7      movem.l  %d0-%d7,(0x4E0,%a1)      movem.l     [/hide]

Bon je crois que je vais modifier la routine de TIGCCLib, thx...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

29

j'ai beau chercher je n'ai rien d'interressant à poster, là tout de suite. Mais bon, c'est pour les hides.

30

bon apres ca fonctionne assez facillement..
code affreux 3: void XGSwap() {      if ( __Xgray_hw_type )     // HW2      {           if (XGrayDBufGetActiveIdx())           {                XGrayDBufSetActiveIdx(0);                _X_CGPlan = __XL_plane2;           }           else           {                XGrayDBufSetActiveIdx(1);                _X_CGPlan = __XL_plane;           }           }      else      {                                                  // HW1 & VTI           if (XGrayDBufGetActiveIdx())           {                XGrayDBufSetActiveIdxSync(0);                _X_CGPlan = __XL_plane2;           }           else           {                XGrayDBufSetActiveIdxSync(1);                _X_CGPlan = __XL_plane;           }      } }