71
71
static log_t vdrive_command_log = LOG_ERR;
73
static int vdrive_command_block(vdrive_t *vdrive, char command, char *buffer);
73
static int vdrive_command_block(vdrive_t *vdrive, unsigned char command, char *buffer);
74
74
static int vdrive_command_memory(vdrive_t *vdrive, BYTE *buffer,
75
75
unsigned int length);
76
76
static int vdrive_command_initialize(vdrive_t *vdrive);
77
77
static int vdrive_command_copy(vdrive_t *vdrive, char *dest, int length);
78
static int vdrive_command_rename(vdrive_t *vdrive, char *dest, int length);
79
static int vdrive_command_scratch(vdrive_t *vdrive, char *name, int length);
78
static int vdrive_command_rename(vdrive_t *vdrive, BYTE *dest, int length);
79
static int vdrive_command_scratch(vdrive_t *vdrive, BYTE *name, int length);
80
80
static int vdrive_command_position(vdrive_t *vdrive, BYTE *buf,
81
81
unsigned int length);
145
145
case 'R': /* Rename */
146
status = vdrive_command_rename(vdrive, (char *)name, length);
146
status = vdrive_command_rename(vdrive, (BYTE *)name, length);
149
149
case 'S': /* Scratch */
150
status = vdrive_command_scratch(vdrive, (char *)name, length);
150
status = vdrive_command_scratch(vdrive, (BYTE *)name, length);
193
194
switch ((p[1] - 1) & 0x0f) {
195
/* XXX incorrect: U1 is not exactly the same as B-R */
196
/* -- should store the buffer pointer */
198
status = vdrive_command_block(vdrive, 'R', name + 1);
197
status = vdrive_command_block(vdrive, (unsigned char)0xd2, name + 1);
202
/* XXX incorrect: U2 is not exactly the same as B-W */
203
/* -- should store the buffer pointer */
205
status = vdrive_command_block(vdrive, 'W', name + 1);
202
status = vdrive_command_block(vdrive, (unsigned char)0xd7, name + 1);
208
205
case 2: /* Jumps */
270
267
for (ip = 0; ip < 4; ip++) {
271
while (*bp == ' ' || *bp == ')' || *bp == ',' || *bp == '#')
268
/* 1541 firmware skips 0x20, 0x2c, and 0x1d */
269
while (*bp == ' ' || *bp == ')' || *bp == ',' || *bp == '#' || *bp == 0x1d)
281
279
return -ip; /* negative of # arguments found */
284
static int vdrive_command_block(vdrive_t *vdrive, char command, char *buffer)
282
static int vdrive_command_block(vdrive_t *vdrive, unsigned char command, char *buffer)
286
284
int channel = 0, drive = 0, track = 0, sector = 0, position = 0;
293
291
switch (command) {
292
/* 1581 has u-R (shifted) and u-W (shifted) for block read/write
293
without track/sector checking. */
294
/* Use this for U1,UA and U2,UB also */
297
l = vdrive_get_block_parameters(buffer, &channel, &drive, &track,
302
log_debug("B-R/W parsed ok. (l=%d) channel %d mode %d, "
303
"drive=%d, track=%d sector=%d.", l, channel,
304
vdrive->buffers[channel].mode, drive, track, sector);
307
if (vdrive->buffers[channel].mode != BUFFER_MEMORY_BUFFER)
308
return CBMDOS_IPE_NO_CHANNEL;
310
if (command == 0xd7) {
312
if (vdrive->image->read_only)
313
return CBMDOS_IPE_WRITE_PROTECT_ON;
314
if (disk_image_write_sector(vdrive->image,
315
vdrive->buffers[channel].buffer,
317
return CBMDOS_IPE_NOT_READY;
320
rc = disk_image_read_sector(vdrive->image,
321
vdrive->buffers[channel].buffer,
326
return CBMDOS_IPE_NOT_READY;
328
vdrive->buffers[channel].bufptr = 0;
330
log_error(vdrive_command_log, "B-R/W invalid parameter "
331
"C:%i D:%i T:%i S:%i.", channel, drive, track, sector);
334
/* Old style B-R and B-W */
296
337
l = vdrive_get_block_parameters(buffer, &channel, &drive, &track,
307
348
return CBMDOS_IPE_NO_CHANNEL;
309
350
if (command == 'W') {
310
352
if (vdrive->image->read_only)
311
353
return CBMDOS_IPE_WRITE_PROTECT_ON;
354
/* Update length of block based on the buffer pointer. */
355
l = vdrive->buffers[channel].bufptr - 1;
356
vdrive->buffers[channel].buffer[0] = ( l < 1 ? 1 : l );
312
357
if (disk_image_write_sector(vdrive->image,
313
358
vdrive->buffers[channel].buffer,
314
359
track, sector) < 0)
315
360
return CBMDOS_IPE_NOT_READY;
361
/* after write, buffer pointer is 1. */
362
vdrive->buffers[channel].bufptr = 1;
317
365
rc = disk_image_read_sector(vdrive->image,
318
366
vdrive->buffers[channel].buffer,
368
/* set buffer length base on first value */
369
vdrive->buffers[channel].length =
370
vdrive->buffers[channel].buffer[0] + 1;
371
/* buffer pointer is 1, not 0. */
372
vdrive->buffers[channel].bufptr = 1;
323
376
return CBMDOS_IPE_NOT_READY;
325
vdrive->buffers[channel].bufptr = 0;
327
379
log_error(vdrive_command_log, "B-R/W invalid parameter "
328
380
"C:%i D:%i T:%i S:%i.", channel, drive, track, sector);
417
468
static int vdrive_command_copy(vdrive_t *vdrive, char *dest, int length)
419
470
char *name, *files, *p, c;
421
473
/* Split command line */
422
474
if (!dest || !(files = (char *)memchr(dest, '=', length)) )
427
479
if (strchr (dest, ':'))
428
dest = strchr (dest, ':') +1;
480
dest = strchr(dest, ':') + 1;
430
482
#ifdef DEBUG_DRIVE
431
483
log_debug("COPY: dest= '%s', orig= '%s'.", dest, files);
434
if (vdrive_iec_open(vdrive, dest, strlen(dest), 1))
486
if (vdrive_iec_open(vdrive, (BYTE *)dest, strlen(dest), 1))
435
487
return CBMDOS_IPE_FILE_EXISTS;
437
489
p = name = files;
446
498
#ifdef DEBUG_DRIVE
447
499
log_debug("searching for file '%s'.", name);
449
if (vdrive_iec_open(vdrive, name, strlen(name), 0)) {
501
if (vdrive_iec_open(vdrive, (BYTE *)name, strlen(name), 0)) {
450
502
vdrive_iec_close(vdrive, 1);
451
503
return CBMDOS_IPE_NOT_FOUND;
454
while (!vdrive_iec_read(vdrive, (BYTE *)&c, 0)) {
507
status = vdrive_iec_read(vdrive, (BYTE *)&c, 0);
455
508
if (vdrive_iec_write(vdrive, c, 1)) {
456
509
vdrive_iec_close(vdrive, 0); /* No space on disk. */
457
510
vdrive_iec_close(vdrive, 1);
458
511
return CBMDOS_IPE_DISK_FULL;
513
} while (status == SERIAL_OK);
462
515
vdrive_iec_close(vdrive, 0);
463
516
name = p; /* Next file. */
466
519
return CBMDOS_IPE_OK;
469
static int vdrive_command_rename(vdrive_t *vdrive, char *dest, int length)
522
static int vdrive_command_rename(vdrive_t *vdrive, BYTE *dest, int length)
473
526
int status = CBMDOS_IPE_OK, rc;
474
527
cbmdos_cmd_parse_t cmd_parse_dst, cmd_parse_src;
476
if (!dest || !(src = (char*)memchr(dest, '=', length)) )
529
if (!dest || !(src = memchr((char *)dest, '=', length)) )
477
530
return CBMDOS_IPE_SYNTAX;
481
if (strchr (dest, ':'))
482
dest = strchr (dest, ':') + 1;
534
if (strchr((char *)dest, ':'))
535
dest = (BYTE *)strchr((char *)dest, ':') + 1;
484
537
#ifdef DEBUG_DRIVE
485
538
log_debug("RENAME: dest= '%s', orig= '%s'.", dest, src);
488
541
cmd_parse_dst.cmd = dest;
489
cmd_parse_dst.cmdlength = strlen(dest);
542
cmd_parse_dst.cmdlength = strlen((char *)dest);
490
543
cmd_parse_dst.readmode = CBMDOS_FAM_READ;
492
545
rc = cbmdos_command_parse(&cmd_parse_dst);
638
691
unsigned int t, s;
640
/* FIXME: size of BAM define */
641
BYTE *b, oldbam[5 * 256];
693
BYTE *b, oldbam[BAM_MAXSIZE];
643
695
status = vdrive_command_initialize(vdrive);
647
699
if (vdrive->image->read_only)
648
700
return CBMDOS_IPE_WRITE_PROTECT_ON;
650
/* FIXME: size of BAM define */
651
memcpy(oldbam, vdrive->bam, 5 * 256);
702
memcpy(oldbam, vdrive->bam, BAM_MAXSIZE);
653
704
vdrive_bam_clear_all(vdrive->image_format, vdrive->bam);
662
713
/* First map out the BAM and directory itself. */
663
714
status = vdrive_bam_allocate_chain(vdrive, vdrive->Bam_Track,
664
715
vdrive->Bam_Sector);
665
717
if (status != CBMDOS_IPE_OK) {
666
/* FIXME: size of BAM define */
667
memcpy(vdrive->bam, oldbam, 5 * 256);
718
memcpy(vdrive->bam, oldbam, BAM_MAXSIZE);
788
839
unsigned int channel, rec_lo, rec_hi, position;
791
return CBMDOS_IPE_NO_RECORD;
841
/* default the position to 1 */
844
/* default the high record to 0 */
847
/* default the low record to 1 */
850
/* if no channel is specified, return NO CHANNEL */
852
return CBMDOS_IPE_NO_CHANNEL;
854
/* remove bit 5 & 6 from the channel */
855
channel = buf[0] & 15;
796
858
position = buf[3];
798
860
if (vdrive->buffers[channel].mode != BUFFER_RELATIVE)
799
861
return CBMDOS_IPE_NO_CHANNEL;
801
vdrive_rel_position(vdrive, channel, rec_lo, rec_hi, position);
803
vdrive->buffers[channel].bufptr = 0;
805
return CBMDOS_IPE_OK;
863
return vdrive_rel_position(vdrive, channel, rec_lo, rec_hi, position);