Esempio n. 1
0
static int vdrive_command_copy(vdrive_t *vdrive, char *dest, int length)
{
    char *name, *files, *p, c;
    int status = 0;

    /* Split command line */
    if (!dest || !(files = (char *)memchr(++dest, '=', length)) ) {
        return CBMDOS_IPE_SYNTAX;
    }
    *files++ = 0;

#ifdef DEBUG_DRIVE
    log_debug("COPY: dest= '%s', orig= '%s'.", dest, files);
#endif

    if (vdrive_iec_open(vdrive, (BYTE *)dest, (unsigned int)strlen(dest), 1, NULL))
        return CBMDOS_IPE_FILE_EXISTS;

    name = p = files;
    while (*name) { /* Loop for given files.  */
        for (; *p && *p != ','; p++) ;
        *p = 0;

        /* Skip optional colon. */
        if ((files = strchr(name, ':')))
            name = files + 1;

#ifdef DEBUG_DRIVE
        log_debug("searching for file '%s'.", name);
#endif
        if (vdrive_iec_open(vdrive, (BYTE *)name, (unsigned int)strlen(name), 0, NULL)) {
            vdrive_iec_close(vdrive, 1);
            return CBMDOS_IPE_NOT_FOUND;
        }

        do {
            status = vdrive_iec_read(vdrive, (BYTE *)&c, 0);
            if (vdrive_iec_write(vdrive, c, 1)) {
                vdrive_iec_close(vdrive, 0); /* No space on disk.  */
                vdrive_iec_close(vdrive, 1);
                return CBMDOS_IPE_DISK_FULL;
            }
        } while (status == SERIAL_OK);

        vdrive_iec_close(vdrive, 0);
        name = p + 1; /* Next file */
    }
    vdrive_iec_close(vdrive, 1);
    return CBMDOS_IPE_OK;
}
Esempio n. 2
0
void vdrive_close_all_channels(vdrive_t *vdrive)
{
    unsigned int i;
    bufferinfo_t *p;

    for (i = 0; i <= 15; i++) {
        p = &(vdrive->buffers[i]);
        if (p->mode != BUFFER_NOT_IN_USE && p->mode != BUFFER_COMMAND_CHANNEL)
            vdrive_iec_close(vdrive, i);
    }
}
Esempio n. 3
0
static int iec_open_read_sequential(vdrive_t *vdrive, unsigned int secondary, unsigned int track, unsigned int sector)
{
    int status;
    bufferinfo_t *p = &(vdrive->buffers[secondary]);

    vdrive_alloc_buffer(p, BUFFER_SEQUENTIAL);
    p->bufptr = 2;

    status = vdrive_read_sector(vdrive, p->buffer, track, sector);
    p->length = p->buffer[0] ? 0 : p->buffer[1];

    vdrive_set_last_read(track, sector, p->buffer);

    if (status != 0) {
        vdrive_iec_close(vdrive, secondary);
        return SERIAL_ERROR;
    }
    return SERIAL_OK;
}
Esempio n. 4
0
static int iec_open_read(vdrive_t *vdrive, unsigned int secondary)
{
    int type;
    unsigned int track, sector;
    bufferinfo_t *p = &(vdrive->buffers[secondary]);
    BYTE *slot = p->slot;

    if (!slot) {
        vdrive_iec_close(vdrive, secondary);
        vdrive_command_set_error(vdrive, CBMDOS_IPE_NOT_FOUND, 0, 0);
        return SERIAL_ERROR;
    }

    type = slot[SLOT_TYPE_OFFSET] & 0x07;
    track = (unsigned int)slot[SLOT_FIRST_TRACK];
    sector = (unsigned int)slot[SLOT_FIRST_SECTOR];

    /* Del, Seq, Prg, Usr (Rel not supported here).  */
    if (type != CBMDOS_FT_REL)
        return iec_open_read_sequential(vdrive, secondary, track, sector);

    return SERIAL_ERROR;
}
Esempio n. 5
0
int autostart_prg_with_disk_image(const char *file_name,
                                  fileio_info_t *fh,
                                  log_t log,
                                  const char *image_name)
{
    const int drive = 8;
    const int secondary = 1;
    autostart_prg_t *prg;
    vdrive_t *vdrive;
    int i;
    int old_tde_state;
    int file_name_size;
    BYTE data;
    unsigned int disk_image_type;
    int result, result2;

    /* identify disk image type */
    switch (drive_get_disk_drive_type(drive - 8)) {
    case DRIVE_TYPE_1540:
    case DRIVE_TYPE_1541:
    case DRIVE_TYPE_1541II:
    case DRIVE_TYPE_1551:
    case DRIVE_TYPE_1570:
    case DRIVE_TYPE_2031:
        disk_image_type = DISK_IMAGE_TYPE_D64;
        break;
    case DRIVE_TYPE_2040:
    case DRIVE_TYPE_3040:
    case DRIVE_TYPE_4040:
        disk_image_type = DISK_IMAGE_TYPE_D67;
        break;
    case DRIVE_TYPE_1571:
    case DRIVE_TYPE_1571CR:
        disk_image_type = DISK_IMAGE_TYPE_D71;
        break;
    case DRIVE_TYPE_1581:
    case DRIVE_TYPE_2000:
    case DRIVE_TYPE_4000:
        disk_image_type = DISK_IMAGE_TYPE_D81;
        break;
    case DRIVE_TYPE_8050:
        disk_image_type = DISK_IMAGE_TYPE_D80;
        break;
    case DRIVE_TYPE_8250:
    case DRIVE_TYPE_1001:
        disk_image_type = DISK_IMAGE_TYPE_D82;
        break;
    default:
        log_error(log, "No idea what disk image format to use.");
        return -1;
    }

    /* read prg file */
    prg = load_prg(file_name, fh, log);
    if (prg == NULL) {
        return -1;
    }

    /* disable TDE */
    resources_get_int("DriveTrueEmulation", &old_tde_state);
    if (old_tde_state != 0) {
        log_message(log, "Turning true drive emulation off.");
        resources_set_int("DriveTrueEmulation", 0);
    }

    do {
        result = -1;

        /* create empty image */
        if (vdrive_internal_create_format_disk_image(image_name, (char *)"AUTOSTART", disk_image_type) < 0) {
            log_error(log, "Error creating autostart disk image: %s", image_name);
            break;
        }

        /* attach disk image */
        if (file_system_attach_disk(drive, image_name) < 0) {
            log_error(log, "Could not attach disk image: %s", image_name);
            break;
        }

        /* get vdrive */
        vdrive = file_system_get_vdrive((unsigned int)drive);
        if (vdrive == NULL) {
            break;
        }

        /* get file name size */
        file_name_size = strlen((const char *)fh->name);
        if (file_name_size > 16) {
            file_name_size = 16;
        }

        /* open file on disk */
        if (vdrive_iec_open(vdrive, (const BYTE *)fh->name, file_name_size, secondary, NULL) != SERIAL_OK) {
            log_error(log, "Could not open file");
            break;
        }

        result2 = 0;
        /* write PRG data to file */
        for (i = -2; i < (int)prg->size; i++) {
            switch (i) {
            case -2:
                data = (BYTE)prg->start_addr;
                break;
            case -1:
                data = (BYTE)(prg->start_addr >> 8);
                break;
            default:
                data = prg->data[i];
                break;
            }
            if (vdrive_iec_write(vdrive, data, secondary) != SERIAL_OK) {
                log_error(log, "Could not write file");
                result2 = -1;
                break;
            }
        }

        /* close file */
        if (vdrive_iec_close(vdrive, secondary) != SERIAL_OK) {
            log_error(log, "Could not close file");
            break;
        }
        result = result2;
    } while (0);

    /* free prg file */
    free_prg(prg);

    /* re-enable TDE */
    if (old_tde_state != 0) {
        log_message(log, "Turning true drive emulation on.");
        resources_set_int("DriveTrueEmulation", old_tde_state);
    }

    /* ready */
    return result;
}
Esempio n. 6
0
static int iec_open_write(vdrive_t *vdrive, unsigned int secondary,
                          cbmdos_cmd_parse_t *cmd_parse, const BYTE *name)
{
    bufferinfo_t *p = &(vdrive->buffers[secondary]);
    unsigned int track, sector;
    BYTE *slot = p->slot, *e;

    if (vdrive->image->read_only || VDRIVE_IMAGE_FORMAT_4000_TEST) {
        vdrive_command_set_error(vdrive, CBMDOS_IPE_WRITE_PROTECT_ON, 0, 0);
        return SERIAL_ERROR;
    }

    /* set flag for overwrite mode */
    p->needsupdate = 0;

    if (slot) {
        /* file exists */
        if (*name == '@') {
            /* replace mode: we don't want the dirent updated at all until
                close */
            /* allocate buffers */
            vdrive_alloc_buffer(p, BUFFER_SEQUENTIAL);
            p->bufptr = 2;

            /* Create our own slot, since the one passed is static */
            p->slot = lib_calloc(1, 32);

            /* Copy the static on to the new one. */
            memcpy(p->slot, slot, 32);
            slot = p->slot;

            /* set flag for replace mode */
            p->needsupdate = 1;

            /* find a new track and sector when writing */
            p->track = p->sector = 0;
        } else {
            if (p->readmode == CBMDOS_FAM_APPEND) {
                /* append mode */
                /* allocate buffers */
                vdrive_alloc_buffer(p, BUFFER_SEQUENTIAL);

                /* Create our own slot, since the one passed is static */
                p->slot = lib_calloc(1, 32);

                /* Copy the static on to the new one. */
                memcpy(p->slot, slot, 32);
                slot = p->slot;

                /* set file unclosed */
                p->slot[SLOT_TYPE_OFFSET] &= 0x7f;

                /* get the starting track and sector */
                p->track = track = slot[SLOT_FIRST_TRACK];
                p->sector = sector = slot[SLOT_FIRST_SECTOR];

                /* update block count as we find the end of the file */
                /* the real drives actually don't do this, so each time you
                    append to a file, the block count increases by 1.  I think it
                    is safer to correct the block count. */
                slot[SLOT_NR_BLOCKS] = 255;
                slot[SLOT_NR_BLOCKS + 1] = 255;

                /* scan to the end of the file */
                while (track) {
                    p->track = track;
                    p->sector = sector;
                    if (vdrive_read_sector(vdrive, p->buffer, p->track, p->sector)) {
                        /* couldn't read sector, report error and leave */
                        vdrive_free_buffer(p);
                        vdrive_command_set_error(vdrive, CBMDOS_IPE_ILLEGAL_TRACK_OR_SECTOR, p->track, p->sector);
                        return SERIAL_ERROR;
                    }
                    /* setup next link */
                    track = p->buffer[0];
                    sector = p->buffer[1];

                    /* Increment block count. */
                    if (!(++slot[SLOT_NR_BLOCKS])) {
                        ++slot[SLOT_NR_BLOCKS + 1];
                    }
                }
                /* compensate if the dir link is 0 (rare possibility) */
                if (!p->track) {
                    /* Our loop didn't even execute once, set the block
                       size to 0 */
                    slot[SLOT_NR_BLOCKS] = 0;
                    slot[SLOT_NR_BLOCKS + 1] = 0;
                    /* set buffer pointer to 2 */
                    sector = 1;
                }
                /* set the buffer pointer */
                p->bufptr = sector + 1;
            } else {
                /* can't overwrite an existing file */
                vdrive_iec_close(vdrive, secondary);
                vdrive_command_set_error(vdrive, CBMDOS_IPE_FILE_EXISTS, 0, 0);
                return SERIAL_ERROR;
            }
        }
    } else {
        /* new file... */
        /* create a slot based on the opening name */
        vdrive_dir_create_slot(p, cmd_parse->parsecmd, cmd_parse->parselength,
                               cmd_parse->filetype);

        /* Write the directory entry to disk as an UNCLOSED file. */

        vdrive_dir_find_first_slot(vdrive, NULL, -1, 0, &p->dir);
        e = vdrive_dir_find_next_slot(&p->dir);

        /* If there is not space for the slot, disk is full */
        if (!e) {
            vdrive_free_buffer(p);
            vdrive_command_set_error(vdrive, CBMDOS_IPE_DISK_FULL, 0, 0);
            return SERIAL_ERROR;
        }

        /* find a new track and sector when writing */
        p->track = p->sector = 0;
    }

    if (!p->needsupdate) {
        /* copy the slot information into the sector. */
        memcpy(&p->dir.buffer[p->dir.slot * 32 + 2],
               p->slot + 2, 30);

        /* Write the sector. */
        vdrive_write_sector(vdrive, p->dir.buffer, p->dir.track, p->dir.sector);
    }

    return SERIAL_OK;
}
Esempio n. 7
0
int autostart_prg_with_disk_image(const char *file_name, fileio_info_t *fh, const char *image_name)
{
	const int drive = 8;
	const int secondary = 1;
	autostart_prg_t *prg;
	vdrive_t *vdrive;
	int i;
	int old_tde_state;
	int file_name_size;
	BYTE lo,hi;

	/* read prg file */ 
	prg = load_prg(file_name, fh);
	if (prg == NULL) {
		return -1;
	}

	/* disable TDE */
	resources_get_int("DriveTrueEmulation", &old_tde_state);
	if (old_tde_state != 0)
		resources_set_int("DriveTrueEmulation", 0);

	/* create empty image */
	if (vdrive_internal_create_format_disk_image(image_name, 
				(char *)"AUTOSTART", DISK_IMAGE_TYPE_D64) <0 ) {
		//log_error(log, "Error creating autostart disk image: %s", image_name);
		free_prg(prg);
		return -1;
	}

	/* attach disk image */
	if (file_system_attach_disk(drive, image_name) < 0) {
		//log_error(log, "Could not attach disk image: %s", image_name);
		free_prg(prg);
		return -1;
	}

	/* copy file to disk */
	vdrive = file_system_get_vdrive((unsigned int)drive);
	if (vdrive == NULL) {
		free_prg(prg);
		return -1;
	}

	/* get file name size */
	file_name_size = strlen((const char *)fh->name);
	if (file_name_size > 16) {
		file_name_size = 16;
	}

	/* open file on disk */
	if (vdrive_iec_open(vdrive, (const BYTE *)fh->name,
				file_name_size, secondary, NULL) != SERIAL_OK) {
		//log_error(log, "Could not open file");
		free_prg(prg);
		return -1;
	}

	/* write start address to file */
	lo = (BYTE)(prg->start_addr & 0xff);
	hi = (BYTE)((prg->start_addr >> 8) & 0xff);
	if ((vdrive_iec_write(vdrive, lo, secondary) != SERIAL_OK) ||
			(vdrive_iec_write(vdrive, hi, secondary) != SERIAL_OK)) {
		//log_error(log, "Could not write file");
		free_prg(prg);
		return -1;
	}

	/* write PRG data to file */
	for (i = 0; i < prg->size; i++) {
		if (vdrive_iec_write(vdrive, prg->data[i], secondary) != SERIAL_OK) {
			//log_error(log, "Could not write file");
			free_prg(prg);
			return -1;
		}
	}

	/* close file */
	if (vdrive_iec_close(vdrive, secondary) != SERIAL_OK) {
		//log_error(log, "Could not close file");
		free_prg(prg);
		return -1;
	}

	/* free prg file */
	free_prg(prg);

	/* re-enable TDE */
	if (old_tde_state != 0)
		resources_set_int("DriveTrueEmulation", old_tde_state);

	/* ready */
	return 0;
}