Logo Search packages:      
Sourcecode: cbmlink version File versions  Download package

qdisk.c

Go to the documentation of this file.
/**
 * @file qdisk.c
 * Extension for quick 1541 disk operations on the remote host
 * @author Marko Mäkelä (msmakela@nic.funet.fi)
 */

/*
 * Copyright © 2002 Marko Mäkelä
 *
 *     This program is free software; you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation; either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with this program; if not, write to the Free Software
 *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "comm.h"
#include "info.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "qdisk.h"
#include "rdfile.h"
#include "ext.h"
#include "qdisk-o.h"

/** fast formatting routine for the 1541 */
00036 static const unsigned char format1541[] = {
  0xa5, 0x51, 0x10, 0x2b, 0xa9, 0x60, 0x85, 0x20, 0xad, 0x00, 0x1c, 0x29,
  0x03, 0x85, 0x4a, 0xa5, 0x22, 0xd0, 0x02, 0xa9, 0x2c, 0x29, 0x7e, 0x49,
  0xfe, 0x0a, 0x05, 0x4a, 0x38, 0xe9, 0x04, 0x85, 0x4a, 0xa9, 0x01, 0x85,
  0x22, 0x85, 0x51, 0xa9, 0x0a, 0x8d, 0x38, 0x06, 0x4c, 0x9c, 0xf9, 0xa0,
  0x00, 0xd1, 0x32, 0xf0, 0x05, 0x91, 0x32, 0x4c, 0x9c, 0xf9, 0xa9, 0x10,
  0x2c, 0x00, 0x1c, 0xd0, 0x04, 0x4a, 0x4c, 0xdb, 0xfd, 0xad, 0x0c, 0x1c,
  0x29, 0x1f, 0x09, 0xc0, 0x8d, 0x0c, 0x1c, 0xa9, 0xff, 0x8d, 0x03, 0x1c,
  0xa9, 0x55, 0x8d, 0x01, 0x1c, 0xa0, 0x00, 0xa2, 0x00, 0xa5, 0x39, 0x99,
  0x00, 0x03, 0xc8, 0xc8, 0x8a, 0x99, 0x00, 0x03, 0xc8, 0xa5, 0x51, 0x99,
  0x00, 0x03, 0xc8, 0xa5, 0x13, 0x99, 0x00, 0x03, 0xc8, 0xa5, 0x12, 0x99,
  0x00, 0x03, 0xc8, 0xa9, 0x0f, 0x99, 0x00, 0x03, 0xc8, 0x99, 0x00, 0x03,
  0xc8, 0xb9, 0xfa, 0x02, 0x59, 0xfb, 0x02, 0x59, 0xfc, 0x02, 0x59, 0xfd,
  0x02, 0x99, 0xf9, 0x02, 0xe8, 0xe4, 0x43, 0xd0, 0xc4, 0x8e, 0x37, 0x06,
  0x98, 0x48, 0xa9, 0x03, 0x85, 0x31, 0x20, 0x30, 0xfe, 0x68, 0xa8, 0x88,
  0x20, 0xe5, 0xfd, 0x20, 0xf5, 0xfd, 0xa9, 0x00, 0x85, 0x32, 0x20, 0xe1,
  0x04, 0xce, 0x37, 0x06, 0xd0, 0xf8, 0x50, 0xfe, 0xb8, 0x20, 0x00, 0xfe,
  0xa9, 0x00, 0x85, 0x32, 0xa9, 0xc8, 0x8d, 0x39, 0x06, 0xa5, 0x43, 0x8d,
  0x37, 0x06, 0x20, 0x4a, 0x05, 0xe6, 0x51, 0xa5, 0x51, 0xc9, 0x24, 0x90,
  0x05, 0xa9, 0x01, 0x4c, 0xdb, 0xfd, 0x4c, 0x9c, 0xf9, 0x20, 0x30, 0x05,
  0xa4, 0x32, 0xa2, 0x0a, 0x50, 0xfe, 0xb8, 0xb9, 0x00, 0x03, 0x8d, 0x01,
  0x1c, 0xc8, 0xca, 0xd0, 0xf3, 0x84, 0x32, 0xa2, 0x09, 0xa9, 0x55, 0x20,
  0x24, 0x05, 0x20, 0x30, 0x05, 0xa0, 0x04, 0x50, 0xfe, 0xb8, 0xb9, 0x90,
  0x05, 0x8d, 0x01, 0x1c, 0x88, 0x10, 0xf4, 0xa2, 0x40, 0xa0, 0x04, 0x50,
  0xfe, 0xb8, 0xb9, 0x95, 0x05, 0x8d, 0x01, 0x1c, 0x88, 0x10, 0xf4, 0xca,
  0xd0, 0xef, 0xa2, 0x08, 0xa9, 0x55, 0x50, 0xfe, 0xb8, 0x8d, 0x01, 0x1c,
  0xca, 0xd0, 0xf7, 0x60, 0xa2, 0x05, 0xa9, 0xff, 0xd0, 0xf0, 0xce, 0x39,
  0x06, 0xd0, 0x0f, 0x68, 0x68, 0xa9, 0x06, 0xce, 0x38, 0x06, 0xd0, 0x03,
  0x4c, 0x9c, 0xf9, 0x4c, 0xdb, 0xfd, 0x20, 0x56, 0xf5, 0xa2, 0x0a, 0xa4,
  0x32, 0x50, 0xfe, 0xb8, 0xad, 0x01, 0x1c, 0xd9, 0x00, 0x03, 0xd0, 0xda,
  0xc8, 0xca, 0xd0, 0xf1, 0x84, 0x32, 0x20, 0x56, 0xf5, 0xa0, 0x04, 0x50,
  0xfe, 0xb8, 0xad, 0x01, 0x1c, 0xd9, 0x90, 0x05, 0xd0, 0xc4, 0x88, 0x10,
  0xf2, 0xa2, 0x40, 0xa0, 0x04, 0x50, 0xfe, 0xb8, 0xad, 0x01, 0x1c, 0xd9,
  0x95, 0x05, 0xd0, 0xb2, 0x88, 0x10, 0xf2, 0xca, 0xd0, 0xed, 0xce, 0x37,
  0x06, 0xd0, 0xbb, 0x60, 0x4a, 0x29, 0xa5, 0xd4, 0x55, 0x4a, 0x29, 0xa5,
  0x94, 0x52, 0xa0, 0xff, 0xa9, 0x00, 0xa2, 0x00, 0x85, 0x12, 0x86, 0x13,
  0x84, 0x51, 0xc8, 0x84, 0x7f, 0x20, 0x00, 0xc1, 0x20, 0x07, 0xd3, 0xa2,
  0x01, 0x86, 0x08, 0xca, 0x86, 0x09, 0xa9, 0xe0, 0x85, 0x01, 0xa5, 0x01,
  0x30, 0xfc, 0xc9, 0x02, 0x90, 0x07, 0xa9, 0x03, 0xa2, 0x00, 0x4c, 0x0a,
  0xe6, 0x20, 0x05, 0xf0, 0x20, 0xb7, 0xee, 0xa0, 0x90, 0xb9, 0x97, 0x05,
  0x91, 0x6d, 0xc8, 0xc0, 0xa0, 0x90, 0xf6, 0x98, 0x91, 0x6d, 0xc8, 0xc0,
  0xab, 0xd0, 0xf9, 0xa9, 0x41, 0x8d, 0x01, 0x01, 0xa0, 0x02, 0x91, 0x6d,
  0xa0, 0xa6, 0x91, 0x6d, 0x88, 0xa9, 0x32, 0x91, 0x6d, 0xa5, 0x12, 0xa0,
  0xa2, 0x91, 0x6d, 0xa5, 0x13, 0xc8, 0x91, 0x6d, 0xa9, 0x12, 0x85, 0x80,
  0xa9, 0x01, 0x85, 0x81, 0x20, 0x93, 0xef, 0xc6, 0x81, 0x20, 0x93, 0xef,
  0x20, 0xff, 0xee, 0x20, 0x05, 0xf0, 0xa0, 0x01, 0xa9, 0xff, 0x91, 0x6d,
  0xe6, 0x81, 0x20, 0x64, 0xd4, 0x20, 0x42, 0xd0, 0x4c, 0x94, 0xc1
};

