Source file: /~heha/vt/viewers/vt080.zip/src/v2/INSTCHK.ASM

;Diese Installationschecks ließen durchaus gewollte
;Mehrfachinstallationen zu! Ist nötig, wenn man z.B. 2 gleiche Karten
;besitzt. (identische Hardware, nur unterschiedliche Portadressen)

;Dieses Stück immer im TRANSIENTEN TEIL includen!
;IDEAL-Mode sowie TINY-Modell erforderlich!
;Dieses sehr allgemein gehaltene Stück Source benötigt folgende Variablen
;und Konstanten im RESIDENTEN Teil:

;MUXI	db 0		Die Multiplex-Nummer, 0=Auto-Detect
;			Der Int2F muß bei Aufruf mit AH=MUXI und AL=0
;			MUXRESPONSE (mit al=0) aufrufen und danach IRET.
;AnsCode equ xxxx	16bit Applikations-spezifischer Antwort-Code
;			Dieser muß vom Int2F in BX geliefert werden
;VerCode equ yyyy	16bit Versions-Code, um andere Version zu erkennen
;			Dieser muß vom Int2F in CX geliefert werden
;IntTab	[IntEntry xx]* db 0  Tabelle von Interruptvektoren (*=n Wiederh.)
;			Die Interruptroutinen bekommen bei Verwendung
;			dieses Makros die festen Namen OldIntxx bzw. NewIntxx

;Wenn das Symbol EXE definiert ist, dann noch
;PrefixSeg dw 0		Das PSP-Segment; zur Freigabe des Speichers erforderlich

;*************************************************************************

macro IntEntry nr	;;nr ohne Suffix und GROSS angeben
	db	0&nr&h	;;erst die Nummer in Hex
OldInt&nr dd	0	;;dann ein Platzhalter für den OldInt
     dw  ofs NewInt&nr	;;dann noch der Offset der neuen Int-Routine
endm

macro MuxResponse
	mov	bx,AnsCode
	mov	cx,VerCode
	mov	dx,cs
	mov	si,ofs IntTab	;zur Deinstallation
 ifdef EXE
	mov	di,[cs:PrefixSeg]
 endif
	dec	al		;=FF: installiert!
endm

macro _INSTCHK
proc CheckMux	;PE: AH: Mux-Nummer
		;PA: Z=1: Mux-Nummer okay
	push	ds		;Kann Leben retten!
	 MUX	,0
	pop	ds
	inc	al		;FF?
	jnz	@@e		;nein, nächster...
	cmp	bx,AnsCode	;Spezifischer Code?
@@e:	ret
endp

proc InstChk	;Transient
	;Installationscheck, ES=Zeiger auf installierte Routine oder n.a.!,
	;Bit7(CH)=0: Installationscheck erfolgreich, dann:
	;Bit6(CH)=0: Richtige Version
	;ES: Segmentadresse der residenten Routine
	;Bit3-0(CH): Zähler für verbogene Zeiger
	;PE UND PA: [MUXI]=Multiplex-Nummer (AH zum Int2f)
	;VR: AX,BX,CX,DX,SI,DI,ES,BP
	mov	ah,[MUXI]
	or	ah,ah		;Auto-Detect?
	jz	@@a		;ja!
	call	CheckMux
	jz	@@h		;wenn gefunden dann zum VersionsCheck
	jr	@@g		;sonst NICHT GEFUNDEN vorgeben
	;Start mit Multiplex-Nummer FFh (also von hinten)
@@b:	push	ax
	 call	CheckMux
	pop	ax
	jz	@@c		;ja, gefunden
@@a:	dec	ah
	js	@@b		;FF..80 abtippeln
@@g:	mov	ch,bit 7
	mov	dx,ds
	mov	si,ofs IntTab	;Eigene Adresse, sonst kommt sie vom InstChk!!
	jr	@@d
@@c:
	mov	[MUXI],ah	;gleich mal merken
