ST-Tips: Ab ins Dunkle - Der Bildschirmabschalter

Die Entwickler des ATARI ST haben offenbar ein kleines Detail übersehen oder für zu unwichtig gehalten, denn das Videosignal des Rechners wird auch dann nicht abgeschaltet, wenn der Rechner längere Zeit nicht benutzt wird.

Da dieser Umstand auf die Dauer unschöne Brennspuren auf der Fluoreszensschicht des Bildschirms hinterläßt und die Fummelei am Helligkeitsregler nicht die eleganteste Lösung ist, habe ich ein kleines Programm geschrieben, welches das Videosignal abschaltet wenn die Tastatur/Maus des Rechners 5 Minuten lang nicht benutzt wird. Das Bild erscheint wieder, wenn eine Taste gedrückt oder die Maus bewegt wird.

Das Programm wird im AUTO-Ordner untergebracht, damit es bei einem Systemstart installiert wird.

Die Funktion des Programms möchte ich anhand des dokumentierten Quellcodes erläutern:

Vorausschickend bleibt zu sagen, daß an der Speicheradresse SFF8200 das Register für die Video-Anzeige liegt. In diesem Register steuert das Bit 0 die Synchronisation des Bildes. Wird dieses Bit auf ’T gesetzt,werden die intern erzeugten Synchronisationssignale abgeschaltet und der Bildschirm erscheint dunkel. Zu beachten bleibt, daß bei gesetztem Bit der VBL-Interrupt, der verschiedene periodische Systemaufgaben ausführt, simuliert werden muß:

’60000’ geladen. Da der Timer mit einer Frequenz von 200 Hz Interrupts erzeugt und der Zähler in der eigenen Routine nach jedem Interrupt um 1 dekrementiert wird, ist nach 60000/200 = 300 Sekunden oder 5 Minuten! der Zähler auf ’0’ gezählt; ein Zähler für die Simulation des VBL-Interrupt’s wird mit 3 geladen; dieser Zähler wird in der neuen Timer-Routine bei jedem Aufruf um 1 dekrementiert und bei Erreichen von ’0’ wird der VBL-Interrupt simuliert. Dies gibt eine Simulationsfrequenz von 200/3 = 66.66... Hz. Ein Flag für Keyboard-Interrupts wird mit ’0’ vorbesetzt; danach werden die Interrupt-Vektoren für den Timer und das Keyboard auf die neuen Routinen gesetzt und die alten Vektoren jeweils an das Ende der eigenen Routinen geschrieben; zusätzlich wird noch der Vektor auf den VBL-Handler in die neue Timer-Routine geschrieben.

Wenn dies der Fall ist, wird das Keyboard-Interruptflag getestet und, falls es gesetzt ist, der Bildschirm eingeschaltet. Ist das Interruptflag nicht gesetzt,wird der Zähler für die VBL-Simulation erniedrigt und bei Bedarf der VBL-Interrupt ausgeführt.

War bei Anruf der Timer-Routine der Bildschirm noch eingeschaltet, wird der Timer-Zähler um ’1’ erniedrigt. Ist der Zähler noch nicht auf ’0’ gezählt (die 5 Minuten sind noch nicht abgelaufen) wird die alte Timer-Routine angesprungen.

Andernfalls wird das Keyboardflag gelöscht, der nächste VBL-Interrupt abgewartet und dann der Bildschirm abgeschaltet. Die neue Timer-Routine wird in jedem Fall mit dem Aufruf der alten Routine beendet.

Anmerkung:

Der Inhalt des Datenregisters D0 muß gerettet werden, da in einer Interrupt-Routine die Registerinhalte nicht verändert werden dürfen.

****************************************
*               CRT-SAVER              *
*               H.-J. Moes             *
*              Dorfstraße 19           *
*             7854 Inzlingen           *
*                                      *
****************************************

v_shift =	$ff820a	* adresse des videoshifters

.text