/** fast track transfer routine for the 1541 */
00086 static const unsigned char track1541[] = {
  0x78, 0x20, 0x7b, 0x03, 0xa9, 0x00, 0x85, 0x00, 0x58, 0x20, 0x42, 0xd0,
  0x78, 0xa9, 0x00, 0x20, 0x37, 0x03, 0x20, 0x89, 0x03, 0x84, 0x0b, 0x20,
  0xb9, 0x03, 0x85, 0x71, 0xc9, 0x02, 0x90, 0x02, 0x58, 0x60, 0x20, 0xb9,
  0x03, 0x85, 0x0a, 0x85, 0x18, 0x20, 0x7b, 0x03, 0xa9, 0xe0, 0x58, 0x85,
  0x02, 0xa5, 0x02, 0x30, 0xfc, 0x10, 0xd5, 0x85, 0x72, 0x49, 0xff, 0x85,
  0x6f, 0xa9, 0x00, 0x8d, 0x00, 0x18, 0xea, 0x66, 0x6f, 0x2a, 0x0a, 0x66,
  0x6f, 0x2a, 0x0a, 0x8d, 0x00, 0x18, 0xa9, 0x00, 0x66, 0x6f, 0x2a, 0x0a,
  0x66, 0x6f, 0x2a, 0x0a, 0x8d, 0x00, 0x18, 0xa9, 0x00, 0x66, 0x6f, 0x2a,
  0x0a, 0x66, 0x6f, 0x2a, 0x0a, 0x8d, 0x00, 0x18, 0xa9, 0x00, 0x66, 0x6f,
  0x2a, 0x0a, 0x66, 0x6f, 0x2a, 0x0a, 0x8d, 0x00, 0x18, 0x20, 0x88, 0x03,
  0xea, 0xea, 0xea, 0xa9, 0x02, 0x8d, 0x00, 0x18, 0x20, 0x88, 0x03, 0x20,
  0x88, 0x03, 0xa5, 0x72, 0x60, 0xa0, 0x00, 0x8c, 0x00, 0x18, 0x20, 0x88,
  0x03, 0x60, 0xa5, 0x13, 0x85, 0x17, 0xa5, 0x12, 0x85, 0x16, 0x45, 0x17,
  0x45, 0x18, 0x45, 0x19, 0x85, 0x1a, 0x20, 0x34, 0xf9, 0x20, 0x56, 0xf5,
  0xa0, 0xf8, 0x50, 0xfe, 0xb8, 0xad, 0x01, 0x1c, 0xd9, 0x2c, 0x00, 0xd0,
  0xf0, 0xc8, 0xd0, 0xf2, 0x60, 0xa9, 0x05, 0x2c, 0x00, 0x18, 0xd0, 0xfb,
  0xa9, 0x00, 0x85, 0x6f, 0x20, 0x88, 0x03, 0xea, 0xa2, 0x04, 0xad, 0x00,
  0x18, 0x6a, 0x26, 0x6f, 0x6a, 0x6a, 0x26, 0x6f, 0xca, 0xd0, 0xf3, 0xa5,
  0x6f, 0x60, 0x20, 0x54, 0x04, 0xa2, 0xf9, 0x50, 0xfe, 0xb8, 0xad, 0x01,
  0x1c, 0x95, 0x2c, 0xe8, 0xd0, 0xf5, 0x20, 0x97, 0xf4, 0xa5, 0x16, 0x45,
  0x17, 0x45, 0x18, 0x45, 0x19, 0x45, 0x1a, 0xd0, 0xe1, 0xa6, 0x70, 0xca,
  0xe4, 0x19, 0x90, 0xda, 0xa6, 0x19, 0xe8, 0xe4, 0x70, 0xd0, 0x02, 0xa2,
  0x00, 0x86, 0x19, 0xbd, 0x13, 0x05, 0xd0, 0xca, 0xfe, 0x13, 0x05, 0x8a,
  0x20, 0x37, 0x03, 0x20, 0x54, 0x04, 0x20, 0x56, 0xf5, 0x50, 0xfe, 0xb8,
  0xad, 0x01, 0x1c, 0x99, 0x00, 0x06, 0xc8, 0xd0, 0xf4, 0xa0, 0xba, 0x50,
  0xfe, 0xb8, 0xad, 0x01, 0x1c, 0x99, 0x00, 0x01, 0xc8, 0xd0, 0xf4, 0x20,
  0xe0, 0xf8, 0xa0, 0x00, 0xb9, 0x00, 0x06, 0x20, 0x37, 0x03, 0x48, 0x68,
  0xc8, 0xd0, 0xf5, 0xc6, 0x71, 0xd0, 0x8f, 0xad, 0x00, 0x1c, 0x49, 0x08,
  0x8d, 0x00, 0x1c, 0x60, 0x20, 0x56, 0xf5, 0x50, 0xfe, 0xb8, 0xad, 0x01,
  0x1c, 0xc9, 0x52, 0xd0, 0xf3, 0x60, 0x20, 0x37, 0x03, 0x20, 0x89, 0x03,
  0x20, 0xb9, 0x03, 0x85, 0x19, 0x49, 0xff, 0xf0, 0x70, 0x20, 0xb9, 0x03,
  0x99, 0x00, 0x06, 0xc8, 0xd0, 0xf7, 0x20, 0x7b, 0x03, 0x20, 0xe9, 0xf5,
  0x85, 0x3a, 0xad, 0x00, 0x1c, 0x29, 0x10, 0xf0, 0x55, 0x20, 0x8f, 0xf7,
  0x20, 0x92, 0x03, 0xa2, 0x09, 0x50, 0xfe, 0xb8, 0xca, 0xd0, 0xfa, 0xca,
  0x8e, 0x03, 0x1c, 0xad, 0x0c, 0x1c, 0x29, 0x1f, 0x09, 0xc0, 0x8d, 0x0c,
  0x1c, 0xa9, 0xff, 0xa2, 0x05, 0x8d, 0x01, 0x1c, 0xb8, 0x50, 0xfe, 0xb8,
  0xca, 0xd0, 0xfa, 0xa0, 0xbb, 0xb9, 0x00, 0x01, 0x50, 0xfe, 0xb8, 0x8d,
  0x01, 0x1c, 0xc8, 0xd0, 0xf4, 0xb9, 0x00, 0x06, 0x50, 0xfe, 0xb8, 0x8d,
  0x01, 0x1c, 0xc8, 0xd0, 0xf4, 0x50, 0xfe, 0xad, 0x0c, 0x1c, 0x09, 0xe0,
  0x8d, 0x0c, 0x1c, 0x8c, 0x03, 0x1c, 0xa5, 0x19, 0x10, 0x84, 0xa9, 0x08,
  0x2c, 0xa9, 0x01, 0x4c, 0x69, 0xf9, 0x85, 0x70, 0x85, 0x71, 0x20, 0x37,
  0x03, 0xaa, 0xa9, 0x00, 0x9d, 0x13, 0x05, 0xca, 0x10, 0xfa, 0x20, 0xda,
  0x03, 0xa9, 0x01, 0x4c, 0x69, 0xf9, 0xff, 0xff, 0x20, 0x4b, 0x04, 0xa9,
  0x06, 0x85, 0x31, 0xa5, 0x0a, 0x20, 0x4b, 0xf2, 0xa4, 0x71, 0xf0, 0xd6,
  0x4c, 0x62, 0x04
};

