1 /*
2  * vdrive.h - Virtual disk-drive implementation.
3  *
4  * Written by
5  *  Andreas Boose <viceteam@t-online.de>
6  *
7  * This file is part of VICE, the Versatile Commodore Emulator.
8  * See README for copyright notice.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23  *  02111-1307  USA.
24  *
25  */
26 
27 #ifndef VICE_VDRIVE_H
28 #define VICE_VDRIVE_H
29 
30 #include "types.h"
31 #include "vdrive-dir.h"
32 
33 /* temporarily until the 4000 support is not safe */
34 #define VDRIVE_IMAGE_FORMAT_4000_TEST (vdrive->image_format == VDRIVE_IMAGE_FORMAT_4000)
35 
36 /* High level disk formats.
37    They can be different than the disk image type.  */
38 #define VDRIVE_IMAGE_FORMAT_1541 0
39 #define VDRIVE_IMAGE_FORMAT_1571 1
40 #define VDRIVE_IMAGE_FORMAT_1581 2
41 #define VDRIVE_IMAGE_FORMAT_8050 3 /* Dual Disk Drive */
42 #define VDRIVE_IMAGE_FORMAT_8250 4 /* Dual Disk Drive */
43 #define VDRIVE_IMAGE_FORMAT_2040 5 /* Dual Disk Drive */
44 #define VDRIVE_IMAGE_FORMAT_4000 6
45 #define VDRIVE_IMAGE_FORMAT_9000 8
46 
47 #define BUFFER_NOT_IN_USE      0
48 #define BUFFER_DIRECTORY_READ  1
49 #define BUFFER_SEQUENTIAL      2
50 #define BUFFER_MEMORY_BUFFER   3
51 #define BUFFER_RELATIVE        4
52 #define BUFFER_COMMAND_CHANNEL 5
53 
54 #define WRITE_BLOCK 512
55 
56 #define SET_LO_HI(p, val)               \
57     do {                                \
58         *((p)++) = (val) & 0xff;        \
59         *((p)++) = ((val) >> 8) & 0xff; \
60     } while (0)
61 
62 #define DRIVE_RAMSIZE           0x400
63 
64 #define BAM_MAXSIZE (33 * 256)
65 
66 /* Serial Error Codes. */
67 #define SERIAL_OK               0
68 #define SERIAL_WRITE_TIMEOUT    1
69 #define SERIAL_READ_TIMEOUT     2
70 #define SERIAL_FILE_NOT_FOUND   64      /* EOF */
71 #define SERIAL_NO_DEVICE        128
72 
73 #define SERIAL_ERROR                    (2)
74 #define SERIAL_EOF                      (0x40)
75 #define SERIAL_DEVICE_NOT_PRESENT       (0x80)
76 
77 typedef struct bufferinfo_s {
78     unsigned int mode;     /* Mode on this buffer */
79     unsigned int readmode; /* Is this channel for reading or writing */
80     uint8_t *buffer;          /* Use this to save data */
81     uint8_t *slot;            /* Save data for directory-slot */
82     unsigned int bufptr;   /* Use this to save/read data to disk */
83     unsigned int track;    /* which track is allocated for this sector */
84     unsigned int sector;   /*   (for write files only) */
85     unsigned int length;   /* Directory-read length */
86     unsigned int record;   /* Current record */
87 
88     /* REL file information stored in buffers since we can have more than
89         one open */
90     uint8_t *side_sector;
91     /* location of the side sectors */
92     uint8_t *side_sector_track;
93     uint8_t *side_sector_sector;
94 
95     uint8_t *super_side_sector;
96     /* location of the super side sector */
97     uint8_t super_side_sector_track;
98     uint8_t super_side_sector_sector;
99 
100     uint8_t *buffer_next;          /* next buffer for rel file */
101     unsigned int track_next;    /* track for the next sector */
102     unsigned int sector_next;   /* sector for the next sector */
103 
104     unsigned int record_max;  /* Max rel file record, inclusive */
105     unsigned int record_next; /* Buffer pointer to beginning of next record */
106     uint8_t needsupdate;         /* true if the current sector needs to be
107                                   written (from REL write) */
108     uint8_t super_side_sector_needsupdate; /* similar to above */
109     uint8_t *side_sector_needsupdate;
110 
111     vdrive_dir_context_t dir; /* directory listing context or directory entry */
112 } bufferinfo_t;
113 
114 struct disk_image_s;
115 
116 /* Run-time data struct for each drive. */
117 typedef struct vdrive_s {
118     struct disk_image_s *image;
119 
120     /* Current image file */
121     unsigned int mode;         /* Read/Write */
122     unsigned int image_format; /* 1541/71/81 */
123     unsigned int unit;	       /* IEC bus device number */
124     unsigned int drive;        /* Drive 0 or 1 (for dual drive units) */
125 
126     unsigned int Bam_Track;
127     unsigned int Bam_Sector;
128     unsigned int bam_name;     /* Offset from start of BAM to disk name.   */
129     unsigned int bam_id;       /* Offset from start of BAM to disk ID.  */
130     unsigned int Header_Track; /* Directory header location */
131     unsigned int Header_Sector;
132     unsigned int Dir_Track;    /* First directory sector location */
133     unsigned int Dir_Sector;
134     unsigned int num_tracks;
135 
136     unsigned int d90toggle;    /* D9090/60 new sector toggle */
137     int last_code;             /* for command channel status string */
138 
139     /* CBM partition first and last track (1581)
140      * Part_Start is 1, Part_End = num_tracks if no partition is used
141      */
142     unsigned int Part_Start, Part_End;
143 
144     unsigned int bam_size;
145     uint8_t *bam;	/* Disk header blk (if any) followed by BAM blocks */
146     bufferinfo_t buffers[16];
147 
148     /* Memory read command buffer.  */
149     uint8_t mem_buf[256];
150     unsigned int mem_length;
151 
152     /* removed side sector data and placed it in buffer structure */
153     /* BYTE *side_sector; */
154 
155     uint8_t ram[0x800];
156 } vdrive_t;
157 
158 /* Actually, serial-code errors ... */
159 
160 #define FLOPPY_COMMAND_OK       0
161 #define FLOPPY_ERROR            2
162 
163 
164 /* Return values used around. */
165 
166 #define FD_OK           0
167 #define FD_EXIT         1       /* -1,0, 1 are fixed values */
168 
169 #define FD_NOTREADY     -2
170 #define FD_CHANGED      -3      /* File has changed on disk */
171 #define FD_NOTRD        -4
172 #define FD_NOTWRT       -5
173 #define FD_WRTERR       -6
174 #define FD_RDERR        -7
175 #define FD_INCOMP       -8      /* DOS Format Mismatch */
176 #define FD_BADIMAGE     -9      /* ID mismatch (Disk or tape) */
177 #define FD_BADNAME      -10     /* Illegal filename */
178 #define FD_BADVAL       -11     /* Illegal value */
179 #define FD_BADDEV       -12
180 #define FD_BAD_TS       -13     /* Track or sector */
181 #define FD_BAD_TRKNUM   -14     /* Illegal track number */
182 #define FD_BAD_SECNUM   -15     /* Illegal sector number */
183 
184 
185 #define CHK_NUM         0
186 #define CHK_RDY         1
187 
188 /* ------------------------------------------------------------------------- */
189 
190 extern void vdrive_init(void);
191 extern int vdrive_device_setup(vdrive_t *vdrive, unsigned int unit, unsigned int drive);
192 extern void vdrive_device_shutdown(vdrive_t *vdrive);
193 extern int vdrive_attach_image(struct disk_image_s *image, unsigned int unit, unsigned int drive, vdrive_t *vdrive);
194 extern void vdrive_detach_image(struct disk_image_s *image, unsigned int unit, unsigned int drive, vdrive_t *vdrive);
195 extern void vdrive_close_all_channels(vdrive_t *vdrive);
196 extern int vdrive_get_max_sectors(vdrive_t *vdrive, unsigned int track);
197 extern int vdrive_get_max_sectors_per_head(vdrive_t *vdrive, unsigned int track);
198 extern void vdrive_get_last_read(unsigned int *track, unsigned int *sector, uint8_t **buffer);
199 extern void vdrive_set_last_read(unsigned int track, unsigned int sector, uint8_t *buffer);
200 
201 extern void vdrive_alloc_buffer(struct bufferinfo_s *p, int mode);
202 extern void vdrive_free_buffer(struct bufferinfo_s *p);
203 extern void vdrive_set_disk_geometry(vdrive_t *vdrive);
204 extern int vdrive_read_sector(vdrive_t *vdrive, uint8_t *buf, unsigned int track, unsigned int sector);
205 extern int vdrive_write_sector(vdrive_t *vdrive, const uint8_t *buf, unsigned int track, unsigned int sector);
206 
207 #endif
208