move.l	a7,a5	*	alten Stackpointer retten
move.1	#uss,a7	*	Stackpointer auf userstack
move.1	4(a5),a5	*	adresse der basepage
move.l	#$100,d7	*	laenge der basepage '
add.l	12(a5),d7	*	laenge des textsegment
add.1	20(a5),d7	*	laenge des datensegment
add.l	28(a5),d7	*	laenge des bss-segment
clr.l	-(sp)	* userstack wird Supervisorstack
move.w	#$20,-(sp)	*	in Supervisormodus schalten
trap	1
move.l d0,ssp	*	alten supervisorstack-pointer retten
addq.l	#6,sp
bsr		init	*	initialisierung
move.l	ssp,-(sp)	*	supervisorstack-pointer zurueck
move.w	#$20,-(sp)	*	supervisormodus abschalten
trap	1
addq.l	#6,sp	*	.stack-korrektur
clr.w	-(sp)	*	kein fehler
move.l	d7,-(sp)	*	programmlaenge
move.w	#$31,-(sp)	*	keep process
trap	1

init	pea	initstring	*	begruessungsstring ausgeben
move.w	#$09,-(sp)	*	Print line
trap	1
addq.l	#6,sp
move.w	#65535,d0

halt subq.w	#1,d0	*	verzoegerungsschleife
bne	halt

move.w	#60000,count	*	zaehler fuer timerdurchlaeufe
move.b	#3,vblcount	*	zaehler fuer simulierten VBL-interrupt
move.b	#0,keyflag	*	flag fuer keyboard-interrupt
move.l	$118,keyalt + 2	* alter keyboard-/midi-interrupt
move.l	#keybrd,$118
move.l	$114,timealt+2	*	alter timer c - interrupt
move.l	#timer,$114
move.l	$70,vbl+2	*	vbl-vektor eintragen
rts

keybrd move.w	#60000,count	*	zaehler neu laden
bset	#0,keyflag	*	flag setzen
keyalt	jmp	$100000	*	alte keyboard-/midi-routine aufrufen
timer btst	#0,v_shift	*	externe Synchronisation ?
beq	ein	*	bildschirm ist eingeschaltet
aus	btst	#0,keyflag	*	tastaturinterrupt aufgetreten ?
bne	_ein	*	ja

subq.b	#1,vblcount	*	VBL-zaehler dekrementieren

bne	timealt	*	noch keine 3 timerdurchlaeufe
move.b	#3,vblcount	*	zaehler neu laden
andi.w	#$f8ff,SR	*	Interruptmaske low

pea	timealt	*	nach VBL-simulation in alte timerroutine

move.w	SR,-(sp)	*	interrupt-stackzustand simulieren

vbl	jmp	$100000	*	VBL-handler anspringen

_ein	bclr	#0,v_shift	*	auf interne Synchronisation schalten
	
timealt	jmp	$100000	*	in alte timerroutine springen

*

ein	subq.w	#1,count	*	zeit abgelaufen

bne	timealt	*	nein
bclr	#0,keyflag	*	flag loeschen
move.w	SR,-(sp)	*	Statusregister	retten
andi.w	#$f8ff,SR	*	interruptmaske	low
move.1	d0,-(sp)	*	datenregister retten
move.l	$466,d0	*	zaehler fuer ausgefuehrte VBL-interrupts
warte	cmp.1	$466,d0	*	auf naechsten VBL-interrupt warten
beq	warte

bset	#0,v_shift	*	auf externe Synchronisation schalten
move.l	(sp)+,d0	*	register zurueckholen
move.w	(sp) + ,SR	*	Statusregister zurueckholen
bra	timealt	*	in alte timerroutine

*

. data

initstring	.dc.b $1b,$45	* ESC E clear home
.de.b $1b,$59,32+3,32+3	* ESC Y
.dc.b ’CRT-Saver ST-Computer HJ Moes’
.dc.b $0d,0
vblcount	.dc.b 0	*	zaehler fuer VBL-simulation
keyflag	.dc.b 0	*	flag fuer keyboard-interrupt
. even
ssp	.dc.l 0	*	Speicher fuer alten Supervisorstack-pointer
count	.dc.w 0	*	zaehler fuer timer C - interrupts
.ds.1	50
uss	.dc.l 0	*	userstack

*	assembliert mit folgendem Batch-File :

*	as68 -1 -u %l.s
*	link68 %1.68k = %l.o
*	relmod %1.68k %l.prg

_________________________________________________