/** entry point to the formatting routine */
00135 static const unsigned char format_entry[] = {
  0xa0, 0xff, 0xa9, 0x00, 0xa2, 0x00
};

/** work area */
00140 static char workbuf[257];

/** write a block of data to disk memory
 * @param comm          the communication primitives
 * @param buf           the data
 * @param len           length of the data in bytes
 * @param addr          the start address in drive memory
 */
static int
00149 m_w (const struct comm* comm,
     const void* buf,
     unsigned len,
     unsigned addr)
{
  /** buffer pointer */
  register const char* b = buf;
  /** pointer to end of buffer */
  register const char* bend = b + len;

  for (; b < bend; b += 32, addr += 32) {
    int status;
    unsigned l = bend - b > 32 ? 32 : bend - b;
    workbuf[0] = l + 6;
    memcpy (workbuf + 1, "M-W", 3);
    workbuf[4] = addr, workbuf[5] = addr >> 8, workbuf[6] = l;
    memcpy (workbuf + 7, b, l);
    if ((status = rdfile_raw (comm, 0, workbuf)))
      return status;
    if (workbuf[0] != '0' || workbuf[1] != '0') {
      fputs ("qdisk: M-W failed\n", stderr);
      return -1;
    }
  }

  return 0;
}

/** fast format a 1541 disk
 * @param comm          the communication primitives
 * @param file          output file for disk status message
 * @param name          disk name (16 characters, not NUL terminated)
 * @param id1           first ID byte
 * @param id2           second ID byte
 * @return        zero on success, nonzero on error
 */
