~ubuntu-branches/ubuntu/maverick/vice/maverick

« back to all changes in this revision

Viewing changes to src/vdrive/vdrive-command.c

  • Committer: Bazaar Package Importer
  • Author(s): Zed Pobre
  • Date: 2005-02-01 11:30:26 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050201113026-3eyakzsmmheclvjg
Tags: 1.16-1
* New upstream version
* Fixes crash on 64-bit architectures (closes: #287640)
* x128 working again (closes: #286767)
* Works fine with /dev/dsp in use (not in the main changelog, but tested
  on my local machine as working).  Presumably, this also takes care of
  the issue with dsp being held.  I'm not sure if this is because I'm
  testing it on a 2.6 kernel now -- if you are still having problems
  with /dev/dsp, please reopen the bugs. (closes: #152952, #207942)
* Don't kill Makefile.in on clean

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
 
71
71
static log_t vdrive_command_log = LOG_ERR;
72
72
 
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);
82
82
 
143
143
        break;
144
144
 
145
145
      case 'R':         /* Rename */
146
 
        status = vdrive_command_rename(vdrive, (char *)name, length);
 
146
        status = vdrive_command_rename(vdrive, (BYTE *)name, length);
147
147
        break;
148
148
 
149
149
      case 'S':         /* Scratch */
150
 
        status = vdrive_command_scratch(vdrive, (char *)name, length);
 
150
        status = vdrive_command_scratch(vdrive, (BYTE *)name, length);
151
151
        break;
152
152
 
153
153
      case 'I':
174
174
        break;
175
175
 
176
176
      case 'M': /* Memory */
 
177
        /* FIXME: The ":" could be a low address of a read/write/execute */
177
178
        if (!minus)     /* M-x does not allow a : */
178
179
            status = CBMDOS_IPE_INVAL;
179
180
        else
192
193
        } else {
193
194
            switch ((p[1] - 1) & 0x0f) {
194
195
              case 0: /* UA */
195
 
                /* XXX incorrect: U1 is not exactly the same as B-R */
196
 
                /*      -- should store the buffer pointer */
197
196
                if (name)
198
 
                    status = vdrive_command_block(vdrive, 'R', name + 1);
 
197
                    status = vdrive_command_block(vdrive, (unsigned char)0xd2, name + 1);
199
198
                break;
200
199
 
201
200
              case 1: /* UB */
202
 
                /* XXX incorrect: U2 is not exactly the same as B-W */
203
 
                /*      -- should store the buffer pointer */
204
201
                if (name)
205
 
                    status = vdrive_command_block(vdrive, 'W', name + 1);
 
202
                    status = vdrive_command_block(vdrive, (unsigned char)0xd7, name + 1);
206
203
                break;
207
204
 
208
205
              case 2: /* Jumps */
268
265
    bp = buf;
269
266
 
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)
272
270
            bp++;
273
271
        if (*bp == 0)
274
272
            break;
281
279
    return -ip;                 /* negative of # arguments found */
282
280
}
283
281
 
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)
285
283
{
286
284
    int channel = 0, drive = 0, track = 0, sector = 0, position = 0;
287
285
    int l, rc;
291
289
#endif
292
290
 
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 */
 
295
      case 0xd2:
 
296
      case 0xd7:
 
297
        l = vdrive_get_block_parameters(buffer, &channel, &drive, &track,
 
298
                                        &sector);
 
299
 
 
300
        if (l < 0) {
 
301
#ifdef DEBUG_DRIVE
 
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);
 
305
#endif
 
306
 
 
307
            if (vdrive->buffers[channel].mode != BUFFER_MEMORY_BUFFER)
 
308
                return CBMDOS_IPE_NO_CHANNEL;
 
309
 
 
310
            if (command == 0xd7) {
 
311
                /* For write */
 
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,
 
316
                                            track, sector) < 0)
 
317
                    return CBMDOS_IPE_NOT_READY;
 
318
            } else {
 
319
                /* For read */
 
320
                rc = disk_image_read_sector(vdrive->image,
 
321
                                            vdrive->buffers[channel].buffer,
 
322
                                            track, sector);
 
323
                if (rc > 0)
 
324
                    return rc;
 
325
                if (rc < 0)
 
326
                    return CBMDOS_IPE_NOT_READY;
 
327
            }
 
328
            vdrive->buffers[channel].bufptr = 0;
 
329
        } else {
 
330
            log_error(vdrive_command_log, "B-R/W invalid parameter "
 
331
                      "C:%i D:%i T:%i S:%i.", channel, drive, track, sector);
 
332
        }
 
333
        break;
 
334
      /* Old style B-R and B-W */
294
335
      case 'R':
295
336
      case 'W':
296
337
        l = vdrive_get_block_parameters(buffer, &channel, &drive, &track,
307
348
                return CBMDOS_IPE_NO_CHANNEL;
308
349
 
309
350
            if (command == 'W') {
 
351
                /* For write */
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;
316
363
            } else {
 
364
                /* For read */
317
365
                rc = disk_image_read_sector(vdrive->image,
318
366
                                            vdrive->buffers[channel].buffer,
319
367
                                            track, sector);
 
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;
320
373
                if (rc > 0)
321
374
                    return rc;
322
375
                if (rc < 0)
323
376
                    return CBMDOS_IPE_NOT_READY;
324
377
            }
325
 
            vdrive->buffers[channel].bufptr = 0;
326
378
        } else {
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);
377
429
    return CBMDOS_IPE_OK;
378
430
}
379
431
 
380
 
 
381
432
static int vdrive_command_memory(vdrive_t *vdrive, BYTE *buffer,
382
433
                                 unsigned int length)
