        Implementation notes for ADFS V2.11 floppy drivers
        ==================================================

1.0     Scope
        -----

1.1     From ADFS version 2.10 onwards, code was added to support the
        Chips and Technology 82C710 Universal Peripheral Controller allowing
        the use of IDE based Winchester disks and the inbuilt NEC '765
        compatible floppy disk controller.  This was in addition to the
        existing ST506 hard disc driver and 1772/9793 floppy disc
        controller.

1.2     This document attempts to describe the structure and algorithms
        used by the 765 floppy disk driver and the modifications made to the
        existing 1772/9793 drivers.  In addition specifications are
        provided for the type of floppy drives supported and particular
        configuration and assembly options.

2.0     Source file structure
        ---------------------

        ADFS is created with Aasm and is invoked with one of the 'obey'
        files provided in the root directory.  The source starts with a
        root file defining the version to be produced, these being:

         a) Hdr_2,50 to make normal release version
         b) Hdr_A500 to make an A500 version
         c) Hdr_SDB to make a version for the software development board
         d) Hdr_Test to make a debug version

        The obey files provided build the following versions:

         MakeA1 - Makes the release version
         MakeA500 - Makes an A500 version
         MakeSDB - Makes a version for the software development board
         Mk - Makes a version with debug information
            
        The global assembler variable 'MOS_Version', defined in these files,
        determines the version of RiscOS for which the module is being
        assembled.  When assembled for version 2.11 and later the post reset
        service call code makes no attempt to detect or configure the
        82C710, assuming that the MOS provides the ReadSysInfo call to
        detect and configure it.

        The header file then links to the various source files as follows:

         1) Fixes       Documents bug fixes
         2) DevVersion  Gets all common header files
         3) Adfs00      Defines global structures and workspace
         4) AdfsMacros  Common assembler macros
         5) AdfsErrors  Defines error blocks
         6) ConstIDE    IDE constants
         7) StaticsFDC  Static workspace for FDC
         8) StaticsIDE  Static workspace for IDE
         9) Adfs05      Debug routines
         10) Adfs10/11  ST506 drivers
         11) Adfs12     Winchester driver entry points
         12) Adfs13/14  IDE drivers
         13) Adfs15     1772 drivers
         14) Adfs17     '765 FDC driver
         15) Adfs18     Floppy Disc Control Block processing
         16) Adfs19     Floppy driver entry points
         17) Adfs20     Common floppy/winchester entry points
         18) Adfs50     Module services
         19) TokenHelp  Tokenized help text
         20) Mformat    MultiFS floppy format functions

        The file Adfs20 collects all the common floppy/winchester driver
        entry points and branches to either the Winchester handler or floppy
        handler dependent on the state of bit2 of the drive number.  This was
        done to allow parallel development of both the IDE and '765 drivers.

        It is essential that a header path be defined with a line such as:

         Set Hdr$Path SCSI::HD4.$.Hdr.,SCSI::HD4.$.Hdr2.

        Some assemble switches are defined to enable various options to be
        selectively assembled:

        FlpMultiFS      Defined in Adfs15, normally true, allows assembly of
                        the code added to the 1772 driver to support MultiFS

        FlpMediaCheck   Defined in Adfs18, normally false, allows inclusion
                        of code to check the MediaID signal from the drive
                        and ensures the media present is capable of supporting
                        the operation requested at the density selected.


3.0     1772/9793 Enhancements
        ----------------------

        The enhancements made to ADFS V2.06 were to provide support for
        MultiFS.  To this end changes were made to:

3.1     The read track DiscOp:

        This DiscOp was expanded to read a whole tracks worth of ID fields. 
        To use this option the alternate defect list option bit (bit 4) is
        set in R1.  The operation reads 4 bytes of sector ID information
        into the buffer pointed to by R3 for every sector on the track.  The
        order of data is:

                Cylinder, Head, Sector No., Size

        where "size" is 0 for 128 byte sectors, 1 for 256 bytes etc.  The
        operation is terminated after 200mS (1 revolution).  Several ID's
        may be read twice so the buffer should be at least 16 bytes longer
        than the maximum number of ID's expected (512 bytes at most).  The
        disc record provided is amended to return the actual number of
        sectors per track found (at offset 1).  Note to use this option a
        valid defect list must be provided, which at a minimum is a word of
        &20000000 following on after the disc record.


3.2     The mount operation:

        This change enables ADFS to identify single, double (and quad
        density on the A500) discs with sector sizes ranging from 128 to 8K
        and sector numbering schemes starting with any given offset.  To
        achieve this the mount operation uses the read track DiscOp with the
        alternate defect bit set to read a whole track's worth of ID's into
        the buffer passed in the mount call.  Initially double density
        format is assumed (quad on A500) followed by single (double on A500)
        in a cyclical fashion until either the format is identified or the
        mount retry count is exhausted.

        Following a successful read track operation the lowest sector number
        is found from the ID's read.  The disk record is now filled in with
        the reserved byte at offset 8 indicating the lowest sector number on
        each track. If any data was requested it is read at this point.


3.3     LowSector - A new disk record field

        The reserved byte at offset 8 in the disk record is now used to
        indicate the starting sector number on a track (bits 0 to 5) while
        bits 6 and 7 are used as option bits:
                                             
         bit0..5 Lowest Sector number on a track
         bit6    Set if side 1 tracks 0 to 79 
         bit7    Set to read 40 track discs in an 80 track drive


