home *** CD-ROM | disk | FTP | other *** search
- ;;; PROGRAMA en assembler para comprobar la subrutina de dibujado rápido
- ;;; de triangulos rellenos --> Navi / PhyMosys
- .MODEL SMALL
- .STACK
- .386
-
- LOCALS @@
- w EQU WORD PTR
- b EQU BYTE PTR
- d EQU DWORD PTR
-
- .CODE
- ; INCLUDE GRFLIB.INC
-
- Save1 DD 0
- kk dw 0
-
- FillTriangle PROC
- PUSHAD
- PUSH ES
- MOV AX, DS:[BX+2] ; Pillamos y1
- CMP AX, DS:[BX+6]
- JB @@Cont1 ; y1<y2 ?
- JE @@Iguales1
- XCHG AX, DS:[BX+6]
- MOV DX, DS:[BX+0]
- MOV DS:[BX+2], AX
- XCHG DX, DS:[BX+4]
- MOV DS:[BX+0], DX ; Cambio realizado.
- JMP @@Cont1
- @@Iguales1:
- INC w DS:[BX+6] ; Fuera las divisiones por 0.
-
- @@Cont1: MOV AX, DS:[BX+2] ; y1
- CMP AX, DS:[BX+10]
- JB @@Cont2 ; y1<y3 ?
- JE @@Iguales2
- XCHG AX, DS:[BX+10]
- MOV DX, DS:[BX+0]
- MOV DS:[BX+2], AX
- XCHG DX, DS:[BX+8]
- MOV DS:[BX+0], DX ; Cambio realitzado.
- JMP @@Cont2
- @@Iguales2:
- INC w DS:[BX+10] ; Fuera las divisiones por 0.
-
- @@Cont2: MOV AX, DS:[BX+6] ; y2
- CMP AX, DS:[BX+10]
- JB @@Cont3 ; y2<y3 ?
- JE @@Iguales3
- XCHG AX, DS:[BX+10]
- MOV DX, DS:[BX+4]
- MOV DS:[BX+6], AX
- XCHG DX, DS:[BX+8]
- MOV DS:[BX+4], DX ; Cambio realitzado.
- JMP @@Cont3
- @@Iguales3:
- INC w DS:[BX+6] ; Fuera las divisiones por 0.
-
- @@Cont3: MOV BP, BX
- MOV AX, 0A000h
- MOV ES, AX ; Segmento de video de la VGA
-
- ; Inicialización de variables.
-
- MOVZX EDI, w DS:[BP+2]
- MOV EAX, EDI
- SHL EDI, 6 ; EDI * 64
- MOVZX ESI, w DS:[BP+6]; Calculamos ESI paralelamente
- SHL EAX, 8 ; EAX * 256
- SHL ESI, 6+7 ; ESI * 64 y a fixed point
- MOVZX EBX, w DS:[BP+0]; Cargamos la x1
- ADD EDI, EAX ; EDI * 320
- MOV EAX, ESI
- ADD EDI, EBX ; EDI -> y1 * 320 + x1
- SHL EAX, 8+7-(6+7) ; EAX * 256 y a fixed point (antes)
- SAL EDI, 7 ; Pasamos a punto fijo.
- ADD ESI, EAX ; EDI -> y2 * 320
-
- MOV AX, w DS:[BP+0]
- MOV BX, w DS:[BP+2]
- SUB AX, w DS:[BP+8] ; AX = x1 - x3
- SUB BX, w DS:[BP+10]; BX = y1 - y3
- MOVSX EAX, AX
- MOVSX EBX, BX ; Solo el WORD de bajo.
- SAL EAX, 7+7 ; +7 para la proxima división.
- SAL EBX, 7 ; Pasamos a fixed point.
- XOR EDX, EDX
- OR EAX, EAX
- JNS @@Ok2 ; El signo de EDX es muy importante.
- DEC EDX
- @@Ok2: IDIV EBX ; En EAX el resultado.
- MOV CS:[Save1], EAX ; Para dentro de un ratito
- MOV ECX, EAX ; Guardamos el resultado para después
- ADD EAX, 320*128 ; EAX = EAX + 320 (en fixed)
- MOV EBX, EAX
-
- PUSH EBX
- MOV AX, w DS:[BP+4]
- MOV BX, w DS:[BP+6]
- SUB AX, w DS:[BP+0] ; AX = x2 - x1
- SUB BX, w DS:[BP+2] ; BX = y2 - y1
- MOVSX EAX, AX
- MOVSX EBX, BX ; Solo el WORD de bajo.
- SAL EAX, 7+7 ; +7 para la proxima división.
- SAL EBX, 7 ; Pasamos a fixed point.
- XOR EDX, EDX
- OR EAX, EAX
- JNS @@Ok3 ; El signo de EDX es muy importante.
- DEC EDX
- @@Ok3: IDIV EBX ; En EAX el resultado.
- SUB EAX, ECX ; ECX lo habiamos calculado antes.
- JNS @@Positivo ; Si el signo es (-) cambiarlo.
- NEG EAX
- @@Positivo: MOV EDX, EAX ; Ya está calculado el EDX!
- POP EBX
-
- XOR ECX, ECX ; El ECX (chantatachan... >8-D )
- MOV w CS:[OverW1], 9090h ; Insertamos 2 NOPs
- MOV AX, DS:[BP+4]
- CLD ; Hacia la derecha... :(
- MOV w CS:[OverW2], 9090h
- CMP AX, DS:[BP+0] ; x2>x1 ?
- JA @@Ok1
- MOV w CS:[OverW1], 0CF29h ; CF29h -> SUB DI,CX
- MOV w CS:[OverW2], 0CF29h
-
- ; El primer bucle.
-
- @@Ok1: MOVZX AX, b DS:[BP+12]; Pillamos el color.
- MOV AH, AL
- SHL EAX, 16
- MOVZX AX, b DS:[BP+12]
- MOV AH, AL
-
- @@BucleW1: CMP EDI, ESI
- JNB @@FinBucle1 ; Hasta que EDI>=ESI
-
- PUSH EDI ; Tenemos que guardar estos registros
- PUSH ECX
- SHR ECX, 7
- SHR EDI, 7
- OverW1: NOP ; 2*NOP / SUB DI,CX
- NOP
- SHR CX, 1
- JNC @@NoDoble1
- STOSB
- @@NoDoble1: SHR CX, 1
- JNC @@NoDoble1b
- STOSW
- @@NoDoble1b:REP STOSd ; Dibujamos 1 línea horizontal.
- POP ECX
- POP EDI
-
- ADD EDI, EBX ; Incrementamos valors
- ADD ECX, EDX
- JMP @@BucleW1
- @@FinBucle1:
-
- ; Re-inicialitzación de las variables.
-
- PUSH EBX
- MOV AX, w DS:[BP+4]
- MOV BX, w DS:[BP+6]
- SUB AX, w DS:[BP+8] ; AX = x2 - x3
- SUB BX, w DS:[BP+10]; BX = y2 - y3
- MOVSX EAX, AX
- MOVSX EBX, BX ; Solo el WORD de bajo.
- SAL EAX, 7+7 ; +7 para la próxima división.
- SAL EBX, 7 ; Pasamos a fixed point.
- MOVZX ESI, w DS:[BP+10]
- XOR EDX, EDX
- OR EAX, EAX
- JNS @@Ok4 ; El signo de EDX es muy importante.
- DEC EDX
- @@Ok4: IDIV EBX ; En EAX el resultado.
- SHL ESI, 6+7 ; ESI * 64 y a fixed point.
- MOV EDX, EAX
- MOV EAX, ESI
- SUB EDX, CS:[Save1] ; El 'save' lo habiamos calculado antes
- JNS @@Positivo2 ; Si el signo es (-) cambiarlo.
- NEG EDX ; Ya está recalculado EDX!
- @@Positivo2: SAL EAX, (8+7)-(6+7); EAX * 256 y a fixed point.
- POP EBX
- ADD ESI, EAX ; ESI -> y3 * 320
-
- ; El darrer bucle.
-
- MOVZX AX, b DS:[BP+12] ; Pillamos el color.
- MOV AH, AL
- SHL EAX, 16
- MOVZX AX, b DS:[BP+12]
- MOV AH, AL
-
- @@BucleW2: CMP EDI, ESI
- JNB @@FinBucle2 ; Hasta que EDI>=ESI
-
- PUSH EDI ; Tenemos que guardar estos registros
- PUSH ECX
- SHR ECX, 7
- SHR EDI, 7
- OverW2: NOP ; 2*NOP / SUB DI,CX
- NOP
- SHR CX, 1
- JNC @@NoDoble2
- STOSB
- @@NoDoble2: SHR CX, 1
- JNC @@NoDoble2b
- STOSW
- @@NoDoble2b:REP STOSd ; Dibujamos 1 línea horizontal.
- POP ECX
- POP EDI
-
- ADD EDI, EBX ; Incrementamos valores
- SUB ECX, EDX
- JMP @@BucleW2
- @@FinBucle2:
- POP ES
- POPAD
- RET ; Un bonito triangulo, no? :)
- FillTriangle ENDP
-
- PUBLIC Triangulo
- ;; La llamada se hace así: Triangulo(tr1 : TrianType);
- Triangulo PROC
- PUSH BP
- MOV BP, SP
- PUSH DS
- MOV AX, [BP+8]
- MOV DS, AX
- MOV BX, [BP+6]
- CALL FillTriangle
- POP DS
- POP BP
- RETF
- Triangulo ENDP
- END
-