int
00186 qdisk_format (const struct comm* comm,
            FILE* file,
            const char* name,
            char id1,
            char id2)
{
  /** start address of the drive code */
  unsigned start;
  int status;
  char* buf = malloc ((sizeof format1541) + 16);
  /* copy the code */
  memcpy (buf, format1541, sizeof format1541);
  /* copy the disk name */
  memcpy (buf + sizeof format1541, name, 16);
  /* copy the disk ID */
  for (start = 0; start < (sizeof format1541) - 9; start++) {
    if (memcmp (buf + start, format_entry, sizeof format_entry))
      continue;
    buf[start + 3] = id1, buf[start + 5] = id2;
    break;
  }
  start += 0x400;
  status = m_w (comm, buf, (sizeof format1541) + 16, 0x400);
  free (buf);
  if (!status) {
    memcpy (workbuf, "\5M-E", 4);
    workbuf[4] = start, workbuf[5] = start >> 8;
    status = rdfile_raw (comm, file, workbuf);
  }
  return status;
}

/** install the code for copying 1541 tracks
 * @param comm          the communication primitives
 * @param hostinfo      information on the remote host
 * @return        zero on success, nonzero on error
 */
int
00224 qdisk_install (const struct comm* comm,
             const struct hostinfo* hostinfo)
{
  int status = m_w (comm, track1541, sizeof track1541, 0x300);
  if (!status && !(status = rdfile_remove (comm))) {
    switch (hostinfo->host) {
    case PET: case PET3: case PET4:
      break;
    case Vic:
      return ext (comm, hostinfo, track_20, sizeof track_20, 0, 0) ? 2 : 0;
    case C64: case C128:
      return ext (comm, hostinfo, track_64, sizeof track_64, 0, 0) ? 2 : 0;
    case C264:
      return ext (comm, hostinfo, track_16, sizeof track_16, 0, 0) ? 2 : 0;
    case P500: case B128: case B256:
      break;
    }
    fprintf (stderr, "qdisk: unsupported server %u\n", hostinfo->host);
    status = 1;
  }
  return status;
}

