--- Frodo4/Src/1541d64.h 2003/07/01 17:51:17 1.2 +++ Frodo4/Src/1541d64.h 2005/06/27 19:55:48 1.8 @@ -1,7 +1,7 @@ /* - * 1541d64.h - 1541 emulation in .d64 file + * 1541d64.h - 1541 emulation in disk image files (.d64/.x64/zipcode) * - * Frodo (C) 1994-1997,2002-2003 Christian Bauer + * Frodo (C) 1994-1997,2002-2005 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,99 +24,129 @@ #include "IEC.h" -// BAM structure -typedef struct { - uint8 dir_track; // Track... - uint8 dir_sector; // ...and sector of first directory block - int8 fmt_type; // Format type - int8 pad0; - uint8 bitmap[4*35]; // Sector allocation - uint8 disk_name[18]; // Disk name - uint8 id[2]; // Disk ID - int8 pad1; - uint8 fmt_char[2]; // Format characters - int8 pad2[4]; - int8 pad3[85]; -} BAM; - -// Directory entry structure -typedef struct { - uint8 type; // File type - uint8 track; // Track... - uint8 sector; // ...and sector of first data block - uint8 name[16]; // File name - uint8 side_track; // Track... - uint8 side_sector; // ...and sector of first side sector - uint8 rec_len; // Record length - int8 pad0[4]; - uint8 ovr_track; // Track... - uint8 ovr_sector; // ...and sector on overwrite - uint8 num_blocks_l; // Number of blocks, LSB - uint8 num_blocks_h; // Number of blocks, MSB - int8 pad1[2]; -} DirEntry; - -// Directory block structure -typedef struct { - uint8 padding[2]; // Keep DirEntry word-aligned - uint8 next_track; - uint8 next_sector; - DirEntry entry[8]; -} Directory; +/* + * Definitions + */ +// Constants +const int NUM_SECTORS_35 = 683; // Number of sectors in a 35-track image +const int NUM_SECTORS_40 = 768; // Number of sectors in a 40-track image + +// Disk image types +enum { + TYPE_D64, // D64 file + TYPE_ED64, // Converted zipcode file (D64 with header ID) + TYPE_X64 // x64 file +}; + +// Channel descriptor +struct channel_desc { + int mode; // Channel mode + bool writing; // Flag: writing to file (for file channels) + int buf_num; // Buffer number for direct access and file channels + uint8 *buf; // Pointer to start of buffer + uint8 *buf_ptr; // Pointer to current position in buffer + int buf_len; // Remaining bytes in buffer + int track, sector; // Track and sector the buffer will be written to (for writing to file channels) + int num_blocks; // Number of blocks in file (for writing to file channels) + int dir_track; // Track... + int dir_sector; // ...and sector of directory block containing file entry + int entry; // Number of entry in directory block +}; -class D64Drive : public Drive { +// Disk image file descriptor +struct image_file_desc { + int type; // See definitions above + int header_size; // Size of file header + int num_tracks; // Number of tracks + uint8 id1, id2; // Block header ID (as opposed to BAM ID) + uint8 error_info[NUM_SECTORS_40]; // Sector error information (1 byte/sector) + bool has_error_info; // Flag: error info present in file +}; + +// Disk image drive class +class ImageDrive : public Drive { public: - D64Drive(IEC *iec, char *filepath); - virtual ~D64Drive(); - virtual uint8 Open(int channel, char *filename); + ImageDrive(IEC *iec, const char *filepath); + virtual ~ImageDrive(); + + virtual uint8 Open(int channel, const uint8 *name, int name_len); virtual uint8 Close(int channel); - virtual uint8 Read(int channel, uint8 *byte); + virtual uint8 Read(int channel, uint8 &byte); virtual uint8 Write(int channel, uint8 byte, bool eoi); virtual void Reset(void); private: - void open_close_d64_file(char *d64name); - uint8 open_file(int channel, char *filename); - void convert_filename(char *srcname, char *destname, int *filemode, int *filetype); - bool find_file(char *filename, int *track, int *sector); + void close_image(void); + bool change_image(const char *path); + + uint8 open_file(int channel, const uint8 *name, int name_len); uint8 open_file_ts(int channel, int track, int sector); - uint8 open_directory(char *pattern); - uint8 open_direct(int channel, char *filename); - void close_all_channels(); - void execute_command(char *command); - void block_read_cmd(char *command); - void buffer_ptr_cmd(char *command); - bool parse_bcmd(char *cmd, int *arg1, int *arg2, int *arg3, int *arg4); - void chd64_cmd(char *d64name); + uint8 create_file(int channel, const uint8 *name, int name_len, int type, bool overwrite = false); + uint8 open_directory(const uint8 *pattern, int pattern_len); + uint8 open_direct(int channel, const uint8 *filename); + void close_all_channels(void); + int alloc_buffer(int want); void free_buffer(int buf); - bool read_sector(int track, int sector, uint8 *buffer); - int offset_from_ts(int track, int sector); - uint8 conv_from_64(uint8 c, bool map_slash); - char orig_d64_name[256]; // Original path of .d64 file + bool find_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry, bool cont); + bool find_first_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry); + bool find_next_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry); + bool alloc_dir_entry(int &track, int §or, int &entry); + + bool is_block_free(int track, int sector); + int num_free_blocks(int track); + int alloc_block(int track, int sector); + int free_block(int track, int sector); + bool alloc_block_chain(int track, int sector); + bool free_block_chain(int track, int sector); + bool alloc_next_block(int &track, int §or, int interleave); + + bool read_sector(int track, int sector, uint8 *buffer); + bool write_sector(int track, int sector, uint8 *buffer); + void write_error_info(void); - FILE *the_file; // File pointer for .d64 file + virtual void block_read_cmd(int channel, int track, int sector, bool user_cmd = false); + virtual void block_write_cmd(int channel, int track, int sector, bool user_cmd = false); + virtual void block_allocate_cmd(int track, int sector); + virtual void block_free_cmd(int track, int sector); + virtual void buffer_pointer_cmd(int channel, int pos); + virtual void mem_read_cmd(uint16 adr, uint8 len); + virtual void mem_write_cmd(uint16 adr, uint8 len, uint8 *p); + virtual void copy_cmd(const uint8 *new_file, int new_file_len, const uint8 *old_files, int old_files_len); + virtual void rename_cmd(const uint8 *new_file, int new_file_len, const uint8 *old_file, int old_file_len); + virtual void scratch_cmd(const uint8 *files, int files_len); + virtual void initialize_cmd(void); + virtual void new_cmd(const uint8 *name, int name_len, const uint8 *comma); + virtual void validate_cmd(void); + + FILE *the_file; // File pointer for image file + image_file_desc desc; // Image file descriptor + bool write_protected; // Flag: image file write-protected + + uint8 ram[0x800]; // 2k 1541 RAM + uint8 dir[258]; // Buffer for directory blocks + uint8 *bam; // Pointer to BAM in 1541 RAM (buffer 4, upper 256 bytes) + bool bam_dirty; // Flag: BAM modified, needs to be written back - uint8 *ram; // 2KB 1541 RAM - BAM *bam; // Pointer to BAM - Directory dir; // Buffer for directory blocks + channel_desc ch[18]; // Descriptors for channels 0..17 (16 = internal read, 17 = internal write) + bool buf_free[4]; // Flags: buffer 0..3 free? +}; - int chan_mode[16]; // Channel mode - int chan_buf_num[16]; // Buffer number of channel (for direct access channels) - uint8 *chan_buf[16]; // Pointer to buffer - uint8 *buf_ptr[16]; // Pointer in buffer - int buf_len[16]; // Remaining bytes in buffer - bool buf_free[4]; // Buffer 0..3 free? +/* + * Functions + */ - char cmd_buffer[44]; // Buffer for incoming command strings - int cmd_len; // Length of received command +// Check whether file with given header (64 bytes) and size looks like one +// of the file types supported by this module +extern bool IsImageFile(const char *path, const uint8 *header, long size); - int image_header; // Length of .d64 file header +// Read directory of disk image file into (empty) c64_dir_entry vector +extern bool ReadImageDirectory(const char *path, vector &vec); - uint8 error_info[683]; // Sector error information (1 byte/sector) -}; +// Create new blank disk image file +extern bool CreateImageFile(const char *path); #endif