home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / datafiles / text / c_manual / devices / paralleldevice / example2.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  16KB  |  425 lines

  1. /***********************************************************/
  2. /*                                                         */
  3. /* Amiga C Encyclopedia (ACE) V3.0      Amiga C Club (ACC) */
  4. /* -------------------------------      ------------------ */
  5. /*                                                         */
  6. /* Book:    ACM Devices                 Amiga C Club       */
  7. /* Chapter: Parallel Device             Tulevagen 22       */
  8. /* File:    Example2.c                  181 41  LIDINGO    */
  9. /* Author:  Anders Bjerin               SWEDEN             */
  10. /* Date:    92-04-26                                       */
  11. /* Version: 1.00                                           */
  12. /*                                                         */
  13. /*   Copyright 1992, Anders Bjerin - Amiga C Club (ACC)    */
  14. /*                                                         */
  15. /* Registered members may use this program freely in their */
  16. /*     own commercial/noncommercial programs/articles.     */
  17. /*                                                         */
  18. /***********************************************************/
  19.  
  20.  
  21.  
  22. /* This example is rather similar to Example 1, but this time    */
  23. /* we do not wait for the parallel port to complete our request. */
  24. /* Instead we do somethings (well not very much) and now and     */
  25. /* then checks if the request has been completed.                */
  26.  
  27.  
  28.  
  29. #include <exec/types.h>       /* STRPTR           */
  30. #include <devices/parallel.h> /* Parallel Device  */
  31.  
  32.  
  33.  
  34. /* Size of our data buffer: */
  35. #define MY_BUFFER_SIZE 200
  36.  
  37. /* Parallel flags: (Check for end-of-file characters.) */
  38. #define PARALLEL_FLAGS PARF_EOFMODE
  39.  
  40. /* Additional flags: (Nothing) */
  41. #define ADDITIONAL_FLAGS 0
  42.  
  43.  
  44.  
  45. /* Declare a pointer to our reply port: */
  46. struct MsgPort *replymp = NULL;
  47.  
  48. /* Declare a pointer to our parallel request block: */
  49. struct IOExtPar *parallel_req = NULL;
  50.  
  51. /* Store the parallel device error here: */
  52. UWORD parallel_dever = TRUE;
  53.  
  54. /* Declare our data buffer: */
  55. BYTE buffer[ MY_BUFFER_SIZE ];
  56.  
  57.  
  58.  
  59. /* Declare our functions: */
  60.  
  61. /* Our main function: */
  62. void main();
  63.  
  64. /* Clears and removes everything nice and neatly: */
  65. void clean_up( UBYTE error, STRPTR text );
  66.  
  67. /* Sets the parallel parameters: */
  68. UBYTE SetParParams(
  69.   struct IOExtPar *ioreq,
  70.   UBYTE parallel_flags,
  71.   ULONG extended_flags,
  72.   UBYTE *eof_chars
  73. );
  74.  
  75. /* Explains error messages: */
  76. void ParError( UBYTE error );
  77.  
  78. /* Sends data to the parallel device without waiting: */
  79. void ParWriteNoWait(
  80.   struct IOExtPar *ioreq,
  81.   BYTE *data,
  82.   ULONG length
  83. );
  84.  
  85. /* Collects data from the parallel device without waiting: */
  86. void ParReadNoWait(
  87.   struct IOExtPar *ioreq,
  88.   BYTE *data,
  89.   ULONG length
  90. );
  91.  
  92.  
  93.  
  94. void main()
  95. {
  96.   /* Error number: */
  97.   UBYTE error;
  98.   
  99.   /* The eight end-of-file characters: */
  100.   /* They MUST be in descending order! */
  101.   UBYTE eof_char[8]={ 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00 };
  102.  
  103.   /* Declare a pointer and set it to NULL: */
  104.   struct IOExtPar *ptr = NULL;
  105.   
  106.   
  107.   
  108.   /* Get a reply port: (No name, priority 0) */
  109.   replymp = (struct MsgPort *)
  110.     CreatePort( NULL, 0 );
  111.   if( !replymp )
  112.     clean_up( 0, "Could not create the reply port!" );
  113.  
  114.  
  115.  
  116.   /* Create a parallel request block: */
  117.   parallel_req = (struct IOExtPar *)
  118.     CreateExtIO( replymp, sizeof( struct IOExtPar ) );
  119.   if( !parallel_req )
  120.     clean_up( 0, "Not enough memory for the parallel request block!" );
  121.  
  122.  
  123.  
  124.   /* Open the Parallel Device: */
  125.   parallel_dever = OpenDevice( PARALLELNAME, 0, parallel_req, 0 );
  126.   if( parallel_dever )
  127.     clean_up( parallel_dever, "Could not open the Parallel Device!" );
  128.  
  129.  
  130.  
  131.   /* Set the parallel device's parameters: */
  132.   error = (UBYTE) SetParParams(
  133.     parallel_req,     /* Pointer to our parallel request block.        */
  134.     PARALLEL_FLAGS,   /* Parallel flags.                               */
  135.     ADDITIONAL_FLAGS, /* Additional flags.                             */
  136.     eof_char          /* Pointer to an array of eight end-of-file chr. */
  137.   );
  138.  
  139.   /* OK? */
  140.   if( error )
  141.     clean_up( error, "Could not set the parallel parameters!" );
  142.  
  143.  
  144.  
  145.   /* Send 0 bytes to the parallel port and return immediately: */
  146.   ParWriteNoWait( parallel_req, buffer, 0 ); 
  147.  
  148.  
  149.   /* As long as the pointer is not pointing to */
  150.   /* the request we should stay in the loop:   */
  151.   while( ptr == NULL )
  152.   {
  153.     /*   ... do something ...    */
  154.     /* Well, I do not know what. */
  155.   
  156.     /* Check if the request has been completed: (If the  */
  157.     /* request has been compleded CheckIO() will return  */
  158.     /* a pointer to the request, else NULL is returned.) */
  159.     ptr = (struct IOExtPar *) CheckIO( parallel_req );
  160.   }
  161.  
  162.   /* At last the request was completed! */
  163.  
  164.  
  165.   /* Remove the requstblock's message. (The ptr and ioreq */
  166.   /* are in this example identical, so it does not matter */
  167.   /* whichever you will use. The paranteces around the    */
  168.   /* expression is actually unnecessary, but this looks   */
  169.   /* better.)                                             */
  170.   Remove( &(ptr->IOPar.io_Message.mn_Node) );
  171.  
  172.  
  173.   /* Check if everything is OK? */
  174.   if( parallel_req->IOPar.io_Error )
  175.     ParError( error );
  176.   else
  177.     printf( "Data sent without any problems!\n" );
  178.  
  179.  
  180.  
  181.   /* Clean up and quit: */
  182.   clean_up( 0, "The End!" );
  183. }
  184.  
  185.  
  186.  
  187. /* Close and return everything that has been */
  188. /* opened and allocated before we quit:      */
  189.  
  190. void clean_up( UBYTE error, STRPTR text )
  191. {
  192.   /* Print some information about the problem: */
  193.   if( error )
  194.     ParError( error );
  195.  
  196.   /* Close the Parallel Device: */ 
  197.   if( !parallel_dever )
  198.     CloseDevice( parallel_req );
  199.  
  200.   /* Deallocate the parallel request block: */
  201.   if( parallel_req )
  202.     DeleteExtIO( parallel_req, sizeof( struct IOExtPar ) );
  203.  
  204.   /* Remove the replyport: */
  205.   if( replymp )
  206.     DeletePort( replymp);
  207.  
  208.  
  209.   /* Print the message: */
  210.   printf( "%s\n", text );
  211.  
  212.   /* Quit: */
  213.   exit( 0 );
  214. }
  215.  
  216.  
  217.  
  218. /* SetParParams() sets the parallel parameters. It initializes a IOExtPar  */
  219. /* structure, and does a PDCMD_SETPARAMS commad. If everything is OK it    */
  220. /* returns NULL, else an error number is returned.                         */
  221. /*                                                                         */
  222. /* Synopsis: er = SetParParams( io, bl, br, bt, rl, wl, sl, sf, ef, chr ); */
  223. /*                                                                         */
  224. /* er:       (UBYTE) SetParParams() returns 0 if everything was OK, else   */
  225. /*           an error value is returned. See function ParError() for more  */
  226. /*           information.                                                  */
  227. /*                                                                         */ 
  228. /* io:       (struct IOExtPar *) Pointer to the parallel request block you */
  229. /*           want to initialize.                                           */
  230. /*                                                                         */
  231. /*           PARF_RAD_BOOGIE Not supported by the parallel device for the  */
  232. /*                           moment.                                       */
  233. /*                                                                         */
  234. /*           PARF_SHARED     Set this flag if you want to allow other      */
  235. /*                           tasks running at the same time to use the     */
  236. /*                           parallel device. The default is exclusive-    */
  237. /*                           access. (If some other task is using the      */
  238. /*                           parallel device with the shared bit set, and  */
  239. /*                           you call this function with exclusive access, */
  240. /*                           your request will fail.)                      */
  241. /*                                                                         */
  242. /*           PARF_EOFMODE    Set this flag if you want to check for end of */
  243. /*                           file characters. (You may use up to eight end */
  244. /*                           of file characters, which are specified       */
  245. /*                           below.)                                       */
  246. /*                                                                         */
  247. /* ef:       (ULONG) Not supported by the parallel device for the moment.  */
  248. /*                                                                         */
  249. /* chr:      (UBYTE *) Pointer to an array containing eight end-of-file    */
  250. /*           characters. If the parallel flag "PARF_EOFMODE" is set, the   */
  251. /*           parallel device will check each character which is sent or    */
  252. /*           received, and if it matches one of the end-of-file characters */
  253. /*           the read/wite request is terminated.                          */
  254.  
  255. UBYTE SetParParams(
  256.   struct IOExtPar *ioreq, /* Pointer to our parallel request block.        */
  257.   UBYTE parallel_flags,   /* Parallel flags.                               */
  258.   ULONG extended_flags,   /* Additional parallel flags.                    */
  259.   UBYTE *eof_chars        /* Pointer to an array containing eight end-of-  */
  260.                           /* file characters.                              */
  261. )
  262. {
  263.   int loop;           /* Used in the loop.      */
  264.   UBYTE *ptr;         /* Unsigned byte pointer. */
  265.   
  266.   
  267.   /* Set parallel flags: */
  268.   ioreq->io_ParFlags = parallel_flags;
  269.  
  270.   /* Set additional flags: */
  271.   ioreq->io_PExtFlags = extended_flags;
  272.   
  273.   
  274.   /* Get the address of the IOTArray: */
  275.   ptr = (UBYTE *) &(ioreq->io_PTermArray);
  276.  
  277.   /* Set all eight end of file characters: */
  278.   for( loop=0; loop < 8; loop++ )
  279.   {
  280.     /* Copy character after character: */
  281.     *ptr = eof_chars[ loop ];
  282.  
  283.     /* Step one byte foreward: */
  284.     ptr++;
  285.   }
  286.   
  287.   /* All values have now been set, lets do a PDCMD_SETPARAMS request: */
  288.   ioreq->IOPar.io_Command = PDCMD_SETPARAMS;
  289.   
  290.   /* Do our request, and when complete return 0 if */
  291.   /* OK, else an error value:                      */
  292.   return( (UBYTE) DoIO( ioreq ) );
  293. }
  294.  
  295.  
  296.  
  297. /* ParError() tells the user what went wrong. You give it the error code */
  298. /* you received, and ParError() will print a short description of the    */
  299. /* problem. Useful when debugging.                                       */
  300. /*                                                                       */
  301. /* Synopsis: ParError( error );                                          */
  302. /*                                                                       */
  303. /* error:    (UBYTE) The error value you want to have explained.         */
  304.  
  305. void ParError( UBYTE error )
  306. {
  307.   switch( error )
  308.   {
  309.     case ParErr_DevBusy:
  310.       printf( "Some other task is already using the parallel Device!\n" );
  311.       break;
  312.     case ParErr_BufTooBig:
  313.       printf( "The parallel buffer is too big! (?)\n" );
  314.       break;
  315.     case ParErr_InvParam:
  316.       printf( "Invalid parameters!\n" );
  317.       break;
  318.     case ParErr_LineErr:
  319.       printf( "Line error, check all cables!\n" );
  320.       break;
  321.     case ParErr_NotOpen:
  322.       printf( "The Parallel Device is not open!\n" );
  323.       break;
  324.     case ParErr_PortReset:
  325.       printf( "Someone has resetted the Parallel Device!\n" );
  326.       break;
  327.     case ParErr_InitErr:
  328.       printf( "Could not initialize the Parallel Device!\n" );
  329.       break;
  330.  
  331.     default:
  332.       printf( "An unknown error was reported! Error nr: %d\n", error );
  333.   }
  334. }
  335.  
  336.  
  337.  
  338.  
  339.  
  340. /* ParWriteNoWait() sends some data to the Parallel Port, but returns */
  341. /* immediately. You only have to give it a pointer to the data you    */
  342. /* want to write and tell it how many bytes you want to transfer.     */
  343. /* Since it does not wait for the request to be completed, you have   */
  344. /* to take care of removing the message yourself. Note that all       */
  345. /* requests that have been started must be completed or aborted       */
  346. /* before your program may close the parallel device.                 */
  347. /*                                                                    */
  348. /* Synopsis: error = ParWriteNoWait( io, data, length );              */
  349. /*                                                                    */
  350. /* io:       (struct IOExtPar *) Pointer to an initialized parallel   */
  351. /*           request block.                                           */
  352. /*                                                                    */
  353. /* data:     (BYTE *) Pointer to the first byte of the data you want  */
  354. /*           to send (write).                                         */
  355. /*                                                                    */
  356. /* length:   (ULONG) How many bytes you want to transfer. If you want */
  357. /*           to continue to send data until we have received an end-  */
  358. /*           of-file character, set the length to -1. (Note that the  */
  359. /*           parallel device will then ONLY stop when it receives one */
  360. /*           of the specified end-of-file characters.)                */
  361.  
  362. void ParWriteNoWait(
  363.   struct IOExtPar *ioreq, /* Pointer to our parallel request block.   */
  364.   BYTE *data,             /* Pointer to the data you want to send.    */
  365.   ULONG length            /* The length of the data you want to send. */
  366. )
  367. {
  368.   /* We want to send (write) some data: */
  369.   ioreq->IOPar.io_Command = CMD_WRITE;
  370.  
  371.   /* Give the start address of our data: */
  372.   ioreq->IOPar.io_Data = (APTR) data;
  373.  
  374.   /* Set the length of the message: */
  375.   ioreq->IOPar.io_Length = length;
  376.  
  377.   /* Do our request and return immediately: */
  378.   SendIO( ioreq );
  379. }
  380.  
  381.  
  382.  
  383. /* ParReadNoWait() reads some data from the Parallel Port, but returns */
  384. /* immediately. You only have to give it a pointer to some memory      */
  385. /* where the data should be stored, and tell it how many bytes you     */
  386. /* want to read. Since it does not wait for the request to be          */
  387. /* completed, you have to take care of removing the message yourself.  */
  388. /* Note that all requests that have been started must be completed or  */
  389. /* aborted before your program may close the parallel device.          */
  390. /*                                                                     */
  391. /*                                                                     */
  392. /* Synopsis: error = ParReadNoWait( io, data, length );                */
  393. /*                                                                     */
  394. /* io:       (struct IOExtPar *) Pointer to an initialized parallel    */
  395. /*           request block.                                            */
  396. /*                                                                     */
  397. /* data:     (BYTE *) Pointer to the memory buffer where you want to   */
  398. /*           store all data.                                           */
  399. /*                                                                     */
  400. /* length:   (ULONG) How many bytes you want to read. If you want to   */
  401. /*           continue to send data until we have received an end-of-   */
  402. /*           file character, set the length to -1. (Note that the      */
  403. /*           parallel device will then ONLY stop when it receives one  */
  404. /*           of the end-of-file characters.)                           */
  405.  
  406. void ParReadNoWait(
  407.   struct IOExtPar *ioreq, /* Pointer to our parallel request block. */
  408.   BYTE *data,             /* Where the data should be placed.     */
  409.   ULONG length            /* How many bytes you want to read.     */
  410. )
  411. {
  412.   /* We want to read some data: */
  413.   ioreq->IOPar.io_Command = CMD_READ;
  414.  
  415.   /* Give the start address of our data: */
  416.   ioreq->IOPar.io_Data = (APTR) data;
  417.  
  418.   /* Set how many bytes you want to read: */
  419.   ioreq->IOPar.io_Length = length;
  420.  
  421.   /* Do our request and return immediately: */
  422.   DoIO( ioreq );
  423. }
  424.  
  425.