Quelltext /~heha/hs/dos/dosmisc.zip/SRC/REC202.ASM

		.8086
		.MODEL	tiny
		.CODE
		IDEAL
PSPAdr:
Deutsch		equ	1		;Deutsch eingeschaltet
					;Ausschalten durch Auskommentierung
		org	0e6h
StkOfs		dw	?
StkSeg		dw	?
MaxFiles	dw	?		;Anzahl Datensätze, default 100
MemAX		dw	?
AdrFiles	dw	?
NameBuf		db	11 dup (?)	;ab in die Kommandozeile!
ExecFlag	db	?
MemSI		dw	?
EndAdr		dw	?
start:		jmp	Start1

RecLng		equ	22
;Aufbau des Datensatzes: (Gesamtlänge 16h = 22 Bytes)
;8 Byte Name			+0
;3 Byte Typ			+8
;1 Byte Angezeigt-Flag		+0bh
;2 Byte Such-Zugriffe		+0ch
;2 Byte Öffnungs-Zugriffe	+0eh
;2 Byte Lesezugriffe		+10h
;2 Byte Schreibzugriffe		+12h
;2 Byte Exec-Zugriffe		+14h


NewInt21:	pushf
		 sti
		 cmp	ax,0f748h
		 jne	KennFlt
		 cmp	dx,3abch
		 jne	KennFlt
		 mov	ax,0cba3h
		 mov	dx,cs
		popf
		iret
KennFlt:
		 cmp	[cs:ExecFlag],1		;Reentranter Aufruf?
		 jge	ToOldInt21		;ja-fertig
;Solche Semaphoren haben ihre Tücken, wenn es darum geht, daß
;einige DOS-Aufrufe nie oder arg verzögert zurückkehren, und zwar
;die INT 31h, 4Bh und 4Ch, nebenbei auch 00h, wird aber vorher
;herausgefiltert
		 cmp	ah,0fh			;Konsolzugriffe?
		 jc	ToOldInt21		;ja-fertig
		 cmp	ah,57h			;Sonstige Zugriffe?
		 jc	access			;ja!
ToOldInt21:	popf
CallOldInt21:	db	0eah			;JMP FAR
OldInt21	dd	?			;geretteter Int21

acctbl:		;Suchtabelle, Aufbau:
		;- n Bytes Funktionsnummer
		;- 1 Nächste Zugriffsart
		;- 0 Ende Tabelle
		db	11h,17h,4eh,56h,1	;Suchen
		db	0fh,16h,3ch,3dh,3eh,1	;Öffnen
		db	14h,21h,23h,27h,3fh,44h,1 ;Lesen
		db	13h,15h,22h,28h,40h,41h,1 ;Schreiben
		db	4bh,0			;Ausführen (Laden)

access:		;Zugriffs-Zweig
		inc	[cs:ExecFlag]	;Semaphore Verlegter Stack
		mov	[cs:stkseg],ss
		mov	[cs:stkofs],sp	;Ganz sicher gehen
		push	cs		;(evtl. unnötig)
		pop	ss
		mov	sp,(offset stkofs) ;Erst DEC, dann PUSH?
		  push	ax
		  push	bx
		  push	cx
		  push	dx
		  push	si
		  push	di
		  push	es
		  push	ds
		   push	cs
		   pop	ds			;Code=Daten
		mov	[MemAX],bx	;Handle
		mov	cx,ax		;retten
		mov	si,offset acctbl
		cld
		mov	bx,0ch		;mit Suche beginnen
sktbl:		lodsb
		cmp	al,1		;Kennung nächstes BX
		jnz	sctbl1
		add	bx,2
sctbl1:		cmp	ah,al
		je	acc
		or	al,al
		jnz	sktbl
acce:   	  pop	ds
		  pop	es
		  pop	di
		  pop	si
		  pop	dx
		  pop	cx
		  pop	bx
		  pop	ax
		  mov	ss,[cs:stkseg]
		  mov	sp,[cs:stkofs]
test1:
		cmp	ah,3ch
		je	acchdl		;Bei diesen Funktionen
		cmp	ah,3dh		;nachher Handlenummer
		je	acchdl		;abfangen und eintragen
		dec	[cs:ExecFlag]
		jmp	ToOldInt21