@@h:	cmp	cx,VerCode	;Versionsnummer okay?
	mov	ch,0
	jz	@@d
	mov	ch,bit 6
@@d:	push	dx		;Segment der residenten Kopie retten
	 jr	@@m		;Fußgesteuerte While-Schleife (ASM-Konstrukt)
@@l:
	 DOS	35h		;Get IntXX
	 SES	[si],bx		;Einziehen
	 cmp	[si+4],bx	;Ziel-Vektor (Vergleich)
	 jnz	@@f
	 mov	bx,es
	 cmp	bx,dx
	 jz	@@o
@@f:	 inc	ch		;ch <>0 wenn andere TSR stört
@@O:	 add	si,6
@@m:	 lodsb			;nächster Int-Vektor
	 or	al,al
	 jnz	@@l		;Alle Ints "eingezogen" und gecheckt
	pop	es		;Aufs eigne oder fremde Segment...
	ret
	endp

proc HookAll
	;- klinkt alle Interrupts ein
	;- gibt das Environment frei, wenn FreeEnv definiert
	;VR: AX,DX,SI
	mov	si,ofs IntTab
	jr	@@m
@@l:
	mov	dx,[si+4]
	DOS	25h		;SetIntXX
	add	si,6
@@m:	lodsb			;nächster Int-Vektor
	or	al,al
	jnz	@@l
ifdef FreeEnv
 ifdef EXE
  ifdef DEV
	mov	ax,[PrefixSeg]
	or	ax,ax
	jz	@@nofree
	mov	es,ax
  else
	mov	es,[PrefixSeg]
  endif
	mov	es,[es:2ch]
 else
	mov	es,[2ch]
 endif
	DOS	49h		;ES=CS annehmen!
@@nofree:
endif
	ret
endp HookAll

proc Unhook	;(transient) ES=Segment resident, wenn EXE nicht definiert
	;- Klinkt alle Interrupts aus
	;- Gibt den belegten Speicher frei
	;VR: AX,DX,SI,DI (,ES)
	MUX	[MUXI],0	;SI-Adresse ermitteln
 ifdef EXE
	mov	es,dx
 endif
	push	ds
	 jr	@@m		;Kopfgesteuert Schleife
@@l:
	 lds	dx,[es:si]
	 DOS	25h		;SetIntXX
	 add	si,6
@@m:	 seges	lodsb		;nächster Int-Vektor
	 or	al,al
	 jnz	@@l
	pop	ds
 ifdef EXE
  ifdef DEV
	or	di,di
	jz	@@e
  endif
	mov	es,di
 endif
	DOS	49h
@@e:
	ret
endp

proc FindFreeMUX c
	;PE: [MUXI] 0=AutoDetect...
	;PA: CY=1: Nichts gefunden oder gegebener Mux. war belegt
	;    CY=0: [MUXI] enthält gefundenen Mux-Kanal
 uses bx,cx,dx			;Nichts anbrennen lassen!
	mov	ah,[MUXI]
	xor	al,al
	or	ah,ah		;Auto Detect?
	jz	@@s		;ja, freien Muxer suchen
	push	ds es
	 MUX			;Test ob Muxer auch frei ist
	pop	es ds
	add	al,0ffh		;CY=0 wenn AL=0, sonst 1
	jr	@@e		;ggf. "Nichts frei" melden!
@@s:
	mov	ah,80h
@@l:	push	ax
	 push	ds es		;Nicht die Hosen runterlassen!
	  MUX
	 pop	es ds
	 or	al,al		;frei?
	 jz	@@1		;ja!
	pop	ax
	inc	ah		;nächster Versuch!
	jnz	@@l
	stc
	jr	@@e		;Nichts frei
@@1:	pop	ax
	mov	[MUXI],ah
@@e:	ret
endp FindFreeMUX

endm
Detected encoding: OEM (CP437)1
Wrong umlauts? - Assume file is ANSI (CP1252) encoded