It is currently Thu Sep 19, 2019 3:28 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Language C to PB, Trying adapt D64,D71,D81 DiskImage Source
PostPosted: Mon Sep 09, 2019 5:17 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Hallo -- hello @ all

I trying to adapt .. convert a c Source for D64,D71,D80 DiskImages to Purebasic for my C64 File Lister. Thta use c1541.exe and openCBM.

Update: My progress is further down in this thread.

I have a Problem with the line in the c Source procedure

int di_track_blocks_free(DiskImage *di, int track)
.......
unsigned char *bam; << is this a pointer or just a byte because the return code
.......
return(bam [track * 4] ); what have i to do ?

The Header
Code:
typedef enum imagetype {
  D64 = 1,
  D71,
  D81
} ImageType;

typedef enum filetype {
  T_DEL = 0,
  T_SEQ,
  T_PRG,
  T_USR,
  T_REL,
  T_CBM,
  T_DIR
} FileType;

typedef struct ts {
  unsigned char track;
  unsigned char sector;
} TrackSector;

typedef struct diskimage {
  char *filename;
  int size;
  ImageType type;
  unsigned char *image;
  TrackSector bam;
  TrackSector bam2;
  TrackSector dir;
  int openfiles;
  int blocksfree;
  int modified;
  int status;
  TrackSector statusts;
} DiskImage;

typedef struct rawdirentry {
  TrackSector nextts;
  unsigned char type;
  TrackSector startts;
  unsigned char rawname[16];
  TrackSector relsidets;
  unsigned char relrecsize;
  unsigned char unused[4];
  TrackSector replacetemp;
  unsigned char sizelo;
  unsigned char sizehi;
} RawDirEntry;

typedef struct imagefile {
  DiskImage *diskimage;
  RawDirEntry *rawdirentry;
  char mode;
  int position;
  TrackSector ts;
  TrackSector nextts;
  unsigned char *buffer;
  int bufptr;
  int buflen;
} ImageFile;


DiskImage *di_load_image(char *name);
DiskImage *di_create_image(char *name, int size);
void di_free_image(DiskImage *di);
void di_sync(DiskImage *di);

int di_status(DiskImage *di, char *status);

ImageFile *di_open(DiskImage *di, unsigned char *rawname, FileType type, char *mode);
void di_close(ImageFile *imgfile);
int di_read(ImageFile *imgfile, unsigned char *buffer, int len);
int di_write(ImageFile *imgfile, unsigned char *buffer, int len);

int di_format(DiskImage *di, unsigned char *rawname, unsigned char *rawid);
int di_delete(DiskImage *di, unsigned char *rawpattern, FileType type);
int di_rename(DiskImage *di, unsigned char *oldrawname, unsigned char *newrawname, FileType type);

int di_sectors_per_track(ImageType type, int track);
int di_tracks(ImageType type);
int di_get_block_num(ImageType type, TrackSector ts);

unsigned char *di_title(DiskImage *di);
int di_track_blocks_free(DiskImage *di, int track);
int di_is_ts_free(DiskImage *di, TrackSector ts);
void di_alloc_ts(DiskImage *di, TrackSector ts);
void di_free_ts(DiskImage *di, TrackSector ts);

int di_rawname_from_name(unsigned char *rawname, char *name);
int di_name_from_rawname(char *name, unsigned char *rawname);



The C Source
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "diskimage.h"


typedef struct errormessage {
  signed int number;
  char *string;
} ErrorMessage;


ErrorMessage error_msg[] = {
  /* non-errors */
  { 0, "ok" },
  { 1, "files scratched" },
  { 2, "partition selected" },
  /* errors */
  { 20, "read error (block header not found)" },
  { 21, "read error (drive not ready)" },
  { 22, "read error (data block not found)" },
  { 23, "read error (crc error in data block)" },
  { 24, "read error (byte sector header)" },
  { 25, "write error (write-verify error)" },
  { 26, "write protect on" },
  { 27, "read error (crc error in header)" },
  { 30, "syntax error (general syntax)" },
  { 31, "syntax error (invalid command)" },
  { 32, "syntax error (long line)" },
  { 33, "syntax error (invalid file name)" },
  { 34, "syntax error (no file given)" },
  { 39, "syntax error (invalid command)" },
  { 50, "record not present" },
  { 51, "overflow in record" },
  { 52, "file too large" },
  { 60, "write file open" },
  { 61, "file not open" },
  { 62, "file not found" },
  { 63, "file exists" },
  { 64, "file type mismatch" },
  { 65, "no block" },
  { 66, "illegal track and sector" },
  { 67, "illegal system t or s" },
  { 70, "no channel" },
  { 71, "directory error" },
  { 72, "disk full" },
  { 73, "dos mismatch" },
  { 74, "drive not ready" },
  { 75, "format error" },
  { 76, "controller error" },
  { 77, "selected partition illegal" },
  { -1, NULL }
};


/* convert to rawname */
int di_rawname_from_name(unsigned char *rawname, char *name) {
  int i;

  memset(rawname, 0xa0, 16);
  for (i = 0; i < 16 && name[i]; ++i) {
    rawname[i] = name[i];
  }
  return(i);
}


/* convert from rawname */
int di_name_from_rawname(char *name, unsigned char *rawname) {
  int i;

  for (i = 0; i < 16 && rawname[i] != 0xa0; ++i) {
    name[i] = rawname[i];
  }
  name[i] = 0;
  return(i);
}


/* return status string */
int di_status(DiskImage *di, char *status) {
  ErrorMessage *err = error_msg;

  /* special case for power up */
  if (di->status == 254) {
    switch (di->type) {
    case D64:
      sprintf(status, "73,cbm dos v2.6 1541,00,00");
      break;
    case D71:
      sprintf(status, "73,cbm dos v3.0 1571,00,00");
      break;
    case D81:
      sprintf(status, "73,copyright cbm dos v10 1581,00,00");
      break;
    }
    return(73);
  }

  while (err->number >= 0) {
    if (di->status == err->number) {
      sprintf(status, "%02d,%s,%02d,%02d", di->status, err->string, di->statusts.track, di->statusts.sector);
      return(di->status);
    }
    err++;
  }
  sprintf(status, "%02d,unknown error,%02d,%02d", di->status, di->statusts.track, di->statusts.sector);
  return(di->status);
}


int set_status(DiskImage *di, int status, int track, int sector) {
  di->status = status;
  di->statusts.track = track;
  di->statusts.sector = sector;
  return(status);
}


/* return write interleave */
int interleave(ImageType type) {
  switch (type) {
  case D64:
    return(10);
    break;
  case D71:
    return(6);
    break;
  default:
    return(1);
    break;
  }
}


/* return number of tracks for image type */
int di_tracks(ImageType type) {
  switch (type) {
  case D64:
    return(35);
    break;
  case D71:
    return(70);
    break;
  case D81:
    return(80);
    break;
  }
  return(0);
}


/* return disk geometry for track */
int di_sectors_per_track(ImageType type, int track) {
  switch (type) {
  case D71:
    if (track > 35) {
      track -= 35;
    }
    // fall through
  case D64:
    if (track < 18) {
      return(21);
    } else if (track < 25) {
      return(19);
    } else if (track < 31) {
      return(18);
    } else {
      return(17);
    }
    break;
  case D81:
    return(40);
    break;
  }
  return(0);
}

