#ifndef HIDEUNITS20_H
#define HIDEUNITS20_H   (1)

/*****************************************************************
 *                                                               *
 *  Filename:   hideunits20.h                                    *
 *  Release:    1.62                                             *
 *  Date:       13.11.1991 17:13                                 *
 *                                                               *
 *  'hidedisk.device' - Unit definitions.                        *
 *  20 sectors version.                                          *
 *                                                               *
 *  (C) Copyright 1991 Stefan Klensch All Rights Reserved        *
 *                                                               *
 *****************************************************************/

#ifndef EXEC_TYPES_H
#include "exec/types.h"
#endif

#include "exec/exec.h"

#ifndef EXEC_SEMAPHORES_H
#include "exec/semaphores.h"
#endif

#ifndef DEVICES_TIMER_H
#include "devices/timer.h"
#endif

#ifndef RESOURCES_DISK_H
#include "resources/disk.h"
#endif

#ifndef HIDESECS20_H
#include "hidesecs20.h"
#endif

/*****************************************************************
 * JmpTable                                                      *
 *****************************************************************
 * An address of such a jmptable will be relinked into private   *
 * unit structure for relative jumping on mode (HD/DD)           *
 *****************************************************************/

struct JmpTable {                           /* startof                      */
    void    (*jt_DecodeLong)();             /* decode one long              */
    void    (*jt_DecodeData)();             /* decode no checksum           */
    void    (*jt_DecWithChk)();             /* decode + chksum              */
    void    (*jt_DecodeSecLabel)();         /* decode sector label          */

    void    (*jt_EncodeLong)();             /* encode one long              */
    void    (*jt_EncodeLongs)();            /* encode more longs            */
    void    (*jt_EncChkSetData)();          /* encode,make+set datachksum   */
    void    (*jt_EncodeSecLabel)();         /* encode sector label          */

    void    (*jt_AdjustFormatSec)();        /* make edges of sec            */

    void    (*jt_SetHdrChkSum)();           /* set header's chk             */
    void    (*jt_CmpHdrChkSum)();           /* compare chksum hdr           */
    void    (*jt_SetDatChkSum)();           /* set data chk                 */
    void    (*jt_CmpDatChkSum)();           /* compare data chksum          */

    void    (*jt_CopyRawSecs)();            /* copy raw sectors             */
    };                                      /* sizeof                       */

/*****************************************************************
 * PrivateUnit                                                   *
 *****************************************************************
 * This keeps all informations necessary for accessing HD/DD     *
 * disks correctly.                                              *
 *****************************************************************/

struct PrivateUnit {                        /* startof                      */

/*****************************************************************
 * Jmptable for mode-specific routines.                          *
 *****************************************************************/

    struct  JmpTable *pru_JmpTable;         /* this unit's jmptab           */

/*****************************************************************
 * Backward reference to master-device and public unit.          *
 *****************************************************************/

    APTR    pru_Device;                     /* ref to device                */
    APTR    pru_PublicUnit;                 /* ref to public unit           */

/*****************************************************************
 * Technical constants this unit.                                *
 *****************************************************************/

    UWORD   pru_NumSecs;                    /* # sectors                    */
    UWORD   pru_NumTracks;                  /* # tracks                     */
    UWORD   pru_Sync;                       /* syncword 16 bit              */
    UWORD   pru_Precomp01;                  /* precomp start track          */

    UWORD   pru_ReadSz;                     /* read-size DMA                */
    UWORD   pru_WriteSz;                    /* write-size DMA               */
    UWORD   pru_GapSz;                      /* sizeof gap front/rear        */
    UWORD   pru_SecSz;                      /* rawsector size (encoded)     */
    UWORD   pru_TrackSz;                    /* sizeof rawtrack              */

    UWORD   pru_SearchGap;                  /* gap for searching hdrs       */
    UWORD   pru_SearchSectorSkip;           /* skipsize searching hdrs      */
    UWORD   pru_LinearSkipBack;             /* skipback for linearsectors   */
    UWORD   pru_LSyncToHdr;                 /* offset lsync->header         */
    UWORD   pru_SecDatOff;                  /* sector data offset from hdr  */
    UWORD   pru_ReadBufOff;                 /* offset read                  */

