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: | + | < |
| + | |||