home *** CD-ROM | disk | FTP | other *** search
- /*
- * MyTDIO.c
- *
- * Handles a trackdisk RAW read with WORDSYNC.
- * I can't get the ETD_RAWREAD to work, so coded one myself. DAV
- */
-
- #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 <hardware/custom.h>
- #include <hardware/cia.h>
- #include <hardware/intbits.h>
- #include <hardware/adkbits.h>
- #include <hardware/dmabits.h>
- #include <resources/disk.h>
-
- #define __NO_PRAGMAS
- #include <functions.h>
-
- #define CIAF_DSKSELALL (CIAF_DSKSEL3 | CIAF_DSKSEL2\
- | CIAF_DSKSEL1 | CIAF_DSKSEL0)
-
- #ifndef NUMHEADS
- #define NUMHEADS 2
- #endif
-
- extern struct Custom custom;
- extern struct CIA ciaa, ciab;
-
- /* Above doesn't seem to work with Aztec, small data model, so ... */
-
- #define CUSTOMADD ((struct Custom *)0xdff000)
- #define CIAAADD ((struct CIA *)0xbfe001)
- #define CIABADD ((struct CIA *)0xbfd000)
-
- /*
- * Disable/Enable interrupts at the CPU
- */
- static APTR sysStack;
- static ULONG oldSR;
-
- cpuDisable()
- {
- oldSR = SetSR(0x700L,0x700L);
- sysStack = SuperState();
- }
- cpuEnable()
- {
- if(sysStack) UserState(sysStack);
- SetSR(oldSR,0x700L);
- }
-
-
- /* make a special read request up */
-
- MyTDIO(struct IOExtTD *tdreq)
- {
- struct Custom *pcustom = CUSTOMADD; /*&custom;*/
- struct CIA *pciaa = CIAAADD; /*&ciaa;*/
- struct CIA *pciab = CIABADD; /*&ciab;*/
-
- UWORD command;
- ULONG actual,length,offset;
- APTR data;
- UBYTE flags;
- int drive,head;
- UWORD dsklenw;
- long timeout;
-
- struct IOStdReq *req = (struct IOStdReq *) tdreq;
-
- if(!(req->io_Command == ETD_RAWREAD || req->io_Command == TD_RAWREAD)) {
- req->io_Error = 100;
- return;
- }
-
- /* our request - local copy parameters */
- command = req->io_Command;
- flags = req->io_Flags;
- actual = req->io_Actual; /* SPECIAL - expect drive unit # here */
- length = req->io_Length;
- data = req->io_Data;
- offset = req->io_Offset; /* Track (not cyl) */
-
- drive = actual;
- head = offset % (NUMSECS*TD_SECTOR);
-
- /* Seek to track */
-
- req->io_Offset = offset * (NUMSECS*TD_SECTOR);
- req->io_Command = TD_SEEK;
- DoIO((struct IORequest *)req);
- if(req->io_Error != 0) {
- req->io_Error = 101;
- return;
- }
-
- /* Do raw - read magic */
-
- cpuDisable();
-
- pcustom->dmacon = DMAF_SETCLR | DMAF_DISK | DMAF_MASTER;
-
- /* turn OFF bits - not GCR, and no pre-comp. for now */
- pcustom->adkcon = ADKF_PRECOMP0|ADKF_PRECOMP1|ADKF_MSBSYNC|ADKF_WORDSYNC;
- /* turn ON bits - mfm */
- pcustom->adkcon = ADKF_SETCLR|ADKF_WORDSYNC|ADKF_MFMPREC|ADKF_FAST;
- /* turn ON wordsync if required */
- if(flags & IOTDF_WORDSYNC)
- pcustom->adkcon = ADKF_SETCLR|ADKF_WORDSYNC;
-
-
- pcustom->dsksync = 0x4489;
-
- pcustom->dsklen = DSKDMAOFF; /* 0x4000 */
- pcustom->dskpt = data;
- dsklenw = 0x8000 | ((length >> 1) & 0x3fff);
- pciab->ciaprb &= ~CIAF_DSKMOTOR; /* ensure motor on */
-
- if(drive == 0)
- pciab->ciaprb &= ~CIAF_DSKSEL0;
- else if(drive == 1)
- pciab->ciaprb &= ~CIAF_DSKSEL1;
- else if(drive == 2)
- pciab->ciaprb &= ~CIAF_DSKSEL2;
- else if(drive == 3)
- pciab->ciaprb &= ~CIAF_DSKSEL3;
-
- if(head == 0)
- pciab->ciaprb &= ~CIAF_DSKSIDE;
- else
- pciab->ciaprb |= CIAF_DSKSIDE;
-
- pcustom->dsklen = dsklenw; /* first write */
-
- timeout = 0;
- while(pciaa->ciapra & CIAF_DSKRDY) { /* wait for ready */
- if(++timeout > 1000000L) {
- pcustom->dsklen = DSKDMAOFF;
- pciab->ciaprb |= (CIAF_DSKSELALL);
- cpuEnable();
- req->io_Error = 102;
- return; /* timed out waiting for ready */
- }
- }
-
- if(flags & IOTDF_INDEXSYNC) {
- timeout = pciab->ciaicr;
- timeout = 0;
- while(!(pciab->ciaicr & CIAICRF_FLG)) { /* wait for index pls */
- if(++timeout > 1000000L) {
- pcustom->dsklen = DSKDMAOFF;
- pciab->ciaprb |= (CIAF_DSKSELALL);
- cpuEnable();
- req->io_Error = 103;
- return; /* timed out waiting for index */
- }
- }
- }
-
- pcustom->intena = INTF_SETCLR | INTF_DSKBLK;
- pcustom->intreq = INTF_DSKBLK; /* clear pending DMA-done */
- pcustom->dsklen = dsklenw; /* second write - start DMA*/
- timeout = 0;
- while(!(pcustom->intreqr & INTF_DSKBLK)) { /* wait for DMA done */
- if(++timeout > 1000000L) {
- pcustom->dsklen = DSKDMAOFF;
- pciab->ciaprb |= (CIAF_DSKSELALL);
- cpuEnable();
- req->io_Error = 104;
- return; /* timed out waiting for DMA */
- }
- }
- pciab->ciaprb |= (CIAF_DSKSELALL);
- pcustom->dsklen = DSKDMAOFF;
- pcustom->intreq = INTF_DSKBLK; /* clear DMA-done */
- cpuEnable();
- req->io_Error = 0;
-
- return;
- }
-
-