    ULONG   pru_LSync;                      /* syncword 32 bit              */
    ULONG   pru_MaxOffset;                  /* max. offset                  */
    ULONG   pru_TimeOut;                    /* timeout blkdma               */

/*****************************************************************
 * Private diskstate/type.                                       *
 *****************************************************************/

    UBYTE   pru_DiskType;                   /* type of (HD or not)          */
    UBYTE   pru_DiskEmpty;                  /* TRUE if this has no disk     */
    UBYTE   pru_DiskDense;                  /* 1 if HD                      */
    UBYTE   pru_Retries;                    /* private # retries            */
    UBYTE   pru_SecId;                      /* sector id                    */
    UBYTE   pru_Pad0;                       /* fill                         */

/*****************************************************************
 * Private diskchange-support.                                   *
 *****************************************************************/

    struct  MinList pru_ChgIrList;          /* list for diskchange-link     */

    struct  Interrupt *pru_SingleChgIr;     /* single-ir                    */
    ULONG   pru_ChangeCnt;                  /* changecounter                */
    };                                      /* endof                        */

/*****************************************************************
 * UserUnit                                                      *
 *****************************************************************
 * This little structure will be relinked into user's iosr on    *
 * successful Opens.                                             *
 *****************************************************************/

struct UserUnit {                           /* startof                      */
    struct  PrivateUnit *usu_PrivateUnit;   /* ptr to privateunit           */
    ULONG   usu_OpenFlags;                  /* user's openflags             */
    };                                      /* sizeof                       */

/*****************************************************************
 * HideBltNode                                                   *
 *****************************************************************
 * This structure will be used for blitter - usage in MFM mode.  *
 * It keeps all stuff necessary for blitter, pointers...         *
 *****************************************************************/

struct HideBltNode {                        /* startof                      */

/*****************************************************************
 * From here to hbn_Cleanup, this is a standard bltnode (see     *
 * hardware/blit.h).                                             *
 *****************************************************************/

    struct  HideBltNode *hbn_Next;          /* next in list                 */
    long    (*hbn_Function)();              /* func to call                 */

    BYTE    hbn_Stat;                       /* not used                     */
    BYTE    hbn_Dummy;                      /* not used                     */

    WORD    hbn_BltSize;                    /* blitter's size               */
    WORD    hbn_BeamSync;                   /* not used                     */

    long    (*hbn_Cleanup)();               /* not used                     */

/*****************************************************************
 * # of bytes, source and destination address.                   *
 *****************************************************************/

    ULONG   hbn_Bytes;                      /* # bytes blitting             */
    UWORD   *hbn_Source;                    /* srcptr                       */
    UWORD   *hbn_Dest;                      /* dstptr                       */

/*****************************************************************
 * Backward reference to private unit.                           *
 *****************************************************************/

    struct  PrivateUnit *hbn_PrivUnit;      /* priv. unitptr caller         */

/*****************************************************************
 * Field to store next B/A/Dptr. On multiple blit operations     *
 * (MFM encoding), pointers will be precomputed while blit is    *
 * in progress and stuffed when blit finished.                   *
 *****************************************************************/

    UWORD   *hbn_NextBAD[3];                /* next ptrs to stuff           */
    };                                      /* endof                        */

/*****************************************************************
 * IndexData                                                     *
 *****************************************************************
 * This data is linked into DRU_HNDEX - interrupt's IS_DATA      *
 * field and is used for easier transfer-start of DMA.           *
 *****************************************************************/

struct IndexData {                          /* startof                      */
    ULONG   ixdat_DmaWords;                 /* # words for transfer         */
    void    (*ixdat_DmaStart)();            /* start-routine DMA            */
    struct  PrivateUnit *ixdat_PrivUnit;    /* privunit current             */
    APTR    ixdat_Device;                   /* backward dev-reference       */
    };                                      /* endof                        */