3.4     The write track operation:

        This DiscOp was revised to accept the new MultiFS disk format
        specification parameter block.  The revised parameters are as
        follows:

        R1 = 4, bits 4 to 7 are used as option bits
        R2 = Disc address
        R3-> Track buffer or 0 when using a disk format specification block
        R4-> Disk format specification block if R3=0
        R5-> Disk record

        The disk format specification record is as follows:

        Offset  Function
        ------  --------
        0       Sector Size, multiples of 128
        4       Gap1 length
        8       Reserved
        12      Gap3 length
        16      Sectors Per Track
        17      Density, 1= single, 2= double, 4= Quad, 8= Octal 
        18      Options, b0= index mark required, b1= double step
                b2..3 = 0= interleave sides, 1..3= sequence sides
        19      Fill Value
        20      Cylinders Per Drive, normally 80
        24      Reserved
        28      Reserved
        32      Reserved
        36..    Sector List arranged: cylinder, head, sector, size


4.0     Module Initialisation
        ---------------------

        During the module post reset service call a choice is made as to
        whether an 82C710 controller is fitted or not.  In versions of
        RiscOS after 2.11 the module performs an XOS_ReadSysInfo call with
        R0=2 to check on IOEB ASIC presence.  If this ASIC is present then
        the module assumes that an 82C710 controller is present and has been
        configured.  If not it assumes a 1772 type disk controller.  In
        versions of RiscOS prior to 2.11 the module first determines if a
        1772 is fitted by write/reading the track register. If this fails
        then an attempt is made to place the 82C710 into configuration mode. 
        If successful the 82C710 is configured with a working setup.  The
        type of floppy disc controller found (1772/82C710 or none) is saved
        in the static variable "MachineID".

        Both types of floppy driver fully reset their associated hardware,
        claim interrupt vectors and initialise their independent workspaces. 
        The 1772 driver reports the number of floppies configured in CMOS to
        FileCore.  However the 82C710 driver performs drive mapping as
        follows.


4.1     Drive mapping

        Following initialisation if there is at least one floppy drive
        configured in CMOS RAM, the 82C710 driver attempts to determine all
        floppy drives present in the system by performing a restore
        operation on each of drives 0 to 3 and then testing for a track 0
        indication from the drive.  For each drive returning a track 0
        indication an entry is made in the byte array FlpDrvMap and the
        number of detected drives incremented.  Thus it is possible for the
        user's drive 0 to actually be phyical drive 1 and for drive 2 to be
        missing and phyical drive 3 to be logical drive 1.  This method
        allows the addition of an external drive 2 or 3 but for the user to
        treat it as drive 1.  The driver reports to FileCore the minimum of
        the configured number of floppies and those detected.


5.0     82C710 Driver Structure
        -----------------------

5.0.1   The 82C710 provides a Floppy Disk Controller (FDC) based around the
        rather ancient '765 from NEC.  This controller was aimed at the 8
        inch drive market and has a number of features dating back to these
        days such as drive polling, head load/unload timing etc.  This
        implementation has however been modified to support the standard
        PC/AT architecture which requires the addition of a digital output
        register to perform motor/drive selection, a digital input register
        to read disk changed status and a configuration control register to
        select data rates upto 1Mbps.  It is this last function, together
        with its PC compatibility, that has provided this rather arcane
        controller with a rather protracted existence.

5.0.2   In return for the high data rates the driver has to provide drive
        startup and shutdown functionality, and most importantly head
        settling delays.  It is this settling time and the rather coarse
        resolution of the system clock tick (10mS) that cause some loss of
        performance when writing to disks formatted on 1772 based systems.

5.0.3   A new 1.6Mbyte ADFS 'F' format is supported at a data rate
        of 500Kbps.  The driver recognizes octal density drive records and
        indeed selects the 1Mbps clock rate required, but due to hardware
        limitations in the 82C710 this mode is at present non-functional

5.0.4   As a final indictment of its function the controller refuses to
        format disks in anything other than IBM format (with a leading Index
        Address Mark following the physical index pulse), thus wasting
        valuable track length.  It is this last feature that causes disks
        formatted in ADFS L mode (16 x 256 byte sectors per track) to have
        rather reduced inter sector gaps and thus be susceptible to drive
        speed variation.  ADFS D and E format disks will also be formatted
        with a leading index address mark.

5.0.5   The new driver was written to support the MultiFS specification
        thereby allowing RiscOS to read/write disks in a hardware
        independent manner from virtually any computer system supporting
        IBM/ISO compatible disk formats.

5.0.6   The 82C710 floppy driver has been added as a set of alternative
        routines processing the following functions:

         1) DiscOps
            a) Verify
            b) Read Sectors
            c) Write Sectors
            d) Read ID
            e) Format track
            f) Seek
            g) Restore
            h) StepIn and StepOut are not supported

         2) MiscOps:
            a) Mount requests
            b) Poll changed requests
            c) Lock drive requests
            d) Unlock drive requests
            e) Get poll period requests

5.0.7   The file Adfs19 receives all floppy drive requests and branches to
        one of two driver routines dependent upon the value in MachineID,
        i.e. 1772 or 82C710 type.  In general the 1772 routines used have
        been little modified since version 2.06 of ADFS

5.0.8   The 82C710 driver relies heavily on interrupts and to this end
        receives interrupts from drive index pulses, the centisecond clock
        and the '765 disk controller.


