Skip to content

Commit

Permalink
mc_emu: Fixed to 8MB MC0 card working
Browse files Browse the repository at this point in the history
  • Loading branch information
rickgaiser committed Sep 10, 2023
1 parent 7ff45f1 commit 6502a4c
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 116 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ Options:
mixing not possible
-ata1=<mode> See -ata0=<mode>
-mc0=<mode> MC0 emulation mode, supported are:
- no (default)
- <file>
-mc1=<mode> See -mc0=<mode>
-elf=<file> ELF file to boot, supported are:
- auto (elf file from cd/dvd) (default)
- <file>
Expand Down
6 changes: 6 additions & 0 deletions ee/loader/config/emu-mc-file.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Name of loaded config, to show to user
name = "MC emulation using image file"

# Modules to load
[[module-emu]]
file = "mc_emu.irx"
225 changes: 118 additions & 107 deletions ee/loader/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ _off64_t lseek64 (int __filedes, _off64_t __offset, int __whence); // should be
#include "../../../iop/common/cdvd_config.h"
#include "../../../iop/common/fakemod.h"
#include "../../../iop/common/fhi_bdm.h"
#include "../../../iop/common/fhi.h"
#include "toml.h"

#define NEWLIB_PORT_AWARE
Expand Down Expand Up @@ -76,6 +77,11 @@ void print_usage()
printf(" mixing not possible\n");
printf(" -ata1=<mode> See -ata0=<mode>\n");
printf("\n");
printf(" -mc0=<mode> MC0 emulation mode, supported are:\n");
printf(" - no (default)\n");
printf(" - <file>\n");
printf(" -mc1=<mode> See -mc0=<mode>\n");
printf("\n");
printf(" -elf=<file> ELF file to boot, supported are:\n");
printf(" - auto (elf file from cd/dvd) (default)\n");
printf(" - <file>\n");
Expand Down Expand Up @@ -658,6 +664,62 @@ void *modlist_get_settings(struct SModList *ml, const char *name)
return settings;
}

int fhi_bdm_add_file_by_fd(struct fhi_bdm *bdm, int fhi_fid, int fd)
{
int i;
off_t size;
unsigned int frag_start = 0;
struct fhi_bdm_fragfile *frag = &bdm->fragfile[fhi_fid];

// Get file size
size = lseek64(fd, 0, SEEK_END);

// Get current frag use count
for (i = 0; i < BDM_MAX_FILES; i++)
frag_start += bdm->fragfile[i].frag_count;

// Set fragment file
frag->frag_start = frag_start;
frag->frag_count = fileXioIoctl2(fd, USBMASS_IOCTL_GET_FRAGLIST, NULL, 0, (void *)&bdm->frags[frag->frag_start], sizeof(bd_fragment_t) * (BDM_MAX_FRAGS - frag->frag_start));
frag->size = size;

// Check for max fragments
if ((frag->frag_start + frag->frag_count) > BDM_MAX_FRAGS) {
printf("Too many fragments (%d)\n", frag->frag_start + frag->frag_count);
return -1;
}

// Debug info
printf("fragfile[%d] fragments: start=%u, count=%u\n", fhi_fid, frag->frag_start, frag->frag_count);
for (i=0; i<frag->frag_count; i++)
printf("- frag[%d] start=%u, count=%u\n", i, (u32)bdm->frags[frag->frag_start+i].sector, bdm->frags[frag->frag_start+i].count);

// Set BDM driver name and number
// NOTE: can be set only once! Check?
bdm->drvName = (u32)fileXioIoctl2(fd, USBMASS_IOCTL_GET_DRIVERNAME, NULL, 0, NULL, 0);
fileXioIoctl2(fd, USBMASS_IOCTL_GET_DEVICE_NUMBER, NULL, 0, &bdm->devNr, 4);
char *drvName = (char *)&bdm->drvName;
printf("Using BDM device: %s%d\n", drvName, (int)bdm->devNr);

return 0;
}

int fhi_bdm_add_file(struct fhi_bdm *bdm, int fhi_fid, const char *name)
{
int fd, rv;

// Open file
printf("Loading %s...\n", name);
fd = open(name, O_RDONLY);
if (fd < 0) {
printf("Unable to open %s\n", name);
return -1;
}

rv = fhi_bdm_add_file_by_fd(bdm, fhi_fid, fd);
close(fd);
return rv;
}

