예제 #1
0
static int vdrive_internal_format_disk_image(const char *filename,
                                             const char *disk_name)
{
    vdrive_t *vdrive;
    const char *format_name;
    int status = 0;

    format_name = (disk_name == NULL) ? " " : disk_name;

    /* FIXME: Pass unit here.  */
    machine_drive_flush();
    vdrive = vdrive_internal_open_fsimage(filename, 0);

    if (vdrive == NULL)
        return -1;

    if (vdrive_command_format(vdrive, format_name) != CBMDOS_IPE_OK)
        status = -1;

    if (vdrive_internal_close_disk_image(vdrive) < 0)
        return -1;

    return status;
}
예제 #2
0
int vdrive_command_execute(vdrive_t *vdrive, const BYTE *buf,
                           unsigned int length)
{
    int status = CBMDOS_IPE_INVAL;
    BYTE *p, *minus;
    char *name;

    if (!length)
        return CBMDOS_IPE_OK;
    if (length > IP_MAX_COMMAND_LEN) {
        vdrive_command_set_error(vdrive, CBMDOS_IPE_LONG_LINE, 0, 0);
        return CBMDOS_IPE_LONG_LINE;
    }

    if (buf[length - 1] == 0x0d) {
        --length; /* chop CR character */
    }

    p = lib_malloc(length + 1);
    memcpy(p, buf, length);
    p[length] = 0;

    minus = (BYTE *)memchr(p, '-', length);
    name = (char *)memchr(p, ':', length);

#ifdef DEBUG_DRIVE
    log_debug("Command '%c' (%s).", *p, p);
#endif

    switch (*p) {
      case 'M':
      case 'P':
        break;          /* In binary commands, colons are data */
      default:
        if (name) {     /* Fix name length */
            length -= (BYTE *)name - p;
        }
    }

    switch (*p) {
      case 'C':         /* Copy */
        if (p[1] == 'D' && vdrive->image_format == VDRIVE_IMAGE_FORMAT_4000) {
            if (!name) { /* CD_ doesn't allow a : */
                name = (char *)(p + 1);
            }
            status = vdrive_command_chdir(vdrive, (BYTE *)name, length);
        } else {
            status = vdrive_command_copy(vdrive, (char *)name, length);
        }
        break;

      case '/':         /* change partition */
        if ((vdrive->image_format == VDRIVE_IMAGE_FORMAT_1581) ||
            (vdrive->image_format == VDRIVE_IMAGE_FORMAT_4000)) {
            if (!name) { /* handle "/dir" */
                name = (char *)(p + 1);
                --length;
            }
            status = vdrive_command_chpart(vdrive, (BYTE *)name, length);
        }
        break;

#if 0
      case 'D':         /* Duplicate is unused */
        break;
#endif

      case 'R':         /* Rename */
        status = vdrive_command_rename(vdrive, (BYTE *)name, length);
        break;

      case 'S':         /* Scratch */
        status = vdrive_command_scratch(vdrive, (BYTE *)name, length);
        break;

      case 'I':
        status = vdrive_command_initialize(vdrive);
        break;

      case 'N':
        /* Skip ":" at the start of the name.  */
        status = vdrive_command_format(vdrive,
                                       (name == NULL) ? NULL : name + 1);
        break;

      case 'V':
        status = vdrive_command_validate(vdrive);
        break;

      case 'B': /* Block, Buffer */
        if (!name)      /* B-x does not require a : */
            name = (char *)(p + 2);
        if (minus) {
            status = vdrive_command_block(vdrive, minus[1], name + 1);
        }
        break;

      case 'M': /* Memory */
        if (minus) {
            status = vdrive_command_memory(vdrive, minus + 1, length);
        }
        break;

      case 'P': /* Position */
        status = vdrive_command_position(vdrive, p, length);
        break;

      case 'U': /* User */
        if (!name) {    /* Colons are optional */
            name = (char *)(p + 1);
        }
        switch (p[1] & 0x0f) {
          case 1: /* UA */
            if (name)
                status = vdrive_command_block(vdrive, (unsigned char)0xd2, name + 1);
            break;

          case 2: /* UB */
            if (name)
                status = vdrive_command_block(vdrive, (unsigned char)0xd7, name + 1);
            break;

          case 3: /* Jumps */
          case 4:
          case 5:
          case 6:
          case 7:
          case 8:
            status = CBMDOS_IPE_NOT_READY;
            break;

          case 9: /* UI */
            if (p[2] == '-' || p[2] == '+') {
                status = CBMDOS_IPE_OK; /* Set IEC bus speed */
                break;
            }
            /* Fall through. */
          case 10: /* U:, UJ */
            vdrive_close_all_channels(vdrive); /* Warm/Cold reset */
            status = CBMDOS_IPE_DOS_VERSION;
            break;

          default: /* U0, UK..UO */
            if (p[1] == '0') {
                status = CBMDOS_IPE_OK;
                break;
            }
            status = CBMDOS_IPE_NOT_READY;
            break;
        } /* Un */
        break;

      default:
        break;
    } /* commands */

    if (status == CBMDOS_IPE_INVAL) {
        log_error(vdrive_command_log, "Wrong command `%s'.", p);
    }

    vdrive_command_set_error(vdrive, status, 0, 0);

    lib_free((char *)p);
    return status;
}