Disk schreibgeschützt? Ihr ST warnt Sie, wenn nicht

Haben Sie nicht auch schon öfter mal eine Diskette aus Versehen gelöscht? Dieses kleine Programm kann Ihnen hier unter die Arme greifen. Denn es wird Sie jedesmal mit einem Ton warnen, wenn eine nicht schreibgeschützte Diskette in das Laufwerk gelegt wird.

Die Bedienung des Programmes ist äußerst einfach. Es kann mit nahezu jedem Assembler bearbeitet werden. Es könnten eventuell Probleme bei den Kommentaren und am Ende des Listings bei den DS.x-Befehlen auftreten. Durch das Weglassen der Kommentare und Ersetzen der DS.x-durch BLK.x-Mnemonics dürften keine Fehler mehr Vorkommen.

Nach erfolgreichem Assemblieren sann man das erhaltene Programm aus dem Desktop starten oder man Kopiert es in den AUTO-Ordner der Startdiskette. Dort installiert es sich dann selbst.

Nun wird man jedesmal durch einen Ton gewarnt, wenn eine Diskette mit fehlendem Schreibschutz eingelegt wird.

Es muß nur noch beachtet werden, daß das Programm durch einen RESET verloren geht, d.h. es muß erneut installiert werden.

Wie funktioniert das alles ?

Als erstes muß das Einlegen einer Diskette ohne Schreibschutz festgestellt werden. Dank dem TOS hat man es sehr leicht, denn in der Speicherzelle h&9B2 wird dieses Ereignis durch den Wert Null angezeigt. Ansonsten enthält sie den Wert $FF.

Da es leider keine andere Möglichkeit gibt, als die Abfrage in den VBL-Interrupt einzubinden, muß man den Wechsel von $FF auf $00 feststellen. Würde man dies nicht so lösen, hätte man einen Dauerton, solange die Diskette eingelegt ist.

Der Wechsel wird durch das Zwischenspeichern des Wertes aus der Adresse $9B2 erkannt. Der jeweils aktuelle Inhalt dieser Speicherzelle wird mit dem alten gespeicherten Wert verglichen. Tritt hier ein Unterschied auf, fand ein Wechsel statt. Es muß nur noch geprüft werden, ob es sich um die Änderung von $FF auf $00 handelt.

Hat man auf diese Weise erkannt, daß eine Diskette ohne Schreibschutz eingelegt wurde, geht es an den Soundchip. Die Programmierung dieses Chips sieht so aus, daß man ein Register anwählt und dann einen Wert hineinschreibt.

Es wurden folgende Adressen des Soundchips verwendet:

$FF8800 In dieser Speicherzelle kann ein Register angewählt und ebenso ausgelesen werden. SFF8802 Hier kann man einen Wert in das gewählte Register schreiben.

Will man nun dem Soundchip einen Ton entlocken, muß man als erstes einen Kanal einschalten. Um einen klaren Ton zu erhalten, wird das Rauschen abgestellt. Das zugehörige Register ist hier das siebte. Dort werden die entsprechenden Bits gesetzt oder gelöscht.

Der nächste Schritt ist das setzen der Frequenz für den Ton. Hierzu ist das erste Register zuständig.

Da das Programm im VBL abläuft, kann man sich aus Zeitgründen nicht um die Dauer des Tones kümmern. Doch hier bietet sich die Möglichkeit an, eine Hüllkurve des Soundchips zu benutzen, d.h. der Chip kümmert sich selber um die Dauer. Das hat allerdings den Nachteil, daß keine schönen Klänge verwirklicht werden können. Um die Hüllkurve festzulegen, muß man das 12. und 13. Register verwenden.

Wer sich noch für die Installation der Routine im VBL-Interrupt interessiert kann dies in der Januar ’88-Ausgabe auf Seite 84 nachlesen.

*	Computer meldet sich mit einem, Ton wenn
*	eine nicht schreibgeschuetzte Diskette in's
*	Laufwerk gelegt wird .
*
*	(C) Markus Siebler
*
* Programmlaenge veststellen

	move.l	$4(a7),a0
	move.l	$c(a0),d0 
	add.l	$14(a0),d0 
	add.l	$1c(a0),d0 
	add.l	#$100,d0 
	move.l	d0,len

* Superviser anschalten

	clr.l	-(sp) 
	move.w	#$20,-(sp) 
	trap	#1 
	add.l	#6,sp 
	move.l	d0,save_ssp

* Routine in VBL-Liste eintragen

	move.l	$456,a1 
	clr.l	d1
loop:
	tst.l	$0 (a1,d1)
	beq		free
	addq	#4,d1
	jmp	loop
free:
	tst.l	d1
	bne		m3
	addq	#4,d1
	bra		loop
m3:
	lea.l 	$0(a1,d1),a2 
	move.l	#vbl,a1
	move.l	a1,(a2)

* Programm verlassen

	jmp		ende

* VBL-Routine 

