home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d0xx / d038 / handler.lha / Handler / my-handler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-10-20  |  7.7 KB  |  242 lines

  1. /*  my-handler.c 
  2.  *
  3.  *  This is a "dumb" handler that can be used as a model. 
  4.  *  Functionally this handler does nothing but "play pretend" so I suppose 
  5.  *  you could classify my-handler as a NIL: AmigaDOS device.
  6.  * 
  7.  *  Phillip Lindsay  (C) 1986 Commodore 
  8.  *  You may freely distribute this source and use it for Amiga Development -
  9.  *  as long as the Copyright notice is left intact.
  10.  *   
  11.  *  (! Please note that support of non-BCPL modules  
  12.  *                                          is a new feature in release 1.2 !) 
  13.  *
  14.  * A sample "devs:mountlist" entry for a non-bcpl module:
  15.  * 
  16.  * (! PLEASE NOTE: that this is supported ONLY by the MOUNT command on
  17.  *     1.2 WORKBENCH release greater than 33.43 THANKS TO ANDY FINKEL !)     
  18.  *----------------------------------------------------------------------------- 
  19.  *   MY0:       Handler   = l:my-handler
  20.  *              Stacksize = 5000
  21.  *              Priority  = 5
  22.  *              GlobVec   = 1
  23.  *   #
  24.  * ----------------------------------------------------------------------------
  25.  * Since most people will not have the new MOUNT command I have included
  26.  *  a program that uses the expansion.library to install the device node. 
  27.  * 
  28.  * But PLEASE don't distribute AmigaDOS device handlers that use a 
  29.  * "install program." The "mountlist" in almost all cases (except AUTOCONFIG) 
  30.  *  should be taken advantage of for AmigaDOS device installation.
  31.  *
  32.  * I have done this under MANX, but I don't see too much trouble getting
  33.  * it to work with Lattice...just don't use any startup code and
  34.  * disable the stack checking on LC2 with '-v'. 
  35.  * 
  36.  */
  37.  
  38. #include <exec/types.h>
  39. #include <exec/nodes.h>
  40. #include <exec/lists.h>
  41. #include <exec/ports.h>
  42. #include <exec/libraries.h>
  43. #include <exec/devices.h>
  44. #include <exec/io.h>
  45. #include <exec/memory.h>
  46. #include <devices/console.h>
  47. #include <intuition/intuition.h>
  48. #include <libraries/dos.h>
  49. #include <libraries/dosextens.h>
  50. #include <libraries/filehandler.h>
  51.  
  52. #ifdef MANX
  53. #include <functions.h>
  54. #endif
  55.  
  56. #include "my-handler.h"
  57.  
  58. /* my version of BADDR() has no problems with casting */
  59. #undef  BADDR
  60. #define BADDR(x)    ((APTR)((long)x << 2))
  61.  
  62. #define ACTION_FIND_INPUT       1005L /* please refer to DOS Tech. Ref. */
  63. #define ACTION_FIND_OUTPUT      1006L
  64. #define ACTION_END              1007L
  65.  
  66. #define DOS_FALSE     0L
  67. #define DOS_TRUE    -1L           /* BCPL "TRUE" */
  68.  
  69. #ifdef MANX
  70. ULONG              SysBase, /* these are here to make the startup code happy */
  71.                    _savsp;  /* (this is unique to Manx Aztec C startup)      */ 
  72. #endif
  73.  
  74. _main() 
  75. {
  76.  
  77.  /* handler support routines */
  78.  
  79.  extern void           returnpkt(); /* sends a packet back to sender          */
  80.  struct DosPacket      *taskwait(); /* waits for packet from the world        */
  81.  
  82.  
  83.  /* handler related data structures */
  84.  
  85.  struct Process        *myproc;     /* my process                             */
  86.  struct DosPacket      *mypkt;      /* a pointer to the dos packet sent       */
  87.  BSTR                  parmdevname; /* pointer to device name in parmpkt Arg1 */
  88.  long                  parmextra;   /* extra info passed in parmpkt      Arg2 */
  89.  struct DeviceNode     *mynode;     /* our device node passed in parmpkt Arg3 */
  90.  struct FileHandle     *fh;         /* a pointer to our file handle           */
  91.  long                  open;        /* handler open flag                      */
  92.  long                  run;         /* handler main loop flag                 */
  93.  
  94. /* I have left all my debug's in...you'll see how they save you headaches
  95.  * the first time you try to debug your handler...
  96.  */
  97.  
  98. #ifdef DEBUG
  99.   kprintf("**** Start my-handler ****\n");
  100. #endif
  101.  
  102. /* misc. init. */
  103.  myproc          = (struct Process *) FindTask(0L);  /* find myself        */
  104.  open            = DOS_FALSE;                       /* not open            */
  105.  run             = TRUE;                           /* handler loop flag    */
  106.  
  107. /* since we were started as a non-BCPL module we get sent the parameter pkt */
  108. /* (ie. parameter packet not in D1) */
  109.  
  110. mypkt = taskwait();  /* wait for parameter packet */
  111.  
  112. #ifdef DEBUG
  113.  kprintf("Got Parmeter Packet.\n");
  114. #endif
  115.  
  116.  parmdevname     = (BSTR)  mypkt->dp_Arg1;  /* BSTR name passed to handler   */
  117.  parmextra       = mypkt->dp_Arg2;          /* Extra Info passed             */
  118.  
  119.  /* get pointer to our device node */
  120.  mynode = (struct DeviceNode *) BADDR(mypkt->dp_Arg3); /* ptr to device node */
  121.  
  122.  /*
  123.   * This is where you do your handler initialization
  124.   *  Open what ever devices ... parse the device name passed in
  125.   *  the parameter packet...etc...
  126.   */
  127.  
  128.  
  129. /* if initialzation was possible then we... */
  130.  
  131.  mynode->dn_Task = &myproc->pr_MsgPort; /* install our taskid ...
  132.                              * if we don't...for every reference to our handler
  133.                              * a NEW process will be created.  This is fine for
  134.                              * things like CON: (console handler) but if you
  135.                              * plan to be the only dude on block ( like the
  136.                              * file-system handler or SER: ) you should fill
  137.                              * the task field with your taskid 
  138.                              * (ie. &(pr_MsgPort) )
  139.                              * Note: remember that shared code has to be
  140.                              *  reentrant. (like CON: handler) 
  141.                              *  ( keep your variables on the stack [autos],
  142.                              *    and allocate memory for larger data
  143.                              *  structures and "FLAG" global data structures
  144.                              *  that need only be intialized once ) 
  145.                              */
  146. #ifdef DEBUG
  147.  kprintf("Returning parmeter packet...A-O-K.\n");
  148. #endif
  149.  
  150. returnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2);    /* everything a-o-k */
  151.  
  152. #ifdef DEBUG
  153.  kprintf("Waiting for packet..\n");
  154. #endif
  155.  
  156.  while(run)   /* start of the real work */
  157.   {
  158.    mypkt = taskwait();  /* wait for a packet */
  159.  
  160.    switch(mypkt->dp_Type)
  161.     {
  162.      case ACTION_FIND_INPUT:     /* opening your device */
  163.      case ACTION_FIND_OUTPUT: 
  164.  
  165. #ifdef DEBUG
  166.  kprintf("Action FindInput/Ouput : %ld\n",mypkt->dp_Type);
  167. #endif
  168.  
  169.           fh = (struct FileHandle *) BADDR(mypkt->dp_Arg1);  
  170.           fh->fh_Port = DOS_TRUE;
  171.           open++;
  172.           returnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2);
  173.           break;
  174.      
  175.      case ACTION_END:
  176.  
  177. #ifdef DEBUG
  178.  kprintf("Action End : %ld\n",mypkt->dp_Type);
  179. #endif
  180.  
  181. /* we want to fall out of the loop if not OPEN.
  182.  */
  183.  
  184.           if((--open) <= 0)  run = FALSE;
  185.          
  186.           returnpkt(mypkt,DOS_TRUE,mypkt->dp_Res2);
  187.           break;
  188.  
  189.      case ACTION_READ:
  190.  
  191. #ifdef DEBUG
  192.  kprintf("Action Read : %ld\n",mypkt->dp_Type);
  193. #endif
  194.  
  195. /* we *always* read nothing */
  196.  
  197.           returnpkt(mypkt,0L,mypkt->dp_Res2);
  198.           break;
  199.  
  200.      case ACTION_WRITE:
  201. #ifdef DEBUG
  202.  kprintf("Action Write : %ld\n",mypkt->dp_Type);
  203. #endif
  204.  
  205. /* we *always* write everything */
  206.  
  207.           returnpkt(mypkt,mypkt->dp_Arg3,mypkt->dp_Res2);   
  208.           break;
  209.  
  210.      default:
  211. #ifdef DEBUG
  212.  kprintf("Unknown packet type %ld\n",mypkt->dp_Type);
  213. #endif
  214. /* say what? */
  215.           returnpkt(mypkt,DOS_FALSE,ERROR_ACTION_NOT_KNOWN);
  216.  
  217.     } /* end of switch(mypkt->dp_Type) */   
  218.     
  219.   } /* end of while(run) */
  220.  
  221.  
  222.  mynode->dn_Task = FALSE; /* zero the taskid field of device node */
  223.  
  224.  /* INSERT HERE -> do some clean up and leave */
  225.  
  226. /* we are a process "so we fall off the end of the world" */
  227.  
  228. /*  If we are reentrant we can't rely on our initial stack being saved.
  229.  *  Which means NO exit()'s ... We must just fall through....If your
  230.  *  not reentrant then don't worry about ending here.
  231.  *
  232.  * BTW, you don't necessarlly have to leave...You could stick around and
  233.  * wait all day for packets....its all according to what your handler
  234.  * is set-up to do. 
  235.  */
  236.  
  237. } /* end of _main() */
  238.  
  239.  
  240.  
  241. /* EOF - end of my-handler */
  242.