X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=samples%2Fdiodemo.c;h=3e52f2fa920c8b67c69a17ceac128acf174252e4;hb=2eac69a94361323bf7556d2cdde8f61c85c5ef99;hp=55e5a9761fee4db77116ce7072989b4c5a620a74;hpb=16e88a489b01419825fecb836360f23845e1d5c8;p=cc65
diff --git a/samples/diodemo.c b/samples/diodemo.c
index 55e5a9761..3e52f2fa9 100644
--- a/samples/diodemo.c
+++ b/samples/diodemo.c
@@ -1,13 +1,46 @@
+/*****************************************************************************/
+/* */
+/* diodemo.c */
+/* */
+/* Direct Disk I/O Demo Program */
+/* */
+/* */
+/* */
+/* (C) Copyright 2005, Oliver Schmidt,
*/
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
#include
#include
#include
#include
#include
#include
+#include
#include
-#define MAX_CHUNKS 10 // Maximum acceptable number of chunks
+#define MAX_CHUNKS 10 /* Maximum acceptable number of chunks */
static unsigned char ScreenX;
@@ -15,32 +48,37 @@ static unsigned char ScreenY;
static void ClearLine (void)
+/* Clear the screen line the cursor is on */
{
cputc ('\r');
cclear (ScreenX);
}
-static driveid_t AskForDrive (char* Name)
+static unsigned char AskForDrive (const char* Name)
+/* Ask for a drive id and return it */
{
- driveid_t Drive = 0;
- char Char;
+ unsigned char Drive = 0;
+ char Char;
- cprintf ("\r\n%s Drive ID ?", Name);
+ cprintf ("\r\n%s Drive ID ? ", Name);
+ cursor (1);
do {
Char = cgetc ();
if (isdigit (Char)) {
cputc (Char);
- Drive = (driveid_t) (Drive * 10 + Char - '0');
+ Drive = Drive * 10 + Char - '0';
}
} while (Char != CH_ENTER);
+ cursor (0);
return Drive;
}
-static void AskForDisk (char* Name, driveid_t Drive)
+static void AskForDisk (const char* Name, unsigned char Drive)
+/* Ask the user to insert a specific disk */
{
ClearLine ();
cprintf ("\rInsert %s Disk into Drive %d !", Name, Drive);
@@ -49,110 +87,151 @@ static void AskForDisk (char* Name, driveid_t Drive)
}
-static char* AllocBuffer (sectsize_t SectSize, sectnum_t SectCount, sectnum_t* ChunkCount)
+static char* AllocBuffer (unsigned int SectSize, unsigned int SectCount, unsigned int* ChunkCount)
+/* Allocate a copy buffer on the heap and return a pointer to it */
{
- void* Buffer = NULL;
+ char* Buffer = NULL;
unsigned long BufferSize;
unsigned int Chunks = 1;
+ /* Increase number of chunks resp. decrease size */
+ /* of one chunk until buffer allocation succeeds */
do {
- *ChunkCount = (sectnum_t) ((SectCount + Chunks - 1) / Chunks);
+ *ChunkCount = (unsigned int) ((SectCount + Chunks - 1) / Chunks);
BufferSize = *ChunkCount * (unsigned long) SectSize;
if (BufferSize < UINT_MAX) {
Buffer = malloc ((size_t) BufferSize);
}
} while (Buffer == NULL && ++Chunks <= MAX_CHUNKS);
- return (char*) Buffer;
+ return Buffer;
}
-int main (void)
+int main (int argc, const char* argv[])
{
- driveid_t SourceId;
- driveid_t TargetId;
- dhandle_t Source = NULL;
- dhandle_t Target = NULL;
- sectsize_t SectSize;
- sectnum_t SectCount;
- char* Buffer;
- sectnum_t Sector;
- sectnum_t ChunkCount;
- sectnum_t ChunkOffset = 0;
+ unsigned char SourceId;
+ unsigned char TargetId;
+ dhandle_t Source = NULL;
+ dhandle_t Target = NULL;
+ unsigned int SectSize;
+ unsigned int SectCount;
+ char* Buffer;
+ unsigned int Sector;
+ unsigned int ChunkCount;
+ unsigned int ChunkOffset = 0;
clrscr ();
screensize (&ScreenX, &ScreenY);
+ /* Allow user to read exit messages */
+ if (doesclrscrafterexit ()) {
+ atexit ((void (*)) cgetc);
+ }
+
cputs ("Floppy Disk Copy\r\n");
chline (16);
cputs ("\r\n");
- SourceId = AskForDrive ("Source");
- TargetId = AskForDrive ("Target");
- cputs ("\r\n\r\n");
+ /* Get source and target drive id (which may very well be identical) */
+ switch (argc) {
+ case 1:
+ SourceId = AskForDrive ("Source");
+ TargetId = AskForDrive ("Target");
+ cputs ("\r\n");
+ break;
+
+ case 2:
+ SourceId = TargetId = atoi (argv[1]);
+ break;
+
+ case 3:
+ SourceId = atoi (argv[1]);
+ TargetId = atoi (argv[2]);
+ break;
+
+ default:
+ cprintf ("\r\nToo many arguments\r\n");
+ return EXIT_FAILURE;
+ }
+
+ cputs ("\r\n");
do {
+ /* Check for single drive copy or inital iteration */
if (SourceId == TargetId || Source == NULL) {
AskForDisk ("Source", SourceId);
}
+ /* Check for initial iteration */
if (Source == NULL) {
+
+ /* Open source drive */
Source = dio_open (SourceId);
if (Source == NULL) {
- cprintf ("\r\n\r\nError %d on opening Drive %d\r\n", (int) _oserror, SourceId);
+ cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, SourceId);
return EXIT_FAILURE;
}
SectSize = dio_query_sectsize (Source);
SectCount = dio_query_sectcount (Source);
+ /* Allocate buffer */
Buffer = AllocBuffer (SectSize, SectCount, &ChunkCount);
if (Buffer == NULL) {
- cputs ("\r\n\r\nError on allocating Buffer\r\n");
+ cputs ("\r\n\nError on allocating Buffer\r\n");
return EXIT_FAILURE;
}
}
ClearLine ();
+ /* Read one chunk of sectors into buffer */
for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
cprintf ("\rReading Sector %d of %d", Sector + 1, SectCount);
+ /* Read one sector */
if (dio_read (Source, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
- cprintf ("\r\n\r\nError %d on reading Drive %d\r\n", (int) _oserror, SourceId);
+ cprintf ("\r\n\nError %d on reading from Drive %d\r\n", (int) _oserror, SourceId);
return EXIT_FAILURE;
}
}
+ /* Check for single drive copy or inital iteration */
if (TargetId == SourceId || Target == NULL) {
AskForDisk ("Target", TargetId);
}
+ /* Open target drive on initial iteration */
if (Target == NULL) {
Target = dio_open (TargetId);
if (Target == NULL) {
- cprintf ("\r\n\r\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
+ cprintf ("\r\n\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
return EXIT_FAILURE;
}
+ /* Check for compatible drives */
if (dio_query_sectsize (Target) != SectSize ||
dio_query_sectcount (Target) != SectCount) {
- cputs ("\r\n\r\nFormat mismatch between Drives\r\n");
+ cputs ("\r\n\nFormat mismatch between Drives\r\n");
return EXIT_FAILURE;
}
}
ClearLine ();
+ /* Write one chunk of sectors from buffer */
for (Sector = ChunkOffset; Sector < SectCount && (Sector - ChunkOffset) < ChunkCount; ++Sector) {
cprintf ("\rWriting Sector %d of %d", Sector + 1, SectCount);
+ /* Write one sector */
if (dio_write (Target, Sector, Buffer + (Sector - ChunkOffset) * SectSize) != 0) {
- cprintf ("\r\n\r\nError %d on opening Drive %d\r\n", (int) _oserror, TargetId);
+ cprintf ("\r\n\nError %d on writing to Drive %d\r\n", (int) _oserror, TargetId);
return EXIT_FAILURE;
}
}
+ /* Advance to next chunk */
ChunkOffset += ChunkCount;
} while (Sector < SectCount);