int main(int argc, char *argv[])
{
Expand All @@ -682,6 +744,9 @@ int main(int argc, char *argv[])
const char *sATAMode = "no";
const char *sATA0File = NULL;
const char *sATA1File = NULL;
const char *sMCMode = "no";
const char *sMC0File = NULL;
const char *sMC1File = NULL;
const char *sELFFile = "auto";
int iELFArgcStart = -1;
const char *sMediaType = NULL;
Expand All @@ -700,6 +765,10 @@ int main(int argc, char *argv[])
sATA0File = &argv[i][6];
else if (!strncmp(argv[i], "-ata1=", 6))
sATA1File = &argv[i][6];
else if (!strncmp(argv[i], "-mc0=", 5))
sMC0File = &argv[i][5];
else if (!strncmp(argv[i], "-mc1=", 5))
sMC1File = &argv[i][5];
else if (!strncmp(argv[i], "-elf=", 5))
sELFFile = &argv[i][5];
else if (!strncmp(argv[i], "-mt=", 4))
Expand Down Expand Up @@ -736,6 +805,11 @@ int main(int argc, char *argv[])
sATAMode = "file";
}

// Check for "file" mode of mc emulation
if (sMC0File != NULL || sMC1File != NULL) {
sMCMode = "file";
}

if (sMediaType != NULL) {
if (!strncmp(sMediaType, "cdda", 4)) {
eMediaType = SCECdPS2CD;
Expand Down Expand Up @@ -817,6 +891,16 @@ int main(int argc, char *argv[])
return -1;
}

/*
* Load MC emulation driver settings
*/
if (!strcmp(sMCMode, "no")) {
// Load nothing
} else if (load_driver("emu-mc", sMCMode) < 0) {
printf("ERROR: mc driver %s failed\n", sMCMode);
return -1;
}

/*
* Load all needed files before rebooting the IOP
*/
Expand Down Expand Up @@ -960,25 +1044,8 @@ int main(int argc, char *argv[])
}
printf("- media = %s\n", sMT);

//
// Add ISO as fragfile[0] to fragment list
//
struct fhi_bdm_fragfile *frag = &set_fhi_bdm->fragfile[0];
frag->frag_start = 0;
frag->frag_count = fileXioIoctl2(fd_iso, USBMASS_IOCTL_GET_FRAGLIST, NULL, 0, (void *)&set_fhi_bdm->frags[frag->frag_start], sizeof(bd_fragment_t) * (BDM_MAX_FRAGS - frag->frag_start));
frag->size = iso_size;
printf("ISO fragments: start=%u, count=%u\n", frag->frag_start, frag->frag_count);
for (i=0; i<frag->frag_count; i++) {
printf("- frag[%d] start=%u, count=%u\n", i, (u32)set_fhi_bdm->frags[frag->frag_start+i].sector, set_fhi_bdm->frags[frag->frag_start+i].count);
}
if ((frag->frag_start + frag->frag_count) > BDM_MAX_FRAGS) {
printf("Too many fragments (%d)\n", frag->frag_start + frag->frag_count);
if (fhi_bdm_add_file_by_fd(set_fhi_bdm, FHI_FID_CDVD, fd_iso) < 0)
return -1;
}
set_fhi_bdm->drvName = (u32)fileXioIoctl2(fd_iso, USBMASS_IOCTL_GET_DRIVERNAME, NULL, 0, NULL, 0);
fileXioIoctl2(fd_iso, USBMASS_IOCTL_GET_DEVICE_NUMBER, NULL, 0, &set_fhi_bdm->devNr, 4);
char *drvName = (char *)&set_fhi_bdm->drvName;
printf("Using BDM device: %s%d\n", drvName, (int)set_fhi_bdm->devNr);
close(fd_iso);

