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; }
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; }