home *** CD-ROM | disk | FTP | other *** search
/ World of A1200 / World_Of_A1200.iso / datafiles / text / c_manual / devices / paralleldevice / example4.c < prev    next >
C/C++ Source or Header  |  1995-02-27  |  23KB  |  562 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:    Example4.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 does not do anything, but it consists of    */
  23. /* several useful functions that you can use yourself after */
  24. /* small modifications. The functions demonstrates all      */
  25. /* commands there exist for the parallel device, so if you  */
  26. /* had problems in understanding how a command was used you */
  27. /* can look here.                                           */
  28.  
  29.  
  30.  
  31. #include <exec/types.h>
  32. #include <exec/errors.h>
  33. #include <devices/parallel.h>
  34.  
  35.  
  36.  
  37. /* Declare the functions: */
  38.  
  39. /* Sets the parallel parameters: */
  40. UBYTE SetParParams(
  41.   struct IOExtPar *ioreq,
  42.   UBYTE parallel_flags,
  43.   ULONG extended_flags,
  44.   UBYTE *eof_chars
  45. );
  46.  
  47. /* Explains error messages: */
  48. void ParError( UBYTE error );
  49.  
  50. /* Sends data to the parallel device: */
  51. UBYTE ParWrite(
  52.   struct IOExtPar *ioreq,
  53.   BYTE *data,
  54.   ULONG length
  55. );
  56.  
  57. /* Collects data from the parallel device: */
  58. UBYTE ParRead(
  59.   struct IOExtPar *ioreq,
  60.   BYTE *data,
  61.   ULONG length
  62. );
  63.  
  64. /* Sends data to the parallel device without waiting: */
  65. void ParWriteNoWait(
  66.   struct IOExtPar *ioreq,
  67.   BYTE *data,
  68.   ULONG length
  69. );
  70.  
  71. /* Collects data from the parallel device without waiting: */
  72. void ParReadNoWait(
  73.   struct IOExtPar *ioreq,
  74.   BYTE *data,
  75.   ULONG length
  76. );
  77.  
  78. /* Remove all queued requests: */
  79. UBYTE ParFlush( struct IOExtPar *ioreq );
  80.  
  81. /* Print some information about the parallel device: */
  82. UBYTE ParQuery( struct IOExtPar *ioreq );
  83.  
  84. /* Reset the parallel device: */
  85. UBYTE ParReset( struct IOExtPar *ioreq );
  86.  
  87. /* Temporarily stop all paralllel communication: */
  88. UBYTE ParStop( struct IOExtPar *ioreq );
  89.  
  90. /* Restart parallel communication: */
  91. UBYTE ParStart( struct IOExtPar *ioreq );
  92.  
  93.  
  94.  
  95. /* Do hardly nothing: */
  96. void main();
  97.  
  98. void main()
  99. {
  100.   printf( "This example consists of many support functions,\n" );
  101.   printf( "but does not do anything. See source code...\n" );
  102. }
  103.  
  104.  
  105.  
  106. /***************************************/
  107. /* PARALLEL DEVICE - SUPPORT FUNCTIONS */
  108. /***************************************/
  109.  
  110.  
  111.  
  112. /* SetParParams() sets the parallel parameters. It initializes a IOExtPar  */
  113. /* structure, and does a PDCMD_SETPARAMS commad. If everything is OK it    */
  114. /* returns NULL, else an error number is returned.                         */
  115. /*                                                                         */
  116. /* Synopsis: er = SetParParams( io, bl, br, bt, rl, wl, sl, sf, ef, chr ); */
  117. /*                                                                         */
  118. /* er:       (UBYTE) SetParParams() returns 0 if everything was OK, else   */
  119. /*           an error value is returned. See function ParError() for more  */
  120. /*           information.                                                  */
  121. /*                                                                         */ 
  122. /* io:       (struct IOExtPar *) Pointer to the parallel request block you */
  123. /*           want to initialize.                                           */
  124. /*                                                                         */
  125. /*           PARF_RAD_BOOGIE Not supported by the parallel device for the  */
  126. /*                           moment.                                       */
  127. /*                                                                         */
  128. /*           PARF_SHARED     Set this flag if you want to allow other      */
  129. /*                           tasks running at the same time to use the     */
  130. /*                           parallel device. The default is exclusive-    */
  131. /*                           access. (If some other task is using the      */
  132. /*                           parallel device with the shared bit set, and  */
  133. /*                           you call this function with exclusive access, */
  134. /*                           your request will fail.)                      */
  135. /*                                                                         */
  136. /*           PARF_EOFMODE    Set this flag if you want to check for end of */
  137. /*                           file characters. (You may use up to eight end */
  138. /*                           of file characters, which are specified       */
  139. /*                           below.)                                       */
  140. /*                                                                         */
  141. /* ef:       (ULONG) Not supported by the parallel device for the moment.  */
  142. /*                                                                         */
  143. /* chr:      (UBYTE *) Pointer to an array containing eight end-of-file    */
  144. /*           characters. If the parallel flag "PARF_EOFMODE" is set, the   */
  145. /*           parallel device will check each character which is sent or    */
  146. /*           received, and if it matches one of the end-of-file characters */
  147. /*           the read/wite request is terminated.                          */
  148.  
  149. UBYTE SetParParams(
  150.   struct IOExtPar *ioreq, /* Pointer to our parallel request block.        */
  151.   UBYTE parallel_flags,   /* Parallel flags.                               */
  152.   ULONG extended_flags,   /* Additional parallel flags.                    */
  153.   UBYTE *eof_chars        /* Pointer to an array containing eight end-of-  */
  154.                           /* file characters.                              */
  155. )
  156. {
  157.   int loop;           /* Used in the loop.      */
  158.   UBYTE *ptr;         /* Unsigned byte pointer. */
  159.   
  160.   
  161.   /* Set parallel flags: */
  162.   ioreq->io_ParFlags = parallel_flags;
  163.  
  164.   /* Set additional flags: */
  165.   ioreq->io_PExtFlags = extended_flags;
  166.   
  167.   
  168.   /* Get the address of the IOTArray: */
  169.   ptr = (UBYTE *) &(ioreq->io_PTermArray);
  170.  
  171.   /* Set all eight end of file characters: */
  172.   for( loop=0; loop < 8; loop++ )
  173.   {
  174.     /* Copy character after character: */
  175.     *ptr = eof_chars[ loop ];
  176.  
  177.     /* Step one byte foreward: */
  178.     ptr++;
  179.   }
  180.   
  181.   /* All values have now been set, lets do a PDCMD_SETPARAMS request: */
  182.   ioreq->IOPar.io_Command = PDCMD_SETPARAMS;
  183.   
  184.   /* Do our request, and when complete return 0 if */
  185.   /* OK, else an error value:                      */
  186.   return( (UBYTE) DoIO( ioreq ) );
  187. }
  188.  
  189.  
  190.  
  191. /* ParError() tells the user what went wrong. You give it the error code */
  192. /* you received, and ParError() will print a short description of the    */
  193. /* problem. Useful when debugging.                                       */
  194. /*                                                                       */
  195. /* Synopsis: ParError( error );                                          */
  196. /*                                                                       */
  197. /* error:    (UBYTE) The error value you want to have explained.         */
  198.  
  199. void ParError( UBYTE error )
  200. {
  201.   switch( error )
  202.   {
  203.     /* Parallel device errors: */
  204.     case ParErr_DevBusy:
  205.       printf( "Some other task is already using the parallel Device!\n" );
  206.       break;
  207.     case ParErr_BufTooBig:
  208.       printf( "The parallel buffer is too big! (?)\n" );
  209.       break;
  210.     case ParErr_InvParam:
  211.       printf( "Invalid parameters!\n" );
  212.       break;
  213.     case ParErr_LineErr:
  214.       printf( "Line error, check all cables!\n" );
  215.       break;
  216.     case ParErr_NotOpen:
  217.       printf( "The Parallel Device is not open!\n" );
  218.       break;
  219.     case ParErr_PortReset:
  220.       printf( "Someone has resetted the Parallel Device!\n" );
  221.       break;
  222.     case ParErr_InitErr:
  223.       printf( "Could not initialize the Parallel Device!\n" );
  224.       break;
  225.  
  226.     /* Exec errors: */
  227.     case IOERR_OPENFAIL:
  228.       printf( "The device could not be opened!\n" );
  229.       break;
  230.     case IOERR_ABORTED:
  231.       printf( "The request was aborted!\n" );
  232.       break;
  233.     case IOERR_NOCMD:
  234.       printf( "The parallel device does not know about this command!\n" );
  235.       break;
  236.     case IOERR_BADLENGTH:
  237.       printf( "The length of the request was not valid!\n" );
  238.       break;
  239.  
  240.     /* Unknown error: */
  241.     default:
  242.       printf( "Unknown error! Error code: %d\n", error );
  243.   }
  244. }
  245.  
  246.  
  247.  
  248. /* ParWrite() sends some data to the Parallel Port. You only have */
  249. /* to give it a pointer to the data you want to write and tell it */
  250. /* how many bytes you want to transfer.                           */
  251. /*                                                                */
  252. /* Synopsis: error = ParWrite( io, data, length );                */
  253. /*                                                                */
  254. /* error:    (UBYTE) ParWrite() returns 0 if everything was OK,   */
  255. /*           else an error number is returned.                    */
  256. /*                                                                */
  257. /* io:       (struct IOExtPar *) Pointer to an initialized        */
  258. /*           parallel request block.                              */
  259. /*                                                                */
  260. /* data:     (BYTE *) Pointer to the first byte of the data you   */
  261. /*           want to send (write).                                */
  262. /*                                                                */
  263. /* length:   (ULONG) How many bytes you want to transfer. If you  */
  264. /*           want to continue to send data until we have received */
  265. /*           an end-of-file character, set the length to -1.      */
  266. /*           (Note that the parallel device will then ONLY stop   */
  267. /*           when it has received one of the end-of-file          */
  268. /*           characters.)                                         */
  269.  
  270. UBYTE ParWrite(
  271.   struct IOExtPar *ioreq, /* Pointer to our parallel request block.   */
  272.   BYTE *data,             /* Pointer to the data you want to send.    */
  273.   ULONG length            /* The length of the data you want to send. */
  274. )
  275. {
  276.   /* We want to send (write) some data: */
  277.   ioreq->IOPar.io_Command = CMD_WRITE;
  278.  
  279.   /* Give the start address of our data: */
  280.   ioreq->IOPar.io_Data = (APTR) data;
  281.  
  282.   /* Set the length of the message: (If you want to continue    */
  283.   /* to write until you have received an end-of-file character, */
  284.   /* set length to -1.)                                         */
  285.   ioreq->IOPar.io_Length = length;
  286.  
  287.   /* Do our request, and return 0 if everything is OK, else */
  288.   /* return an error number: (This is a task sleep.)        */
  289.   return( (UBYTE) DoIO( ioreq ) );
  290. }
  291.  
  292.  
  293.  
  294. /* ParRead() reads some data from the Parallel Port. You only have   */
  295. /* to give it a pointer to some memory where the data should be      */
  296. /* stored, and tell it how many bytes you want to read. The rest is  */
  297. /* done automatically.                                               */
  298. /*                                                                   */
  299. /* Synopsis: error = ParRead( io, data, length );                    */
  300. /*                                                                   */
  301. /* error:    (UBYTE) ParRead() returns 0 if everything was OK, else  */
  302. /*           an error number is returned.                            */
  303. /*                                                                   */
  304. /* io:       (struct IOExtPar *) Pointer to an initialized parallel  */
  305. /*           request block.                                          */
  306. /*                                                                   */
  307. /* data:     (BYTE *) Pointer to the memory buffer where you want    */
  308. /*           to store all collected data.                            */
  309. /*                                                                   */
  310. /* length:   (ULONG) How many bytes you want to read. If you want to */
  311. /*           continue to read data until we have received an end-of- */
  312. /*           file character, set the length to -1.                   */
  313.  
  314. UBYTE ParRead(
  315.   struct IOExtPar *ioreq, /* Pointer to our parallel request block. */
  316.   BYTE *data,             /* Where the data should be placed.       */
  317.   ULONG length            /* How many bytes you want to read.       */
  318. )
  319. {
  320.   /* We want to read some data: */
  321.   ioreq->IOPar.io_Command = CMD_READ;
  322.  
  323.   /* Give the start address of our data: */
  324.   ioreq->IOPar.io_Data = (APTR) data;
  325.  
  326.   /* Set how many bytes you want to read. (If you want to continue  */
  327.   /* to read data until you have received an end-of-file character, */
  328.   /* set length to -1.)                                             */
  329.   ioreq->IOPar.io_Length = length;
  330.  
  331.   /* Do our request, and return 0 if everything is OK, else */
  332.   /* return an error number: (This is a task sleep. Zzz )   */
  333.   return( (UBYTE) DoIO( ioreq ) );
  334. }
  335.  
  336.  
  337.  
  338. /* ParWriteNoWait() sends some data to the Parallel Port, but returns */
  339. /* immediately. You only have to give it a pointer to the data you    */
  340. /* want to write and tell it how many bytes you want to transfer.     */
  341. /* Since it does not wait for the request to be completed, you have   */
  342. /* to take care of removing the message yourself. Note that all       */
  343. /* requests that have been started must be completed or aborted       */
  344. /* before your program may close the parallel device.                 */
  345. /*                                                                    */
  346. /* Synopsis: error = ParWriteNoWait( io, data, length );              */
  347. /*                                                                    */
  348. /* io:       (struct IOExtPar *) Pointer to an initialized parallel   */
  349. /*           request block.                                           */
  350. /*                                                                    */
  351. /* data:     (BYTE *) Pointer to the first byte of the data you want  */
  352. /*           to send (write).                                         */
  353. /*                                                                    */
  354. /* length:   (ULONG) How many bytes you want to transfer. If you want */
  355. /*           to continue to send data until we have received an end-  */
  356. /*           of-file character, set the length to -1. (Note that the  */
  357. /*           parallel device will then ONLY stop when it receives one */
  358. /*           of the specified end-of-file characters.)                */
  359.  
  360. void ParWriteNoWait(
  361.   struct IOExtPar *ioreq, /* Pointer to our parallel request block.   */
  362.   BYTE *data,             /* Pointer to the data you want to send.    */
  363.   ULONG length            /* The length of the data you want to send. */
  364. )
  365. {
  366.   /* We want to send (write) some data: */
  367.   ioreq->IOPar.io_Command = CMD_WRITE;
  368.  
  369.   /* Give the start address of our data: */
  370.   ioreq->IOPar.io_Data = (APTR) data;
  371.  
  372.   /* Set the length of the message: */
  373.   ioreq->IOPar.io_Length = length;
  374.  
  375.   /* Do our request and return immediately: */
  376.   SendIO( ioreq );
  377. }
  378.  
  379.  
  380.  
  381. /* ParReadNoWait() reads some data from the Parallel Port, but returns */
  382. /* immediately. You only have to give it a pointer to some memory      */
  383. /* where the data should be stored, and tell it how many bytes you     */
  384. /* want to read. Since it does not wait for the request to be          */
  385. /* completed, you have to take care of removing the message yourself.  */
  386. /* Note that all requests that have been started must be completed or  */
  387. /* aborted before your program may close the parallel device.          */
  388. /*                                                                     */
  389. /*                                                                     */
  390. /* Synopsis: error = ParReadNoWait( io, data, length );                */
  391. /*                                                                     */
  392. /* io:       (struct IOExtPar *) Pointer to an initialized parallel    */
  393. /*           request block.                                            */
  394. /*                                                                     */
  395. /* data:     (BYTE *) Pointer to the memory buffer where you want to   */
  396. /*           store all data.                                           */
  397. /*                                                                     */
  398. /* length:   (ULONG) How many bytes you want to read. If you want to   */
  399. /*           continue to send data until we have received an end-of-   */
  400. /*           file character, set the length to -1. (Note that the      */
  401. /*           parallel device will then ONLY stop when it receives one  */
  402. /*           of the end-of-file characters.)                           */
  403.  
  404. void ParReadNoWait(
  405.   struct IOExtPar *ioreq, /* Pointer to our parallel request block. */
  406.   BYTE *data,             /* Where the data should be placed.     */
  407.   ULONG length            /* How many bytes you want to read.     */
  408. )
  409. {
  410.   /* We want to read some data: */
  411.   ioreq->IOPar.io_Command = CMD_READ;
  412.  
  413.   /* Give the start address of our data: */
  414.   ioreq->IOPar.io_Data = (APTR) data;
  415.  
  416.   /* Set how many bytes you want to read: */
  417.   ioreq->IOPar.io_Length = length;
  418.  
  419.   /* Do our request and return immediately: */
  420.   DoIO( ioreq );
  421. }
  422.  
  423.  
  424.  
  425. /* ParFlush() will remove all queued commands.                 */
  426. /*                                                             */
  427. /* Synopsis: error = ParFlush( io );                           */
  428. /*                                                             */
  429. /* error:    (UBYTE) The function returns 0 if everything was  */
  430. /*           OK, else an error number is returned.             */
  431. /*                                                             */
  432. /* io:       (struct IOExtPar *) Pointer to an initialized     */
  433. /*           parallel request block.                           */
  434.  
  435. UBYTE ParFlush( struct IOExtPar *ioreq )
  436. {
  437.   /* We want to remove all queued requests: */
  438.   ioreq->IOPar.io_Command = CMD_FLUSH;
  439.  
  440.   /* Do our request, and return 0 if everything is OK, else */
  441.   /* return an error number:                                */
  442.   return( (UBYTE) DoIO( ioreq ) );
  443. }
  444.  
  445.  
  446.  
  447. /* ParQuery() will print some information about the parallel   */
  448. /* device. This is very useful for debugging.                  */
  449. /*                                                             */
  450. /* Synopsis: error = ParQuery( io );                           */
  451. /*                                                             */
  452. /* error:    (UBYTE) The function returns 0 if everything was  */
  453. /*           OK, else an error number is returned.             */
  454. /*                                                             */
  455. /* io:       (struct IOExtPar *) Pointer to an initialized     */
  456. /*           parallel request block.                           */
  457.  
  458. UBYTE ParQuery( struct IOExtPar *ioreq )
  459. {
  460.   UBYTE error;
  461.  
  462.  
  463.   /* Check the parallel device: */
  464.   ioreq->IOPar.io_Command = PDCMD_QUERY;
  465.  
  466.   /* Do our request: */
  467.   error = DoIO( ioreq );
  468.  
  469.   /* OK? */
  470.   if( error )
  471.     printf( "Could not get any information from the device!\n" );
  472.   else
  473.   {
  474.     /* Check the "io_Status" field: */
  475.     if( ioreq->io_Status & IOPTF_PARBUSY )
  476.       printf( "Printer is busy.\n" );
  477.  
  478.     if( ioreq->io_Status & IOPTF_PAPEROUT )
  479.       printf( "Paper out!\n" );
  480.  
  481.     if( ioreq->io_Status & IOPTF_PARSEL )
  482.       printf( "Printerr selected!\n" );
  483.  
  484.     printf( "Device is %s\n",
  485.       ioreq->io_Status & IOPTF_RWDIR ? "Writing" : "Reading" ); 
  486.   }
  487.  
  488.   return( error );
  489. }
  490.  
  491.  
  492.  
  493. /* ParReset() will reset the parallel device. All commands that */
  494. /* are qued to the device will be removed, commands that are    */
  495. /* currently executed will be aborted and finally all parallel  */
  496. /* flags are resetted.                                          */
  497. /*                                                              */
  498. /* Synopsis: error = ParReset( io );                            */
  499. /*                                                              */
  500. /* error:    (UBYTE) The function returns 0 if everything was   */
  501. /*           OK, else an error number is returned.              */
  502. /*                                                              */
  503. /* io:       (struct IOExtPar *) Pointer to an initialized      */
  504. /*           parallel request block.                            */
  505.  
  506. UBYTE ParReset( struct IOExtPar *ioreq )
  507. {
  508.   /* We want to reset the parallel device: */
  509.   ioreq->IOPar.io_Command = CMD_RESET;
  510.  
  511.   /* Do our request, and return 0 if everything is OK, else */
  512.   /* return an error number:                                */
  513.   return( (UBYTE) DoIO( ioreq ) );
  514. }
  515.  
  516.  
  517.  
  518. /* ParStop() will temporary stop the parallel communication.   */
  519. /*                                                             */
  520. /* Synopsis: error = ParStop( io );                            */
  521. /*                                                             */
  522. /* error:    (UBYTE) The function returns 0 if everything was  */
  523. /*           OK, else an error number is returned.             */
  524. /*                                                             */
  525. /* io:       (struct IOExtPar *) Pointer to an initialized     */
  526. /*           parallel request block.                           */
  527.  
  528. UBYTE ParStop( struct IOExtPar *ioreq )
  529. {
  530.   /* We want to start parallel communication again: */
  531.   ioreq->IOPar.io_Command = CMD_STOP;
  532.  
  533.   /* Do our request, and return 0 if everything is OK, else */
  534.   /* return an error number:                                */
  535.   return( (UBYTE) DoIO( ioreq ) );
  536. }
  537.  
  538.  
  539.  
  540. /* ParStart() will restart the parallel communication, which   */
  541. /* has previously been halted by a ParStop() call.             */
  542. /*                                                             */
  543. /* Synopsis: error = ParStart( io );                           */
  544. /*                                                             */
  545. /* error:    (UBYTE) The function returns 0 if everything was  */
  546. /*           OK, else an error number is returned.             */
  547. /*                                                             */
  548. /* io:       (struct IOExtPar *) Pointer to an initialized     */
  549. /*           parallel request block.                           */
  550.  
  551. UBYTE ParStart( struct IOExtPar *ioreq )
  552. {
  553.   /* We want to start parallel communication again: */
  554.   ioreq->IOPar.io_Command = CMD_START;
  555.  
  556.   /* Do our request, and return 0 if everything is OK, else */
  557.   /* return an error number:                                */
  558.   return( (UBYTE) DoIO( ioreq ) );
  559. }
  560.  
  561.  
  562.