/*****************************************************************
 * PublicUnit                                                    *
 *****************************************************************
 * This structure is and keeps the public part, which is shared  *
 * by the unit owners HD and DD                                  *
 *****************************************************************/

struct PublicUnit {                         /* startof                      */
    struct  Unit puu_Unit;                  /* std execunit                 */

/*****************************************************************
 * Cache control section, MUST stand here (xx(ax,dx))            *
 * On 20 sectors, GCR_SECTORS is increased to 20 sectors to      *
 * be equal with 20 sector unit.                                 *
 *****************************************************************/

    UWORD   *puu_CachePtrs[GCR_SECTORS];    /* ptrs for HD/DD               */
    BYTE    puu_CacheErrs[GCR_SECTORS];     /* error-field                  */

    UWORD   puu_CacheTrack;                 /* track in cache               */
    UWORD   *puu_CacheDataStart;            /* start of cachedata           */
    UBYTE   puu_CacheFlags;                 /* flags                        */
    UBYTE   puu_CachePad0;                  /* fillbyte                     */

/*****************************************************************
 * DD and HD private unit                                        *
 *****************************************************************/

    struct  PrivateUnit puu_DDPru;          /* privunit DD                  */
    struct  PrivateUnit puu_HDPru;          /* privunit HD                  */

/*****************************************************************
 * Backward reference to master.                                 *
 *****************************************************************/

    APTR    puu_Device;                     /* devptr hide                  */

/*****************************************************************
 * Unitnumber and process-control flags.                         *
 *****************************************************************/

    UBYTE   puu_UnitNum;                    /* number of unit               */
    UBYTE   puu_Flags;                      /* own flags, see below         */
    UBYTE   puu_MotOffDelays;               /* delaycnt motor off           */
    UBYTE   puu_DskCtrl;                    /* current state disk           */
    UBYTE   puu_Turbo;                      /* set if 68020/higher          */
    UBYTE   puu_UserMemOdd;                 /* true, if usermem odd         */
    UBYTE   puu_UserMemChip;                /* true, if usermem in chip     */

/*****************************************************************
 * Read/Write section (std read/write).                          *
 *****************************************************************/

    UBYTE   puu_RWSector;                   /* read/write sector            */
    UWORD   puu_RWTrack;                    /* read/write track             */
    UWORD   *puu_RWBuf;                     /* read/write buf               */
    UWORD   *puu_RWSecLabel;                /* read/write seclabel          */

/*****************************************************************
 * Current track head is above.                                  *
 *****************************************************************/

    WORD    puu_CurTrack;                   /* current track                */

/*****************************************************************
 * Msgports for timer/dru message - sends/replies.               *
 *****************************************************************/

    struct  MsgPort puu_DruTimerMp;         /* timer reply/dru              */

/*****************************************************************
 * Diskresource-Unit for port allocation and INDEX/WORDSYNC      *
 * interrupt recognition.                                        *
 *****************************************************************/

    struct  DiscResourceUnit puu_Dru;       /* DiskResource-Unit            */

/*****************************************************************
 * VBlank and MicroHz Timer for waiting.                         *
 *****************************************************************/

    struct  timerequest puu_VBTimerIO;      /* timereq vblank               */
    struct  timerequest puu_MHTimerIO;      /* timereq micro                */

/*****************************************************************
 * Task section, std Exec task                                   *
 *****************************************************************/

    struct  Task puu_Task;                  /* task struct                  */

/*****************************************************************
 * Buffer section, chipbuffer r/w pointer to current for hard-   *
 * read/write and private chip sector for fast -> chip copy.     *
 *****************************************************************/

    UWORD   *puu_TrackBuf;                  /* trackbuffer                  */
    UWORD   *puu_PrivChipSec;               /* private chip sector          */

/*****************************************************************
 * Bsy section, masterflag, sectors decoded, read as write-      *
 * prepare and syncs found by synchandler.                       *
 *****************************************************************/

