******************************************************************** * IDEdrv RBF Device Driver * * (C) 2026 Roelof van Silfhout * * IDEdrv is a RBF device driver -- one * that fetches 256bytes from 512-byte PHYSICAL sectors. * * * * * Edt/Rev YYYY/MM/DD Modified by Comment * ------------------------------------------------------------------ * 0 2026/03/18 Initial version nam IDEdrv ttl RBF ATA/IDE Device Driver use defsfile tylg set Drivr+Objct atrv set ReEnt+rev rev set 0 edition set 1 mod eom,name,tylg,atrv,start,DSKSTA fcb DIR.+SHARE.+PEXEC.+PREAD.+PWRIT.+EXEC.+UPDAT. name fcs /IDEdrv/ fcb edition ********************************************************************* * * Static Storage * * org DRVBEG rmb DRVMEM*DrvCnt V.IDECMD rmb 1 last IDE command DSKSTA equ . * Start of driver code start lbra Init lbra Read lbra Write lbra GetStat lbra SetStat * run terminate direct without lbra instruction! * * Terminate * * Entry: * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Term clrb do nothing, return no error status rts * **** Init * * Entry: * Y = address of device descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Init ldb #DrvCnt get maximum drives supported stb V.NDRV,u save in our device memory leax DRVBEG,u point X to the drive tables lda #$FF load max capacity value * Invalidate V.NDRV drive tables drvx sta DD.TOT+2,x sta V.TRAK,X Inz to high track count leax DRVMEM,x point to next drive table decb decrement counter bne drvx if not zero, continue * Check media type lda PD.TYP,y get type byte anda #TYPH.SSM mask out all but sector size cmpa #TYPH.512 needs to be 512 bytes bne ierr error if not * initialise IDE controller ldx V.PORT,u get hw address get controller base address clr dmaltc,x disable everything force 256byte mode ldb #IDE_LBA set LBA mode stb ideadr3,x LBA 24...27 save ldb idecmst,x read status cmpb #(IDERDY+IDEDSC) idle? lbne initerr drive not ready ldb #H.RST stb idecmst,x restore drive bsr delay isnrdy bsr delay ldb idecmst,x check if done bitb #IDEBSY bne isnrdy clrb return, no errors rts ierr ldb #E$BTyp flag error sector size rts initerr ldb #E$NotRdy set not ready error rts delay lda #64 set up a delay counter del deca decrement the delay count bne del hang in there for the count rts ******************** * Read * * Entry: * B = MSB of the disk's LSN * X = LSB of the disk's LSN * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * * First check if LSN0 is wanted Read cmpx #$0000 LSN 0? bne ReadSect branch if not tstb LSN 0? bne ReadSect branch if not bsr ReadSect else read LSN0 bcs rret if error, return * copying LSN0 data to path descriptor leax DRVBEG,u point X to start of drive table ldb PD.DRV,y get drive number lsn@ beq CopyLSN0 branch if drive zero leax DRVMEM,x else increase X by drive table size decb decrement drive number bra lsn@ branch to loop * X = drive table pointer for PD.DRV * Copy DD.SIZ bytes (LSN0) from buffer to drive table CopyLSN0 ldu PD.BUF,y ldb #DD.SIZ CpyLSNLp pulu a one cycle less than lda ,u+ sta ,x+ decb bne CpyLSNLp rret rts ****** Read Sector * * Single sector read routine * Entry: * Y = address of path descriptor * U = address of device memory area * B = Sector bits 23-16 * X = Sector bits 15-0 * ReadSect lda #H.DMARD IDE read command using DMA sta V.IDECMD,u doides bsr idesetup deal with the hardware settings rts ****** Write Sector * * Entry: * B = MSB of the disk's LSN * X = LSB of the disk's LSN * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * Write lda #H.DMAWR IDE write command using DMA sta V.IDECMD,u bra doides and execute command ******************** * common setup IDE sector transfer using DMA * ***** Setup IDE controller * Entry: U = address of device memory area * Exit: B = status byte for device * destroys A,X idesetup pshs b,y * set DMA start address ldd PD.BUF,y get buffer address to copy data from/to std DMA.SAD DMAC source address register * DMA through MMU select task to use clra system task sta DMA.STSK Task to copy to * fix for LBA mode of addressing sectors ldb #IDE_LBA always use LBA addressing mode lda PD.DRV,y get drive number even numbers are master, odd are slave lsra shift LSBit into carry bcc ex1@ orb #IDE_DSL it is a slave drive ex1@ ldy V.PORT,u base address device in Y stb ideadr3,y LBA 24...27 taken to be 0 puls b stb ideadr2,y LBA 16...23 tfr x,d sta ideadr1,y LBA 8...15 stb ideadr0,y LBA 0...7 ldb #1 one sector at a time stb idescnt,y * setup DMA controller ldd #256 one sector for OS9 std DMA.SBC save in DMA byte counter * check if ide is ready ldb idecmst,y read controller status cmpb #IDERDY+IDEDSC bne ider2 error, not there * setup DMA control bits lda #EXTDMA enable external IO DMA ldb V.IDECMD,u get IDE command to do cmpb #H.DMARD is it a read operation? beq ideps1 branch if so * if writing then add in DMA_RW bit ora #DMAWRT ideps1 sta DMA.SCH place in DMA control register lda #3 sta DAT.CTRL arm DMA controller * enable DMA for IDE device lda #L_DMAEN sta dmaltc,y enable IDE DMA stb idecmst,y issue command * wait for DMA completion * - using HALT so CPU isn't doing much ... ider1 lda idestat,y bita #IDEIRQ beq ider1 wait for completion * DMA done continue with disable device DMA * and check error status clr dmaltc,y prevent DMA * put DMA back in MEM2MEM mode for OS9 calls ldb #MEM2MEM stb DMA.SCH put back in register ldb idecmst,y check status andb #IDEERR leave error bit beq ider2 return if no error ldb #E$NotRdy load error in back puls pc,y ider2 clrb no errors puls pc,y ****** GetStat/SetStat * * Entry: * R$B = function code * Y = address of path descriptor * U = address of device memory area * * Exit: * CC = carry set on error * B = error code * SetStat clrb no action rts GetStat ldx PD.RGS,y get registers ldb R$B,x get caller's B * B has function to do, for now return error ldb #E$UnkSvc unknown service coma ex1 rts emod eom equ * end