/** remove the code for copying 1541 tracks
 * @param comm          the communication primitives
 * @return        zero on success, nonzero on error
 */
int
00252 qdisk_remove (const struct comm* comm)
{
  unsigned char ch = 0;
  return (*comm->comm_write) (&ch, 1);
}

/** fast read a disk
 * @param comm          the communication primitives
 * @param file          output file for disk image
 * @param buf           work area
 * @return        zero on success, nonzero on error
 */
int
00265 qdisk_read (const struct comm* comm,
          FILE* file,
          char* buf)
{
#if 0
  char track;
  for (track = 1; track <= 35; track++) {
    unsigned char sectors;
    /* read this track */
    if ((*comm->comm_write) (&track, 1))
      return 3;
    (*comm->comm_sr) ();
    if ((*comm->comm_read) (&sectors, 1))
      return 3;
fprintf (stderr, "qdisk: track %u, sectors 0..%u\n", track, sectors);
    for (sectors++; sectors--; ) {
      if ((*comm->comm_read) (workbuf, 257))
      return 3;
      /* to do: write the data */
    }
  }
#else
  fputs ("-qr not yet implemented\n", stderr);
#endif
  return 0;
}

/** fast write a disk
 * @param comm          the communication primitives
 * @param file          input file for disk image
 * @param interleave    the interleave factor
 * @param buf           work area
 * @return        zero on success, nonzero on error
 */
int
00300 qdisk_write (const struct comm* comm,
           FILE* file,
           unsigned interleave,
           char* buf)
{
  fputs ("-qw not yet implemented\n", stderr);
  return 0;
}

Generated by  Doxygen 1.6.0   Back to index