From: tomme@Minsk.docs.uu.se (Thomas Holmstr|m)
Newsgroups: comp.sys.amiga.programmer
Subject: InputHandler debugging (long)
Date: 14 Dec 92 20:31:18 GMT
Organization: Uppsala University
NNTP-Posting-Host: minsk.docs.uu.se




I am having some trouble with a piece of code which will be hooked into
the input handler list. The program always crash on the Signal() (1*) in the
handler routine when I push a key. It works fine if I comment out the
Signal() (ie. it doesn't do *anything* until I break it). I can send the
task the signal from Xoper and that works fine.
	Part of the problem is that I cannot find a good way of debugging
interrupts. I don't have any streams to write info to, do I? I've looked
at similar code hooking into the input handler list and I think I do
that the right way. Sorry for the somewhat log posting, I don't think
I could make it any shorter and still keep the relevant parts in.
	I'm using Dice, the registered version, and since it supports
registered arguments I really would like to use that instead of an
assembler routine, but when I declare the function as __regargs the reference
at (2*) uses _InputHandler (or _C_InputHandler) when it should be
@InputHandler. I've tried to redefined the Interrupt struct as
> struct Interrupt {
>    struct  Node is_Node;
>    APTR    is_Data;
>    VOID    (__regargs)(*is_Code)();}
or something like that (I'm not at my computer right now). How to do this?


Thanks in advance for any comments and/or suggestions.


The program:
/************************* Global declarations ***************************/
struct HandlerData {
  struct MsgPort *parentport;
  struct Task *parenttask;
  ULONG unblanksig;
} handlerdata;
struct Process *process;
ULONG handlersig, timersig, unblanksig;

/*********************** Main function ************************/
void main(void) {
  init();
  while(locked) {
    ULONG wsigs = handlersig | timersig | unblanksig | SIGBREAKF_CTRL_C;
    signals = Wait(wsigs);
    if(signals & SIGBREAKF_CTRL_C) {
	/* Cleanup and exit */
    }
    if(signals & handlersig) {
	/* Handle message */
    }
    if(signals & timersig) blank();
    if(signals & unblanksig) unblank();
  }
  cleanup();
}

/*********************** Init code **************************/
[...]
  if(!(process = (struct Process *)FindTask(NULL))) {
	/* Error */
  }
[...]
  if(!(handlerport = CreatePort(HPORT_NAME, HPORT_PRI))) {
	/* Error */
  }
  handlersig = (1 << (handlerport->mp_SigBit));
[...]
  if((usignr = AllocSignal(-1)) == -1) {
	/* Error */
  }
  unblanksig = (1 << usignr);
[...]
  inputreq->io_Command = IND_ADDHANDLER;
  inputreq->io_Data = &interrupt;
  interrupt.is_Node.ln_Pri = HANDLER_PRI;	/* #defined as 10 */
  handlerdata.parentport = handlerport;
  handlerdata.parenttask = &(process->pr_Task);
  handlerdata.unblanksig = unblanksig;
  interrupt.is_Data = &handlerdata;
  interrupt.is_Code = InputHandler; /* InputHandler calls C_InputHandler (2*) */
  if(DoIO(inputreq)) {
	/* Error */
  }

/*********** Input handler, called with stack-arguments ***************/
struct InputEvent *
	C_InputHandler(struct InputEvent *ev, struct HandlerData *data) {
  struct InputEvent *currev, *retev, *procev, *tmpev;
  currev = ev; retev = procev = NULL;
  while(currev) {
    tmpev = currev->ie_NextEvent;
    switch(currev->ie_Class) {
      case IECLASS_RAWKEY :
      case IECLASS_RAWMOUSE :
	Signal(data->parenttask, data->unblanksig);  /* Crash here!! (1*) */
	break;
      default :
    }
    currev = tmpev;
  }
  return ev;
}

/*********** _InputHandler called with register arguments *************/
		xref	_C_InputHandler
		xdef	_InputHandler
_InputHandler:	movem.l	A0/A1,-(A7)
		jsr     _C_InputHandler
		addq.l	#8,A7
		rts
		end
--
_/_/_/_/_/   _/    _/         Thomas  Holmstr|m
   _/       _/_/_/_/        tomme@Student.docs.uu.se
  _/       _/    _/            +46 18 261628
 _/       _/    _/   DVL, University of Uppsala, Sweden