Skip to content

Commit

Permalink
Add defragmentation support
Browse files Browse the repository at this point in the history
  • Loading branch information
rickgaiser committed Jun 13, 2022
1 parent 3b9e99a commit 1473a90
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 68 deletions.
1 change: 1 addition & 0 deletions modules/iopcore/cdvdman/Makefile
Expand Up @@ -33,6 +33,7 @@ IOP_BIN = bdm_cdvdman.irx
IOP_OBJS_DIR = obj.bdm/
IOP_OBJS += device-bdm.o
IOP_CFLAGS += -DBDM_DRIVER
IOP_LIBS += -L$(PS2SDK)/iop/lib -lbdm
ifeq ($(IOPCORE_DEBUG),1)
USE_DEV9 = 1
endif
Expand Down
45 changes: 3 additions & 42 deletions modules/iopcore/cdvdman/device-bdm.c
Expand Up @@ -7,6 +7,7 @@
#include "internal.h"

#include <bdm.h>
#include <bd_defrag.h>

#include "device.h"

Expand Down Expand Up @@ -85,11 +86,6 @@ void DeviceStop(void)

void DeviceFSInit(void)
{
int i;
DPRINTF("USB: NumParts = %d\n", cdvdman_settings.common.NumParts);
for (i = 0; i < cdvdman_settings.common.NumParts; i++)
DPRINTF("USB: LBAs[%d] = %lu\n", i, cdvdman_settings.LBAs[i]);

DPRINTF("Waiting for device...\n");
WaitSema(bdm_io_sema);
DPRINTF("Waiting for device...done!\n");
Expand All @@ -110,51 +106,16 @@ void DeviceUnmount(void)

int DeviceReadSectors(u32 lsn, void *buffer, unsigned int sectors)
{
u32 sector;
u16 count;
register u32 r, sectors_to_read, lbound, ubound, nlsn, offslsn;
register int i, esc_flag = 0;
u8 *p = (u8 *)buffer;
int rv = SCECdErNO;

// DPRINTF("%s(%u, 0x%p, %u)\n", __func__, (unsigned int)lsn, buffer, sectors);

if (g_bd == NULL)
return SCECdErTRMOPN;

lbound = 0;
ubound = (cdvdman_settings.common.NumParts > 1) ? 0x80000 : 0xFFFFFFFF;
offslsn = lsn;
r = nlsn = 0;
sectors_to_read = sectors;

WaitSema(bdm_io_sema);
for (i = 0; i < cdvdman_settings.common.NumParts; i++, lbound = ubound, ubound += 0x80000, offslsn -= 0x80000) {

if (lsn >= lbound && lsn < ubound) {
if ((lsn + sectors) > (ubound - 1)) {
sectors_to_read = ubound - lsn;
sectors -= sectors_to_read;
nlsn = ubound;
} else
esc_flag = 1;

sector = cdvdman_settings.LBAs[i] + (offslsn * g_bd_sectors_per_sector);
count = sectors_to_read * g_bd_sectors_per_sector;
if (g_bd->read(g_bd, sector, &p[r], count) != count) {
rv = SCECdErREAD;
break;
}

r += sectors_to_read * 2048;
offslsn += sectors_to_read;
sectors_to_read = sectors;
lsn = nlsn;
}

if (esc_flag)
break;
}
if (bd_defrag(g_bd, &cdvdman_settings.frags, lsn * 4, buffer, sectors * 4) != (sectors * 4))
rv = SCECdErREAD;
SignalSema(bdm_io_sema);

return rv;
Expand Down
7 changes: 5 additions & 2 deletions modules/iopcore/common/cdvd_config.h
Expand Up @@ -2,6 +2,9 @@
#ifndef __CDVD_CONFIG__
#define __CDVD_CONFIG__

#include <tamtypes.h>
#include <usbhdfsd-common.h>

// flags
#define IOPCORE_COMPAT_ALT_READ 0x0001
#define IOPCORE_COMPAT_0_SKIP_VIDEOS 0x0002
Expand All @@ -13,7 +16,7 @@
// fakemodule_flags
#define FAKE_MODULE_FLAG_DEV9 (1 << 0) // not used, compiled in
#define FAKE_MODULE_FLAG_USBD (1 << 1) // Used with BDM-USB or PADEMU
#define FAKE_MODULE_FLAG_SMAP (1 << 2) // not used, compiled in
#define FAKE_MODULE_FLAG_SMAP (1 << 2) // Used with SMB or BDM-UDPBD
#define FAKE_MODULE_FLAG_ATAD (1 << 3) // not used, compiled in
#define FAKE_MODULE_FLAG_CDVDSTM (1 << 4) // not used, compiled in
#define FAKE_MODULE_FLAG_CDVDFSV (1 << 5) // not used, compiled in
Expand Down Expand Up @@ -61,7 +64,7 @@ struct cdvdman_settings_smb
struct cdvdman_settings_bdm
{
struct cdvdman_settings_common common;
u32 LBAs[ISO_MAX_PARTS];
bd_fraglist_t frags;
} __attribute__((packed));

#endif
59 changes: 35 additions & 24 deletions src/bdmsupport.c
Expand Up @@ -12,6 +12,8 @@
#include "include/cheatman.h"
#include "modules/iopcore/common/cdvd_config.h"

#include <usbhdfsd-common.h>

#define NEWLIB_PORT_AWARE
#include <fileXio_rpc.h> // fileXioIoctl, fileXioDevctl

Expand Down Expand Up @@ -314,38 +316,47 @@ static void bdmLaunchGame(int id, config_set_t *configSet)
int irx_size = size_bdm_cdvdman_irx;
compatmask = sbPrepare(game, configSet, irx_size, irx, &index);
settings = (struct cdvdman_settings_bdm *)((u8 *)irx + index);
if (settings == NULL)
return;
memset(&settings->frags, 0, sizeof(bd_fraglist_t));

for (i = 0; i < game->parts; i++) {
bd_fraglist_t part_frags;
int fidx;

// Open file
sbCreatePath(game, partname, bdmPrefix, "/", i);
fd = open(partname, O_RDONLY);
if (fd >= 0) {
int *pBDMDriver = (int *)bdmDriver;
*pBDMDriver = fileXioIoctl(fd, USBMASS_IOCTL_GET_DRIVERNAME, "");
LOG("bdmDriver=%s\n", bdmDriver);

if (settings != NULL)
settings->LBAs[i] = fileXioIoctl(fd, USBMASS_IOCTL_GET_LBA, "");

if (fileXioIoctl(fd, USBMASS_IOCTL_CHECK_CHAIN, "") != 1) {
close(fd);
// Game is fragmented. Do not continue.
if (settings != NULL)
sbUnprepare(&settings->common);

guiMsgBox(_l(_STR_ERR_FRAGMENTED), 0, NULL);
return;
}
if (fd < 0) {
sbUnprepare(&settings->common);
guiMsgBox(_l(_STR_ERR_FILE_INVALID), 0, NULL);
return;
}

if ((gPS2Logo) && (i == 0))
EnablePS2Logo = CheckPS2Logo(fd, 0);
// Get driver - we should only need to do this once
int *pBDMDriver = (int *)bdmDriver;
*pBDMDriver = fileXioIoctl(fd, USBMASS_IOCTL_GET_DRIVERNAME, "");

// Get fragment list
fileXioIoctl2(fd, USBMASS_IOCTL_GET_FRAGLIST, NULL, 0, (void *)&part_frags, sizeof(bd_fraglist_t));
if ((settings->frags.count + part_frags.count) > 10) {
// Too many fragments
close(fd);
} else {
// Unable to open part of the game. Do not continue.
if (settings != NULL)
sbUnprepare(&settings->common);
guiMsgBox(_l(_STR_ERR_FILE_INVALID), 0, NULL);
sbUnprepare(&settings->common);
guiMsgBox(_l(_STR_ERR_FRAGMENTED), 0, NULL);
return;
}

// Add part fragments to iopcore fragment list
for (fidx = 0; fidx < part_frags.count; fidx++) {
settings->frags.list[settings->frags.count] = part_frags.list[fidx];
settings->frags.count++;
}

if ((gPS2Logo) && (i == 0))
EnablePS2Logo = CheckPS2Logo(fd, 0);

close(fd);
}

// Initialize layer 1 information.
Expand Down

1 comment on commit 1473a90

@TnA-Plastic
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically the naming is a bit confusing, because it does not "Defrag" but "support fragments". 😅

Please sign in to comment.