Win3x.Org

Windows & DOS Community

[propose]Disquette de l'ouvrage « Guide Microsoft de la programmation des cartes graphiques » & « PC Graphics Handbook »

Règles du forum

Ce forum sert à contribuer au site ou faire une demande de contribution. Pour proposer un programme, suivez simplement le guide en trois étapes !
Les présentations des différents programmes ne sont pas figées : si vous pensez pouvoir les améliorer, n'hésitez pas à proposer votre version !

Répondre   Page 1 sur 1  [ 6 messages ]
Auteur Message
gm86
Sujet du message : Re: [propose]DOS : Disquette de l'ouvrage « Guide Microsoft de la programmation des cartes graphiques »
Publié : 16 févr. 2020 21:27
Membre inscrit
Avatar de l’utilisateur
Hors-ligne
 
Messages : 644
Inscription : 01 sept. 2008 19:07
 
Dans ce cas, ne la perdez pas : lien auto-destructible.

Note : le programme d'interruption verticale s'attend à ce qu'on assigne l'IRQ 2 à la carte EGA/VGA (IRQ9 par redirection sur le PC/AT).


Dimanche 9 février 2000

J'ai corrigé le listing 12-1 en rapport avec cette interruption verticale. Comme dit dans l'ouvrage PC Graphics Handbook, il faut que le handler soit non-réentrant. Dorénavant, l'ISR ne doit plus planter.

D'ailleurs, il y a deux méthodes pour utiliser l'interruption verticale sur notre matériel moderne :
- forcer le port PCI sur l'IRQ 9 (les anciens BIOS partagent le premier port avec l'AGP) si aucune carte ISA PnP ne l'exploite (MIDI par ex.) ;
- modifier le listing pour exploiter l'IRQ selon qu'elle est 8 ou 16 bits.
Bien sûr, on suppose que la carte vidéo gère l'IRQ ou que le BIOS lui en attribue une (le programme ne marche qu'en mode DOS).


Le dimanche d'après

J'ai ajouté un listing corrigé. Je vous propose donc une nouvelle archive à la place. 12-1.ASM est adaptable à présent :
	TITLE	'Listing 12.1'
	NAME	VREGA
	PAGE	55,132

;
; Nom :	VREGA
;
; Fonction:	Routine d'interruption verticale pour EGA et VGA
;
; Appelant:	Microsoft C:
;
;		int EnableISR0A ();	/* retourne 0 si bien installée */
;
;		void DisableISR0A ();
;

; Une carte VGA PnP peut se voir attribuer une ligne IRQ autre que 2/9 :
IRQ		EQU	2	; le PC/AT redirige la ligne IRQ2 sur 9.

if IRQ lt 2 or IRQ eq 6 or IRQ eq 8 or IRQ eq 13	; PIT/KBD/FDC/RTC/FPU
if1
%out Ligne IRQ réservée !
%out Assemblage interromptu.
endif
else

CRT_MODE	EQU	49h	; adresses de la zone des informations
ADDR_6845	EQU	63h	;   vidéo du BIOS

DGROUP	GROUP	_DATA

_TEXT	SEGMENT	byte public 'CODE'
	ASSUME	cs:_TEXT,ds:DGROUP

ISR0A	PROC	far	; handler d'interruption pour l'INT 0Ah

	push	ax	; préservation registres
	push	dx
	push	ds

	mov	ax,seg DGROUP
	mov	ds,ax	; DS -> DGROUP
if IRQ ge 8 and IRQ ne 9
	mov	al,20h
	out	0A0h,al	; EOI au PIC esclave du PC/AT
endif

; Voir si c'est bien une interruption verticale

	mov	dx,3C2h	; DX := port d'E/S pour le
			;   registre 0 d'état des entrées
	in	al,dx
	test	al,80h	; tester le bit 7 du reg. d'état
	jnz	L10	; saut si interruption verticale

; Ce n'est pas une interruption verticale. On chaîne donc le traitement
;   vers l'ancien handler

if IRQ lt 8 and IRQ ne 2
	mov	al,20h
	out	20h,al	; EOI au PIC maître du PC/AT
endif
	pushf		; simuler une INT
	call    ds:PrevISR0A    ;  vers l'ancien handler de l'Int 0Ah
	jmp	short Lexit

; Traiter une interruption verticale

