[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

/*
 * Key_Reset.c
 *
 * This is in two parts...
 *
 * Compile this C code with SAS C 5.10:
 *      lc -b1 -cfistq -v -y Key_Reset
 *
 * Assemble the ASM code with Adapt
 *  HX68 KeyHandler.a to KeyHandler.o
 *
 * Link with:
 * Blink FROM LIB:c.o+Key_Reset.o+KeyHandler.o TO
 *        Key_Reset LIB LIB:lc.lib LIB:amiga.lib
 */

/*
 * Keyboard device reset handler example...
 */
#include <exec/types.h>
#include <exec/io.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <devices/keyboard.h>
#include <intuition/intuition.h>
#include <exec/interrupts.h>

#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/dos_protos.h>

#include <stdio.h>

#ifdef LATTICE
int CXBRK(void) { return(0); }     /* Disable SAS CTRL/C handling */
int chkabort(void) { return(0); }  /* really */
void main();
#endif

extern VOID ResetHandler();

UBYTE NameString[]="Reset Handler Test";

struct NewWindow mywin={0,0,178,10,0,1,CLOSEWINDOW,
                      WINDOWDRAG|WINDOWCLOSE|SIMPLE_REFRESH|NOCAREREFRESH
                      NULL,NULL,NameString,NULL,NULL,0,0,0,0,WBENCHSCREEN};

extern struct IntuitionBase *IntuitionBase;

struct MyData
    {
    struct Task  *MyTask;
           ULONG MySignal;
    };

/*
 * This routine opens a window and waits for the one event that
 * can happen (CLOSEWINDOW)
 */
short WaitForUser(ULONG MySignal)
{
struct Window  *win;
       short   ret=0;

if (IntuitionBase=(struct IntuitionBase *)
                   OpenLibrary("intuition.library",0L))
    {
    if (win=(struct Window *)OpenWindow(&mywin))
        {
        ret=(MySignal==Wait(MySignal | (1L << win->UserPort->mp_SigBit)));
        CloseWindow(win);
        }
    else
        printf("Error: Could not open window\n");
    CloseLibrary((struct Library *)IntuitionBase);
    }
else
    printf("Error: Could not open intution.library\n");
return(ret);
}

VOID main(int argc, char *argv[])
{
struct IOStdReq  *KeyIO;
struct MsgPort   *KeyMP;
struct Interrupt *keyHandler;
struct MyData    MyDataStuff;
       ULONG     MySignal;

if ((MySignal=AllocSignal(-1L))!=-1)
    {
    MyDataStuff.MyTask=FindTask(NULL);
    MyDataStuff.MySignal=1L << MySignal;

    if (KeyMP=CreatePort(NULL,NULL))
        {
        if (keyHandler =
                AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR))
            {
            if (KeyIO=(struct IOStdReq *)
                      CreateExtIO(KeyMP,sizeof(struct IOStdReq)))
                {
                if (!OpenDevice("keyboard.device",NULL,(struct IORequest *)
                                                        KeyIO,NULL))
                    {
                    keyHandler->is_Code=ResetHandler;
                    keyHandler->is_Data=(APTR)&MyDataStuff;

                    /*
                     * Note that only software interrupt priorities
                     * can be used for the .ln_Pri on the reset
                     * handler...
                     */
                    keyHandler->is_Node.ln_Pri=16;

                    keyHandler->is_Node.ln_Name=NameString;
                    KeyIO->io_Data=(APTR)keyHandler;
                    KeyIO->io_Command=KBD_ADDRESETHANDLER;
                    DoIO((struct IORequest *)KeyIO);

                    if (WaitForUser(MyDataStuff.MySignal))
                        {
                        if (argc) /* Check for CLI */
                            {
                            printf("System going down\n");
                            printf("Cleaning up...\n");
                            /* Show a delay, like cleanup... */
                            Delay(20);
                            printf("*Poof*\n");
                            }
                        /* We are done with our cleanup */

                        KeyIO->io_Data=(APTR)keyHandler;
                        KeyIO->io_Command=KBD_RESETHANDLERDONE;
                        DoIO((struct IORequest *)KeyIO);
                        /*
                         * Note that since the above call
                         * tells the system it is safe to reboot
                         * and will cause the reboot if this
                         * task was the last to say so, the call
                         * never really returns...  The system
                         * just reboots...
                         */
                        }

                    KeyIO->io_Data=(APTR)keyHandler;
                    KeyIO->io_Command=KBD_REMRESETHANDLER;
                    DoIO((struct IORequest *)KeyIO);

                    CloseDevice((struct IORequest *)KeyIO);
                    }
                else
                    printf("Error: Could not open keyboard.device\n");

                DeleteExtIO((struct IORequest *)KeyIO);
                }
            else
                printf("Error: Could not create I/O request\n");

            FreeMem(keyHandler,sizeof(struct Interrupt));
            }
        else
            printf("Error: Could not allocate memory for interrupt\n");

        DeletePort(KeyMP);
        }
    else
        printf("Error: Could not create message port\n");

    FreeSignal(MySignal);
    }
else
    printf("Error: Could not allocate signal\n");
}
\kern -20pt
************************************************************************
*       KeyHandler.a
*
* Keyboard reset handler that signals the task in the structure...
*
* See Key_Reset.c for details on how to compile/assemble/link...
*
************************************************************************
* Required includes...
*
        INCDIR  "include:"
        INCLUDE "exec/types.i"
        INCLUDE "exec/io.i"
        INCLUDE "devices/keyboard.i"
*
        xref    _AbsExecBase    ; We get this from outside...
        xref    _LVOSignal      ; We get this from outside...
*
************************************************************************
* Make the entry point external...
*
        xdef    _ResetHandler
*
************************************************************************
*
* This is the input handler
* The is_Data field is passed to you in a1.
*
* This is the structure that is passed in A1 in this example...
*
        STRUCTURE       MyData,0
        APTR            MyTask
        ULONG           MySignal
*
************************************************************************
* The handler gets called here...
*
_ResetHandler:  move.l  MySignal(a1),d0 ; Get signal to send
                move.l  MyTask(a1),a1           ; Get task
*
* Now signal the task...
*
                move.l  a6,-(sp)        ; Save the stack...
                move.l  _AbsExecBase,a6 ; Get ExecBase
                jsr     _LVOSignal(a6)  ; Send the signal
                move.l  (sp)+,a6        ; Restore A6
*
* Return to let other handlers execute.
*
                rts                     ; return from handler...
*
                END
************************************************************************