/* This program is probably copyright Commodore-Amiga. It was mailed * to me directly by Robert Peck at Commodore-Amiga in response * to a question about a previous version's copyright status. I * therefore assume that it is Commodore-Amiga's intention that this * program be freely redistributable. Fred Fish, 3-Jan-86. */ /* trackdisk.c */ /* program to demonstrate the use of the trackdisk driver */ /* author: Rob Peck, 12/1/85 */ /* This code may be freely utilized to develop programs for the Amiga */ #include "exec/types.h" #include "exec/nodes.h" #include "exec/lists.h" #include "exec/memory.h" #include "exec/interrupts.h" #include "exec/ports.h" #include "exec/libraries.h" #include "exec/io.h" #include "exec/tasks.h" #include "exec/execbase.h" #include "exec/devices.h" #include "devices/trackdisk.h" #define TD_READ CMD_READ #define BLOCKSIZE TD_SECTOR SHORT error; struct MsgPort *diskport; struct IOExtTD *diskreq; BYTE diskbuffer[BLOCKSIZE]; BYTE *diskdata; SHORT testval; extern struct MsgPort *CreatePort(); extern struct IORequest *CreateExtIO(); ULONG diskChangeCount; ReadCylSec(cyl, sec, hd) SHORT cyl, sec, hd; { LONG offset; diskreq->iotd_Req.io_Length = BLOCKSIZE; diskreq->iotd_Req.io_Data = (APTR)diskbuffer; /* show where to put the data when read */ diskreq->iotd_Req.io_Command = ETD_READ; /* check that disk not changed before reading */ diskreq->iotd_Count = diskChangeCount; /* convert from cylinder, head, sector to byte-offset value to get * right one (as dos and everyone else sees it)...*/ /* driver reads one CYLINDER at a time (head does not move for * 22 sequential sector reads, or better-put, head doesnt move for * 2 sequential full track reads.) */ offset = TD_SECTOR * (sec + NUMSECS * hd + NUMSECS * NUMHEADS * cyl); diskreq->iotd_Req.io_Offset = offset; DoIO(diskreq); return(0); } MotorOn() { /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */ diskreq->iotd_Req.io_Length = 1; /* this says motor is to be turned on */ diskreq->iotd_Req.io_Command = TD_MOTOR; /* do something with the motor */ DoIO(diskreq); printf("\nOld motor state was: %ld",diskreq->iotd_Req.io_Actual); printf("\nio_Error value was: %ld",diskreq->iotd_Req.io_Error); return(0); } MotorOff() { printf("\n\nNow turn it off"); diskreq->iotd_Req.io_Length = 0; /* says that motor is to be turned on */ diskreq->iotd_Req.io_Command = TD_MOTOR; /* do something with the motor */ DoIO(diskreq); printf("\nOld motor state was: %ld",diskreq->iotd_Req.io_Actual); printf("\nio_Error value was: %ld",diskreq->iotd_Req.io_Error); return(0); } SeekFullRange(howmany) SHORT howmany; { int i; for(i=0; iiotd_Req.io_Offset = ((NUMCYLS -1)*NUMSECS*NUMHEADS -1 ) * 512; /* seek to cylinder 79, head 1 */ diskreq->iotd_Req.io_Command = TD_SEEK; DoIO(diskreq); if(diskreq->iotd_Req.io_Error != 0) printf("\nSeek Cycle Number %ld, Error = %ld", i, diskreq->iotd_Req.io_Error); diskreq->iotd_Req.io_Offset = 0; /* seek to cylinder 0, head 0 */ diskreq->iotd_Req.io_Command = TD_SEEK; DoIO(diskreq); if(diskreq->iotd_Req.io_Error != 0) printf("\nSeek Cycle Number %ld, Error = %ld", i, diskreq->iotd_Req.io_Error); printf("\nCompleted a seek"); } return(0); } main() { SHORT cylinder,head,sector; diskdata = &diskbuffer[0]; /* point to first location in disk buffer */ diskport = CreatePort(0,0); if(diskport == 0) exit(100); /* error in createport */ diskreq = (struct IOExtTD *)CreateExtIO(diskport, sizeof(struct IOExtTD)); /* make an io request block for communicating with the disk */ if(diskreq == 0) { DeletePort(diskport); exit(200); } error = OpenDevice(TD_NAME,0,diskreq,0); /* open the device for access, unit 0 is builtin drive */ printf("\nError value returned by OpenDevice was: %lx", error); /* now get the disk change value */ diskreq->iotd_Req.io_Command = TD_CHANGENUM; DoIO(diskreq); diskChangeCount = diskreq->iotd_Req.io_Actual; printf("\nChange number for disk is currently %ld",diskChangeCount); MotorOn(); SeekFullRange(10); for(cylinder=0; cylinder<80; cylinder++) /* tracks to test */ { for(head=0; head<2; head++) /* number of heads to test */ for(sector=0; sector<11; sector++) /* sectors to test */ { ReadCylSec(cylinder, sector, head); if(diskreq->iotd_Req.io_Error != 0) printf("\nError At Cyl=%ld, Sc=%ld, Hd=%ld, Error=%ld", cylinder,sector,head, diskreq->iotd_Req.io_Error); } printf("\nCompleted reading Cylinder=%ld",cylinder); } MotorOff(); CloseDevice(diskreq); DeleteExtIO(diskreq, sizeof(struct IOExtTD)); DeletePort(diskport); } /* end of main */ /*********************************************************************** * * Exec Support Function -- Extended IO Request * ***********************************************************************/ extern APTR AllocMem(); /****** exec_support/CreateExtIO ************************************** * * NAME * CreateExtIO() -- create an Extended IO request * * SYNOPSIS * ioReq = CreateExtIO(ioReplyPort,size); * * FUNCTION * Allocates memory for and initializes a new IO request block * of a user-specified number of bytes. * * INPUTS * ioReplyPort - a pointer to an already initialized * message port to be used for this IO request's reply port. * * RESULT * Returns a pointer to the new block. Pointer is of the type * struct IORequest. * * 0 indicates inability to allocate enough memory for the request block * or not enough signals available. * * EXAMPLE * struct IORequest *myBlock; * if( (myBlock = CreateExtIO(myPort,sizeof(struct IOExtTD)) == NULL) * exit(NO_MEM_OR_SIGNALS); * * example used to allocate space for IOExtTD (trackdisk driver * IO Request block for extended IO operations). * * SEE ALSO * DeleteExtIO * ***********************************************************************/ struct IORequest *CreateExtIO(ioReplyPort,size) struct MsgPort *ioReplyPort; LONG size; { struct IORequest *ioReq; if (ioReplyPort == 0) return ((struct IORequest *) 0); ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC); if (ioReq == 0) return ((struct IORequest *) 0); ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE; ioReq -> io_Message.mn_Node.ln_Pri = 0; ioReq -> io_Message.mn_ReplyPort = ioReplyPort; return (ioReq); } /****** exec_support/DeleteExtIO ************************************** * * NAME * DeleteExtIO() - return memory allocated for extended IO request * * SYNOPSIS * DeleteExtIO(ioReq,size); * * FUNCTION * See summary line at NAME. Also frees the signal bit which * had been allocated by the call to CreateExtIO. * * INPUTS * A pointer to the IORequest block whose resources are to be freed. * * RESULT * Frees the memory. Returns (no error conditions shown) * * EXAMPLE * struct IORequest *myBlock; * DeleteExtIO(myBlock,(sizeof(struct IOExtTD))); * * example shows that CreateExtIO had been used to create a trackdisk * (extended) IO Request block. * * SEE ALSO * CreateExtIO * **************************************************************************/ DeleteExtIO(ioExt,size) struct IORequest *ioExt; LONG size; { ioExt -> io_Message.mn_Node.ln_Type = 0xff; ioExt -> io_Device = (struct Device *) -1; ioExt -> io_Unit = (struct Unit *) -1; FreeMem (ioExt, size); }