acchdl:		popf
		;Alles wie frisch nach dem Aufruf
		pushf			;wichtig!!
		 cli	;???
		 push	cs		;weil nachfolgendes CALL
		 call	CallOldInt21	;NEAR ist
		 sti	;ganz wichtig, sonst Verklemmung bei Spielen!!!
		pushf
		jc	reti
		push	cx
		cmp	ax,5		;Standardhandle?
		jb	popreti		;ignorieren
		;Nun Handle eintragen, ax=Handle, [MemSI]=^Record
		push	si
		push	di
		mov	si,[cs:MemSI]
		or	si,si		;volle Tabelle?
		jz	fullreti
		mov	di,offset ImmHandles
		mov	cx,30
hdlsklp:	cmp	[word ptr cs:di],0 ;frei?
		jz	hdlsk1
		add	di,4
		loop	hdlsklp
		mov	di,offset ImmHandles
hdlsk1:		mov	[cs:di],ax	;Handle-Nummer
		mov	[cs:di+2],si	;Basisadresse
fullreti:	pop	di
		pop	si
popreti:	pop	cx
reti:		dec	[cs:ExecFlag]
		popf
		retf	2


acc:		;Tatsächlicher Zugriff
		cmp	ah,44h		;Gerätetreiber
		jnz	acc1
		cmp	cl,3
		jz	acc1
		cmp	cl,2		;Schreiben?
		jnz	acce2a		;Kein Zugriff
		add	bx,2		;Richtigen Zugriff einstellen

acc1:		;Wirklicher Zugriff, bx=Ablage von Basis
		;[MemAX]=Handle, CX=Funktion, (SP):DX=Name bzw. FCB-Adr.
		;ah=Funktion High
		;Ausgabe: [MemSI]=Recordzeiger, Record-Eintrag
		cmp	ah,3dh		;Öffnen?
		je	acch
		cmp	ah,3ch		;Erstellen?
		je	acch
		cmp	ah,4bh		;Execute?
		je	acch
		cmp	ah,4eh		;FindFirst?
		jne	acch2
acch:		;Name suchen
		pop	ds
		push	ds
		call	SetEntry	;ah=Funktionsnummer
acch3:		mov	[MemSI],si	;DS wieder eigen!
		jc	acce2a		;Fehler: Tabelle voll
;		push	ax
;		mov	ax,0e23h
;Test-		int	10h
;zweck		pop	ax
		inc	[word ptr bx+si]
		jnz	acce2a		;Kein Überlauf
		dec	[word ptr bx+si]
acce2a:		jmp	acce

acch2:		mov	ax,[MemAX]	;Handle
		cmp	ax,5		;Standardhandle?
		jb	acce2a		;ja
		mov	di,offset ImmHandles
		mov	dx,cx
		mov	cx,30
skhandle:	cmp	ax,[di]
		je	fndhandle
		add	di,4
		loop	skhandle
		jmp	short acce2a

fndhandle:	cmp	dh,3Eh		;Schließen (Handle)?
		jne	NoClose
		mov	[word ptr di],0
NoClose:	mov	si,[di+2]	;Zugehöriges Datenfeld
		clc
		je	acce2a		;bei Close kein Eintrag!
		jmp	acch3		;weiter wie normal

;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;	Unterprogramme für Interrupt-Programm
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀

SetEntry:	;Namenseintrag finden oder ggf. erstellen
		;PE: SI=Programmadresse Namen lesen (zum Unterscheiden
		;von FCB- und Handlefunktionen)
		;    DS:DX - Zeiger auf Dateiname
		;PA: CY - Fehler: Tabelle voll, dann SI=0
		;    SI - Adresse Datensatz
		;    DS=CS
		push	cs
		call	GetEntry
		jnc	EntryEnd	;gefunden
		jz	EntryEnd	;Tabelle voll
;NewEntry:	;Neue Datei eintragen
		push	di
		mov	si,offset NameBuf	;Namenspuffer
		mov	cx,11
		rep	movsb		;einschaufeln
		xor	ax,ax		;0
		stosb
		stosw			;Nullen eintragen
		stosw
		stosw
		stosw
		stosw
		mov	[AdrFiles],di
		pop	si
		clc			;Kein Fehler
EntryEnd:	ret

