コード例 #1
0
ファイル: cbmrpm41.c プロジェクト: bogde/OpenCBM
static void ARCH_SIGNALDECL
handle_CTRL_C(int dummy)
{
    CBM_FILE fd_cbm_local;

    /*
     * remember fd_cbm, and make the global one invalid
     * so that no routine can call a cbm_...() routine
     * once we have cancelled another one
     */
    fd_cbm_local = fd;
    fd = CBM_FILE_INVALID;

    fprintf(stderr, "\nSIGINT caught, resetting IEC bus...\n");

    DEBUG_PRINTDEBUGCOUNTERS();

    arch_sleep(1);
    cbm_reset(fd_cbm_local);

#if 0   // reset automatically restores the VIA shift register
    arch_usleep(100000);
    fprintf(stderr, "Emergency resetting VIA2 shift register to default.\n");
    cbm_exec_command(fd, drive, CmdBuffer, sizeof(CmdBuffer));
#endif

    cbm_driver_close(fd);
    exit(1);
}
コード例 #2
0
ファイル: pp.c プロジェクト: Flaviowebit/openCBM
static int write_block(unsigned char tr, unsigned char se, const unsigned char *blk, int size, int read_status)
{
    int i = 0;
    unsigned char status[2];

                                                                        SETSTATEDEBUG((void)0);
    status[0] = tr; status[1] = se;
    write_n(status, 2);

                                                                        SETSTATEDEBUG((void)0);
    /* send first byte twice if length is odd */
    if(size % 2) {
        write_n(blk, 2);
        i = 1;
    }
                                                                        SETSTATEDEBUG(debugLibImgByteCount=0);
    write_n(blk+i, size-i);

                                                                        SETSTATEDEBUG(debugLibImgByteCount=-1);
#ifndef USE_CBM_IEC_WAIT    
    if(size == BLOCKSIZE) {
        arch_usleep(20000);
    }
#endif

                                                                        SETSTATEDEBUG((void)0);
    read_n(status, 2);

                                                                        SETSTATEDEBUG((void)0);
    return status[1];
}
コード例 #3
0
ファイル: pp.c プロジェクト: jkaessens/opencbm
static void pp_check_direction(enum pp_direction_e dir)
{
    static enum pp_direction_e direction = PP_READ;
    if(direction != dir)
    {
        arch_usleep(100);
        direction = dir;
    }
}
コード例 #4
0
ファイル: pp.c プロジェクト: jkaessens/opencbm
static void close_disk(void)
{
    pp_write(fd_cbm, 0, 0);
    arch_usleep(100);
    cbm_iec_wait(fd_cbm, IEC_DATA, 0);

    /* make sure the XP1541 portion of the cable is in input mode */
    cbm_pp_read(fd_cbm);
}
コード例 #5
0
ファイル: archlib_vice.c プロジェクト: jkaessens/opencbm
int
cbmarch_iec_wait(CBM_FILE HandleDevice, int Line, int State)
{
    FUNC_ENTER();

    if (State)
    {
        while(!cbm_iec_get(HandleDevice, Line))
            arch_usleep(10);
    }
    else
    {
        while(cbm_iec_get(HandleDevice, Line))
            arch_usleep(10);
    }

    FUNC_LEAVE_INT(cbmarch_iec_poll(HandleDevice));
}
コード例 #6
0
ファイル: pp.c プロジェクト: jkaessens/opencbm
static int read_block(unsigned char tr, unsigned char se, unsigned char *block)
{
    int  i;
    unsigned char status;

    pp_write(fd_cbm, tr, se);
#ifndef USE_CBM_IEC_WAIT
    arch_usleep(20000);
#endif
    pp_read(fd_cbm, &status, &status);

    for(i=0; i<BLOCKSIZE; i+=2) pp_read(fd_cbm, &block[i], &block[i+1]);

    return status;
}
コード例 #7
0
ファイル: pp.c プロジェクト: Flaviowebit/openCBM
static void close_disk(void)
{
                                                                        SETSTATEDEBUG((void)0);
    pp_write(fd_cbm, 0, 0);
    arch_usleep(100);
                                                                        SETSTATEDEBUG((void)0);
    cbm_iec_wait(fd_cbm, IEC_DATA, 0);

    /* make sure the XP1541 portion of the cable is in input mode */
                                                                        SETSTATEDEBUG((void)0);
    cbm_pp_read(fd_cbm);
                                                                        SETSTATEDEBUG((void)0);

    opencbm_plugin_pp_dc_read_n = NULL;

    opencbm_plugin_pp_dc_write_n = NULL;
}
コード例 #8
0
ファイル: pp.c プロジェクト: Flaviowebit/openCBM
static int read_block(unsigned char tr, unsigned char se, unsigned char *block)
{
    unsigned char status[2];
                                                                        SETSTATEDEBUG((void)0);

    status[0] = tr; status[1] = se;
    write_n(status, 2);

#ifndef USE_CBM_IEC_WAIT    
    arch_usleep(20000);
#endif
                                                                        SETSTATEDEBUG((void)0);
    read_n(status, 2);

                                                                        SETSTATEDEBUG(debugLibImgByteCount=0);
    read_n(block, BLOCKSIZE);
                                                                        SETSTATEDEBUG(debugLibImgByteCount=-1);

                                                                        SETSTATEDEBUG((void)0);
    return status[1];
}
コード例 #9
0
ファイル: pp.c プロジェクト: jkaessens/opencbm
static int write_block(unsigned char tr, unsigned char se, const unsigned char *blk, int size, int read_status)
{
    int i = 0;
    unsigned char status;

    pp_write(fd_cbm, tr, se);

    if(size % 2) {
        pp_write(fd_cbm, *blk, *blk);
        i = 1;
    }

    for(; i<size; i+=2) pp_write(fd_cbm, blk[i], blk[i+1]);

#ifndef USE_CBM_IEC_WAIT
    if(size == BLOCKSIZE) {
        arch_usleep(20000);
    }
#endif

    pp_read(fd_cbm, &status, &status);

    return status;
}
コード例 #10
0
ファイル: xu1541.c プロジェクト: Flaviowebit/openCBM
/*! \brief read data from the xu1541 device

 \param data
    Pointer to a buffer which will contain the data read from the xu1541

 \param len
    The number of bytes to read from the xu1541

 \return
    The number of bytes read
*/
int xu1541_read(unsigned char *data, size_t len) 
{
    int bytesRead = 0;
    
    xu1541_dbg(1, "read %d bytes to address %p", len, data);
    
    while(len > 0) 
    {
	int rd, bytes2read;
	int link_ok = 0, err = 0;
	unsigned char rv[2];
	  
	/* limit transfer size */
	bytes2read = (len > XU1541_IO_BUFFER_SIZE)?XU1541_IO_BUFFER_SIZE:len;

	/* request async read, ignore errors as they happen due to */
	/* link being disabled */
	rd = usb.control_msg(xu1541_handle, 
			USB_TYPE_CLASS | USB_ENDPOINT_IN, 
			XU1541_REQUEST_READ, bytes2read, 0, 
			NULL, 0,
			1000);
	
	if(rd < 0) {
	    fprintf(stderr, "USB error in xu1541_request_read(): %s\n", 
		    usb.strerror());
	    exit(-1);
	    return -1;
	}

	/* since the xu1541 may disable interrupts and wouldn't be able */
	/* to do proper USB communication we'd have to expect USB errors */

	/* try to get result, to make sure usb link is working again */
	/* we can't do this in the read itself since windows returns */
	/* just 0 bytes while the USB link is down which we can't */
	/* distinguish from a real 0 byte read event */

	xu1541_dbg(2, "sent request for %d bytes, waiting for result", 
		   bytes2read);

	do 
	{
	    /* get the result code which also contains the current state */
	    /* the xu1541 is in so we know when it's done reading on IEC */
	    if((rd = usb.control_msg(xu1541_handle, 
				     USB_TYPE_CLASS | USB_ENDPOINT_IN, 
				     XU1541_GET_RESULT, 0, 0, 
				     (char*)rv, sizeof(rv), 
				     1000)) == sizeof(rv)) 
	    {
	        xu1541_dbg(2, "got result %d/%d", rv[0], rv[1]);
	      
		// if the first byte is still not XU1541_IO_READ_DONE,
	        // then the device hasn't even entered the copy routine yet, 
	        // so sleep to not slow it down by overloading it with USB 
	        // requests
	        if(rv[0] != XU1541_IO_READ_DONE) 
		{
		    xu1541_dbg(3, "unexpected result");
		    arch_usleep(TIMEOUT_DELAY);
		} 
		else
		{
		    xu1541_dbg(3, "link ok");

	            link_ok = 1;
		    errno = 0;
		}
	    } 
	    else 
	    {
		xu1541_dbg(3, "usb timeout");

		/* count the error states (just out of couriosity) */
		err++;
	    }
	} 
	while(!link_ok);
	
	/* finally read data itself */
	if((rd = usb.control_msg(xu1541_handle, 
				 USB_TYPE_CLASS | USB_ENDPOINT_IN, 
				 XU1541_READ, bytes2read, 0, 
				 (char*)data, bytes2read, 1000)) < 0) 
	{
	    fprintf(stderr, "USB error in xu1541_read(): %s\n", 
		    usb.strerror());
	    return -1;
	}
	
	len -= rd;
	data += rd;
	bytesRead += rd;

	xu1541_dbg(2, "received chunk of %d bytes, total %d, left %d", 
		   rd, bytesRead, len);
	
	/* force end of read */
	if(rd < bytes2read) 
	    len = 0;
    }
    return bytesRead;
}
コード例 #11
0
ファイル: xu1541.c プロジェクト: Flaviowebit/openCBM
/*! \brief write data to the xu1541 device

 \param data
    Pointer to buffer which contains the data to be written to the xu1541

 \param len
    The length of the data buffer to be written to the xu1541

 \return
    The number of bytes written
*/
int xu1541_write(const unsigned char *data, size_t len) 
{
    int bytesWritten = 0;

    xu1541_dbg(1, "write %d bytes from address %p", len, data);

    while(len) 
    {
        int link_ok = 0, err = 0;
        int wr, bytes2write;
	bytes2write = (len > XU1541_IO_BUFFER_SIZE)?XU1541_IO_BUFFER_SIZE:len;
	
	/* the write itself moved the data into the buffer, the actual */
	/* iec write is triggered _after_ this USB write is done */
	if((wr = usb.control_msg(xu1541_handle, 
				 USB_TYPE_CLASS | USB_ENDPOINT_OUT, 
				 XU1541_WRITE, bytes2write, 0, 
				 (char*)data, bytes2write, 
				 USB_TIMEOUT)) < 0) 
	{
	    fprintf(stderr, "USB error xu1541_write(): %s\n", usb.strerror());
	    exit(-1);
	    return -1;
	}
	
	len -= wr;
	data += wr;
	bytesWritten += wr;

	xu1541_dbg(2, "wrote chunk of %d bytes, total %d, left %d", 
		   wr, bytesWritten, len);
 
	/* wait for USB to become available again by requesting the result */
	do 
	{
	    unsigned char rv[2];

	    /* request async result */
	    if(usb.control_msg(xu1541_handle, 
			       USB_TYPE_CLASS | USB_ENDPOINT_IN, 
			       XU1541_GET_RESULT, 0, 0, 
			       (char*)rv, sizeof(rv), 
			       1000) == sizeof(rv)) 
	    {
	        /* the USB link is available again if we got a valid result */
	        if(rv[0] == XU1541_IO_RESULT) {
		    /* device reports failure, stop writing */
		    if(!rv[1])
		        len = 0;

		    link_ok = 1;
		    errno = 0;
		} 
		else
		{
		    xu1541_dbg(3, "unexpected result (%d/%d)", rv[0], rv[1]);
		    arch_usleep(TIMEOUT_DELAY);
		}
	    } 
	    else 
	    {
	        xu1541_dbg(3, "usb timeout");
	        /* count the error states (just out of couriosity) */
	        err++;
	    }
	} 
	while(!link_ok);
    }
    return bytesWritten;
}
コード例 #12
0
ファイル: xu1541.c プロジェクト: Flaviowebit/openCBM
/*! \brief perform an ioctl on the xu1541

 \param cmd
   The IOCTL number

 \param addr
   The (IEC) device to use

 \param secaddr
   The (IEC) secondary address to use

 \return
   Depends upon the IOCTL.

 \todo
   Rework for cleaner structure. Currently, this is a mess!
*/
int xu1541_ioctl(unsigned int cmd, unsigned int addr, unsigned int secaddr)
{
  int nBytes;
  char ret[4];

  xu1541_dbg(1, "ioctl %d for device %d, sub %d", cmd, addr, secaddr);

  /* some commands are being handled asynchronously, namely the ones that */
  /* send a iec byte. These need to ask for the result with a seperate */
  /* command */
  if((cmd == XU1541_TALK)   || (cmd == XU1541_UNTALK) ||
     (cmd == XU1541_LISTEN) || (cmd == XU1541_UNLISTEN) ||
     (cmd == XU1541_OPEN)   || (cmd == XU1541_CLOSE)) 
  {
      int link_ok = 0, err = 0;

      /* USB_TIMEOUT msec timeout required for reset */
      if((nBytes = usb.control_msg(xu1541_handle, 
				   USB_TYPE_CLASS | USB_ENDPOINT_IN, 
				   cmd, (secaddr << 8) + addr, 0, 
				   NULL, 0, 
				   1000)) < 0) 
      {
	  fprintf(stderr, "USB error in xu1541_ioctl(async): %s\n", 
		  usb.strerror());
	  exit(-1);
	  return -1;
      }

      /* wait for USB to become available again by requesting the result */
      do 
      {
	  unsigned char rv[2];
	  
	  /* request async result code */
	  if(usb.control_msg(xu1541_handle, 
			     USB_TYPE_CLASS | USB_ENDPOINT_IN, 
			     XU1541_GET_RESULT, 0, 0, 
			     (char*)rv, sizeof(rv), 
			     1000) == sizeof(rv)) 
	  {
	      /* we got a valid result */
	      if(rv[0] == XU1541_IO_RESULT) 
	      {
		  /* use that result */
		  nBytes = sizeof(rv)-1;
		  ret[0] = rv[1];
		  /* a returned byte means that the USB link is fine */
		  link_ok = 1;
		  errno = 0;
	      } 
	      else 
	      {
		  xu1541_dbg(3, "unexpected result (%d/%d)", rv[0], rv[1]);

		  /* not the expected result */
		  arch_usleep(TIMEOUT_DELAY);
	      }
	  } 
	  else 
	  {
	      xu1541_dbg(3, "usb timeout");

	      /* count the error states (just out of couriosity) */
	      err++;

	      arch_usleep(TIMEOUT_DELAY);
	  }
      } 
      while(!link_ok);
  } 
  else 
  {

      /* sync transfer, read result directly */
      if((nBytes = usb.control_msg(xu1541_handle, 
		   USB_TYPE_CLASS | USB_ENDPOINT_IN, 
		   cmd, (secaddr << 8) + addr, 0, 
		   ret, sizeof(ret), 
		   USB_TIMEOUT)) < 0) 
      {
	  fprintf(stderr, "USB error in xu1541_ioctl(sync): %s\n", 
		  usb.strerror());
	  exit(-1);
	  return -1;
      }
  }

  xu1541_dbg(2, "returned %d bytes", nBytes);

  /* return ok(0) if command does not have a return value */
  if(nBytes == 0) 
      return 0;

  xu1541_dbg(2, "return val = %x", ret[0]);
  return ret[0];
}