;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
|
|