GetEntry:	;Sucht Eintrag (FAR-codiert!)
		;PA: CY=1 nicht gefunden
		;    SI=0 und Z=1: Tabelle außerdem voll
		cld
		push	cs
		pop	es
		mov	di,offset NameBuf
		mov	al,' '
		mov	cx,11
		rep	stosb		;11 Zeichen mit Space löschen
		call	NCopy		;ah=Funktionsnummer
		push	cs
		pop	ds
		cld
		mov	cx,[MaxFiles]
		mov	si,ImmFiles
locloop_23:
		 mov	di,offset NameBuf
		 push	cx
		 push	si
		 mov	cx,11
		 repe	cmpsb		;vergleichen
		 pop	si
		 pop	cx
		 je	loc23ret	;Name gefunden, CY=0!
		 add	si,RecLng
		 loop	locloop_23

		mov	di,[AdrFiles]
		cmp	di,[EndAdr]	;war voll?
		jb	loc23ret	;nein-neuer Eintrag
		xor	si,si		;Z=1
		stc			;Fehler
loc23ret:	retf

NCopy:		;Dateiname von Handlefunktion oder FCB holen
		mov	si,dx		;Anfadr. bleibt in ds:dx!
		mov	cx,11
		cmp	ah,30h
		jb	NameCopy	;FCB-Funktion!
		;ganz anders
		xor	ah,ah		;Punkt-Merker
skend0:		lodsb			;suchen
		or	al,al
		jnz	skend0
skend4:		dec	si		;*Erst* DEC ist viiel angenehmer!
		mov	al,[si]
		cmp	al,'.'
		jne	skend2		;Punkt gefunden
		or	ah,ah		;Punkt war schon mal?
		jne	skend3
		inc	ah		;Richtigen Punkt kennzeichnen
		mov	cx,3
		mov	di,(offset NameBuf)+8
		call	PokeNT
skend2:		cmp	al,':'
		je	skend3
		cmp	al,'/'
		je	skend3
		cmp	al,'\'
		je	skend3
		cmp	si,dx
		jne	skend4
		dec	si
skend3:		mov	cx,8
NameCopy:	mov	di,offset NameBuf
		;hineinlaufen
PokeNT:		;Eintragen Name bzw. Typ (Vorgabe durch cx und di)
		;si zeige auf Punkt oder letztes Zeichen der vor-
		;hergehenden Pfadangabe
		push	ax
		push	si
		inc	si
pokent1:	lodsb
		or	al,al
		jz	pntend
		cmp	al,'.'
		jz	pntend
		call	UpCase
		stosb
		loop	Pokent1
pntend:		pop	si
		pop	ax
		ret


UpCase:		;al:= UpCase(al) ohne hohe Zeichen
		cmp	al,'a'
		jb	UpCas1
		cmp	al,'z'
		ja	UpCas1
		and	al,not 20h
UpCas1:		ret

InitData:	;Datensätze initialisieren
		push	ds
		pop	es			;Zieldatensegment
		mov	di,offset ImmHandles	;Handlepuffer
		mov	cx,30			;Handles max. (fiktiv)
locloop_40:	 xor	ax,ax
		 stosw				;0000
		 mov	ax,ImmFiles
		 stosw				;Zeiger auf 1. Element
		 loop	locloop_40	;30mal für 4 Bytes = 120 Bytes
		mov	ax,[MaxFiles]
		mov	cx,RecLng/2
		mul	cx
		mov	cx,ax
		xor	ax,ax
		rep	stosw
		mov	[AdrFiles],ImmFiles
		ret

;╔══════════════════════════════════════════════════════╗
;║	Hauptprogramm					║
;╚══════════════════════════════════════════════════════╝
instcont:	;Fortsetzung Installation
		push	ax
		call	InitData
		pop	dx
		mov	ax,3100h
		int	21h		;TSR dx Paragrafen

ImmHandles:	;Hier beginnen die Tabellen!
ImmFiles	equ	offset ImmHandles+120

;╒═══════════════════════════════════════════╕
;├──────>>> Start-Eintrittspunkt <<<─────────┤
;╘═══════════════════════════════════════════╛
Start1:
		mov	ah,'S'
		call	SCANCL
		je	suppress
		mov	dx,offset Text1
		call	OSTRLF		;Meldung ausgeben
