12#include "mcman-internal.h"
14#if defined(BUILDING_VMCMAN)
15typedef struct vmc_cardinfo_
26static vmc_cardinfo_t mcman_vmc_cardinfo[MCMAN_MAXSLOT];
28static void mcman_iomanx_backing_clear_slot(
int slot)
30 vmc_cardinfo_t *cardinfo;
31 cardinfo = &mcman_vmc_cardinfo[slot];
32 if (cardinfo->fd >= 0) {
33 iomanX_close(cardinfo->fd);
35 memset(cardinfo, 0,
sizeof(vmc_cardinfo_t));
39 mcman_probePS2Card(0, slot);
42static int mcman_iomanx_backing_validate(
int slot,
int check_mounted)
44 vmc_cardinfo_t *cardinfo;
46 if (slot > MCMAN_MAXSLOT) {
50 cardinfo = &mcman_vmc_cardinfo[slot];
53 if (cardinfo->mounted == 0) {
60int mcman_iomanx_backing_mount(
int port,
int slot,
const char *filename)
65 vmc_cardinfo_t *cardinfo;
69 r = mcman_iomanx_backing_validate(slot, 0);
76 cardinfo = &mcman_vmc_cardinfo[slot];
78 fd = iomanX_open(filename, FIO_O_RDWR, 0);
86 cardsize = iomanX_lseek(fd, 0, FIO_SEEK_END);
87 cardinfo->cardsize = cardsize;
88 iomanX_lseek(fd, 0, FIO_SEEK_SET);
96 read_result = iomanX_read(fd, &superblock,
sizeof(superblock));
97 if (read_result !=
sizeof(superblock)) {
98 if (read_result >= 0) {
107 if (strncmp(superblock.magic, SUPERBLOCK_MAGIC, 28) != 0) {
112 if (superblock.cardtype != sceMcTypePS2) {
116 total_pages = superblock.pages_per_cluster * superblock.blocksize;
118 if (cardsize == ((superblock.pagesize + 0x10) * total_pages)) {
119 cardinfo->has_ecc = 1;
121 else if (cardsize == ((superblock.pagesize) * total_pages)) {
122 cardinfo->has_ecc = 0;
130 if (superblock.pagesize != 512 && superblock.pagesize != 528) {
137 cardinfo->pagesize = superblock.pagesize;
138 cardinfo->blocksize = superblock.blocksize;
139 cardinfo->flags = superblock.cardflags;
142 mcman_probePS2Card(port, slot);
143 if (McGetFormat(port, slot) > 0) {
147 if (McGetFormat(port, slot) < 0) {
154 mcman_iomanx_backing_clear_slot(slot);
159int mcman_iomanx_backing_umount(
int port,
int slot)
165 r = mcman_iomanx_backing_validate(slot, 1);
170 mcman_iomanx_backing_clear_slot(slot);
176int mcman_iomanx_backing_getcardspec(
int port,
int slot, s16 *pagesize, u16 *blocksize,
int *cardsize, u8 *flags)
179 vmc_cardinfo_t *cardinfo;
183 r = mcman_iomanx_backing_validate(slot, 1);
188 cardinfo = &mcman_vmc_cardinfo[slot];
191 *pagesize = cardinfo->pagesize;
195 *blocksize = cardinfo->blocksize;
199 *cardsize = cardinfo->cardsize;
203 *flags = cardinfo->flags;
209int mcman_iomanx_backing_erase(
int port,
int slot,
int page)
212 vmc_cardinfo_t *cardinfo;
216 r = mcman_iomanx_backing_validate(slot, 1);
221 cardinfo = &mcman_vmc_cardinfo[slot];
225 int effective_page_size;
227 memset(buf, ((cardinfo->flags & CF_ERASE_ZEROES) != 0) ? 0x0 : 0xFF, sizeof(buf));
228 effective_page_size = (cardinfo->pagesize + (cardinfo->has_ecc ? 0x10 : 0));
229 iomanX_lseek(cardinfo->fd, page * effective_page_size, FIO_SEEK_SET);
230 iomanX_write(cardinfo->fd, buf, effective_page_size);
236int mcman_iomanx_backing_write(
int port,
int slot,
int page,
void *pagebuf,
void *eccbuf)
239 vmc_cardinfo_t *cardinfo;
243 r = mcman_iomanx_backing_validate(slot, 1);
248 cardinfo = &mcman_vmc_cardinfo[slot];
251 int effective_page_size;
253 effective_page_size = (cardinfo->pagesize + (cardinfo->has_ecc ? 0x10 : 0));
254 iomanX_lseek(cardinfo->fd, page * effective_page_size, FIO_SEEK_SET);
255 if (pagebuf != NULL) {
256 iomanX_write(cardinfo->fd, pagebuf, 512);
259 iomanX_lseek(cardinfo->fd, 512, FIO_SEEK_CUR);
262 if (cardinfo->has_ecc) {
263 if (eccbuf != NULL) {
264 iomanX_write(cardinfo->fd, eccbuf, 16);
267 iomanX_lseek(cardinfo->fd, 16, FIO_SEEK_CUR);
277int mcman_iomanx_backing_read(
int port,
int slot,
int page,
void *pagebuf,
void *eccbuf)
280 vmc_cardinfo_t *cardinfo;
284 r = mcman_iomanx_backing_validate(slot, 1);
289 cardinfo = &mcman_vmc_cardinfo[slot];
293 int effective_page_size;
295 pagesize = cardinfo->pagesize;
297 effective_page_size = (cardinfo->pagesize + (cardinfo->has_ecc ? 0x10 : 0));
298 iomanX_lseek(cardinfo->fd, page * effective_page_size, FIO_SEEK_SET);
299 if (pagebuf != NULL) {
300 iomanX_read(cardinfo->fd, pagebuf, 512);
303 iomanX_lseek(cardinfo->fd, 512, FIO_SEEK_CUR);
306 if (cardinfo->has_ecc) {
307 if (eccbuf != NULL) {
308 iomanX_read(cardinfo->fd, eccbuf, 16);
311 iomanX_lseek(cardinfo->fd, 16, FIO_SEEK_CUR);
313 }
else if (pagebuf != NULL && eccbuf != NULL) {
320 memset(eccbuf, ((cardinfo->flags & CF_ERASE_ZEROES) != 0) ? 0x0 : 0xFF, 16);
327 ecc_count = (pagesize + 0x7f) >> 7;
329 ecc_count = pagesize >> 7;
334 McDataChecksum(p_page, p_ecc);
336 p_ecc = (
void *)((u8 *)p_ecc + 3);
337 p_page = (
void *)((u8 *)p_page + 128);