home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 1 / FishNMoreVol1.bin / more / system / idev / idev.c < prev    next >
C/C++ Source or Header  |  1988-01-02  |  9KB  |  462 lines

  1. /*
  2. ** FILE:    idev.c
  3. ** PROGRAM:    idev
  4. ** VERSION:    1.0
  5. **
  6. ** DESCRIPTIPON:
  7. **    This file contains the function idev() and its support functions.
  8. **    It forms the heart of the program, and is responsible for all
  9. **    user interaction.  Idev() returns when the user asks to quit.
  10. **
  11. **    Idev() expects the device name, unit number and device flags
  12. **    as supplied by the user, and also the IORequest, properly
  13. **    initialized by OpenDevice() with the given parameters.
  14. **
  15. ** HISTORY:
  16. **    26-Aug-87    Original Version   (Ed Puckett)
  17. */
  18.  
  19. #include <exec/types.h>
  20. #include <exec/lists.h>
  21. #include <exec/nodes.h>
  22. #include <exec/ports.h>
  23. #include <exec/io.h>
  24. #include <exec/devices.h>
  25. #include <exec/libraries.h>
  26. #include <libraries/dos.h>
  27. #include <stdio.h>
  28. #include <ctype.h>
  29.  
  30. #include "main.h"
  31. #include "idev.h"
  32.  
  33.  
  34.  
  35. #define BUFSIZE     1024
  36.  
  37. static char  buffer[BUFSIZE];
  38.  
  39.  
  40.  
  41. typedef enum
  42.   { C_QUIT,
  43.     C_HELP,
  44.     C_RDIOREQ,
  45.     C_WRIOREQ,
  46.     C_RDBUFFER,
  47.     C_WRBUFFER,
  48.     C_PATCHBUFADDR,
  49.     C_SEND,
  50.     C_VECT
  51.   }
  52. COMMAND;
  53.  
  54.  
  55.  
  56. extern int  vect_intfc();       /* assembly interface for vect() */
  57.  
  58.  
  59.  
  60. /*-------------------------------------------------------------------------------
  61. */
  62.  
  63. void  idev (devname, unitnum, ioreq, flags)
  64.  
  65. char         *devname;
  66. int         unitnum;
  67. struct IOStdReq  *ioreq;
  68. ULONG         flags;
  69.  
  70. { COMMAND  cmd;
  71.   char       filename[257];
  72.   int       size, vectnum;
  73.   int       prot_offset;
  74.   COMMAND  getcmd ();
  75.   BOOL       getstring(), getint();
  76.   void       help(), rdfile(), wrfile(), send(), vect();
  77.  
  78.  
  79.   help (devname, unitnum, ioreq, flags);
  80.  
  81.   prot_offset= (char *) &ioreq->io_Command - (char *) ioreq;
  82.  
  83.   while ((cmd= getcmd ()) != C_QUIT)
  84.     { switch (cmd)
  85.     { case C_HELP:
  86.         help (devname, unitnum, ioreq, flags);
  87.         break;
  88.  
  89.       case C_RDIOREQ:
  90.         if ( getstring (filename, sizeof (filename)) )
  91.           rdfile (((char *) ioreq + prot_offset), (IOREQSIZE - prot_offset), filename);
  92.         break;
  93.  
  94.       case C_WRIOREQ:
  95.         if ( getstring (filename, sizeof (filename)) && getint (&size) )
  96.           wrfile (((char *) ioreq + prot_offset), (IOREQSIZE - prot_offset), size, filename);
  97.         break;
  98.  
  99.       case C_RDBUFFER:
  100.         if ( getstring (filename, sizeof (filename)) )
  101.           rdfile ((char *) buffer, BUFSIZE, filename);
  102.         break;
  103.  
  104.       case C_WRBUFFER:
  105.         if ( getstring (filename, sizeof (filename)) && getint (&size) )
  106.           wrfile ((char *) buffer, BUFSIZE, size, filename);
  107.         break;
  108.  
  109.       case C_PATCHBUFADDR:
  110.         ioreq->io_Data= (APTR) buffer;
  111.         printf ("Buffer address 0x%08lx patched to io_Data field\n", (unsigned long) buffer);
  112.         break;
  113.  
  114.       case C_SEND:
  115.         send (ioreq);
  116.         break;
  117.  
  118.       case C_VECT:
  119.         if ( getint (&vectnum) )
  120.           vect (ioreq, vectnum);
  121.         break;
  122.     }
  123.     }
  124. }
  125.  
  126.  
  127.  
  128. /*-------------------------------------------------------------------------------
  129. */
  130.  
  131. /* Note: the CC_x defines should be lowercase characters if alphabetic */
  132.  
  133. #define CC_HELP1    '?'
  134. #define CC_HELP2    'h'
  135. #define CC_READ     'r'
  136. #define CC_WRITE    'w'
  137. #define CCQ_IOREQ    'i'
  138. #define CCQ_BUFFER    'b'
  139. #define CC_PATCHBUFADDR '&'
  140. #define CC_SEND     '!'
  141. #define CC_VECT     '^'
  142. #define CC_QUIT     'q'
  143.  
  144.  
  145.  
  146. static COMMAND    getcmd ()
  147.  
  148. { char     cmdchar[2], qual[2];
  149.   void     ckbrk(), flushline();
  150.  
  151.   for (;;)
  152.     { ckbrk ();
  153.  
  154.       printf ("\n%s--> ", cmdname);
  155.  
  156.       if (scanf ("%1s", cmdchar) == EOF)
  157.     { printf ("\n*** EOF\n");
  158.       return C_QUIT;
  159.     }
  160.  
  161.       cmdchar[0]= tolower (cmdchar[0]);
  162.       switch (cmdchar[0])
  163.     { case CC_HELP1:
  164.       case CC_HELP2:
  165.         return C_HELP;
  166.  
  167.       case CC_READ:
  168.       case CC_WRITE:
  169.         if (scanf ("%1s", qual) == EOF)
  170.         { printf ("\n*** EOF\n");
  171.           return C_QUIT;
  172.         }
  173.  
  174.         qual[0]= tolower (qual[0]);
  175.         switch (qual[0])
  176.           { case CCQ_IOREQ:
  177.           return  ((cmdchar[0] == CC_READ) ? C_RDIOREQ : C_WRIOREQ);
  178.  
  179.         case CCQ_BUFFER:
  180.           return  ((cmdchar[0] == CC_READ) ? C_RDBUFFER : C_WRBUFFER);
  181.  
  182.         default:
  183.           printf ("\n*** Qualifier for '%c' must be '%c' or '%c'.", cmdchar[0], CCQ_IOREQ, CCQ_BUFFER);
  184.           }
  185.  
  186.         break;
  187.  
  188.       case CC_PATCHBUFADDR:
  189.         return C_PATCHBUFADDR;
  190.  
  191.       case CC_SEND:
  192.         return C_SEND;
  193.  
  194.       case CC_VECT:
  195.         return C_VECT;
  196.  
  197.       case CC_QUIT:
  198.         return C_QUIT;
  199.     }
  200.  
  201.       printf ("\n*** Invalid command -- enter '%c' or '%c' for help.\n", CC_HELP1, CC_HELP2);
  202.  
  203.       flushline ();
  204.     }
  205. }
  206.  
  207.  
  208.  
  209. static void  help (devname, unitnum, ioreq, flags)
  210.  
  211. char         *devname;
  212. int         unitnum;
  213. struct IOStdReq  *ioreq;
  214. ULONG         flags;
  215.  
  216. { printf ("\n");
  217.   printf ("Device: \"%s\"\n",  devname);
  218.   printf ("Unit:   %d\n",      unitnum);
  219.   printf ("Flags:  0x%08lx\n", flags);
  220.   printf ("\n");
  221.   printf ("Buffer Address = 0x%08lx     I/O Request Address = 0x%08lx\n", (unsigned long) buffer, (unsigned long) ioreq);
  222.   printf ("Buffer Size    = 0x%08x     I/O Request Size    = 0x%08x\n",  (unsigned) BUFSIZE, (unsigned) IOREQSIZE);
  223.   printf ("\n");
  224.   printf ("Commands:\n");
  225.   printf ("   %c or %c                  help\n",                                    CC_HELP1, CC_HELP2);
  226.   printf ("   %c%c filename             read  I/O request from file\n",             CC_READ,  CCQ_IOREQ);
  227.   printf ("   %c%c filename size        write I/O request to file\n",               CC_WRITE, CCQ_IOREQ);
  228.   printf ("   %c%c filename             read  buffer from file\n",                  CC_READ,  CCQ_BUFFER);
  229.   printf ("   %c%c filename size        write buffer to file\n",                    CC_WRITE, CCQ_BUFFER);
  230.   printf ("   %c                       patch buffer address to ioreq->io_Data\n",   CC_PATCHBUFADDR);
  231.   printf ("   %c                       send I/O request to device via DoIO\n",      CC_SEND);
  232.   printf ("   %c n                     send I/O request in reg A1 via vector #n\n", CC_VECT);
  233.   printf ("   %c                       quit\n",                                     CC_QUIT);
  234.   printf ("\n");
  235.   printf ("Notes:  I/O request memory is read/written starting from io_Command.\n");
  236.   printf ("        Vectors are numbered starting from 1.\n");
  237.   printf ("        ESC ('\\033') will abort a partially entered command.\n");
  238. }
  239.  
  240.  
  241.  
  242. /*-------------------------------------------------------------------------------
  243. */
  244.  
  245. static BOOL  getstring (buf, bufsize)
  246.  
  247. char  *buf;
  248. int   bufsize;
  249.  
  250. { int        c;
  251.   unsigned  bufpos;
  252.   void        ckbrk(), flushline();
  253.  
  254.  
  255.   ckbrk ();
  256.  
  257.   buf[0]= '\0';
  258.  
  259.   do
  260.     { c= getchar ();
  261.  
  262.       if ((c == EOF) || (c == '\033'))
  263.     { flushline ();
  264.       return FALSE;
  265.     }
  266.  
  267.       if (c == '\n')
  268.     printf (">>> ");
  269.     }
  270.   while (isspace (c));
  271.  
  272.   ungetc (c, stdin);
  273.  
  274.  
  275.   ckbrk ();
  276.  
  277.   for (bufpos= 0; bufpos < bufsize; ++bufpos)
  278.     { c= getchar ();
  279.  
  280.       if ((c == EOF) || (c == '\033'))
  281.     { flushline();
  282.       buf[0]= '\0';
  283.       return FALSE;
  284.     }
  285.  
  286.       if (isspace (c))
  287.     { buf[bufpos]= '\0';
  288.       return TRUE;
  289.     }
  290.  
  291.       buf[bufpos]= c;
  292.     }
  293.  
  294.  
  295.   printf ("\n*** Input buffer overflow\n");
  296.   flushline ();
  297.   buf[bufsize - 1]= '\0';
  298.   return FALSE;
  299. }
  300.  
  301.  
  302.  
  303. static BOOL  getint (ip)
  304.  
  305. int  *ip;
  306.  
  307. { char    str[20];
  308.   BOOL    getstring();
  309.  
  310.   if (! getstring (str, sizeof (str)))
  311.     return FALSE;
  312.  
  313.   if (sscanf (str, "%d", ip) != 1)
  314.     { printf ("\n*** Could not scan number\n");
  315.       return FALSE;
  316.     }
  317.  
  318.   return TRUE;
  319. }
  320.  
  321.  
  322.  
  323. static void  rdfile (buf, bufsize, filename)
  324.  
  325. char  *buf;
  326. int   bufsize;
  327. char  *filename;
  328.  
  329. { FILE    *fp;
  330.   int    n;
  331.  
  332.   if ((fp= fopen (filename, "r")) == NULL)
  333.     { printf ("*** Can't open \"%s\"\n", filename);
  334.       return;
  335.     }
  336.  
  337.   n= fread ((char *) buf, 1, bufsize, fp);
  338.  
  339.   if (getc (fp) != EOF)
  340.     printf ("*** Warning: buffer size (%d) exceeded before EOF.\n", bufsize);
  341.  
  342.   printf ("%d bytes read.\n", n);
  343.  
  344.   fclose (fp);
  345. }
  346.  
  347.  
  348.  
  349. static void  wrfile (buf, bufsize, xfsize, filename)
  350.  
  351. char  *buf;
  352. int   bufsize;
  353. int   xfsize;
  354. char  *filename;
  355.  
  356. { FILE    *fp;
  357.   int    n;
  358.  
  359.   if ((xfsize <= 0) || (xfsize > bufsize))
  360.     { printf ("*** Size must be > 0, <= %d\n", bufsize);
  361.       return;
  362.     }
  363.  
  364.   if ((fp= fopen (filename, "w")) == NULL)
  365.     { printf ("*** Can't open \"%s\"\n", filename);
  366.       return;
  367.     }
  368.  
  369.   if ((n= fwrite ((char *) buf, 1, xfsize, fp)) < xfsize)
  370.     printf ("*** Warning: incomplete write.\n");
  371.  
  372.   printf ("%d bytes written.\n", n);
  373.  
  374.   fclose (fp);
  375. }
  376.  
  377.  
  378.  
  379. static void  send (req)
  380.  
  381. struct IORequest  *req;
  382.  
  383. { int  error;
  384.  
  385.   printf ("Sending I/O request...");
  386.   error= DoIO (req);
  387.   printf ("\nI/O request sent...");
  388.  
  389.   if (error == 0)
  390.     printf ("no error\n");
  391.   else
  392.     printf ("error = %d\n", error);
  393. }
  394.  
  395.  
  396.  
  397. static void  vect (req, vectnum)
  398.  
  399. struct IORequest  *req;
  400. int          vectnum;
  401.  
  402. { struct Device  *dev;
  403.   int         vn, error;
  404.   LONG         val;
  405.   int         vect_intfc();
  406.  
  407.  
  408.   if (vectnum <= 0)
  409.     { printf ("*** Vector number must be positive\n");
  410.       return;
  411.     }
  412.  
  413.  
  414.   dev= req->io_Device;
  415.  
  416.   for (vn= 1; vn <= vectnum; vn += 1)
  417.     { if ( ((val= *((LONG *) ((char *) dev - (LIB_VECTSIZE * vn)))) == -1) || (val == NULL) )
  418.     { printf ("*** There are only %d vectors\n", (vn - 1));
  419.       return;
  420.     }
  421.     }
  422.  
  423.  
  424.   printf ("Vectoring I/O request through vector #%d...", vectnum);
  425.   error= vect_intfc (req, vectnum);
  426.   printf ("\nI/O request vectored...");
  427.  
  428.   if (error == 0)
  429.     printf ("no error\n");
  430.   else
  431.     printf ("error = %d\n", error);
  432. }
  433.  
  434.  
  435.  
  436. /*-------------------------------------------------------------------------------
  437. */
  438.  
  439. static void  ckbrk ()
  440.  
  441. { ULONG  SetSignal();
  442.  
  443.   if (SetSignal (0, 0) & SIGBREAKF_CTRL_C)
  444.     { printf ("\n*** BREAK\n");
  445.       quit (Q_ABORT, NULL, 0, 0, 0);
  446.     }
  447. }
  448.  
  449.  
  450.  
  451. static void  flushline ()
  452.  
  453. { register int    c;
  454.   void        ckbrk();
  455.  
  456.   ckbrk ();
  457.  
  458.   while ( ((c= getchar ()) != EOF) && (c != '\n') )
  459.     ;
  460. }
  461.  
  462.