10	' CRT.PRG Lader
11	Filename$="CRT.PRG"
12	OPEN "O",1,FilenameS
13	READ Wert
14	REPEAT
15	PRINT #1, CHR$ {Wert);
16	Summe=Summe+Wert
17	READ Wert
18	UNTIL Wert=-1
19	READ Pruefsumme
20	IF Pruefsumme<>Summe THEN
21	PRINT "Fehler In Datas"
22	ENDIF
23	CLOSE 1
100	DATA 96,26,0.0.1,56,0,0,0.254
101	DATA 0,0,0,0,0,0,0,0,0,0
102	DATA 0,0,0.0,0,0,0,0,42.79
103	DATA 46.124,0,0,2,50,42,109,0,4
104	DATA 46,60,0,0,1,0,222,173,0,12
105	DATA 222.173,0,20,222,173,0,28,66,167
106	DATA 63,60.0.32.78,65,35,192,0,0
107	DATA 1,100,92,143,97.24,47,57.0,0
108	DATA 1,100.63,60.0,32,78.65,92,143
109	DATA 66,103,47,7.63,60,0,49,78,65
110	DATA 72,121.0.0,1,56,63,60,0.9
111	DATA 78,65.92,143,48,60,255,255,83,64
112	DATA 102,252.51,252,234,96,0,0.1,104
113	DATA 19,252.0,3,0,0,1,98,19,252
114	DATA 0,0,0,0,1,99,35,249.0,0
115	DATA 1,24,0,0,0,188,35,252,0,0
116	DATA 0,170,0.0,1,24,35,249,0.0
117	DATA 1,20,0,0.1,0,35,252,0,0
118	DATA 0,192,0,0,1,20,35,249,0,0
119	DATA 0,112,0,0,0,242,78,117,51,252
120	DATA 234,96,0,0,1,104,8.249.0,0
121	DATA 0 0,1,99,78,249,0,16,0,0
122	DATA 8,57,0,0,0.255,130,10,103,58
123	DATA 8,57,0,0,0,0,1,99,102,34
124	DATA 83,57,0,0,1,98,102,34,19,252
125	DATA 0,3,0,0,1,98,2,124,248,255
126	DATA 72,121,0,0,0.254,64,231,78,249
127	DATA 0,16,0,0,8,185,0,0,0,255
128	DATA 130,10,78,249,0,16,0,0,83,121
129	DATA 0,0,1,104.102,242,8,185,0,0
130	DATA 0,0,1,99,64.231.2.124,248.255
131	DATA 47,0,32,57,0,0,4,102,176,185
132	DATA 0,0,4,102,103,248,8,249,'0,0
133	DATA 0,255,130,10,32,31,70,223,96,198
134	DATA 27,69,27,89,35,35,67,82,84,45
135	DATA 83,97,118,101.114,32,32,32,83,84
136	DATA 45,67.111,109,112,117,116,101,114,32
137	DATA 32,72,46,74,46,32,77,111,101,115
138	DATA 13,0,0,0,0,0,0,0,0,0
139	DATA 0,0,0,0,0,0,0,0,0,0
140	DATA 0,0,0,0,0.0.0,0,0,0
141	DATA 0,0,0,0,0,0,0,0,0,0
142	DATA 0,0,0,0,0,0,0,0,0,0
143	DATA 0,0,0,0,0,0,0,0,0,0
144	DATA 0,0,0,0,0,0,0,0,0.0
145	DATA 0,0,0,0,0,0,0,0,0,0
146	DATA 0.0,0,0,0,0,0.0,0,0
147	DATA 0.0,0,0,0,0,0,0,0.0
148	DATA 0,0,0,0,0,0,0,0,0,0
149	DATA 0,0,0.0,0,0,0.0.0,0
150	DATA 0,0,0.0,0,0,0,0,0,0
151	DATA 0,0,0,0,0,0,0,0,0,0
152	DATA 0,0,0,0,0,0,0.0,0.0
153	DATA 0,0,0,0,0,0,0,0,0,0
154	DATA 0,0,0,0,0,0,0,0,0,0
155	DATA 0,0,0,0,0,0,0,0,0,0
156	DATA 0,0,0.0,0,0,0,0,0,0
157	DATA 0,0,0,0,0,0,0.0,0,0
158	DATA 0,0,0,0,0,0,0,0,0,0
159	DATA 0,0,0,0,0,0,0,4,36,10
160	DATA 24,24,8,8,10.6,14,6,14,10
161	DATA 8,24,8,10,10,28,10,0,26
9998 DATA -1
9999 DATA 24015

(H.S.Moes)



Aus: ST-Computer 08 / 1987, Seite 144

Links

Copyright-Bestimmungen: siehe Über diese Seite