5.1     Disk Control Blocks

        The 82C710 driver uses a concept of Disk Control Blocks or DCB's
        which are '765 controller commands packaged in a 64 byte structure. 
        Every high level function is converted into a series of simple
        controller operations which are formatted into DCB's and queued to
        be executed asynchronously to the foreground process, thus allowing
        the overlap of I/O and foreground activity.

        All DCB's are processed in the background by means of a message
        system, thereby removing the distinction between foreground and
        background operations.  The DCB maintains a status field indicating
        the state of the command, that can be polled, and in addition
        provides for the address of a routine, called the 'post' routine, to
        be called upon command completion, in interrupt state.  The DCB's
        are queued and executed in the order of presentation.

        A significant advantage of DCB's is that various device specific
        commands can be issued by applications, such as for disk protection
        etc., but can be processed by the driver without the need for the
        application to deal directly with IRQ's/FIQ's or talk to the
        hardware directly.  This should effectively allow for future
        enhancements to the hardware while maintaining backwards
        compatibility by emulation of the outdated hardware.

        The DCB is structured thus:
                         
        Offset  Function
        -----------------------------------------------------
        0       Data buffer pointer
        4       Data buffer size, bit31= read, bit30= scatter list
        8       CPU R12 for 'post' routine
        12      Address of 'post' routine
        16      Command status, -1= pending, 0= no error else an error code
        20      Escape inhibit, 0= allow escape aborts
        21      Command timeout in centiseconds, 0= none
        22      Retries, 0= none
        23      Data clock rate, 0= 500Kbps, 1= 300K, 2= 250K, 3= 1M
        24      Cylinder number
        25      '765 command block length, bit7= no wait
        26      '765 command
        27      Bit0/1= drive no., bit2= head, bit7= implied seek
        28      '765 parameters
        35      Verify flag, &FF= verify data only
        36      Command status return area
        44      Reserved for ADFS
        48      Reserved for ADFS
        52      Reserved for ADFS
        56      Reserved
        60      Reserved for user

        Total size 64 bytes


5.2     Drive Finite State System

        The control of a floppy disk drive involves operations such as motor
        startup, head seeking/settling, drive ready detection etc. that
        incur considerable delay.  In order to allow foreground processing 
        during these operations and to simplify and ensure correct tracking 
        of drive condition a finite state system was used to control drive
        operation.  The actual implementation uses two state machines, one
        for the drive and one for the '765 controller, but they may be
        considered one system.

5.2.1   Drive Motor Control

        The drive motor control control system is in one of four states:

         1) Off
         2) SpinUp
         3) Empty
         4) Ready

        The current state is held in 'FlpDrive', which contains the address
        of the routine handling the current state.  The system recognizes
        the following events:

         1) Drive select/deselect
         2) Index pulse interrupt
         3) Time goal

5.2.1.1 The system remains in the off state until a drive select event is
        received from an active DCB.  Selections in the range 0..3 cause the
        system to start the drive motor, anything else turns all drives off. 
        Upon starting the drive motor (a common motor enable is assumed) a
        time goal of 500mS (1000mS for drives 2 & 3) is set and the system
        enters the "SpinUp" state to enable the drive motors to come up to
        speed.

5.2.1.2 During the "SpinUp" state the receipt of a motor startup time goal
        causes the system to arm the drive empty timer, which expires after
        400mS.  Receipt of an index pulse within the drive empty timeout
        causes the transition to the "ready" state and the issuing of a
        "drive ready/index" message to the current DCB.  Expiry of the drive
        empty timer indicates that no disk is inserted and results in an
        error message being sent to the current DCB and the transition to
        the "Empty" state with a time goal of 2 seconds to turn off the
        motors.

5.2.1.3 When in the "Empty" state the receipt of an index pulse interrupt
        causes the transition to the "SpinUp" state and the re-arming of the
        drive empty timer.  Receipt of a time goal event results in the
        drive motors being disabled, all drives becoming deselected and the
        transition to the "Off" state.

5.2.1.4 Entry to the ready state causes a count of 8 to be loaded into the
        motor off counter.  Upon receipt of an index pulse the motor off
        counter is decremented until it reaches zero when the motors are
        turned off and the system enters the "Off" state.  At every index
        pulse the empty timer is retriggered and an "Index" message sent to
        the current DCB.  Expiry of the empty timer causes a transition to
        the empty state together with an error message to the current DCB. 
        Further drive selections during this phase set the motor off counter
        to 8 again.  All drives are assumed to be ready at the same time,
        thus changing from a drive that is "ready" assumes that the new
        drive is also ready - it may result however in an empty message
        being received 400mS later.
                                   
        The ready/empty state of a drive is recorded in the drive
        record.


5.2.2   Drive Head Position Control

        The head position control system is combined with disk controller
        management as the two are implicitly linked and it is not possible
        to change drive head position without affecting the disk controller. 
        The system can be in the following states:

         1) Error
         2) Reset
         3) Idle
         4) Seeking
         5) Restoring
         6) Settling
         7) Busy

        The current state is held in the local static variable 'FlpState',
        which contains the address of the routine handling the current
        state.  The system recognizes the following events:

         1) Controller Interrupt
         2) Time Goal
         3) Seek request
         4) Command request

5.2.2.1 The system starts in the "Reset" state with the '765 disk
        controller having just been released from a hard reset.  The '765
        has an odd feature, related to its lengthy pedigree with 8" floppy
        drives, that results in 4 interrupts being generated after the
        reset, associated with internal changes in the "drive ready" signal. 
        A 'request interrupt status' command is issued for each interrupt in
        order to get the FDC into the "idle" state.  An overall timeout
        period of 250mS is imposed to prevent lockups due to controller
        malfunction.  If the timeout occurs, the system enters the "Error"
        state which provides an error response to all requests.  At
        initialisation the floppy driver will not install unless the
        controller becomes ready within this timeout.

5.2.2.2 Normally the drive head position control system is in the "Idle"
        state when it will accept seek and command requests.  Upon receipt
        of a seek request a comparison is made of the requested track and
        the head position recorded in the drive record.  If no seek is
        required the state system remains idle and returns a seek done
        status.  If a write operation is requested (in the DCB buffer length
        field) then a head settling delay of 30mS is setup, otherwise no
        head settling is required (if a read error occurs, it will be
        retried).  If the current head position is unknown, as recorded in
        the drive record, then a restore command is executed and the system
        enters the "Restoring" state, otherwise a seek command is issued and
        the system enters the "Seeking" state.

