Added support for >2GB HDFs on 32-bit systems, fixes #20

This commit is contained in:
Dimitris Panokostas 2019-01-12 10:42:55 +01:00
parent 07bd50f0a3
commit ee40607ee2
2 changed files with 79 additions and 76 deletions

View file

@ -32,25 +32,25 @@ CPPFLAGS=-MD -MT $@ -MF $(@:%.o=%.d)
# SDL1 targets
#
ifeq ($(PLATFORM),rpi3)
CPPFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
CPPFLAGS += ${DISPMANX_FLAGS} -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1
NAME = amiberry-rpi3-sdl1
else ifeq ($(PLATFORM),rpi2)
CPPFLAGS += ${DISPMANX_FLAGS} -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
CPPFLAGS += ${DISPMANX_FLAGS} -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1
NAME = amiberry-rpi2-sdl1
else ifeq ($(PLATFORM),rpi1)
CPPFLAGS += ${DISPMANX_FLAGS} -DUSE_SDL1
CPPFLAGS += ${DISPMANX_FLAGS} -D_FILE_OFFSET_BITS=64 -DUSE_SDL1
LDFLAGS += ${DISPMANX_LDFLAGS}
NAME = amiberry-rpi1-sdl1
else ifeq ($(PLATFORM),android)
CFLAGS += -mfpu=neon -mfloat-abi=soft
DEFS += -DANDROIDSDL -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
DEFS += -D_FILE_OFFSET_BITS=64 -DANDROIDSDL -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL1
ANDROID = 1
HAVE_NEON = 1
HAVE_SDL_DISPLAY = 1
@ -61,21 +61,21 @@ else ifeq ($(PLATFORM),android)
#
else ifeq ($(PLATFORM),rpi3-sdl2-dispmanx)
USE_SDL2 = 1
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 ${DISPMANX_FLAGS}
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1
NAME = amiberry-rpi3-sdl2-dispmanx
else ifeq ($(PLATFORM),rpi2-sdl2-dispmanx)
USE_SDL2 = 1
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 ${DISPMANX_FLAGS}
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS}
HAVE_NEON = 1
NAME = amiberry-rpi2-sdl2-dispmanx
else ifeq ($(PLATFORM),rpi1-sdl2-dispmanx)
USE_SDL2 = 1
CPPFLAGS += -DUSE_SDL2 ${DISPMANX_FLAGS}
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DUSE_SDL2 ${DISPMANX_FLAGS}
LDFLAGS += ${DISPMANX_LDFLAGS}
NAME = amiberry-rpi1-sdl2-dispmanx
@ -84,25 +84,25 @@ USE_SDL2 = 1
#
else ifeq ($(PLATFORM),rpi3-sdl2)
USE_SDL2 = 1
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
HAVE_NEON = 1
NAME = amiberry-rpi3-sdl2
else ifeq ($(PLATFORM),rpi2-sdl2)
USE_SDL2 = 1
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
HAVE_NEON = 1
NAME = amiberry-rpi2-sdl2
else ifeq ($(PLATFORM),rpi1-sdl2)
USE_SDL2 = 1
CPPFLAGS += -DUSE_SDL2
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DUSE_SDL2
NAME = amiberry-rpi1-sdl2
else ifeq ($(PLATFORM),orangepi-pc)
USE_SDL2 = 1
CFLAGS += -march=armv7-a -mtune=cortex-a7 -mfpu=neon-vfpv4
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD
HAVE_NEON = 1
NAME = amiberry-orangepi-pc
ifdef DEBUG
@ -114,7 +114,7 @@ USE_SDL2 = 1
else ifeq ($(PLATFORM),xu4)
USE_SDL2 = 1
CFLAGS += -mcpu=cortex-a15.cortex-a7 -mtune=cortex-a15.cortex-a7 -mfpu=neon-vfpv4
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
HAVE_NEON = 1
NAME = amiberry-xu4
ifdef DEBUG
@ -126,7 +126,7 @@ USE_SDL2 = 1
else ifeq ($(PLATFORM),c1)
USE_SDL2 = 1
CFLAGS += -march=armv7-a -mcpu=cortex-a5 -mtune=cortex-a5 -mfpu=neon-vfpv4
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
HAVE_NEON = 1
NAME = amiberry-c1
ifdef DEBUG
@ -138,7 +138,7 @@ USE_SDL2 = 1
else ifeq ($(PLATFORM),vero4k)
USE_SDL2 = 1
CFLAGS += -march=armv8-a -mtune=cortex-a53 -mfpu=neon-fp-armv8
CPPFLAGS += -I/opt/vero3/include -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
CPPFLAGS += -I/opt/vero3/include -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
LDFLAGS += -L/opt/vero3/lib
HAVE_NEON = 1
NAME = amiberry-vero4k
@ -146,21 +146,21 @@ USE_SDL2 = 1
else ifeq ($(PLATFORM),tinker)
USE_SDL2 = 1
CFLAGS += -march=armv7-a -mtune=cortex-a17 -mfpu=neon-vfpv4
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DFASTERCYCLES -DUSE_RENDER_THREAD -DMALI_GPU
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DFASTERCYCLES -DUSE_RENDER_THREAD -DMALI_GPU
HAVE_NEON = 1
NAME = amiberry-tinker
else ifeq ($(PLATFORM),rockpro64)
USE_SDL2 = 1
CFLAGS += -march=armv8-a -mtune=cortex-a53 -mfpu=neon-fp-armv8
CPPFLAGS += -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
CPPFLAGS += -D_FILE_OFFSET_BITS=64 -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2 -DMALI_GPU -DUSE_RENDER_THREAD -DFASTERCYCLES
HAVE_NEON = 1
NAME = amiberry-rockpro64
else ifeq ($(PLATFORM),android-sdl2)
USE_SDL2 = 1
CFLAGS += -mfpu=neon -mfloat-abi=soft
DEFS += -DANDROIDSDL -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
DEFS += -D_FILE_OFFSET_BITS=64 -DANDROIDSDL -DARMV6T2 -DUSE_ARMNEON -DARM_HAS_DIV -DUSE_SDL2
ANDROID = 1
HAVE_NEON = 1
HAVE_SDL_DISPLAY = 1

