home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC Interdit
/
pc-interdit.iso
/
graph
/
modexlib.asm
< prev
next >
Wrap
Assembly Source File
|
1994-10-08
|
14KB
|
431 lines
.286
w equ word ptr
b equ byte ptr
data segment public
extrn vscreen:dword
extrn vpage:word
extrn palette:dataptr
data ends
code segment public
assume cs:code,ds:data
public init_modex, p13_2_modex, squeeze, copyscreen, double
public clrx, split, setpal, getpal, switch, setstart, enter400
public waitretrace, fade_out, fade_to, copy_block, pal_rot
switch proc far ;schaltet zw. beiden Bildschirmseiten um
mov bx,vpage ;Startadresse laden
mov dx,3d4h
mov al,0ch ;auf CRTC-Register 0dh/0ch aufteilen
mov ah,bh
out dx,ax ;Highbyte setzen (Register 0dh)
inc al
mov ah,bl
out dx,ax ;Lowbyte setzen (Register 0ch)
cmp bx,16000d ;Startadresse umschalten (0/16000)
je setze0
mov vpage,16000
ret
setze0:
mov vpage,0
ret
switch endp
Init_ModeX proc pascal far ;schaltet Mode X ein
mov ax,0013h ;Mode 13h setzen
int 10h
mov dx,3c4h ;Timing Sequenzer
mov al,4 ;Register 4 (Memory Mode):
out dx,al ;Bit 3 löschen -> Chain4 aus
inc dx
in al,dx
and al,0f7h
or al,4h ;Bit 2 setzen -> Odd/Even Mode aus
out dx,al
dec dx
mov ax,0f02h ;Register 2 (Write Plane Mask):
out dx,ax ;0fh: alle Planes beim Schreiben ein
mov ax,0a000h ;Bildschirmspeicher löschen
mov es,ax
xor di,di
xor ax,ax
mov cx,0ffffh
cld
rep stosw
mov dx,3d4h ;CRTC
mov al,14h ;Register 14h (Underline Row Adress):
out dx,al
inc dx
in al,dx ;Bit 6 löschen -> Doubleword adress. aus
and al,0bfh
out dx,al
dec dx
mov al,17h ;Register 17h (CRTC Mode):
out dx,al ;Bit 6 setzen -> Byte Mode ein
inc dx
in al,dx
or al,40h
out dx,al
ret
Endp
Enter400 proc pascal far ;active le mode X (200 lignes)
mov dx,3d4h ;et l'étend sur 400 ligness
mov al,9 ;Registre 9 de CRTC (Maximum Row Adress)
out dx,al ;sélectionne le registre
inc dx ;Lit le contenu
in al,dx
and al,01110000b ;Met à 0 les bits 7 et 3
out dx,al ;renvoie la nouvelle valeur
ret
Enter400 endp
plan_l: db 0
plan_pos: dw 0
p13_2_modex proc pascal far start,pic_size:word
mov dx,03ceh ;fixe Write Mode 0
mov ax,4005h ;sous le registre GDC 5 (GDC Mode)
out dx,ax
mov b plan_l,1 ;mémorise le masque de plan
push ds
lds si,dword ptr ds:vscreen ;charge l'adresse source
mov w plan_pos,si ;et la sauvegarde
mov ax,0a000h ;fixe l'adresse de destination
mov es,ax
mov di,start
mov cx,pic_size ;lit le nombre de pixels
@lpplan:
mov al,02h ;dans le Registre 2 du TS (Write Plane Mask)
mov ah,b plan_l ;masque le plan
mov dx,3c4h
out dx,ax
@lp1:
movsb ;copie un byte
add si,3 ;prochain byte source
loop @lp1
mov di,start ;relit l'adresse de destination
inc w plan_pos ;nouvelle adresse source
mov si,w plan_pos
mov cx,pic_size ;lit la taille
shl b plan_l,1 ;masque le plan suivant
cmp b plan_l,10h ;les 4 plans sont copiés ?
jne @lpplan
pop ds
ret
Endp
Split proc pascal far row:byte ;fractionne l'écran à la ligne row
mov bl,row
xor bh,bh
shl bx,1 ;*2 à cause du dédoublement des lignes
mov cx,bx
mov dx,3d4h ;CRTC
mov al,07h ;Registre 7 (Overflow low)
out dx,al
inc dx
in al,dx
and al,11101111b ;met le Bit 8 de la ligne dans le bit 4
shr cx,4
and cl,16
or al,cl
out dx,al ;écriture
dec dx
mov al,09h ;Registre 9 (Maximum Row Adress)
out dx,al
inc dx
in al,dx
and al,10111111b ;charge le bit 6 avec le bit 9 de la ligne
shr bl,3
and bl,64
or al,bl
out dx,al ;écriture
dec dx
mov al,18h ;Registre 18h (Line Compare/Split Screen)
mov ah,row ;fixe les 8 autres bits
shl ah,1
out dx,ax
ret
Endp
SetStart proc pascal far t:word ;setzt Bildschirmstart auf angegebene Adr.
mov dx,3d4h ;CRTC
mov al,0ch ;Register 0ch(Linear Starting Adress Middle)
mov ah,byte ptr t + 1 ;Bits 15:8 setzen
out dx,ax ;Register 0dh(LSA Low)
mov al,0dh ;Bits 7:0 setzen
mov ah,byte ptr t
out dx,ax
ret
Endp
WaitRetrace proc pascal far
mov dx,3dah ;Input Status Register 1
@wait1:
in al,dx ;Bit3 = 0 si le rayon est en train de
test al,08h ;dessiner l'image de l'écran
jnz @wait1
@wait2:
in al,dx ;Bit3 = 1 si le rayon est en retour de
test al,08h ;balayage
jz @wait2
ret ;le rayon est en bas de l'écran
Endp
public squeeze
squeeze proc pascal far ;compose un écran à partir de deux moitiés
mov si,200*80 ;première adresse de début
mov di,199 ;première valeur de la ligne de fractionnement
sqlp: ;boucle principale
call waitretrace ;attend le retour de balayage
call split pascal, di ;crée la moitié inférieure par fractionnement
call setstart pascal, si ;crée la moitié supérieure par défilement
sub si,80 ;une ligne vers le bas
dec di ;diminue la ligne de fractionnement
cmp di,99d ;ce qui remonte la moitié inférieure
jae sqlp ;fini ?
ret
squeeze endp
clrx proc pascal far pmask:byte ;Löscht Mode X - Seiten
mov al,02h
mov ah,pmask
mov dx,3c4h
out dx,ax
mov ax,0a000h ;Startadresse und Länge holen
mov es,ax
mov di,vpage
xor ax,ax
mov cx,8000
rep stosw ;und löschen
ret
clrx endp
copyscreen proc pascal far ziel,quelle:word
mov dx,3c4h ;alle Planes selektieren
mov ax,0f02h
out dx,ax
mov dx,3ceh ;Write-Mode 1 (kopieren)
mov ax,4105h
out dx,ax
push ds
mov ax,0a000h ;Quell- und Zielsegment im VGA
mov es,ax
mov ds,ax
mov si,quelle ;Quell- und Zieloffset laden
mov di,ziel
mov cx,16000d ;16000 Byte (=64000 Pixel) kopieren
rep movsb
pop ds
mov dx,3ceh ;Write-Mode 0
mov ax,4005h
out dx,ax
ret
copyscreen endp
SetPal proc pascal far
push si
mov si,offset palette ;Adresse holen
mov cx,256*3 ;Anzahl Farben holen
xor al,al
mov dx,03c8h ;External Palette RAM, Pixel Write Adress
out dx,al ;ab Farbe 0 setzen
inc dx ;Pixel Color Value
rep outsb ;alle Farben an VGA schicken
pop si
ret
Endp
getpal proc pascal far
push di
mov di,offset palette ;Adresse holen
mov cx,256*3 ;Anzahl Farben holen
xor al,al
mov dx,03c7h ;External Palette RAM, Pixel Read Adress
out dx,al ;ab Farbe 0 lesen
mov dx,3c9h ;Pixel Color Value
rep insb ;alle Farben an VGA schicken
pop di
ret
Endp
double proc pascal far
mov dx,3d4h ;registre 13h du CRTC (Row Offset)
mov ax,5013h ;positionné à 80 (largeur double)
out dx,ax ;et écriture
ret
double endp
fade_out proc pascal far ;fondu de fermeture, dépend du mode vidéo
local maxcoul:word ;couleur de valeur maximale
mov maxcoul,63
mov ax,ds ;charge le segment de segmentation
mov es,ax
main_loop: ;boucle principale parcourue une fois par image
lea si,palette ;source et destination sur palette
mov di,si
mov cx,768 ;768 octets à modifier
lp:
lodsb ;lit une couleur
dec al ;la décrémente
jns fixe ;si pas encore négative, la réinstalle
xor al,al ;sinon 0
fixe:
stosb ;écrit la couleur
dec cx ;compteur d'itérations
jne lp
call waitretrace ;synchronisation
call setpal ;prend en compte la palette calculée
dec maxcoul ;décrémente la boucle extérieure
jne main_loop ;Pas fini ? on continue
ret
fade_out endp
fade_to proc pascal far destpal:dword, longueur:word, pas:byte
;transforme progressivement la palette "Palette" en "DestPal" transmis
;par Pascal comme Array of Byte
local maxcoul:word
mov ax,63 ;calcule le nombre d'itérations nécessaires
div pas ;pour atteindre 63
xor ah,ah
mov maxcoul,ax ;mémorise le nombre d'itérations
next_frame:
les di,destpal ;cherche l'offset, Pascal transmet les tableaux en mode far
lea si,palette ;cherche l'offset de "Palette"
mov cx,768 ;768 octets à traiter
suite:
mov al,[si] ;lit une palette dans la palette courante
mov ah,[di] ;lit la couleur de destpal
mov bl,ah
sub bl,al ;différence de plus
cmp bl,pas ;d'un pas ?
jg plus ;-> décrémente
neg bl ;Différence de plus d'un pas
cmp bl,pas ;en négatif ?
jg moins
mov al,ah ;destination atteinte, on fixe la couleur
ecrire:
dec cx ;décrémente boucle des couleurs
je fini ;0 ? -> fini
mov [si],al ;écrit la couleur dans la palette
inc si ;couleur suivante
inc di
jmp suite ;on continue
moins:
sub al,pas ;décrémentation
jmp ecrire
plus:
add al,pas ;incrémentation
jmp ecrire
fini: ;palette calculé
call waitretrace ;synchronisation
call setpal ;réalise la palette
dec maxcoul ;a-t-on fait 63 itérations ?
jne next_frame ;non -> suite
ret
fade_to endp
copy_block proc pascal far destination,source,largeur,hauteur:word
local interligne:word
mov dx,3ceh ;GDC
mov ax,4105h ;Mode de lecture 0, Mode d'écriture 1
out dx,ax ;émis sur le registre 5 : GDC Mode
mov dx,3c4h ;TS
mov ax,0f02h ;active tous les plans
out dx,ax ;émis sur le registre 2 : Write Plane Mask
push ds
mov ax,0a000h ;copier à l'intérieur de VGA
mov es,ax ;-> les deux segments à 0a000h
mov ds,ax
mov si,source ;données d'origine
mov di,destination ;copiée en destination
mov dx,hauteur ;copie "hauteur" ligne
mov ax,80 ;calcul l'intervalle entre deux lignes
sub ax,largeur ;(= 80-largeur)
mov interligne,ax
line_lp:
mov cx,largeur ;charge la largeur
rep movsb ;copie une ligne
add si,interligne
add di,interligne
dec dx ;compteur de lignes
jne line_lp
pop ds
ret
copy_block endp
Pal_Rot proc pascal far Start,Ende:Word
;effectue une rotation sur unepartie de la palette de Debut à Fin
;avec décalage de 1
;si Debut < Fin : Rotation vers le bas
;si Debut > Fin : Rotation vers le haut
mov ax,ds ;es doit pointer sur le segment de données
mov es,ax
lea si,palette ;charge l'offset de la palette
mov di,si ;en si et di
mov ax,3 ;"convertit Début en offset de palette
mul start
add si,ax ;ajoute à si
mov ax,3 ;la même chose pour la fin
mul ende
add di,ax ;ajoute à di
mov bx,[si] ;sauvegarde les octets de la couleur du début
mov dl,[si+2]
mov cx,di ;la différence entre Debut et Fin
sub cx,si ;donne le nombre d'octets à copier
mov di,si ;couleur de début comme offset de destination
add si,3 ;une couleur plus loin comme offset source
;prêt pour la copie
cld ;a priori copie vers l'avant
or cx,cx ;si cx négatif (Debut > Fin)
jns enavant
std ;alors copir vers l'arrière
neg cx ;on corrige cx
sub si,4 ;si sur le 2ème octet de l'avant dernière couleur
add di,2 ;di sur le 2ème octet de la dernière couleur
add cx,2 ;copie 2 octets supplémentaires
enavant: ;pour que, après la boucle de copie, la position soit correcte
rep movsb ;copie les couleurs
mov [di],bx ;les octets de l'ancienne couleur de Debut
mov [di+2],dl ;deviennent la dernière couleur
cld ;remet à 0 l'indicateur de direction
ret
Pal_Rot Endp
code ends
end