Amiga.org
Operating System Specific Discussions => Amiga OS => Amiga OS -- Development => Topic started by: Sidewinder on November 11, 2004, 10:22:26 PM
-
I'm attempting to develop a way to Wait() for mouse inputs rather than using a busy loop. I was thinking about useing an interrupt handler to do this by setting a signal when there is a change to the I/O ports, but there is something wrong with my code. Can anyone help me figure out what I'm doing wrong here?
#include <stdio.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <hardware/intbits.h>
#include <libraries/lowlevel.h>
#include <devices/timer.h>
#include <clib/exec_protos.h>
#include <clib/lowlevel_protos.h>
#include <clib/timer_protos.h>
struct Library *LowlevelBase = NULL;
struct Library *TimerBase = NULL;
struct Interrupt *IOPortInterrupt, *PriorInterrupt;
struct Task *task;
BYTE signalBit;
void IOPortInterruptHandler(void);
int main(void)
{
LowlevelBase = OpenLibrary("lowlevel.library", 0L);
IOPortInterrupt = (struct Interrupt *)AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC);
if (LowlevelBase && IOPortInterrupt)
{
struct timerequest TimerIO;
struct timeval time;
ULONG portState = 0;
ULONG lastState = 0;
ULONG signals;
if (!OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)&TimerIO, 0))
{
TimerBase = (struct Library *)TimerIO.tr_node.io_Device;
IOPortInterrupt->is_Node.ln_Type = NT_INTERRUPT;
IOPortInterrupt->is_Node.ln_Pri = 0;
IOPortInterrupt->is_Node.ln_Name = "PortIOInterrupt";
IOPortInterrupt->is_Data = NULL;
IOPortInterrupt->is_Code = IOPortInterruptHandler;
task = FindTask(NULL);
signalBit = AllocSignal(-1);
signals = (1L << signalBit);
PriorInterrupt = SetIntVector(INTB_PORTS, IOPortInterrupt);
SetJoyPortAttrs(1, SJA_Type, SJA_TYPE_MOUSE);
do
{
Wait(signals);
portState = ReadJoyPort(1);
if (portState != lastState)
{
GetSysTime(&time);
printf("%d sec, %d micro\n", time.tv_secs, time.tv_micro);
lastState = portState;
}
}
while (GetKey() != 64); /* Press Space-Bar to Exit. */
SetJoyPortAttrs(1, SJA_Reinitialize);
SetIntVector(INTB_PORTS, PriorInterrupt);
}
}
if (LowlevelBase)
{
CloseLibrary(LowlevelBase);
}
return 0;
}
void IOPortInterruptHandler(void)
{
Signal(task, (1L << signalBit));
return;
}
-
Why make it this complex, why not use IDCMP? Another easy way would be using input.device/IND_ADDHANDLER to add an input handler.
-
@Piru
Well, mainly because I'm not really interested in the events. I'm more interested in the data at the port and I can read the data directly with ReadJoyPort(). But I need a way to pause the program until that data at the port changes.
-
Topic hijack...
I also need to investigate the possiblitiy of a low level/low latency wait for hardware interrupt that may be generated by my graphics card on completion of a rendering operation.
I know I can (assuming I know exactly which interrupt to use) send the task to sleep and then use an interrupt handler to signal it when the time comes, but is there a lower latency way?
Anybody had any real experience with this kind of thing?