5.2.2.3 In the "Restoring" state the system waits for a controller interrupt
        when a sense interrupt status command is issued.  If an error
        was encountered (such as no track 0) an error message is sent to the
        current DCB and the system goes to the "Idle" state; otherwise a
        seek command is issued and the "Seeking" state is entered.

5.2.2.4 In the "Seeking" state the system waits for a controller interrupt,
        when a sense interrupt status command is issued.  If an error was
        encountered an error message is sent to the current DCB and the
        system goes to the "Idle" state; otherwise the head settling period
        setup is enforced by setting a time goal and the system goes to the
        "Settling" state.  Note that most drives require a 15mS settling
        time but the centisecond clock only gives a resolution of 10mS.  A
        requested period of 30mS will ensure at least 20mS even if a clock
        tick happens almost immediately.  If the head settling period is 0
        then the system goes to the idle state and a seek done message is
        sent to the current DCB.

5.2.2.5 During the "Settling" state the the clock tick interrupt handler
        decrements the time goal until 0 is reached, when a time goal event
        is generated.  The system no goes to the "Idle" state and a seek
        done message is sent to the current DCB.

5.2.2.6 When the system is idle command request events will be accepted. The
        command block present in the DCB is sent to the FDC and the system
        enters the "Busy" state if the controller accepted the command.  A
        time out of 2.5 seconds is set to ensure that fatal controller
        errors do not hang the system.

5.2.2.7 When in the "Busy" state the system is awaiting a controller
        interrupt or time goal event.  A time goal event implies that the
        FDC has failed.  In this event the controller is reset, the system
        goes to the "Reset" state and an error message is sent to the
        current DCB.  A controller interrupt event signals command
        completion.  An IRQ message is sent to the current DCB which must
        determine the cause of the interrupt and clear it.  The system exits
        to the "Idle" state.
       

5.2.3   Step rate control

        In keeping with the original 1772 driver, it is possible to
        configure step rates of 2, 3, 6 or 12mS on a drive by drive basis. 
        However the step rates provided by the '765 controller depend on the
        data clock rate selected, therefore before every command the routine
        'Flp765specify' is called to check the selected clock rate against
        the data rate selected and the configured step rate and determine if
        another 'specify' command (used to set step rates) is required.  Due
        to limitations in the '765 it is not always possible to set exactly
        the step rate configured.  The following table shows the configured
        and actual rates used for various densities:

                                          Actual Step Rate (mS)
         Configured Step Rate   Single  Double  300K    Quad    Octal
         ------------------------------------------------------------
                2               2       2       1.7     2       2
                3               4       4       3.3     3       3
                6               6       6       6.7     6       6
                12              26      26      25      12      8

        It should be noticed that in single and double density modes
        selection of the 12mS step rate actually results in a 26mS rate
        being used - this is intentional to support older 40/80 track 5.25"
        disks.  It should also be noticed that at octal density it is not
        possible to step at 12mS - this is a limitation of the hardware but
        should not cause problems since drives capable of supporting octal
        density can normally be stepped at 2 or 3 mS rates.


5.3     DCB processing

        The disk control block (or DCB) is at the heart of the 82C710
        driver.  Every disk operation is performed by DCB's.  The driver
        maintains one DCB named 'FlpDCB' in its static workspace to permit
        FileCore background operations.  Once a DCB has been constructed it
        is submitted either by calling 'FlpAddDCB' from within ADFS or by
        using the SWI ADFS_FlpProcessDCB.  In both cases R1 points to the
        DCB to be processed, however the SWI provides a "No-Wait" option
        (see later).  DCB processing is performed by routines in the source
        file Adfs18.

5.3.1   The routine FlpAddDCB determines if the '765 command is allowed.  If
        not an error is returned otherwise a message handling routine is
        assigned and the DCB added to the end of the current list of DCB's,
        headed by 'FlpDCBqueue'.  All standard '765 commands are supported
        with the addition of the "version" command (&10).

5.3.2   DCB processing depends on the receipt of asynchronous messages,
        processed by the message handler for that DCB.  The following
        messages are supported:

         '765 interrupt
         Index pulse
         Seek done
         Error
         Escape
         Startup
         '765 reset completed

5.3.3   A DCB remains dormant in the FIFO queue until it receives a 
        "StartUp" message.  The routine 'FlpMessage' is used to send a
        message to the current DCB - only the first DCB in the queue
        receives any messages.  Upon receipt of a "StartUp" message the DCB
        is guaranteed exclusive use of the disk controller to perform its
        function.  Actions taken after this point are dependent upon the
        command type and message handler assigned.  The following message
        handlers are defined:

         FlpHandlerData         For data read/write operations
         FlpHandlerReadID       For read ID commands
         FlpHandlerSeek         For seek/restore commands
         FlpHandlerDrv          For Sense Drive Interrupt commands
         FlpHandlerImm          For other immediate commands

        All DCB's maintain a current state indicator to remember the current
        activity:

         Idle
         Awaiting drive ready
         Awaiting seek done
         Awaiting '765 IRQ
         Awaiting '765 reset complete
         Awaiting index pulse
         Awaiting '765 IRQ or index pulse
         Complete
         Seeking during retry

5.3.4   All DCB message handlers must process the "StartUp" and "Error"
        messages, otherwise messages may be selectively ignored.


5.4      Data read/write DCB's

        The read/write and verify message handler is the most complex of all
        the handlers and is illustrative of the techniques used in all
        others.  Command processing commences with the "StartUp" message
        when the drive requested in the '765 command block area of the DCB
        is selected by calling the drive state system.  If the drive must
        spin up the command phase is changed to "awaiting drive ready" and
        the DCB waits for a drive ready message.  If the drive is empty an
        error is reported and the DCB completes.  If the drive was already
        upto speed processing continues.

