Source file: /~heha/hs/dos/dosmisc.zip/SRC/BEL.ASM

;hoffentlich QEMM-kompatibel
	include	prolog.asm
REQfunc		equ	345h		;in AX
REQcode		equ	9877h		;in DX
ANScode		equ	8766h		;in AX; DX=Segmentadresse
ResPara		equ	(ISRBase-PSPOrg+ISRE-ISRA+0fh)/16

		org	5ch
ISRBase:	;FCB's überschreiben
ctrl0		db	?		;Ein/Aus-Schalter
		org	100h
		print	Text0		;Meldung
		mov	si,81h
		cld
scancl:		lodsb
		cmp	al,'?'
		je	help
		and	al,0dfh		;Upcase
		cmp	al,'U'
		je	UnInst
		cmp	al,'D'
		je	DisActiv
		cmp	al,'H'
		je	help
		cmp	al,0dh
		jne	scancl
		jmp	Install
help:	;Hilfe Option "H" oder "?"
		mov	dx,offset TextH
		jr	TXTO1

UnInst:	;Deinstallation(sversuch) Option "U"
		call	InstChk		;Überhaupt installiert?
		mov	dx,offset Text5
		jnz	TXTO1		;Wenn nicht nötig!
		or	ch,ch
		jz	Raus
		PRINT	Text4
		mov	dx,offset Text4a
disab:		xor	al,al
		jmp	setab
DisActiv:;Deaktivieren Option "D"
		call	InstChk
		mov	dx,ofs Text5
		jnz	TXTO1
		mov	dx,ofs Text4
		jr	disab
	;Deinstallation
Raus:		lds	dx,[es:ofs OldInt10-ISRA+ISRBASE]
		DOS	2510h
		DOS	49h		;den Speicher ab es freigeben
		push	cs
		pop	ds
		mov	dx,ofs Text3	;removed...
TXTO1:		jmp	TXTOut

InstChk:;Installationscheck, ES=Zeiger auf installierte Routine oder n.a.!,
	;Z=1: Installationscheck erfolgreich, dann:
	;ES: Segmentadresse der residenten Routine
	;ch=0: Zeiger nicht von anderen verbogen
		mov	ax,REQfunc	;eigentlich Cursorform ermitteln
		mov	dx,REQcode
		int	10h
		cmp	ax,ANScode	;gleich?
		pushf			;Z-Flag retten
		push	dx		;Segment der TSR
	;Segment retten
		xor	ch,ch
		DOS	3510h		;Get Int10
		SES	<OldInt10>,bx
		cmp	bx,ofs NewInt10-ISRA+ISRBASE
		je	T10OK
		mov	bx,es
		cmp	bx,dx
		je	T10OK
		inc	ch		;ch <>0 wenn andere TSR stört
T10OK:		pop	es
		popf
		ret

;Berechne CPU-Geschwindigkeitsmaß
CalcCPUSpeed:	mov	ax,40h
		mov	es,ax
		xor	ax,ax
		mov	bx,6ch

		mov	dx,[es:bx]	;Zeitzähler 18.2 Hz
TCalc1:		cmp	[es:bx],dx
		je	TCalc1		;Auf Änderung warten, max. 1/18.2 ms
		mov	dx,[es:bx]	;Neuer Wert (hätte auch INC DX genügt)
TCalc2:		inc	ax
		cmp	[es:bx],dx	;auf Änderung warten, genau 1/18.2 ms
		jmp	short $+2
		jmp	short $+2
		jmp	short $+2
		jmp	short $+2	;gegen überschnelle Rechner
		je	TCalc2 		;Schleife
		xor	dx,dx
		mov	bx,37h
		div	bx
		mov	[CPUSpeed],ax
		ret
	;AX: ein Maß für die Taktfrequenz

