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 driveid_t AskForDrive (const char* Name)
58 /* Ask for a drive id and return it */
63 cprintf ("\r\n%s Drive ID ?", Name);
69 Drive = Drive * 10 + Char - '0';
71 } while (Char != CH_ENTER);
77 static void AskForDisk (const char* Name, driveid_t Drive)
78 /* Ask the user to insert a specific disk */
81 cprintf ("\rInsert %s Disk into Drive %d !", Name, Drive);
87 static char* AllocBuffer (sectsize_t SectSize, sectnum_t SectCount, sectnum_t* ChunkCount)
88 /* Allocate a copy buffer on the heap and return a pointer to it */
91 unsigned long BufferSize;
92 unsigned int Chunks = 1;
94 /* Increase number of chunks resp. decrease size */
95 /* of one chunk until buffer allocation succeeds */
97 *ChunkCount = (sectnum_t) ((SectCount + Chunks - 1) / Chunks);
98 BufferSize = *ChunkCount * (unsigned long) SectSize;
99 if (BufferSize < UINT_MAX) {
100 Buffer = malloc ((size_t) BufferSize);
102 } while (Buffer == NULL && ++Chunks <= MAX_CHUNKS);
108 int main (int argc, const char* argv[])
112 dhandle_t Source = NULL;
113 dhandle_t Target = NULL;
118 sectnum_t ChunkCount;
119 sectnum_t ChunkOffset = 0;
122 screensize (&ScreenX, &ScreenY);
124 cputs ("Floppy Disk Copy\r\n");
128 /* Get source and target drive id (which may very well be identical) */
131 SourceId = AskForDrive ("Source");
132 TargetId = AskForDrive ("Target");
137 SourceId = TargetId = atoi (argv[1]);
141 SourceId = atoi (argv[1]);
142 TargetId = atoi (argv[2]);
146 cprintf ("\r\nToo many arguments\r\n");
153 /* Check for single drive copy or inital iteration */
154 if (SourceId == TargetId || Source == NULL) {
155 AskForDisk ("Source", SourceId);
158 /* Check for initial iteration */
159 if (Source == NULL) {
161 /* Open source drive */
162 Source = dio_open (SourceId);
163 if (Source == NULL) {
164 cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, SourceId);
168 SectSize = dio_query_sectsize (Source);
169 SectCount = dio_query_sectcount (Source);
171 /* Allocate buffer */
172 Buffer = AllocBuffer (SectSize, SectCount, &ChunkCount);
173 if (Buffer == NULL) {
174 cputs ("\r\n\nError on allocating Buffer\r\n");
181 /* Read one chunk of sectors into buffer */
182 for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
183 cprintf ("\rReading Sector %d of %d", Sector + 1, SectCount);
185 /* Read one sector */
186 if (dio_read (Source, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
187 cprintf ("\r\n\nError %d on reading from Drive %d\r\n", (int) _oserror, SourceId);
192 /* Check for single drive copy or inital iteration */
193 if (TargetId == SourceId || Target == NULL) {
194 AskForDisk ("Target", TargetId);
197 /* Open target drive on initial iteration */
198 if (Target == NULL) {
199 Target = dio_open (TargetId);
200 if (Target == NULL) {
201 cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
205 /* Check for compatible drives */
206 if (dio_query_sectsize (Target) != SectSize ||
207 dio_query_sectcount (Target) != SectCount) {
208 cputs ("\r\n\nFormat mismatch between Drives\r\n");
215 /* Write one chunk of sectors from buffer */
216 for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
217 cprintf ("\rWriting Sector %d of %d", Sector + 1, SectCount);
219 /* Write one sector */
220 if (dio_write (Target, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
221 cprintf ("\r\n\nError %d on writing to Drive %d\r\n", (int) _oserror, TargetId);
226 /* Advance to next chunk */
227 ChunkOffset += ChunkCount;
229 } while (Sector < SectCount);
232 cprintf ("\rSuccessfully copied %d Sectors\r\n", SectCount);