383
434
{
417
468
static int vdrive_command_copy(vdrive_t *vdrive, char *dest, int length)
418
469
{
419
470
    char *name, *files, *p, c;
 
471
    int status = 0;
420
472
 
421
473
    /* Split command line */
422
474
    if (!dest || !(files = (char *)memchr(dest, '=', length)) )
425
477
    *files++ = 0;
426
478
 
427
479
    if (strchr (dest, ':'))
428
 
        dest = strchr (dest, ':') +1;
 
480
        dest = strchr(dest, ':') + 1;
429
481
 
430
482
#ifdef DEBUG_DRIVE
431
483
    log_debug("COPY: dest= '%s', orig= '%s'.", dest, files);
432
484
#endif
433
485
 
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;
436
488
 
437
489
    p = name = files;
446
498
#ifdef DEBUG_DRIVE
447
499
        log_debug("searching for file '%s'.", name);
448
500
#endif
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;
452
504
        }
453
505
 
454
 
        while (!vdrive_iec_read(vdrive, (BYTE *)&c, 0)) {
 
506
        do {
 
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;
459
512
            }
460
 
        }
 
513
        } while (status == SERIAL_OK);
461
514
 
462
515
        vdrive_iec_close(vdrive, 0);
463
516
        name = p; /* Next file.  */
466
519
    return CBMDOS_IPE_OK;
467
520
}
468
521
 
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)
470
523
{
471
 
    char *src;
 
524
    BYTE *src;
472
525
    BYTE *slot;
473
526
    int status = CBMDOS_IPE_OK, rc;
474
527
    cbmdos_cmd_parse_t cmd_parse_dst, cmd_parse_src;
475
528
 
476
 
    if (!dest || !(src = (char*)memchr(dest, '=', length)) )
 
529
    if (!dest || !(src = memchr((char *)dest, '=', length)) )
477
530
        return CBMDOS_IPE_SYNTAX;
478
531
 
479
532
    *src++ = 0;
480
533
 
481
 
    if (strchr (dest, ':'))
482
 
        dest = strchr (dest, ':') + 1;
 
534
    if (strchr((char *)dest, ':'))
 
535
        dest = (BYTE *)strchr((char *)dest, ':') + 1;
483
536
 
484
537
#ifdef DEBUG_DRIVE
485
538
    log_debug("RENAME: dest= '%s', orig= '%s'.", dest, src);
486
539
#endif
487
540
 
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;
491
544
 
492
545
    rc = cbmdos_command_parse(&cmd_parse_dst);
497
550
    }
498
551
 
499
552
    cmd_parse_src.cmd = src;
500
 
    cmd_parse_src.cmdlength = strlen(src);
 
553
    cmd_parse_src.cmdlength = strlen((char *)src);
501
554
    cmd_parse_src.readmode = CBMDOS_FAM_READ;
502
555
 
503
556
    rc = cbmdos_command_parse(&cmd_parse_src);
563
616
    return status;
564
617
}
565
618
 
566
 
static int vdrive_command_scratch(vdrive_t *vdrive, char *name, int length)
 
619
static int vdrive_command_scratch(vdrive_t *vdrive, BYTE *name, int length)
567
620
{
568
621
    int status, rc;
569
622
    BYTE *slot;
637
690
{
638
691
    unsigned int t, s;
639
692
    int status;
640
 
    /* FIXME: size of BAM define */
641
 
    BYTE *b, oldbam[5 * 256];
 
693
    BYTE *b, oldbam[BAM_MAXSIZE];
642
694
 
643
695
    status = vdrive_command_initialize(vdrive);
644
696
 
647
699
    if (vdrive->image->read_only)
648
700
        return CBMDOS_IPE_WRITE_PROTECT_ON;
649
701
 
650
 
    /* FIXME: size of BAM define */
651
 
    memcpy(oldbam, vdrive->bam, 5 * 256);
 
702
    memcpy(oldbam, vdrive->bam, BAM_MAXSIZE);
652
703
 
653
704
    vdrive_bam_clear_all(vdrive->image_format, vdrive->bam);
654
705
 
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);
 
716
 
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);
668
719
        return status;
669
720
    }
670
721
 
787
838
{
788
839
    unsigned int channel, rec_lo, rec_hi, position;
789
840
 
790
 
    if (length < 5)
791
 
        return CBMDOS_IPE_NO_RECORD;
 
841
    /* default the position to 1 */
 
842
    if (length <= 4)
 
843
        buf[3] = 1;
 
844
    /* default the high record to 0 */
 
845
    if (length <= 3)
 
846
        buf[2] = 0;
 
847
    /* default the low record to 1 */
 
848
    if (length <= 2)
 
849
        buf[1] = 1;
 
850
    /* if no channel is specified, return NO CHANNEL */
 
851
    if (length <= 1)
 
852
        return CBMDOS_IPE_NO_CHANNEL;
792
853
 
793
 
    channel = buf[0];
 
854
    /* remove bit 5 & 6 from the channel */
 
855
    channel = buf[0] & 15;
794
856
    rec_lo = buf[1];
795
857
    rec_hi = buf[2];
796
858
    position = buf[3];
798
860
    if (vdrive->buffers[channel].mode != BUFFER_RELATIVE)
799
861
        return CBMDOS_IPE_NO_CHANNEL;
800
862
 
801
 
    vdrive_rel_position(vdrive, channel, rec_lo, rec_hi, position);
802
 
 
803
 
    vdrive->buffers[channel].bufptr = 0;
804
 
 
805
 
    return CBMDOS_IPE_OK;
 
863
    return vdrive_rel_position(vdrive, channel, rec_lo, rec_hi, position);
806
864
}
807
865
 
808
866