Install:	call	InstChk		;Installationscheck
		mov	dx,offset Text2	;Schon mal laden
		jz	enab
		call	CalcCPUSpeed
	;ISR nach vorn schaufeln
		cld
		push	cs
		pop	es
		mov	si,ofs ISRA
		mov	di,ofs ISRBase
		mov	cx,(ISRE-ISRA)/2
		rep	movsw
	;Zeiger verbiegen
		mov	dx,ofs NewInt10-ISRA+ISRBASE
		DOS	2510h			;Set Int10
	;Environment freigeben
		mov	es,[2ch]	;Segment Environment
		DOS	49h		;ENV-Speicher ab es freigeben
	;Test des Hochladens
		mov	ax,cs
		mov	es,ax		;Eigenes Programm=Resident!
		cmp	ax,0a000h
		jc	NoHi		;unten
		PRINT	Text1a
NoHi:		mov	dx,offset Text1
	;VB enabeln
enab:		;DX ist schon OK!
		mov	al,80h
setab:		mov	[es:Ctrl0],al	;Bit 7 setzen: enabled
	;dx-adressierten Text ausgeben
TXTOut:		DOS	9		;Textausgabe
	;Programm beenden
		push	dx
		PRINT	_NL
		pop	dx
		cmp	dx,ofs Text1	;Installierung? (etwas seltsam!)
		mov	ax,4C00h
		jnz	exi
		mov	ah,31h		;Resident
		mov	dx,ResPara
exi:		int	21h

errm:		print	Text1
		DOS	4c02h		;Errorlevel 2

ISRA:
		db	?		;CTRL0
Data:		dw	1DE1h,60h,20h	;Tonhöhe, Tondauer, Pausendauer
		dw	0d01h,60h,20h
		dw	0a01h,60h,0
		dw	0
CPUSpeed	dw	?

NewInt10:	;Neue INT10-Routine
NewInt10:	pushf
		cmp	ax,REQfunc
		jne	I10cont
		cmp	dx,REQcode
		jne	I10cont
		mov	ax,ANScode
		mov	dx,cs
		popf
		iret
I10cont:	cmp	ax,0e07h
		je	bel
		popf
		JMPF			;jmp far
OldInt10	dd	?

bel:		push	ax
		push	cx
		push	si
		push	ds
		push	cs
		pop	ds
		sti
		test	[ctrl0],80h
		jz	isrend
		cld
		mov	si,offset data-ISRA+ISRBASE
isrbeg:		cmp	[word si],0	;Ende
		jz	isrend
		mov	al,0B6h
		out	43h,al		;8253 wrt timr mode
		lodsw
		out	42h,al		;8253 timer 2 spkr
		mov	al,ah
		out	42h,al		;8253 timer 2 spkr
		in	al,61h		;8255 port B, read
		or	al,3
		out	61h,al		;8255 B - spkr, etc
		lodsw
		call	WaitAX
		in	al,61h		;8255 port B, read
		and	al,0FCh
		out	61h,al		;8255 B - spkr, etc
		lodsw
		call	WaitAX
		jr	isrbeg

isrend:		pop	ds
		pop	si
		pop	cx
		pop	ax
		popf
		iret

WaitAX:		;wartet ca. AX Millisekunden (?)
		or	ax,ax
		jz	RetWAX
		push	bx
wait1:		xor	bx,bx
wait2:		inc	bx
		cmp	[ofs (CPUSpeed-ISRA)+ISRBASE],bx
		jae	wait2
		dec	ax
		jnz	wait1
		pop	bx
RetWAX:		ret
ISRE:

Text0	db	'BEL 1.1 [QEMM] (haftmann#software): $'
Text1a	db	'hoch$'
Text1	db	'geladen, Speicherbedarf '
	dcd	%((ResPara)*16+16)
	db	' Bytes.$'
Text2	db	'reaktiviert.$'
Text3	db	'vom Speicher entfernt.$'
Text4	db	'deaktiviert.$'
Text4a	db	' (Andere TSR stahl Int10)$'
Text5	db	'Noch nicht installiert!$'
TextH	db	'			++ FREEWARE ++',nl
	db	'Programm zum Aufmöbeln von PC-Speaker-Piepsern.',nl,10
	db	'Parameter:	- (keiner)	TSR laden oder aktivieren',nl
	db	'		- h oder ?	diese Hilfe',nl
	db	'		- d		BEL deaktivieren',nl
	db	'		- u		TSR entfernen$'
_NL	db	nl,'$'

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