Ein Wecker im ST

Haben Sie sich auch schon einmal geärgert, daß Sie, um die Uhrzeit zu erfahren, immer das Kontrollfeld aufrufen müssen? Oder haben Sie vielleicht bei der begeisterten Arbeit am Atari einen Termin vergessen? Dann sollten Sie diesen Artikel lesen, der zeigt, wie man die Uhrzeit permanent in den Bildschirm einblenden kann und einen einstellbaren Wecker programmiert.

Nachdem in der Juni-Ausgabe ein Verfahren vorgestellt wurde, eine Echtzeituhr durch Akku-Pufferung des Tastaturprozessors zu realisieren, soll dieses Programm eine Anregung für die Benutzung der internen Uhr sein. Übrigens ist dieses kleine Programm auch für diejenigen interessant, die die Bauanleitung nicht nachgebaut haben oder die eine andere Uhr an ihrem Rechner betreiben.

Eingabe und Bedienung des Programmes

Das abgedruckte Programm wurde mit dem Alcyon-C-Compiler des Atari-Entwicklungspaketes entwickelt. Wenn Sie mit einem anderen Compiler arbeiten, müssen daher eventuell kleine Änderungen durchgeführt werden. Manche Compiler erlauben nur 16-Bit-Objektindizes, dort muß im Listing "strings[...]“ zu "strings[(int)...]“ werden. Der Megamax-Compiler, der Typkonflikte genauer prüft, hat statt "= &txtinfo;“, lieber den Ausdruck "= (char *) (&txtinfo);“. Außerdem erfordern manche Compiler möglicherweise die Änderung der Betriebssystemaufrufe Cconout, Dosound und Get-time, die hier in „osbind.h“ definiert wurden.

Beim anschließenden Linken muß darauf geachtet werden, daß dieses Programm ein Accessory werden soll. Bei einigen Linkern ist dann eine andere Startup-Datei dazuzulinken. Nachdem dies alles hoffentlich fehlerfrei geklappt hat, kann das Programm auf eine Systemdiskette kopiert werden und wird von nun an bei jedem Systemkaltstart gebootet.

Nun zur Bedienung: im linken Menü sollte jetzt ein Eintrag „ST-Bildschirmuhr“ vorhanden sein. Klicken Sie diesen Eintrag an, so erscheint auf dem Bildschirm ein Formular, in dem sich die Zeitanzeige (Uhr) und der Wecker einzeln ein- und ausschalten lassen. Wenn Sie einfach Return drücken, so wird nur die Uhr eingeschaltet. Sollten Sie vorher den Wecker eingeschaltet und eine Weckzeit angegeben haben, so ist auch dieser aktiviert. Sobald die eingestellte Zeit erreicht wird, ertönt zweimal ein Piepston und auf dem Bildschirm erscheint eine Mitteilung, die Sie an die Zeit erinnert.

Das Programm arbeitet in der vorliegenden Version mit allen GEM-Programmen, sowohl bei hoher als auch bei mittlerer Auflösung. Da bei niedriger Auflösung die Menüzeile sowieso keinen Platz mehr für die Zeit bietet, wird diese Auflösung nicht unterstützt. Vor der Arbeit mit Programmen, die die ganze Menüzeile ausnutzen, sollte die Zeitanzeige abgeschaltet werden.

Funktionsweise des Programms

Um nicht unnötig Verwirrung zu stiften, möchte ich die Erläuterung des Programms in der Zeile „... = graf_handle(...)“ beginnen. In dieser Zeile wird die augenblickliche Zeichenhöhe (in zh) ermittelt. Darauf folgt die Eröffnung einer VDI-Arbeitsstation und die Eintragung des Accessories in das linke Menü.

Die daran anschließende while-Schleife stellt die Hauptarbeitsroutine des Programmes dar. Sie wird immer wieder durchlaufen (Accessories enden nicht...) und je nachdem, ob Anzeigen der Uhrzeit oder Wecken gewünscht wird (boolsche Variable „weck“ und „anz“) oder nicht, wird ein String für die Ausgabe aus der mit Gettime ermittelten Zeit aufgebaut.

Die Zeit, die man mit Gettime ermittelt, hat folgendes Format:

Bit Nr.
32...........................5....0
JJJJJJJMMMMTTTTTsssssmmmmmmsssss

Falls Wecken gewünscht wurde und die Zeit mit der Weckzeit übereinstimmt (Vergleich der Strings), so wird zweimal ein Piepston mit Cconout ausgegeben. Die drei Aufrufe von Do-sound sorgen für eine zeitliche Verzögerung. „while(Dosound(- 1));“ wartet auf die Ausführung der Soundbefehle.

An diesem Programmteil schließt sich der evnt___multi-Aufruf an, der auf Anklicken des Menüeintrages maximal 10 Sekunden wartet. Danach wird in der while Schleife fortgefahren.

Wenn ein Menüeintrag angeklickt wurde, so wird mit form_do das Formular verwaltet. Ansonsten wird nur wieder am Anfang der while-Schleife die Zeit angezeigt. Wenn Sie nicht wollen, daß die Zeit alle 10 Sekunden angezeigt wird, so können Sie die 10000 in evnt___multi abändern. Sie gibt die Zeit in Millisekunden an.

Die integrierte Resourcedatei

Nur durch die Einbindung aller relevanten Informationen aus einer Resource-Datei innerhalb der ersten Hälfte des Programmes wurde die Veröffentlichung eines Programmes mit Grafik möglich. Die Routinen am Anfang (unter „appl_init“ bis „graf_handle“) dienen dem Aufbau funktionsfähiger Objektbäume, die mit „objc_...“- und „form____“ Zeichen- und bearbeitbar sind. Alle diese Aufgaben werden sonst durch den Befehl „rsrc__load“ durchgeführt.

Sollte Ihnen das Verständnis dieses ersten Programmteiles Schwierigkeiten bereiten, so kann ich nur auf die verfügbare GEM-Literatur verweisen.

Verwendete Literatur:

ATARI ST intern, Data Becker GEM-Programmierung, Heim-Verlag

#include	<osbind.h>	/*	Betriebssystemaufrufe	*/
#include	<gemdefs.h>	/*	GEM-Definitionen	*/
#include	<obdefs.h>	/*	Objektdefinitionen	*/
#define	UEIN 4	/*	Objekt im Baum	*/
#define	WZEIT 10	/*	Objekt im Baum	*/
#define	WAUS 9	/*	Objekt im Baum	*/
#define	ANZAHL 12	/*	Objektanzahl	*/

char *strings[] = { "ST Computer BiIdschirmuhr","Uhr:","EIN","AUS",
	"Wecker: ", "EIN" , "AUS”, "____", "Weckzeit: __: __", "9999" , "OK" };

TEDINFO txtinfo = { 7L, 8L, 9L, 3, 6, 0, 0x1180, 0x0, 255, 5, 16 };

OBJECT Objekte[] = {
-1,	1 ,	11,	G_BOX, NONE,	OUTLINED,	0x21111L,	0,0,	29,9,
2,	-1 ,	-1,	G_BUTTON, NONE,	OUTLINED,	0x0L,	2,1,	25,1,
6,	3,	5,	G_BOX, NONE,	NORMAL,	0x1100L.	2.3,	25,1,
4, -1,		-1,	G_STRING, NONE,	NORMAL,	0x1L,	0,0,	6,1,
5.	-1 ,	-1,	G_BUTTON, 0x11,	NORMAL,	0x2L,	13,0,	5,1,
2,	-1,	-1,	G_BUTTON, 0x11,	NORMAL,	0x3L,	20,0,	5,1,
10,	7,	9,	G_BOX, NONE,	NORMAL,	0x1100L,	2,5,	25,1,
8,	-1,	-1,	G_STRING, NONE,	NORMAL,	0x4L,	0,0,	7,1,
9,	-1,	-1,	G_BUTTON, 0x11,	NORMAL,	0x5L,	13,0,	5,1,
6,	-1,	-1,	G_BUTTON, 0x11,	NORMAL,	0x6L,	20,0,	5,1,
11,	-1,	-1.	G_FTEXT, EDITABLE,	NORMAL,	0x0L.	2,7,	15,1,
0, -1,		-1,	G_BUTTON, 0x27,	NORMAL,	0xAL,	20,7,	7,1 };

int contrl(12], intin[128], intout[128], ptsin[128], ptsout[128];
extern int gl_apid;	/*	Prozesskennziffer	des	AES	*/
	/* bei GST:	extern	short	gl_apid;	*/

main()
{
register long	zeit;		/*	Variable	*/
static char	uhr[] = ”00.00.00 00:00";
static char	warte[] = { 0xff, 20, 0xff, 0 };
register char zr;
short	tast,a_nr,anz,weck,ereig,zh,vn,h,aus[57];				
/*Bei Megamax int	tast,a_nr,anz,weck,ereig,zh,vn,h,aus[57]; */

GRECT fm;		/*	Formularabmessungen	*/
appl_init();		/*	Beim AES anmelden	*/
for{h = 0; h<ANZAHL; h++ )			/*	Objektkoordinaten */
{ rsrc_obfix(objekte,h);			/*	umrechnen	*/
switch(objekte[h],ob_type)			/*	Je nach Objekttyp	*/
{ case G_STRING:	/*	Objektspezifikation	*/
case G_BUTTON:	/*	richtig setzen	*/
	objekte[h].ob_spec = Strings[Objekte{h}.ob_spec];
	break;	/* Fertig... */
case G_FTEXT;	/*	Formatierter Text	*/
	objekte[h].ob_spec = &txtinfo;	}}
txtinfo.te_ptext =	strings[txtinfo.te_ptext];	/*	TEDINFO	*/
txtinfo.te_ptmplt =	strings[txtinfo.te_ptmplt};	/*	auch	*/
txtinfo.te_pvalid =	strings[txtinfo.te__pvalid] ;	/*	setzen */

form_center(objekte,&fm.g_x,&fm.g_y,&fm.g_w,&fm.g_h);	/* zentr. */
objc_change(objekte,UEIN,0,fm.g_x,fm.g_y, fm.g_w, fm.g_h,SELECTED,0);
objc_change(objekte.WAUS,0,fm.g_x,fm.g_y,fm.g_w,fm.g_h,SELECTED.0);

vn = graf_handle(&h,&zh,&h,&h); zh -= 2;	/*	Zeichenhöhe holen */
v_opnvwk(&h,&vn,aus);	/*	Arbeitsstation oeffnen */
vst_color(vn,1);	/*	Zeichenfarbe schwarz	*/
menu_register(gl_apid," ST-BiIdschirmuhr ");	/*	Namen	eintragen */

while(1)	/*	...immer wieder	*/
{	if(anz || weck)	/*	Uhrzeit abfragen?	*/
	{	zeit = Gettime() >>5;	/*	Zeit holen	*/
		zr = ((char)zeit)	& 0x3f;	/*	Minuten errechnen	*/
		uhr[12] = zr / 10	+ '0';	uhr[13] * zr % 10 + '0‘;
		zeit >>= 6;	/*	Stunden errechnen	*/
		zr = zeit & 0xlf;	/*	Nur 5 Bits	*/
		uhr[9] = zr / 10	+ '0'; uhr[10] = zr % 10 + '0'; }
	if(anz)	/*	Uhrzeit anzeigen?	*/
	{	zeit >>= 5;	/*	Tag errechnen	*/
		zr = ((char)zeit)	& 0x1f;	/*	Nur 5 Bits	*/
		uhr[ 0] = zr / 10	+ '0';	uhr[1] = zr % 10 + '0‘;
		zeit >>= 5;	/*	Monat errechnen	*/
		zr = ((char)zeit)	& 0xf;	/*	Nur 4 Bits	*/
		uhr[ 3] = zr / 10	+ '0';	uhr[	4] =zr%10+ '0';
	zr = ((char)((zeit >> 4) + 80L) %	100) & 0x7f;	/*	Jahre */
	uhr[ 6] = zr / 10	+ '0';	uhr[	7] =zr % 10+ '0';
	v_gtext(vn,504,zh,uhr); }	/*	String ausgeben	*/
if(weck)	/*	Wecker eingeschaltet?	*/
	if(uhr[ 9] == strings[7][0] && uhr[10] == strings[7][1] && 
		uhr[12] == strings[7][2] && uhr[13] == strings[7][3])
	{	Cconout(7); while(Dosound(-1L)); Dosound(warte); /* 1. */
		while(Dosound(-1L)); Cconout(7); /* 2. Piepston	*/
		form_alert(1,	/*	Meldung ausgeben	*/
			" [1][Ich möchte Sie an die|Uhrzeit erinnern.][ OK ] ") ; }
		ereig = evnt_multi(MU_TIMER | MU_MESAG, /* Warten... */
			0,0,0,0,0,0,0,0,0,0,0,0,0,aus,10000,0,&h,&h,&h,&h,&h,&h); 
		if ( (ereig & MU_MESAG) && (*aus == AC_OPEN)) /* Menüeintrag? */
		{	form_dial(FMD_START,fm.g_x,fm.g_y,fm.g_w,fm.g_h,
				fm.g_x,fm.g_y,fm.g_w,fm.g_h); 
			objc_draw(objekte,ROOT,MAX_DEPTH,fm.g_x,fm.g_y,fm.g_w,fm.g_h); 
			tast = form_do(objekte,WZEIT);	/* Formulareingabe holen */
			form_dial(FMD_FINISH,fm.g_x,fm.g_y,fm.g_w,fm.g_h, 
				fm.g_x,fm.g_y,fm.g_w,fm.g_h); 
			objc_change(objekte,tast,0,	/* Abbruchtaste zurücksetzen */
				fm.g_x,fm.g_y,fm.g_w,fm.g_h,NORMAL,0);
			if(objekte[UEIN].ob_state)	anz = 1;	/* Anzeige einschalten */
			else		anz = 0;	/* ausschalten */
			if(objekte[WAUS].ob_state)	weck = 0;	/* Nicht wecken */
			else	weck = 1;	})	/* Ende von while	*/
}


Aus: ST-Computer 10 / 1986, Seite 36

Links

Copyright-Bestimmungen: siehe Über diese Seite