ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/1541d64.cpp
(Generate patch)

Comparing Frodo4/Src/1541d64.cpp (file contents):
Revision 1.6 by cebix, 2004-01-12T14:31:57Z vs.
Revision 1.9 by cebix, 2004-01-14T16:46:17Z

# Line 1 | Line 1
1   /*
2   *  1541d64.cpp - 1541 emulation in disk image files (.d64/.x64/zipcode)
3   *
4 < *  Frodo (C) 1994-1997,2002-2003 Christian Bauer
4 > *  Frodo (C) 1994-1997,2002-2004 Christian Bauer
5   *  zipcode decoding routines (C) 1993-1997 Marko Mäkelä, Paul David Doherty
6   *
7   *  This program is free software; you can redistribute it and/or modify
# Line 34 | Line 34
34   #include "C64.h"
35   #include "main.h"
36  
37 + #define DEBUG 0
38 + #include "debug.h"
39 +
40  
41   // Channel modes (IRC users listen up :-)
42   enum {
# Line 106 | Line 109 | const int accum_num_sectors[41] = {
109  
110   // Prototypes
111   static bool match(const uint8 *p, int p_len, const uint8 *n);
112 + static FILE *open_image_file(const char *path, bool write_mode);
113 + static bool parse_image_file(FILE *f, image_file_desc &desc);
114  
115  
116   /*
# Line 196 | Line 201 | bool ImageDrive::change_image(const char
201  
202   uint8 ImageDrive::Open(int channel, const uint8 *name, int name_len)
203   {
204 +        D(bug("ImageDrive::Open channel %d, file %s\n", channel, name));
205 +
206          set_error(ERR_OK);
207  
208          // Channel 15: execute file name as command
# Line 237 | Line 244 | uint8 ImageDrive::open_file(int channel,
244          if (plain_name_len > 16)
245                  plain_name_len = 16;
246  
247 +        D(bug(" plain name %s, type %d, mode %d\n", plain_name, type, mode));
248 +
249          // Channel 0 is READ, channel 1 is WRITE
250          if (channel == 0 || channel == 1) {
251                  mode = channel ? FMODE_WRITE : FMODE_READ;
# Line 269 | Line 278 | uint8 ImageDrive::open_file(int channel,
278          if (find_first_file(plain_name, plain_name_len, dir_track, dir_sector, entry)) {
279  
280                  // File exists
281 +                D(bug(" file exists, dir track %d, sector %d, entry %d\n", dir_track, dir_sector, entry));
282                  ch[channel].dir_track = dir_track;
283                  ch[channel].dir_sector = dir_sector;
284                  ch[channel].entry = entry;
# Line 334 | Line 344 | uint8 ImageDrive::open_file(int channel,
344          } else {
345  
346                  // File doesn't exist
347 +                D(bug(" file not found\n"));
348 +
349                  // Set file type to SEQ if not specified in file name
350                  if (type == FTYPE_DEL)
351                          type = FTYPE_SEQ;
# Line 356 | Line 368 | uint8 ImageDrive::open_file(int channel,
368  
369   uint8 ImageDrive::open_file_ts(int channel, int track, int sector)
370   {
371 +        D(bug("open_file_ts track %d, sector %d\n", track, sector));
372 +
373          // Allocate buffer and set channel mode
374          int buf = alloc_buffer(-1);
375          if (buf == -1) {
# Line 381 | Line 395 | uint8 ImageDrive::open_file_ts(int chann
395  
396   uint8 ImageDrive::create_file(int channel, const uint8 *name, int name_len, int type, bool overwrite)
397   {
398 +        D(bug("create_file %s, type %d\n", name, type));
399 +
400          // Allocate buffer
401          int buf = alloc_buffer(-1);
402          if (buf == -1) {
# Line 407 | Line 423 | uint8 ImageDrive::create_file(int channe
423                  return ST_OK;
424          }
425          ch[channel].num_blocks = 1;
426 +        D(bug(" first data block on track %d, sector %d\n", ch[channel].track, ch[channel].sector));
427  
428          // Write directory entry
429          memset(de, 0, SIZEOF_DE);
# Line 629 | Line 646 | uint8 ImageDrive::open_direct(int channe
646  
647   uint8 ImageDrive::Close(int channel)
648   {
649 +        D(bug("ImageDrive::Close channel %d\n", channel));
650 +
651          switch (ch[channel].mode) {
652                  case CHMOD_FREE:
653                          break;
# Line 655 | Line 674 | uint8 ImageDrive::Close(int channel)
674                                  // Write last data block
675                                  ch[channel].buf[0] = 0;
676                                  ch[channel].buf[1] = ch[channel].buf_len - 1;
677 +                                D(bug(" writing last data block\n"));
678                                  if (!write_sector(ch[channel].track, ch[channel].sector, ch[channel].buf))
679                                          goto free;
680  
# Line 672 | Line 692 | uint8 ImageDrive::Close(int channel)
692                                          de[DE_OVR_TRACK] = de[DE_OVR_SECTOR] = 0;
693                                  }
694                                  write_sector(ch[channel].dir_track, ch[channel].dir_sector, dir);
695 +                                D(bug(" directory entry updated\n"));
696                          }
697   free:           free_buffer(ch[channel].buf_num);
698                          ch[channel].buf = NULL;
# Line 710 | Line 731 | void ImageDrive::close_all_channels()
731  
732   uint8 ImageDrive::Read(int channel, uint8 &byte)
733   {
734 + //      D(bug("ImageDrive::Read channel %d\n", channel));
735 +
736          switch (ch[channel].mode) {
737                  case CHMOD_FREE:
738                          if (current_error == ERR_OK)
# Line 735 | Line 758 | uint8 ImageDrive::Read(int channel, uint
758  
759                          // Read next block if necessary
760                          if (ch[channel].buf_len == 0 && ch[channel].buf[0]) {
761 +                                D(bug(" reading next data block track %d, sector %d\n", ch[channel].buf[0], ch[channel].buf[1]));
762                                  if (!read_sector(ch[channel].buf[0], ch[channel].buf[1], ch[channel].buf))
763                                          return ST_READ_TIMEOUT;
764                                  ch[channel].buf_ptr = ch[channel].buf + 2;
# Line 775 | Line 799 | uint8 ImageDrive::Read(int channel, uint
799  
800   uint8 ImageDrive::Write(int channel, uint8 byte, bool eoi)
801   {
802 + //      D(bug("ImageDrive::Write channel %d, byte %02x, eoi %d\n", channel, byte, eoi));
803 +
804          switch (ch[channel].mode) {
805                  case CHMOD_FREE:
806                          if (current_error == ERR_OK)
# Line 814 | Line 840 | uint8 ImageDrive::Write(int channel, uin
840                                  if (!alloc_next_block(track, sector, DATA_INTERLEAVE))
841                                          return ST_TIMEOUT;
842                                  ch[channel].num_blocks++;
843 +                                D(bug("next data block on track %d, sector %d\n", track, sector));
844  
845                                  // Write buffer with link to new block
846                                  ch[channel].buf[0] = track;
# Line 995 | Line 1022 | bool ImageDrive::alloc_dir_entry(int &tr
1022  
1023                  uint8 *de = dir + DIR_ENTRIES;
1024                  for (entry=0; entry<8; entry++, de+=SIZEOF_DE) {
1025 <                        if (de[DE_TYPE] == 0)
1025 >                        if (de[DE_TYPE] == 0) {
1026 >                                D(bug(" allocated entry %d in dir track %d, sector %d\n", entry, track, sector));
1027                                  return true;
1028 +                        }
1029                  }
1030          }
1031  
# Line 1004 | Line 1033 | bool ImageDrive::alloc_dir_entry(int &tr
1033          int last_track = track, last_sector = sector;
1034          if (!alloc_next_block(track, sector, DIR_INTERLEAVE))
1035                  return false;
1036 +        D(bug(" new directory block track %d, sector %d\n", track, sector));
1037  
1038          // Write link to new block to last block
1039          dir[DIR_NEXT_TRACK] = track;
# Line 1074 | Line 1104 | int ImageDrive::alloc_block(int track, i
1104          if (p[byte] & (1 << bit)) {
1105  
1106                  // Yes, allocate and decrement free block count
1107 +                D(bug("allocating block at track %d, sector %d\n", track, sector));
1108                  p[byte] &= ~(1 << bit);
1109                  p[0]--;
1110                  bam_dirty = true;
# Line 1101 | Line 1132 | int ImageDrive::free_block(int track, in
1132          if (!(p[byte] & (1 << bit))) {
1133  
1134                  // Yes, free and increment free block count
1135 +                D(bug("freeing block at track %d, sector %d\n", track, sector));
1136                  p[byte] |= (1 << bit);
1137                  p[0]++;
1138                  bam_dirty = true;
# Line 1262 | Line 1294 | const int conv_job_error[16] = {
1294   };
1295  
1296   // Read sector, return error code
1297 < int read_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer)
1297 > static int read_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer)
1298   {
1299          // Convert track/sector to byte offset in file
1300          long offset = offset_from_ts(desc, track, sector);
# Line 1282 | Line 1314 | int read_sector(FILE *f, const image_fil
1314   }
1315  
1316   // Write sector, return error code
1317 < int write_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer)
1317 > static int write_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer)
1318   {
1319          // Convert track/sector to byte offset in file
1320          long offset = offset_from_ts(desc, track, sector);
# Line 1318 | Line 1350 | bool ImageDrive::write_sector(int track,
1350   }
1351  
1352   // Write error info back to image file
1353 < void write_back_error_info(FILE *f, const image_file_desc &desc)
1353 > static void write_back_error_info(FILE *f, const image_file_desc &desc)
1354   {
1355          if (desc.type == TYPE_D64 && desc.has_error_info) {
1356                  int num_sectors = desc.num_tracks == 40 ? NUM_SECTORS_40 : NUM_SECTORS_35;
# Line 1328 | Line 1360 | void write_back_error_info(FILE *f, cons
1360   }
1361  
1362   // Format disk image
1363 < bool format_image(FILE *f, image_file_desc &desc, bool lowlevel, uint8 id1, uint8 id2, const uint8 *disk_name, int disk_name_len)
1363 > static bool format_image(FILE *f, image_file_desc &desc, bool lowlevel, uint8 id1, uint8 id2, const uint8 *disk_name, int disk_name_len)
1364   {
1365          uint8 p[256];
1366  
# Line 1925 | Line 1957 | error:
1957   *  Open disk image file, return file handle
1958   */
1959  
1960 < FILE *open_image_file(const char *path, bool write_mode)
1960 > static FILE *open_image_file(const char *path, bool write_mode)
1961   {
1962   #if 0
1963          if (is_zipcode_file(path)) {
# Line 2009 | Line 2041 | static bool parse_x64_file(FILE *f, imag
2041          return true;
2042   }
2043  
2044 < bool parse_image_file(FILE *f, image_file_desc &desc)
2044 > static bool parse_image_file(FILE *f, image_file_desc &desc)
2045   {
2046          // Read header
2047          uint8 header[64];
# Line 2031 | Line 2063 | bool parse_image_file(FILE *f, image_fil
2063   }
2064  
2065  
2066 + /*
2067 + *  Read directory of disk image file into (empty) c64_dir_entry vector,
2068 + *  returns false on error
2069 + */
2070 +
2071 + bool ReadImageDirectory(const char *path, vector<c64_dir_entry> &vec)
2072 + {
2073 +        bool result = false;
2074 +
2075 +        // Open file
2076 +        FILE *f = open_image_file(path, false);
2077 +        if (f) {
2078 +                int num_dir_blocks = 0;
2079 +
2080 +                // Determine file type and fill in image_file_desc structure
2081 +                image_file_desc desc;
2082 +                if (!parse_image_file(f, desc))
2083 +                        goto done;
2084 +
2085 +                // Scan all directory blocks
2086 +                uint8 dir[256];
2087 +                dir[DIR_NEXT_TRACK] = DIR_TRACK;
2088 +                dir[DIR_NEXT_SECTOR] = 1;
2089 +
2090 +                while (dir[DIR_NEXT_TRACK] && num_dir_blocks < num_sectors[DIR_TRACK]) {
2091 +                        if (read_sector(f, desc, dir[DIR_NEXT_TRACK], dir[DIR_NEXT_SECTOR], dir) != ERR_OK)
2092 +                                break;
2093 +                        num_dir_blocks++;
2094 +
2095 +                        // Scan all 8 entries of a block
2096 +                        uint8 *de = dir + DIR_ENTRIES;
2097 +                        for (int j=0; j<8; j++, de+=SIZEOF_DE) {
2098 +
2099 +                                // Skip empty entries
2100 +                                if (de[DE_TYPE] == 0)
2101 +                                        continue;
2102 +
2103 +                                // Convert file name (strip everything after and including the first trailing space)
2104 +                                uint8 name_buf[17];
2105 +                                memcpy(name_buf, de + DE_NAME, 16);
2106 +                                name_buf[16] = 0;
2107 +                                uint8 *p = (uint8 *)memchr(name_buf, 0xa0, 16);
2108 +                                if (p)
2109 +                                        *p = 0;
2110 +
2111 +                                // Convert file type
2112 +                                int type = de[DE_TYPE] & 7;
2113 +                                if (type > 4)
2114 +                                        type = FTYPE_UNKNOWN;
2115 +
2116 +                                // Read start address
2117 +                                uint8 sa_lo = 0, sa_hi = 0;
2118 +                                uint8 buf[256];
2119 +                                if (read_sector(f, desc, de[DE_TRACK], de[DE_SECTOR], buf) == ERR_OK) {
2120 +                                        sa_lo = buf[2];
2121 +                                        sa_hi = buf[3];
2122 +                                }
2123 +
2124 +                                // Add entry
2125 +                                vec.push_back(c64_dir_entry(name_buf, type, !(de[DE_TYPE] & 0x80), de[DE_TYPE] & 0x40, ((de[DE_NUM_BLOCKS_H] << 8) + de[DE_NUM_BLOCKS_L]) * 254, 0, sa_lo, sa_hi));
2126 +                        }
2127 +                }
2128 +
2129 +                result = true;
2130 + done:   fclose(f);
2131 +        }
2132 +        return result;
2133 + }
2134 +
2135 +
2136   /*
2137   *  Create new blank disk image file, returns false on error
2138   */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines