home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / e / amigae / rkrmsrc / exec_library / interrupts / timersoftint.e < prev    next >
Text File  |  1995-04-05  |  4KB  |  125 lines

  1. -> timersoftint.e - Timer device software interrupt message port example.
  2.  
  3. -> E-Note: we need eCodeSoftInt() in order to execute E code as an interrupt
  4. MODULE 'amigalib/io',
  5.        'amigalib/lists',
  6.        'other/ecode',
  7.        'devices/timer',
  8.        'dos/dos',
  9.        'exec/interrupts',
  10.        'exec/io',
  11.        'exec/memory',
  12.        'exec/nodes',
  13.        'exec/ports'
  14.  
  15. ENUM ERR_NONE, ERR_DEVICE, ERR_ECODE, ERR_TIMER
  16.  
  17. RAISE ERR_DEVICE IF OpenDevice()<>0
  18.  
  19. CONST MICRO_DELAY=1000
  20.  
  21. ENUM OFF, ON, STOPPED
  22.  
  23. OBJECT tsiData
  24.   counter
  25.   flag
  26.   port:PTR TO mp
  27. ENDOBJECT
  28.  
  29. DEF tsidata=NIL:PTR TO tsiData
  30.  
  31. PROC main() HANDLE
  32.   DEF port=NIL:PTR TO mp, softint=NIL:PTR TO is, tr:PTR TO timerequest,
  33.       endcount, code
  34.  
  35.   -> Allocate message port, data and interrupt objects.  Don't use createPort()
  36.   -> or CreateMsgPort() since they allocate a signal (don't need that) for a
  37.   -> PA_SIGNAL type port.  We need PA_SOFTINT.
  38.   tsidata:=NewM(SIZEOF tsiData, MEMF_PUBLIC OR MEMF_CLEAR)
  39.   port:=NewM(SIZEOF mp, MEMF_PUBLIC OR MEMF_CLEAR)
  40.   newList(port.msglist)  -> Initialise message list
  41.   softint:=NewM(SIZEOF is, MEMF_PUBLIC OR MEMF_CLEAR)
  42.  
  43.   -> Set up the (software) interrupt structure.  Note that this task runs at
  44.   -> priority 0.  Software interrupts may only be priority -32, -16, 0, +16,
  45.   -> +32. Also not that the correct node type for a software interrupt is
  46.   -> NT_INTERRUPT.  (NT_SOFTINT is an internal Exec flag).  This is the same
  47.   -> setup as that for a software interrupt which you Cause().
  48.   -> E-Note: We can initialise data here to contain a pointer to shared data
  49.   ->         structures.  The interrupt routine will receive the data in A1.
  50.   -> E-Note: eCodeSoftInt() protects an E function and preserves non-scratch
  51.   ->         registers so you can call it from, for instance, interrupts.
  52.   IF NIL=(code:=eCodeSoftInt({tsoftcode})) THEN Raise(ERR_ECODE)
  53.   softint.code:=code  -> The software interrupt routine
  54.   softint.data:=tsidata
  55.   softint.ln.pri:=0
  56.  
  57.   port.ln.type:=NT_MSGPORT  -> Set up the PA_SOFTINT message port (no need to
  58.   port.flags:=PA_SOFTINT    -> make this port public).
  59.   port.sigtask:=softint  -> Pointer to interrupt object
  60.  
  61.   -> Allocate timerequest
  62.   IF NIL=(tr:=createExtIO(port, SIZEOF timerequest)) THEN Raise(ERR_TIMER)
  63.  
  64.   -> Open timer.device.  0 is success
  65.   OpenDevice('timer.device', UNIT_MICROHZ, tr, 0)
  66.   tsidata.flag:=ON  -> Init data structure to share globally.
  67.   tsidata.port:=port
  68.  
  69.   -> Send of the first timerequest to start.  IMPORTANT: Do NOT beginIO() to
  70.   -> any device other than audio or timer from within a software or hardware
  71.   -> interrupt.  The beginIO() code may allocate memory, wait or perform other
  72.   -> functions which are illegal or dangerous during interrupts.
  73.   WriteF('starting softint.  CTRL-C to break...\n')
  74.  
  75.   tr.io.command:=TR_ADDREQUEST  -> Initial iorequest to start
  76.   tr.time.micro:=MICRO_DELAY    -> software interrupt
  77.   beginIO(tr)
  78.  
  79.   Wait(SIGBREAKF_CTRL_C)
  80.   endcount:=tsidata.counter
  81.   WriteF('timer softint counted \d milliseconds.\n', endcount)
  82.  
  83.   WriteF('Stopping timer...\n')
  84.   tsidata.flag:=OFF
  85.  
  86.   WHILE tsidata.flag<>STOPPED DO Delay(10)
  87.   CloseDevice(tr)
  88.  
  89. EXCEPT DO
  90.   IF tr THEN deleteExtIO(tr)
  91.   IF softint THEN Dispose(softint)
  92.   IF port THEN Dispose(port)
  93.   IF tsidata THEN Dispose(tsidata)
  94.   SELECT exception
  95.   CASE ERR_DEVICE;  WriteF('Couldn''t open timer.device\n')
  96.   CASE ERR_ECODE;   WriteF('Ran out of memory in eCodeSoftInt()\n')
  97.   CASE ERR_TIMER;   WriteF('Couldn''t create timerequest\n')
  98.   CASE "MEM";       WriteF('Ran out of memory\n')
  99.   ENDSELECT
  100. ENDPROC
  101.  
  102. PROC tsoftcode(data)
  103.   DEF tr:PTR TO timerequest
  104.   -> E-Note: thanks to eCodeSoftInt() we get the softint.data as an argument,
  105.   ->         so we could use that instead of the global tsidata.  This means
  106.   ->         that tsidata could be made local to main()...
  107.  
  108.   -> Remove the message from the port.
  109.   tr:=GetMsg(tsidata.port)
  110.  
  111.   -> Keep on going if main() hasn't set flag to OFF.
  112.   IF tr AND (tsidata.flag=ON)
  113.     -> Increment counter and re-send timerequest -- IMPORTANT: This
  114.     -> self-perpetuating technique of calling beginIO() during a software
  115.     -> interrupt may only be used with the audio and timer device.
  116.     tsidata.counter:=tsidata.counter+1
  117.     tr.io.command:=TR_ADDREQUEST
  118.     tr.time.micro:=MICRO_DELAY
  119.     beginIO(tr)
  120.   ELSE
  121.     -> Tell main() we're out of here.
  122.     tsidata.flag:=STOPPED
  123.   ENDIF
  124. ENDPROC
  125.