home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
103.lha
/
IntDevExpl
/
idev.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-21
|
9KB
|
462 lines
/*
** FILE: idev.c
** PROGRAM: idev
** VERSION: 1.0
**
** DESCRIPTIPON:
** This file contains the function idev() and its support functions.
** It forms the heart of the program, and is responsible for all
** user interaction. Idev() returns when the user asks to quit.
**
** Idev() expects the device name, unit number and device flags
** as supplied by the user, and also the IORequest, properly
** initialized by OpenDevice() with the given parameters.
**
** HISTORY:
** 26-Aug-87 Original Version (Ed Puckett)
*/
#include <exec/types.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/devices.h>
#include <exec/libraries.h>
#include <libraries/dos.h>
#include <stdio.h>
#include <ctype.h>
#include "main.h"
#include "idev.h"
#define BUFSIZE 1024
static char buffer[BUFSIZE];
typedef enum
{ C_QUIT,
C_HELP,
C_RDIOREQ,
C_WRIOREQ,
C_RDBUFFER,
C_WRBUFFER,
C_PATCHBUFADDR,
C_SEND,
C_VECT
}
COMMAND;
extern int vect_intfc(); /* assembly interface for vect() */
/*-------------------------------------------------------------------------------
*/
void idev (devname, unitnum, ioreq, flags)
char *devname;
int unitnum;
struct IOStdReq *ioreq;
ULONG flags;
{ COMMAND cmd;
char filename[257];
int size, vectnum;
int prot_offset;
COMMAND getcmd ();
BOOL getstring(), getint();
void help(), rdfile(), wrfile(), send(), vect();
help (devname, unitnum, ioreq, flags);
prot_offset= (char *) &ioreq->io_Command - (char *) ioreq;
while ((cmd= getcmd ()) != C_QUIT)
{ switch (cmd)
{ case C_HELP:
help (devname, unitnum, ioreq, flags);
break;
case C_RDIOREQ:
if ( getstring (filename, sizeof (filename)) )
rdfile (((char *) ioreq + prot_offset), (IOREQSIZE - prot_offset), filename);
break;
case C_WRIOREQ:
if ( getstring (filename, sizeof (filename)) && getint (&size) )
wrfile (((char *) ioreq + prot_offset), (IOREQSIZE - prot_offset), size, filename);
break;
case C_RDBUFFER:
if ( getstring (filename, sizeof (filename)) )
rdfile ((char *) buffer, BUFSIZE, filename);
break;
case C_WRBUFFER:
if ( getstring (filename, sizeof (filename)) && getint (&size) )
wrfile ((char *) buffer, BUFSIZE, size, filename);
break;
case C_PATCHBUFADDR:
ioreq->io_Data= (APTR) buffer;
printf ("Buffer address 0x%08lx patched to io_Data field\n", (unsigned long) buffer);
break;
case C_SEND:
send (ioreq);
break;
case C_VECT:
if ( getint (&vectnum) )
vect (ioreq, vectnum);
break;
}
}
}
/*-------------------------------------------------------------------------------
*/
/* Note: the CC_x defines should be lowercase characters if alphabetic */
#define CC_HELP1 '?'
#define CC_HELP2 'h'
#define CC_READ 'r'
#define CC_WRITE 'w'
#define CCQ_IOREQ 'i'
#define CCQ_BUFFER 'b'
#define CC_PATCHBUFADDR '&'
#define CC_SEND '!'
#define CC_VECT '^'
#define CC_QUIT 'q'
static COMMAND getcmd ()
{ char cmdchar[2], qual[2];
void ckbrk(), flushline();
for (;;)
{ ckbrk ();
printf ("\n%s--> ", cmdname);
if (scanf ("%1s", cmdchar) == EOF)
{ printf ("\n*** EOF\n");
return C_QUIT;
}
cmdchar[0]= tolower (cmdchar[0]);
switch (cmdchar[0])
{ case CC_HELP1:
case CC_HELP2:
return C_HELP;
case CC_READ:
case CC_WRITE:
if (scanf ("%1s", qual) == EOF)
{ printf ("\n*** EOF\n");
return C_QUIT;
}
qual[0]= tolower (qual[0]);
switch (qual[0])
{ case CCQ_IOREQ:
return ((cmdchar[0] == CC_READ) ? C_RDIOREQ : C_WRIOREQ);
case CCQ_BUFFER:
return ((cmdchar[0] == CC_READ) ? C_RDBUFFER : C_WRBUFFER);
default:
printf ("\n*** Qualifier for '%c' must be '%c' or '%c'.", cmdchar[0], CCQ_IOREQ, CCQ_BUFFER);
}
break;
case CC_PATCHBUFADDR:
return C_PATCHBUFADDR;
case CC_SEND:
return C_SEND;
case CC_VECT:
return C_VECT;
case CC_QUIT:
return C_QUIT;
}
printf ("\n*** Invalid command -- enter '%c' or '%c' for help.\n", CC_HELP1, CC_HELP2);
flushline ();
}
}
static void help (devname, unitnum, ioreq, flags)
char *devname;
int unitnum;
struct IOStdReq *ioreq;
ULONG flags;
{ printf ("\n");
printf ("Device: \"%s\"\n", devname);
printf ("Unit: %d\n", unitnum);
printf ("Flags: 0x%08lx\n", flags);
printf ("\n");
printf ("Buffer Address = 0x%08lx I/O Request Address = 0x%08lx\n", (unsigned long) buffer, (unsigned long) ioreq);
printf ("Buffer Size = 0x%08x I/O Request Size = 0x%08x\n", (unsigned) BUFSIZE, (unsigned) IOREQSIZE);
printf ("\n");
printf ("Commands:\n");
printf (" %c or %c help\n", CC_HELP1, CC_HELP2);
printf (" %c%c filename read I/O request from file\n", CC_READ, CCQ_IOREQ);
printf (" %c%c filename size write I/O request to file\n", CC_WRITE, CCQ_IOREQ);
printf (" %c%c filename read buffer from file\n", CC_READ, CCQ_BUFFER);
printf (" %c%c filename size write buffer to file\n", CC_WRITE, CCQ_BUFFER);
printf (" %c patch buffer address to ioreq->io_Data\n", CC_PATCHBUFADDR);
printf (" %c send I/O request to device via DoIO\n", CC_SEND);
printf (" %c n send I/O request in reg A1 via vector #n\n", CC_VECT);
printf (" %c quit\n", CC_QUIT);
printf ("\n");
printf ("Notes: I/O request memory is read/written starting from io_Command.\n");
printf (" Vectors are numbered starting from 1.\n");
printf (" ESC ('\\033') will abort a partially entered command.\n");
}
/*-------------------------------------------------------------------------------
*/
static BOOL getstring (buf, bufsize)
char *buf;
int bufsize;
{ int c;
unsigned bufpos;
void ckbrk(), flushline();
ckbrk ();
buf[0]= '\0';
do
{ c= getchar ();
if ((c == EOF) || (c == '\033'))
{ flushline ();
return FALSE;
}
if (c == '\n')
printf (">>> ");
}
while (isspace (c));
ungetc (c, stdin);
ckbrk ();
for (bufpos= 0; bufpos < bufsize; ++bufpos)
{ c= getchar ();
if ((c == EOF) || (c == '\033'))
{ flushline();
buf[0]= '\0';
return FALSE;
}
if (isspace (c))
{ buf[bufpos]= '\0';
return TRUE;
}
buf[bufpos]= c;
}
printf ("\n*** Input buffer overflow\n");
flushline ();
buf[bufsize - 1]= '\0';
return FALSE;
}
static BOOL getint (ip)
int *ip;
{ char str[20];
BOOL getstring();
if (! getstring (str, sizeof (str)))
return FALSE;
if (sscanf (str, "%d", ip) != 1)
{ printf ("\n*** Could not scan number\n");
return FALSE;
}
return TRUE;
}
static void rdfile (buf, bufsize, filename)
char *buf;
int bufsize;
char *filename;
{ FILE *fp;
int n;
if ((fp= fopen (filename, "r")) == NULL)
{ printf ("*** Can't open \"%s\"\n", filename);
return;
}
n= fread ((char *) buf, 1, bufsize, fp);
if (getc (fp) != EOF)
printf ("*** Warning: buffer size (%d) exceeded before EOF.\n", bufsize);
printf ("%d bytes read.\n", n);
fclose (fp);
}
static void wrfile (buf, bufsize, xfsize, filename)
char *buf;
int bufsize;
int xfsize;
char *filename;
{ FILE *fp;
int n;
if ((xfsize <= 0) || (xfsize > bufsize))
{ printf ("*** Size must be > 0, <= %d\n", bufsize);
return;
}
if ((fp= fopen (filename, "w")) == NULL)
{ printf ("*** Can't open \"%s\"\n", filename);
return;
}
if ((n= fwrite ((char *) buf, 1, xfsize, fp)) < xfsize)
printf ("*** Warning: incomplete write.\n");
printf ("%d bytes written.\n", n);
fclose (fp);
}
static void send (req)
struct IORequest *req;
{ int error;
printf ("Sending I/O request...");
error= DoIO (req);
printf ("\nI/O request sent...");
if (error == 0)
printf ("no error\n");
else
printf ("error = %d\n", error);
}
static void vect (req, vectnum)
struct IORequest *req;
int vectnum;
{ struct Device *dev;
int vn, error;
LONG val;
int vect_intfc();
if (vectnum <= 0)
{ printf ("*** Vector number must be positive\n");
return;
}
dev= req->io_Device;
for (vn= 1; vn <= vectnum; vn += 1)
{ if ( ((val= *((LONG *) ((char *) dev - (LIB_VECTSIZE * vn)))) == -1) || (val == NULL) )
{ printf ("*** There are only %d vectors\n", (vn - 1));
return;
}
}
printf ("Vectoring I/O request through vector #%d...", vectnum);
error= vect_intfc (req, vectnum);
printf ("\nI/O request vectored...");
if (error == 0)
printf ("no error\n");
else
printf ("error = %d\n", error);
}
/*-------------------------------------------------------------------------------
*/
static void ckbrk ()
{ ULONG SetSignal();
if (SetSignal (0, 0) & SIGBREAKF_CTRL_C)
{ printf ("\n*** BREAK\n");
quit (Q_ABORT, NULL, 0, 0, 0);
}
}
static void flushline ()
{ register int c;
void ckbrk();
ckbrk ();
while ( ((c= getchar ()) != EOF) && (c != '\n') )
;
}