static int hdf_read_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { long outlen = 0; int coffset; if (offset == 0) hfd->cache_valid = 0; coffset = isincache (hfd, offset, len); if (coffset >= 0) { memcpy (buffer, hfd->cache + coffset, len); return len; } hfd->cache_offset = offset; if (offset + CACHE_SIZE > hfd->offset + (hfd->physsize - hfd->virtual_size)) hfd->cache_offset = hfd->offset + (hfd->physsize - hfd->virtual_size) - CACHE_SIZE; hdf_seek (hfd, hfd->cache_offset); poscheck (hfd, CACHE_SIZE); if (hfd->handle_valid == HDF_HANDLE_LINUX) outlen = fread (hfd->cache, 1, CACHE_SIZE, hfd->handle->h); else if (hfd->handle_valid == HDF_HANDLE_ZFILE) outlen = zfile_fread (hfd->cache, 1, CACHE_SIZE, hfd->handle->zf); hfd->cache_valid = 0; if (outlen != CACHE_SIZE) return 0; hfd->cache_valid = 1; coffset = isincache (hfd, offset, len); if (coffset >= 0) { memcpy (buffer, hfd->cache + coffset, len); return len; } write_log ("hdf_read: cache bug! offset=0x%llx len=%d\n", offset, len); hfd->cache_valid = 0; return 0; }
void hfd_flush_cache (struct hardfiledata *hfd, int now) { DWORD outlen = 0; if (!hfd->cache_needs_flush || !hfd->cache_valid) return; if (now || time (NULL) > hfd->cache_needs_flush + CACHE_FLUSH_TIME) { hdf_log ("flushed %d %d %d\n", now, time(NULL), hfd->cache_needs_flush); hdf_seek (hfd, hfd->cache_offset); poscheck (hfd, CACHE_SIZE); WriteFile (hfd->handle, hfd->cache, CACHE_SIZE, &outlen, NULL); hfd->cache_needs_flush = 0; } }
int hdf_write (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { int n; DEBUG_LOG ("called with offset=0x%llx len=%d\n", offset, len); hfd->cache_valid = 0; hdf_seek (hfd, offset); poscheck (hfd, len); n = write ((int)hfd->handle, buffer, len); DEBUG_LOG ("Wrote %d bytes\n", n); return n; }
static int hdf_write_2 (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { int outlen = 0; if (hfd->ci.readonly) { if (g_debug) { write_log("hfd->readonly\n"); } return 0; } if (hfd->dangerous) { if (g_debug) { write_log("hfd->dangerous\n"); } return 0; } hfd->cache_valid = 0; hdf_seek (hfd, offset); poscheck (hfd, len); memcpy (hfd->cache, buffer, len); if (hfd->handle_valid == HDF_HANDLE_LINUX) { outlen = fwrite (hfd->cache, 1, len, hfd->handle->h); //fflush(hfd->handle->h); if (g_debug) { write_log("wrote %u bytes (wanted %d) at offset %llx\n", outlen, len, offset); } const TCHAR *name = hfd->emptyname == NULL ? _T("<unknown>") : hfd->emptyname; if (offset == 0) { long outlen2; uae_u8 *tmp; int tmplen = 512; tmp = (uae_u8*)xmalloc (uae_u8, tmplen); if (tmp) { memset (tmp, 0xa1, tmplen); hdf_seek (hfd, offset); outlen2 = fread (tmp, 1, tmplen, hfd->handle->h); if (memcmp (hfd->cache, tmp, tmplen) != 0 || outlen != len) gui_message (_T("\"%s\"\n\nblock zero write failed!"), name); xfree (tmp); } } } else if (hfd->handle_valid == HDF_HANDLE_ZFILE) { outlen = zfile_fwrite (hfd->cache, 1, len, hfd->handle->zf); } return outlen; }
int hdf_read_target (struct hardfiledata *hfd, void *buffer, uae_u64 offset, int len) { int got = 0; uae_u8 *p = (uae_u8*)buffer; if (hfd->drive_empty) return 0; if (offset < hfd->virtual_size) { uae_u64 len2 = offset + len <= hfd->virtual_size ? len : hfd->virtual_size - offset; if (!hfd->virtual_rdb) return 0; memcpy (buffer, hfd->virtual_rdb + offset, len2); return len2; } offset -= hfd->virtual_size; while (len > 0) { int maxlen; int ret = 0; if (hfd->physsize < CACHE_SIZE) { hfd->cache_valid = 0; hdf_seek (hfd, offset); poscheck (hfd, len); if (hfd->handle_valid == HDF_HANDLE_LINUX) { ret = fread (hfd->cache, 1, len, hfd->handle->h); memcpy (buffer, hfd->cache, ret); } else if (hfd->handle_valid == HDF_HANDLE_ZFILE) { ret = zfile_fread (buffer, 1, len, hfd->handle->zf); } maxlen = len; } else { maxlen = len > CACHE_SIZE ? CACHE_SIZE : len; ret = hdf_read_2 (hfd, p, offset, maxlen); } got += ret; if (ret != maxlen) return got; offset += maxlen; p += maxlen; len -= maxlen; } return got; }