20 IRX_ID(
"ROM_file_driver", 2, 1);
44 struct RomImg images[ROMDRV_MAX_IMAGES];
51 static int init(
void);
52 static int romOpen(
iop_file_t *fd,
const char *path,
int mode);
54 static int romRead(
iop_file_t *fd,
void *buffer,
int size);
55 static int romLseek(
iop_file_t *fd,
int offset,
int whence);
56 static struct RomImg *romGetImageStat(
const void *start,
const void *end,
struct RomImg *ImageStat);
59 IOMAN_RETURN_VALUE_IMPL(0);
60 IOMAN_RETURN_VALUE_IMPL(
EIO);
63 IOMAN_RETURN_VALUE(0),
64 IOMAN_RETURN_VALUE(0),
65 IOMAN_RETURN_VALUE(0),
69 IOMAN_RETURN_VALUE(
EIO),
71 IOMAN_RETURN_VALUE(0),
72 IOMAN_RETURN_VALUE(0),
73 IOMAN_RETURN_VALUE(0),
74 IOMAN_RETURN_VALUE(0),
75 IOMAN_RETURN_VALUE(0),
76 IOMAN_RETURN_VALUE(0),
77 IOMAN_RETURN_VALUE(0),
78 IOMAN_RETURN_VALUE(0),
79 IOMAN_RETURN_VALUE(0),
89 int _start(
int argc,
char **argv)
94 if (RegisterLibraryEntries(&_exp_romdrv) != 0) {
95 return MODULE_NO_RESIDENT_END;
98 #ifdef ROMDRV_EXPORT_DEVICES
99 if (RegisterLibraryEntries(&_exp_romdrvX) != 0) {
100 return MODULE_NO_RESIDENT_END;
106 DelDrv(DeviceOps.name);
108 return (AddDrv(&DeviceOps) < 0) ? MODULE_NO_RESIDENT_END : MODULE_RESIDENT_END;
111 static int init(
void)
113 memset(romdrvData.images, 0,
sizeof(romdrvData.images));
114 memset(romdrvData.fileStats, 0,
sizeof(romdrvData.fileStats));
115 memset(romdrvData.fileSlots, 0,
sizeof(romdrvData.fileSlots));
117 romGetImageStat((
const void *)0xbfc00000, (
const void *)0xbfc40000, &romdrvData.images[0]);
121 int romAddDevice(
int unit,
const void *image)
123 int result, OldState;
126 if (unit < ROMDRV_MAX_IMAGES) {
129 if (romdrvData.images[unit].ImageStart == NULL) {
130 stat = romGetImageStat(image, (
const void *)((
const u8 *)image + 0x8000), &romdrvData.images[unit]);
133 result = stat != NULL ? 0 : ROMDRV_ADD_BAD_IMAGE;
135 result = ROMDRV_ADD_FAILED;
139 result = ROMDRV_ADD_FAILED;
145 int romDelDevice(
int unit)
147 int result, OldState;
149 if (unit < ROMDRV_MAX_IMAGES) {
152 if (romdrvData.images[unit].ImageStart != NULL) {
153 romdrvData.images[unit].ImageStart = 0;
158 result = ROMDRV_DEL_FAILED;
161 result = ROMDRV_DEL_FAILED;
167 static int romOpen(
iop_file_t *fd,
const char *path,
int mode)
171 if (fd->unit < ROMDRV_MAX_IMAGES) {
174 image = &romdrvData.images[fd->unit];
176 if (image->ImageStart != NULL) {
180 if (mode != O_RDONLY) {
187 for (slotNum = 0; slotNum < ROMDRV_MAX_FILES; slotNum++) {
188 if (romdrvData.fileStats[slotNum].data == NULL) {
192 if (slotNum == ROMDRV_MAX_FILES) {
197 stat = GetFileStatFromImage(image, path, &romdrvData.fileStats[slotNum]);
202 romdrvData.fileSlots[slotNum].slotNum = slotNum;
203 romdrvData.fileSlots[slotNum].offset = 0;
204 fd->privdata = &romdrvData.fileSlots[slotNum];
223 if (slot->slotNum < ROMDRV_MAX_FILES) {
226 stat = &romdrvData.fileStats[slot->slotNum];
228 if (stat->data != NULL) {
241 static int romRead(
iop_file_t *fd,
void *buffer,
int size)
246 stat = &romdrvData.fileStats[slot->slotNum];
249 if (stat->romdirent->size < (u32)(slot->offset + size)) {
250 size = stat->romdirent->size - slot->offset;
258 memcpy(buffer, (
const u8 *)stat->data + slot->offset, size);
259 slot->offset += size;
264 static int romLseek(
iop_file_t *fd,
int offset,
int whence)
271 stat = &romdrvData.fileStats[slot->slotNum];
272 size = stat->romdirent->size;
279 newOffset = slot->offset + offset;
282 newOffset = size + offset;
289 slot->offset = (size < (u32)newOffset) ? size : (u32)newOffset;
294 static struct RomImg *romGetImageStat(
const void *start,
const void *end,
struct RomImg *ImageStat)
305 ptr = (u32 *)file->name;
306 if (ptr[0] == 0x45534552 && ptr[1] == 0x54 && (*(u16 *)&ptr[2] == 0) && (((file->size + 15) & ~15) == offset)) {
307 ImageStat->ImageStart = start;
308 ImageStat->RomdirStart = ptr;
310 ImageStat->RomdirEnd = (
const void *)((
const u8 *)ptr + size);
315 ImageStat->ImageStart = NULL;
322 unsigned int i, offset, ExtInfoOffset;
323 u8 filename_temp[12];
329 ((u32 *)filename_temp)[0] = 0;
330 ((u32 *)filename_temp)[1] = 0;
331 ((u32 *)filename_temp)[2] = 0;
332 for (i = 0; *filename >= 0x21 && i <
sizeof(filename_temp); i++) {
333 filename_temp[i] = *filename;
337 if (ImageStat->RomdirStart != NULL) {
338 RomdirEntry = ImageStat->RomdirStart;
341 if (((u32 *)filename_temp)[0] == ((u32 *)RomdirEntry->name)[0] && ((u32 *)filename_temp)[1] == ((u32 *)RomdirEntry->name)[1] && (*(u16 *)&((u32 *)filename_temp)[2] == *(u16 *)&((u32 *)RomdirEntry->name)[2])) {
343 stat->romdirent = RomdirEntry;
344 stat->data = ImageStat->ImageStart + offset;
345 stat->extinfo = NULL;
347 if (RomdirEntry->ExtInfoEntrySize != 0) {
348 stat->extinfo = (
void *)((u8 *)ImageStat->RomdirEnd + ExtInfoOffset);
355 offset += (RomdirEntry->size + 15) & ~15;
356 ExtInfoOffset += RomdirEntry->ExtInfoEntrySize;
358 }
while (((u32 *)RomdirEntry->name)[0] != 0x00000000);
369 #ifdef ROMDRV_EXPORT_DEVICES
370 const struct RomImg *romGetDevice(
int unit)
373 const struct RomImg *result;
375 if (unit < ROMDRV_MAX_IMAGES) {
378 if (romdrvData.images[unit].ImageStart != NULL) {
379 result = &romdrvData.images[unit];