Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| tutoriaux:vga-avance-dac-part-3 [2021/05/02 23:16] – frater | back2root:tutoriaux:vga-avance-dac-part-3 [2024/08/08 10:54] (Version actuelle) – [Le Code] frater | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | ======  | + | ====== VGA Avancée - DAC - Part 3 ====== | 
| ===== CopperList avancée ===== | ===== CopperList avancée ===== | ||
| Ligne 14: | Ligne 14: | ||
| === Wait: 0x10 === | === Wait: 0x10 === | ||
| - | |||
| Aucune modification n'est apportée a cette instruction. | Aucune modification n'est apportée a cette instruction. | ||
| Ligne 26: | Ligne 25: | ||
| Cette instruction prends les valeurs du dernier " | Cette instruction prends les valeurs du dernier " | ||
| - | Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 | + | ^   | 
| - | 0x30 LineH LineL Red Green Blue | + | |   | 
| - | Les bytes " | + | Les bytes " | 
| === EOC: 0xFF === | === EOC: 0xFF === | ||
| Ligne 40: | Ligne 39: | ||
| #include " | #include " | ||
| #include " | #include " | ||
| - | + | ||
| typedef unsigned char BYTE; | typedef unsigned char BYTE; | ||
| typedef unsigned int WORD; | typedef unsigned int WORD; | ||
| - | + | ||
| // copper_maxrow is a parameter to avoid copper/ | // copper_maxrow is a parameter to avoid copper/ | ||
| // copper_error must be set to 0 to run | // copper_error must be set to 0 to run | ||
| - | + | ||
| int    copper_maxrow  | int    copper_maxrow  | ||
| BYTE    | BYTE    | ||
| - | + | ||
| #define PRECIS  | #define PRECIS  | ||
| - | + | ||
| BYTE copperlistv2[] = | BYTE copperlistv2[] = | ||
| { | { | ||
| Ligne 60: | Ligne 59: | ||
|     0x30, 0x00, 0xC8, 0xFF, 0xFF, 0x00,         // GradiantTo 0x32 0xFF, |     0x30, 0x00, 0xC8, 0xFF, 0xFF, 0x00,         // GradiantTo 0x32 0xFF, | ||
|     0x30, 0x00, 0xFA, 0xFF, 0x00, 0x00,         // GradiantTo 0x64 0x09, |     0x30, 0x00, 0xFA, 0xFF, 0x00, 0x00,         // GradiantTo 0x64 0x09, | ||
| - |     0x30, 0x01, 0x2C, 0x00, 0x00, 0x00,         // GradiantTo 0x96 0x00, | + |     0x30, 0x01, 0x2C, 0x00, 0x00, 0x00,         // GradiantTo 0x96 0x00, | 
| 0xFF // EOC | 0xFF // EOC | ||
| - |      | + | |
| }; | }; | ||
| - | + | ||
| void DrawCopperListv2(char *copperlist) | void DrawCopperListv2(char *copperlist) | ||
| { | { | ||
| Ligne 73: | Ligne 72: | ||
|   WORD  line_end=0, line_start=0;  |   WORD  line_end=0, line_start=0;  | ||
|   WORD  line_delta=0;  |   WORD  line_delta=0;  | ||
| - | + | ||
| if (copper_error!=0) | if (copper_error!=0) | ||
| return; | return; | ||
| - | + | ||
| asm { | asm { | ||
| push ds | push ds | ||
| push si | push si | ||
|         lds    |         lds    | ||
| - |         xor    cx,cx                      | + | xor cx,cx // reset cx : line counter | 
| xor bx,bx | xor bx,bx | ||
|         mov    |         mov    | ||
| Ligne 92: | Ligne 91: | ||
| test al,0x08 | test al,0x08 | ||
| je w2 } | je w2 } | ||
| - | + | ||
| - | start:asm { // protection | + | start:asm {                            | 
|         mov    |         mov    | ||
| - |         cmp    | + |         cmp    | 
|         jb    start2  |         jb    start2  | ||
| - | jmp eocl } // exit | + |         jmp    eocl }                  | 
| - | + | ||
| start2: asm { | start2: asm { | ||
| - | lodsb // load copper list operand | + |         lodsb                          | 
|         cmp    |         cmp    | ||
|         jne    |         jne    | ||
| xor al,al | xor al,al | ||
| jmp eocl } | jmp eocl } | ||
| - | + | ||
| start3: asm { | start3: asm { | ||
|         cmp    |         cmp    | ||
| jne start4 | jne start4 | ||
| jmp wait_line } | jmp wait_line } | ||
| - | + | ||
| start4:asm { | start4:asm { | ||
|         cmp    |         cmp    | ||
| jne start5 | jne start5 | ||
| jmp set_color } | jmp set_color } | ||
| - | + | ||
| start5:asm { | start5:asm { | ||
|         cmp    |         cmp    | ||
| je gradient | je gradient | ||
| - | + | ||
|         mov    |         mov    | ||
| jmp eocl } | jmp eocl } | ||
| - | + | ||
| // ------------------------------------- GRADIENT | // ------------------------------------- GRADIENT | ||
| gradient: asm { | gradient: asm { | ||
| - |         mov    line_start, | + |         mov    line_start, | 
| lodsw | lodsw | ||
| - |         mov    bh,al                    | + | mov bh,al // reverse endian | 
| mov bl,ah | mov bl,ah | ||
| - |         mov    | + |         mov    | 
| - |         | + | |
| // calculate the number of line between line_start and line_end | // calculate the number of line between line_start and line_end | ||
| - | sub bx,cx | + | sub bx,cx | 
| - |         mov    line_delta, | + |         mov    line_delta, | 
| - | + | ||
| - | lodsb // load red_end | + |         lodsb                          | 
| - | shr al,2 // reduce to 6 bits only | + |         shr    al,2                    | 
| - |         mov    red_end, | + |         mov    red_end, | 
| mov ah,al | mov ah,al | ||
| - |          | + | |
| - |         mov    bl, | + |         mov    bl, | 
| - | sub al,bl // end - start | + | sub al,bl // end - start | 
| - |         mov    | + |         mov    | 
| - |         mov    red_prec, | + |         mov    red_prec, | 
| - | + | ||
| - | lodsb // load green_end | + |         lodsb                          | 
| shr al,2 | shr al,2 | ||
|         mov    green_end, |         mov    green_end, | ||
| mov ah,al | mov ah,al | ||
| - |         mov    bl, | + |         mov    bl, | 
| sub al,bl | sub al,bl | ||
| - |         mov    | + |         mov    | 
|         mov    green_prec, |         mov    green_prec, | ||
| - | + | ||
| - | lodsb // load blue_end | + |         lodsb                          | 
| shr al,2 | shr al,2 | ||
| mov blue_end,al | mov blue_end,al | ||
| Ligne 161: | Ligne 160: | ||
| sub al,bl | sub al,bl | ||
|         mov    |         mov    | ||
| - |         mov    blue_prec, | + |         mov    blue_prec, | 
| - | + | ||
| gr_start: asm { | gr_start: asm { | ||
| - | inc cx // cx = cx+1 | + |         inc    cx                      | 
| - |         cmp    | + |         cmp    | 
| jb gradient_hbl | jb gradient_hbl | ||
| - |         jmp    start  }                  | + |         jmp    start  }                | 
| - | + | ||
| gradient_hbl: | gradient_hbl: | ||
| - | mov dx,0x3da } // read input state | + |         mov    dx,0x3da }              | 
| gr_in_retrace: | gr_in_retrace: | ||
| - | in al,dx // test if we are redrawing | + |         in    al,dx                    | 
| test al,1 | test al,1 | ||
| jne gr_in_retrace } | jne gr_in_retrace } | ||
| - | + | ||
| gr_in_display: | gr_in_display: | ||
| in al,dx | in al,dx | ||
| test al,1 // wait for hbl (horizontal return) | test al,1 // wait for hbl (horizontal return) | ||
| je gr_in_display | je gr_in_display | ||
| - | + | ||
| mov ax,cx | mov ax,cx | ||
| - |         sub    ax, | + |         sub    ax, | 
| - |         mov    bx, | + |         mov    bx, | 
| - | + | ||
| xor dx,dx | xor dx,dx | ||
| - |         shl    | + |         shl    | 
|         div    |         div    | ||
| - |         mov    bx,ax                    | + | mov bx,ax // bx = percentage 0..100 | 
| - | + | ||
| cli | cli | ||
|         mov    |         mov    | ||
| Ligne 195: | Ligne 194: | ||
|         out    |         out    | ||
| inc dx | inc dx | ||
| - | + | ||
| xor ax,ax | xor ax,ax | ||
|         mov    |         mov    | ||
| - |         imul  bl                      // must be signed multiplication  | + | imul bl // must be signed multiplication | 
|         shr    |         shr    | ||
|         add    |         add    | ||
| - | out dx,al // set RED to dac | + | out dx,al // set RED to dac | 
| mov red_end,al | mov red_end,al | ||
| - | + | ||
| xor ax,ax | xor ax,ax | ||
|         mov    |         mov    | ||
| - |         imul  bl                      // must be signed multiplication  | + | imul bl // must be signed multiplication | 
|         shr    |         shr    | ||
|         add    |         add    | ||
| - |         out    dx,al                      | + | out dx,al // set GREEN to dac | 
|         mov    green_end, |         mov    green_end, | ||
| - | + | ||
| xor ax,ax | xor ax,ax | ||
|         mov    |         mov    | ||
| - |         imul  bl                      // must be signed multiplication  | + | imul bl // must be signed multiplication | 
|         shr    |         shr    | ||
|         add    |         add    | ||
| - | out dx,al // set BLUE to dac | + | out dx,al // set BLUE to dac | 
| mov blue_end,al | mov blue_end,al | ||
| sti | sti | ||
| - | + | ||
|         jmp    |         jmp    | ||
| - | + | ||
| // ------------------------------------- WAIT | // ------------------------------------- WAIT | ||
| wait_line: | wait_line: | ||
| lodsw | lodsw | ||
| - | mov bh,al // swap byte endian encoding craps | + | mov bh,al // swap byte endian encoding craps | 
| - |         mov    | + |         mov    | 
| - | mov dx,0x3da } // input state | + |         mov    dx,0x3da }              | 
| - | + | ||
| wait_next: asm { | wait_next: asm { | ||
| - | inc cx // cx = cx+1 | + |         inc    cx                      | 
| - |         cmp    | + |         cmp    | 
|         jae    |         jae    | ||
| - | + | ||
| in_retrace: | in_retrace: | ||
| - | in al,dx // read input state, test if we are redrawing | + |         in    al,dx                    | 
| test al,1 | test al,1 | ||
| jne in_retrace } | jne in_retrace } | ||
| Ligne 244: | Ligne 243: | ||
| je in_display | je in_display | ||
|         jmp    |         jmp    | ||
| - | + | ||
| wait_end: | wait_end: | ||
| jmp start } | jmp start } | ||
| - | + | ||
| // ------------------------------------- SETCOLOR | // ------------------------------------- SETCOLOR | ||
| set_color: asm { | set_color: asm { | ||
| cli | cli | ||
| - | lodsb // get color index | + |         lodsb                          | 
|         mov    |         mov    | ||
| mov dx,0x3c8 | mov dx,0x3c8 | ||
|         out    |         out    | ||
|         inc    |         inc    | ||
| - | + | ||
| - | lodsb // get RED level | + |         lodsb                          | 
| shr al,2 | shr al,2 | ||
|         mov    |         mov    | ||
| - | out dx,al // set RED to dac | + | out dx,al // set RED to dac | 
| - | + | ||
| - | lodsb // get GREEN level | + |         lodsb                          | 
| shr al,2 | shr al,2 | ||
|         mov    |         mov    | ||
| - | out dx,al // set GREEN to dac | + | out dx,al // set GREEN to dac | 
| - | + | ||
| - | lodsb // get BLUE level | + |         lodsb                          | 
| shr al,2 | shr al,2 | ||
|         mov    |         mov    | ||
| - | out dx,al // set BLUE to dac | + | out dx,al // set BLUE to dac | 
| sti | sti | ||
| jmp start } // get next operand | jmp start } // get next operand | ||
| - | + | ||
| eocl:asm { | eocl:asm { | ||
| sti | sti | ||
| pop si | pop si | ||
| pop ds | pop ds | ||
| - |         mov    | + |         mov    | 
| - | + | ||
| - |         xor    al,al                    | + | xor al,al // normally we should restore whole DAC's status | 
| - |         mov    dx, | + |         mov    dx, | 
| out dx,al | out dx,al | ||
| inc dx | inc dx | ||
| - |         out    dx,al                    | + | out dx,al // turn to RGB 0,0,0 | 
| out dx,al | out dx,al | ||
| out dx,al } | out dx,al } | ||
| } | } | ||
| - | + | ||
| void main() | void main() | ||
| { | { | ||
| unsigned char running=1; | unsigned char running=1; | ||
| - | + | ||
|   textmode(3); |   textmode(3); | ||
| clrscr(); | clrscr(); | ||
| - | + | ||
| while (running) | while (running) | ||
| { | { | ||
| Ligne 304: | Ligne 303: | ||
| } | } | ||
| // do some stuffs | // do some stuffs | ||
| - | + | ||
|     printf(" |     printf(" | ||
|     DrawCopperListv2(copperlistv2); |     DrawCopperListv2(copperlistv2); | ||
| } | } | ||
| - | + | ||
|   printf(" |   printf(" | ||
| } | } | ||
| + | |||
| + | |||
| </ | </ | ||
| == Commentaire sur les sources == | == Commentaire sur les sources == | ||
| - | A cause des limitations du x86 concernant les jump conditionnels (near) il a fallut mettre en place un structure de type switch case. | + | <WRAP center round info 95%> | 
| + | A cause des limitations du x86 concernant les jump conditionnels (near), il a fallut mettre en place un structure de type switch case; car l' | ||
| - | Le build-in assembler de borland C++ n'est pas capable de faire de sauts conditionnel au delà d'un delta de -126 +127; car l' | + | Le build-in assembler de borland C++ utilise des instruction  | 
| + | </ | ||
| <code asm> | <code asm> | ||
|         mov    |         mov    | ||
| - |         cmp    | + |         cmp    | 
|         jae    |         jae    | ||
| Ligne 334: | Ligne 337: | ||
| je gradient | je gradient | ||
|         jmp    |         jmp    | ||
| + | |||
| + | |||
| </ | </ | ||
| Ligne 345: | Ligne 350: | ||
| locals | locals | ||
| .386 | .386 | ||
| - | + | ||
| PRECIS  | PRECIS  | ||
| - | + | ||
| CODESEG | CODESEG | ||
| - | + | ||
| - | ; public variables  | + | ; public variables | 
| - | + | ||
| _copper_error  | _copper_error  | ||
| _copper_maxrow  | _copper_maxrow  | ||
| - | + | ||
| public _copper_error | public _copper_error | ||
| public _copper_maxrow | public _copper_maxrow | ||
| - | + | ||
| ; private variables | ; private variables | ||
| - | + | ||
| ; | ; | ||
| ; | ; | ||
| ; | ; | ||
| ; | ; | ||
| - |      | + | |
| ; | ; | ||
| ; | ; | ||
| ; | ; | ||
| - | + | ||
| ; | ; | ||
| ; | ; | ||
| ; | ; | ||
| - | + | ||
| ; | ; | ||
| ; | ; | ||
| Ligne 378: | Ligne 383: | ||
| public  | public  | ||
| - | + | ||
| _DrawCopperList PROC C FAR | _DrawCopperList PROC C FAR | ||
|         ARG      CopperList: |         ARG      CopperList: | ||
| Ligne 386: | Ligne 391: | ||
| local    | local    | ||
| local    | local    | ||
| - | + | ||
| - |          | + | |
| push ds | push ds | ||
| push si | push si | ||
| - |          | + | |
|         lds    |         lds    | ||
| - |          | + | |
|         cmp    cs: |         cmp    cs: | ||
| - |         jne    clean_eocl  | + | jne clean_eocl | 
| - | + | ||
|         xor    ecx, |         xor    ecx, | ||
| xor ebx,ebx | xor ebx,ebx | ||
| - | + | ||
|         mov    |         mov    | ||
| w1:      | w1:      | ||
| test al,08h | test al,08h | ||
| - |         jne    | + | jne w1 | 
| w2:      | w2:      | ||
| test al,08h | test al,08h | ||
| - | je w2 | + | je w2 | 
| - | + | ||
| start:  | start:  | ||
| - |         cmp    | + |         cmp    | 
|         jae    |         jae    | ||
| lodsb ; load copper list operand | lodsb ; load copper list operand | ||
|         cmp    |         cmp    | ||
| - | je clean_eocl | + | je clean_eocl | 
| - | + | ||
|         cmp    |         cmp    | ||
| je wait_line | je wait_line | ||
| - | + | ||
|         cmp    |         cmp    | ||
| je set_color | je set_color | ||
| - |          | + | |
|         cmp    |         cmp    | ||
| je gradient | je gradient | ||
| - | + | ||
|         mov    |         mov    | ||
| jmp eocl | jmp eocl | ||
| - | + | ||
| ; ------------------------------------- GRADIENT | ; ------------------------------------- GRADIENT | ||
| - | gradient:  | + | gradient: | 
|         mov    line_start, |         mov    line_start, | ||
| lodsw | lodsw | ||
| Ligne 434: | Ligne 438: | ||
| mov bl,ah | mov bl,ah | ||
|         mov    line_end, |         mov    line_end, | ||
| - |          | + | |
| ; calculate the number of line between line_start and line_end | ; calculate the number of line between line_start and line_end | ||
| - | sub bx,cx | + | sub bx,cx | 
| - |         mov    line_delta, | + |         mov    line_delta, | 
| - | + | ||
| lodsb ; load red_end | lodsb ; load red_end | ||
| shr al,2 ; reduce to 6 bits only | shr al,2 ; reduce to 6 bits only | ||
|         mov    red_end, |         mov    red_end, | ||
| mov ah,al | mov ah,al | ||
| - |          | + | |
|         mov    bl, |         mov    bl, | ||
| sub al,bl ; end - start | sub al,bl ; end - start | ||
|         mov    red_step, |         mov    red_step, | ||
| mov red_prec,ah | mov red_prec,ah | ||
| - | + | ||
| lodsb ; load green_end | lodsb ; load green_end | ||
| shr al,2 | shr al,2 | ||
| Ligne 457: | Ligne 461: | ||
|         mov    green_step, |         mov    green_step, | ||
|         mov    green_prec, |         mov    green_prec, | ||
| - | + | ||
| lodsb ; load blue_end | lodsb ; load blue_end | ||
| shr al,2 | shr al,2 | ||
| Ligne 466: | Ligne 470: | ||
|         mov    blue_step, |         mov    blue_step, | ||
|         mov    blue_prec, |         mov    blue_prec, | ||
| - | + | ||
| gr_start: | gr_start: | ||
| inc cx ; cx = cx+1 | inc cx ; cx = cx+1 | ||
| Ligne 472: | Ligne 476: | ||
|         jb      |         jb      | ||
| jmp start ; next operant | jmp start ; next operant | ||
| - | + | ||
| gradient_hbl: | gradient_hbl: | ||
|         mov    dx, |         mov    dx, | ||
| - |          | + | |
| gr_in_retrace: | gr_in_retrace: | ||
|         in      |         in      | ||
| test al,1 | test al,1 | ||
| - | jne gr_in_retrace | + | jne gr_in_retrace | 
| - | + | ||
| gr_in_display: | gr_in_display: | ||
| in al,dx | in al,dx | ||
| Ligne 490: | Ligne 494: | ||
|         sub    ax, |         sub    ax, | ||
|         mov    bx, |         mov    bx, | ||
| - | + | ||
| xor dx,dx | xor dx,dx | ||
|         shl    eax, |         shl    eax, | ||
| div bx ; pct_current / pct_max | div bx ; pct_current / pct_max | ||
| mov bx,ax ; bx = percentage 0..100 | mov bx,ax ; bx = percentage 0..100 | ||
| - | + | ||
| cli | cli | ||
| mov al,color | mov al,color | ||
| Ligne 501: | Ligne 505: | ||
| out dx,al ; select color index | out dx,al ; select color index | ||
| inc dx | inc dx | ||
| - | + | ||
| xor eax,eax | xor eax,eax | ||
| mov al,red_step | mov al,red_step | ||
| - |         imul    | + |         imul    | 
| shr ax,PRECIS | shr ax,PRECIS | ||
| add al,red_prec | add al,red_prec | ||
| out dx,al ; set RED to dac | out dx,al ; set RED to dac | ||
| mov red_end,al | mov red_end,al | ||
| - | + | ||
| xor ax,ax | xor ax,ax | ||
|         mov    al, |         mov    al, | ||
| - |         imul    | + |         imul    | 
| shr ax,PRECIS | shr ax,PRECIS | ||
|         add    al, |         add    al, | ||
| out dx,al ; set GREEN to dac | out dx,al ; set GREEN to dac | ||
|         mov    green_end, |         mov    green_end, | ||
| - | + | ||
| xor ax,ax | xor ax,ax | ||
|         mov    al, |         mov    al, | ||
| - |         imul    | + |         imul    | 
| shr ax,PRECIS | shr ax,PRECIS | ||
|         add    al, |         add    al, | ||
| Ligne 526: | Ligne 530: | ||
| mov blue_end,al | mov blue_end,al | ||
| sti | sti | ||
| - | + | ||
|         jmp    gr_start  |         jmp    gr_start  | ||
| - | + | ||
| ; ------------------------------------- WAIT | ; ------------------------------------- WAIT | ||
| wait_line: | wait_line: | ||
| Ligne 535: | Ligne 539: | ||
| mov bl,ah ; bx = line word | mov bl,ah ; bx = line word | ||
|         mov    dx, |         mov    dx, | ||
| - | + | ||
| wait_next: | wait_next: | ||
| inc cx ; cx = cx+1 | inc cx ; cx = cx+1 | ||
| - | cmp cx,bx ; current line >= wait_line ? | + | cmp cx,bx ; current line>= wait_line ? | 
|         jae    wait_end  |         jae    wait_end  | ||
| - | + | ||
| in_retrace: | in_retrace: | ||
|         in      |         in      | ||
| test al,1 | test al,1 | ||
| - |         jne    in_retrace  | + | jne in_retrace | 
| in_display: | in_display: | ||
| in al,dx | in al,dx | ||
| Ligne 550: | Ligne 554: | ||
|         je      |         je      | ||
|         jmp    wait_next  |         jmp    wait_next  | ||
| - | + | ||
| wait_end: | wait_end: | ||
| - | jmp start | + | jmp start | 
| - | + | ||
| ; ------------------------------------- SETCOLOR | ; ------------------------------------- SETCOLOR | ||
| - | set_color:  | + | set_color: | 
| cli | cli | ||
| lodsb ; get color index | lodsb ; get color index | ||
| Ligne 562: | Ligne 566: | ||
| out dx,al ; select color index | out dx,al ; select color index | ||
|         inc    dx                      ; mov    |         inc    dx                      ; mov    | ||
| - | + | ||
| lodsb ; get RED level | lodsb ; get RED level | ||
| shr al,2 | shr al,2 | ||
| mov red_prec,al | mov red_prec,al | ||
| out dx,al ; set RED to dac | out dx,al ; set RED to dac | ||
| - | + | ||
| lodsb ; get GREEN level | lodsb ; get GREEN level | ||
| shr al,2 | shr al,2 | ||
|         mov    green_prec, |         mov    green_prec, | ||
| out dx,al ; set GREEN to dac | out dx,al ; set GREEN to dac | ||
| - | + | ||
| lodsb ; get BLUE level | lodsb ; get BLUE level | ||
| shr al,2 | shr al,2 | ||
| Ligne 579: | Ligne 583: | ||
| sti | sti | ||
| jmp start ; get next operand | jmp start ; get next operand | ||
| - | + | ||
| clean_eocl: | clean_eocl: | ||
| xor al,al | xor al,al | ||
| Ligne 586: | Ligne 590: | ||
| pop si | pop si | ||
| pop ds | pop ds | ||
| - | + | ||
| xor al,al ; normally we should restore whole DAC's status | xor al,al ; normally we should restore whole DAC's status | ||
|         mov    dx, |         mov    dx, | ||
| Ligne 593: | Ligne 597: | ||
| out dx,al ; turn to RGB 0,0,0 | out dx,al ; turn to RGB 0,0,0 | ||
| out dx,al | out dx,al | ||
| - | out dx,al | + | out dx,al | 
| ret | ret | ||
| _DrawCopperList endp | _DrawCopperList endp | ||
| - |        | + | |
| END | END | ||
| - | </ | + | |
| - | + | ||
| + | </ | ||
| === le header .h === | === le header .h === | ||
| Ligne 613: | Ligne 619: | ||
| #endif | #endif | ||
| </ | </ | ||
| - | + | ||
| - | <nspages tutoriaux -simpleList -h1 -exclude: | + | < | 
| + | |||