Add disc read/write callbacks
Instead of relying on the disc data being directly mapped, and accessing blocks by memcpy'ing from it, provide op_read/op_write callbacks so that the host can do disc ops itself (e.g. access SD). The disc_descr_t describes the callbacks (and an opaque pointer passed as an argument when they are invoked), per-disc.
This commit is contained in:
parent
f0ff05081c
commit
854e89e162
3 changed files with 45 additions and 6 deletions
|
|
@ -189,6 +189,10 @@ pitfalls/observations:
|
||||||
routed to host-side C code in `disc.c`. The emulation code
|
routed to host-side C code in `disc.c`. The emulation code
|
||||||
doesn't support any of the advanced things a driver can be asked
|
doesn't support any of the advanced things a driver can be asked
|
||||||
to do, such as formatting – just read/write of a block.
|
to do, such as formatting – just read/write of a block.
|
||||||
|
The read/write can be performed internally, by passing a pointer
|
||||||
|
to an in-memory mapping of the disc data (e.g. `unix_main.c` just
|
||||||
|
`mmap()`s the disc); or, `op_read`/`op_write` callbacks can be
|
||||||
|
used for when a host disc op needs to be performed.
|
||||||
When the disc is asked to be ejected, a `umac` callback is called;
|
When the disc is asked to be ejected, a `umac` callback is called;
|
||||||
currently this just exits the emulator. The beginnings of
|
currently this just exits the emulator. The beginnings of
|
||||||
multi-disc support are there, but not enabled – again, bare
|
multi-disc support are there, but not enabled – again, bare
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,15 @@
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
typedef int (*disc_op_read)(void *ctx, uint8_t *data, unsigned int offset, unsigned int len);
|
||||||
|
typedef int (*disc_op_write)(void *ctx, uint8_t *data, unsigned int offset, unsigned int len);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *base;
|
uint8_t *base;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int read_only;
|
int read_only;
|
||||||
|
void *op_ctx;
|
||||||
|
disc_op_read op_read;
|
||||||
|
disc_op_write op_write;
|
||||||
} disc_descr_t;
|
} disc_descr_t;
|
||||||
|
|
||||||
#define DISC_NUM_DRIVES 2
|
#define DISC_NUM_DRIVES 2
|
||||||
|
|
|
||||||
42
src/disc.c
42
src/disc.c
|
|
@ -130,11 +130,14 @@ int disc_pv_hook(uint8_t opcode)
|
||||||
// Struct for each drive
|
// Struct for each drive
|
||||||
typedef struct sony_drive_info {
|
typedef struct sony_drive_info {
|
||||||
int num; // Drive number
|
int num; // Drive number
|
||||||
uint8_t *data;
|
uint8_t *data; // If non-zero, direct mapping of block data
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int to_be_mounted; // Flag: drive must be mounted in accRun
|
int to_be_mounted; // Flag: drive must be mounted in accRun
|
||||||
int read_only; // Flag: force write protection
|
int read_only; // Flag: force write protection
|
||||||
uint32_t status; // Mac address of drive status record
|
uint32_t status; // Mac address of drive status record
|
||||||
|
void *op_ctx;
|
||||||
|
disc_op_read op_read; // Callback for read (when data == 0)
|
||||||
|
disc_op_write op_write; // '' '' write ''
|
||||||
} sony_drinfo_t;
|
} sony_drinfo_t;
|
||||||
|
|
||||||
// List of drives handled by this driver
|
// List of drives handled by this driver
|
||||||
|
|
@ -164,6 +167,9 @@ void SonyInit(disc_descr_t discs[DISC_NUM_DRIVES])
|
||||||
drives[0].read_only = discs[0].read_only;
|
drives[0].read_only = discs[0].read_only;
|
||||||
drives[0].data = discs[0].base;
|
drives[0].data = discs[0].base;
|
||||||
drives[0].size = discs[0].size;
|
drives[0].size = discs[0].size;
|
||||||
|
drives[0].op_ctx = discs[0].op_ctx;
|
||||||
|
drives[0].op_read = discs[0].op_read;
|
||||||
|
drives[0].op_write = discs[0].op_write;
|
||||||
// FIXME: Disc 2
|
// FIXME: Disc 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,8 +301,20 @@ int16_t SonyPrime(uint32_t pb, uint32_t dce)
|
||||||
size_t actual = 0;
|
size_t actual = 0;
|
||||||
if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {
|
if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {
|
||||||
DDBG("DISC: READ %ld from +0x%x\n", length, position);
|
DDBG("DISC: READ %ld from +0x%x\n", length, position);
|
||||||
DDBG(" (Read buffer: %p)\n", (void *)&info->data[position]);
|
if (info->data) {
|
||||||
memcpy(buffer, &info->data[position], length);
|
DDBG(" (Read buffer: %p)\n", (void *)&info->data[position]);
|
||||||
|
memcpy(buffer, &info->data[position], length);
|
||||||
|
} else {
|
||||||
|
if (info->op_read) {
|
||||||
|
DDBG(" (read op into buffer)\n");
|
||||||
|
int r = info->op_read(info->op_ctx, buffer, position, length);
|
||||||
|
if (r < 0)
|
||||||
|
return set_dsk_err(paramErr);
|
||||||
|
} else {
|
||||||
|
DERR("No disc read strategy!\n");
|
||||||
|
return set_dsk_err(offLinErr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clear TagBuf
|
// Clear TagBuf
|
||||||
WriteMacInt32(0x2fc, 0);
|
WriteMacInt32(0x2fc, 0);
|
||||||
|
|
@ -310,9 +328,21 @@ int16_t SonyPrime(uint32_t pb, uint32_t dce)
|
||||||
return set_dsk_err(wPrErr);
|
return set_dsk_err(wPrErr);
|
||||||
|
|
||||||
DDBG("DISC: WRITE %ld to +0x%x\n", length, position);
|
DDBG("DISC: WRITE %ld to +0x%x\n", length, position);
|
||||||
DDBG(" (Write buffer: %p)\n", (void *)&info->data[position]);
|
if (info->data) {
|
||||||
memcpy(&info->data[position], buffer, length);
|
DDBG(" (Write buffer: %p)\n", (void *)&info->data[position]);
|
||||||
}
|
memcpy(&info->data[position], buffer, length);
|
||||||
|
} else {
|
||||||
|
if (info->op_write) {
|
||||||
|
DDBG(" (write op into buffer)\n");
|
||||||
|
int r = info->op_write(info->op_ctx, buffer, position, length);
|
||||||
|
if (r < 0)
|
||||||
|
return set_dsk_err(paramErr);
|
||||||
|
} else {
|
||||||
|
DERR("No disc write strategy!\n");
|
||||||
|
return set_dsk_err(offLinErr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update ParamBlock and DCE
|
// Update ParamBlock and DCE
|
||||||
WriteMacInt32(pb + ioActCount, actual);
|
WriteMacInt32(pb + ioActCount, actual);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue