Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente Prochaine révisionLes deux révisions suivantes | ||
tutoriaux:vga-avance-dac-part-3 [2021/05/02 23:12] – créée frater | tutoriaux:vga-avance-dac-part-3 [2021/05/03 16:34] – frater | ||
---|---|---|---|
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 | + | Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 0x30 LineH LineL Red Green Blue |
- | 0x30 LineH LineL Red Green Blue | + | |
Les bytes " | Les bytes " | ||
Ligne 40: | Ligne 38: | ||
#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 58: | ||
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 71: | ||
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 90: | ||
test al,0x08 | test al,0x08 | ||
je w2 } | je w2 } | ||
- | + | ||
start:asm { // protection | start:asm { // protection | ||
mov | mov | ||
- | cmp | + | cmp |
jb start2 | jb start2 | ||
jmp eocl } // exit | jmp eocl } // exit | ||
- | + | ||
start2: asm { | start2: asm { | ||
lodsb // load copper list operand | lodsb // load copper list operand | ||
Ligne 105: | Ligne 103: | ||
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 { | ||
Ligne 130: | Ligne 128: | ||
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 // 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 | mov | ||
mov red_prec, | mov red_prec, | ||
- | + | ||
lodsb // load green_end | lodsb // load green_end | ||
shr al,2 | shr al,2 | ||
Ligne 153: | Ligne 151: | ||
mov | mov | ||
mov green_prec, | mov green_prec, | ||
- | + | ||
lodsb // load blue_end | lodsb // load blue_end | ||
shr al,2 | shr al,2 | ||
Ligne 162: | Ligne 160: | ||
mov | mov | ||
mov blue_prec, | mov blue_prec, | ||
- | + | ||
gr_start: asm { | gr_start: asm { | ||
inc cx // cx = cx+1 | inc cx // cx = cx+1 | ||
Ligne 168: | Ligne 166: | ||
jb gradient_hbl | jb gradient_hbl | ||
jmp start } // next operant | jmp start } // next operant | ||
- | + | ||
gradient_hbl: | gradient_hbl: | ||
mov dx,0x3da } // read input state | mov dx,0x3da } // read input state | ||
Ligne 175: | Ligne 173: | ||
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 // bx = percentage 0..100 | mov bx,ax // bx = percentage 0..100 | ||
- | + | ||
cli | cli | ||
mov | mov | ||
Ligne 195: | Ligne 193: | ||
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 // set GREEN to dac | 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 | ||
Ligne 220: | Ligne 218: | ||
mov blue_end,al | mov blue_end,al | ||
sti | sti | ||
- | + | ||
jmp | jmp | ||
- | + | ||
// ------------------------------------- WAIT | // ------------------------------------- WAIT | ||
wait_line: | wait_line: | ||
Ligne 229: | Ligne 227: | ||
mov | mov | ||
mov dx,0x3da } // input state | mov dx,0x3da } // input state | ||
- | + | ||
wait_next: asm { | wait_next: asm { | ||
inc cx // cx = cx+1 | inc cx // cx = cx+1 | ||
- | cmp | + | cmp |
jae | jae | ||
- | + | ||
in_retrace: | in_retrace: | ||
in al,dx // read input state, test if we are redrawing | in al,dx // read input state, test if we are redrawing | ||
Ligne 244: | Ligne 242: | ||
je in_display | je in_display | ||
jmp | jmp | ||
- | + | ||
wait_end: | wait_end: | ||
jmp start } | jmp start } | ||
- | + | ||
// ------------------------------------- SETCOLOR | // ------------------------------------- SETCOLOR | ||
set_color: asm { | set_color: asm { | ||
Ligne 256: | Ligne 254: | ||
out | out | ||
inc | inc | ||
- | + | ||
lodsb // get RED level | lodsb // get RED level | ||
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 // get GREEN level | ||
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 // get BLUE level | ||
shr al,2 | shr al,2 | ||
Ligne 273: | Ligne 271: | ||
sti | sti | ||
jmp start } // get next operand | jmp start } // get next operand | ||
- | + | ||
eocl:asm { | eocl:asm { | ||
sti | sti | ||
Ligne 279: | Ligne 277: | ||
pop ds | pop ds | ||
mov | mov | ||
- | + | ||
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 288: | Ligne 286: | ||
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 302: | ||
} | } | ||
// 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. | A cause des limitations du x86 concernant les jump conditionnels (near) il a fallut mettre en place un structure de type switch case. | ||
Ligne 321: | Ligne 320: | ||
<code asm> | <code asm> | ||
mov | mov | ||
- | cmp | + | cmp |
jae | jae | ||
Ligne 334: | Ligne 333: | ||
je gradient | je gradient | ||
jmp | jmp | ||
+ | |||
</ | </ | ||
Ligne 345: | Ligne 345: | ||
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 378: | ||
public | public | ||
- | + | ||
_DrawCopperList PROC C FAR | _DrawCopperList PROC C FAR | ||
ARG CopperList: | ARG CopperList: | ||
Ligne 386: | Ligne 386: | ||
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 433: | ||
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 456: | ||
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 465: | ||
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 471: | ||
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 489: | ||
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 500: | ||
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 525: | ||
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 534: | ||
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 549: | ||
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 561: | ||
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 578: | ||
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 585: | ||
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 592: | ||
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 612: | Ligne 612: | ||
#endif | #endif | ||
+ | |||
</ | </ | ||
- | + | ||
- | <nspages tutoriaux -simpleList -h1 -exclude: | + | <nspages tutoriaux -simpleList -h1 -exclude: |
+ |