    UBYTE   puu_BsyMode;                    /* TRUE, if to do busy          */
    UBYTE   puu_BsySecsDecode;              /* # secs decoded bsy           */
    UBYTE   puu_BsyWriteRead;               /* read before write            */
    UBYTE   puu_BsyPad0;                    /* fill                         */
    UWORD   puu_BsySyncsFound;              /* #syncs found                 */

/*****************************************************************
 * Signal semaphore for change-support.                          *
 * This inhibits those ugly problems removing/adding diskchange- *
 * interrupts while unittask scans list after diskremove/insert. *
 *****************************************************************/

    struct  SignalSemaphore puu_ChgSigSem;  /* signalsem for lock           */

/*****************************************************************
 * Delays for step/settle/recalibrate.                           *
 *****************************************************************/

    ULONG   puu_StepDelay;                  /* delay one step               */
    ULONG   puu_SettleDelay;                /* delay after seekend          */
    ULONG   puu_Seek000Delay;               /* recalibrate                  */

/*****************************************************************
 * HideBlitNode for MFM blitter support.                         *
 *****************************************************************/

    struct  HideBltNode puu_Hbn;            /* private bltnode              */

/*****************************************************************
 * Custom base of Amiga hardware                                 *
 * Remarked here to avoid absolute long 'lea' (codespace).       *
 *****************************************************************/

    struct  Custom *puu_CustomBase;         /* ptr customregs               */
    };                                      /* endof                        */

/*****************************************************************
 * Definitions for puu_CacheFlags                                *
 *****************************************************************/

#define PUUCB_HIGHDENS  (5)                 /* buf has high-density cache   */
#define PUUCF_HIGHDENS  (1 << 5)

#define PUUCB_REORG     (4)                 /* buf reorganized for write    */
#define PUUCF_REORG     (1 << 4)

#define PUUCB_SHORT     (3)                 /* short cache (write -2)       */
#define PUUCF_SHORT     (1 << 3)

#define PUUCB_ERROR     (2)                 /* buf has chksum/sector err(s) */
#define PUUCF_ERROR     (1 << 2)

#define PUUCB_NODMA     (1)                 /* nosechdr reading wordsync    */
#define PUUCF_NODMA     (1 << 1)

#define PUUCB_CHANGED   (0)                 /* buf was changed by write     */
#define PUUCF_CHANGED   (1 << 0)

/*****************************************************************
 * Unknown track for cache-clearing/making invalid.              *
 *****************************************************************/

#define PUUC_UNKNOWN    (-1)                /* this doesn't exist           */

/*****************************************************************
 * Clearmask for search headers.                                 *
 *****************************************************************/

#define PUUC_SEARCH     (~(PUUCF_REORG|PUUCF_ERROR|PUUCF_SHORT))

/*****************************************************************
 * Unknown track for CurTrack                                    *
 *****************************************************************/

#define CURTRACK_UNKNOWN    (-2)            /* not equal PUUC_UNKNOWN !     */

/*****************************************************************
 * Flags for OpenDevice(). Unit's default is read/write with     *
 * BsyDecode/Encode (Decodes while Disk-DMA is in progress !!)   *
 * and no 'click' if no disk is in drive.                        *
 *                                                               *
 * PUUOF_NOTBSY  = 1 disables bsy-decoding (= trackdisk).        *
 * PUUOF_DOKLICK = 1 enables those noisy 'click's.               *
 *****************************************************************/

#define PUUOB_NOTBSY    (4)                 /* read not busy, if 1          */
#define PUUOF_NOTBSY    (1 << 4)

#define PUUOB_DOKLICK   (5)                 /* clicks on, if 1              */
#define PUUOF_DOKLICK   (1 << 5)

/*****************************************************************
 * Flags - Definitions for puu_Flags                             *
 *****************************************************************/

#define PUUB_DELOFF     (7)                 /* delayed motor off            */
#define PUUF_DELOFF     (1 << 7)

#define PUUB_NOKLICK    (6)                 /* no click, if 1               */
#define PUUF_NOKLICK    (1 << 6)

#define PUUB_STOPPED    (5)                 /* unit stopped                 */
#define PUUF_STOPPED    (1 << 5)