/* convert track, sector to blocknum */
int di_get_block_num(ImageType type, TrackSector ts) {
  int block;

  switch (type) {
  case D64:
    if (ts.track < 18) {
      block = (ts.track - 1) * 21;
    } else if (ts.track < 25) {
      block = (ts.track - 18) * 19 + 17 * 21;
    } else if (ts.track < 31) {
      block = (ts.track - 25) * 18 + 17 * 21 + 7 * 19;
    } else {
      block = (ts.track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18;
    }
    return(block + ts.sector);
    break;
  case D71:
    if (ts.track > 35) {
      block = 683;
      ts.track -= 35;
    } else {
      block = 0;
    }
    if (ts.track < 18) {
      block += (ts.track - 1) * 21;
    } else if (ts.track < 25) {
      block += (ts.track - 18) * 19 + 17 * 21;
    } else if (ts.track < 31) {
      block += (ts.track - 25) * 18 + 17 * 21 + 7 * 19;
    } else {
      block += (ts.track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18;
    }
    return(block + ts.sector);
    break;
  case D81:
    return((ts.track - 1) * 40 + ts.sector);
    break;
  }
  return(0);
}


/* get a pointer to block data */
unsigned char *get_ts_addr(DiskImage *di, TrackSector ts) {
  return(di->image + di_get_block_num(di->type, ts) * 256);
}


/* return a pointer to the next block in the chain */
TrackSector next_ts_in_chain(DiskImage *di, TrackSector ts) {
  unsigned char *p;
  TrackSector newts;

  p = get_ts_addr(di, ts);
  newts.track = p[0];
  newts.sector = p[1];
  if (p[0] > di_tracks(di->type)) {
    newts.track = 0;
    newts.sector = 0;
  } else if (p[1] > di_sectors_per_track(di->type, p[0])) {
    newts.track = 0;
    newts.sector = 0;
  }
  return(newts);
}


/* return a pointer to the disk title */
unsigned char *di_title(DiskImage *di) {
  switch (di->type) {
  default:
  case D64:
  case D71:
    return(get_ts_addr(di, di->dir) + 144);
    break;
  case D81:
    return(get_ts_addr(di, di->dir) + 4);
    break;
  }
}


/* return number of free blocks in track */
int di_track_blocks_free(DiskImage *di, int track) {
  unsigned char *bam;

  switch (di->type) {
  default:
  case D64:
    bam = get_ts_addr(di, di->bam);
    break;
  case D71:
    bam = get_ts_addr(di, di->bam);
    if (track >= 36) {
      return(bam[track + 185]);
    }
    break;
  case D81:
    if (track <= 40) {
      bam = get_ts_addr(di, di->bam);
    } else {
      bam = get_ts_addr(di, di->bam2);
      track -= 40;
    }
    return(bam[track * 6 + 10]);
    break;
  }
  return(bam[track * 4]);
}


/* count number of free blocks */
int blocks_free(DiskImage *di) {
  int track;
  int blocks = 0;

  for (track = 1; track <= di_tracks(di->type); ++track) {
    if (track != di->dir.track) {
      blocks += di_track_blocks_free(di, track);
    }
  }
  return(blocks);
}


/* check if track, sector is free in BAM */
int di_is_ts_free(DiskImage *di, TrackSector ts) {
  unsigned char mask;
  unsigned char *bam;

  switch (di->type) {
  case D64:
    bam = get_ts_addr(di, di->bam);
    if (bam[ts.track * 4]) {
      mask = 1<<(ts.sector & 7);
      return(bam[ts.track * 4 + ts.sector / 8 + 1] & mask ? 1 : 0);
    } else {
      return(0);
    }
    break;
  case D71:
    mask = 1<<(ts.sector & 7);
    if (ts.track < 36) {
      bam = get_ts_addr(di, di->bam);
      return(bam[ts.track * 4 + ts.sector / 8 + 1] & mask ? 1 : 0);
    } else {
      bam = get_ts_addr(di, di->bam2);
      return(bam[(ts.track - 35) * 3 + ts.sector / 8 - 3] & mask ? 1 : 0);
    }
    break;
  case D81:
    mask = 1<<(ts.sector & 7);
    if (ts.track < 41) {
      bam = get_ts_addr(di, di->bam);
    } else {
      bam = get_ts_addr(di, di->bam2);
      ts.track -= 40;
    }
    return(bam[ts.track * 6 + ts.sector / 8 + 11] & mask ? 1 : 0);
    break;
  }
  return(0);
}


/* allocate track, sector in BAM */
void di_alloc_ts(DiskImage *di, TrackSector ts) {
  unsigned char mask;
  unsigned char *bam;

  di->modified = 1;
  switch (di->type) {
  case D64:
    bam = get_ts_addr(di, di->bam);
    bam[ts.track * 4] -= 1;
    mask = 1<<(ts.sector & 7);
    bam[ts.track * 4 + ts.sector / 8 + 1] &= ~mask;
    break;
  case D71:
    mask = 1<<(ts.sector & 7);
    if (ts.track < 36) {
      bam = get_ts_addr(di, di->bam);
      bam[ts.track * 4] -= 1;
      bam[ts.track * 4 + ts.sector / 8 + 1] &= ~mask;
    } else {
      bam = get_ts_addr(di, di->bam);
      bam[ts.track + 185] -= 1;
      bam = get_ts_addr(di, di->bam2);
      bam[(ts.track - 35) * 3 + ts.sector / 8 - 3] &= ~mask;
    }
    break;
  case D81:
    if (ts.track < 41) {
      bam = get_ts_addr(di, di->bam);
    } else {
      bam = get_ts_addr(di, di->bam2);
      ts.track -= 40;
    }
    bam[ts.track * 6 + 10] -= 1;
    mask = 1<<(ts.sector & 7);
    bam[ts.track * 6 + ts.sector / 8 + 11] &= ~mask;
    break;
  }
}


/* allocate next available block */
TrackSector alloc_next_ts(DiskImage *di, TrackSector prevts) {
  unsigned char *bam;
  int spt, s1, s2, t1, t2, bpt, boff, res1, res2;
  TrackSector ts;

  switch (di->type) {
  default:
  case D64:
    s1 = 1;
    t1 = 35;
    s2 = 1;
    t2 = 35;
    res1 = 18;
    res2 = 0;
    bpt = 4;
    boff = 0;
    break;
  case D71:
    s1 = 1;
    t1 = 35;
    s2 = 36;
    t2 = 70;
    res1 = 18;
    res2 = 53;
    bpt = 4;
    boff = 0;
    break;
  case D81:
    s1 = 1;
    t1 = 40;
    s2 = 41;
    t2 = 80;
    res1 = 40;
    res2 = 0;
    bpt = 6;
    boff = 10;
    break;
  }

  bam = get_ts_addr(di, di->bam);
  for (ts.track = s1; ts.track <= t1; ++ts.track) {
    if (ts.track != res1) {
      if  (bam[ts.track * bpt + boff]) {
   spt = di_sectors_per_track(di->type, ts.track);
   ts.sector = (prevts.sector + interleave(di->type)) % spt;
   for (; ; ts.sector = (ts.sector + 1) % spt) {
     if (di_is_ts_free(di, ts)) {
       di_alloc_ts(di, ts);
       return(ts);
     }
   }
      }
    }
  }

  if (di->type == D71 || di->type == D81) {
    bam = get_ts_addr(di, di->bam2);
    for (ts.track = s2; ts.track <= t2; ++ts.track) {
      if (ts.track != res2) {
   if  (bam[(ts.track - t1) * bpt + boff]) {
     spt = di_sectors_per_track(di->type, ts.track);
     ts.sector = (prevts.sector + interleave(di->type)) % spt;
     for (; ; ts.sector = (ts.sector + 1) % spt) {
       if (di_is_ts_free(di, ts)) {
         di_alloc_ts(di, ts);
         return(ts);
       }
     }
   }
      }
    }
  }

  ts.track = 0;
  ts.sector = 0;
  return(ts);
}


/* allocate next available directory block */
TrackSector alloc_next_dir_ts(DiskImage *di) {
  unsigned char *p;
  int spt;
  TrackSector ts, lastts;

  if (di_track_blocks_free(di, di->bam.track)) {
    ts.track = di->bam.track;
    ts.sector = 0;
    while (ts.track) {
      lastts = ts;
      ts = next_ts_in_chain(di, ts);
    }
    ts.track = lastts.track;
    ts.sector = lastts.sector + 3;
    spt = di_sectors_per_track(di->type, ts.track);
    for (; ; ts.sector = (ts.sector + 1) % spt) {
      if (di_is_ts_free(di, ts)) {
   di_alloc_ts(di, ts);
   p = get_ts_addr(di, lastts);
   p[0] = ts.track;
   p[1] = ts.sector;
   p = get_ts_addr(di, ts);
   memset(p, 0, 256);
   p[1] = 0xff;
   di->modified = 1;
   return(ts);
      }
    }
  } else {
    ts.track = 0;
    ts.sector = 0;
    return(ts);
  }
}


/* free a block in the BAM */
void di_free_ts(DiskImage *di, TrackSector ts) {
  unsigned char mask;
  unsigned char *bam;

  di->modified = 1;
  switch (di->type) {
  case D64:
    mask = 1<<(ts.sector & 7);
    bam = get_ts_addr(di, di->bam);
    bam[ts.track * 4 + ts.sector / 8 + 1] |= mask;
    bam[ts.track * 4] += 1;
    break;
  case D71:
    mask = 1<<(ts.sector & 7);
    if (ts.track < 36) {
      bam = get_ts_addr(di, di->bam);
      bam[ts.track * 4 + ts.sector / 8 + 1] |= mask;
      bam[ts.track * 4] += 1;
    } else {
      bam = get_ts_addr(di, di->bam);
      bam[ts.track + 185] += 1;
      bam = get_ts_addr(di, di->bam2);
      bam[(ts.track - 35) * 3 + ts.sector / 8 - 3] |= mask;
    }
    break;
  case D81:
    if (ts.track < 41) {
      bam = get_ts_addr(di, di->bam);
    } else {
      bam = get_ts_addr(di, di->bam2);
      ts.track -= 40;
    }
    mask = 1<<(ts.sector & 7);
    bam[ts.track * 6 + ts.sector / 8 + 11] |= mask;
    bam[ts.track * 6 + 10] += 1;
    break;
  default:
    break;
  }
}


/* free a chain of blocks */
void free_chain(DiskImage *di, TrackSector ts) {
  while (ts.track) {
    di_free_ts(di, ts);
    ts = next_ts_in_chain(di, ts);
  }
}


DiskImage *di_load_image(char *name) {
  FILE *file;
  int filesize, l, read;
  DiskImage *di;

  /* open image */
  if ((file = fopen(name, "rb")) == NULL) {
    //puts("fopen failed");
    return(NULL);
  }

  /* get file size*/
  if (fseek(file, 0, SEEK_END)) {
    //puts("fseek failed");
    fclose(file);
    return(NULL);
  }
  filesize = ftell(file);
  fseek(file, 0, SEEK_SET);

  if ((di = malloc(sizeof(*di))) == NULL) {
    //puts("malloc failed");
    fclose(file);
    return(NULL);
  }

  /* check image type */
  switch (filesize) {
  case 174848: // standard D64
  case 175531: // D64 with error info (which we just ignore)
    di->type = D64;
    di->bam.track = 18;
    di->bam.sector = 0;
    di->dir = di->bam;
    break;
  case 349696:
    di->type = D71;
    di->bam.track = 18;
    di->bam.sector = 0;
    di->bam2.track = 53;
    di->bam2.sector = 0;
    di->dir = di->bam;
    break;
  case 819200:
    di->type = D81;
    di->bam.track = 40;
    di->bam.sector = 1;
    di->bam2.track = 40;
    di->bam2.sector = 2;
    di->dir.track = 40;
    di->dir.sector = 0;
    break;
  default:
    //puts("unknown type");
    free(di);
    fclose(file);
    return(NULL);
  }

  di->size = filesize;

  /* allocate buffer for image */
  if ((di->image = malloc(filesize)) == NULL) {
    //puts("image malloc failed");
    free(di);
    fclose(file);
    return(NULL);
  }

  /* read file into buffer */
  read = 0;
  while (read < filesize) {
    if ((l = fread(di->image, 1, filesize - read, file))) {
      read += l;
    } else {
      //puts("fread failed");
      free(di->image);
      free(di);
      fclose(file);
      return(NULL);
    }
  }

  di->filename = malloc(strlen(name) + 1);
  strcpy(di->filename, name);
  di->openfiles = 0;
  di->blocksfree = blocks_free(di);
  di->modified = 0;
  fclose(file);
  set_status(di, 254, 0, 0);
  return(di);
}


DiskImage *di_create_image(char *name, int size) {
  DiskImage *di;

  if ((di = malloc(sizeof(*di))) == NULL) {
    //puts("malloc failed");
    return(NULL);
  }

  /* check image type */
  switch (size) {
  case 174848: // standard D64
  case 175531: // D64 with error info (which we just ignore)
    di->type = D64;
    di->bam.track = 18;
    di->bam.sector = 0;
    di->dir = di->bam;
    break;
  case 349696:
    di->type = D71;
    di->bam.track = 18;
    di->bam.sector = 0;
    di->bam2.track = 53;
    di->bam2.sector = 0;
    di->dir = di->bam;
    break;
  case 819200:
    di->type = D81;
    di->bam.track = 40;
    di->bam.sector = 1;
    di->bam2.track = 40;
    di->bam2.sector = 2;
    di->dir.track = 40;
    di->dir.sector = 0;
    break;
  default:
    //puts("unknown type");
    free(di);
    return(NULL);
  }

  di->size = size;

  /* allocate buffer for image */
  if ((di->image = malloc(size)) == NULL) {
    //puts("image malloc failed");
    free(di);
    return(NULL);
  }
  memset(di->image, 0, size);

  di->filename = malloc(strlen(name) + 1);
  strcpy(di->filename, name);
  di->openfiles = 0;
  di->blocksfree = blocks_free(di);
  di->modified = 1;
  set_status(di, 254, 0, 0);
  return(di);
}


void di_sync(DiskImage *di) {
  FILE *file;
  int l, left;
  unsigned char *image;

  if ((file = fopen(di->filename, "wb"))) {
    image = di->image;
    left = di->size;
    l = 0;
    while (left) {
      if ((l = fwrite(image, 1, left, file)) == 0) {
   fclose(file);
   return;
      }
      left -= l;
      image += l;
    }
    fclose(file);
    di->modified = 0;
  }
}


void di_free_image(DiskImage *di) {
  if (di->modified) {
    di_sync(di);
  }
  if (di->filename) {
    free(di->filename);
  }
  free(di->image);
  free(di);
}


int match_pattern(unsigned char *rawpattern, unsigned char *rawname) {
  int i;

  for (i = 0; i < 16; ++i) {
    if (rawpattern[i] == '*') {
      return(1);
    }
    if (rawname[i] == 0xa0) {
      if (rawpattern[i] == 0xa0) {
   return(1);
      } else {
   return(0);
      }
    } else {
      if (rawpattern[i] == '?' || rawpattern[i] == rawname[i]) {
      } else {
   return(0);
      }
    }
  }
  return(1);
}


RawDirEntry *find_file_entry(DiskImage *di, unsigned char *rawpattern, FileType type) {
  unsigned char *buffer;
  TrackSector ts;
  RawDirEntry *rde;
  int offset;

  ts = next_ts_in_chain(di, di->bam);
  while (ts.track) {
    buffer = get_ts_addr(di, ts);
    for (offset = 0; offset < 256; offset += 32) {
      rde = (RawDirEntry *)(buffer + offset);
      if ((rde->type & ~0x40) == (type | 0x80)) {
   if (match_pattern(rawpattern, rde->rawname)) {
     return(rde);
   }
      }
    }
    ts = next_ts_in_chain(di, ts);
  }
  return(NULL);
}


RawDirEntry *alloc_file_entry(DiskImage *di, unsigned char *rawname, FileType type) {
  unsigned char *buffer;
  TrackSector ts, lastts;
  RawDirEntry *rde;
  int offset;

  /* check if file already exists */
  ts = next_ts_in_chain(di, di->bam);
  while (ts.track) {
    buffer = get_ts_addr(di, ts);
    for (offset = 0; offset < 256; offset += 32) {
      rde = (RawDirEntry *)(buffer + offset);
      if (rde->type & 0x3f) { // cv: mask out file type to ignore closed/locked DEL files
   if (strncmp(rawname, rde->rawname, 16) == 0) {
     set_status(di, 63, 0, 0);
     //puts("file exists");
     return(NULL);
   }
      }
    }
    ts = next_ts_in_chain(di, ts);
  }

  /* allocate empty slot */
  ts = next_ts_in_chain(di, di->bam);
  while (ts.track) {
    buffer = get_ts_addr(di, ts);
    for (offset = 0; offset < 256; offset += 32) {
      rde = (RawDirEntry *)(buffer + offset);
      if (rde->type == 0) {
   memset((unsigned char *)rde + 2, 0, 30);
   memcpy(rde->rawname, rawname, 16);
   rde->type = type;
   di->modified = 1;
   return(rde);
      }
    }
    lastts = ts;
    ts = next_ts_in_chain(di, ts);
  }

  /* allocate new dir block */
  ts = alloc_next_dir_ts(di);
  if (ts.track) {
    rde = (RawDirEntry *)get_ts_addr(di, ts);
    memset((unsigned char *)rde + 2, 0, 30);
    memcpy(rde->rawname, rawname, 16);
    rde->type = type;
    di->modified = 1;
    return(rde);
  } else {
    set_status(di, 72, 0, 0);
    //puts("directory full");
    return(NULL);
  }
}


/* open a file */
ImageFile *di_open(DiskImage *di, unsigned char *rawname, FileType type, char *mode) {
  ImageFile *imgfile;
  RawDirEntry *rde;
  unsigned char *p;

  set_status(di, 255, 0, 0);

  if (strcmp("rb", mode) == 0) {

    if ((imgfile = malloc(sizeof(*imgfile))) == NULL) {
      //puts("malloc failed");
      return(NULL);
    }
    if (strcmp("$", rawname) == 0) {
      imgfile->mode = 'r';
      imgfile->ts = di->dir;
      p = get_ts_addr(di, di->dir);
      imgfile->buffer = p + 2;
      if ((di->type == D64) || (di->type == D71)) {
   imgfile->nextts.track = 18; // 1541/71 ignores bam t/s link
   imgfile->nextts.sector = 1;
      } else {
   imgfile->nextts.track = p[0];
   imgfile->nextts.sector = p[1];
      }
      imgfile->buflen = 254;
      rde = NULL;
    } else {
      if ((rde = find_file_entry(di, rawname, type)) == NULL) {
   set_status(di, 62, 0, 0);
   //puts("find_file_entry failed");
   free(imgfile);
   return(NULL);
      }
      imgfile->mode = 'r';
      imgfile->ts = rde->startts;
      if (imgfile->ts.track > di_tracks(di->type)) {
   return(NULL);
      }
      p = get_ts_addr(di, rde->startts);
      imgfile->buffer = p + 2;
      imgfile->nextts.track = p[0];
      imgfile->nextts.sector = p[1];
      if (imgfile->nextts.track == 0) {
   imgfile->buflen = imgfile->nextts.sector - 1;
      } else {
   imgfile->buflen = 254;
      }
    }

  } else if (strcmp("wb", mode) == 0) {

    if ((rde = alloc_file_entry(di, rawname, type)) == NULL) {
      //puts("alloc_file_entry failed");
      return(NULL);
    }
    if ((imgfile = malloc(sizeof(*imgfile))) == NULL) {
      //puts("malloc failed");
      return(NULL);
    }
    imgfile->mode = 'w';
    imgfile->ts.track = 0;
    imgfile->ts.sector = 0;
    if ((imgfile->buffer = malloc(254)) == NULL) {
      free(imgfile);
      //puts("malloc failed");
      return(NULL);
    }
    imgfile->buflen = 254;
    di->modified = 1;

  } else {
    return(NULL);
  }

  imgfile->diskimage = di;
  imgfile->rawdirentry = rde;
  imgfile->position = 0;
  imgfile->bufptr = 0;

  ++(di->openfiles);
  set_status(di, 0, 0, 0);
  return(imgfile);
}


int di_read(ImageFile *imgfile, unsigned char *buffer, int len) {
  unsigned char *p;
  int bytesleft;
  int counter = 0;

  while (len) {
    bytesleft = imgfile->buflen - imgfile->bufptr;
    if (bytesleft == 0) {
      if (imgfile->nextts.track == 0) {
   return(counter);
      }
      if (((imgfile->diskimage->type == D64) || (imgfile->diskimage->type == D71)) && imgfile->ts.track == 18 && imgfile->ts.sector == 0) {
   imgfile->ts.track = 18;
   imgfile->ts.sector = 1;
      } else {
   imgfile->ts = next_ts_in_chain(imgfile->diskimage, imgfile->ts);
      }
      if (imgfile->ts.track == 0) {
   return(counter);
      }
      p = get_ts_addr(imgfile->diskimage, imgfile->ts);
      imgfile->buffer = p + 2;
      imgfile->nextts.track = p[0];
      imgfile->nextts.sector = p[1];
      if (imgfile->nextts.track == 0) {
   imgfile->buflen = imgfile->nextts.sector - 1;
      } else {
   imgfile->buflen = 254;
      }
      imgfile->bufptr = 0;
    } else {
      if (len >= bytesleft) {
      while (bytesleft) {
        *buffer++ = imgfile->buffer[imgfile->bufptr++];
        --len;
        --bytesleft;
        ++counter;
        ++(imgfile->position);
      }
      } else {
      while (len) {
        *buffer++ = imgfile->buffer[imgfile->bufptr++];
        --len;
        --bytesleft;
        ++counter;
        ++(imgfile->position);
      }
      }
    }
  }
  return(counter);
}


int di_write(ImageFile *imgfile, unsigned char *buffer, int len) {
  unsigned char *p;
  int bytesleft;
  int counter = 0;

  while (len) {
    bytesleft = imgfile->buflen - imgfile->bufptr;
    if (bytesleft == 0) {
      if (imgfile->diskimage->blocksfree == 0) {
   set_status(imgfile->diskimage, 72, 0, 0);
   return(counter);
      }
      imgfile->nextts = alloc_next_ts(imgfile->diskimage, imgfile->ts);
      if (imgfile->ts.track == 0) {
   imgfile->rawdirentry->startts = imgfile->nextts;
      } else {
   p = get_ts_addr(imgfile->diskimage, imgfile->ts);
   p[0] = imgfile->nextts.track;
   p[1] = imgfile->nextts.sector;
      }
      imgfile->ts = imgfile->nextts;
      p = get_ts_addr(imgfile->diskimage, imgfile->ts);
      p[0] = 0;
      p[1] = 0xff;
      memcpy(p + 2, imgfile->buffer, 254);
      imgfile->bufptr = 0;
      if (++(imgfile->rawdirentry->sizelo) == 0) {
   ++(imgfile->rawdirentry->sizehi);
      }
      --(imgfile->diskimage->blocksfree);
    } else {
      if (len >= bytesleft) {
   while (bytesleft) {
     imgfile->buffer[imgfile->bufptr++] = *buffer++;
     --len;
     --bytesleft;
     ++counter;
     ++(imgfile->position);
   }
      } else {
   while (len) {
     imgfile->buffer[imgfile->bufptr++] = *buffer++;
     --len;
     --bytesleft;
     ++counter;
     ++(imgfile->position);
   }
      }
    }
  }
  return(counter);
}


void di_close(ImageFile *imgfile) {
  unsigned char *p;

  if (imgfile->mode == 'w') {
    if (imgfile->bufptr) {
      if (imgfile->diskimage->blocksfree) {
   imgfile->nextts = alloc_next_ts(imgfile->diskimage, imgfile->ts);
   if (imgfile->ts.track == 0) {
     imgfile->rawdirentry->startts = imgfile->nextts;
   } else {
     p = get_ts_addr(imgfile->diskimage, imgfile->ts);
     p[0] = imgfile->nextts.track;
     p[1] = imgfile->nextts.sector;
   }
   imgfile->ts = imgfile->nextts;
   p = get_ts_addr(imgfile->diskimage, imgfile->ts);
   p[0] = 0;
   p[1] = 0xff;
   memcpy(p + 2, imgfile->buffer, 254);
   imgfile->bufptr = 0;
   if (++(imgfile->rawdirentry->sizelo) == 0) {
     ++(imgfile->rawdirentry->sizehi);
   }
   --(imgfile->diskimage->blocksfree);
   imgfile->rawdirentry->type |= 0x80;
      }
    } else {
      imgfile->rawdirentry->type |= 0x80;
    }
    free(imgfile->buffer);
  }
  --(imgfile->diskimage->openfiles);
  free(imgfile);
}


int di_format(DiskImage *di, unsigned char *rawname, unsigned char *rawid) {
  unsigned char *p;
  TrackSector ts;

  di->modified = 1;

  switch (di->type) {

  case D64:
    /* erase disk */
    if (rawid) {
      memset(di->image, 0, 174848);
    }

    /* get ptr to bam */
    p = get_ts_addr(di, di->bam);

    /* setup header */
    p[0] = 18;
    p[1] = 1;
    p[2] = 'A';
    p[3] = 0;

    /* clear bam */
    memset(p + 4, 0, 0x8c);

    /* free blocks */
    for (ts.track = 1; ts.track <= di_tracks(di->type); ++ts.track) {
      for (ts.sector = 0; ts.sector < di_sectors_per_track(di->type, ts.track); ++ts.sector) {
   di_free_ts(di, ts);
      }
    }

    /* allocate bam and dir */
    ts.track = 18;
    ts.sector = 0;
    di_alloc_ts(di, ts);
    ts.sector = 1;
    di_alloc_ts(di, ts);

    /* copy name */
    memcpy(p + 0x90, rawname, 16);

    /* set id */
    memset(p + 0xa0, 0xa0, 2);
    if (rawid) {
      memcpy(p + 0xa2, rawid, 2);
    }
    memset(p + 0xa4, 0xa0, 7);
    p[0xa5] = '2';
    p[0xa6] = 'A';

    /* clear unused bytes */
    memset(p + 0xab, 0, 0x55);

    /* clear first dir block */
    memset(p + 256, 0, 256);
    p[257] = 0xff;
    break;

  case D71:
    /* erase disk */
    if (rawid) {
      memset(di->image, 0, 349696);
    }

    /* get ptr to bam2 */
    p = get_ts_addr(di, di->bam2);

    /* clear bam2 */
    memset(p, 0, 256);

    /* get ptr to bam */
    p = get_ts_addr(di, di->bam);

    /* setup header */
    p[0] = 18;
    p[1] = 1;
    p[2] = 'A';
    p[3] = 0x80;

    /* clear bam */
    memset(p + 4, 0, 0x8c);

    /* clear bam2 counters */
    memset(p + 0xdd, 0, 0x23);

    /* free blocks */
    for (ts.track = 1; ts.track <= di_tracks(di->type); ++ts.track) {
      if (ts.track != 53) {
   for (ts.sector = 0; ts.sector < di_sectors_per_track(di->type, ts.track); ++ts.sector) {
     di_free_ts(di, ts);
   }
      }
    }

    /* allocate bam and dir */
    ts.track = 18;
    ts.sector = 0;
    di_alloc_ts(di, ts);
    ts.sector = 1;
    di_alloc_ts(di, ts);

    /* copy name */
    memcpy(p + 0x90, rawname, 16);

    /* set id */
    memset(p + 0xa0, 0xa0, 2);
    if (rawid) {
      memcpy(p + 0xa2, rawid, 2);
    }
    memset(p + 0xa4, 0xa0, 7);
    p[0xa5] = '2';
    p[0xa6] = 'A';

    /* clear unused bytes */
    memset(p + 0xab, 0, 0x32);

    /* clear first dir block */
    memset(p + 256, 0, 256);
    p[257] = 0xff;
    break;

  case D81:
    /* erase disk */
    if (rawid) {
      memset(di->image, 0, 819200);
    }

    /* get ptr to bam */
    p = get_ts_addr(di, di->bam);

    /* setup header */
    p[0] = 0x28;
    p[1] = 0x02;
    p[2] = 0x44;
    p[3] = 0xbb;
    p[6] = 0xc0;

    /* set id */
    if (rawid) {
      memcpy(p + 4, rawid, 2);
    }

    /* clear bam */
    memset(p + 7, 0, 0xfa);

    /* get ptr to bam2 */
    p = get_ts_addr(di, di->bam2);

    /* setup header */
    p[0] = 0x00;
    p[1] = 0xff;
    p[2] = 0x44;
    p[3] = 0xbb;
    p[6] = 0xc0;

    /* set id */
    if (rawid) {
      memcpy(p + 4, rawid, 2);
    }

    /* clear bam2 */
    memset(p + 7, 0, 0xfa);

    /* free blocks */
    for (ts.track = 1; ts.track <= di_tracks(di->type); ++ts.track) {
      for (ts.sector = 0; ts.sector < di_sectors_per_track(di->type, ts.track); ++ts.sector) {
   di_free_ts(di, ts);
      }
    }

    /* allocate bam and dir */
    ts.track = 40;
    ts.sector = 0;
    di_alloc_ts(di, ts);
    ts.sector = 1;
    di_alloc_ts(di, ts);
    ts.sector = 2;
    di_alloc_ts(di, ts);
    ts.sector = 3;
    di_alloc_ts(di, ts);

    /* get ptr to dir */
    p = get_ts_addr(di, di->dir);

    /* copy name */
    memcpy(p + 4, rawname, 16);

    /* set id */
    memset(p + 0x14, 0xa0, 2);
    if (rawid) {
      memcpy(p + 0x16, rawid, 2);
    }
    memset(p + 0x18, 0xa0, 5);
    p[0x19] = '3';
    p[0x1a] = 'D';

    /* clear unused bytes */
    memset(p + 0x1d, 0, 0xe3);

    /* clear first dir block */
    memset(p + 768, 0, 256);
    p[769] = 0xff;
    break;

  }

  di->blocksfree = blocks_free(di);

  return(set_status(di, 0, 0, 0));
}


int di_delete(DiskImage *di, unsigned char *rawpattern, FileType type) {
  RawDirEntry *rde;
  int delcount = 0;

  switch (type) {

  case T_SEQ:
  case T_PRG:
  case T_USR:
  case T_DEL: // cv: allow to delete special closed/locked DEL files
    while ((rde = find_file_entry(di, rawpattern, type))) {
      free_chain(di, rde->startts);
      rde->type = 0;
      ++delcount;
    }
    if (delcount) {
      return(set_status(di, 1, delcount, 0));
    } else {
      return(set_status(di, 62, 0, 0));
    }
    break;

  default:
    return(set_status(di, 64, 0, 0));
    break;

  }
}


int di_rename(DiskImage *di, unsigned char *oldrawname, unsigned char *newrawname, FileType type) {
  RawDirEntry *rde;

  if ((rde = find_file_entry(di, oldrawname, type))) {
    memcpy(rde->rawname, newrawname, 16);
    return(set_status(di, 0, 0, 0));
  } else {
    return(set_status(di, 62, 0, 0));
  }
}




Code Test Directory

Code:
/*

  directory listing

 */

#include <stdio.h>
#include <string.h>
#include "diskimage.h"

static char *ftype[] = {
  "del",
  "seq",
  "prg",
  "usr",
  "rel",
  "cbm",
  "dir",
  "???"
};

static char usage[] = "test_dir <diskimage>";


void ptoa(unsigned char *s) {
  unsigned char c;

  while ((c = *s)) {
    c &= 0x7f;
    if (c >= 'A' && c <= 'Z') {
      c += 32;
    } else if (c >= 'a' && c <= 'z') {
      c -= 32;
    } else if (c == 0x7f) {
      c = 0x3f;
    }
    *s++ = c;
  }
}


int main(int argc, char *argv[]) {
  DiskImage *di;
  unsigned char buffer[254];
  ImageFile *dh;
  int offset;
  char quotename[19];
  char name[17];
  char id[6];
  int type;
  int closed;
  int locked;
  int size;

  /* Check usage */
  if (argc != 2) {
    puts(usage);
    return(1);
  }

  /* Load image into ram */
  if ((di = di_load_image(argv[1])) == NULL) {
    puts("di_load_image failed");
    return(1);
  }

  /* Open directory for reading */
  if ((dh = di_open(di, "$", T_PRG, "rb")) == NULL) {
    puts("Couldn't open directory");
    goto CloseImage;
  }

  /* Convert title to ascii */
  di_name_from_rawname(name, di_title(di));
  ptoa(name);

  /* Convert ID to ascii */
  memcpy(id, di_title(di) + 18, 5);
  id[5] = 0;
  ptoa(id);

  /* Print title and disk ID */
  printf("0 \"%-16s\" %s\n", name, id);

  /* Read first block into buffer */
  if (di_read(dh, buffer, 254) != 254) {
    printf("BAM read failed\n");
    goto CloseDir;
  }

  /* Read directory blocks */
  while (di_read(dh, buffer, 254) == 254) {
    for (offset = -2; offset < 254; offset += 32) {

      /* If file type != 0 */
      if (buffer[offset+2]) {

   di_name_from_rawname(name, buffer + offset + 5);
   type = buffer[offset + 2] & 7;
   closed = buffer[offset + 2] & 0x80;
   locked = buffer[offset + 2] & 0x40;
   size = buffer[offset + 31]<<8 | buffer[offset + 30];

   /* Convert to ascii and add quotes */
   ptoa(name);
   sprintf(quotename, "\"%s\"", name);

   /* Print directory entry */
   printf("%-4d  %-18s%c%s%c\n", size, quotename, closed ? ' ' : '*', ftype[type], locked ? '<' : ' ');
      }
    }
  }

  /* Print number of blocks free */
  printf("%d blocks free\n", di->blocksfree);

 CloseDir:
  /* Close file */
  di_close(dh);

 CloseImage:
  /* Release image */
  di_free_image(di);

  /* Done */
  return(0);
}




My Gui in PB with OpenCBM and c1541 support

Image


Last edited by Marty2PB on Fri Sep 13, 2019 6:07 pm, edited 4 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Mon Sep 09, 2019 6:54 pm 
Offline
Addict
Addict
User avatar

Joined: Wed Dec 23, 2009 10:14 pm
Posts: 3055
Location: Boston, MA
.......
unsigned char *bam; << is this a pointer or just a byte because the return code
.......
return(bam [track * 4] ); what have i to do ?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, *bam is a pointer.
They use it to "walk" through memory.
You can do the same.
Code:
Structure myChar
  c.c[0]
EndStructure
Define *bam.myChar
Define.s x$ = "Hello World!"
*bam = @x$
Debug Chr(*bam\c[0])
Debug Chr(*bam\c[2])

_________________
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Mon Sep 09, 2019 10:01 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Hey Skywalk :)

Great, thanks it works.

Image

I get now the free Blocks of the C64 Diskimage. The lister uses at time c1541.exe from sdl2vice

Code:
    ; /* return number of free blocks in track */
   
    Procedure.i di_track_blocks_free(*di.DiskImage, track.i)
       
        Structure UnsignedChar
            b.b[0]
        EndStructure
           
        Define *bam.UnsignedChar
       
        Select *di\Type
            Case "D64":
                *bam = get_ts_addr(*di, *di\bam)
                Debug *bam
            Case "D71":
                *bam = get_ts_addr(*di, *di\bam)
                If (track >= 36)
                   ProcedureReturn bam + (track + 185)
                EndIf   
            Case "D81":
            Default
        EndSelect       
       
        ProcedureReturn ( *bam\b [track * 4]  )
       
    EndProcedure   


i changed the Readfile Macro
Code:
Macro LoadDiskImage(diFileName, diFileSize)
       
        *di\image = AllocateMemory(diFileSize)
       
        Define DiskImage = OpenFile( #PB_Any, diFileName )
        If DiskImage
            While Not Eof( DiskImage )             
                ReadData(DiskImage, *di\image, diFileSize)
            Wend
            CloseFile(DiskImage)
        EndIf
    EndMacro


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Tue Sep 10, 2019 11:31 am 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
in the "Procdure di_open(*di.DiskImage, rawname.s, Mode.s)"
Purebasic Combilation crasht "somtimes" at "Debug *p\c[0]" :?
What could it be?

and I'm a confused with char *name, unsigned char *rawname as procdure arguement?

Code:
int di_name_from_rawname(char *name, unsigned char *rawname) {
  int i;

  for (i = 0; i < 16 && rawname[i] != 0xa0; ++i) {
    name[i] = rawname[i];
  }
  name[i] = 0;
  return(i);
}



is this right?
Code:
;---------------------------------------------------------------------------------------------------------
; /* convert from rawname */
;---------------------------------------------------------------------------------------------------------
Procedure di_name_from_rawname(*name.char, *rawname.char)
        Protected i.i
       
        For i = 0 To 16
            If ( *rawname\c[i] ! $a0 )
                *name\c[i] = *rawname\c[i];
            EndIf
           
        Next   
       
        *name\c[i] = 0
        ProcedureReturn i
     EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Tue Sep 10, 2019 11:40 am 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4308
Location: Germany
Code:
for (i = 0; i < 16

is in PB:
Code:
For i = 0 To 15

:wink:

Code:
Structure char
  c.a[0]
EndStructure


Procedure.i di_name_from_rawname(*name.char, *rawname.char)
 
  Protected i.i

  For i = 0 To 15
    If *rawname\c[i] = $a0
      Break
    EndIf
    *name\c[i] = *rawname\c[i]
  Next i
  *name\c[i] = 0
 
  ProcedureReturn i
 
EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Tue Sep 10, 2019 10:48 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Hello infratec

Great, it work. i dunno ....

Image :D

The other thing is:
Code:
  /* Read first block into buffer */
  if (di_read(dh, buffer, 254) != 254) {
    printf("BAM read failed\n");
    goto CloseDir;
  }

  /* Read directory blocks */
  while (di_read(dh, buffer, 254) == 254) {
    for (offset = -2; offset < 254; offset += 32) {

      /* If file type != 0 */
      if (buffer[offset+2]) {

      di_name_from_rawname(name, buffer + offset + 5);
      type = buffer[offset + 2] & 7;
      closed = buffer[offset + 2] & 0x80;
      locked = buffer[offset + 2] & 0x40;
      size = buffer[offset + 31]<<8 | buffer[offset + 30];

      /* Convert to ascii and add quotes */
      ptoa(name);
      sprintf(quotename, "\"%s\"", name);

      /* Print directory entry */
      printf("%-4d  %-18s%c%s%c\n", size, quotename, closed ? ' ' : '*', ftype[type], locked ? '<' : ' ');
      }
    }
  }


i converted to pb and add the filtype in this procedure.
I get the titleheader and Disk ID but not the filename. I get various mixed ascii signs.
I think i do any false wiht the buffer size [254] and or in combination with offset.
The Buffer in the C source is set to 254. My buffer goes out of the box to 261?
:shock:

The counter procedure " di_read(*imgfile.ImageFile, *buffer.CharBuffer, len.i)" is right and goes to 254.


Code:
;---------------------------------------------------------------------------------------------------------
    ; /* Read directory blocks */
;---------------------------------------------------------------------------------------------------------     
    Procedure.i di_read_directory_blocks(*imgfile.ImageFile)
               
        Protected offset.i, type.i, closed.i, locked.i, size.i, C64FileLen.i, C64File.s, ftype.s

        If ( di_read(*imgfile, @buffer.OffsetBuffer, 254) ! 254)
           
            Debug "BAM Read failed"
           
        Else
            ;/* Read directory blocks */
            While ( di_read(*imgfile,  @buffer.OffsetBuffer, 254) = 254)
               
               
                For offset = -2 To 253                   
                    offset + 32
                   
                    ; If file type != 0                     
                    If ( @buffer\c[ offset +2 ] )
                        C64FileLen = di_name_from_rawname(@name.OffsetBuffer,@buffer.OffsetBuffer + offset + 5)
                        type    = @buffer\c[ offset + 2 ] &   7
                        closed  = @buffer\c[ offset + 2 ] & $80
                        locked  = @buffer\c[ offset + 2 ] & $40
                        size    = @buffer\c[ offset + 31 ] << 8 | @buffer\c[ offset + 30 ]
                       
                        Select type
                            Case 0: ftype = "del"
                            Case 1: ftype = "seq"
                            Case 2: ftype = "prg"
                            Case 3: ftype = "usr"                               
                            Case 4: ftype = "rel"
                            Case 5: ftype = "cbm"                                 
                            Case 6: ftype = "dir"                                 
                            Default:ftype = "???"                                 
                        EndSelect
                       
                        If ( closed )
                            ftype = "*"+ftype
                        Else
                            ftype = " "+ftype
                        EndIf
                       
                        If ( locked )
                            ftype + "<"
                        Else
                            ftype + " "
                        EndIf     
                                                       
                        ; /* Convert To ascii  */
                        C64File.s = PeekS(@name, C64FileLen )
                        Debug C64File + ftype
                    EndIf   
                   
                    Debug offset
                Next offset                               
            Wend   
        EndIf       
    EndProcedure   


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Wed Sep 11, 2019 7:11 am 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4308
Location: Germany
Try
Code:
C64File.s = PeekS(@name, C64FileLen, #PB_Ascii)


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Wed Sep 11, 2019 3:08 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Hm.. this and other variants i have test it. UTF and Unicode is really nonsense but No changes. Only Ascii Mismatch. I try other things

This is really strange? the For loop should only go to 254. But breaks at offset with "size.i" at 228 [+31] where I'm totally on it.

in c
unsigned char buffer[254];

is in pb?

Structure buffer
c.a[254]
EndStructure
.....
@b.buffer and or *b.buffer
.....


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Wed Sep 11, 2019 4:09 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 514
Iirc. uchar is 1 byte so it looks correct :)


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Wed Sep 11, 2019 9:49 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Next C to PB :mrgreen:

Code:
RawDirEntry *find_file_entry(DiskImage *di, unsigned char *rawpattern, FileType type) {
  unsigned char *buffer;
  TrackSector ts;
  RawDirEntry *rde;
  int offset;

  ts = next_ts_in_chain(di, di->bam);
  while (ts.track) {
    buffer = get_ts_addr(di, ts);
   
   for (offset = 0; offset < 256; offset += 32) {
   
   rde = (RawDirEntry *)(buffer + offset);

   if ((rde->type & ~0x40) == (type | 0x80)) {
   
      if (match_pattern(rawpattern, rde->rawname)) {
        return(rde);
      }
      }
    }
    ts = next_ts_in_chain(di, ts);
  }
  return(NULL);
}



rde is "big" a pointer with structure. buffer + offeset = ok but this: (RawDirEntry *)
how do interpret this line

rde = (RawDirEntry *)(buffer + offset); ??

*rde.RawDirEntry * ( *buffer + offset ).... so?


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Wed Sep 11, 2019 10:18 pm 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4308
Location: Germany
Code:
Procedure.i next_ts_in_chain(*di.DiskImageStructure, *ts.TrackSectorStructure)
 
  Protected *p.CharStructure
  Static newts.TrackSectorStructure
 
 
  *p = get_ts_addr(*di, *ts)
  newts\track = *p\c[0]
  newts\sector = *p\c[1]
  If *p\c[0] > di_tracks(*di\type)
    newts\track = 0
    newts\sector = 0
  ElseIf *p\c[1] > di_sectors_per_track(*di\type, *p\c[0])
    newts\track = 0
    newts\sector = 0
  EndIf
 
  ProcedureReturn @newts
 
EndProcedure


Procedure.i find_file_entry(*di.DiskImageStructure, *rawpattern, type.i)
 
  Protected Result.i
  Protected *buffer
  Protected *ts.TrackSectorStructure
  Protected *rde.RawDirEntryStructure
  Protected offset.i
 
  *ts = next_ts_in_chain(*di, *di\bam)
  While *ts\track
    *buffer = get_ts_addr(*di, *ts)
   
    For offset = 0 To 255 Step 32
   
      *rde = *buffer + offset

      If (*rde\type & ~$40) = (type | $80)
   
        If match_pattern(*rawpattern, *rde\rawname)
          Result = *rde
          Break 2
        EndIf
      EndIf
    Next offset
    *ts = next_ts_in_chain(*di, *ts)
  Wend
 
  ProcedureReturn Result
 
EndProcedure


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Thu Sep 12, 2019 9:00 am 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
Super and big thanks fo the Help :D

Image

The Disk Track, Sector, Map is right but it doesn't show the correct filenames.

Progress:

Code:
DeclareModule CBMDiskImage
   
    ; Init Procedures
    Declare.l di_load_image(DiskImageFile$)                         ; Load image INTO ram
    Declare.l di_open(*di, *rawname, type.i, Mode.s)                 ; Open directory for reading
    Declare.i di_title(*di)                                         ; Get image Title
    Declare.i di_name_from_rawname(*name, *rawname )                 ; Convert title to ascii, in combinaion with "di_title(*di)"
    Declare.i di_read(*imgfile, *buffer, len)                       ; Read first block INTO buffer
    Declare.i di_read_directory_blocks(*imgfile)
   
    ; Tools Procdures
    Declare.i vDSK_Get_FreeBlocks(*di)                              ; Return Free Blocks From Image                   
    Declare.s vDSK_Get_TitleHead(*di)                               ; Convert Title to ascii and return the Title Header
    Declare.s vDSK_Get_Title_ID(*di)                                ; Convert ID To ascii and return the ID String
    Declare.s vDSK_Get_Filename(*di, Fullpath = #False)             ; Return the Image Filename (Fullpath = #true: Return the Fullpath)
    Declare.s vDSK_Get_ImageFormat(*di)                             ; Return the Image Format as string
    Declare.i vDSK_Close_Image(*imgfile)
    Declare.i vDSK_Test_BAM(*di)
   
    ; Source Taken and Converted from DiskImagery64
    ; http://lallafa.de/blog/c64-projects/diskimagery64/
    ; https://sourceforge.net/p/diskimagery64/code/HEAD/tree/
   
EndDeclareModule

Module CBMDiskImage
   
    Structure TrackSector
        track.c
        sector.c
    EndStructure 
   
    Structure Rawname
        c.a[17]
    EndStructure
   
    Structure Unused
        c.a[4]
    EndStructure
   
    Structure Image
        b.b
    EndStructure
   
    Structure Diskimage
        filename.s
        filepath.s
        size.i
        Type.s{3}       
        *image     
        bam.TrackSector
        bam2.TrackSector
        dir.TrackSector
        openfiles.i
        blocksfree.i
        modified.i
        status.i
        statusts.TrackSector 
    EndStructure
   
    Structure  Rawdirentry
        nextts.TrackSector
        type.c
        startts.TrackSector
        *rawname.Rawname
        relsidets.TrackSector
        relrecsize.c
        *unused.Unused
        replacetemp.TrackSector
        sizelo.c
        sizehi.c
    EndStructure
   
    Structure  ImageFile
        *diskimage.Diskimage
        *rawdirentry.Rawdirentry         
        mode.s
        position.i
        ts.TrackSector
        nextts.TrackSector         
        *buffer.CharBuffer
        bufptr.i
        buflen.i
    EndStructure 
   
    Structure UnsignedChar
        b.b[0]
        c.c[0]
    EndStructure 
   
    Structure char
        c.a[17]
    EndStructure
   
    Structure ptoa
        c.a[17]
    EndStructure
   
    Structure rawpattern
        c.a[17]
    EndStructure   
   
    Structure CharBuffer
        c.a[254]
    EndStructure
   
   
    Macro LoadDiskImage(diFileName, diFileSize)
       
        *di\image = AllocateMemory(diFileSize)
       
        Define DiskImage = OpenFile( #PB_Any, diFileName )
        If DiskImage
            While Not Eof( DiskImage )             
                ReadData(DiskImage, *di\image, diFileSize)
            Wend
            CloseFile(DiskImage)
        EndIf
    EndMacro
    Procedure.s Filetype_Get(type)
       
        Select type
            Case 0:ProcedureReturn "del"
            Case 1:ProcedureReturn "seq"
            Case 2:ProcedureReturn "prg"
            Case 3:ProcedureReturn "usr"                               
            Case 4:ProcedureReturn "rel"
            Case 5:ProcedureReturn "cbm"                                 
            Case 6:ProcedureReturn "dir"                                                               
            Default
                ProcedureReturn "???"
        EndSelect       
    EndProcedure       
   
    Procedure.i Filetype(type)
       
        Select type
            Case 0:ProcedureReturn 0; ftype = "del"
            Case 1:ProcedureReturn 1; ftype = "seq"
            Case 2:ProcedureReturn 2; ftype = "prg"
            Case 3:ProcedureReturn 3; ftype = "usr"                               
            Case 4:ProcedureReturn 4; ftype = "rel"
            Case 5:ProcedureReturn 5; ftype = "cbm"                                 
            Case 6:ProcedureReturn 6; ftype = "dir"                                                               
        EndSelect
       
    EndProcedure       
;---------------------------------------------------------------------------------------------------------
; /* convert Pet to Ascii */
;---------------------------------------------------------------------------------------------------------       
    Procedure pettoascii(*s.char, *c.ptoa)
       
        For i = 0 To 15
            *c\c[i] = *s\c[i]
            *c\c[i] & $7f;
           
            If (*c\c[i] >= 'A' And *c\c[i] <= 'Z' )
                *c\c[i] + 32
            ElseIf   (*c\c[i] >= 'a' And *c\c[i] <= 'z' )
                *c\c[i] - 32
            ElseIf (*c\c[i] = $7f)
                *c\c[i] = $3f                           
            EndIf                   
        Next i   
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
; /* convert to rawname */
;---------------------------------------------------------------------------------------------------------       
   
    Procedure.i di_rawname_from_name(*rawname.Rawname, *name.char)               
        FillMemory( *rawname, 16, $a0)           
        For i = 0 To 15
            *rawname\c[i] = *name\c[i]
        Next     
       
        ProcedureReturn i       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
; /* convert from rawname */
;---------------------------------------------------------------------------------------------------------   
    Procedure.i di_name_from_rawname(*name.char, *rawname.Rawname)
       
        Protected TitleLenght.i, s.s
       
        For TitleLenght = 0 To 15
            If *rawname\c[TitleLenght] = $a0
                Break
            EndIf
            *name\c[TitleLenght] = *rawname\c[TitleLenght]               
           
            ;Debug s.s + Chr(*name\c[TitleLenght])
           
        Next TitleLenght
        *name\c[TitleLenght] = 0       
       
        ProcedureReturn TitleLenght       

    EndProcedure
;---------------------------------------------------------------------------------------------------------
; /* return number of tracks for image type *
;---------------------------------------------------------------------------------------------------------
    Procedure.i set_status(*di.DiskImage, status.i, track.i, sector.i)       
        *di\status          = status
        *di\statusts\track  = track     
        *di\statusts\sector = sector
        ProcedureReturn status       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
; /* return write interleave */
;---------------------------------------------------------------------------------------------------------
    Procedure.i interleave(Type.s)       
        Select Type
            Case "D64": ProcedureReturn 10
            Case "D71": ProcedureReturn 6
            Case "D81": ProcedureReturn 1
            Default
        EndSelect       
    EndProcedure 
       
;---------------------------------------------------------------------------------------------------------
; /* return number of tracks for image type *
;--------------------------------------------------------------------------------------------------------- 
    Procedure.i di_tracks(*di.DiskImage)       
        Select *di\Type
            Case "D64": ProcedureReturn 35
            Case "D71": ProcedureReturn 70
            Case "D81": ProcedureReturn 80
                Default:ProcedureReturn 0
        EndSelect               
    EndProcedure 
;---------------------------------------------------------------------------------------------------------
; /* return disk geometry for track */
;---------------------------------------------------------------------------------------------------------
    Procedure.i di_sectors_per_track(*di.DiskImage, track.i)
       
        Select *di\Type
            Case "D64"
                If (track < 18)     :ProcedureReturn 21
                ElseIf (track < 25) :ProcedureReturn 19
                ElseIf (track < 31) :ProcedureReturn 18
                Else
                    ProcedureReturn 17
                EndIf
               
            Case "D71"
                If (track > 35)
                    track - 35
                EndIf
               
            Case "D81": ProcedureReturn 40
               
            Default
                ; No Supportet
                ProcedureReturn 0
        EndSelect
       
    EndProcedure
;---------------------------------------------------------------------------------------------------------
    ; /* convert track, sector to blocknum */
;---------------------------------------------------------------------------------------------------------   
    Procedure.i di_get_block_num(*di.DiskImage, *ts.TrackSector)
       
        Protected block.i
       
        Select *di\Type
            Case "D64":
                If (*ts\track < 18)
                   block.i = (*ts\track - 1) * 21
                ElseIf (*ts\track < 25)
                    block.i = (*ts\track - 18) * 19 + 17 * 21
                ElseIf (*ts\track < 31)
                    block.i = (*ts\track - 25) * 18 + 17 * 21 + 7 * 19
                Else
                    block.i = (*ts\track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18
                EndIf   
                ;Debug "Block: " + Str(block + *ts\sector)
                ProcedureReturn  (block + *ts\sector) 
               
             Case "D71":
                If (*ts\track > 35)
                    block = 683;
                    *ts\track - 35
                Else
                    block = 0
                EndIf
               
                If (*ts\track < 18)
                    block + (*ts\track - 1) * 21
                ElseIf (*ts\track < 25)
                    block + (*ts\track - 18) * 19 + 17 * 21
                ElseIf (*ts\track < 31)
                    block + (*ts\track - 25) * 18 + 17 * 21 + 7 * 19
                Else
                    block + (*ts\track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18
                EndIf 
                ProcedureReturn (block + *ts\sector)
               
            Case "D81":
                ProcedureReturn ( (*ts\track - 1) * 40 + *ts\sector)
            Default:
                ProcedureReturn 0
        EndSelect   
       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
    ; /* get a pointer to block data */
;---------------------------------------------------------------------------------------------------------     
    Procedure.i get_ts_addr(*di.DiskImage,  *ts.TrackSector)               
        ProcedureReturn ( *di\Image + di_get_block_num(*di, *ts) * 256 )
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
    ; /* return a pointer to the next block in the chain */
;---------------------------------------------------------------------------------------------------------
    Procedure.i next_ts_in_chain(*di.DiskImage,  *ts.TrackSector)
 
        Define *p.UnsignedChar
       
        Static newts.TrackSector

        *p = get_ts_addr(*di, *ts)
        newts\track  = *p\b[0]
        newts\sector = *p\b[1]
       
        If ( *p\b[0] > di_tracks(*di) )
            newts\track     = 0
            newts\sector    = 0
        ElseIf ( *p\b[1] > di_sectors_per_track(*di, *p\b[0] ) )
            newts\track     = 0
            newts\sector    = 0
        EndIf
       ProcedureReturn @newts
       
    EndProcedure
;---------------------------------------------------------------------------------------------------------
    ; /* return a pointer to the disk title */
;---------------------------------------------------------------------------------------------------------   
    Procedure di_title(*di.DiskImage)
        Select (*di\Type)
            Case "D64": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 144)
            Case "D71": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 144)
            Case "D81": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 4)
            Default:
                ; Not Support
                ProcedureReturn 0
        EndSelect
     EndProcedure
;---------------------------------------------------------------------------------------------------------
    ; /* return number of free blocks in track */
;---------------------------------------------------------------------------------------------------------   
    Procedure.l di_track_blocks_free(*di.DiskImage, track.i)
               
        Define *bam.UnsignedChar
       
        Select *di\Type
            Case "D64":
                *bam = get_ts_addr(*di, *di\bam)
               
            Case "D71":
                *bam = get_ts_addr(*di, *di\bam)
                If (track >= 36)
                   ProcedureReturn ( *bam\b [track + 185] )
               EndIf 
               
            Case "D81":
                If (track <= 40)
                    *bam = get_ts_addr(*di, *di\bam);
                Else
                    *bam = get_ts_addr(*di, *di\bam2);
                    track - 40                       ;
                EndIf
                ProcedureReturn ( *bam\b[track * 6 + 10]);               
            Default
        EndSelect       
       
        ProcedureReturn ( *bam\b [track * 4]  )       
    EndProcedure   
       
;---------------------------------------------------------------------------------------------------------
    ; count number of free blocks
;---------------------------------------------------------------------------------------------------------   
    Procedure.i blocks_free(*di.DiskImage)       
        Protected Track.i, Blocks.i = 0
       
        For Track = 1 To di_tracks(*di.DiskImage)           
            If ( Track <> *di\dir\track )
                Blocks + di_track_blocks_free(*di, Track)
            EndIf
        Next
        ProcedureReturn Blocks
    EndProcedure
   
;---------------------------------------------------------------------------------------------------------
; /* check If track, sector is free IN BAM */
;---------------------------------------------------------------------------------------------------------
    Procedure.i di_is_ts_free( *di.DiskImage, *ts.TrackSector)
       
        Protected mask.l
        Define *bam.UnsignedChar
       
        Select *di\Type
            Case "D64"               
                *bam = get_ts_addr(*di, *di\bam)
               
                If ( *bam\b[ *ts\track * 4 ] )
                    mask = 1 << ( *ts\sector & 7)
                    If ( mask )
                        ProcedureReturn (*bam\b[*ts\track * 4 + *ts\sector / 8 + 1] & mask)
                    Else
                        ProcedureReturn (*bam\b[*ts\track * 4 + *ts\sector / 8 + 1])
                    EndIf   
                Else
                    ProcedureReturn 0
                EndIf
     
            Case "D71"
            Case "D81"
            Default
                ; NOT SUPPORT
                ProcedureReturn 0
         EndSelect       
       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
    ; /* Load image into ram */
;---------------------------------------------------------------------------------------------------------
    Procedure.l di_load_image(DiskImageFile$)
               
        *di.DiskImage = AllocateMemory(SizeOf(DiskImage))
        InitializeStructure(*di, DiskImage)
       
        Protected ImageFileSize.i
       
        ImageFileSize = FileSize( DiskImageFile$ )
        Select ImageFileSize
            Case 174848         ; // standard D64
                *di\Type       = "D64"
                *di\bam\track  = 18
                *di\bam\sector = 0
                *di\dir        = *di\bam               
            Case 175531         ; // D64 With error info (which we just ignore)   
                *di\Type       = "D64"
                *di\bam\track  = 18
                *di\bam\sector = 0
                *di\dir        = *di\bam
            Case 349696   
                *di\Type       = "D71"
                *di\bam\track  = 18
                *di\bam\sector = 0
                *di\bam2\track = 53
                *di\bam2\sector= 0
                *di\dir        = *di\bam
            Case 819200
                *di\Type       = "D81"
                *di\bam\track  = 40
                *di\bam\sector = 1
                *di\bam2\track = 40
                *di\bam2\sector= 2
                *di\dir\track  = 40
                *di\dir\sector = 0
            Case 533248   
                *di\Type       = "D80: Not Supportet"               
                ProcedureReturn 0               
            Case 278234
                *di\Type       = "G64: Not Supportet"
                ProcedureReturn 0
            Case 667476
                *di\Type       = "G71: Not Supportet"               
                ProcedureReturn 0   
            Case 174912
                *di\Type       = "X64: Not Supportet"               
                ProcedureReturn 0
            Case 1066496
                *di\Type       = "D82: Not Supportet"               
                ProcedureReturn 0                               
            Case 0
                *di\Type = "Images has 0 Bytes"
                ProcedureReturn 0
            Case -1
                *di\Type = "Image " + DiskImageFile$ + "Not Found"
                ProcedureReturn -1
            Case -2   
                *di\Type = "Mismatch Error"               
                ProcedureReturn -2               
            Default
                *di\Type = GetExtensionPart(DiskImageFile$) + " Not Supportet"               
                ProcedureReturn 0
        EndSelect
                       
        LoadDiskImage(DiskImageFile$, ImageFileSize)
       
        ;Debug ShowMemoryViewer(*di\image, ImageFileSize)
       
        *di\filename    = GetFilePart(DiskImageFile$)
        *di\filepath    = GetPathPart(DiskImageFile$)
        *di\openfiles   = 0
        *di\blocksfree  = blocks_free(*di);
        *di\modified    = 0               ;
        set_status(*di, 254, 0, 0);
       
        ProcedureReturn *di.DiskImage
       
    EndProcedure   
   
;---------------------------------------------------------------------------------------------------------
; NOT FINISHED
;---------------------------------------------------------------------------------------------------------
    Procedure.l alloc_next_ts(*di.DiskImage, *prevts.TrackSector)
       
        Protected spt.i, s1.i, s2.i, t1.i, t2.i, bpt.i, boff.i, res1.i, res2.i, tsTrack.i       
        Define *bam.UnsignedChar               
        Static *ts.TrackSector
               
        Select *di\Type
            Case "D64"
                s1      =  1
                t1      = 35
                s2      =  1
                t2      = 35
                res1    = 18
                res2    =  0
                bpt     =  4
                boff    =  0
            Case "D71"
                s1      =  1
                t1      = 35
                s2      = 36
                t2      = 70
                res1    = 18
                res2    = 53
                bpt     =  4
                boff    =  0
            Case "D81"
                s1      =  1
                t1      = 40
                s2      = 41
                t2      = 80
                res1    = 40
                res2    =  0
                bpt     =  6
                boff    = 10               
            Default
                ; Not Support
        EndSelect
       
        *bam = get_ts_addr(*di, *di\bam)
       
        tsTrack = *ts\track
        For tsTrack = s1 To t1           
            If (tsTrack ! res1)               
                If  (*bam\b [ tsTrack * bpt + boff ] )                   
                    *ts\track   = tsTrack
                    spt         = di_sectors_per_track(*di, *ts\track)
                    *ts\sector  = (*prevts\sector + interleave ( *di\type) ) % spt                                                           
                EndIf                   
            EndIf               
        Next tsTrack       
       
        *ts\track   = 0
        *ts\sector  = 0       
        ProcedureReturn *ts.TrackSector     
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
;
;---------------------------------------------------------------------------------------------------------
    Procedure.i match_pattern(*rawpattern.rawpattern, *rawname.char)       
    Protected i.i     
        For i = 0 To 15                       
            If *rawpattern\c[i] = '*'                 
                 ProcedureReturn 1               
             EndIf                       
             If (*rawname\c[i] = $a0 )
                If (*rawpattern\c[i] = $a0)
                     ProcedureReturn 1
                 Else
                     ProcedureReturn  0
                 EndIf
             Else
                 If (*rawpattern\c[i] = '?' ) Or ( *rawpattern\c[i] = *rawname\c[i] )
                 Else
                     ProcedureReturn 0
                 EndIf
             EndIf
             ProcedureReturn 1 
       Next i       
    EndProcedure
;---------------------------------------------------------------------------------------------------------
    ;
;---------------------------------------------------------------------------------------------------------   
    Procedure.l find_file_entry(*di.DiskImage, *rawpattern, type.i)
       
        Protected offset.i
       
        Define *p.UnsignedChar, *buffer.UnsignedChar               
        Static *rde.RawDirEntry, ts.TrackSector       
       
        *p = next_ts_in_chain(*di, *di\bam);
        ts\track  = *p\b[0]
        ts\sector = *p\b[1]
       
        While (ts\track)           
            *buffer = get_ts_addr(*di, @ts);
           
            For offset = 0 To 255 Step 32
   
                *rde = *buffer + offset
                               
                If (*rde\type & ~$40) = (Filetype(type) | $80)
                   
                   If ( match_pattern(*rawpattern, *rde\rawname) )
                       ProcedureReturn *rde
                   EndIf

               EndIf 
              
                *p = next_ts_in_chain(*di, @ts);
                ts\track  = *p\b[0]
                ts\sector = *p\b[1]                 
            Next                                   
        Wend
        ProcedureReturn 0
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
; Not yet finished
;---------------------------------------------------------------------------------------------------------     
    Procedure.l alloc_file_entry(*di.DiskImage, *rawname.char, type.i)
       
        type = Filetype(type)
       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
    ; /* open a file */
;---------------------------------------------------------------------------------------------------------       
    Procedure.l di_open(*di.DiskImage, *rawname.char, type.i, Mode.s)
       
        If ( *di = 0 )
            ProcedureReturn 0
        ElseIf  ( *di = -1 )
            ProcedureReturn -1
        ElseIf  ( *di = -2 )           
            ProcedureReturn -2
        EndIf   
           
        *imgfile.ImageFile = AllocateMemory( SizeOf(ImageFile)  )
        InitializeStructure(*imgfile, ImageFile)
       
        *rde.RawDirEntry   = AllocateMemory( SizeOf(RawDirEntry))
        InitializeStructure(*rde, RawDirEntry)
       
        type = Filetype(type)
       
        Define *p.UnsignedChar
       
        set_status(*di, 255, 0, 0);
       
        Select Mode
            Case "rb"
               
                If ( *rawname = '$' )
                    *imgfile\mode = "r"
                    *imgfile\ts   = *di\dir
                   
                    *p = get_ts_addr(*di, *di\dir)
                    *imgfile\buffer = *p + 2;
                   
                    Select *di\type
                        Case "D64"
                            *imgfile\nextts\track = 18  ; // 1541/71 ignores bam t/s link
                            *imgfile\nextts\sector = 1  ;
                        Case "D71"
                            *imgfile\nextts\track = 18  ; // 1541/71 ignores bam t/s link
                            *imgfile\nextts\sector = 1  ;                           
                        Case "D81"
                            *imgfile\nextts\track = *p\c[0]
                            *imgfile\nextts\sector =*p\c[1]                           
                        Default
                            ; No Supportet and NULL
                    EndSelect
                    *imgfile\buflen = 254;                   
                    *rde = 0                               
                Else
                   
                    *rde = find_file_entry(*di, *rawname, Filetype(type))
                    If ( *rde = 0 )
                        set_status(*di, 62, 0, 0);
                        FreeMemory(*imgfile)   
                        ProcedureReturn 0
                    EndIf
                   
                   
                    *imgfile\mode = "r"
                    *imgfile\ts = *rde\startts
               
                    If (*imgfile\ts\track > di_tracks(*di))
                        ProcedureReturn 0
                    EndIf   
                   
                    *p = get_ts_addr(*di, *rde\startts)
                   
                    *imgfile\buffer        = *p + 2
                   
                    *imgfile\nextts\track  = *p\c[0]
                    *imgfile\nextts\sector = *p\c[1]
                   
                   
                    If (*imgfile\nextts\track = 0)
                        *imgfile\buflen = *imgfile\nextts\sector - 1
                    Else
                        *imgfile\buflen = 254
                    EndIf                     
                                       
                EndIf         
            Case "wb"   
            Default
        EndSelect

        *imgfile\diskimage      = *di
        *imgfile\rawdirentry    = *rde
        *imgfile\position       = 0
        *imgfile\bufptr         = 0
       
        *di\openfiles           + 1
       
        set_status(*di, 0, 0, 0)
       
        ProcedureReturn *imgfile
    EndProcedure 
;---------------------------------------------------------------------------------------------------------
; ;   /* Read first block INTO buffer */
;---------------------------------------------------------------------------------------------------------       
    Procedure.i di_read(*imgfile.ImageFile, *buffer.CharBuffer, len.i)
       
        Define *p.UnsignedChar , bytesleft.i ,  counter.i = 0
        Static *tts.TrackSector
       
        While len.i
            bytesleft.i = *imgfile\buflen - *imgfile\bufptr
           
            If (bytesleft.i = 0)
               
                If (*imgfile\nextts\track = 0)
                    ProcedureReturn counter
                EndIf
               
                If ( *imgfile\diskimage\Type = "D64") Or  ( *imgfile\diskimage\Type = "D71") And  ( *imgfile\ts\track = 18) And (*imgfile\ts\sector = 0)
                    *imgfile\ts\track  = 18
                    *imgfile\ts\sector = 1
                Else          
                    *tts = next_ts_in_chain(*imgfile\diskimage, *imgfile\ts)
                    *imgfile\ts\sector = *tts\sector
                    *imgfile\ts\track  = *tts\track
                EndIf
               
                If (*imgfile\ts\track = 0)
                    ProcedureReturn counter
                EndIf
               
                *p = get_ts_addr(*imgfile\diskimage,  *imgfile\ts);
                *imgfile\buffer        = *p + 2
                *imgfile\nextts\track  = *p\c[0]
                *imgfile\nextts\sector = *p\c[1]
               
                If (*imgfile\nextts\track = 0)
                    *imgfile\buflen = *imgfile\nextts\sector - 1
                Else
                    *imgfile\buflen = 254
                EndIf
               
                *imgfile\bufptr        = 0
                        
            Else
                If (len.i >= bytesleft.i)
                    While bytesleft.i
                        *buffer + 1
                        *buffer = *imgfile\buffer\c[ *imgfile\bufptr +1 ]
                        len         - 1
                        bytesleft   - 1
                        counter     + 1
                        *imgfile\position + 1
                    Wend                                                               
                Else   
                    While len.i
                        *buffer + 1
                        *buffer = *imgfile\buffer\c[ *imgfile\bufptr +1 ]
                        len         - 1
                        bytesleft   - 1
                        counter     + 1
                        *imgfile\position + 1
                    Wend
                EndIf   
            EndIf
        Wend
       
        ProcedureReturn counter
       
    EndProcedure 
   
;---------------------------------------------------------------------------------------------------------
    ; /* Openfile */
;---------------------------------------------------------------------------------------------------------
    Procedure.i cbmfile_read(*imgfile.ImageFile, *name.char, FileType.i)   
       
        *imgfile = di_open(*imgfile\diskimage, @*buffer, ftype ,"rb")
       
        C64FileLenght.i = di_rawname_from_name(@rawname.Rawname, *name)
       
       
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
    ; /* Read directory blocks */
;---------------------------------------------------------------------------------------------------------     
   Procedure.i di_read_directory_blocks(*imgfile.ImageFile)
               
        Protected offset.i, type.i, closed.i, locked.i, size.i, C64FileLen.i, C64File.s, ftype.s
       
        Structure BufferChar
            c.a[254]
        EndStructure
       
        Define *buffer.BufferChar
       
        If ( di_read(*imgfile, @*buffer, 254) ! 254)           
            Debug "BAM Read failed"
            ProcedureReturn 0
        EndIf       
        ;/* Read directory blocks */
            While ( di_read(*imgfile, @*buffer, 254) = 254)               
                *buffer =  @*buffer                   
                For offset = -2 To 254 Step 32               
                                       
                    ; If file type != 0                     
                    If (*buffer\c[ offset+2 ]! 0)
                        C64FileLen = di_name_from_rawname(@name.char, *buffer +  offset + 5)
 
                        type    = *buffer\c[ offset +2] & $7
                        ftype   = Filetype_Get(type)
                       
                        ;cbmfile_read(*imgfile,@name.char, type)
                                                                           
                        closed  = *buffer\c[ offset +2 ] & $80    ; // closed/locked file?
                        locked  = *buffer\c[ offset +2 ] & $40    ; // closed/locked file?
                        size    = *buffer\c[ offset + 31 ] << $8 | *buffer\c[ offset + 30 ]; // blocks size

                        If ( closed ) : ftype = "*"+ftype: Else: ftype = " "+ftype: EndIf                       
                        If ( locked ) : ftype + "<"      : Else: ftype + " "      : EndIf     
                                                       
                        ; /* Convert To ascii  */                       
                        pettoascii(@name,@ptoa.ptoa)
                        C64File.s = PeekS(@ptoa, C64FileLen -1, #PB_Ascii )                       
                        Debug C64File + ftype
                    EndIf   
                   
                    Debug offset
                Next offset                               
            Wend                   
    EndProcedure   
;---------------------------------------------------------------------------------------------------------
;
;---------------------------------------------------------------------------------------------------------
    Procedure di_close(*imgfile.ImageFile)
       
        Define *p.UnsignedChar
        Static *tts.TrackSector
       
        Select *imgfile\mode
            Case "w"
               
                If (*imgfile\bufptr)
                   
                    If (*imgfile\diskimage\blocksfree)
                                                                       
                        *tts = alloc_next_ts(*imgfile\diskimage, *imgfile\ts)
                       
                        *imgfile\nextts\sector = *tts\sector
                        *imgfile\nextts\track = *tts\track
                       
                        If (*imgfile\ts\track = 0)
                            *imgfile\rawdirentry\startts = *imgfile\nextts
                        Else
                            *p = get_ts_addr(*imgfile\diskimage, *imgfile\ts)
                            *p\c[0] = *imgfile\nextts\track
                            *p\c[1] = *imgfile\nextts\sector
                        EndIf
                       
                        *imgfile\ts = *imgfile\nextts
                       
                        *p = get_ts_addr(*imgfile\diskimage, *imgfile\ts)
                        *p\c[0] = 0
                        *p\c[1] = $ff
                       
                        CopyMemory(*imgfile\buffer , *p + 2, 254)
                       
                        *imgfile\bufptr = 0
                       
                        If ( (*imgfile\rawdirentry\sizelo + 1) = 0 )                           
                             *imgfile\rawdirentry\sizehi + 1
                        EndIf
                       
                        *imgfile\diskimage\blocksfree - 1
                        *imgfile\rawdirentry\type | $80                                             
                    EndIf
                 Else
                     *imgfile\rawdirentry\type | $80                                                               
                 EndIf
                 
                 FreeMemory(*imgfile\buffer)
         EndSelect
         
         *imgfile\diskimage\openfiles - 1
         FreeMemory(*imgfile)                         
     EndProcedure
     
;---------------------------------------------------------------------------------------------------------
; /* Close file */
;---------------------------------------------------------------------------------------------------------         
     Procedure.i vDSK_Close_Image(*imgfile.ImageFile)
         di_close(*imgfile)
         
     EndProcedure
;---------------------------------------------------------------------------------------------------------
; Return Disk Image Format
;---------------------------------------------------------------------------------------------------------         
    Procedure.s vDSK_Get_ImageFormat(*di.DiskImage)
       
        If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
            ProcedureReturn ""
        EndIf
       
        ProcedureReturn *di\Type
         
    EndProcedure     
;---------------------------------------------------------------------------------------------------------
; Return Disk Filename
;---------------------------------------------------------------------------------------------------------         
    Procedure.s vDSK_Get_Filename(*di.DiskImage, Fullpath.i = #False)
       
        If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
            ProcedureReturn ""
        EndIf
       
        Select Fullpath
            Case #False
                ProcedureReturn *di\filename
            Case #True
                ProcedureReturn *di\filepath + *di\filename
        EndSelect           
    EndProcedure         
;---------------------------------------------------------------------------------------------------------
; Return Free Blocks Of the C64 Disk Image
;---------------------------------------------------------------------------------------------------------         
    Procedure.i vDSK_Get_FreeBlocks(*di.DiskImage)
       
        If ( *di = 0 )
            ProcedureReturn 0
        ElseIf  ( *di = -1 )
            ProcedureReturn -1
        ElseIf  ( *di = -2 )           
            ProcedureReturn -2
        EndIf 
       
        ProcedureReturn *di\blocksfree
    EndProcedure         
;---------------------------------------------------------------------------------------------------------
; Get C64 Disk Image Title
;---------------------------------------------------------------------------------------------------------       
    Procedure.s vDSK_Get_TitleHead(*di.DiskImage)
       
        Protected TitleLenght.i = 0, Title.s = ""
       
        If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
            ProcedureReturn ""
        EndIf
       
         ;Convert title To ascii
        TitleLenght.i = di_name_from_rawname(@name.char, CBMDiskImage::di_title(*di) )
       
        pettoascii(@name,@ptoa.ptoa)
       
        Title.s = PeekS(@ptoa, TitleLenght +1,#PB_Ascii )
        Title.s = LSet( Title.s, 16, Chr(32) )

        ProcedureReturn Title.s
    EndProcedure 
;---------------------------------------------------------------------------------------------------------
; Get C64 Disk Image ID
;---------------------------------------------------------------------------------------------------------       
    Procedure.s vDSK_Get_Title_ID(*di.DiskImage)
       
        Protected TitleLenght.i = 0, ident.s = ""
       
        If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
            ProcedureReturn ""
        EndIf
       
        CopyMemory(di_title(*di) +18 , @id.char, 5)    ; Convert ID To ascii
       
        pettoascii(@id,@ptoa.ptoa)
       
        ident.s = PeekS(@ptoa, 4 +1,#PB_Ascii )
       
        ProcedureReturn ident.s       
    EndProcedure     
;---------------------------------------------------------------------------------------------------------
; Test BAM
;---------------------------------------------------------------------------------------------------------   
    Procedure vDSK_Test_BAM(*di.DiskImage)
       
        Protected FreeSector.i
        Debug "Track" +#TAB$+ "Free"+#TAB$+"Map"
       
        Static ts.TrackSector
       
        CurrenTrack = ts\track
        CurrenSectr = ts\sector
       
        For CurrenTrack = 1 To di_tracks( *di )           
           
            free.i =  di_track_blocks_free(*di, CurrenTrack)
            sect.i =  di_sectors_per_track(*di, CurrenTrack)           
           
            Free$ = ""
            For CurrenSectr = 0 To di_sectors_per_track(*di, CurrenTrack) -1
                ts\track   = CurrenTrack
                ts\sector  = CurrenSectr
                FreeSector = di_is_ts_free(*di, @ts)
               
                Select FreeSector
                    Case 0
                        Free$ + "*"
                    Default
                        Free$ + "-"                       
                EndSelect                       
            Next
            Debug " "+Str(CurrenTrack) + ":  "+#TAB$+ Str(free)+"/"+Str(sect) +#TAB$+ Free$
        Next       
        Debug ""
        Debug Str( *di\blocksfree ) + " blocks free"
       
       
    EndProcedure 
EndModule
;
; Beispiel 1

    ;   
    ;                               /* Load image INTO ram */
    ;
*di = CBMDiskImage::di_load_image("B:\daten 2 - Kopie.d64")

    ;                       /* Open directory For reading */
    ;
*imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
If ( *imgfile = 0 )
    Debug "Couldn't open directory"
    End
EndIf


    ;
    ;                   
    ;                      /* Convert title To ascii */
        Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
        Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)
        Debug "| --------------------------------| Disk ID |"
        Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
        Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) ) 
        Debug "| Test Bam   : " + #CRLF$
        CBMDiskImage::vDSK_Test_BAM(*di)
        CBMDiskImage::di_read_directory_blocks(*imgfile)       
        Debug "| ---------------------------------------|" +#CRLF$+#CRLF$             
       
       
       
       
;
; Beispiel 2
       
        *di = CBMDiskImage::di_load_image("B:\NEWIMAGE.d64")
        *imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
        Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
        Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
        Debug "| --------------------------------| Disk ID |"
        Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
        Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
        Debug "| Test Bam   : " + #CRLF$
        CBMDiskImage::vDSK_Test_BAM(*di)       
        ;CBMDiskImage::di_read_directory_blocks(*imgfile)
        Debug "| ---------------------------------------|" +#CRLF$+#CRLF$
       
;
; Beispiel 3       
        *di = CBMDiskImage::di_load_image("B:\FUR DIE SCHULE,DiskID-2A  1.d64")
        *imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
        Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
        Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
        Debug "| --------------------------------| Disk ID |"
        Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
        Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) ) 
        Debug "| Test Bam   : " + #CRLF$
        CBMDiskImage::vDSK_Test_BAM(*di)           
        Debug "| ---------------------------------------|" +#CRLF$+#CRLF$
;         
; ;
; ; Beispiel 4       
        *di = CBMDiskImage::di_load_image("B:\      NEWI  MAGE.D64")
        *imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
        Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
        Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
        Debug "| --------------------------------| Disk ID |"
        Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
        Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
        Debug "| Test Bam   : " + #CRLF$
        CBMDiskImage::vDSK_Test_BAM(*di)           
        Debug "| ---------------------------------------|" +#CRLF$+#CRLF$


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Thu Sep 12, 2019 9:46 pm 
Offline
Addict
Addict

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 4308
Location: Germany
Code:
DeclareModule CBMDiskImage
 
  ; Init Procedures
  Declare.l di_load_image(DiskImageFile$)                         ; Load image INTO ram
  Declare.l di_open(*di, *rawname, type.i, Mode.s)                ; Open directory for reading
  Declare.i di_title(*di)                                         ; Get image Title
  Declare.i di_name_from_rawname(*name, *rawname )                ; Convert title to ascii, in combinaion with "di_title(*di)"
  Declare.i di_read(*imgfile, *buffer, len)                       ; Read first block INTO buffer
  Declare.i di_read_directory_blocks(*imgfile)
 
  ; Tools Procdures
  Declare.i vDSK_Get_FreeBlocks(*di)                              ; Return Free Blocks From Image                   
  Declare.s vDSK_Get_TitleHead(*di)                               ; Convert Title to ascii and return the Title Header
  Declare.s vDSK_Get_Title_ID(*di)                                ; Convert ID To ascii and return the ID String
  Declare.s vDSK_Get_Filename(*di, Fullpath = #False)             ; Return the Image Filename (Fullpath = #true: Return the Fullpath)
  Declare.s vDSK_Get_ImageFormat(*di)                             ; Return the Image Format as string
  Declare.i vDSK_Close_Image(*imgfile)
  Declare.i vDSK_Test_BAM(*di)
 
  ; Source Taken and Converted from DiskImagery64
  ; http://lallafa.de/blog/c64-projects/diskimagery64/
  ; https://sourceforge.net/p/diskimagery64/code/HEAD/tree/
 
EndDeclareModule

Module CBMDiskImage
 
  Structure TrackSector
    track.c
    sector.c
  EndStructure
 
  Structure Rawname
    c.a[17]
  EndStructure
 
  Structure Unused
    c.a[4]
  EndStructure
 
  Structure Image
    b.b
  EndStructure
 
  Structure Diskimage
    filename.s
    filepath.s
    size.i
    Type.s{3}       
    *image     
    bam.TrackSector
    bam2.TrackSector
    dir.TrackSector
    openfiles.i
    blocksfree.i
    modified.i
    status.i
    statusts.TrackSector
  EndStructure
 
  Structure  Rawdirentry
    nextts.TrackSector
    type.c
    startts.TrackSector
    *rawname.Rawname
    relsidets.TrackSector
    relrecsize.c
    *unused.Unused
    replacetemp.TrackSector
    sizelo.c
    sizehi.c
  EndStructure
 
  Structure  ImageFile
    *diskimage.Diskimage
    *rawdirentry.Rawdirentry         
    mode.s
    position.i
    ts.TrackSector
    nextts.TrackSector         
    *buffer.CharBuffer
    bufptr.i
    buflen.i
  EndStructure
 
  Structure UnsignedChar
    b.b[0]
    c.c[0]
  EndStructure
 
  Structure char
    c.a[17]
  EndStructure
 
  Structure ptoa
    c.a[17]
  EndStructure
 
  Structure rawpattern
    c.a[17]
  EndStructure   
 
  Structure CharBuffer
    c.a[254]
  EndStructure
 
 
  Macro LoadDiskImage(diFileName, diFileSize)
   
    *di\image = AllocateMemory(diFileSize)
   
    Define DiskImage = OpenFile( #PB_Any, diFileName )
    If DiskImage
      While Not Eof( DiskImage )             
        ReadData(DiskImage, *di\image, diFileSize)
      Wend
      CloseFile(DiskImage)
    EndIf
  EndMacro
 
  Procedure.s Filetype_Get(type)
   
    Select type
      Case 0:ProcedureReturn "del"
      Case 1:ProcedureReturn "seq"
      Case 2:ProcedureReturn "prg"
      Case 3:ProcedureReturn "usr"                               
      Case 4:ProcedureReturn "rel"
      Case 5:ProcedureReturn "cbm"                                 
      Case 6:ProcedureReturn "dir"                                                               
      Default
        ProcedureReturn "???"
    EndSelect       
  EndProcedure       
 
  Procedure.i Filetype(type)
   
    Select type
      Case 0:ProcedureReturn 0; ftype = "del"
      Case 1:ProcedureReturn 1; ftype = "seq"
      Case 2:ProcedureReturn 2; ftype = "prg"
      Case 3:ProcedureReturn 3; ftype = "usr"                               
      Case 4:ProcedureReturn 4; ftype = "rel"
      Case 5:ProcedureReturn 5; ftype = "cbm"                                 
      Case 6:ProcedureReturn 6; ftype = "dir"                                                               
    EndSelect
   
  EndProcedure       
  ;---------------------------------------------------------------------------------------------------------
  ; /* convert Pet to Ascii */
  ;---------------------------------------------------------------------------------------------------------       
  Procedure ptoa(*c.char)
   
    Protected c.a
   
    For i = 0 To 15
      c = *c\c[i]
      If c = 0
        Break
      EndIf
     
      c & $7f
     
      If c >= 'A' And c <= 'Z'
        c + 32
      ElseIf c >= 'a' And c <= 'z'
        c - 32
      ElseIf c = $7f
        c = $3f                           
      EndIf
      *c\c[i] = c
    Next i   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* convert to rawname */
  ;---------------------------------------------------------------------------------------------------------       
 
  Procedure.i di_rawname_from_name(*rawname.Rawname, *name.char)               
    FillMemory( *rawname, 16, $a0)           
    For i = 0 To 15
      *rawname\c[i] = *name\c[i]
    Next     
   
    ProcedureReturn i       
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* convert from rawname */
  ;---------------------------------------------------------------------------------------------------------   
  Procedure.i di_name_from_rawname(*name.char, *rawname.Rawname)
   
    Protected TitleLenght.i, s.s
   
    For TitleLenght = 0 To 15
      If *rawname\c[TitleLenght] = $a0
        Break
      EndIf
      *name\c[TitleLenght] = *rawname\c[TitleLenght]               
     
      ;Debug s.s + Chr(*name\c[TitleLenght])
     
    Next TitleLenght
    *name\c[TitleLenght] = 0       
   
    ProcedureReturn TitleLenght       
   
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; /* return number of tracks for image type *
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i set_status(*di.DiskImage, status.i, track.i, sector.i)       
    *di\status          = status
    *di\statusts\track  = track     
    *di\statusts\sector = sector
    ProcedureReturn status       
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* return write interleave */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i interleave(Type.s)       
    Select Type
      Case "D64": ProcedureReturn 10
      Case "D71": ProcedureReturn 6
      Case "D81": ProcedureReturn 1
      Default
    EndSelect       
  EndProcedure
 
  ;---------------------------------------------------------------------------------------------------------
  ; /* return number of tracks for image type *
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i di_tracks(*di.DiskImage)       
    Select *di\Type
      Case "D64": ProcedureReturn 35
      Case "D71": ProcedureReturn 70
      Case "D81": ProcedureReturn 80
      Default:ProcedureReturn 0
    EndSelect               
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; /* return disk geometry for track */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i di_sectors_per_track(*di.DiskImage, track.i)
   
    Select *di\Type
      Case "D64"
        If (track < 18)     :ProcedureReturn 21
        ElseIf (track < 25) :ProcedureReturn 19
        ElseIf (track < 31) :ProcedureReturn 18
        Else
          ProcedureReturn 17
        EndIf
       
      Case "D71"
        If (track > 35)
          track - 35
        EndIf
       
      Case "D81": ProcedureReturn 40
       
      Default
        ; No Supportet
        ProcedureReturn 0
    EndSelect
   
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; /* convert track, sector to blocknum */
  ;---------------------------------------------------------------------------------------------------------   
  Procedure.i di_get_block_num(*di.DiskImage, *ts.TrackSector)
   
    Protected block.i
   
    Select *di\Type
      Case "D64":
        If (*ts\track < 18)
          block.i = (*ts\track - 1) * 21
        ElseIf (*ts\track < 25)
          block.i = (*ts\track - 18) * 19 + 17 * 21
        ElseIf (*ts\track < 31)
          block.i = (*ts\track - 25) * 18 + 17 * 21 + 7 * 19
        Else
          block.i = (*ts\track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18
        EndIf   
        ;Debug "Block: " + Str(block + *ts\sector)
        ProcedureReturn  (block + *ts\sector)
       
      Case "D71":
        If (*ts\track > 35)
          block = 683;
          *ts\track - 35
        Else
          block = 0
        EndIf
       
        If (*ts\track < 18)
          block + (*ts\track - 1) * 21
        ElseIf (*ts\track < 25)
          block + (*ts\track - 18) * 19 + 17 * 21
        ElseIf (*ts\track < 31)
          block + (*ts\track - 25) * 18 + 17 * 21 + 7 * 19
        Else
          block + (*ts\track - 31) * 17 + 17 * 21 + 7 * 19 + 6 * 18
        EndIf
        ProcedureReturn (block + *ts\sector)
       
      Case "D81":
        ProcedureReturn ( (*ts\track - 1) * 40 + *ts\sector)
      Default:
        ProcedureReturn 0
    EndSelect   
   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* get a pointer to block data */
  ;---------------------------------------------------------------------------------------------------------     
  Procedure.i get_ts_addr(*di.DiskImage,  *ts.TrackSector)               
    ProcedureReturn ( *di\Image + di_get_block_num(*di, *ts) * 256 )
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* return a pointer to the next block in the chain */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i next_ts_in_chain(*di.DiskImage,  *ts.TrackSector)
   
    Define *p.UnsignedChar
   
    Static newts.TrackSector
   
    *p = get_ts_addr(*di, *ts)
    newts\track  = *p\b[0]
    newts\sector = *p\b[1]
   
    If ( *p\b[0] > di_tracks(*di) )
      newts\track     = 0
      newts\sector    = 0
    ElseIf ( *p\b[1] > di_sectors_per_track(*di, *p\b[0] ) )
      newts\track     = 0
      newts\sector    = 0
    EndIf
    ProcedureReturn @newts
   
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; /* return a pointer to the disk title */
  ;---------------------------------------------------------------------------------------------------------   
  Procedure di_title(*di.DiskImage)
    Select (*di\Type)
      Case "D64": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 144)
      Case "D71": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 144)
      Case "D81": ProcedureReturn (get_ts_addr( *di, *di\dir ) + 4)
      Default:
        ; Not Support
        ProcedureReturn 0
    EndSelect
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; /* return number of free blocks in track */
  ;---------------------------------------------------------------------------------------------------------   
  Procedure.l di_track_blocks_free(*di.DiskImage, track.i)
   
    Define *bam.UnsignedChar
   
    Select *di\Type
      Case "D64":
        *bam = get_ts_addr(*di, *di\bam)
       
      Case "D71":
        *bam = get_ts_addr(*di, *di\bam)
        If (track >= 36)
          ProcedureReturn ( *bam\b [track + 185] )
        EndIf
       
      Case "D81":
        If (track <= 40)
          *bam = get_ts_addr(*di, *di\bam);
        Else
          *bam = get_ts_addr(*di, *di\bam2);
          track - 40                       ;
        EndIf
        ProcedureReturn ( *bam\b[track * 6 + 10]);               
      Default
    EndSelect       
   
    ProcedureReturn ( *bam\b [track * 4]  )       
  EndProcedure   
 
  ;---------------------------------------------------------------------------------------------------------
  ; count number of free blocks
  ;---------------------------------------------------------------------------------------------------------   
  Procedure.i blocks_free(*di.DiskImage)       
    Protected Track.i, Blocks.i = 0
   
    For Track = 1 To di_tracks(*di.DiskImage)           
      If ( Track <> *di\dir\track )
        Blocks + di_track_blocks_free(*di, Track)
      EndIf
    Next
    ProcedureReturn Blocks
  EndProcedure
 
  ;---------------------------------------------------------------------------------------------------------
  ; /* check If track, sector is free IN BAM */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i di_is_ts_free( *di.DiskImage, *ts.TrackSector)
   
    Protected mask.l
    Define *bam.UnsignedChar
   
    Select *di\Type
      Case "D64"               
        *bam = get_ts_addr(*di, *di\bam)
       
        If ( *bam\b[ *ts\track * 4 ] )
          mask = 1 << ( *ts\sector & 7)
          If ( mask )
            ProcedureReturn (*bam\b[*ts\track * 4 + *ts\sector / 8 + 1] & mask)
          Else
            ProcedureReturn (*bam\b[*ts\track * 4 + *ts\sector / 8 + 1])
          EndIf   
        Else
          ProcedureReturn 0
        EndIf
       
      Case "D71"
      Case "D81"
      Default
        ; NOT SUPPORT
        ProcedureReturn 0
    EndSelect       
   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* Load image into ram */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.l di_load_image(DiskImageFile$)
   
    *di.DiskImage = AllocateMemory(SizeOf(DiskImage))
    InitializeStructure(*di, DiskImage)
   
    Protected ImageFileSize.i
   
    ImageFileSize = FileSize( DiskImageFile$ )
    Select ImageFileSize
      Case 174848         ; // standard D64
        *di\Type       = "D64"
        *di\bam\track  = 18
        *di\bam\sector = 0
        *di\dir        = *di\bam               
      Case 175531         ; // D64 With error info (which we just ignore)   
        *di\Type       = "D64"
        *di\bam\track  = 18
        *di\bam\sector = 0
        *di\dir        = *di\bam
      Case 349696   
        *di\Type       = "D71"
        *di\bam\track  = 18
        *di\bam\sector = 0
        *di\bam2\track = 53
        *di\bam2\sector= 0
        *di\dir        = *di\bam
      Case 819200
        *di\Type       = "D81"
        *di\bam\track  = 40
        *di\bam\sector = 1
        *di\bam2\track = 40
        *di\bam2\sector= 2
        *di\dir\track  = 40
        *di\dir\sector = 0
      Case 533248   
        *di\Type       = "D80: Not Supportet"               
        ProcedureReturn 0               
      Case 278234
        *di\Type       = "G64: Not Supportet"
        ProcedureReturn 0
      Case 667476
        *di\Type       = "G71: Not Supportet"               
        ProcedureReturn 0   
      Case 174912
        *di\Type       = "X64: Not Supportet"               
        ProcedureReturn 0
      Case 1066496
        *di\Type       = "D82: Not Supportet"               
        ProcedureReturn 0                               
      Case 0
        *di\Type = "Images has 0 Bytes"
        ProcedureReturn 0
      Case -1
        *di\Type = "Image " + DiskImageFile$ + "Not Found"
        ProcedureReturn -1
      Case -2   
        *di\Type = "Mismatch Error"               
        ProcedureReturn -2               
      Default
        *di\Type = GetExtensionPart(DiskImageFile$) + " Not Supportet"               
        ProcedureReturn 0
    EndSelect
   
    LoadDiskImage(DiskImageFile$, ImageFileSize)
   
    ;Debug ShowMemoryViewer(*di\image, ImageFileSize)
   
    *di\filename    = GetFilePart(DiskImageFile$)
    *di\filepath    = GetPathPart(DiskImageFile$)
    *di\openfiles   = 0
    *di\blocksfree  = blocks_free(*di);
    *di\modified    = 0               ;
    set_status(*di, 254, 0, 0)        ;
   
    ProcedureReturn *di.DiskImage
   
  EndProcedure   
 
  ;---------------------------------------------------------------------------------------------------------
  ; NOT FINISHED
  ;---------------------------------------------------------------------------------------------------------
  Procedure.l alloc_next_ts(*di.DiskImage, *prevts.TrackSector)
   
    Protected spt.i, s1.i, s2.i, t1.i, t2.i, bpt.i, boff.i, res1.i, res2.i, tsTrack.i       
    Define *bam.UnsignedChar               
    Static *ts.TrackSector
   
    Select *di\Type
      Case "D64"
        s1      =  1
        t1      = 35
        s2      =  1
        t2      = 35
        res1    = 18
        res2    =  0
        bpt     =  4
        boff    =  0
      Case "D71"
        s1      =  1
        t1      = 35
        s2      = 36
        t2      = 70
        res1    = 18
        res2    = 53
        bpt     =  4
        boff    =  0
      Case "D81"
        s1      =  1
        t1      = 40
        s2      = 41
        t2      = 80
        res1    = 40
        res2    =  0
        bpt     =  6
        boff    = 10               
      Default
        ; Not Support
    EndSelect
   
    *bam = get_ts_addr(*di, *di\bam)
   
    tsTrack = *ts\track
    For tsTrack = s1 To t1           
      If tsTrack <> res1
        If  *bam\b [ tsTrack * bpt + boff ]
          *ts\track   = tsTrack
          spt         = di_sectors_per_track(*di, *ts\track)
          *ts\sector  = (*prevts\sector + interleave ( *di\type) ) % spt                                                           
        EndIf                   
      EndIf               
    Next tsTrack       
   
    *ts\track   = 0
    *ts\sector  = 0       
    ProcedureReturn *ts.TrackSector     
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ;
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i match_pattern(*rawpattern.rawpattern, *rawname.char)       
    Protected i.i     
    For i = 0 To 15                       
      If *rawpattern\c[i] = '*'                 
        ProcedureReturn 1               
      EndIf                       
      If (*rawname\c[i] = $a0 )
        If (*rawpattern\c[i] = $a0)
          ProcedureReturn 1
        Else
          ProcedureReturn  0
        EndIf
      Else
        If (*rawpattern\c[i] = '?' ) Or ( *rawpattern\c[i] = *rawname\c[i] )
        Else
          ProcedureReturn 0
        EndIf
      EndIf
      ProcedureReturn 1
    Next i       
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ;
  ;---------------------------------------------------------------------------------------------------------   
  Procedure.l find_file_entry(*di.DiskImage, *rawpattern, type.i)
   
    Protected offset.i
   
    Define *p.UnsignedChar, *buffer.UnsignedChar               
    Static *rde.RawDirEntry, ts.TrackSector       
   
    *p = next_ts_in_chain(*di, *di\bam);
    ts\track  = *p\b[0]
    ts\sector = *p\b[1]
   
    While (ts\track)           
      *buffer = get_ts_addr(*di, @ts);
     
      For offset = 0 To 255 Step 32
       
        *rde = *buffer + offset
       
        If (*rde\type & ~$40) = (Filetype(type) | $80)
         
          If ( match_pattern(*rawpattern, *rde\rawname) )
            ProcedureReturn *rde
          EndIf
         
        EndIf
       
        *p = next_ts_in_chain(*di, @ts);
        ts\track  = *p\b[0]
        ts\sector = *p\b[1]                 
      Next                                   
    Wend
    ProcedureReturn 0
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; Not yet finished
  ;---------------------------------------------------------------------------------------------------------     
  Procedure.l alloc_file_entry(*di.DiskImage, *rawname.char, type.i)
   
    type = Filetype(type)
   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* open a file */
  ;---------------------------------------------------------------------------------------------------------       
  Procedure.l di_open(*di.DiskImage, *rawname.char, type.i, Mode.s)
   
    If ( *di = 0 )
      ProcedureReturn 0
    ElseIf  ( *di = -1 )
      ProcedureReturn -1
    ElseIf  ( *di = -2 )           
      ProcedureReturn -2
    EndIf   
   
    *imgfile.ImageFile = AllocateMemory( SizeOf(ImageFile)  )
    InitializeStructure(*imgfile, ImageFile)
   
    *rde.RawDirEntry   = AllocateMemory( SizeOf(RawDirEntry))
    InitializeStructure(*rde, RawDirEntry)
   
    type = Filetype(type)
   
    Define *p.UnsignedChar
   
    set_status(*di, 255, 0, 0);
   
    Select Mode
      Case "rb"
       
        If ( *rawname = '$' )
          *imgfile\mode = "r"
          *imgfile\ts   = *di\dir
         
          *p = get_ts_addr(*di, *di\dir)
          *imgfile\buffer = *p + 2;
         
          Select *di\type
            Case "D64"
              *imgfile\nextts\track = 18  ; // 1541/71 ignores bam t/s link
              *imgfile\nextts\sector = 1  ;
            Case "D71"
              *imgfile\nextts\track = 18  ; // 1541/71 ignores bam t/s link
              *imgfile\nextts\sector = 1  ;                           
            Case "D81"
              *imgfile\nextts\track = *p\c[0]
              *imgfile\nextts\sector =*p\c[1]                           
            Default
              ; No Supportet and NULL
          EndSelect
          *imgfile\buflen = 254;                   
          *rde = 0                               
        Else
         
          *rde = find_file_entry(*di, *rawname, Filetype(type))
          If ( *rde = 0 )
            set_status(*di, 62, 0, 0);
            FreeMemory(*imgfile)   
            ProcedureReturn 0
          EndIf
         
         
          *imgfile\mode = "r"
          *imgfile\ts = *rde\startts
         
          If (*imgfile\ts\track > di_tracks(*di))
            ProcedureReturn 0
          EndIf   
         
          *p = get_ts_addr(*di, *rde\startts)
         
          *imgfile\buffer        = *p + 2
         
          *imgfile\nextts\track  = *p\c[0]
          *imgfile\nextts\sector = *p\c[1]
         
         
          If (*imgfile\nextts\track = 0)
            *imgfile\buflen = *imgfile\nextts\sector - 1
          Else
            *imgfile\buflen = 254
          EndIf                     
         
        EndIf         
      Case "wb"   
      Default
    EndSelect
   
    *imgfile\diskimage      = *di
    *imgfile\rawdirentry    = *rde
    *imgfile\position       = 0
    *imgfile\bufptr         = 0
   
    *di\openfiles           + 1
   
    set_status(*di, 0, 0, 0)
   
    ProcedureReturn *imgfile
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; ;   /* Read first block INTO buffer */
  ;---------------------------------------------------------------------------------------------------------       
  Procedure.i di_read(*imgfile.ImageFile, *buffer.CharBuffer, len.i)
   
    Protected *p.UnsignedChar , bytesleft.i ,  counter.i
    Protected *tts.TrackSector
   
    While len
      bytesleft = *imgfile\buflen - *imgfile\bufptr
     
      If bytesleft = 0
       
        If *imgfile\nextts\track = 0
          ProcedureReturn counter
        EndIf
       
        If (*imgfile\diskimage\Type = "D64" Or *imgfile\diskimage\Type = "D71") And *imgfile\ts\track = 18 And *imgfile\ts\sector = 0
          *imgfile\ts\track  = 18
          *imgfile\ts\sector = 1
        Else         
          *tts = next_ts_in_chain(*imgfile\diskimage, *imgfile\ts)
          *imgfile\ts\sector = *tts\sector
          *imgfile\ts\track  = *tts\track
        EndIf
       
        If (*imgfile\ts\track = 0)
          ProcedureReturn counter
        EndIf
       
        *p = get_ts_addr(*imgfile\diskimage, *imgfile\ts)
        *imgfile\buffer        = *p + 2
        *imgfile\nextts\track  = *p\c[0]
        *imgfile\nextts\sector = *p\c[1]
       
        If (*imgfile\nextts\track = 0)
          *imgfile\buflen = *imgfile\nextts\sector - 1
        Else
          *imgfile\buflen = 254
        EndIf
       
        *imgfile\bufptr = 0
       
      Else
        If len >= bytesleft
          While bytesleft
            ;*buffer + 1
            *buffer\c[counter] = *imgfile\buffer\c[*imgfile\bufptr]
            *imgfile\bufptr + 1
            len         - 1
            bytesleft   - 1
            counter     + 1
            *imgfile\position + 1
          Wend                                                               
        Else   
          While len
            ;*buffer + 1
            *buffer\c[counter] = *imgfile\buffer\c[*imgfile\bufptr]
            *imgfile\bufptr + 1
            len         - 1
            bytesleft   - 1
            counter     + 1
            *imgfile\position + 1
          Wend
        EndIf
      EndIf
    Wend
   
    ProcedureReturn counter
   
  EndProcedure
 
  ;---------------------------------------------------------------------------------------------------------
  ; /* Openfile */
  ;---------------------------------------------------------------------------------------------------------
  Procedure.i cbmfile_read(*imgfile.ImageFile, *name.char, FileType.i)   
   
    *imgfile = di_open(*imgfile\diskimage, @*buffer, ftype ,"rb")
   
    C64FileLenght.i = di_rawname_from_name(@rawname.Rawname, *name)
   
   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ; /* Read directory blocks */
  ;---------------------------------------------------------------------------------------------------------     
  Procedure.i di_read_directory_blocks(*imgfile.ImageFile)
   
    Structure ByteArrayStructure
      c.a[0]
    EndStructure
   
    Protected *buffer.ByteArrayStructure
   
    Protected offset.i, type.i, closed.i, locked.i, size.i, C64FileLen.i, C64File.s, ftype.s
   
    Protected *name.char
    Protected ptoasc.ptoa
   
    *buffer = AllocateMemory(254)
    *name = AllocateMemory(17)
   
   
    If di_read(*imgfile, *buffer, 254) <> 254
      Debug "BAM Read failed"
      ProcedureReturn 0
    EndIf       
    ;/* Read directory blocks */
    While di_read(*imgfile, *buffer, 254) = 254
     
      ShowMemoryViewer(*buffer, 254)
     
      For offset = -2 To 253 Step 32               
       
        ; If file type != 0                     
        If *buffer\c[ offset+2 ]
          C64FileLen = di_name_from_rawname(*name, *buffer +  offset + 5)
         
          type    = *buffer\c[ offset + 2] & 7
          ftype   = Filetype_Get(type)
         
          ;cbmfile_read(*imgfile,@name.char, type)
         
          closed  = *buffer\c[offset + 2] & $80    ; // closed/locked file?
          locked  = *buffer\c[offset + 2] & $40    ; // closed/locked file?
          size    = *buffer\c[offset + 31] << 8 | *buffer\c[offset + 30]; // blocks size
         
          If closed : ftype = "*"+ftype: Else: ftype = " "+ftype: EndIf                       
          If locked : ftype + "<"      : Else: ftype + " "      : EndIf     
         
          ; /* Convert To ascii  */                       
          ptoa(*name)
          C64File.s = PeekS(*name, C64FileLen, #PB_Ascii )                       
          Debug C64File + ftype
        EndIf   
       
        ;Debug offset
      Next offset                               
    Wend                   
  EndProcedure   
  ;---------------------------------------------------------------------------------------------------------
  ;
  ;---------------------------------------------------------------------------------------------------------
  Procedure di_close(*imgfile.ImageFile)
   
    Define *p.UnsignedChar
    Static *tts.TrackSector
   
    Select *imgfile\mode
      Case "w"
       
        If (*imgfile\bufptr)
         
          If (*imgfile\diskimage\blocksfree)
           
            *tts = alloc_next_ts(*imgfile\diskimage, *imgfile\ts)
           
            *imgfile\nextts\sector = *tts\sector
            *imgfile\nextts\track = *tts\track
           
            If (*imgfile\ts\track = 0)
              *imgfile\rawdirentry\startts = *imgfile\nextts
            Else
              *p = get_ts_addr(*imgfile\diskimage, *imgfile\ts)
              *p\c[0] = *imgfile\nextts\track
              *p\c[1] = *imgfile\nextts\sector
            EndIf
           
            *imgfile\ts = *imgfile\nextts
           
            *p = get_ts_addr(*imgfile\diskimage, *imgfile\ts)
            *p\c[0] = 0
            *p\c[1] = $ff
           
            CopyMemory(*imgfile\buffer , *p + 2, 254)
           
            *imgfile\bufptr = 0
           
            If ( (*imgfile\rawdirentry\sizelo + 1) = 0 )                           
              *imgfile\rawdirentry\sizehi + 1
            EndIf
           
            *imgfile\diskimage\blocksfree - 1
            *imgfile\rawdirentry\type | $80                                             
          EndIf
        Else
          *imgfile\rawdirentry\type | $80                                                               
        EndIf
       
        FreeMemory(*imgfile\buffer)
    EndSelect
   
    *imgfile\diskimage\openfiles - 1
    FreeMemory(*imgfile)                         
  EndProcedure
 
  ;---------------------------------------------------------------------------------------------------------
  ; /* Close file */
  ;---------------------------------------------------------------------------------------------------------         
  Procedure.i vDSK_Close_Image(*imgfile.ImageFile)
    di_close(*imgfile)
   
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; Return Disk Image Format
  ;---------------------------------------------------------------------------------------------------------         
  Procedure.s vDSK_Get_ImageFormat(*di.DiskImage)
   
    If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
      ProcedureReturn ""
    EndIf
   
    ProcedureReturn *di\Type
   
  EndProcedure     
  ;---------------------------------------------------------------------------------------------------------
  ; Return Disk Filename
  ;---------------------------------------------------------------------------------------------------------         
  Procedure.s vDSK_Get_Filename(*di.DiskImage, Fullpath.i = #False)
   
    If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
      ProcedureReturn ""
    EndIf
   
    Select Fullpath
      Case #False
        ProcedureReturn *di\filename
      Case #True
        ProcedureReturn *di\filepath + *di\filename
    EndSelect           
  EndProcedure         
  ;---------------------------------------------------------------------------------------------------------
  ; Return Free Blocks Of the C64 Disk Image
  ;---------------------------------------------------------------------------------------------------------         
  Procedure.i vDSK_Get_FreeBlocks(*di.DiskImage)
   
    If ( *di = 0 )
      ProcedureReturn 0
    ElseIf  ( *di = -1 )
      ProcedureReturn -1
    ElseIf  ( *di = -2 )           
      ProcedureReturn -2
    EndIf
   
    ProcedureReturn *di\blocksfree
  EndProcedure         
  ;---------------------------------------------------------------------------------------------------------
  ; Get C64 Disk Image Title
  ;---------------------------------------------------------------------------------------------------------       
  Procedure.s vDSK_Get_TitleHead(*di.DiskImage)
   
    Protected TitleLenght.i = 0, Title.s = ""
   
    If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
      ProcedureReturn ""
    EndIf
   
    ;Convert title To ascii
    TitleLenght.i = di_name_from_rawname(@name.char, CBMDiskImage::di_title(*di) )
   
    ptoa(@name)
   
    Title.s = PeekS(@name, TitleLenght +1,#PB_Ascii )
    Title.s = LSet( Title.s, 16, Chr(32) )
   
    ProcedureReturn Title.s
  EndProcedure
  ;---------------------------------------------------------------------------------------------------------
  ; Get C64 Disk Image ID
  ;---------------------------------------------------------------------------------------------------------       
  Procedure.s vDSK_Get_Title_ID(*di.DiskImage)
   
    Protected TitleLenght.i = 0, ident.s = ""
   
    If ( *di = 0 ) Or ( *di = -1 ) Or ( *di = -2 )
      ProcedureReturn ""
    EndIf
   
    CopyMemory(di_title(*di) +18 , @id.char, 5)    ; Convert ID To ascii
   
    ptoa(@id)
   
    ident.s = PeekS(@id, 4 +1,#PB_Ascii )
   
    ProcedureReturn ident.s       
  EndProcedure     
  ;---------------------------------------------------------------------------------------------------------
  ; Test BAM
  ;---------------------------------------------------------------------------------------------------------   
  Procedure vDSK_Test_BAM(*di.DiskImage)
   
    Protected FreeSector.i
    Debug "Track" +#TAB$+ "Free"+#TAB$+"Map"
   
    Static ts.TrackSector
   
    CurrenTrack = ts\track
    CurrenSectr = ts\sector
   
    For CurrenTrack = 1 To di_tracks( *di )           
     
      free.i =  di_track_blocks_free(*di, CurrenTrack)
      sect.i =  di_sectors_per_track(*di, CurrenTrack)           
     
      Free$ = ""
      For CurrenSectr = 0 To di_sectors_per_track(*di, CurrenTrack) -1
        ts\track   = CurrenTrack
        ts\sector  = CurrenSectr
        FreeSector = di_is_ts_free(*di, @ts)
       
        Select FreeSector
          Case 0
            Free$ + "*"
          Default
            Free$ + "-"                       
        EndSelect                       
      Next
      Debug " "+Str(CurrenTrack) + ":  "+#TAB$+ Str(free)+"/"+Str(sect) +#TAB$+ Free$
    Next       
    Debug ""
    Debug Str( *di\blocksfree ) + " blocks free"
   
   
  EndProcedure
EndModule
;
; Beispiel 1

;   
; Load image INTO ram
;
*di = CBMDiskImage::di_load_image("B:\daten 2 - Kopie.d64")
;*di = CBMDiskImage::di_load_image("d:\Bernd\Extras\tmp\PureBasic\C64\V-1541.D64")

; Open directory For reading
;
*imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
If ( *imgfile = 0 )
  Debug "Couldn't open directory"
  End
EndIf


;
;                   
; Convert title To ascii
Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)
Debug "| --------------------------------| Disk ID |"
Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
Debug "| Test Bam   : " + #CRLF$
CBMDiskImage::vDSK_Test_BAM(*di)
CBMDiskImage::di_read_directory_blocks(*imgfile)       
Debug "| ---------------------------------------|" +#CRLF$+#CRLF$             




;
; Beispiel 2

*di = CBMDiskImage::di_load_image("B:\NEWIMAGE.d64")
*imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
Debug "| --------------------------------| Disk ID |"
Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
Debug "| Test Bam   : " + #CRLF$
CBMDiskImage::vDSK_Test_BAM(*di)       
;CBMDiskImage::di_read_directory_blocks(*imgfile)
Debug "| ---------------------------------------|" +#CRLF$+#CRLF$

;
; Beispiel 3       
*di = CBMDiskImage::di_load_image("B:\FUR DIE SCHULE,DiskID-2A  1.d64")
*imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
Debug "| --------------------------------| Disk ID |"
Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
Debug "| Test Bam   : " + #CRLF$
CBMDiskImage::vDSK_Test_BAM(*di)           
Debug "| ---------------------------------------|" +#CRLF$+#CRLF$
;         
; ;
; ; Beispiel 4       
*di = CBMDiskImage::di_load_image("B:\      NEWI  MAGE.D64")
*imgfile = CBMDiskImage::di_open(*di, '$', 2 ,"rb")
Debug "| Disk   :" + CBMDiskImage::vDSK_Get_Filename(*di)
Debug "| Format :" + CBMDiskImage::vDSK_Get_ImageFormat(*di)       
Debug "| --------------------------------| Disk ID |"
Debug "| Disk Name  :  0 " + Chr(34) + CBMDiskImage::vDSK_Get_TitleHead(*di) + Chr(34)  + " "+CBMDiskImage::vDSK_Get_Title_ID(*di)     
Debug "| Free Blocks: " + Str( CBMDiskImage::vDsk_Get_FreeBlocks(*di) )
Debug "| Test Bam   : " + #CRLF$
CBMDiskImage::vDSK_Test_BAM(*di)           
Debug "| ---------------------------------------|" +#CRLF$+#CRLF$


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Thu Sep 12, 2019 9:48 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
:oops: Thanks infratec :D

PS: Great, I'm watching over the source. Man, I did some things wrong. Many thanks for the help. Listing works.


Top
 Profile  
Reply with quote  
 Post subject: Re: Language C to PB, Trying adapt D64,D71,D80 DiskImage Sou
PostPosted: Fri Sep 13, 2019 6:03 pm 
Offline
User
User

Joined: Thu Mar 13, 2014 4:31 pm
Posts: 15
:mrgreen:

Image

I use a Font *.fon, converted from my Amiga 4000, "Fixplain 7.fnt" and Modified for CBM PetAscii

I Adding now Copy, Write and Format


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye