Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!rutgers!ames!ucbcad!ucbvax!decvax!decwrl!cookie.dec.com!wecker
From: wecker@cookie.dec.com (DAVE  CUM GRANO SALIS  WECKER)
Newsgroups: comp.sys.amiga
Subject: Tiny clock program (my own rewrite)
Message-ID: <6914@decwrl.DEC.COM>
Date: Sun, 14-Dec-86 13:47:16 EST
Article-I.D.: decwrl.6914
Posted: Sun Dec 14 13:47:16 1986
Date-Received: Tue, 16-Dec-86 03:03:46 EST
Sender: daemon@decwrl.DEC.COM
Organization: Digital Equipment Corporation
Lines: 217

I thought people might like this... it is a repost of Mike Meyer's clock
program with the following goodies:

	1)	It now works under Manx
	2)	It updates the display every 4 seconds UNLESS memory
		usage is changing, then it updates every 1/4 second.
		This means that even though it runs at high priority (20),
		it stays out of the way unless there are interesting things
		to monitor (in the way of memory usage).
	3)	I wrote my own "tiny" printf replacement [fmt()] so this
		program is SMALL.
	4)	The display is centered and short enough that it can be
		used with VT100 and not intefere with the top line of text.
	5)	I like it ;-)

Two side notes:

	1.	The memory usage numbers are in "k" (i.e., 1024 bytes) so
		the shell MEM command and this won't appear to agree until
		you divide the shell number by 1024 (not 1000).

	2.	This is the program I used to notice the bizarre copy behavior
		to RAM: (double space usage). I am happy to note that it is
		COMPLETELY fixed under 1.2 (yea 1.2 ! ! ! !).

==============================CLOCK.C========================================
/* clock - a dumb, digital clock in its own window
 *
 * original: Mike Meyer	    - public domain, not for sale
 * v1.1:     Dave Wecker    - under Manx, auto change of timings, no printf
 *
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 

/********* the following block can be commented out for LATTICE *******/
#include  
#ifdef NULL
#undef NULL
#endif
#define NULL ((void *)0)
 
#define INTUITION_REV	1L

static struct NewWindow	New_Window = {
	150, 0,			/* Centered, top */
	337, 8,			/* Just big enough for the time */
	-1, -1,			/* Default pens */
	CLOSEWINDOW,		/* All we care about is closing */
	WINDOWCLOSE		/* Borderless, fairly standard window */
	| WINDOWDEPTH | WINDOWDRAG | SIMPLE_REFRESH | BORDERLESS,
	(struct Gadget *) NULL,
	(struct Image *) NULL,
	(UBYTE *)"",			/* Empty title */
	(struct Screen *) NULL,
	(struct BitMap *) NULL,
	0, 0, 0, 0,		/* no change sizes, doesn't matter */
	WBENCHSCREEN		/* Of course! */
	} ;
 
static char	Date_Buffer[] =  "Chip:XXX Fast:XXXX Time:XX:XX:XX";

static struct IntuiText	Date_Text = {
	3, 0,				/* Use non standard pen colors */
	JAM2,				/* Use both of them */
	0, 0,				/* in the upper left-hand corner */
	(struct TextAttr *) NULL,	/* Use default text */
	(UBYTE *)Date_Buffer,		/* Buffer for time */
	(struct IntuiText *) NULL	/* All of text */
	} ;

struct IntuitionBase	*IntuitionBase ;
 
/*
 * Some things that need to be shared with done.
 */
static struct Window		*Wind = NULL ;
static struct timerequest	Time_Req ;
static struct MsgPort		*Timer_Port = NULL, *CreatePort() ;

/* My own little format routine (so we don't need printf)   */
/*    str = address in string to place integer		    */
/*    wid = number of digits to fill in			    */
/*    lead= 0 : don't use leading zeros, 1 : use leading    */
/*    num = number to format				    */

void fmt(str,wid,lead,num)
char	*str;
int	wid,lead,num;
    {
    register int i,some;
    register char chr;

    some = 0;
    for (str += --wid; wid >= 0; wid--) {
	if (num == 0 && some == 1) {
	    if (lead) chr = '0';
	    else      chr = ' ';
	    }
	else {
	    chr  = '0' + (char)(num % 10);
	    num /= 10;
	    some = 1;
	    }
	*str-- = chr;
	}
    }

