/******************************************************************************
 * memreg.c - Chapter 6 sample code                                           *
 *                                                                            *
 * mach64 functions to access the memory mapped registers.                    *
 *                                                                            *
 * Copyright (c) 1994-1997 ATI Technologies Inc.  All rights reserved.        *
 ******************************************************************************/

#include "defines.h"
#include "main.h"

/******************************************************************************
 *regw - write to a memory mapped register through an available aperture.     *
 *                                                                            *
 *  Function: This function will provide write access to the memory           *
 *            mapped registers. Each register is 32 bits wide. The            *
 *            appropriate method is selected based which aperture is          *
 *            enabled. Preference is given to the linear aperture since       *
 *            this method is better suited for protected mode.  It is         *
 *            assumed that one of the two apertures is enabled.               *
 *  Linear aperture method: This method will provide write access on all      *
 *            bus types except ISA. ISA will work if the linear aperture      *
 *            can be enabled without mapping to existing extended memory.     *
 *            It is assumed that the linear memory aperture is enabled.       *
 *            The base address of the memory mapped registers is (base        *
 *            aperture address + 3FFC00h) for a 4M aperture size and          *
 *            (base aperture address + 7FFC00h) for an 8M aperture            *
 *            size. Each register occupies 4 bytes. This is the more          *
 *            efficient method for protected mode applications, and will      *
 *            work even if VGA is disabled.                                   *
 *  VGA aperture method: This method will provide write access on all         *
 *            bus types. It is assumed that the VGA aperture is enabled.      *
 *            The base address of the memory mapped registers is              *
 *            B000:FC00h. Each register occupies 4 bytes. This is also        *
 *            the more efficient method for real mode applications,           *
 *            however, VGA must be enabled on the card.                       *
 *    Inputs: regindex - Register byte offset from start of register block.   *
 *            data - 32bit data value to fill register.                       *
 *   Outputs: 0 - unsuccessful                                                *
 *            1 - successful                                                  *
 *     Notes: It is assumed that the global variables                         *
 *            MODE_INFO.vga_aperture_status and                               *
 *            MODE_INFO.linear_aperture_status are correctly set.             *
 ******************************************************************************/

int regw (int regindex, unsigned long data)
{
    unsigned long *appaddr;             // Pointer to actual register.

    // Determine offset address.

    if (MODE_INFO.linear_aperture_status == ON)
    {
        // Calculate linear aperture address.

        appaddr = (unsigned long *) (MODE_INFO.virt_seg +
                                     MODE_INFO.linear_memreg_offset +
                                     regindex);
    }
    else if (MODE_INFO.vga_aperture_status == ON)
    {
        // Calculate VGA aperture address.

        appaddr = (unsigned long *) (MODE_INFO.vga_memreg_offset + regindex);
    }
    else
    {
        // No aperture set at all.

        return (0);
    } // if

    // Write to appaddr.

    *appaddr = data;
    return (1);
} // regw


/******************************************************************************
 *regr - read from a memory mapped register through an available aperture.    *
 *                                                                            *
 *  Function: This function will provide read access to the memory            *
 *            mapped registers. Each register is 32 bits wide. The            *
 *            appropriate method is selected based which aperture is          *
 *            enabled. Preference is given to the linear aperture since       *
 *            this method is better suited for protected mode.  It is         *
 *            assumed that one of the two apertures is enabled.               *
 *  Linear aperture method: This method will provide read access on all       *
 *            bus types except ISA. ISA will work if the linear aperture      *
 *            can be enabled without mapping to existing extended             *
 *            memory. It is assumed that the linear memory aperture is        *
 *            enabled. The base address of the memory mapped registers        *
 *            is (base aperture address + 3FFC00h) for a 4M aperture          *
 *            size and (base aperture address + 7FFC00h) for an 8M            *
 *            aperture size. Each register occupies 4 bytes.  This is         *
 *            the more efficient method for protected mode applications,      *
 *            and will work even if VGA is disabled.                          *
 *  VGA aperture method: This method will provide read access on all          *
 *            bus types. It is assumed that the VGA aperture is               *
 *            enabled. The base address of the memory mapped registers        *
 *            is B000:FC00h. Each register occupies 4 bytes. This is          *
 *            also the more efficient method for real mode applications,      *
 *            however, VGA must be enabled on the card.                       *
 *    Inputs: regindex - Register byte offset from start of register block.   *
 *   Outputs: data - 32bit contents of register.                              *
 *     Notes: It is assumed that the global variables                         *
 *            MODE_INFO.vga_aperture_status and                               *
 *            MODE_INFO.linear_aperture_status are correctly set.             *
 ******************************************************************************/

unsigned long regr (unsigned int regindex)
{
    unsigned long *appaddr;             // Pointer to actual register.

    // Determine offset address.

    if (MODE_INFO.linear_aperture_status == ON)
    {
        // Calculate linear aperture address.

        appaddr = (unsigned long *) (MODE_INFO.virt_seg +
                                     MODE_INFO.linear_memreg_offset +
                                     regindex);
    }
    else if (MODE_INFO.vga_aperture_status == ON)
    {
        // Calculate VGA aperture address.

        appaddr = (unsigned long *) (MODE_INFO.vga_memreg_offset + regindex);
    }
    else
    {
        // No aperture set at all.

        return (0);
    } // if

    // Read appaddr.

    return (*appaddr);
} // regr
