[comp.sys.amiga.tech] Analog Joystick Driver

dbk@fbog.UUCP (Dave B. Kinzer @ Price Rd. GEG) (11/07/88)

   I've been working on the Vertical blanking period interrupt *server*
and I have made a couple of assumptions about this.  I'd like to check
this out with some more experienced types.

  1)  I have assumed that I am allowed to do a ReplyMsg during the
      server routine (to complete the I/O request).

  2)  I am allowed access to the user's data space during the routine in
      order to write the input event to the user's data buffer (clearly
      works now but has implications should process data space eventually
      become protected).  Are messages and I/O requests required to be in
      shared memory?

Advance Thanks!
More questions to follow, I'm sure.

-- 
|     // You've heard of CATS and DOGS, I'm from GOATS, Dave Kinzer         |
|    //  Gladly Offering All Their Support!             noao!nud!fbog!dbk   |
|  \X/   "My employer's machine, my opinion."           (602) 897-3085      |

cs161agc@sdcc10.ucsd.EDU (John Schultz) (01/17/89)

  Ok, here's an analog joystick driver for the right mouse port.  I've
tried to make it as "legal" as possible.  Previous versions for my
own use locked out intuition (I starved it's input events), which
wasn't very friendly.  So this version uses the Potgo Resource.
Only one slight problem; FreePotbits doesn't seem to work.  I've
coded these routines in Benchmark and Lattice 5.0, and FreePotgobits
does nada (Or I is doing somting ron?).  So, the program works the
first time, but can't allocate the necessary bits the second time.
I've tried "freeing" my first request, then trying again as per the
RKM docs, but that no work either.  Answers anyone?

  Anyway, here's the code in Benchmark:

MODULE AJoystick;

FROM SYSTEM IMPORT ADR,ADDRESS,BYTE,INLINE,REG,SHIFT;
FROM CustomHardware IMPORT custom;
FROM Interrupts IMPORT
  Interrupt,InterruptPtr,AddIntServer,RemIntServer,
                Disable,Enable;
FROM INTHardware IMPORT INTVertB;
FROM Nodes IMPORT NTInterrupt;
FROM Memory IMPORT AllocMem,FreeMem,MemReqSet,MemPublic;
FROM Terminal IMPORT BusyRead;
FROM TermInOut IMPORT WriteCard,WriteString,Write,WriteInt,WriteLn;

FROM Resources IMPORT OpenResource;
FROM PotgoResource IMPORT
PotgoName,PotgoBase,AllocPotBits,FreePotBits,
                          WritePotgo;

CONST
  A1   = 9;
  WORD = BITSET(1);      (* Clear bits 15,13, set bit 0 *)
  MASK = BITSET(0A001H); (* Write to bits 15, 13, and 0 *)

TYPE
  cardptr = POINTER TO CARDINAL;

VAR

  ch        : CHAR;

  AStickInt : InterruptPtr;

  ajx,ajy   : INTEGER;

  allocmask : BITSET;

  pot1dat,
  temp      : cardptr;
  pot1val   : CARDINAL;

  OpenedAOK : BOOLEAN;

PROCEDURE ReadPots(): LONGCARD;
BEGIN
  temp := cardptr(REG(A1));
  INLINE(48E7H,3F3EH); (* Push *)
  Disable;

  pot1val := temp^;
  WritePotgo(WORD,MASK);

  Enable;
  INLINE(4CDFH,7CFCH); (* Pop *)
  RETURN 0D;
END ReadPots;

PROCEDURE OpenAJoystick(): BOOLEAN;
BEGIN

  OpenedAOK := FALSE;

  PotgoBase := OpenResource(ADR(PotgoName));
  IF PotgoBase = NIL THEN
    WriteString("Couldn't open PotgoResouce.\n");
    RETURN FALSE;
  END;
  
  allocmask := AllocPotBits(MASK);
  IF allocmask # MASK THEN
    WriteString("Couldn't AllocPotBits 15,13, and 0.\n");
    FreePotBits(allocmask);
    RETURN FALSE;
  END; (* IF *)

  AStickInt := AllocMem(SIZE(Interrupt),MemReqSet{MemPublic});
  IF AStickInt = NIL THEN
    WriteString("No Public Memory for AStickInt.\n");
    FreePotBits(allocmask);
    RETURN FALSE;
  END;

  WITH AStickInt^ DO
    isNode.lnType := NTInterrupt;
    isNode.lnPri  := BYTE(10);
    isNode.lnName := ADR("AnalogJoystick");
    isCode        := ADR(ReadPots);
    isData        := ADR(custom^.pot1dat);
  END; (* WITH AStickInt *) 

  AddIntServer(INTVertB,AStickInt^);

  OpenedAOK := TRUE;

END OpenAJoystick;

PROCEDURE CloseAJoystick;
BEGIN
  IF OpenedAOK THEN
    RemIntServer(INTVertB,AStickInt^);
    FreeMem(AStickInt,SIZE(Interrupt));
    FreePotBits(allocmask);
  END;
END CloseAJoystick;

PROCEDURE ReadAJoystick(VAR x,y : INTEGER);
BEGIN
  x := SHIFT(pot1val,-8); (* in C: x = potval >> 8 *)
  y := INTEGER(BITSET(pot1val)*BITSET(0FFH)); (* C: y = potval &
0xff *)
END ReadAJoystick;

BEGIN

  IF NOT OpenAJoystick() THEN RETURN; END;
  ch := 0C;
  REPEAT
    ReadAJoystick(ajx,ajy);
    WriteString(" potx: ");
    WriteInt(ajx,4);
    WriteString(" poty: ");
    WriteInt(ajy,4);
    WriteString("     \r");
    BusyRead(ch);
  UNTIL ch # 0C;
  CloseAJoystick;
END AJoystick.