Exemple #1
0
void
TEightTrack::FreeTrackSectors (int track)
{
	int	i;

	for (i=0; i<numSectors; i++)
	{
		if (aSectorOwners[i] == track)
		{
			FreeSector(i);
		}
	}
}
Exemple #2
0
long
TEightTrack::ReadTrack (char* pDst, int trackNum, long size)
{
	int		curSeg;
	int		curOff;
	int		lenToCopy;
	int		lenToBound;
	sector_t	sector;
	char*		pSrc;
	STrack*	pTrack;
	long		countDistributed = 0;

	pTrack = &aTracks[trackNum];

	// don't attempt to read any more than is in the original file
	size = AMin (size, pTrack->bytesToRead);

	while (size)
	{
		// real-mode-like addressing in scrambled sectors
		// get src ptr, segment, offset
		curSeg = pTrack->bytesDistributed / SECTOR_SIZE;
		curOff = pTrack->bytesDistributed % SECTOR_SIZE;
		lenToBound = SECTOR_SIZE - curOff;

		// Note that MakePtr() may force a load from disk if idling
		// has not preloaded the needed segment.
		pSrc = MakePtr (curSeg, curOff, trackNum, &sector);

		if (pSrc == NULL)
		{
			// we were unable to get any more. 
			// we are probably trying to read from disk during an interrupt,
			// which is a no-no.
			// let's get out of here
			break;
		}
		else
		{
			// read to sector boundary, size, or bytesToRead (which ever smallest)
			lenToCopy = AMin (lenToBound, size);

			// "distribute" bytes to reader
			memcpy (pDst, pSrc, lenToCopy);

			// updates
			countDistributed += lenToCopy;
			pTrack->bytesDistributed += lenToCopy;
			curOff += lenToCopy;
			pDst += lenToCopy;
			pTrack->bytesToRead -= lenToCopy;
			size -= lenToCopy;

			ASSERT (curOff <= SECTOR_SIZE);

			if (curOff == SECTOR_SIZE)
			{
				// free sector that has been distributed
				FreeSector (sector);

				// wrap to next sector
				curSeg++;
				curOff = 0;
			}
		}
	}

	return countDistributed;
}	
Exemple #3
0
int FlashRead(FILE *stream, ui8 *buf, ui32 len)
{
  FFIL_T *link_ptr = &((FFSEnt *)stream->handle)->entry.file;
  int  unfinished = FALSE, status = GET_OK;
  ui32 i, num_sectors, space_left, remaining = len;
  ui32 full_len = Flash->sect_sz;
  ui8 *sector;

  /*-------------------------------------------------------------------*/
  /* If the file mode does not permit reading, return error.           */
  /*-------------------------------------------------------------------*/
  if (!(link_ptr->comm->open_mode & F_READ))
  {
    set_errno(EACCES);
    return -1;
  }

  /*-------------------------------------------------------------------*/
  /* If len is 0, return 0.                                            */
  /*-------------------------------------------------------------------*/
  if (len == 0)
    return 0;

  /*-------------------------------------------------------------------*/
  /* If curr_ptr is invalid, return zero.                              */
  /*-------------------------------------------------------------------*/
  if (stream->curr_ptr.sector == (ui16)-1 ||
      stream->curr_ptr.sector == FDRTY_SECT ||
      (stream->curr_ptr.sector == link_ptr->comm->one_past_last.sector &&
       stream->curr_ptr.offset == link_ptr->comm->one_past_last.offset))
    return 0;

  /*-------------------------------------------------------------------*/
  /* If we're in the middle of a sector, read what's left from it.     */
  /*-------------------------------------------------------------------*/
  if (stream->curr_ptr.offset)
  {
    /*-----------------------------------------------------------------*/
    /* If the stream does not have a cache entry, get the sector from  */
    /* the cache.                                                      */
    /*-----------------------------------------------------------------*/
    if (stream->cached == NULL)
    {
      status = GetSector(&Flash->cache, (int)stream->curr_ptr.sector,
                         FALSE, link_ptr->comm, &stream->cached);
      if (status == GET_WRITE_ERROR)
        return -1;
    }

    /*-----------------------------------------------------------------*/
    /* Get the pointer to the sector data.                             */
    /*-----------------------------------------------------------------*/
    sector = ((CacheEntry *)stream->cached)->sector;

    /*-----------------------------------------------------------------*/
    /* Figure out how much space is left in current sector.            */
    /*-----------------------------------------------------------------*/
    space_left = (ui32)(Flash->sect_sz - stream->curr_ptr.offset);

    /*-----------------------------------------------------------------*/
    /* If what has to be read comes only from this sector, read it and */
    /* set remaining to 0 so that we're done.                          */
    /*-----------------------------------------------------------------*/
    if (space_left >= remaining)
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, set    */
      /* unfinished flag to true and read as much as possible.         */
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->one_past_last.sector ==
                                               stream->curr_ptr.sector &&
          link_ptr->comm->one_past_last.offset <stream->curr_ptr.offset +
          (int)remaining)
      {
        unfinished = TRUE;
        remaining = (ui32)(link_ptr->comm->one_past_last.offset -
                           stream->curr_ptr.offset);
        len = remaining;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to copy from sector to buf, remaining bytes.       */
      /*---------------------------------------------------------------*/
      memcpy(buf, &sector[stream->curr_ptr.offset], remaining);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len = (ui32)-1;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Adjust current offset.                                        */
      /*---------------------------------------------------------------*/
      stream->curr_ptr.offset += (ui16)remaining;

      /*---------------------------------------------------------------*/
      /* We're done reading so return.                                 */
      /*---------------------------------------------------------------*/
      goto read_exit;
    }

    /*-----------------------------------------------------------------*/
    /* Else read what's left of this sector, adjust remaining and      */
    /* later, continue reading the other sectors.                      */
    /*-----------------------------------------------------------------*/
    else
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, read   */
      /* as much as possible before returning.                         */
      /*---------------------------------------------------------------*/
      if (stream->curr_ptr.sector == link_ptr->comm->last_sect)
      {
        /*-------------------------------------------------------------*/
        /* If we don't have to the end of the sector, adjust how many  */
        /* more bytes are available for read.                          */
        /*-------------------------------------------------------------*/
        if (link_ptr->comm->one_past_last.sector != (ui16)-1)
          space_left = (ui32)(link_ptr->comm->one_past_last.offset -
                              stream->curr_ptr.offset);
        len = space_left;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to copy space_left bytes from sector to buffer.    */
      /*---------------------------------------------------------------*/
      memcpy(buf, &sector[stream->curr_ptr.offset], space_left);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len = (ui32)-1;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Adjust remaining (number of bytes left to be read) and the    */
      /* buf pointer.                                                  */
      /*---------------------------------------------------------------*/
      remaining -= space_left;
      buf += space_left;

      /*---------------------------------------------------------------*/
      /* Adjust current offset.                                        */
      /*---------------------------------------------------------------*/
      stream->curr_ptr.offset = 0;

      /*---------------------------------------------------------------*/
      /* If this is the last sector, we have to stop, else get next    */
      /* sector to read from.                                          */
      /*---------------------------------------------------------------*/
      if (stream->curr_ptr.sector == link_ptr->comm->last_sect)
      {
        stream->curr_ptr.sector = link_ptr->comm->one_past_last.sector;
        stream->curr_ptr.offset = link_ptr->comm->one_past_last.offset;
        unfinished = TRUE;
        goto read_exit;
      }
      else
      {
        stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
        ++stream->curr_ptr.sect_off;
      }

      /*---------------------------------------------------------------*/
      /* Free current sector because we're done reading from it.       */
      /*---------------------------------------------------------------*/
      FreeSector(&stream->cached, &Flash->cache);
    }
  }

  /*-------------------------------------------------------------------*/
  /* Figure out how many sectors need to be read.                      */
  /*-------------------------------------------------------------------*/
  num_sectors = (remaining + Flash->sect_sz - 1) / Flash->sect_sz;

  /*-------------------------------------------------------------------*/
  /* Loop through number of sectors, reading them in one at a time.    */
  /*-------------------------------------------------------------------*/
  for (i = 0; i < num_sectors; ++i)
  {
    /*-----------------------------------------------------------------*/
    /* Get pointer to the cached sector entry.                         */
    /*-----------------------------------------------------------------*/
    status = GetSector(&Flash->cache, (int)stream->curr_ptr.sector,
                       FALSE, link_ptr->comm, &stream->cached);
    if (status == GET_WRITE_ERROR)
    {
      len -= remaining;
      goto read_exit;
    }

    /*-----------------------------------------------------------------*/
    /* Get pointer to the sector data.                                 */
    /*-----------------------------------------------------------------*/
    sector = ((CacheEntry *)stream->cached)->sector;

    /*-----------------------------------------------------------------*/
    /* If what's left to be read is from this sector, it's the last    */
    /* sector to be read (maybe only partially).                       */
    /*-----------------------------------------------------------------*/
    if (remaining <= Flash->sect_sz)
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, set    */
      /* unfinished flag and read as much as possible.                 */
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->one_past_last.sector ==
                                               stream->curr_ptr.sector &&
          link_ptr->comm->one_past_last.offset < (int)remaining)
      {
        unfinished = TRUE;
        len -= (remaining - link_ptr->comm->one_past_last.offset);
        remaining = link_ptr->comm->one_past_last.offset;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to read everything that's left from this sector.   */
      /*---------------------------------------------------------------*/
      memcpy(buf, sector, remaining);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len -= remaining;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Adjust current pointer.                                       */
      /*---------------------------------------------------------------*/
      if (remaining == Flash->sect_sz)
      {
        stream->curr_ptr.offset = 0;

        /*-------------------------------------------------------------*/
        /* If this is the last sector, set current sector number to    */
        /* invalid (-1), else set it to the next sector in the file.   */
        /*-------------------------------------------------------------*/
        if (link_ptr->comm->last_sect == stream->curr_ptr.sector)
          stream->curr_ptr.sector = (ui16)-1;
        else
        {
          stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
          ++stream->curr_ptr.sect_off;
        }

        /*-------------------------------------------------------------*/
        /* Free current sector because we're done reading from it.     */
        /*-------------------------------------------------------------*/
        FreeSector(&stream->cached, &Flash->cache);
      }
      else
        stream->curr_ptr.offset = (ui16)remaining;

      /*---------------------------------------------------------------*/
      /* We're done reading so return.                                 */
      /*---------------------------------------------------------------*/
      goto read_exit;
    }

    /*-----------------------------------------------------------------*/
    /* Else more than one sector remains to be read.                   */
    /*-----------------------------------------------------------------*/
    else
    {
      /*---------------------------------------------------------------*/
      /* If we're trying to read from past the end of the file, set    */
      /* unfinished flag and read as much as possible before returning.*/
      /*---------------------------------------------------------------*/
      if (link_ptr->comm->last_sect == stream->curr_ptr.sector)
      {
        unfinished = TRUE;
        if (link_ptr->comm->one_past_last.offset)
          full_len = link_ptr->comm->one_past_last.offset;
      }

      /*---------------------------------------------------------------*/
      /* Use memcpy to read the whole sector.                          */
      /*---------------------------------------------------------------*/
      memcpy(buf, sector, full_len);

      /*---------------------------------------------------------------*/
      /* If there was an error reading sector, stop.                   */
      /*---------------------------------------------------------------*/
      if (status == GET_READ_ERROR)
      {
        unfinished = TRUE;
        len -= remaining;
        goto read_exit;
      }

      /*---------------------------------------------------------------*/
      /* Update remaining and buf.                                     */
      /*---------------------------------------------------------------*/
      remaining -= full_len;
      buf += full_len;

      /*---------------------------------------------------------------*/
      /* Free current sector because we're done reading from it.       */
      /*---------------------------------------------------------------*/
      FreeSector(&stream->cached, &Flash->cache);

      /*---------------------------------------------------------------*/
      /* If no more sectors stop, else go to next sector in file.      */
      /*---------------------------------------------------------------*/
      if (unfinished)
      {
        stream->curr_ptr.sector = link_ptr->comm->one_past_last.sector;
        stream->curr_ptr.offset = link_ptr->comm->one_past_last.offset;
        len -= remaining;
        goto read_exit;
      }
      else
      {
        stream->curr_ptr.sector =
                           Flash->sect_tbl[stream->curr_ptr.sector].next;
        ++stream->curr_ptr.sect_off;
        stream->curr_ptr.offset = 0;
      }
    }
  }

  /*-------------------------------------------------------------------*/
  /* Before returning, mark access time and, if read could not be      */
  /* finished, free current sector.                                    */
  /*-------------------------------------------------------------------*/
read_exit:
  link_ptr->comm->ac_time = OsSecCount;
  if (unfinished && stream->cached)
    FreeSector(&stream->cached, &Flash->cache);

  return (int)len;
}