5.4.1   A drive ready message is sent by the drive state system on receipt
        of every index pulse.  When received the DCB checks if the '765 is
        in a reset state and if so awaits the completion of the reset phase. 
        If not the drive state is locked to prevent an unwanted motor off or
        an empty message.  Prevention of empty detection during the seek
        phase is necessary because some 3.5" drives inhibit index pulses
        during seeks, which can cause the drive empty timer to expire!

5.4.2   The DCB is examined to see if an implied seek is required (bit7 of
        the drive select byte) and if set the cylinder requested is passed
        to the drive state system for processing.  If a seek is required the
        DCB exits to await the seek done message.

5.4.3   Upon receipt of the seek done message the FIQ handler is setup to
        handle the DMA requests from the '765.  A FIQ is generated for every
        byte transferred, so the FIQ routines must be very efficient to
        prevent data overruns (1 byte every 16uS at 500Kbps).  Even so at
        500Kbps in 256 colour modes there are often data overruns caused by
        bus bandwidth limitations imposed by VIDC.  In these cases it is
        necessary to inhibit video DMA.  On the Perth development system
        overruns occurred during FDC write operations at 500Kbps in mode 15
        with an 8 MHz memoty system (even with a 36MHz ARM3).  When the
        memory speed was uprated to 12MHz overruns only occurred in 256
        colour modes with 36MHz VIDC operation.

5.4.4   Bit 31 of the buffer size field is used to indicate DMA direction, a
        1 indicating a memory write (FDC read).  Bit 30 of this field, if
        set, is used to indicate that the buffer address provided is a
        pointer to a scatter list.

5.4.5   DCB operations are limited to discrete '765 commands and so the
        maximum transfer size that can occur is a whole track's worth.  This
        maximum is enforced by testing the number of the last sector on the
        track.  After setting up the FIQ registers the message handler calls
        the drive state system to issue the command and the DCB exits
        awaiting a '765 interrupt.  A command timeout is setup by the drive
        state system if enabled in the DCB.

5.4.6   Upon receipt of a '765 interrupt the status registers are
        transferred to the result area of the DCB.  If no errors occurred
        and if scatter list processing was requested all list entries
        traversed by the last operation are marked as done.  In the most
        efficient case a whole tracks worth of buffers will be transferred. 
        If the multi-track option is used (ADFS can't use this because
        sector numbers start from 0 and not 1) a whole cylinder's worth of
        buffers will be transferred.  This approach is enforced since if
        scatter lists are updated by the FIQ routine then there is a finite
        period of time when all the buffers are marked as done but before
        the '765 generates an interrupt within which time FileCore can
        modify the scatter list.  Additionally it complicates retry
        operation since the command must be modified in order to start part
        way down a scatter list after an error.

5.4.7   Upon command completion the buffer address field is updated to point
        to the next address past the end of the data transfer and the buffer
        size field contains the number of bytes transferred.

5.4.8   Error handling is dependent upon the type of error.  These being:

         1) Write protect - no retries, operation faulted
         2) Data overruns - Video DMA disabled and operation retried.
         3) No implied seek - Just retry the operation
         3) Wrong track number - restore and retry the operation (with seek)
         4) Other errors cause the head to step in 2 tracks and then
            repeat the operation (with seek)

5.4.9   This sequence is repeated until the retry field becomes negative. 
        An initial value of zero means no retries (for any reason) are
        attempted.

5.4.10  This message handler in addition detects escape messages and aborts
        the command if the DCB escape inhibit field is not set.


5.5     Read ID's DCB command processing

        The read ID message handler functions largely identically to the
        read/write handler except that after any implied seek is performed
        the buffer size field is examined.  If non-zero a series of ID's has
        been requested (starting from the index pulse) so the DCB waits for
        the next index pulse message, otherwise the next ID is read.  The
        command is issued and the DCB awaits an interrupt.

5.5.1   Upon receipt of the interrupt message the handler reads the '765
        status into the results area of the DCB.  If a buffer length was
        specified, the ID is copied to the buffer until either it is full or
        until a second index pulse message is received indicating that all
        ID's on the track have been read.

5.5.2   On exit the buffer address points to the next free space and tje
        size is reduced by the amount of data transferred. 

5.5.3   Error recovery is limited to simply retrying the faulted operation
        until the retry count is exhausted.


5.6     Seek/Restore DCB command processing

        Initially command processing for seek/restore is similar to read and
        write operations except that implied seeks are not recognized.  If
        timeouts are disabled the DCB does not wait for a drive ready
        message but executes the command immediately.

5.6.1   Error recovery is limited to rertying the operation until the retry
        counter is exhausted.  It is important that restore operations have
        at least one retry enabled because the '765 only issues 77 step
        pulses during a restore and then issues an error if track 0 is not
        seen.  If the head was on track 79 a second attempt will be
        necessary to restore the drive.


5.7     Drive Status DCB

        The drive status command has been extended to return information
        about the drives ready/empty/changed/density status in addition to
        its normal function.

5.7.1   Upon receiving the "StartUp" message the requested drive is
        selected.  If the drive state system reports empty the command is
        executed immediately.  If not the disk changed line from the drive
        is sampled.  If inactive the command is executed immediately and the
        drive deselected.

5.7.2   The handler now attempts to reset the disk changed status by seeking
        to track 1 followed by a seek to track 0.  If the changed line does
        not change state the drive is assumed empty (but does not mask index
        pulses during empty).  If the changed state is reset the disk
        changed works bit is set in the drive record.  The drive status word
        is returned at offset 4 of the result area of the DCB.

5.7.3   When the command completes the drive status prior to the operation
        is restored.  If it was not ready the drive is deselected, otherwise
        a short time out is set prior to deselection.


5.8     Other DCB's

        All othe '765 commands use the immediate message handler (such as
        sense drive interrupt, version etc.)  This handler executes the
        command immediately that it receives the "StartUp" message.