View file

@ -37,15 +37,17 @@ struct uae_driveinfo {
#define HDF_HANDLE_FILE 1
#define HDF_HANDLE_ZFILE 2
#define HDF_HANDLE_UNKNOWN 3
#undef INVALID_HANDLE_VALUE
#define INVALID_HANDLE_VALUE NULL
#define CACHE_SIZE 16384
#define CACHE_FLUSH_TIME 5
static const TCHAR *hdz[] = { _T("hdz"), _T("zip"), nullptr };
static const TCHAR *hdz[] = { _T("hdz"), _T("zip"), _T("7z"), nullptr };
int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname)
{
FILE *f = nullptr;
FILE *f = INVALID_HANDLE_VALUE;
int i;
const auto name = my_strdup(pname);
auto zmode = 0;
@ -60,11 +62,11 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname)
hfd->virtual_rdb = nullptr;
if (!hfd->cache)
{
write_log(_T("malloc(%d) failed in hdf_open_target\n"), CACHE_SIZE);
write_log("malloc(%d) failed in hdf_open_target, error %d\n", CACHE_SIZE, errno);
goto end;
}
hfd->handle = xcalloc(struct hardfilehandle, 1);
hfd->handle->f = nullptr;
hfd->handle->f = INVALID_HANDLE_VALUE;
write_log(_T("hfd attempting to open: '%s'\n"), name);
ext = _tcsrchr(name, '.');
@ -78,11 +80,13 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname)
}
}
f = fopen(name, (hfd->ci.readonly ? "rb" : "r+b"));
if (f == nullptr && !hfd->ci.readonly)
if (f == INVALID_HANDLE_VALUE && !hfd->ci.readonly)
{
f = fopen(name, "rbe");
if (f != nullptr)
hfd->ci.readonly = true;
else
goto end;
}
hfd->handle->f = f;
i = _tcslen(name) - 1;
@ -90,46 +94,57 @@ int hdf_open_target(struct hardfiledata *hfd, const TCHAR *pname)
{
if ((i > 0 && (name[i - 1] == '/' || name[i - 1] == '\\')) || i == 0)
{
_tcscpy(hfd->vendor_id, "UAE");
_tcsncpy(hfd->product_id, name + i, 15);
_tcscpy(hfd->product_rev, "0.4");
break;
}
i--;
}
_tcscpy(hfd->vendor_id, _T("UAE"));
_tcscpy(hfd->product_rev, _T("0.4"));
if (f != nullptr)
if (f != INVALID_HANDLE_VALUE)
{
uae_s64 pos = ftell(f);
fseek(f, 0, SEEK_END);
uae_s64 size = ftell(f);
fseek(f, pos, SEEK_SET);
// determine size of hdf file
int ret;
off_t low = -1;
size &= ~(hfd->ci.blocksize - 1);
hfd->physsize = hfd->virtsize = size;
if (hfd->physsize < hfd->ci.blocksize || hfd->physsize == 0)
{
write_log(_T("HDF '%s' is too small\n"), name);
goto end;
if (low == -1) {
// assuming regular file; seek to end and ftell
ret = fseeko(f, 0, SEEK_END);
if (ret)
goto end;
low = ftello(f);
if (low == -1)
goto end;
}
low &= ~(hfd->ci.blocksize - 1);
hfd->physsize = hfd->virtsize = low;
//if (g_debug) {
// write_log("set physsize = virtsize = %lld (low)\n",
// hfd->virtsize);
//}
hfd->handle_valid = HDF_HANDLE_FILE;
if (hfd->physsize < 64 * 1024 * 1024 && zmode)
{
write_log(_T("HDF '%s' re-opened in zfile-mode\n"), name);
if (hfd->physsize < 64 * 1024 * 1024 && zmode) {
write_log("HDF '%s' re-opened in zfile-mode\n", name);
fclose(f);
hfd->handle->f = 0;
hfd->handle->zf = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
hfd->handle->f = INVALID_HANDLE_VALUE;
hfd->handle->zf = zfile_fopen(name, hfd->ci.readonly ? "rb" : "r+b", ZFD_NORMAL);
hfd->handle->zfile = 1;
if (!hfd->handle->zf)
if (!f)
goto end;
zfile_fseek(hfd->handle->zf, 0, SEEK_END);
hfd->physsize = hfd->virtsize = zfile_ftell(hfd->handle->zf);
//if (g_debug) {
// write_log("set physsize = virtsize = %lld\n",
// hfd->virtsize);
//}
zfile_fseek(hfd->handle->zf, 0, SEEK_SET);
hfd->handle_valid = HDF_HANDLE_ZFILE;
}
}
}
else
{
write_log(_T("HDF '%s' failed to open.\n"), name);
write_log("HDF '%s' failed to open. error = %d\n", name, errno);
}
if (hfd->handle_valid || hfd->drive_empty)
{
@ -143,22 +158,13 @@ end:
return 0;
}
static void freehandle(struct hardfilehandle *h)
{
if (!h)
return;
if (!h->zfile && h->f != 0)
fclose(h->f);
if (h->zfile && h->zf)
zfile_fclose(h->zf);
h->zf = nullptr;
h->f = nullptr;
h->zfile = 0;
}
void hdf_close_target(struct hardfiledata *hfd)
{
freehandle(hfd->handle);
write_log("hdf_close_target\n");
if (hfd->handle && hfd->handle->f) {
write_log("closing file handle %p\n", hfd->handle->f);
fclose(hfd->handle->f);
}
xfree(hfd->handle);
xfree(hfd->emptyname);
hfd->emptyname = nullptr;
@ -180,15 +186,13 @@ static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset)
if (hfd->handle_valid == 0)
{
target_startup_msg(_T("Internal error"), _T("hd: hdf handle is not valid."));
uae_restart(1, nullptr);
return -1;
abort();
}
if (offset >= hfd->physsize - hfd->virtual_size)
{
write_log(_T("hd: tried to seek out of bounds! (%I64X >= %I64X - %I64X)\n"), offset, hfd->physsize, hfd->virtual_size);
target_startup_msg(_T("Internal error"), _T("hd: tried to seek out of bounds."));
uae_restart(1, nullptr);
return -1;
abort();
}
offset += hfd->offset;
if (offset & (hfd->ci.blocksize - 1))
@ -196,14 +200,16 @@ static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset)
write_log(_T("hd: poscheck failed, offset=%I64X not aligned to blocksize=%d! (%I64X & %04X = %04X)\n"),
offset, hfd->ci.blocksize, offset, hfd->ci.blocksize, offset & (hfd->ci.blocksize - 1));
target_startup_msg(_T("Internal error"), _T("hd: poscheck failed."));
uae_restart(1, nullptr);
return -1;
abort();
}
if (hfd->handle_valid == HDF_HANDLE_FILE)
{
auto ret = fseek(hfd->handle->f, offset, SEEK_SET);
auto ret = fseeko(hfd->handle->f, offset, SEEK_SET);
if (ret != 0)
{
write_log("hdf_seek failed\n");
return -1;
}
}
else if (hfd->handle_valid == HDF_HANDLE_ZFILE)
{
@ -214,18 +220,19 @@ static int hdf_seek(struct hardfiledata *hfd, uae_u64 offset)
static void poscheck(struct hardfiledata *hfd, int len)
{
int ret;
uae_u64 pos = 0;
if (hfd->handle_valid == HDF_HANDLE_FILE)
{
pos = ftell(hfd->handle->f);
if (pos == -1)
ret = fseeko(hfd->handle->f, 0, SEEK_CUR);
if (ret)
{
write_log(_T("hd: poscheck failed. seek failure"));
target_startup_msg(_T("Internal error"), _T("hd: poscheck failed. seek failure."));
uae_restart(1, nullptr);
return;
abort();
}
pos = ftello(hfd->handle->f);
}
else if (hfd->handle_valid == HDF_HANDLE_ZFILE)
{
@ -235,29 +242,25 @@ static void poscheck(struct hardfiledata *hfd, int len)
{
write_log(_T("hd: poscheck failed, negative length! (%d)"), len);
target_startup_msg(_T("Internal error"), _T("hd: poscheck failed, negative length."));
uae_restart(1, nullptr);
return;
abort();
}
if (pos < hfd->offset)
{
write_log(_T("hd: poscheck failed, offset out of bounds! (%I64d < %I64d)"), pos, hfd->offset);
target_startup_msg(_T("Internal error"), _T("hd: hd: poscheck failed, offset out of bounds."));
uae_restart(1, nullptr);
return;
abort();
}
if (pos >= hfd->offset + hfd->physsize - hfd->virtual_size || pos >= hfd->offset + hfd->physsize + len - hfd->virtual_size)
{
write_log(_T("hd: poscheck failed, offset out of bounds! (%I64d >= %I64d, LEN=%d)"), pos, hfd->offset + hfd->physsize, len);
target_startup_msg(_T("Internal error"), _T("hd: hd: poscheck failed, offset out of bounds."));
uae_restart(1, nullptr);
return;
abort();
}
if (pos & (hfd->ci.blocksize - 1))
{
write_log(_T("hd: poscheck failed, offset not aligned to blocksize! (%I64X & %04X = %04X\n"), pos, hfd->ci.blocksize, pos & hfd->ci.blocksize);
target_startup_msg(_T("Internal error"), _T("hd: poscheck failed, offset not aligned to blocksize."));
uae_restart(1, nullptr);
return;
abort();
}
}