suppress:	mov	ah,'?'
		call	SCANCL
		je	help
		mov	ah,'H'
		call	SCANCL
		jne	action

help:		mov	dx,offset Text4
		jmp	TextExit	;Hilfe ausgeben

action:		mov	ax,0f748h	;Installations-Check
		mov	dx,3abch	;Kennungen
		int	21h
		cmp	ax,0cba3h	;installiert?
		jne	NewRec
		jmp	OldRec

;╔══════════════════════════════════════════════════════╗
;║	Neuanlage von RECORDER				║
;╚══════════════════════════════════════════════════════╝

NewRec:		mov	es,[2ch]	;Segment Environment
		mov	ah,49h
		int	21h		;ENV-Speicher ab es freigeben
		;Zahl auswerten
		call	GetParAdr	;si:= 81h, cx:= Zeichenzahl
		jcxz	loc_45		;kein Parameter: Default=100
		xor	ax,ax		;ax:= 0 (die Zahl)
locloop_42:	mov	bl,[si]
		sub	bl,'0'
		jc	NoDigit
		cmp	bl,9
		ja	NoDigit
		mov	bh,10
		mul	bh		;*10
		xor	bh,bh
		add	ax,bx
NoDigit:	inc	si
		loop	locloop_42
		or	ax,ax		;0?
		jz	loc_45		;wie kein Parameter
		cmp	ax,2000		;zuviel?
		jbe	loc_44
		mov	ax,2000		;begrenzen
		jmp	short loc_44
loc_45:		mov	ax,100
loc_44: 	mov	[MaxFiles],ax	;setzen
		;Interrupts setzen
		mov	ax,3521h
		int	21h		;alter Int21
		mov	[word ptr OldInt21],bx
		mov	[word ptr OldInt21+2],es
		mov	[ExecFlag],0
		mov	dx,offset Text6	;Meldung
		mov	ah,9
		int	21h
		mov	ax,[MaxFiles]
		mov	bx,RecLng
		mul	bx		;*RecLng
		add	ax,ImmFiles	;dazu AnfAdr der Tabelle
		mov	[EndAdr],ax
		push	ax
		call	AXDez		;Bytezahl ausgeben
		mov	dx,offset Text6a
		call	OSTRLF		;"Bytes"
		pop	ax
		add	ax,0Fh		;aufrunden
		mov	cl,4
		shr	ax,cl		;Anzahl Paragrafen berechnen
		push	ax
		push	cs
		pop	es
		mov	bx,ax		;Erforderliche Paragrafen
		cmp	bx,(DTA-PSPAdr+0fh)/16 ;Programm länger?
		jc	allOK
		mov	ah,4ah
		int	21h		;umändern
		jnc	allOK
		mov	dx,offset MemErr
		jmp	TEXTexit
allOK:		mov	dx,offset NewInt21
		mov	ax,2521h
		int	21h		;neuer Int21
		pop	ax
		jmp	instcont	;nach vorn; dieser Programm-Bereich
					;wird von Daten überschrieben

;╔══════════════════════════════════════════════════════════════╗
;║	Aufgenommene Werte ausgeben				║
;╚══════════════════════════════════════════════════════════════╝
OldRec:		mov	ds,dx		;Fremdes Datensegment!
		;Keine Sortierung!
		mov	ah,'D'
		call	SCANCL
		jnz	$+5
		jmp	ToRem
		mov	ah,'L'
		call	SCANCL
		je	list
		mov	ah,'S'
		call	SCANCL
		je	suppr2
		mov	dx,offset Text3	;Tabellenkopf
		call	OSTRLF		;ausgeben
suppr2:		mov	cx,[MaxFiles]
		mov	si,ImmFiles
		xor	ax,ax		;Zeilenzähler
OutLoop:	push	cx
		push	ax
		 ;Summe nach ax bestimmen
		 xor	ax,ax
		 mov	bx,0ch
		 mov	cx,5
summy:		 add	ax,[si+bx]
		 jnc	summy1
		 mov	ax,0ffffh