5.9     Post Routine Function

        When a DCB completes, by calling 'FlpDqDCB', the address in the post
        routine entry is examined and if non zero it is called after setting
        R12 to the value specified in the DCB.  The function of this call is
        identical to that of an interrupt, in fact the routine will run in
        IRQ mode.  By this means a foreground task can be notified of the
        completion of asynchronous overlapping I/O activity without polling
        the command completion status.

5.9.1   This feature is used by DCB's submitted as a result of DiscOp calls
        by FileCore to calculate the next disk address and re-commence data
        operations on another track. 


5.10    DiscOp processing
   
        The 82C710 FileCore interface supports the following FileCore
        DiscOps:

         a) Verify
         b) Read Sectors
         c) Write Sectors
         d) Read ID (read track for 1772 driver)
         e) Format track
         f) Seek
         g) Restore

        The operations "StepIn" and "StepOut" have no equivalent on the '765
        controller and are faulted.

        All DiscOps now support the 'LowSector' field of the disk record to
        set the lowest sector number on a track and also support the double
        step and sequenced sides option bits in this field.

5.10.1  DiscOp processing is performed by routines in the file Adfs19.  All
        data transfer operations not using scatter lists are converted to
        scatter list form internally for ease of processing.  The routine
        'FlpBuildDCB' is called to construct a DCB in the static array
        'FlpDCB'.  This array cannot be on the stack since the DiscOp may
        return before background processing is complete.

5.10.2  All DiscOps setup a 'post routine' dependent upon the type of
        command - read/write/verify or other.  The sole function of the
        'other' type 'post routine' is to mail results to the foreground
        routine and to release FIQ's.  The data transfer type post routine
        is discussed later.

5.10.3  The DiscOp caller is suspended until the foreground part of the
        operation is complete, as seen by polling the mailbox 'FlpFgStatus'. 
        This 4 word array is posted with the results to be returned to the
        caller.


5.11    Data transfer DiscOps

        Data transfer operations setup a 'post routine' to calculate the next
        track/head/sector in sequence to transfer since DCB's are limited to
        single track operations.  In addition the post routine performs the
        FIQ release and FileCore callback necessary for background
        operation.  The FIQ workspace (above the FIQ stack area) is used as
        a mailbox from the foreground to the 'post routine'.  The disk
        address, disk record pointer, operation and scatter list pointer are
        stored here to allow the 'post routine' to calculate the parameters
        for the next DCB.

5.11.1  The post routine used 'FlpLowDataPost' checks the result of the last
        DCB operation, schedules another DCB or completes the command.  A
        separate count is kept of the foreground part of the transfer and
        any background scatter list processing.  The foreground is notified
        through the mailbox 'FlpFgStatus' when the foreground part is
        complete.  Background operation continues until the scatter list is
        exhausted or an unrecovered error occurs.  Note that the process
        status block returned to FileCore needs to point to the offending
        buffer if an error occurs.  The routine 'FlpComplete' is called when
        the operation eventually terminates.


5.11.2  Write Track operation

        As with the 1772 driver the write track operation has been extended
        to use the disk format specifier.  Compatibility with older software
        using a track image has been attempted but the track image is
        ignored, the disk is formatted from information in the disk record. 
        Therefore information like sector interleave, track skews etc. is
        lost!  Note that the '765 controller cannot format a disk without an
        index address mark; therefore disks formatted with the 82C710 driver
        are not identical to those produced on a 1772 base machine.

5.11.3  Read Track/ID operation

        The '765 FDC does not allow a track image to be read so the read
        track command is implemented as reading a whole track of sector
        ID's, 4 bytes each arranged:

         Cylinder, head, sector number, sector size (0= 128, 1= 256 etc.)

        This DiscOp is mapped into a Read ID DCB which reads upto 64 sector
        ID's into the buffer area passed in R2.  The first sector ID
        transferred will normally be that following the index mark (it may
        be the second if there is abnormal interrupt latency from the index
        pulse interrupt).  The first two ID's read may also be duplicated at
        the buffer end due to interrupt latency.


5.11.4  Seek/Restore operation

        The seek and restore operations are mapped into the corresponding
        DCB.  Note that if the no timeout option bit is set in R1 then these
        commands execute without waiting for drive ready indication,
        otherwise the head movement is not executed until after the drive
        comes up to speed.


5.12    Disk error codes

        The routine 'FlpADFSerror' converts the status information returned
        from the '765 controller into a 1 byte error code understandable by
        FileCore.  The following error codes are returned in addition to
        the standard errors


         Error Code             Meaning
         ------------------------------------------------------
         &01                    Fatal - hardware error
         &02                    Fatal - command time out
         &03                    Fatal - Track 0 not found
         &10                    Critical - seek fault
         &20                    Recoverable error - non specific
         &21                    Data overrun
         &22                    Data CRC error
         &23                    Sector or ID not found
         &24                    Missing address mark


5.13    Miscellaneous Operations

        The 82C710 driver supports the following miscellaneous operation
        calls:

         1) Mount
         2) Poll changed
         3) Lock drive
         4) Unlock drive
         5) Get poll frequency


5.13.1  Mount

        The mount operation is used to identify the disk type and format.
        The operation has been revised to support the MultiFS interface,
        and thus returns the density, sectors per track, sector size and
        lowest sector number in the disk record.

5.13.1.1 Mount uses a read ID DCB to identify the disk format starting at the
        disc address passed in R2.  Initially it uses the suggested density
        in the disk record but subsequently tries the following formats:

         1) Quad density
         2) Double density
         3) Octal density
         4) Single density
         5) 300K double density (double density in a 360 RPM PC/AT drive)

5.13.1.2 The order of these attempts can be altered by changing the entries
        in 'FlpCCRtable' in Adfs19.

5.13.1.3 After a successful read ID has been completed, the sector ID buffer
        is scanned for the lowest sector number and the number of sectors
        per track.  If duplicate ID's are found at the end of the buffer
        they are discarded.  The disk record is then updated with the new
        parameters.  If any read operation was requested it is now executed. 
        Note the length of the read must not exceed one track.


5.13.2  Poll changed

        The poll changed routine adopts a very different philosophy to the
        1772 driver.  In the first case an accurate, up to date record is
        maintained in the drive record for each physical drive connected
        recording the drive status, such as empty, changed etc.  This record
        is updated on a revolution by revolution basis.  Thus the first
        difference comes when a poll changed request is made while a
        background operation is in progress.  In this case the current drive
        status is returned.  Note that some new fields have been added to
        the change status:

         Bit 0  Not changed
         Bit 1  Maybe changed
         Bit 2  Changed
         Bit 3  Empty
         Bit 4  Ready
         Bit 5  40 Track
         Bit 6  Empty Works
         Bit 7  Changed Works
         Bit 8  Hi-Density disk
         Bit 9  Density Works
         Bit 10 Ready Works

5.13.2.1 Secondly to prevent the annoying tick/buzz associated with
        constantly polling an empty drive (attempting to reset changed),
        drive empty detection is performed by maintaining a retriggerable
        timer run off of index pulses.  Most 3.5" drives (though not all)
        inhibit index pulses when the drive is empty or starting up.  Disk
        changed is not reset until index pulses are seen, and hopefully a
        disk is present.  Thus if a drive is idle and a poll changed request
        is made and changed is asserted the operation may not return for
        upto 1 second, while the motors startup and drive empty detection
        occurs.

5.13.2.2 Lastly all DiscOps return a drive empty error if disk changed is
        asserted during the course of an operation or the empty timer
        expires.


5.13.3  Lock/Unlock drive

        The drive lock function is implemented by three bits in the static
        variable FlpDriveLock, which is a bit array.  The function of the
        bits are:

         Bit    Function
         ---------------------------------------------------------------
         0      Set by an active DCB to prevent drive motors turning off
                during an operation.

         1      Set by the lock drive call, cleared by unlock.  Prevents
                drive state machine from decremrenting motor off index
                pulse count

         2      Set during seek operations to prevent the empty timer from
                expiring.  Needed in case drive masks index pulses during
                seek operations.

5.13.4  Set Poll Period

        This function always return a poll period of 1 second with an
        82C710 controller to allow for drive empty detection.


6.0     Media ID

        Provision has been made in the sources to test a media ID signal
        from the drive, brought on to IOC C2.  The code to implement this
        check is included by setting the assembler flag 'FlpMediaCheck' to
        true in Adfs18.  The code works by testing if a write operation is
        being requested, the density is quad or more and the Hi-density
        function works (from drive record).  If so the media ID signal is
        read and if low (for low density) the operation is faulted.  The
        Hi-density works bit is set in the drive record if Hi-density is
        output by the controller (quad density or more) but the drive
        responds with low density on Media ID, indicating a low density disk
        fitted.


7.0     New SWI's

        The following SWI's have been added:


7.1     ADFS_ControllerType

        Identifies the drive controller type

        Input: R0= drive number, 0..3 floppy, 4..7 winchester

        Output: R0= controller type
                0 = drive not present
                1 = 1772 controller
                2 = '765 controller
                3 = ST506 drive
                4 = IDE drive

        Corrupts flags


7.2     ADFS_FlpProcessDCB

        Execute a user supplied disk control block

        Input:  R1 -> disk control block

        Output: None, results in DCB

        In addition to the normal DCB functions described earlier this SWI
        uses bit 7 of the command block length as a flag to determine
        whether the SWI should return immediately to the caller after the
        DCB has been queued, before command completion.  If not set the SWI
        will claim FIQ's (necessary for data transfer), submit the DCB and
        wait for command completion.  If set, FIQ's are not claimed (it is
        left to the user to claim and release them) but control is returned
        immediately to the caller after the DCB has been queued.  This
        function allows disk operations to proceed in the background while
        an application performs other useful work.

        The result of the operation is returned in the DCB results area and
        the DCB status area.  The following error codes are returned in the
        DCB status area:
           
         Status value   Meaning
         -----------------------------------------------
         &0             Operation successful
         &80            Escape aborted operation
         &A1            Incorrectly formatted DCB or bad parameters
         &D3            Drive was/became empty
         &FE            Unsupported '765 command
         &80000000      Controller reported an error, see results area
         &FFFFFFFF      Command still pending


8.0     Floppy drive types supported

        The range of floppy drives supported by the 82C710 driver is
        considerably wider than before.  In general ANY PC/XT/AT compatible
        3.5"/5.25" 40/80 track drive can be used.  The following minimal
        requirements will ensure optimal performance:

         1) Disk changed support should be available on pin 34 and should be
        resettable with a step pulse.

         2) The drive should mask index pulses when selected but without
        a disk present.

         3) The drive should not mask index pulses whilst step pulses are
        being issued.

         4) The drive should support a "density in" signal (from FDC) that
        is active high for high density (>=500Kbps).

         5) The drive should supply media ID signals that indicate the
        greatest density supported by the current drive/media.

         6) Drives 0/1 should be ready to use within 500mS of motor startup.

         7) Drives 2/3 should be ready to use within 1000mS of motor
        startup.


8.1     The following table illustrates the combination of motor on and
        drive select signals supplied for various drive selections:

         Drive Selected         /DS0    /DS1    /ME0    /ME1
                0               L       H       L       H
                1               H       L       H       L
                2               H       H       H       L
                3               H       H       L       L
                None            H       H       H       H

        Drives 2 and 3 do not result in any drive select line being asserted
        but can be decoded by an external decoder, such as in Brisbane.


