1 |
|
/* |
2 |
< |
* 1541d64.h - 1541 emulation in .d64 file |
2 |
> |
* 1541d64.h - 1541 emulation in disk image files (.d64/.x64/zipcode) |
3 |
|
* |
4 |
< |
* Frodo (C) 1994-1997,2002 Christian Bauer |
4 |
> |
* Frodo (C) 1994-1997,2002-2003 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
24 |
|
#include "IEC.h" |
25 |
|
|
26 |
|
|
27 |
< |
// BAM structure |
28 |
< |
typedef struct { |
29 |
< |
uint8 dir_track; // Track... |
30 |
< |
uint8 dir_sector; // ...and sector of first directory block |
31 |
< |
int8 fmt_type; // Format type |
32 |
< |
int8 pad0; |
33 |
< |
uint8 bitmap[4*35]; // Sector allocation |
34 |
< |
uint8 disk_name[18]; // Disk name |
35 |
< |
uint8 id[2]; // Disk ID |
36 |
< |
int8 pad1; |
37 |
< |
uint8 fmt_char[2]; // Format characters |
38 |
< |
int8 pad2[4]; |
39 |
< |
int8 pad3[85]; |
40 |
< |
} BAM; |
41 |
< |
|
42 |
< |
// Directory entry structure |
43 |
< |
typedef struct { |
44 |
< |
uint8 type; // File type |
45 |
< |
uint8 track; // Track... |
46 |
< |
uint8 sector; // ...and sector of first data block |
47 |
< |
uint8 name[16]; // File name |
48 |
< |
uint8 side_track; // Track... |
49 |
< |
uint8 side_sector; // ...and sector of first side sector |
50 |
< |
uint8 rec_len; // Record length |
51 |
< |
int8 pad0[4]; |
52 |
< |
uint8 ovr_track; // Track... |
53 |
< |
uint8 ovr_sector; // ...and sector on overwrite |
54 |
< |
uint8 num_blocks_l; // Number of blocks, LSB |
55 |
< |
uint8 num_blocks_h; // Number of blocks, MSB |
56 |
< |
int8 pad1[2]; |
57 |
< |
} DirEntry; |
58 |
< |
|
59 |
< |
// Directory block structure |
60 |
< |
typedef struct { |
61 |
< |
uint8 padding[2]; // Keep DirEntry word-aligned |
62 |
< |
uint8 next_track; |
63 |
< |
uint8 next_sector; |
64 |
< |
DirEntry entry[8]; |
65 |
< |
} Directory; |
27 |
> |
/* |
28 |
> |
* Definitions |
29 |
> |
*/ |
30 |
> |
|
31 |
> |
// Constants |
32 |
> |
const int NUM_SECTORS_35 = 683; // Number of sectors in a 35-track image |
33 |
> |
const int NUM_SECTORS_40 = 768; // Number of sectors in a 40-track image |
34 |
> |
|
35 |
> |
// Disk image types |
36 |
> |
enum { |
37 |
> |
TYPE_D64, // D64 file |
38 |
> |
TYPE_ED64, // Converted zipcode file (D64 with header ID) |
39 |
> |
TYPE_X64 // x64 file |
40 |
> |
}; |
41 |
|
|
42 |
+ |
// Channel descriptor |
43 |
+ |
struct channel_desc { |
44 |
+ |
int mode; // Channel mode |
45 |
+ |
bool writing; // Flag: writing to file (for file channels) |
46 |
+ |
int buf_num; // Buffer number for direct access and file channels |
47 |
+ |
uint8 *buf; // Pointer to start of buffer |
48 |
+ |
uint8 *buf_ptr; // Pointer to current position in buffer |
49 |
+ |
int buf_len; // Remaining bytes in buffer |
50 |
+ |
int track, sector; // Track and sector the buffer will be written to (for writing to file channels) |
51 |
+ |
int num_blocks; // Number of blocks in file (for writing to file channels) |
52 |
+ |
int dir_track; // Track... |
53 |
+ |
int dir_sector; // ...and sector of directory block containing file entry |
54 |
+ |
int entry; // Number of entry in directory block |
55 |
+ |
}; |
56 |
|
|
57 |
+ |
// Disk image file descriptor |
58 |
+ |
struct image_file_desc { |
59 |
+ |
int type; // See definitions above |
60 |
+ |
int header_size; // Size of file header |
61 |
+ |
int num_tracks; // Number of tracks |
62 |
+ |
uint8 id1, id2; // Block header ID (as opposed to BAM ID) |
63 |
+ |
uint8 error_info[NUM_SECTORS_40]; // Sector error information (1 byte/sector) |
64 |
+ |
bool has_error_info; // Flag: error info present in file |
65 |
+ |
}; |
66 |
+ |
|
67 |
+ |
// Disk image drive class |
68 |
|
class D64Drive : public Drive { |
69 |
|
public: |
70 |
< |
D64Drive(IEC *iec, char *filepath); |
70 |
> |
D64Drive(IEC *iec, const char *filepath); |
71 |
|
virtual ~D64Drive(); |
72 |
< |
virtual uint8 Open(int channel, char *filename); |
72 |
> |
|
73 |
> |
virtual uint8 Open(int channel, const uint8 *name, int name_len); |
74 |
|
virtual uint8 Close(int channel); |
75 |
< |
virtual uint8 Read(int channel, uint8 *byte); |
75 |
> |
virtual uint8 Read(int channel, uint8 &byte); |
76 |
|
virtual uint8 Write(int channel, uint8 byte, bool eoi); |
77 |
|
virtual void Reset(void); |
78 |
|
|
79 |
|
private: |
80 |
< |
void open_close_d64_file(char *d64name); |
81 |
< |
uint8 open_file(int channel, char *filename); |
82 |
< |
void convert_filename(char *srcname, char *destname, int *filemode, int *filetype); |
83 |
< |
bool find_file(char *filename, int *track, int *sector); |
80 |
> |
void close_image(void); |
81 |
> |
bool change_image(const char *path); |
82 |
> |
|
83 |
> |
uint8 open_file(int channel, const uint8 *name, int name_len); |
84 |
|
uint8 open_file_ts(int channel, int track, int sector); |
85 |
< |
uint8 open_directory(char *pattern); |
86 |
< |
uint8 open_direct(int channel, char *filename); |
87 |
< |
void close_all_channels(); |
88 |
< |
void execute_command(char *command); |
89 |
< |
void block_read_cmd(char *command); |
89 |
< |
void buffer_ptr_cmd(char *command); |
90 |
< |
bool parse_bcmd(char *cmd, int *arg1, int *arg2, int *arg3, int *arg4); |
91 |
< |
void chd64_cmd(char *d64name); |
85 |
> |
uint8 create_file(int channel, const uint8 *name, int name_len, int type, bool overwrite = false); |
86 |
> |
uint8 open_directory(const uint8 *pattern, int pattern_len); |
87 |
> |
uint8 open_direct(int channel, const uint8 *filename); |
88 |
> |
void close_all_channels(void); |
89 |
> |
|
90 |
|
int alloc_buffer(int want); |
91 |
|
void free_buffer(int buf); |
92 |
+ |
|
93 |
+ |
bool find_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry, bool cont); |
94 |
+ |
bool find_first_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry); |
95 |
+ |
bool find_next_file(const uint8 *pattern, int pattern_len, int &dir_track, int &dir_sector, int &entry); |
96 |
+ |
bool alloc_dir_entry(int &track, int §or, int &entry); |
97 |
+ |
|
98 |
+ |
bool is_block_free(int track, int sector); |
99 |
+ |
int num_free_blocks(int track); |
100 |
+ |
int alloc_block(int track, int sector); |
101 |
+ |
int free_block(int track, int sector); |
102 |
+ |
bool alloc_block_chain(int track, int sector); |
103 |
+ |
bool free_block_chain(int track, int sector); |
104 |
+ |
bool alloc_next_block(int &track, int §or, int interleave); |
105 |
+ |
|
106 |
|
bool read_sector(int track, int sector, uint8 *buffer); |
107 |
< |
int offset_from_ts(int track, int sector); |
108 |
< |
uint8 conv_from_64(uint8 c, bool map_slash); |
107 |
> |
bool write_sector(int track, int sector, uint8 *buffer); |
108 |
> |
void write_error_info(void); |
109 |
|
|
110 |
< |
char orig_d64_name[256]; // Original path of .d64 file |
110 |
> |
virtual void block_read_cmd(int channel, int track, int sector, bool user_cmd = false); |
111 |
> |
virtual void block_write_cmd(int channel, int track, int sector, bool user_cmd = false); |
112 |
> |
virtual void block_allocate_cmd(int track, int sector); |
113 |
> |
virtual void block_free_cmd(int track, int sector); |
114 |
> |
virtual void buffer_pointer_cmd(int channel, int pos); |
115 |
> |
virtual void mem_read_cmd(uint16 adr, uint8 len); |
116 |
> |
virtual void mem_write_cmd(uint16 adr, uint8 len, uint8 *p); |
117 |
> |
virtual void copy_cmd(const uint8 *new_file, int new_file_len, const uint8 *old_files, int old_files_len); |
118 |
> |
virtual void rename_cmd(const uint8 *new_file, int new_file_len, const uint8 *old_file, int old_file_len); |
119 |
> |
virtual void scratch_cmd(const uint8 *files, int files_len); |
120 |
> |
virtual void initialize_cmd(void); |
121 |
> |
virtual void new_cmd(const uint8 *name, int name_len, const uint8 *comma); |
122 |
> |
virtual void validate_cmd(void); |
123 |
> |
|
124 |
> |
FILE *the_file; // File pointer for image file |
125 |
> |
image_file_desc desc; // Image file descriptor |
126 |
> |
bool write_protected; // Flag: image file write-protected |
127 |
> |
|
128 |
> |
uint8 ram[0x800]; // 2k 1541 RAM |
129 |
> |
uint8 dir[258]; // Buffer for directory blocks |
130 |
> |
uint8 *bam; // Pointer to BAM in 1541 RAM (buffer 4, upper 256 bytes) |
131 |
> |
bool bam_dirty; // Flag: BAM modified, needs to be written back |
132 |
|
|
133 |
< |
FILE *the_file; // File pointer for .d64 file |
133 |
> |
channel_desc ch[18]; // Descriptors for channels 0..17 (16 = internal read, 17 = internal write) |
134 |
> |
bool buf_free[4]; // Flags: buffer 0..3 free? |
135 |
> |
}; |
136 |
|
|
102 |
– |
uint8 *ram; // 2KB 1541 RAM |
103 |
– |
BAM *bam; // Pointer to BAM |
104 |
– |
Directory dir; // Buffer for directory blocks |
137 |
|
|
138 |
< |
int chan_mode[16]; // Channel mode |
139 |
< |
int chan_buf_num[16]; // Buffer number of channel (for direct access channels) |
140 |
< |
uint8 *chan_buf[16]; // Pointer to buffer |
109 |
< |
uint8 *buf_ptr[16]; // Pointer in buffer |
110 |
< |
int buf_len[16]; // Remaining bytes in buffer |
138 |
> |
/* |
139 |
> |
* Functions |
140 |
> |
*/ |
141 |
|
|
142 |
< |
bool buf_free[4]; // Buffer 0..3 free? |
142 |
> |
// Check whether file with given header (64 bytes) and size looks like one |
143 |
> |
// of the file types supported by this module |
144 |
> |
extern bool IsImageFile(const char *path, const uint8 *header, long size); |
145 |
|
|
146 |
< |
char cmd_buffer[44]; // Buffer for incoming command strings |
147 |
< |
int cmd_len; // Length of received command |
146 |
> |
// Create new blank disk image file |
147 |
> |
extern bool CreateImageFile(const char *path); |
148 |
|
|
149 |
< |
int image_header; // Length of .d64 file header |
149 |
> |
// Open disk image file |
150 |
> |
extern FILE *open_image_file(const char *path, bool write_mode); |
151 |
|
|
152 |
< |
uint8 error_info[683]; // Sector error information (1 byte/sector) |
153 |
< |
}; |
152 |
> |
// Parse disk image file header, fill in descriptor |
153 |
> |
extern bool parse_image_file(FILE *f, image_file_desc &desc); |
154 |
> |
|
155 |
> |
// Read/write sector from/to disk image file, return error code |
156 |
> |
extern int read_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer); |
157 |
> |
extern int write_sector(FILE *f, const image_file_desc &desc, int track, int sector, uint8 *buffer); |
158 |
> |
|
159 |
> |
// Format disk image |
160 |
> |
extern bool format_image(FILE *f, image_file_desc &desc, bool lowlevel, uint8 id1, uint8 id2, const uint8 *disk_name, int disk_name_len); |
161 |
> |
|
162 |
> |
// Get number of sectors per track |
163 |
> |
extern int sectors_per_track(const image_file_desc &desc, int track); |
164 |
> |
|
165 |
> |
// Get reference to error info byte of given track/sector |
166 |
> |
extern uint8 &error_info_for_sector(image_file_desc &desc, int track, int sector); |
167 |
> |
|
168 |
> |
// Write error info back to image file |
169 |
> |
extern void write_back_error_info(FILE *f, const image_file_desc &desc); |
170 |
|
|
171 |
|
#endif |