main() {
	register short		hours, minutes, seconds, boring;
	register short		chip_free, fast_free ;
	register short		prev_chip, prev_fast;
	struct DateStamp	now ;
	struct IntuiMessage	*Msg;
	struct Task		*FindTask() ;
 
	boring	    = 0;
	prev_chip   = 0;
	prev_fast   = 0;

	if ((IntuitionBase = (struct IntuitionBase *)
	    OpenLibrary("intuition.library", INTUITION_REV)) == NULL)
		done(21);
 
	if ((Timer_Port = CreatePort("Timer Port", 0L)) == NULL)
		done(22);
 
	if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Time_Req, 0L) != 0)
		done(23);
	Time_Req.tr_node.io_Message.mn_ReplyPort = Timer_Port ;
	Time_Req.tr_node.io_Command = TR_ADDREQUEST ;
	Time_Req.tr_node.io_Flags = 0 ;
	Time_Req.tr_node.io_Error = 0 ;
 
	if ((Wind = (struct Window *) OpenWindow(&New_Window)) == NULL)
		done(24);
	
	/* Nudge me up to high priority */
	(void) SetTaskPri((long)FindTask(NULL),20L) ;
 
	for (;;) {
		DateStamp(&now) ;
		prev_chip = chip_free;
		chip_free = AvailMem((long)MEMF_CHIP) >> 10;
		prev_fast = fast_free;
		fast_free = AvailMem((long)MEMF_FAST) >> 10;
		hours = now.ds_Minute / 60 ;
		minutes = now.ds_Minute % 60 ;
		seconds = now.ds_Tick / TICKS_PER_SECOND;

		fmt(&Date_Buffer[5], 3,0,chip_free);
		fmt(&Date_Buffer[14],4,0,fast_free);
		fmt(&Date_Buffer[24],2,0,hours);
		fmt(&Date_Buffer[27],2,1,minutes);
		fmt(&Date_Buffer[30],2,1,seconds);
		PrintIText(Wind->RPort, &Date_Text, 28L, 0L) ;

		if (prev_chip == chip_free && prev_fast == fast_free)
			boring++;
		else	boring = 0;

		/* if things are happening, wake up every 1/4 second */
		if (boring < 16) {
		    Time_Req.tr_time.tv_secs    = 0;
		    Time_Req.tr_time.tv_micro	= 250000L;
		    }

		/* if nothing happening, wake up every 4 seconds */
		else {
		    boring			= 16;
		    Time_Req.tr_time.tv_secs	= 4L;
		    Time_Req.tr_time.tv_micro   = 0;
		    }

		SendIO((char *) &Time_Req.tr_node) ;
		Wait( 1L << Wind->UserPort->mp_SigBit
		    | 1L << Timer_Port->mp_SigBit) ;
 
		while (Msg = (struct IntuiMessage *)GetMsg(Wind->UserPort)) {
			if (Msg->Class == CLOSEWINDOW) {
				ReplyMsg(Msg) ;
				done(0) ;
				}
			else PrintIText(Wind->RPort, &Date_Text, 28L, 0L);
			ReplyMsg(Msg) ;
			}
 
		(void) GetMsg(Timer_Port) ;
		}
	/* NOTREACHED */
	}
/*
 * done - just clean up that which is open, and then leave.
 */
done(how)
int how;
    {
    AbortIO((char *) &Time_Req.tr_node) ;
    if (Wind) CloseWindow(Wind) ;
    if (Time_Req.tr_node.io_Message.mn_ReplyPort)
    	CloseDevice(&Time_Req) ;
    if (Timer_Port) DeletePort(Timer_Port) ;
    if (IntuitionBase) CloseLibrary(IntuitionBase) ;
 
    OpenWorkBench() ;			/* As requested */
    exit(how) ;
    }
==========================================================================

Enjoy!
dave	decwrl!cookie.dec.com!wecker