summy1:		 add	bx,2
		 loop	summy
		 mov	bp,ax		;Letzte Summe für "Tab. voll!"
		 or	ax,ax
		 jz	nextline
		 push	ax
		  call	NameOut
		  jc	nextlin2
		  add	si,0ch
		  ;si zeigt auf Such-Zahl
		  mov	cx,5		;Su/Öf/Le/Sch/Ruf
outnumb:	   lodsw		;String [si] nach ax
		   push	cx
		   call	AXDez
		   pop	cx
		   loop	outnumb
		 pop	ax
		 call	AXDez		;Summe
		 call	CRLF		;Neue Zeile
		pop	ax
		inc	ax
		push	ax
		 call	pause
		 jmp	short nextline
nextlin2:	 add	si,RecLng
		 pop	ax
nextline:	pop	ax
		pop	cx
		loop	OutLoop

		or	bp,bp		;Letzter Platz voll?
		je	nfull		;nein
		 mov	ah,'S'		;Unterdrücken?
		 call	SCANCL
		 je	nfull
		 mov	dx,offset Text2	;"Tabelle voll"
		 call	OSTRLF
nfull:		jmp	ToRemove

;##########LIST UNUSED FILES#############
list:		mov	ah,'S'
		call	SCANCL
		je	suppr3
		mov	dx,offset Text9
		call	ostrlf
suppr3:
		xor	ax,ax
		push	ax
		mov	[cs:CFS],ds
		push	ds
		 push	cs
		 pop	ds
		 mov	dx,offset dta
		 mov	ah,1ah		;SetDTA
		 int	21h
		 mov	dx,offset filename
		 mov	cx,27h		;Alles außer Verzeichnisse u. Labels
		 mov	ah,4eh		;FindFirst
list2:		 int	21h
		 jc	list3
		 mov	dx,(offset dta)+1eh
		;ds:dx zeigt wie gewohnt auf Dateiname
		 mov	ah,35h
		 db	9ah		;ein CALL FAR
		 dw	offset GetEntry	;ah ist größer als 30h
CFS		 dw	?
		pop	ds
		jnc	list1
		mov	si,offset NameBuf ;im fremden Segment
		call	NameOut		;den Namen DX:SI
		call	CRLF
		pop	ax
		inc	ax
		push	ax
		call	Pause
list1:		push	ds
		 push	cs
		 pop	ds
		 mov	ah,4fh
		 jmp	short list2
list3:		pop	ds
		pop	ax
;#########################################

ToRemove:	mov	ah,'R'
		call	SCANCL
		jnz	NoDel
ToRem:		 call	InitData	;löschen = initialisieren
NoDel:		mov	ah,'U'
		call	SCANCL
		jz	$+5
		jmp	DosExit
		 mov	dx,ds		;zum Vergleichen
		 mov	ax,3521h	;Int-Vektor holen
		 int	21h
		 cmp	bx,offset NewInt21
		 mov	ax,es
		 jne	RemErr
		 cmp	ax,dx
		 jne	RemErr
		 ;nun auch es=ds!
		 lds	dx,[OldInt21]	;selbstmodifizierendes ds!
		 mov	ax,2521h	;Interrupt rücksetzen
		 int	21h
		 mov	ah,49h		;Speicher freigeben
		 int	21h
		 mov	dx,offset Text7	;Alles ok.
		 jnc	TextExit
RemErr:		 mov	dx,offset Text5	;Deinstallationsfehler
		push	cs
		pop	ds
		mov	cl,4
		shr	bx,cl
		push	ax
		push	bx
		mov	ah,9
		int	21h
		;Speicher nach dem Übeltäter absuchen!
		mov	ah,52h
		int	21h		;[ES:BX-4]=1.MCB
		mov	cx,[es:bx-2]
		pop	bx
		pop	ax
		add	ax,bx		;Segmentadresse (gesucht)
mcb4:		mov	ds,cx
		cmp	[byte 0],'M'
		je	mcb3
		cmp	[byte 0],'Z'
		jne	mcbf		;Weder M noch Z: Hase im Pfeffer!
		cmp	cx,0a000h
		jnc	mcbf		;nix gefunden (BIOS?)
mcb3:		add	cx,[3]		;Länge
		inc	cx
		cmp	ax,cx
		jnc	mcb4		;Der falsche MCB
		;Übeltäter gefunden!
		mov	si,8
		mov	cx,9		;Warum auch immer 9 Zeichen!
		mov	al,' '		;(Geht nur so!)
