Exemplo n.º 1
0
static void dump_result(nameinfo_t *result) {
	printf("CMD=%s\n", command_to_name(result->cmd));
	printf("DRIVE=%c\n", result->drive == NAMEINFO_UNUSED_DRIVE ? '-' :
				(result->drive == NAMEINFO_UNDEF_DRIVE ? '*' :
				(result->drive == NAMEINFO_LAST_DRIVE ? 'L' :
				result->drive + 0x30)));
	printf("DRIVENAME='%s'\n", result->drivename ? (char*) result->drivename : nullstring);
	printf("NAME='%s' (%d)\n", result->name ? (char*)result->name : nullstring, result->namelen);
	printf("ACCESS=%c\n", result->access ? result->access : '-');
	printf("TYPE=%c", result->type ? result->type : '-'); debug_putcrlf();
	printf("DRIVE2=%c\n", result->file[0].drive == NAMEINFO_UNUSED_DRIVE ? '-' :
				(result->file[0].drive == NAMEINFO_UNDEF_DRIVE ? '*' :
				(result->file[0].drive == NAMEINFO_LAST_DRIVE ? 'L' :
				result->file[0].drive + 0x30)));
	printf("DRIVENAME2='%s'\n", result->file[0].drivename ? (char*) result->file[0].drivename : nullstring);
	printf("NAME2='%s' (%d)\n", result->file[0].name ? (char*)result->file[0].name : nullstring, result->file[0].namelen);
	printf("RECLEN=%d\n", result->recordlen);
	debug_flush();
}
Exemplo n.º 2
0
Arquivo: file.c Projeto: fachat/XD2031
// opens the file, registers an error code in command->error if necessary
// If the open was successful, setup a channel for the given channel number
// (note: explicitely not secondary device number, as IEEE and IEC in parallel
// use overlapping numbers, so they may be shifted or similar to avoid clashes)
//
// The command buffer is used as transmit buffer, so it must not be overwritten
// until the open has been sent.
//
// note that if it returns a value <0 on error, it has to have the error message
// set appropriately.
//
int8_t file_open(uint8_t channel_no, bus_t *bus, errormsg_t *errormsg,
                 void (*callback)(int8_t errnum, uint8_t *rxdata), uint8_t openflag) {

    assert_not_null(bus, "file_open: bus is null");

    cmd_t *command = &(bus->command);
    rtconfig_t *rtconf = &(bus->rtconf);

#ifdef DEBUG_FILE
    debug_printf("OPEN FILE: FOR CHAN: %d WITH NAME: '%s', OPENFLAG=%d\n",
                 channel_no, (char*)&(command->command_buffer), openflag);
#endif

    // note: in a preemtive env, the following would have to be protected
    // to be atomic as we modify static variables

    parse_filename(command, &nameinfo, (openflag & OPENFLAG_LOAD) ? PARSEHINT_LOAD : 0);

#ifdef DEBUG_FILE
    debug_printf("  PARSE -> ACCESS=%c, TYPE=%c\n", nameinfo.access, nameinfo.type);
#endif

    // drive handling needed for error message drive
    if (nameinfo.drive == NAMEINFO_LAST_DRIVE) {
        nameinfo.drive = rtconf->last_used_drive;
    }
    else if (nameinfo.drive == NAMEINFO_UNUSED_DRIVE) {
        // TODO: match CBM behavior
        nameinfo.drive = rtconf->last_used_drive;
    }
    int8_t errdrive = rtconf->errmsg_with_drive ? nameinfo.drive : -1;

    // post-parse

    if (nameinfo.cmd != CMD_NONE && nameinfo.cmd != CMD_DIR && nameinfo.cmd != CMD_OVERWRITE) {
        // command name during open
        // this is in fact ignored by CBM DOS as checked with VICE's true drive emulation
        debug_printf("NO CORRECT CMD: %s\n", command_to_name(nameinfo.cmd));
        nameinfo.cmd = 0;
    }
    if (nameinfo.type != 0 && nameinfo.type != 'S' && nameinfo.type != 'P'
            && nameinfo.type != 'U' && nameinfo.type != 'L') {
        // not set, or set as not sequential and not program
        debug_puts("UNKOWN FILE TYPE: ");
        debug_putc(nameinfo.type);
        debug_putcrlf();
        set_error_tsd(errormsg, CBM_ERROR_FILE_TYPE_MISMATCH, 0, 0, errdrive);
        return -1;
    }
    if (nameinfo.access != 0 && nameinfo.access != 'W' && nameinfo.access != 'R'
            && nameinfo.access != 'A' && nameinfo.access != 'X') {
        debug_puts("UNKNOWN FILE ACCESS TYPE ");
        debug_putc(nameinfo.access);
        debug_putcrlf();
        // not set, or set as not read, write, or append, or r/w ('X')
        set_error_tsd(errormsg, CBM_ERROR_SYNTAX_UNKNOWN, 0, 0, errdrive);
        return -1;
    }
    if (nameinfo.cmd == CMD_DIR && (nameinfo.access != 0 && nameinfo.access != 'R')) {
        // trying to write to a directory
        debug_puts("WRITE TO DIRECTORY!");
        debug_putcrlf();
        set_error_tsd(errormsg, CBM_ERROR_FILE_EXISTS, 0, 0, errdrive);
        return -1;
    }

    uint8_t type = FS_OPEN_RD;

    // file access default
    if (nameinfo.access == 0) {
        if (openflag == OPENFLAG_LOAD) {
            nameinfo.access = 'R';
        } else if (openflag == OPENFLAG_SAVE) {
            nameinfo.access = 'W';
        }
    }

    // file type defaults
    if (nameinfo.type == 0) {
        // do we create a file (access=='W')?
        if (nameinfo.access == 'W') {
            // write (like save)
            if (openflag == OPENFLAG_SAVE) {
                nameinfo.type = 'P';
            } else {
                nameinfo.type = 'S';
            }
        }
        if (nameinfo.access == 'R') {
            if (openflag == OPENFLAG_LOAD) {
                // on load, 'P' is the default
                nameinfo.type = 'P';
            }
        }
    }

    if (nameinfo.access == 'X') {
        // trying to open up a R/W channel
        debug_puts("OPENING UP A R/W CHANNEL!");
        debug_putcrlf();
        type = FS_OPEN_RW;
    }

    if (nameinfo.name[0] == '#') {
        // trying to open up a direct channel
        // Note: needs to be supported for D64 support with U1/U2/...
        // Note: '#' is still blocking on read!
        debug_puts("OPENING UP A DIRECT CHANNEL!");
        debug_putcrlf();

        type = FS_OPEN_DIRECT;
    }

    // if ",W" or secondary address is one, i.e. save
    if (nameinfo.access == 'W') {
        type = FS_OPEN_WR;
    }
    if (nameinfo.access == 'A') {
        type = FS_OPEN_AP;
    }
    if (nameinfo.cmd == CMD_DIR) {
        if (openflag & OPENFLAG_LOAD) {
            type = FS_OPEN_DR;
        } else {
            type = FS_OPEN_RD;
        }
    } else if (nameinfo.cmd == CMD_OVERWRITE) {
        type = FS_OPEN_OW;
    }

#ifdef DEBUG_FILE
    debug_printf("NAME='%s' (%d)\n", nameinfo.name, nameinfo.namelen);
    debug_printf("ACCESS=%c\n", nameinfo.access);
    debug_printf("CMD=%d\n", nameinfo.cmd);
    debug_flush();
#endif

    return file_submit_call(channel_no, type, command->command_buffer, errormsg, rtconf, callback, 0);

}