Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!think.com!ames!vsi1!zorch!amiga0!mykes From: mykes@amiga0.SF-Bay.ORG (Mike Schwartz) Message-ID: Newsgroups: comp.sys.amiga.programmer Subject: Re: Direct hardware drive access Distribution: world References: <2161@pdxgate.UUCP> Date: 1 Apr 91 09:30:22 PST Organization: Amiga makes it possible In article <2161@pdxgate.UUCP> bairds@eecs.cs.pdx.edu (Shawn L. Baird) writes: >Having finished in my attempts at stepping in and out tracks I have decided >to move on to the more difficult prospect of reading and (eventually) >writing tracks. With this move I have several questions: I don't want to give away all my source code, but this should help. > 3. Is there any way to busy loop on the completion of disk DMA? (I > realize that an interrupt is more elegant, but this is just a test > program.) You don't have to use interrupts for ANYTHING on the Amiga if you don't want to :) ; Wait until DMA write is finished. We poll IRQ bits to find out. move.w #2,INTREQW(a6) ; clear DMA done bit ... >>> set up and start your DMA <<< moveq #2,d1 ; to make Randall happy! l1 move.w INTREQR(a6),d0 and.w d1,d0 beq.s l1 ; 0, not finished. Make sure you do the following, too. ; Our work is done. 'dsklen'=$4000 prevents accidental writes, ; leave IRQ bits and disk DMA off. move.w #$10,DMACONW(a6) ; disable disk dma. move.w #$4000,DSKLENW(a6) ; prevent accidental writes move.w #$1002,INTREQW(a6) ; DSKSYN+DSKBLCK (to make Randall Happy!) > > 4. The hardware manual mentions bugs in both reading and writing data. > Now, how am I expected to compensate for these bugs? For reading, I > assume I request an extra word? > ; After a disk write DMA has finished, a delay of POSTWRITE_TIME ; miliseconds is required before any other operations (drive select, ; step, head change, etc). The type of disk drives used have a gap ; between the erase head and the read-write head. The disk drive keeps ; the erase head enabled after the end of write gate to compensate for ; the gap. Failure to wait out the delay may result in writing over ; innocent data on other tracks or sides. > 5. I use DSKSYNC on $4489. Is this correct, or at least for most disks > such as AmigaDOS disks? If $4489 isn't found does it keep searching > forever? > Here is a fragment of code that will read your track. Remember, before this routine has been called, the motor is up to speed, the heads have been stepped to the correct track, and 12ms of settle time has elapsed. The first thing that is done is DSKRDY is tested to make sure that the disk hasn't been ejected. ReadTrack btst #DSKRDY,CIAA beq.s TrackReader ; there is a disk in the drive move.l #ERROR_NoDisk,tdError move.l tdError,d0 rts TrackReader clr.l tdError move.w #$4000,DSKLENW(a6) ; turn off DMA (to be safe) move.w #$8400,ADKCONW(a6) ; turn on precomp (280ns) move.w #$4489,DSKSYNW(a6) ; sync pattern for start of header move.l #trackBuffer,DSKPTRW(a6) ; set DMA transfer address ; clear pending interrupt requests. move.w #$1002,INTREQW(a6) move.w #$8210,DMACONW(a6) ; enable disk dma move.w #$8000+READSIZE,d0 ; a number here would be more informative... Randall can tell you what READSIZE should be. move.w d0,DSKLENW(a6) ; set length (WORDS) move.w d0,DSKLENW(a6) ; again! This starts DMA ; If the disk has not been formatted, the DSKSYN won't happen. You have ; to use the timer to timeout in this case. ; Wait until DMA write is finished. We poll IRQ bits to find out. .retry move.w #200,d1 ; about 600 ms ; This is similar to StepDelay, except it breaks out ; of the busy wait loop (for DMA finished) even ; if the 3ms time hasn't elapsed. .waitsync move.b CRAA,d0 and.b #%11000000,d0 or.b #%00001000,d0 move.b d0,CRAA move.b #%01111111,ICRA move.b #(2148&255),TALOA move.b #(2148>>8),TAHIA .wait move.w INTREQR(a6),d0 btst #1,d0 ; DMA done? bne.s .done btst #0,ICRA beq.s .wait dbra d1,.waitsync ; sync never happened, move.w #$4000,DSKLENW(a6) ; stop DMA move.w #$10,DMACONW(a6) ; stop DMA move.l #ERROR_NoSync,tdError ; No Sync move.l tdError,d0 rts ; The read is complete. .done move.w #$4000,DSKLENW(a6) move.w #$10,DMACONW(a6) ; stop DMA bra DecodeTrack ; use the blitter! > 7. Does anyone have examples of blitter routines which both encode and > decode raw MFM tracks? The hardware manual mentions this as a > possibility as have several people on Usenet. I suspect this > involves some tricky operation with the line mode, with which I'm > just not well enough adjusted to figure it out for myself. > Maybe there should be a routine provided by trackdisk.device to do this. The blitter code isn't as tricky as you'd think. Here is how the CPU does it: DecodeLongWord move.l (a0)+,d0 move.l (a0)+,d1 andi.l #$55555555,d0 andi.l #$55555555,d1 lsl.l #1,d0 or.l d1,d0 rts >--- > Shawn L. Baird, bairds@eecs.ee.pdx.edu, Wraith on DikuMUD > The above message is not licensed by AT&T, or at least, not yet. -- ******************************************************** * Appendix A of the Amiga Hardware Manual tells you * * everything you need to know to take full advantage * * of the power of the Amiga. And it is only 10 pages! * ********************************************************