mcb5:		call	OCHR
		lodsb
		or	al,al		;Ende?
		loopnz	mcb5
mcbf:		mov	dx,offset Text5a
		call	OSTRLF
		mov	ax,4c01h	;Fehler im Dosexitcode
		int	21h

TextExit:	call	OSTRLF
DosExit:	mov	ax,4C00h
		int	21h		;Ende


;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
;	Unterprogramme für Nicht-Interrupt-Teil
;▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
NameOut:	;Gibt den durch DX:SI adressierten Dateinamen auf #1 aus
		;VR: ax,bx,cx,dx
		;Aber nur wenn wildcardfrei oder Option w angegeben
		;Sonst Carry gesetzt
		push	si
		mov	cx,11
NO2:		lodsb
		cmp	al,'?'
		je	NO1
		cmp	al,'*'
		je	NO1
		loop	NO2
NO3:		pop	si
		mov	dx,si		;die Adresse
		mov	bx,1		;auf StdOut
		mov	cx,8		;8 Zeichen Name
		mov	ah,40h		;Ausgabe
		int	21h
		mov	al,'.'
		call	OCHR		;Punkt
		mov	dx,si
		add	dx,8		;Typ ansteuern
		mov	cx,3		;3 Zeichen Typ ausgeben
		mov	ah,40h
		int	21h
		clc
		ret

NO1:		mov	ah,'W'
		call	SCANCL
		je	NO3
		pop	si
		stc
		ret

Pause:		;eine List-Pause einfügen
		;PE: AX - Zeilenzähler
		;VR: AX,CX,DX
		mov	cl,22		;fest
		div	cl
		or	ah,ah		;Rest
		jnz	nohalt
		push	si
		 mov	ah,'P'
		 call	SCANCL
		pop	si
		jne	nohalt
		push	ds
		 mov	ax,cs
		 mov	ds,ax
		 mov	dx,offset Text8
		 mov	ah,9
		 int	21h		;Pausentext
		pop	ds
		mov	ah,8
		int	21h		;Tastaturabfrage
		or	al,al		;Sondertaste?
		jnz	keypressed
		int	21h		;Sondercode abholen
keypressed:	mov	cx,30		;30 Spaces reichen dicke
		mov	al,' '
delline:	call	OCHR
		loop	delline
		mov	al,13
		call	OCHR
nohalt:		ret

SCANCL:		;Durchsuche Parameter nach Buchstaben AH, Zugriff via cs
		;PA: Z=1: gefunden
		call	GetParAdr	;si:= Adr, cx:= Länge
		jcxz	scanret		;Kein Parameter, Z=0
scansk:		mov	al,[cs:si]	;Eignes (!) Segment
		call	UpCase		;immer groß!
		cmp	al,ah		;passend?
		je	scanret		;ja, Z=1
		inc	si
		loop	scansk		;weitersuchen
scanret:	ret

AXDez:		;AX dezimal vzl ausgeben mit Vornullenunterdrückung
		;Es werden konstant 7 Zeichen ausgegeben
		;VR: ax,bx,cx,dx
		push	ax
		mov	al,' '
		call	OCHR
		mov	al,' '
		call	OCHR
		pop	ax
		xor	cx,cx		;Vornullunterdrückung
		mov	bx,10000
		call	ODigit 		;hinterläßt in ax den Rest!
		mov	bx,1000
		call	ODigit
		mov	bx,100
		call	ODigit
		mov	bx,10
		call	ODigit
		add	al,'0'		;Letzten Rest immer ausgeben
		jmp	OCHR

ODigit:		;Ziffernausgabe, ax=Zahl, bx=Teiler, cx=Vornull-Flag
		xor	dx,dx		;High-Teil=0
		div	bx		;ax:=ax/bx, Rest dx (bx Dezimalzahl?!)
		push	dx
		or	cx,ax		;Evtl. Ziffer anmelden
		or	cx,cx		;Immer noch Vornull?
		jnz	digit		;Ziffer
		mov	al,0F0h		;Space
digit:
		add	al,'0'
		 push	cx
		 call	OCHR
		 pop	cx
		pop	ax		;Rest
		ret

