root/sys/arch/mac68k/obio/iwmreg.h
/*      $NetBSD: iwmreg.h,v 1.8 2007/03/04 06:00:09 christos Exp $      */

/*
 * Copyright (c) 1996-99 Hauke Fath.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _MAC68K_IWMREG_H
#define _MAC68K_IWMREG_H

/*
 * iwmreg.h -- Interface declarations for iwm.
 */

#ifndef _LOCORE

/*
 * Configuration
 */

/* Virtual Drive flags register */
enum {
        IWM_DS_DISK     = 0x01,
        IWM_NO_DISK     = 0x02,
        IWM_MOTOR_OFF   = 0x04,
        IWM_WRITABLE    = 0x08,
        IWM_DD_DISK     = 0x10,
        IWM_NO_DRIVE    = 0x80000000
};

/*
 * Access
 */
enum {
        noErr = 0,              /* All went well                          */
        noDriveErr = -64,       /* Drive not installed                    */
        offLinErr = -65,        /* R/W requested for an offline drive     */
        noNybErr = -66,         /* Disk is probably blank                 */
        noAdrMkErr = -67,       /* Can't find an address mark             */
        dataVerErr = -68,       /* Read verify compare failed             */
        badCkSmErr = -69,       /* Bad address mark checksum              */
        badBtSlpErr = -70,      /* Bad address mark (no lead-out)         */
        noDtaMkErr = -71,       /* Could not find a data mark             */
        badDCkSum = -72,        /* Bad data mark checksum                 */
        badDBtSlp = -73,        /* One of the data mark bit slip          */
                                /* nibbles was incorrect.                 */
        wrUnderRun = -74,       /* Could not write fast enough to         */
                                /* keep up with the IWM                   */
        cantStepErr = -75,      /*  Step handshake failed during seek     */
        tk0BadErr = -76,        /* Track 00 sensor does not change        */
                                /* during head calibration                */
        initIWMErr = -77,       /* Unable to initialize IWM               */
        twoSideErr = -78,       /* Tried to access a double-sided disk    */
                                /* on a single-sided drive (400K drive)   */
        spAdjErr = -79,         /* Can't adjust drive speed (400K drive)  */
        seekErr = -80,          /* Wrong track number read in a sector's  */
                                /* address field                          */
        sectNFErr = -81,        /* Sector number never found on a track   */
        fmt1Err = -82,          /* Can't find sector 0 after track format */
        fmt2Err = -83,          /* Can't get enough sync                  */
        verErr = -84            /* Track failed to verify                 */
};

#define IWM_TAG_SIZE 20         /* That's what "SonyEqu.a" says          */


/* Buffer for sector header data */
struct sectorHdr {
        u_int8_t side;
        u_int8_t track;
        u_int8_t sector;
        u_int8_t Tags[IWM_TAG_SIZE];
};
typedef struct sectorHdr sectorHdr_t;

/*
 * Cylinder cache data structure
 * Cyl buffer is allocated in fdopen() and deallocated in fdclose().
 *
 * The "valid" flag is overloaded as "dirty" flag when writing
 * to disk.
 */
struct cylCacheSlot {
        unsigned char *secbuf;          /* ptr to one sector buffer */
        int32_t valid;                  /* content valid for cur. cylinder? */
};
typedef struct cylCacheSlot cylCacheSlot_t;


#else /* _LOCORE */


/*
 * Assembler equates for IWM, kept here to ensure consistency.
 * Modelled after <sys/disklabel.h>
 */

/*
 * Offsets into data structures
 */
        /* sectorHdr_t */
        .equ    o_side,         0
        .equ    o_track,        1
        .equ    o_sector,       2
        .equ    o_Tags,         3

        /* cylCacheSlot_t */
        .equ    o_secbuf,       0
        .equ    o_valid,        4

/*
 * Parameter (a6) offsets from <mac68k/obio/iwm_fdvar.h>
 *
 * int iwmReadSector(sectorHdr_t *hdr, cylCacheSlot_t *r_slots, void *buf)
 * int iwmWriteSector(sectorHdr_t *hdr, cylCacheSlot_t *w_slots)
 */
        .equ    o_hdr,           8
        .equ    o_rslots,       12
        .equ    o_wslots,       12
        .equ    o_buf,          16

/*
 * Offsets from IWM base address
 * Lines are set by any memory access to corresponding address (IM III-34/-44).
 * The SWIM has actual registers at these addresses, so writing to them
 * in IWM mode is a no-no. 
 */
        .equ    ph0L,           0x0000  /* CA0 off (0) */
        .equ    ph0H,           0x0200  /* CA0 on  (1) */
        .equ    ph1L,           0x0400  /* CA1 off (0) */
        .equ    ph1H,           0x0600  /* CA1 on  (1) */
        .equ    ph2L,           0x0800  /* CA2 off (0) */
        .equ    ph2H,           0x0A00  /* CA2 on  (1) */
        .equ    ph3L,           0x0C00  /* LSTRB off (low) */
        .equ    ph3H,           0x0E00  /* LSTRB on (high) */
        .equ    mtrOff,         0x1000  /* disk enable off */
        .equ    mtrOn,          0x1200  /* disk enable on */
        .equ    intDrive,       0x1400  /* select internal drive */
        .equ    extDrive,       0x1600  /* select external drive */
        .equ    q6L,            0x1800  /* Q6 off */
        .equ    q6H,            0x1A00  /* Q6 on */
        .equ    q7L,            0x1C00  /* Q7 off */
        .equ    q7H,            0x1E00  /* Q7 on */


