; DRIVER DE USUARIO DEMOSTRACION DE NMP
;
; Autor : Carlos S nchez
; Fecha : Febrero 1995
; Ensamblador utilizado : A86
;
; Procesador requerido : 286, c¢digo no optimizado.
;
; Fichero resultado : DRIVER.COM, renombrar como NMP.DRV.
; ­­ DRIVER.COM no es ejecutable directamente !!!
;
; Funci¢n seleccionable via AL (8 bits bajos de par metro 1
; de CALLDRV, 8 bits superiores no utilizados).
;
; Par metro para funci¢nes 0 y 1 dado en BL (8 bits bajos de
; segundo par metro, 8 bits altos no utilizados).
;
; Para saber su modo de uso lea el manual de NMP.


; Las tres lineas siguientes son innecesarias, s¢lo las pongo para que en la
; cabecera del fichero NMP.DRV aparezca el (C).

JMP SIGUE
DB 13,'DRIVER DE USUARIO 1.0 (C) 1995 NM Software',26
SIGUE:

; Ahora empieza lo que de verdad vale.

PUSH BP         ; Cabecera general de un procedimiento Turbo Pascal
MOV BP,SP
SUB SP,0300H    ; Reservar 768 bytes de pila para variables locales. En
                ; concreto para la paleta de color.

; AL es el selector de la funci¢n requerida
; Llamo a la funci¢n solicitada y una vez seleccionada registro AL
; queda libre para usar.

CALL READPAL    ; Leo la paleta pues todas las funciones la requieren.

CMP AL,4
JNE SIG4
CALL FUNCION04   ; Fundido incremento inmediato excepto color 0 (silueta)
JMP SALIDA

SIG4:
CMP AL,3
JNE SIG3         ; Fundido incremento progresivo excepto color 0
CALL FUNCION03
JMP SALIDA

SIG3:
CMP AL,2
JNE SIG         ; Fundido incremento progresivo
CALL FUNCION02
JMP SALIDA

SIG:
CMP AL,1
JNE SIG2
CALL FUNCION01  ; Fundido decremento inmediato
JMP SALIDA

SIG2:
OR AL,AL
JNZ MAL
CALL FUNCION00    ; Fundido decremento progresivo (fundido normal)
JMP SALIDA

MAL:
MOV AX,0FFFFh     ; Si la funci¢n es err¢nea devuelve FFFF en AX (flag 13).

SALIDA:
MOV SP,BP       ; C¢digo general de salida de un procedimiento lejano
POP BP          ; de Turbo Pascal.
RETF


;          ***************  FUNCIONES INTERNAS *********************


; FUNCION INTERNA DECREMENTA. Decrementa el valor apuntado por [BP+DI-300h]
; SI SE AJUSTA A LA MASCARA CONTENIDA EN BL.
DECREMENTA:
PUSH CX
MOV AX,DI
MOV CL,3
DIV CL    ; AH:= AX MOD 3;
MOV CL,AH
MOV AL,1
SHL AL,CL
AND AL,BL
JZ NADA
DEC BYTE PTR [BP+DI-0300H]
NADA:
POP CX
RET


; FUNCION INTERNA INCREMENTA. Decrementa el valor apuntado por [BP+DI-300h]
; SI SE AJUSTA A LA MASCARA CONTENIDA EN BL.
INCREMENTA:
PUSH CX
MOV AX,DI
MOV CL,3
DIV CL    ; AH:= AX MOD 3;
MOV CL,AH
MOV AL,1
SHL AL,CL
AND AL,BL
JZ NADA__
INC BYTE PTR [BP+DI-0300H]
NADA__:
POP CX
RET



; FUNCION INTERNA PON_A_CERO. Pone a cero el valor apuntado por [BP+DI-300h]
; SI SE AJUSTA A LA MASCARA CONTENIDA EN BL.
PON_A_CERO:
PUSH CX
MOV AX,DI
MOV CL,3
DIV CL    ; AH:= AX MOD 3;
MOV CL,AH
MOV AL,1
SHL AL,CL
AND AL,BL
JZ NADA_
MOV BYTE PTR [BP+DI-0300H],0
NADA_:
POP CX
RET


