; /* Execute me to compile!
sc GetStats.c link nomath nodebug cpu=any ignore=73 stripdebug ansi strict
quit
*/

/*GetStats - a demonstration on how to use HDOff's messageport
  © by Gideon Zenz, 1996 - freely distributable
  debugged and improved by Matthias Andree, 1996
  This was written to give the user a tool to have a look at HDOff's
  actual status and to have at least one example how to use the
  messyport :)

  You may use this to build up your own programms.
  This program was compiled using the great SAS/C v6.56 © by SAS Institute Inc.

  History:
  1.00 initial by G. Zenz (12.1.96)
  1.01 improved by M. Andree (9.3.96)
       corrected typos, implemented second display for remaining time
       float math no more needed, thus reducing executable size by 4k.
  1.02 Implemented output for hd_HDoffVersion (21.6.96)
  1.03 Implemented output for hd_QueryCtrl (29.6.96)
  1.04 Supporting CD32 Promodule
*/

/*** include all stuff */
#include <stdio.h>
#include <stdlib.h>
#include <exec/exec.h>
#include <proto/exec.h>
#include <dos/dos.h>
#include <proto/dos.h>
#include <clib/alib_protos.h>

#pragma msg 73 warn

/* define HDOff's commands*/
#define hd_GetStats     0x0
#define hd_SetStats     0x1
#define hd_Subscribe    0x2
#define hd_Unsubscribe  0x3
#define hd_StopDrive    0x4
#define hd_Quit         0x5
#define hd_ForceQuit    0x6
#define hd_HDoffVersion 0x7
#define hd_QueryCtrl    0x8
#define hd_Failure      -2
#define hd_Die          -1

/* The message-structure*/
 struct HD {
     struct  Message HD_Msg;
     WORD    HD_Cmd;
     UWORD   HD_TimeHD0;
     UWORD   HD_TimeHD1;
     UWORD   HD_TimeLeftHD0;
     UWORD   HD_TimeLeftHD1;
     BOOL    HD_StatHD0;
     BOOL    HD_StatHD1;
     ULONG   HD_PortVer;
     LONG    HD_Reserved;
     };

/*the obligatory version string :)*/
const UBYTE *version = "$VER: GetStats 1.03 (29.6.96)";

/*Our very own structures*/
struct HD      *MyMsg;
struct MsgPort *MyPort;
struct MsgPort *HDPort;

/*This function does the message handling*/
void DoMessage(WORD Command) {
	MyMsg->HD_Msg.mn_ReplyPort=MyPort;         /*Where HDOff should reply to...*/
	MyMsg->HD_Msg.mn_Node.ln_Type=NT_MESSAGE;
	MyMsg->HD_Msg.mn_Length=sizeof(struct HD);
	MyMsg->HD_Reserved=0L;                     /*To be sure!*/
	MyMsg->HD_Cmd=Command;                     /*Our command*/

	/*NOTE: Forbid'ing is essential! HDOff could go away right after we
	  got its port, and we would post a message to an invalid address!*/
	Forbid();
	if((HDPort=FindPort("HDOFF_PORT"))) {    /*Find HDOff's port address*/
	    PutMsg(HDPort, (struct Message  *) MyMsg);
	    Permit();
	    }
	else {              /*We couldn't find HDOff!*/
	    Permit();
	    printf("HDOff isn't active!\n");
	    FreeMem(MyMsg, sizeof(struct HD));
	    DeletePort(MyPort);
	    exit(RETURN_FAIL);
	    }
}

main() {

    /* Try to create a messageport without name and the priority -1*/
    if( !(MyPort=CreatePort(NULL, -1))) {
	printf("Couldn't create messageport!\n");
	exit(RETURN_FAIL);
	}

    /*Now we allocate the memory used for our messages*/
    if (MyMsg = (struct HD *) AllocMem(sizeof(struct HD), MEMF_PUBLIC | MEMF_CLEAR))
    {
	/*Call GetStats*/
	DoMessage(hd_GetStats);
	WaitPort(MyPort);      /*Wait for an answer...*/

	MyMsg = (struct HD *)GetMsg(MyPort);        /*Get the answer from the waiting stack*/

	/*Print every information we got:*/
	printf("Current status of HDOff:\nStart time HD0 : %d min\nStart time HD1 : %d min\nTime left HD0  : %d:%02d min\nTime left HD1  : %d:%02d min\nStatus HD0     : %s\nStatus HD1     : %s\nPort version   : %d.%02d\n",
		(MyMsg->HD_TimeHD0/60), (MyMsg->HD_TimeHD1/60),
		(MyMsg->HD_TimeLeftHD0/60), (MyMsg->HD_TimeLeftHD0%60),
		(MyMsg->HD_TimeLeftHD1/60), (MyMsg->HD_TimeLeftHD1%60),
					 ((MyMsg->HD_StatHD0)?"OFF":"ON"), ((MyMsg->HD_StatHD1)?"OFF":"ON"),
		((MyMsg->HD_PortVer)/100), ((MyMsg->HD_PortVer)%100));

	/*Check if our HDOff is new enough*/
	if(MyMsg->HD_PortVer>=104) {
	    /*Let`s see which Amiga we use*/
	    DoMessage(hd_QueryCtrl);
	    WaitPort(MyPort);      /*Wait for an answer...*/

	    MyMsg = (struct HD *)GetMsg(MyPort);        /*Get the answer from the waiting stack*/

	    /*And output what we got...*/
	    printf("Controller type: ");
	    switch(MyMsg->HD_StatHD0) {
		case 0: {printf("A600/A1200\n");break;}
		case 1: {printf("A4000\n");break;}
		case 2: {printf("CD32 Promodule\n");break;}
            }

	    /*Now get HDOff`s version string*/
	    DoMessage(hd_HDoffVersion);
	    WaitPort(MyPort);      /*Wait for an answer...*/

	    MyMsg = (struct HD *)GetMsg(MyPort);        /*Get the answer from the waiting stack*/

	    /*Output the version without leading $VER:*/
	    printf("Program version: %s\n", ((char *)(MyMsg->HD_PortVer))+6);
	    }

	FreeMem(MyMsg, sizeof(struct HD));
	} else
	    printf("Couldn't allocate message!\n");

    Forbid();
    while(MyMsg = (struct HD *)GetMsg(MyPort));

    DeletePort(MyPort);
    Permit();
    }