#define PUUB_MOTON      (4)                 /* motor on, if 1               */
#define PUUF_MOTON      (1 << 4)

#define PUUB_CLOSE      (3)                 /* unit closed, remove          */
#define PUUF_CLOSE      (1 << 3)

#define PUUB_EXT        (2)                 /* ext cmd, if 1                */
#define PUUF_EXT        (1 << 2)

#define PUUB_EMPTY      (1)                 /* no disk in drive, if 1       */
#define PUUF_EMPTY      (1 << 1)

#define PUUB_LAB        (0)                 /* seclabel usage, if 1         */
#define PUUF_LAB        (1 << 0)

/*****************************************************************
 * Private task-signals unittask.                                *
 * DMABLK occurs after read/write end of Disk-DMA.               *
 *****************************************************************/

#define SIGB_DMABLK     (11)                /* dma block end                */
#define SIGF_DMABLK     (1 << 11)

/*****************************************************************
 * TIMEDRU will be sent by disk.resource, if we got our stuff or *
 * by end of microhz-delay.                                      *
 *****************************************************************/

#define SIGB_DRUTIME    (10)                /* dru regot/timer end          */
#define SIGF_DRUTIME    (1 << 10)

/*****************************************************************
 * NEWIO sent by VBlankTimer - Reply (DChange) or IOSTD from     *
 * BeginIO's PutMsg.                                             *
 *****************************************************************/

#define SIGB_NEWIO      (9)                 /* new io inport                */
#define SIGF_NEWIO      (1 << 9)

/*****************************************************************
 * KICKON restarts task after unit has been stopped.             *
 *****************************************************************/

#define SIGB_KICKON     (8)                 /* kickon after sleep           */
#define SIGF_KICKON     (1 << 8)

/*****************************************************************
 * BLTEND will arrive after QBlit is finished in MFM mode.       *
 *****************************************************************/

#define SIGB_BLTEND     (4)                 /* qblit finished               */
#define SIGF_BLTEND     (1 << 4)

/*****************************************************************
 * INITREPLY is the answer of unittask when he's ready with      *
 * own initialization.                                           *
 *****************************************************************/

#define SIGB_INITREPLY  (4)                 /* initanswer task              */
#define SIGF_INITREPLY  (1 << 4)

/*****************************************************************
 * NEWSYNC will be sent by SyncWatcher routine only.             *
 *****************************************************************/

#define SIGB_NEWSYNC    (2)                 /* new sync occured             */
#define SIGF_NEWSYNC    (1 << 2)

/*****************************************************************
 * Task-priority/stack                                           *
 *****************************************************************/

#define PUU_TASKPRI     (10)                /* std devicetask-priority      */
#define PUU_TASKSTK     (1000)              /* stack for task               */

/*****************************************************************
 * InitUnitMemList                                               *
 *****************************************************************
 * This structure is for allocating all stuff needed for a unit. *
 * Private, for documentation only.                              *
 *****************************************************************/

struct InitUnitMemList {                    /* startof                      */
    struct  Node iuml_Node;                 /* std exec node                */
    UWORD   iuml_NumEntries;                /* # entries                    */

    APTR    iuml_UnitMem;                   /* mem for unit-struct          */
    ULONG   iuml_UnitSz;                    /* sizeof                       */

    APTR    iuml_StackMem;                  /* taskstack-reqs/mem           */
    ULONG   iuml_StackSz;                   /* sizeof                       */

    APTR    iuml_TrackMem;                  /* chiptrack-reqs               */
    ULONG   iuml_TrackSz;                   /* sizeof                       */

    APTR    iuml_ChipSecMem;                /* chip-sector memory           */
    ULONG   iuml_ChipSecSz;                 /* sizeof                       */
    };                                      /* endof                        */
    
/*****************************************************************
 * Number of entries in above memlist.                           *
 *****************************************************************/

#define IUML_MEMENTRIES (4)                 /* 4 entries requested          */

/*****************************************************************
 * END of hideunits20.h                                          *
 *****************************************************************/

#endif