set_cdvdman->media = eMediaType;
Expand Down Expand Up @@ -1095,120 +1162,64 @@ int main(int argc, char *argv[])
* Enable ATA0 emulation
*/
if (sATA0File != NULL) {
int fd_hdd;
off_t hdd_size;

// Check for FHI backing store
if (set_fhi_bdm == NULL || mod_fhi == NULL) {
printf("ERROR: ATA emulator needs FHI backing store!\n");
return -1;
}
if (modlist_get_by_name(&drv.mod_isys, "atad_emu.irx") == NULL) {
printf("ERROR: ATA emulator not found!\n");
return -1;
}
// Make sure the FHI module gets loaded
mod_fhi->sUDNL = NULL;

/*
* Check if file exists
* Give low level drivers 10s to start
*/
printf("Loading %s...\n", sATA0File);
for (i = 0; i < 1000; i++) {
fd_hdd = open(sATA0File, O_RDONLY);
if (fd_hdd >= 0)
break;

// Give low level drivers some time to init
nopdelay();
}
if (fd_hdd < 0) {
printf("Unable to open %s\n", sATA0File);
// Load fragfile
if (fhi_bdm_add_file(set_fhi_bdm, FHI_FID_ATA0, sATA0File) < 0)
return -1;
}
// Get HDD file size
hdd_size = lseek64(fd_hdd, 0, SEEK_END);

//
// Add ATA0 HDD image as fragfile[1] to fragment list
//
struct fhi_bdm_fragfile *frag = &set_fhi_bdm->fragfile[1];
frag->frag_start = set_fhi_bdm->fragfile[0].frag_count;
frag->frag_count = fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_FRAGLIST, NULL, 0, (void *)&set_fhi_bdm->frags[frag->frag_start], sizeof(bd_fragment_t) * (BDM_MAX_FRAGS - frag->frag_start));
frag->size = hdd_size;
printf("ATA0 fragments: start=%u, count=%u\n", frag->frag_start, frag->frag_count);
for (i=0; i<frag->frag_count; i++) {
printf("- frag[%d] start=%u, count=%u\n", i, (u32)set_fhi_bdm->frags[frag->frag_start+i].sector, set_fhi_bdm->frags[frag->frag_start+i].count);
}
if ((frag->frag_start + frag->frag_count) > BDM_MAX_FRAGS) {
printf("Too many fragments (%d)\n", frag->frag_start + frag->frag_count);
return -1;
}
set_fhi_bdm->drvName = (u32)fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_DRIVERNAME, NULL, 0, NULL, 0);
fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_DEVICE_NUMBER, NULL, 0, &set_fhi_bdm->devNr, 4);
char *drvName = (char *)&set_fhi_bdm->drvName;
printf("Using BDM device: %s%d\n", drvName, (int)set_fhi_bdm->devNr);
close(fd_hdd);
}

