/* Autostart PRG file `file_name'. The PRG file can either be a raw CBM file or a P00 file */ int autostart_prg(const char *file_name, unsigned int runmode) { fileio_info_t *finfo; int result; const char *boot_file_name; int mode; if (event_record_active() || event_playback_active()) return -1; /* open prg file */ finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00, FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME, FILEIO_TYPE_PRG); /* can't open file */ if (finfo == NULL) { #ifdef CELL_DEBUG printf("ERROR: Cannot open `%s'.\n", file_name); #endif return -1; } /* determine how to load file */ switch(AutostartPrgMode) { case AUTOSTART_PRG_MODE_VFS: //log_message(autostart_log, "Loading PRG file `%s' with virtual FS on unit #8.", file_name); result = autostart_prg_with_virtual_fs(file_name, finfo); mode = AUTOSTART_HASDISK; boot_file_name = (const char *)finfo->name; break; case AUTOSTART_PRG_MODE_INJECT: //log_message(autostart_log, "Loading PRG file `%s' with direct RAM injection.", file_name); result = autostart_prg_with_ram_injection(file_name, finfo); mode = AUTOSTART_INJECT; boot_file_name = NULL; break; case AUTOSTART_PRG_MODE_DISK: //log_message(autostart_log, "Loading PRG file `%s' with autostart disk image.", file_name); result = autostart_prg_with_disk_image(file_name, finfo, AutostartPrgDiskImage); mode = AUTOSTART_HASDISK; boot_file_name = "*"; break; default: //log_error(autostart_log, "Invalid PRG autostart mode: %d", AutostartPrgMode); result = -1; break; } /* Now either proceed with disk image booting or prg injection after reset */ if (result >= 0) { ui_update_menus(); reboot_for_autostart(boot_file_name, mode, runmode); } /* close prg file */ fileio_close(finfo); return result; }
/* Autostart PRG file `file_name'. The PRG file can either be a raw CBM file or a P00 file, and the FS-based drive emulation is set up so that its directory becomes the current one on unit #8. */ int autostart_prg(const char *file_name, unsigned int runmode) { char *directory; char *file; fileio_info_t *finfo; if (network_connected()) return -1; finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00, FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME, FILEIO_TYPE_PRG); if (finfo == NULL) { log_error(autostart_log, "Cannot open `%s'.", file_name); return -1; } /* Extract the directory path to allow FS-based drive emulation to work. */ util_fname_split(file_name, &directory, &file); if (archdep_path_is_relative(directory)) { char *tmp; archdep_expand_path(&tmp, directory); lib_free(directory); directory = tmp; /* FIXME: We should actually eat `.'s and `..'s from `directory' instead. */ } /* Setup FS-based drive emulation. */ fsdevice_set_directory(directory ? directory : ".", 8); set_true_drive_emulation_mode(0); orig_drive_true_emulation_state =0; resources_set_int("VirtualDevices", 1); resources_set_int("FSDevice8ConvertP00", 1); file_system_detach_disk(8); ui_update_menus(); /* Now it's the same as autostarting a disk image. */ reboot_for_autostart((char *)(finfo->name), AUTOSTART_HASDISK, runmode); lib_free(directory); lib_free(file); fileio_close(finfo); log_message(autostart_log, "Preparing to load PRG file `%s'.", file_name); return 0; }
int nand_fileio_start(struct command_context *cmd_ctx, struct nand_device *nand, const char *filename, int filemode, struct nand_fileio_state *state) { if (state->address % nand->page_size) { command_print(cmd_ctx, "only page-aligned addresses are supported"); return ERROR_COMMAND_SYNTAX_ERROR; } duration_start(&state->bench); if (NULL != filename) { int retval = fileio_open(&state->fileio, filename, filemode, FILEIO_BINARY); if (ERROR_OK != retval) { const char *msg = (FILEIO_READ == filemode) ? "read" : "write"; command_print(cmd_ctx, "failed to open '%s' for %s access", filename, msg); return retval; } state->file_opened = true; } if (!(state->oob_format & NAND_OOB_ONLY)) { state->page_size = nand->page_size; state->page = malloc(nand->page_size); } if (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) { if (nand->page_size == 512) { state->oob_size = 16; state->eccpos = nand_oob_16.eccpos; } else if (nand->page_size == 2048) { state->oob_size = 64; state->eccpos = nand_oob_64.eccpos; } state->oob = malloc(state->oob_size); } return ERROR_OK; }
/* Flash seek next routine replacement. Create valid directory entry at $0100 */ int flash_trap_seek_next(void) { unsigned int i; BYTE direntry[0x20]; DWORD entry; /* bail out if true fs, not emulated */ if (flash_trap_trueflashfs) { return 0; } /* if we are reading the very first entry in the flash, do initialization stuff. */ entry = mem_read(0xF8) | (mem_read(0xF9) << 8) | (mem_read(0xFA) << 16); if (entry == 0x010000) { read_name_from_mem(); if (name_len == 0) { /* the missing filename detection of the original kernal requires at least one valid entry to work. */ name_len = 5; memcpy(name, "DUMMY", 5); seek_state = ST_ENTRY; } else { char *path = flash_trap_fsflashdir; if (!strlen(path)) { path = NULL; } /* open file */ if (fi) { fileio_close(fi); } fi = fileio_open(name, path, FILEIO_FORMAT_RAW, FILEIO_COMMAND_READ, FILEIO_TYPE_ANY); if (fi) { BYTE addr[2]; fileio_read(fi, addr, 2); load_addr = addr[0] | (addr[1] << 8); seek_state = ST_ENTRY; } else { seek_state = ST_END; } } } switch (seek_state) { case ST_ENTRY: memset(direntry, 0x00, sizeof(direntry)); /* copy the actual searched name to force a match */ memcpy(direntry, name, name_len); /* flash_address */ direntry[0x18] = 0x11; direntry[0x19] = 0x10; direntry[0x1A] = 0x02; /* load_address */ direntry[0x1B] = (BYTE)(load_addr & 0xff); direntry[0x1C] = (BYTE)((load_addr >> 8) & 0xff); direntry[0x1D] = (BYTE)((load_addr >> 16) & 0xff); /* sys_address (non-standard) */ direntry[0x1E] = 0x00; direntry[0x1F] = 0x00; seek_state = ST_END; break; case ST_END: memset(direntry, 0x00, sizeof(direntry)); seek_state = ST_EMPTY; break; default: case ST_EMPTY: memset(direntry, 0xFF, sizeof(direntry)); break; } /* write out directory entry to the buffer at $0100-$011F */ for (i = 0; i < sizeof(direntry); i++) { mem_store((WORD)(0x0100 + i), direntry[i]); } return 1; }
static void command_directory_get(vdrive_t *vdrive, bufinfo_t *bufinfo, BYTE *data, unsigned int secondary) { int i, l, f, statrc; unsigned int blocks; char *direntry; unsigned int filelen, isdir; fileio_info_t *finfo = NULL; unsigned int format = 0; char *buf; buf = (char *)lib_malloc(ioutil_maxpathlen()); bufinfo->bufp = bufinfo->name; if (fsdevice_convert_p00_enabled[(vdrive->unit) - 8]) format |= FILEIO_FORMAT_P00; if (!fsdevice_hide_cbm_files_enabled[vdrive->unit - 8]) format |= FILEIO_FORMAT_RAW; /* * Find the next directory entry and return it as a CBM * directory line. */ /* first test if dirmask is needed - maybe this should be replaced by some regex functions... */ f = 1; do { BYTE *p; finfo = NULL; /* iAN CooG 31/08 */ direntry = ioutil_readdir(bufinfo->ioutil_dir); if (direntry == NULL) break; finfo = fileio_open(direntry, bufinfo->dir, format, FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME, FILEIO_TYPE_PRG); if (finfo == NULL) continue; bufinfo->type = finfo->type; if (bufinfo->dirmask[0] == '\0') break; l = strlen(bufinfo->dirmask); for (p = finfo->name, i = 0; *p && bufinfo->dirmask[i] && i < l; i++) { if (bufinfo->dirmask[i] == '?') { p++; } else if (bufinfo->dirmask[i] == '*') { if (!(bufinfo->dirmask[i + 1])) { f = 0; break; } /* end mask */ while (*p && (*p != bufinfo->dirmask[i + 1])) p++; } else { if (*p != bufinfo->dirmask[i]) break; p++; } if ((!*p) && (!(bufinfo->dirmask[i + 1]))) { f = 0; break; } } if (f > 0) fileio_close(finfo); } while (f); if (direntry != NULL) { BYTE *p = bufinfo->name; strcpy(buf, bufinfo->dir); strcat(buf, FSDEV_DIR_SEP_STR); strcat(buf, direntry); /* Line link, Length and spaces */ *p++ = 1; *p++ = 1; statrc = ioutil_stat(buf, &filelen, &isdir); if (statrc == 0) blocks = (filelen + 253) / 254; else blocks = 0; /* this file can't be opened */ if (blocks > 0xffff) blocks = 0xffff; /* Limit file size to 16 bits. */ SET_LO_HI(p, blocks); if (blocks < 10) *p++ = ' '; if (blocks < 100) *p++ = ' '; if (blocks < 1000) *p++ = ' '; /* * Filename */ *p++ = '"'; for (i = 0; finfo->name[i] && (*p = finfo->name[i]); ++i, ++p); *p++ = '"'; for (; i < 16; i++) *p++ = ' '; if (isdir != 0) { *p++ = ' '; /* normal file */ *p++ = 'D'; *p++ = 'I'; *p++ = 'R'; } else { if (blocks) *p++ = ' '; /* normal file */ else *p++ = '*'; /* splat file */ switch(bufinfo->type) { case CBMDOS_FT_DEL: *p++ = 'D'; *p++ = 'E'; *p++ = 'L'; break; case CBMDOS_FT_SEQ: *p++ = 'S'; *p++ = 'E'; *p++ = 'Q'; break; case CBMDOS_FT_PRG: *p++ = 'P'; *p++ = 'R'; *p++ = 'G'; break; case CBMDOS_FT_USR: *p++ = 'U'; *p++ = 'S'; *p++ = 'R'; break; case CBMDOS_FT_REL: *p++ = 'R'; *p++ = 'E'; *p++ = 'L'; break; } } if (ioutil_access(buf, IOUTIL_ACCESS_W_OK)) *p++ = '<'; /* read-only file */ *p = '\0'; /* to allow strlen */ /* some (really very) old programs rely on the directory entry to be 32 Bytes in total (incl. nullbyte) */ l = strlen((char *)(bufinfo->name + 4)) + 4; while (l < 31) { *p++ = ' '; l++; } *p++ = '\0'; bufinfo->buflen = (int)(p - bufinfo->name); } else { BYTE *p = bufinfo->name; /* EOF => End file */ *p++ = 1; *p++ = 1; *p++ = 0; *p++ = 0; memcpy(p, "BLOCKS FREE.", 12); p += 12; memset(p, ' ', 13); p += 13; memset(p, 0, 3); bufinfo->buflen = 32; bufinfo->eof++; } if (finfo != NULL) /* iAN CooG 31/08 */ fileio_close(finfo); lib_free(buf); }
/* Autostart PRG file `file_name'. The PRG file can either be a raw CBM file or a P00 file */ int autostart_prg(const char *file_name, unsigned int runmode) { fileio_info_t *finfo; int result; const char *boot_file_name; int mode; if (network_connected() || event_record_active() || event_playback_active()) { return -1; } /* open prg file */ finfo = fileio_open(file_name, NULL, FILEIO_FORMAT_RAW | FILEIO_FORMAT_P00, FILEIO_COMMAND_READ | FILEIO_COMMAND_FSNAME, FILEIO_TYPE_PRG); /* can't open file */ if (finfo == NULL) { log_error(autostart_log, "Cannot open `%s'.", file_name); return -1; } /* determine how to load file */ switch (AutostartPrgMode) { case AUTOSTART_PRG_MODE_VFS: log_message(autostart_log, "Loading PRG file `%s' with virtual FS on unit #8.", file_name); result = autostart_prg_with_virtual_fs(file_name, finfo, autostart_log); mode = AUTOSTART_HASDISK; boot_file_name = (const char *)finfo->name; break; case AUTOSTART_PRG_MODE_INJECT: log_message(autostart_log, "Loading PRG file `%s' with direct RAM injection.", file_name); result = autostart_prg_with_ram_injection(file_name, finfo, autostart_log); mode = AUTOSTART_INJECT; boot_file_name = NULL; break; case AUTOSTART_PRG_MODE_DISK: { char *savedir; log_message(autostart_log, "Loading PRG file `%s' with autostart disk image.", file_name); /* create the directory where the image should be written first */ util_fname_split(AutostartPrgDiskImage, &savedir, NULL); ioutil_mkdir(savedir, IOUTIL_MKDIR_RWXU); lib_free(savedir); result = autostart_prg_with_disk_image(file_name, finfo, autostart_log, AutostartPrgDiskImage); mode = AUTOSTART_HASDISK; boot_file_name = "*"; } break; default: log_error(autostart_log, "Invalid PRG autostart mode: %d", AutostartPrgMode); result = -1; break; } /* Now either proceed with disk image booting or prg injection after reset */ if (result >= 0) { ui_update_menus(); reboot_for_autostart(boot_file_name, mode, runmode); } /* close prg file */ fileio_close(finfo); return result; }
int advanced_elf_image_open(struct advanced_elf_image *elf, const char *URL) { memset(elf, 0, sizeof(struct advanced_elf_image)); int retval = fileio_open(&elf->fileio, URL, FILEIO_READ, FILEIO_BINARY); size_t done; if (retval != ERROR_OK) return retval; retval = fileio_read(elf->fileio, sizeof(elf->header), &elf->header, &done); if (retval != ERROR_OK) return retval; if (strncmp((char *)elf->header.e_ident, ELFMAG, SELFMAG) != 0) { LOG_ERROR("invalid ELF file, bad magic number"); return ERROR_IMAGE_FORMAT_ERROR; } if (elf->header.e_ident[EI_CLASS] != ELFCLASS32) { LOG_ERROR("invalid ELF file, only 32bits files are supported"); return ERROR_IMAGE_FORMAT_ERROR; } elf->num_sections = elf->header.e_shnum; elf->sections = (Elf32_Shdr *)calloc(elf->header.e_shnum, sizeof(Elf32_Shdr)); retval = fileio_seek(elf->fileio, elf->header.e_shoff); if (retval != ERROR_OK) return retval; retval = fileio_read(elf->fileio, sizeof(Elf32_Shdr) * elf->header.e_shnum, elf->sections, &done); if (retval != ERROR_OK) return retval; for (int i = 0; i < elf->num_sections; i++) if (elf->sections[i].sh_type == 2 /*SHT_SYMTAB*/) { if (elf->sections[i].sh_entsize != sizeof(Elf32_Sym)) { LOG_ERROR("Unexpected symtab entry size in %s: %d.", URL, elf->sections[i].sh_entsize); return ERROR_IMAGE_FORMAT_ERROR; } elf->num_symbols = elf->sections[i].sh_size / elf->sections[i].sh_entsize; elf->symbols = calloc(elf->num_symbols, elf->sections[i].sh_entsize); retval = fileio_seek(elf->fileio, elf->sections[i].sh_offset); if (retval != ERROR_OK) return retval; retval = fileio_read(elf->fileio, sizeof(Elf32_Sym) * elf->num_symbols, elf->symbols, &done); if (retval != ERROR_OK) return retval; if (done != (sizeof(Elf32_Sym) * elf->num_symbols)) return ERROR_IMAGE_FORMAT_ERROR; int str = elf->sections[i].sh_link; if (str < 0 || str >= elf->header.e_shnum || elf->sections[str].sh_type != 3 /*SHT_STRTAB*/) { LOG_ERROR("Invalid strtab link from symtab section"); return ERROR_IMAGE_FORMAT_ERROR; } elf->strtab_size = elf->sections[str].sh_size; elf->strtab = malloc(elf->sections[str].sh_size); retval = fileio_seek(elf->fileio, elf->sections[str].sh_offset); if (retval != ERROR_OK) return retval; retval = fileio_read(elf->fileio, elf->strtab_size, elf->strtab, &done); if (retval != ERROR_OK) return retval; if (done != elf->strtab_size) return ERROR_IMAGE_FORMAT_ERROR; break; } if (!elf->symbols || !elf->strtab) { LOG_ERROR("The FLASH plugin file does not contain a symbol table and cannot be loaded."); return ERROR_IMAGE_FORMAT_ERROR; } //TODO: actually read sections return retval; }
static int fsdevice_open_file(vdrive_t *vdrive, unsigned int secondary, bufinfo_t *bufinfo, cbmdos_cmd_parse_t *cmd_parse, char *rname) { char *comma; tape_image_t *tape; unsigned int format = 0; fileio_info_t *finfo; if (fsdevice_convert_p00_enabled[(vdrive->unit) - 8]) { format |= FILEIO_FORMAT_P00; } if (!fsdevice_hide_cbm_files_enabled[vdrive->unit - 8]) { format |= FILEIO_FORMAT_RAW; } /* Remove comma. */ if ((cmd_parse->parsecmd)[0] == ',') { (cmd_parse->parsecmd)[1] = '\0'; } else { comma = strchr(cmd_parse->parsecmd, ','); if (comma != NULL) { *comma = '\0'; } } /* Test on wildcards. */ if (cbmdos_parse_wildcard_check(cmd_parse->parsecmd, (unsigned int)strlen(cmd_parse->parsecmd)) > 0) { if (bufinfo[secondary].mode == Write || bufinfo[secondary].mode == Append) { fsdevice_error(vdrive, CBMDOS_IPE_BAD_NAME); return FLOPPY_ERROR; } } /* Open file for write mode access. */ if (bufinfo[secondary].mode == Write) { if (fsdevice_save_p00_enabled[vdrive->unit - 8]) { format = FILEIO_FORMAT_P00; } else { format = FILEIO_FORMAT_RAW; } finfo = fileio_open(rname, fsdevice_get_path(vdrive->unit), format, FILEIO_COMMAND_WRITE, bufinfo[secondary].type); if (finfo != NULL) { bufinfo[secondary].fileio_info = finfo; fsdevice_error(vdrive, CBMDOS_IPE_OK); return FLOPPY_COMMAND_OK; } else { fsdevice_error(vdrive, CBMDOS_IPE_FILE_EXISTS); return FLOPPY_ERROR; } } if (bufinfo[secondary].mode == Append) { /* Open file for append mode access. */ finfo = fileio_open(rname, fsdevice_get_path(vdrive->unit), format, FILEIO_COMMAND_APPEND_READ, bufinfo[secondary].type); if (finfo != NULL) { bufinfo[secondary].fileio_info = finfo; fsdevice_error(vdrive, CBMDOS_IPE_OK); return FLOPPY_COMMAND_OK; } else { fsdevice_error(vdrive, CBMDOS_IPE_NOT_FOUND); return FLOPPY_ERROR; } } /* Open file for read mode access. */ tape = bufinfo[secondary].tape; tape->name = util_concat(fsdevice_get_path(vdrive->unit), FSDEV_DIR_SEP_STR, rname, NULL); charset_petconvstring((BYTE *)(tape->name) + strlen(fsdevice_get_path(vdrive->unit))+ strlen(FSDEV_DIR_SEP_STR), 1); tape->read_only = 1; /* Prepare for buffered reads */ bufinfo[secondary].isbuffered = 0; bufinfo[secondary].iseof = 0; if (tape_image_open(tape) < 0) { lib_free(tape->name); tape->name = NULL; } else { tape_file_record_t *r; static BYTE startaddr[2]; tape_seek_start(tape); tape_seek_to_file(tape, 0); r = tape_get_current_file_record(tape); if ( (r->type==1) || (r->type==3) ) { startaddr[0] = r->start_addr & 255; startaddr[1] = r->start_addr >> 8; bufinfo[secondary].bufp = startaddr; bufinfo[secondary].buflen = 2; } else {