8.2     Drive interface signal description

        In order to encourage greater understanding of the floppy disk drive
        interface the function and use of each of the interface signals is
        discussed further.

8.2.1   General

        All interface signals are open-collector and therefore require a
        pull-up resistor of nominally 1k for 3.5" systems or 150R in older
        5.25" systems.  The pull-up should only be present in only one place
        - either on the drive furthest from the controller (for outputs), or
        on the controller (for inputs).

        Due to the nature of open collector signals no damage will occur if
        several outputs drive one signal - thus it is safe for instance to
        connect "motor on" to "Sel2" and force motor on true whenever Sel2
        is asserted.

        All signals are active (asserted) low , i.e. active when at 0 Volts. 
        Inputs are only valid when a drive is selected.


8.2.2   Drive Select 0,1,2,3 - Output

        These signals select the drive.  Only one should be active at any
        given time.  Most 'AT' compatible drives assume only drive select 1
        will ever be asserted since there is a physical twist in the cable
        to determine the actual drive number.

 
8.2.3   Motor On - Output

        Asserted to turn the drive motor on (and load the head on 5.25"
        drives).  A period of 0.5 seconds (1 second for drives 2 and 3) is
        allowed before any data transfer occurs to allow the drive motor to
        come up to speed.


8.2.4   Side1 - Output

        Asserted to select the under surface of a disk


8.2.5   Step - Output

        Asserted to step the head in the direction given by DirIn.  Also
        used to reset DiskChanged.  A period of 15-20 mS is required to
        allow for head settling after any movement.


8.2.6   DirIn - Output

        Asserted to move the head inwards (to the centre) during head
        movements.


8.2.7   WriteData - Output

        Data from the controller to be written to disk.


8.2.8   WriteGate - Output

        Qualifies WriteData.  Asserted prior to and after WriteData is true
        to enable recording of the data.


8.2.9   Density - Output

        Informs the drive of the current data rate.  Asserted for 500Kbps
        and 1Mbps operations (1.6 and 3.2 Mbyte formats).  Normally on pin2,
        some drives may require an inverted signal if intended for use with
        PS/2 systems.


8.2.10  Track00 - Input

        Asserted by the drive when the head is on track 0.


8.2.11  WriteProtect - Input

        Asserted by the drive when the disk is write protected.


8.2.12  ReadData - Input

        Data stream read from the disk.


8.2.13  Index - Input

        Index pulses are produced every disk revolution (200mS).  The 82C710
        driver uses the presence of index pulses to detect a disk in.  If a
        drive does not support "DiskChanged" then in order to function with
        the 82C710 drivers it MUST inhibit index pulses with the drive
        empty - this is the normal situation.  Performance is improved if
        index pulses are not masked during seek or motor startup.  Index
        pulses must be present within 900mS (1400mS for drives 2 and 3) of
        asserting drive select/motor on otherwise the drive will be deemed
        to be empty.


8.2.14  Disk Changed - Input

        This signal is normally available on pin34 or pin2 and when asserted
        indicates that the disk in the selected drive has been changed. 
        Neither the 1772 nor the 82C710 driver require DiskChanged in
        order to function, but give better performance if available.  The
        signal must never be asserted if non-functional.

        Dependent upon drive type the disk changed signal may either be
        reset by issuing a step pulse (82C710 driver) and/or by asserting
        the disk changed reset signal (1772 driver).  If diskchanged is
        reset by 'step', the wimp polling period is set to 1 per second
        otherwise it is set to 10 times per second.


8.2.15  Ready - Input

        Often available on 5.25" drives and available from drives for
        A440/540 series machines on pin34.  Asserted when the drive is ready
        for read/write operations.  This feature is REQUIRED by the 1772
        driver.  If not present, Ready must be tied low for the driver to
        function.


9.0     Link options for SDB

        The software development board should have the following link
        settings:

         LK41   2 to 3
         LK36   1 to 2
         LK15   1 to 2

        This allows the controller to set the data rate for the
        current operation and permits the driver to read the media ID from
        drives connected to the 26way connector.


10.0    Test software

        The following test programs have been used to test the correct
        operation of both floppy drivers:

10.1    Tester

        This program allows the simultaneous exercise of 2 floppy discs or
        one hard disk and one floppy using common filing operations.  The
        test should run with no errors (apart from access violations) until
        the disk is full.

10.2    TestADFS

        This BASIC program exercises the driver at the DiscOp level and
        checks the basic operation of all supported operations including:

         1) Restore
         2) Write Track
         3) Write sectors
         4) Read sectors
         5) Defect addresses
         6) Double step operation
         7) Single sided operation
         8) Read ID operation
         9) seek operation
         10) Invalid DiscOps

        No errors should be returned from this program


10.3    Format/Verify programs

        The BASIC programs:

        FORM40, FORMAT300, FORMATE, FORMATFM, FORMATL, FORMATQ256,
        FORMATQUAD, VERIFY40 and VERIFYE

        perform write track and verify operations using various disk formats
        to check unusual media identification and handling.  Any disk,
        however formatted, should at least verify using the *VERIFY command
        unless it has corrupt sector information or is a 40 track disk
        without recognized logical structure.


10.4    Seek reliability

        The BASIC program SEEK performs repeated seek operations to check
        the reliability of the head movement mechanism.


10.5    Additional SWI's

        The program SWI checks the operation of the new ADFS_ControllerType
        and ADFS_FlpProcessDCB SWI's.


10.6    File System Performance

        The BASIC program OSGBPB provides a rough estimate of filing system
        performance.  It is useable on floppy and hard disk systems to
        indicate data throughput.  With a correctly formatted floppy
        read/write performance should be about 15K bytes/sec on L format
        discs, 23K bytes/sec D and E format and about 47K bytes/sec on F
        format.
