Source file: /~heha/hsn/dos/noro.zip/GIVEVER.ASM

;Allgemeines SETVER für genau das Child-Programm
;NEU: Mit Vorgaukelei der TRUE VERSION (Int213306)
;Aufruf: term <DOS-Versionsnummer als x.y oder x> <programmname> <parameter>
;P.S.: Hiermit kann man auch Nicht-EXE-Programme mit MZ-Header
;ohne Umbenennung zum Abarbeiten bringen!
;Außer wenn im Stackinhalt des FAR-Calls Segment
;auf ein PSP mit COMMAND o.ä. zeigt!

	include	prolog.asm
	include	"strings.asm"
	mov	[parseg],ds
	;Kommandozeile abscannen
	cld
	mov	si,81h
	mov	di,80h
	mov	cl,[di]
sk1:	lodsb
	dec	cl
	cmp	al,0dh		;Ende?
	jz	help
	cmp	al,21h
	jc	sk1		;Trennzeichen
	cmp	al,'?'
	jz	help
	sub	al,'0'
	jc	helpE
	cmp	al,0ah
	jnc	helpE
	mov	ah,al		;merken
	lodsb
	dec	cl
	sub	al,' '
	jz	sk2		;Nebenversionsnummer=0 annehmen
	cmp	al,'.'-' '
	jnz	helpE
	lodsb
	dec	cl
	sub	al,'0'
	jc	helpE
	cmp	al,0ah
	jnc	helpE
	 mov	bh,ah		;ah retten
	 mov	bl,10
	 mul	bl
	 mov	ah,bh		;ah holen
	cmp	[byte si],' '
	jz	sk2		;Eine Stelle bedeutet Zehner!!
	 mov	bl,al
	 lodsb
	 dec	cl
	 sub	al,'0'
	 jc	helpE
	 cmp	al,0ah
	 jnc	helpE
	 add	al,bl		;Einerstelle aufaddieren
sk2:	xchg	al,ah
	mov	[GivVer],ax	;für die ISR
sk3:	lodsb
	dec	cl
	cmp	al,' '
	jz	sk3
	dec	si
	inc	cl
	;Versionsnummer gelesen; si zeigt nun auf Dateiname
	jmp	short sk4
helpE:
	PRINT	msgHE
help:	PRINT	msgH
	xor	ax,ax
	jmp	hlp

sk4:	movsb			;um 1 Zeichen vorkopieren
	dec	cl		;immer restliche Zeichen mitzählen
	cmp	[byte si],21h
	jnc	sk4
	;80h steht Dateiname
	;SI= ^Parameter
	;DI= ^Ende Dateiname+1
	dec	si
	mov	[si],cl		;Abschlußzeichen
	;SI= ^Parameter MIT Anzahl Bytes

	mov	[by di],0	;Endekennung
	mov	[parofs],si
	mov	si,80h
	mov	di,ofs ExeName
	call	SeekInPath
        mov     sp,ofs ExeName	;erst DEC, dann Schreiben! (wie Z80)

	ResizeM			;Speicherblockgröße verändern

	push	es
	DOS	3521h		;alten Vektor retten
	ses	<OldInt21>,bx

	;Environment im Vorab absuchen:
	mov	es,[2ch]	;Segment Environment
	xor	di,di
	xor	ax,ax
	cld
	jmp	short lp4

lp3:	mov	cx,8		;Länge von COMSPEC=
	mov	si,offset comsp
	repe	cmpsb		;Vergleichen
	je	found		;gleich
	dec	di
lp1:	scasb
	jnz	lp1
lp4:	cmp	[es:di],al
	jnz	lp3
	jmp	short notfnd	;kein COMSPEC gefunden!
found:
	push	es
	pop	ds		;EX DS,ES (fehlt selbst beim 386er!)
	push	cs
	pop	es
	mov	si,di
vorn:	mov	di,ofs commd	;ins Codesegment - Vorgabe überschreiben
	mov	cx,8
next:	lodsb
	cmp	al,':'
	jz	vorn
	cmp	al,'\'
	jz	vorn
	cmp	al,'/'
	jz	vorn
	cmp	al,'.'
	jz	tail
	or	al,al
	jnz	ntail
