#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"
#include "fcntl.h"

#define TD_READ CMD_READ
#define BLOCKSIZE TD_SECTOR
#define NUMCYLS 79
#define NUMHEADS 2

SHORT error;
struct MsgPort *diskport;
struct IOExtTD *diskreq;
APTR diskdata;
SHORT testval;
 
extern struct MsgPort *CreatePort();
extern struct IORequest *CreateExtIO();
 
ULONG diskChangeCount;

BYTE  header[] =
{
  00,00,03,0xf3,00,00,00,00,00,00,00,01,
  00,00,00,00,
  00,00,00,00,00,00,02,00,00,00,03,0xe9,
  00,00,02,00
};

BYTE tail[] =
{
  00,00,03,0xf2
};

ReadCylSec(cyl, sec, hd)
SHORT cyl, sec, hd;
{
        LONG offset;
 
        diskreq->iotd_Req.io_Length = BLOCKSIZE;
        diskreq->iotd_Req.io_Data = diskdata;
        diskreq->iotd_Req.io_Command = ETD_READ;
        diskreq->iotd_Count = diskChangeCount;
        offset = TD_SECTOR * (sec + NUMSECS * hd + NUMSECS * NUMHEADS * cyl);
        diskreq->iotd_Req.io_Offset = offset;
        DoIO(diskreq);
        return(0);
}
  
MotorOn()
{
        diskreq->iotd_Req.io_Length = 1;
        diskreq->iotd_Req.io_Command = TD_MOTOR;
        DoIO(diskreq);
        return(0);
}
 
MotorOff()
{
        diskreq->iotd_Req.io_Length = 0;
        diskreq->iotd_Req.io_Command = TD_MOTOR;
        DoIO(diskreq);
        return(0);
}
  
main()   
{
        SHORT cylinder,head,sector;
        int fh,err;

        fh=open("ram:kick.hex",O_RDWR|O_CREAT,O_CREAT);
        if(fh==-1){
          printf("fehler open\n");
          return(10);
        }

        diskdata = (APTR)AllocMem(BLOCKSIZE,MEMF_CHIP);
        diskport = CreatePort(0,0);
        if(diskport == 0) exit(100);    /* error in createport */
        diskreq = (struct IOExtTD *)CreateExtIO(diskport,
                                                sizeof(struct IOExtTD));
        if(diskreq == 0) { DeletePort(diskport); exit(200); }
 
            error = OpenDevice(TD_NAME,0,diskreq,0);
            diskreq->iotd_Req.io_Command = TD_CHANGENUM;
            DoIO(diskreq);
            diskChangeCount = diskreq->iotd_Req.io_Actual;
            MotorOn();
            cylinder=0;
            head=0;
            dwrite(fh,&header[0],sizeof(header));
            for(sector=1; sector<5; sector++)
              {
                 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);
                 dwrite(fh,diskdata,BLOCKSIZE);
               }
            dwrite(fh,&tail[0],sizeof(tail));
            MotorOff();
            CloseDevice(diskreq);
 
        DeleteExtIO(diskreq, sizeof(struct IOExtTD));
        DeletePort(diskport);

        err=close(fh);
        if(err==-1){
           printf("fehler close\n");
        }
       return(0);
}       /* end of main */
 
 
 
 
 
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);
}
  
  
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);
    return(0);
}