/* 
 * VIA Disk SEL line
 */
        .equ    vBufA,          0x1E00  /* Offset from vBase to register A  */
                                        /* (IM III-43) */
        .equ    vHeadSel,       5       /* Multi-purpose line (SEL) */
        .equ    vHeadSelMask,   0x0020  /* Corresponding bit mask */


/*
 * Disk registers       
 *      bit 0 - CA2, bit 1 - SEL, bit 2 - CA0, bit 3 - CA1         IM III name
 */     

        /* Status */
        .equ    stepDirection,  0x0000  /* Direction of next head step       */
                                        /* 0 = in, 1 = out           (DIRTN) */
        .equ    rdDataFrom0,    0x0001  /* Set up drive to read data from    */
                                        /* head 0                  (RDDATA0) */
        .equ    diskInserted,   0x0002  /* Disk inserted                     */
                                        /* 0 = yes, 1 = no           (CSTIN) */
        .equ    rdDataFrom1,    0x0003  /* Set up drive to read data from    */
                                        /* head 1                  (RDDATA1) */
        .equ    stillStepping,  0x0004  /* Drive is still stepping           */
                                        /* 0 = yes, 1 = no            (STEP) */
        .equ    writeProtected, 0x0006  /* Disk is locked                    */
                                        /* 0 = yes, 1 = no          (WRTPRT) */
        .equ    drvMotorState,  0x0008  /* Drive motor is on                 */
                                        /* 0 = yes, 1 = no         (MOTORON) */
        .equ    singleSided,    0x0009  /* Drive is single-sided             */
                                        /* 0 = yes, 1 = no           (SIDES) */
        .equ    atTrack00,      0x000A  /* Head is at track 00               */
                                        /* 0 = yes, 1 = no             (TK0) */
        .equ    headLoaded,     0x000B  /* Head loaded, drive is ready       */
                                        /* 0 = yes, 1 = no               ()  */
        .equ    drvInstalled,   0x000D  /* Disk drive installed              */
                                        /* 0 = yes, 1 = no               ()  */
        .equ    tachPulse,      0x000E  /* Tachometer pulse (60 /rev.)       */
                                        /* 0 = yes, 1 = no           (TACH)  */
        .equ    diskIsHD,       0x000F  /* HD disk detected                  */
                                        /* 0 = yes, 1 = no          (DRVIN)  */

        /* Commands */
        .equ    stepInCmd,      0x0000  /* Head step direction in    (DIRTN) */
        .equ    stepOutCmd,     0x0001  /* Head step direction out (DIRTN+1) */
        .equ    doStepCmd,      0x0004  /* Step head (STEP)                  */
        .equ    motorOnCmd,     0x0008  /* Switch drive motor on   (MOTORON) */
        .equ    motorOffCmd,    0x0009  /* Switch drive motor off (MOTOROFF) */
        .equ    ejectDiskCmd,   0x000D  /* Eject disk from drive     (EJECT) */
        

/*
 * Low level disk errors
 * For simplicity, they are given the MacOS names and numbers.
 */
        .equ    noErr,            0     /* All went well */
        .equ    noDriveErr,     -64     /* Drive not installed */
        .equ    offLinErr,      -65     /* R/W requested for an offline drive */
        .equ    noNybErr,       -66     /* Disk is probably blank */
        .equ    noAdrMkErr,     -67     /* Can't find an address mark */
        .equ    dataVerErr,     -68     /* Read verify compare failed */
        .equ    badCkSmErr,     -69     /* Bad address mark checksum */
        .equ    badBtSlpErr,    -70     /* Bad address mark (no lead-out) */
        .equ    noDtaMkErr,     -71     /* Could not find a data mark */
        .equ    badDCkSum,      -72     /* Bad data mark checksum */
        .equ    badDBtSlp,      -73     /* One of the data mark bit slip */
                                        /* nibbles was incorrect. */
        .equ    wrUnderRun,     -74     /* Could not write fast enough to */
                                        /* keep up with the IWM */
        .equ    cantStepErr,    -75     /* Step handshake failed during seek */
        .equ    tk0BadErr,      -76     /* Track 00 sensor does not change */
                                        /* during head calibration */
        .equ    initIWMErr,     -77     /* Unable to initialize IWM */
        .equ    twoSideErr,     -78     /* Tried to access a double-sided disk */
                                        /* on a single-sided drive (400K drive) */
        .equ    spAdjErr,       -79     /* Can't adjust drive speed (400K drive) */
        .equ    seekErr,        -80     /* Wrong track number read in a  */
                                        /* sector's address field */
        .equ    sectNFErr,      -81     /* Sector number never found on a track */
        .equ    fmt1Err,        -82     /* Can't find sector 0 after  */
                                        /* track format */
        .equ    fmt2Err,        -83     /* Can't get enough sync */
        .equ    verErr,         -84     /* Track failed to verify */

/*
 * Misc constants
 */
        .equ    iwmMode,        0x17    /* SWIM switch */
        .equ    maxGCRSectors,  12      /* Max. sectors per track for GCR */
          

#endif /* _LOCORE */

#endif /* _MAC68K_IWMREG_H */