; FUNCION INTERNA PON_A_63. Pone a 63 el valor apuntado por [BP+DI-300h]
; SI SE AJUSTA A LA MASCARA CONTENIDA EN BL.
PON_A_63:
PUSH CX
MOV AX,DI
MOV CL,3
DIV CL    ; AH:= AX MOD 3;
MOV CL,AH
MOV AL,1
SHL AL,CL
AND AL,BL
JZ _NADA_
MOV BYTE PTR [BP+DI-0300H],63
_NADA_:

POP CX
RET



; FUNCION INTERNA SETPAL. Escribe la paleta en partes de 128 colores y esperando
; retrazado vertical cada parte para evitar niebla.
SETPAL:
CLD
PUSH DI
PUSH DS
PUSH CX
PUSH SS
POP DS
PUSH BP
POP SI
SUB SI,300h
MOV DX,03C8H
XOR AL,AL
OUT DX,AL
XOR DI,DI
MOV CX,2
POR_PARTES:
PUSH CX
MOV CX,0180H
MOV   DX,03DAH
LB1:
IN    AL,DX
AND   AL,08H
JNZ   LB1
LB2:
IN    AL,DX
AND   AL,08H
JZ    LB2
MOV DX,03C9H
WRITE:
;MOV AL,BYTE PTR [BP+DI-0300H]
OUTSB
LOOP WRITE
POP CX
LOOP POR_PARTES
POP CX
POP DS
POP DI
RET


; FUNCION INTERNA READPAL. Lee la paleta en el especio de pila reservado
; a efecto.
READPAL:
PUSH CX
PUSH AX         ; Preservo registros
PUSH DI
MOV DX,03C7H
XOR AL,AL
OUT DX,AL
XOR DI,DI
INC DX
INC DX
MOV CX,0300H
READBUC:
IN AL,DX
MOV BYTE PTR [BP+DI-0300H],AL
INC DI
LOOP READBUC
POP DI
POP AX
POP CX
RET


;          ***************  FUNCIONES EXTERNAS *********************

FUNCION00:

MOV CX,003FH
BUC63:
PUSH CX
MOV CX,0300H
XOR DI,DI
BUC768:
MOV AL,BYTE PTR [BP+DI-0300H]
OR AL,AL
JZ YACERO
CALL DECREMENTA
YACERO:
INC DI
LOOP BUC768
CALL SETPAL
POP CX
LOOP BUC63
RET



FUNCION01:
MOV CX,0300H
XOR DI,DI
_BUC768:
MOV AL,BYTE PTR [BP+DI-0300H]
CALL PON_A_CERO
INC DI
LOOP _BUC768
CALL SETPAL
RET

FUNCION02:

MOV CX,003FH
BUC63_:
PUSH CX
MOV CX,0300H
XOR DI,DI
BUC768_:
MOV AL,BYTE PTR [BP+DI-0300H]
CMP AL,03Fh
JZ YAFF
CALL INCREMENTA
YAFF:
INC DI
LOOP BUC768_
CALL SETPAL
POP CX
LOOP BUC63_
RET


FUNCION03:

MOV CX,003FH
_BUC63_:
PUSH CX
MOV CX,02FDH
MOV DI,3
BUC765:
MOV AL,BYTE PTR [BP+DI-0300H]
CMP AL,03Fh
JZ YAFF_
CALL INCREMENTA
YAFF_:
INC DI
LOOP BUC765
CALL SETPAL
POP CX
LOOP _BUC63_
RET

FUNCION04:
MOV CX,02FDH
MOV DI,3
_BUC765_:
MOV AL,BYTE PTR [BP+DI-0300H]
CALL PON_A_63
INC DI
LOOP _BUC765_
CALL SETPAL
RET
