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