示例#1
0
/* 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;
}
示例#2
0
/* 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;
}
示例#3
0
文件: fileio.c 项目: Bot007/openOCD
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;
}
示例#4
0
/* 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;
}
示例#5
0
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);
}
示例#6
0
/* 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;
}
示例#7
0
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;
}
示例#8
0
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 {