/*
* Enable ATA1 emulation
*/
if (sATA1File != NULL) {
int fd_hdd;
off_t hdd_size;

// Check for FHI backing store
if (set_fhi_bdm == NULL || mod_fhi == NULL) {
printf("ERROR: ATA emulator needs FHI backing store!\n");
return -1;
}
if (modlist_get_by_name(&drv.mod_isys, "atad_emu.irx") == NULL) {
printf("ERROR: ATA emulator not found!\n");
// Make sure the FHI module gets loaded
mod_fhi->sUDNL = NULL;
// Load fragfile
if (fhi_bdm_add_file(set_fhi_bdm, FHI_FID_ATA1, sATA1File) < 0)
return -1;
}

/*
* Enable MC0 emulation
*/
if (sMC0File != NULL) {
// Check for FHI backing store
if (set_fhi_bdm == NULL || mod_fhi == NULL) {
printf("ERROR: ATA emulator needs FHI backing store!\n");
return -1;
}
// Make sure the FHI module gets loaded
mod_fhi->sUDNL = NULL;
// Load fragfile
if (fhi_bdm_add_file(set_fhi_bdm, FHI_FID_MC0, sMC0File) < 0)
return -1;
}

/*
* Check if file exists
* Give low level drivers 10s to start
*/
printf("Loading %s...\n", sATA1File);
for (i = 0; i < 1000; i++) {
fd_hdd = open(sATA1File, O_RDONLY);
if (fd_hdd >= 0)
break;

// Give low level drivers some time to init
nopdelay();
}
if (fd_hdd < 0) {
printf("Unable to open %s\n", sATA1File);
/*
* Enable MC1 emulation
*/
if (sMC1File != NULL) {
// Check for FHI backing store
if (set_fhi_bdm == NULL || mod_fhi == NULL) {
printf("ERROR: ATA emulator needs FHI backing store!\n");
return -1;
}
// Get ISO file size
hdd_size = lseek64(fd_hdd, 0, SEEK_END);

//
// Add ATA1 HDD image as fragfile[2] to fragment list
//
struct fhi_bdm_fragfile *frag = &set_fhi_bdm->fragfile[2];
frag->frag_start = set_fhi_bdm->fragfile[0].frag_count + set_fhi_bdm->fragfile[1].frag_count;
frag->frag_count = fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_FRAGLIST, NULL, 0, (void *)&set_fhi_bdm->frags[frag->frag_start], sizeof(bd_fragment_t) * (BDM_MAX_FRAGS - frag->frag_start));
frag->size = hdd_size;
printf("ATA0 fragments: start=%u, count=%u\n", frag->frag_start, frag->frag_count);
for (i=0; i<frag->frag_count; i++) {
printf("- frag[%d] start=%u, count=%u\n", i, (u32)set_fhi_bdm->frags[frag->frag_start+i].sector, set_fhi_bdm->frags[frag->frag_start+i].count);
}
if ((frag->frag_start + frag->frag_count) > BDM_MAX_FRAGS) {
printf("Too many fragments (%d)\n", frag->frag_start + frag->frag_count);
// Make sure the FHI module gets loaded
mod_fhi->sUDNL = NULL;
// Load fragfile
if (fhi_bdm_add_file(set_fhi_bdm, FHI_FID_MC1, sMC1File) < 0)
return -1;
}
set_fhi_bdm->drvName = (u32)fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_DRIVERNAME, NULL, 0, NULL, 0);
fileXioIoctl2(fd_hdd, USBMASS_IOCTL_GET_DEVICE_NUMBER, NULL, 0, &set_fhi_bdm->devNr, 4);
char *drvName = (char *)&set_fhi_bdm->drvName;
printf("Using BDM device: %s%d\n", drvName, (int)set_fhi_bdm->devNr);
close(fd_hdd);
}

printf("ELF file: %s\n", sELFFile);
Expand Down
13 changes: 7 additions & 6 deletions iop/common/fhi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
#ifndef FHI_H
#define FHI_H


#include <stdint.h>
#include <irx.h>

#define FHI_FID_CDVD 0
#define FHI_FID_ATA0 1
#define FHI_FID_ATA1 2
#define FHI_FID_MC0 3
#define FHI_FID_MC1 4

#ifdef _IOP

#include <stdint.h>
#include <irx.h>

// Size of the file in SECTORS of 512b
uint32_t fhi_size(int file_handle);
// Read SECTORS from file
Expand All @@ -28,5 +29,5 @@ int fhi_write(int file_handle, const void *buffer, unsigned int sector_start, un
#define I_fhi_read DECLARE_IMPORT(5, fhi_read)
#define I_fhi_write DECLARE_IMPORT(6, fhi_write)


#endif
#endif // _IOP
#endif // FHI_H
6 changes: 3 additions & 3 deletions iop/mc_emu/src/mcemu.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ int MceEraseBlock(MemoryCard *mcd, int page)

for (i = 0; i < mcd->cspec.BlockSize; i++) {
r = fhi_write(FHI_FID_MC0 + mcd->mcnum, mcd->dbufp, page + i, 1);
if (!r) {
if (r != 1) {
DPRINTF("erase error\n");
return 0;
}
Expand All @@ -687,7 +687,7 @@ static int do_read(MemoryCard *mcd)
memset(mcd->cbufp, r, 0x10);

r = fhi_read(FHI_FID_MC0 + mcd->mcnum, mcd->dbufp, mcd->rpage, 1);
if (!r) {
if (r != 1) {
DPRINTF("read error\n");
return 0;
}
Expand Down Expand Up @@ -789,7 +789,7 @@ int MceWrite(MemoryCard *mcd, void *buf, u32 size)
mcd->wroff = 0;

r = fhi_write(FHI_FID_MC0 + mcd->mcnum, mcd->dbufp, mcd->wpage, 1);
if (!r) {
if (r != 1) {
DPRINTF("write error.\n");
return 0;
}
Expand Down
Loading

0 comments on commit 6502a4c

Please sign in to comment.