/* XAD 1.0, written by Jonathan Forbes                                    */
/* Release date: 31st May, 1989                                           */
/* Copyright (C) Xenomiga Technology, 1989                                */
/* Call the Xenomiga BBS (416-921-6638), 14400/38400 HST system, 110 Megs */

/* NOTE:  This program is freely distributable, but is NOT Public Domain. */
/*        You may NOT alter the source without the author's permission.   */


#include <exec/types.h>
#include <exec/io.h>
#include <libraries/dos.h>


#define BLOCK_SIZE 512
#define SECTORS 11
#define HEADS 2
#define READ_MODE 1
#define WRITE_MODE 2


extern struct IOStdReq *CreateStdIO();
extern struct MsgPort  *CreatePort();
struct IOStdReq *RadWriteMsg, *RadReadMsg;
struct MsgPort  *RadWritePort, *RadReadPort;
char   Data[BLOCK_SIZE * SECTORS * HEADS];
char   ParamFile[100], ModeName[50], DeviceName[50];
UBYTE  Mode;
USHORT NumTracks;


void main(argc, argv)
int  argc;
char *argv[];
{
if (argc != 5) {
    puts("XAD 1.0 by Jonathan Forbes");
    puts("Usage: XAD <DeviceName> <FileName> <Mode:READ/WRITE> <NumTacks>\n");
    puts(" E.g.: XAD ramdrive.device Testing.DAT WRITE 79\n");
    exit(1);
    }

NumTracks = atoi(argv[4]);
if (NumTracks < 1) {
    puts("Illegal number of tracks specified\n");
    exit(1);
    }

strcpy(DeviceName, argv[1]);

strcpy(ParamFile, argv[2]);
stoupper(ParamFile);

strcpy(ModeName, argv[3]);
stoupper(ModeName);

FindCorrectMode();
OpenPorts();
SetMessages();
Title();
MainProgram();
CleanUp();
}


RadToDisk()
{
register USHORT i;
ULONG           error;
register ULONG  FilePtr;

error = OpenDevice(DeviceName, 0, RadReadMsg, 0);
if (error) {
    printf("Error opening '%s' in READ mode\n\n", DeviceName);
    exit(1);
    }

FilePtr = Open(ParamFile, MODE_NEWFILE);
if (!FilePtr) {
    printf("Fatal error opening '%s' for output\n\n", ParamFile);
    exit(1);
    }

for (i=0; i<=NumTracks; i++) {
  printf("Writing Cylinder %d\n[A", i);

  RadReadMsg->io_Data   = (APTR) &Data;
  RadReadMsg->io_Offset = (SECTORS * HEADS * i) * BLOCK_SIZE;
  RadReadMsg->io_Length = BLOCK_SIZE * SECTORS * HEADS;
  if (DoIO(RadReadMsg))
      printf("\nError: Track %d\n[2A", i);

  Write(FilePtr, Data, BLOCK_SIZE * SECTORS * HEADS);
  }

Close(FilePtr);
CloseDevice(RadReadMsg);
}


DiskToRad()
{
register USHORT i;
ULONG           error;
register ULONG  FilePtr;

error = OpenDevice(DeviceName, 0, RadWriteMsg, 0);
if (error) {
    printf("Error opening '%s' in WRITE mode\n\n", DeviceName);
    exit(1);
    }

FilePtr = Open(ParamFile, MODE_OLDFILE);
if (!FilePtr) {
    printf("Fatal error opening '%s' for input\n\n", ParamFile);
    exit(1);
    }

for (i=0; i<=NumTracks; i++) {
  printf("Reading cylinder %d\n[A", i);

  Read(FilePtr, Data, BLOCK_SIZE * SECTORS * HEADS);
  RadWriteMsg->io_Data   = (APTR) &Data;
  RadWriteMsg->io_Offset = (SECTORS * HEADS * i) * BLOCK_SIZE;
  RadWriteMsg->io_Length = BLOCK_SIZE * SECTORS * HEADS;
  if (DoIO(RadWriteMsg))
      printf("\nError: Track %d\n[2A", i);
  }

Close(FilePtr);
CloseDevice(RadWriteMsg);
}


OpenPorts()
{
if (!(RadWritePort = CreatePort("RadWrite", 0L))) {
    puts("Couldn't open WRITE port\n");
    exit(1);
    }

if (!(RadReadPort = CreatePort("RadRead", 0L))) {
    puts("Couldn't open READ port\n");
    exit(1);
    }

if (!(RadWriteMsg  = CreateStdIO(RadWritePort))) {;
    puts("Couldn't create WRITE msg\n");
    exit(1);
    }

if (!(RadReadMsg   = CreateStdIO(RadReadPort))) {
    puts("Couldn't create READ msg\n");
    exit(1);
    }
}


FindCorrectMode()
{
if (!strcmp(ModeName, "READ"))
    Mode = READ_MODE;
else if (!strcmp(ModeName, "WRITE"))
    Mode = WRITE_MODE;
else {
    puts("Use READ or WRITE for 'Mode' parameter\n");
    exit(1);
    }
}


SetMessages()
{
RadReadMsg->io_Command  = CMD_READ;
RadWriteMsg->io_Command = CMD_WRITE;
RadReadMsg->io_Length   = 512;
RadWriteMsg->io_Length  = 512;
}


Title()
{
puts("\nXAD 1.0 by Jonathan Forbes\nCopyright (C) Xenomiga Technology, 1989\n");
}


MainProgram()
{
switch (Mode) {
  case READ_MODE:
    DiskToRad();
    break;

  case WRITE_MODE:
    RadToDisk();
    break;
  }
}


CleanUp()
{
DeleteStdIO(RadReadMsg);
DeleteStdIO(RadWriteMsg);
DeletePort(RadWritePort);
DeletePort(RadReadPort);
puts("\n** Done **\n");
}