vbl:
	move.l d0,-(sp)	*	DO	Zwischenspeichern

	move.b $9b2,d0	*	$9b2 enthaelt WP-Status
	cmp.b	ws,d0	*	hat	sich	was geaendert ?
	beq		quit	*	Nein	->	quit
	cmp.b	#$ff,d0	*	Ja -> wurde Disk eingelegt ?
	beq		quit	*	Nein	->	quit

	move.b	#7,$ff8800 * Ja -> Soundchip Reg.7 anwaehlen
	move.b	$ff8800,d0	*	in DO speichern
	and.b	#$fe,d0	*	Kanal 1 Ton ein
	or.b	#$8,d0	*	Kanal 1 Rauschen	aus
	move.b	d0,$ff8802	*	DO wieder in Reg.7 schreiben

	move.b #1,$ff8800 * Frequenz des Tones einstellen
	move.b #3,$ff8802

	move.b #8,$ff8800	* Lautstaerke einstellen
	move.b #$10,$ff8802 * Huellkurve waehlen

	move.b #12,$ff8800	* Frequenz der Huellkurve
	move.b #7,$ff8802

	move.b #13,$ff8800	* Huellkurve waehlen
	move.b #4,$ff8802

quit:
	move.b $9b2,ws	* WP-Status in < ws > speichern
	move.l (sp)+,d0	* DO wieder in alten Zustand
	rts	*	weiter	geht's im VBL

* Supervisor aus 

ende:
	move.l	save_ssp,-(sp) 
	move.w	#$20,-(sp) 
	trap	#1 
	add.l	#6,sp

	* Programm verlassen und resident halten

	move.w	#0,-(sp) 
	move.l	len,-(sp) 
	move.w	#$31,-(sp) 
	trap	#1

len:
	ds.1	1	* Programmlaenge
save_ssp:
	ds.1	1	* USER-Stack-Pointer
ws:
	ds.b 1	* WP-Status
cnt:
	dc.b -1	*	Tondauer
10	' W_PROTEC.PRG Lader (Zeilennummern nicht notwendig)
11	Filename$= "W_PR0TEC.PRG"
12	OPEN ”O", 1,Filename$
13	REPEAT
14		C=C+1
15		READ Wert
16		IF Wert=-1 THEN
17			END
18		ENDIF
19		IF (C MOD 11)=0	THEN
20			IF Wert<>(Summe	AND 255) THEN
21				PRINT"Fehler in Datazeile	"C/11
22				END
23			ENDIF
24			Summe=0
26		ELSE
27			PRINT #1, CHR$(Wert);
28			Summe=Summe+(Wert+C MOD	11)^2
29		ENDIF
30	UNTIL Wert=-1
31	CLOSE(1)
100	DATA 96,26,0,0,1,22,0,0,0,0,68
101	DATA 0,0,0,0,0,0,0,0,0,0,129
102	DATA 0,0,0,0,0,0,0,0,32,111,142
103	DATA 0,4,32,40,0,12,208,168,0,20,65
104	DATA 208,168,0,28,6,128,0,0,1,0,100
105	DATA 35,192,0,0,1,12,66,167,63,60,107
106	DATA 0,32,78,65,223,252,0,0,0,6,149
107	DATA 35,192,0,0,1,16,34,121,0,0,124
108	DATA 4,86,66,129,74,177,16,0,103,0,242
109	DATA 0,10,88,65,78,249,0,0,0,56,51
110	DATA 74,129,102,0,0,8,88,65,96,0,135
111	DATA 255,230,69,241,16,0,34,124,0,0,44
112	DATA 0,102,36,137,78,249,0,0,0,234,23
113	DATA 47,0,16,57,0,0,9,178,176,57,145
114	DATA 0,0,1,20,103,0,0,102,176,60,83
115	DATA 0,255,103,0,0,94,19,252,0,7,69
116	DATA 0,255,136,0,16,57,0,255,136,0,172
117	DATA 2,0,0,254,0,0,0,8,19,192,252
118	DATA 0,255,136,2,19,252,0,1,0,255,7
119	DATA 136,0,19,252,0,3,0,255,136,2,182
120	DATA 19,252,0,8,0,255,136,0,19,252,180
121	DATA 0,16,0,255,136,2,19,252,0,12,41
122	DATA 0,255,136,0,19,252,0,7,0,255,131
123	DATA 136,2,19,252,0,13,0,255,136,0,174
124	DATA 19,252,0,4,0,255,136,2,19,249,109
125	DATA 0,0,9,178,0,0,1,20,32,31,168
126	DATA 78,117,47,57,0,0,1,16,63,60,32
127	DATA 0,32,78,65,223,252,0,0,0,6,149
128	DATA 63,60,0,0,47,57,0,0,1,12,231
129	DATA 63,60,0,49,78,65,0,0,0,49,251
130	DATA 0,0,0,49,0,255,0,0,0,24,127
131	DATA 20,24,22,8,14,114,10,22,0,0,97 
9999 Data -1

Das Assembler-Listing als BASIC-Datas


Markus Siebler
Aus: ST-Computer 04 / 1988, Seite 137

Links

Copyright-Bestimmungen: siehe Über diese Seite