tail:	mov	cl,1
	xor	al,al
ntail:	stosb
	loop	next
notfnd:
	pop	es
	push	cs
	pop	ds
	mov	dx,ofs NewInt21
	DOS	2521h		;neuen Vektor setzen

	mov	dx,ofs ExeName
	mov	bx,ofs params
	DOS	4b00h		;starten
	mov	bx,cs
	mov	ss,bx
        mov     sp,ofs ExeName
	mov	ds,bx
	jnc	bye

	push	ax
	 PRINT	msgE
	pop	ax
	call	ahex
bye:
	lds	dx,[OldInt21]
	DOS	2521h		;alte Vektoren rücksetzen
	DOS	4Dh		;Get Exit Code PA: AH=Type, AL=Code
hlp:	DOS	4Ch		;Programmende

NewInt21: ;DOS-Interrupt
	mov	[cs:fkt],ax
	pushf
	CALLF
OldInt21 dd	?
	pushf
	cmp	[by cs:fkt+1],30h ;High-Teil
	jz	dos30
	cmp	[cs:fkt],3306h
	jnz	IntRet
dos30:	push	bp
	mov	bp,sp
	push	ds
	push	es
	push	si
	push	di
	 push	cs
	 pop	ds
	mov	di,[bp+6]
	dec	di		;MCB adressieren!!!
	mov	es,di
	mov	di,8
	mov	si,offset commd
	cld
eql:	cmp	di,10h
	je	uneq		;fertig weil 8 Zeichen
	cmpsb			;identisch? (allerdings ohne UpCase!)
	jnz	uneq
	cmp	[byte si-1],0	;Ende-Null?
	jnz	eql
uneq:	pop	di
	pop	si
	pop	es
	pop	ds
	pop	bp
	je	Intret		;War command.com gewesen, nix gaukeln!
	cmp	[by cs:fkt+1],30h ;Wohin soll die Versionsnummer?
	jz	d30emu
	mov	bx,[cs:GivVer]	;nach BX bei Int213306
	jr	IntRet
d30emu:	mov	ax,[cs:GivVer]	;nach AX bei Int2130
Intret:	popf
	retf	2

;-------------- Allgemeine UP-Sammlung ----------
ahex:	push	ax		;Werte erhalten
	mov	cl,4		;oberes Nibble auf Bit 3...0
	shr	al,cl		; schieben
	call	ahex1
	pop	ax
ahex1:	and	al,0fh
	add	al,90h		;Hex -> ASCII
	daa
	adc	al,40h
	daa
	mov	dl,al
	mov	ah,2
	int	21h
	ret

comsp	db	'COMSPEC='	;exakt 8 Zeichen
commd	db	'COMMAND',0	;exakt 8 Zeichen
	alignv	2
params	dw	0
parofs	dw	80h
parseg	dw	?

GivVer	dw	0
fkt	dw	0
msgE	db	'DOS-Fehler $'

	_STRCPX
	_STRCPR
	_SEEKNAME
	_SEEKEXT
	_GETENV
	_SEEKINPATH
ExeName	db	80 dup (?)	;Puffer fⁿr kompletten Pfad
        align   2
ResEnd:	;Ab hier von Tochter überschreibbar

	org	ExeName

msgHE	db	'Fehler in Kommandozeile!',13,10,'$'
msgH	db	'GiveVer - mehr als nur SETVER.EXE!  Emuliert auch "Wahre DOS-Version"!',13,10
	db	'Version 1.10 von haftmann#software       +++ Public Domain +++',13,10,10
	db	'Gebrauch: givever versionsnummer programmname [parameter]',13,10
	db	'z.B. givever 5.1 geos.exe, also ganz einfach!',13,10
	db	'(Versionsnummernangabe als ''x.yy'', ''x.y'' oder als ''x'')',13,10
	db	'In dieser Version bitte nur *ausführbare* Programme angeben, also z.B.',13,10
	db	'KEINE Batch-Dateien!!!',13,10
	db	'(In Batch-Dateien ist ein Batch-Aufruf wie folgt möglich:',13,10
	db	'  givever 5 %comspec% /C beispiel.bat)',13,10,'$'

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