L10:	mov	dx,Port3x4	; DX := 3B4h or 3D4h

	in	al,dx	; AL := valeur du reg. adresse du CRTC
	push	ax	; la sauvegarder

	mov	ax,DefaultVREnd	; AH := valeur par défaut pour reg. VR End
			; AL := 11h (numéro du registre)
	and	ah,11101111b	; AH bit 4 := 0 (RAZ latch d'interruption)
	out	dx,ax	; modifier le registre VR End
	jmp	$+2	; laisser un peu de temps au CRTC
	sti		; activer les interruptions

; Faire quelque chose d'utile...

	inc	word ptr _VRcount	; incrémenter un compteur

; Envoyer un signal de fin d'interruption au PIC Intel 8259A pour 
;   autoriser les interruptions sur IRQ2 suivantes

	cli		; désactiver les interruptions
	mov	al,20h	; port du 8259A
	out	20h,al	; envoyer un EOI non spécifique au 8259A
	jmp	$+2	; attendre sa réponse

; Permettre au CRTC de produire d'autres interruptions

	mov	ax,DefaultVREnd	; AH := valeur par défaut pour le reg. VR End
			; AL := 11h (numéro du registre)
	and	ah,11011111b	; AH bit 5 := 0 (autoriser int. verticale)
	or	ah,00010000b	; AH bit 4 := 1 (activer le latch
	out	dx,ax	;   d'interruption)
	jmp	$+2

	pop	ax
	out	dx,al	; restaurer précédente adresse registre

Lexit:	pop	ds	; restauration registres et retour
	pop	dx
	pop	ax
	iret

ISR0A	ENDP


;
; EnableISR0A -- Activer un handler d'Interruption
;
		PUBLIC	_EnableISR0A
_EnableISR0A	PROC	near

	push	bp	; préservation registres
	mov	bp,sp
	push	si
	push	di

	mov	ax,40h
	mov	es,ax	; ES -> zone des infos vidéo du BIOS

; Sauver les valeurs des registres du CRTC

	mov	dx,es:[ADDR_6845]	; DX := adresse du port CRTC
	mov	Port3x4,dx	; sauvegarder l'adresse

	mov	ax,1A00h	; AH := 1AH (numéro fonction INT 10H)
			; AL := 0 (lire combinaison d'affichage)
	int	10h	; AL := 1AH si fonction 1AH supportée
			; BL := sous-système vidéo actif
	cmp	al,1Ah
	jne	L20	; saut si pas VGA

	cmp	bl,7
	je	L21	; saut si VGA

	cmp	bl,8
	je	L21	; saut si VGA

	mov	ax,0FFFFh	; renvoyer 0FFFFh si ni EGA ni VGA
	jmp	short L23

; Obtenir la valeur par défaut pour le registre EGA Vertical Retrace End

L20:	mov	al,es:[CRT_MODE]  ; AL := numéro du mode video du BIOS
	mov	bx,offset DGROUP:EGADefaultVals
	xlat			; AL := valeur par défaut pour le reg. VR End
	jmp	short L22
 
; Obtenir la valeur par défaut pour le registre VGA Vertical Retrace End

L21:	mov	al,VREndReg	; AL := numéro du registre VR End
	out	dx,al
	inc	dx		; DX := 3B5H or 3D5H
	in	al,dx		; AL := valeur courante de ce registre

L22:	mov	VREndValue,al	; la sauvegarder

; Sauvegarder l'ancien vecteur d'interruption 0Ah

if IRQ eq 9
	mov	ax,350Ah	; AH := 35H (numéro de la fonction INT 21h)
				; AL := 0AH (numéro de l'interruption)
else
if IRQ ge 8
	mov	ax,3570h+IRQ-8
else
	mov	ax,3508h+IRQ
endif
endif
	int	21h		; ES:BX := précédent vecteur de l'Int 0AH

	mov	word ptr PrevISR0A,bx
	mov	word ptr PrevISR0A+2,es	; le sauvegarder

; Modifier le vecteur d'interruption avec l'adresse du présent handler

	push	ds		; préserver DS
	mov	dx,offset ISR0A
	push	cs
	pop	ds		; DS:DX -> ISR0A
if IRQ eq 9
	mov	ax,250Ah	; AH := 25H (numéro de fonction de l'Int 21H)
				; AL := 0AH (numéro interruption)
else
if IRQ ge 8
	mov	ax,2570h+IRQ-8
else
	mov	ax,2508h+IRQ
endif
endif
	int	21h		; modifier le vecteur d'interruption Int 0AH
	pop	ds		; restaurer DS

; Réactiver IRQ2 en mettant à 0 le bit 2 du registre de masque du 8259A

	cli			; verrouiller les interruptions
if IRQ eq 9
	mov	dx,21h		; DX := registre de masque du 8259A
	in	al,dx		; AL := valeur présente
	and	al,11111011b	; RAZ bit 2
else
if IRQ ge 8
	mov	dx,0A1h
	in	al,dx
	and	al,not(1 shl (IRQ-8))
else
	mov	dx,21h
	in	al,dx
	and	al,not(1 shl IRQ)
endif
endif
	out	dx,al

; Réactiver les interruptions verticales

	mov	dx,Port3x4	; DX := 3B4H or 3D4H
	mov	ax,DefaultVREnd

	and	ah,11001111b
	out	dx,ax		; RAZ bits 4 et 5 du registre VR End
	jmp	$+2		; laisser le temps au CRTC
	or	ah,00010000b
	out	dx,ax		; mise à 1 du bit 4
	jmp	$+2
	sti			; réactiver les interruptions

	xor	ax,ax		; AX := 0 (valeur de retour)

L23:	pop	di		; restauration registres et retour
	pop	si
	mov	sp,bp
	pop	bp
	ret

_EnableISR0A	ENDP


;
; DisableISR0A -- Désactiver le handler d'interruptions verticales
;
	PUBLIC	_DisableISR0A
_DisableISR0A	PROC	near

	push	bp
	mov	bp,sp
	push	si
	push	di
	push	ds

; Désactiver les interruptions verticales

	cli			; verrouiller les interruptions
	mov	dx,Port3x4
	mov	ax,DefaultVREnd
	out	dx,ax		; restaurer le reg. Vertical Retrace End
	jmp	$+2
	sti			; réactiver les interruptions

; Restaurer le précédent handler du vecteur d'interruption 0Ah

	lds	dx,PrevISR0A	; DS:DX := précédent vecteur Int 0AH
if IRQ eq 9
	mov	ax,250Ah	; AH := 25H (numéro fonction INT 21H)
				; AL := 0AH (numéro interruption)
else
if IRQ ge 8
	mov	ax,2570h+IRQ-8
else
	mov	ax,2508h+IRQ
endif
endif
	int	21h

	pop	ds		; restauration registres et retour
	pop	di
	pop	si
	mov	sp,bp
	pop	bp
	ret

_DisableISR0A	ENDP

_TEXT	ENDS


_DATA	SEGMENT	word public 'DATA'

	EXTRN	_VRcount:word	; déclaré dans le pgm C qui appelle

PrevISR0A	DD	?	; zone de sauvegarde pour l'ancien 
				;   vecteur d'interruption 0Ah
Port3x4		DW	?	; 3B4h ou 3D4h

DefaultVREnd	LABEL	word
VREndReg	DB	11h	; numéro registre Vertical Retrace End
VREndValue	DB	?	; valeur par défaut pour reg.VR End

EGADefaultVals	DB	2Bh,2Bh,2Bh,2Bh,24h,24h,23h,2Eh	; valeur par défaut
		DB	00h,00h,00h,00h,00h,24h,23h,2Eh ;   pour registre EGA
		DB	2Bh				;   EGA VR End

_DATA	ENDS

endif

	END


Jeudi 20

Petite modification du fichier 12-2.C pour éviter le retour à la ligne en mode 40 caractères :
/* Listing 12.2 */

int VRcount = 0;	/* compteur d'interruptions verticales */

void main ()
{
  if (EnableISR0A ())
  {
    printf ("\nImpossible d'activer le handler d'interruptions verticales\n");
    exit (1);
  }

  while (VRcount < 600)
  printf ("\015Nombre d'interruptions verticales : %d", VRcount);

  DisableISR0A ();
}


Voici une procédure pour quiconque puisse tester :
  • Installer QuickC 2.51 (with QuickAssembler).
  • Sélectionner comme courant le répertoire contenant les fichiers 12-2.C et 12-1.ASM ensemble.
  • Taper c:\qc25\bin\new-vars et lancer c:\qc25\bin\qc 12-1.asm via l'invite de commande DOS.
  • Modifier, si nécessaire, la ligne IRQ affichée avec le numéro qu'attribue le BIOS à la carte VGA (display adapter).
  • Activer Options/Full Menus.
  • Choisir Make/Set Program List.
  • Entrer VREGA, puis confirmer par Yes.
  • Choisir 12-1.ASM dans File List puis entrer 12-2.C dans File Name.
  • Enregister avec Save List.
  • Confirmer l'enregistrement de 12-1.ASM par Yes.
  • Choisir Make/Build Program pour compiler 12-2.C, assembler 12-1.ASM et les lier.
  • Hors Windows, lancer l'exécutable VREGA.EXE obtenu.
  • Ne pas interromptre par ^C ou Break !
Samedi 29

Ajout du 13ème point portant malheur à la stabilité du système...
Le programme désinhibe puis réinhibe les interruptions avant l'envoi d'un EOI au PIC (maître sur PC/AT).

Vendredi 20 mars

Ne soyez pas trop cons d'assembler avec la première version d'ASM ou MASM d'IBM : la pseudo-opérateur SHL sera plus qu'une pseudo-instruction avec mon code...

Dernière remontée par gm86 le 16 févr. 2020 21:27.

_________________

C:\ONGRTLNS.W95


Haut
Profil
Afficher : Trier par : Ordre :
Répondre   Page 1 sur 1  [ 6 messages ]
Revenir à « Contributions »
Aller :