OSTRLF:		;ASCII$-String aus Codesegment mit CRLF ausgeben
		push	ds
		mov	ax,cs
		mov	ds,ax
		mov	ah,9
		int	21h		;ds:dx-ASCII$ ausgeben
		pop	ds
CRLF:		;CRLF ausgeben
		mov	al,13
		call	OCHR
		mov	al,10
OCHR:		;Zeichen al ausgeben (Marke KC-like!)
		mov	dl,al
		mov	ah,2
		int	21h		; DOS Zeichen auf StdOut
		ret

GetParAdr:	;si:= Kommandzeilenadresse
		;cx:= Zeichenzahl (kopierfreundlich)
		mov	si,80h
		mov	cl,[cs:si]	;Kommandozeilenzeichenzahl
		xor	ch,ch		;in CX
		inc	si		;1. Zeichen
		cld
		ret


Text1 db ' REC 2.02 (c) 1988 (ZCC■PCM■TK)',13,10
      db ' (c) 1993 haftmann#software    ++ Public Domain ++$'

IFDEF Deutsch

;Deutsche Texte
Text2 db 10,'* Tabelle ist voll *$'
Text3 db 10,'   Dateiname  Suchen Öffnen Lesen  Schr.  Aufruf Summe$'
Text4 db 10,'>> Programm zum Mitschneiden sämtlicher Dateizugriffe <<',13,10,10
      db 'Parameter bei Installation (Erstaufruf):',13,10
      db '[n] - Maximale Dateienzahl als Dezimalzahl (sonst 100)',13,10
      db '? oder h - diese Hilfe; es erfolgt KEINE Installation',13,10,10
      db 'Parameter bei Wiederaufruf:',13,10
      db 'l - Auslisten aller im akt. Directory NICHT genutzten Dateien',13,10
      db 'p - Pause nach 22 Zeilen',13,10
      db 'r - Liste löschen (nach Anzeige)',13,10
      db 'd - Liste löschen',13,10
      db 's - Meldungstext unterdrücken',13,10
      db 'u - Residentes REC entfernen',13,10
      db 'w - "Dateinamen" mit Wildcards ebenfalls anzeigen$'

MemErr db '* Kann REC nicht mit so vielen Dateien (hoch)laden, kein Speicher! *$'
Text5 db '* Kann REC nicht deinstallieren, da das TSR$'
Text5a db ' dies verhindert! *$'
Text6 db '--- Programm resident geladen, Platzbedarf:$'
Text6a db ' Bytes$'
Text7 db '--- REC vom Speicher entfernt$'
Text8 db ' *** Taste drücken! ***',13,'$'
Text9 db ' Liste aller ungenutzten Dateien:$'

ELSE

;Englische Texte, übersetzt vom English-Guru M. Sternberg
Text2 db 10,'* file record table full *$'
Text3 db 10,'   filename   seek   open   read   write  call   sum$'
Text4 db 10,'>> TSR program to record file access activities <<',13,10,10
      db 'parameters on install (use "-" or "/" or no prefix) :',13,10
      db '? or h - just this help screen, (NO installation)',13,10
      db '[n]    - maximum number of files (optional; defaults to 100)',13,10,10
      db 'parameters on recall (query file table database):',13,10
      db 'l      - list all unused files from current directory',13,10
      db 'p      - pause after 22 lines',13,10
      db 'r      - purge file table after displaying',13,10
      db 'd      - purge file table and no display',13,10
      db 's      - suppress (c)-messages and table-head (useful for pipes)',13,10
      db 'u      - uninstall TSR',13,10
      db 'w      - display also files accessed by wildcards (always recorded)$'
MemErr db '* Cannot install REC: insufficient memory for too many files *$'
Text5 db '* Removal of REC collides with TSR$'
Text5a db ' having hooked INT21h ! *$'
Text6 db '--- TSR loaded using$'
Text6a db ' Bytes$'
Text7 db '--- REC removed from memory$'
Text8 db ' *** press any key ***',13,'$'
Text9 db ' List of unused files:$'

ENDIF
filename	db	'*.*',0		;Such-Dateiname
dta:
		end	start
Vorgefundene Kodierung: OEM (CP437)1
Umlaute falsch? - Datei sei ANSI-kodiert (CP1252)