1 /*****************************************************************************/
5 /* Direct Disk I/O Demo Program */
9 /* (C) Copyright 2005, Oliver Schmidt, <ol.sc@web.de> */
12 /* This software is provided 'as-is', without any expressed or implied */
13 /* warranty. In no event will the authors be held liable for any damages */
14 /* arising from the use of this software. */
16 /* Permission is granted to anyone to use this software for any purpose, */
17 /* including commercial applications, and to alter it and redistribute it */
18 /* freely, subject to the following restrictions: */
20 /* 1. The origin of this software must not be misrepresented; you must not */
21 /* claim that you wrote the original software. If you use this software */
22 /* in a product, an acknowledgment in the product documentation would be */
23 /* appreciated but is not required. */
24 /* 2. Altered source versions must be plainly marked as such, and must not */
25 /* be misrepresented as being the original software. */
26 /* 3. This notice may not be removed or altered from any source */
29 /*****************************************************************************/
42 #define MAX_CHUNKS 10 /* Maximum acceptable number of chunks */
45 static unsigned char ScreenX;
46 static unsigned char ScreenY;
49 static void ClearLine (void)
50 /* Clear the screen line the cursor is on */
57 static unsigned char AskForDrive (const char* Name)
58 /* Ask for a drive id and return it */
60 unsigned char Drive = 0;
63 cprintf ("\r\n%s Drive ID ? ", Name);
70 Drive = Drive * 10 + Char - '0';
72 } while (Char != CH_ENTER);
79 static void AskForDisk (const char* Name, unsigned char Drive)
80 /* Ask the user to insert a specific disk */
83 cprintf ("\rInsert %s Disk into Drive %d !", Name, Drive);
89 static char* AllocBuffer (unsigned int SectSize, unsigned int SectCount, unsigned int* ChunkCount)
90 /* Allocate a copy buffer on the heap and return a pointer to it */
93 unsigned long BufferSize;
94 unsigned int Chunks = 1;
96 /* Increase number of chunks resp. decrease size */
97 /* of one chunk until buffer allocation succeeds */
99 *ChunkCount = (unsigned int) ((SectCount + Chunks - 1) / Chunks);
100 BufferSize = *ChunkCount * (unsigned long) SectSize;
101 if (BufferSize < UINT_MAX) {
102 Buffer = malloc ((size_t) BufferSize);
104 } while (Buffer == NULL && ++Chunks <= MAX_CHUNKS);
110 int main (int argc, const char* argv[])
112 unsigned char SourceId;
113 unsigned char TargetId;
114 dhandle_t Source = NULL;
115 dhandle_t Target = NULL;
116 unsigned int SectSize;
117 unsigned int SectCount;
120 unsigned int ChunkCount;
121 unsigned int ChunkOffset = 0;
124 screensize (&ScreenX, &ScreenY);
126 cputs ("Floppy Disk Copy\r\n");
130 /* Get source and target drive id (which may very well be identical) */
133 SourceId = AskForDrive ("Source");
134 TargetId = AskForDrive ("Target");
139 SourceId = TargetId = atoi (argv[1]);
143 SourceId = atoi (argv[1]);
144 TargetId = atoi (argv[2]);
148 cprintf ("\r\nToo many arguments\r\n");
155 /* Check for single drive copy or inital iteration */
156 if (SourceId == TargetId || Source == NULL) {
157 AskForDisk ("Source", SourceId);
160 /* Check for initial iteration */
161 if (Source == NULL) {
163 /* Open source drive */
164 Source = dio_open (SourceId);
165 if (Source == NULL) {
166 cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, SourceId);
170 SectSize = dio_query_sectsize (Source);
171 SectCount = dio_query_sectcount (Source);
173 /* Allocate buffer */
174 Buffer = AllocBuffer (SectSize, SectCount, &ChunkCount);
175 if (Buffer == NULL) {
176 cputs ("\r\n\nError on allocating Buffer\r\n");
183 /* Read one chunk of sectors into buffer */
184 for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
185 cprintf ("\rReading Sector %d of %d", Sector + 1, SectCount);
187 /* Read one sector */
188 if (dio_read (Source, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
189 cprintf ("\r\n\nError %d on reading from Drive %d\r\n", (int) _oserror, SourceId);
194 /* Check for single drive copy or inital iteration */
195 if (TargetId == SourceId || Target == NULL) {
196 AskForDisk ("Target", TargetId);
199 /* Open target drive on initial iteration */
200 if (Target == NULL) {
201 Target = dio_open (TargetId);
202 if (Target == NULL) {
203 cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
207 /* Check for compatible drives */
208 if (dio_query_sectsize (Target) != SectSize ||
209 dio_query_sectcount (Target) != SectCount) {
210 cputs ("\r\n\nFormat mismatch between Drives\r\n");
217 /* Write one chunk of sectors from buffer */
218 for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
219 cprintf ("\rWriting Sector %d of %d", Sector + 1, SectCount);
221 /* Write one sector */
222 if (dio_write (Target, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
223 cprintf ("\r\n\nError %d on writing to Drive %d\r\n", (int) _oserror, TargetId);
228 /* Advance to next chunk */
229 ChunkOffset += ChunkCount;
231 } while (Sector < SectCount);
234 cprintf ("\rSuccessfully copied %d Sectors\r\n", SectCount);