/*
* 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
************************************************************************