/*************************************************************************/
/*                                  TIGA                                 */
/*       Copyright (c) 1988-1990 Texas Instruments Incorporated.         */
/*                         All Rights Reserved                           */
/*-----------------------------------------------------------------------*/
/*  TMS340 Graphics Library						 */
/*************************************************************************/
/*  These functions deal with setting or obtaining the configuration     */
/*  data for different operating modes of the 340-based system.          */
/*                                                                       */
/*  Functions:                                                           */
/*      get_config                                                       */
/*      set_config                                                       */
/*************************************************************************/

/* Names of GSP I/O registers and B-file registers */
#include <gspreg.h>
#include <gsptypes.h>
#include <gspglobs.h>
#include "oem.h"

/* Declare external variables. */
extern SETUP default_setup;	 /* defined in oem.c */
extern short num_modes; 	 /* defined in oemdata.c */
extern SETUP mode_setup[];	 /* defined in oemdata.c */
extern FONT sys16, sys24;	 /* alternate system fonts */
extern int null_patn_line();     /* default area-fill routine */


/*----------------------------------------------------------------------*/
/*  name        get_config                                              */
/*                                                                      */
/*  synopsis    get_config(CfgPtr)                                      */
/*              CONFIG *CfgPtr;     Pointer to returned config struct   */
/*                                                                      */
/*  description This function returns the configuration data for the    */
/*              current mode of operation. The configuration            */
/*              information is copied into the structure pointed to by  */
/*              CfgPtr.                                                 */
/*----------------------------------------------------------------------*/
/*  07/17/88    Original version written......... W.S.Egr/J.G.Littleton */
/*  11/23/88    Added current_mode to config................... W.S.Egr */
/*  01/19/89    Removed ModeNum parameter..................Graham Short */
/*  03/23/90	Modified for TMS340 Graphics Library......J.R. Van Aken */
/*----------------------------------------------------------------------*/
get_config(CfgPtr )
CONFIG       *CfgPtr;
{
    CfgPtr->version_number    = config.version_number;
    CfgPtr->comm_buff_size    = 0;	  /* differs from TIGA */
    CfgPtr->sys_flags         = config.sys_flags;
    CfgPtr->device_rev        = config.device_rev;
    CfgPtr->num_modes         = config.num_modes;
    CfgPtr->current_mode      = config.current_mode;
    CfgPtr->program_mem_start = config.program_mem_start;
    CfgPtr->program_mem_end   = config.program_mem_end;
    CfgPtr->display_mem_start = config.display_mem_start;
    CfgPtr->display_mem_end   = config.display_mem_end;
    CfgPtr->stack_size        = config.stack_size;
    CfgPtr->shared_mem_size   = config.shared_mem_size;
    CfgPtr->shared_host_addr  = config.shared_host_addr;
    CfgPtr->shared_gsp_addr   = config.shared_gsp_addr;
    CfgPtr->mode              = *modeinfo;
}

/*----------------------------------------------------------------------*/
/*  name        set_config                                              */
/*                                                                      */
/*  synopsis    set_config(ModeNum, InitDraw, NumModes, Set)            */
/*              int ModeNum;        Mode number                         */
/*              int InitDraw;       Initialize drawing variables        */
/*              int NumModes;       Number of modes                     */
/*              SETUP *Set;         Setup structure                     */
/*                                                                      */
/*  description This function sets the current operating mode of the    */
/*              Graphics Manager using the mode data passed to it in    */
/*              the Setup structure. The ModeNum of the current mode    */
/*              is stored in the current config structure               */
/*----------------------------------------------------------------------*/
/*  07/17/88    Original version written......... W.S.Egr/J.G.Littleton */
/*  11/23/88    Added current_mode to config................... W.S.Egr */
/*  01/19/89    Modified to download data from host........Graham Short */
/*  01/30/89    Added InitDraw flag........................Graham Short */
/*  02/06/89    Changed text initialization................Graham Short */
/*  03/30/90	Modified for TMS340 Graphics Library......J.R. Van Aken */
/*----------------------------------------------------------------------*/
short set_config(ModeNum, InitDraw)
int ModeNum, InitDraw;
{
    SETUP *Set;
    int i;
    short *p, *r;

    if (ModeNum >= num_modes || ModeNum < -1)
	return (0);	     /* illegal mode number */
    if (ModeNum == -1)
	ModeNum = 0;	     /* default mode number */
    /*----------------------------------------------------------------------*/
    /* Currently two constants MAX_PAGES and MAX_OFFSCREEN have to be	    */
    /* defined by the OEM to fix the maximum size of the config 	    */
    /* structure, both on the host and on the GSP side. 		    */
    /*----------------------------------------------------------------------*/
    Set = &mode_setup[ModeNum];
    default_setup = *Set;
    setup         = (uchar *) &default_setup;
    modeinfo      = (MODEINFO       *)(setup + Set->header.Mode_Info_offset);
    monitorinfo   = (uchar	    *)(setup + Set->header.Monitor_Info_offset);
    page          = (PAGE           *)(setup + Set->header.Page_Info_offset);
    offscreen     = (OFFSCREEN_AREA *)(setup + Set->header.Off_Screen_offset);
    /*----------------------------------------------------------------------*/
    /*  Add the following if the OEM_Data structure was defined in the      */
    /*	oem.h file.							    */
    /*----------------------------------------------------------------------*/
     oemdata       = (OEMDATA        *)(setup + Set->header.OEM_Data_offset);   

    /*------------------------------------------------------------------*/
    /*  Copy configuration information for this mode into the global    */
    /*  config structure                                                */
    /*------------------------------------------------------------------*/
    config.device_rev	= getrev();
    config.current_mode = ModeNum;
    config.num_modes	= num_modes;
    config.mode 	= *modeinfo;	  /* Copy mode info struct */

    /*------------------------------------------------------------------*/
    /*	Select system font based on display resolution			*/
    /*------------------------------------------------------------------*/
    if (config.mode.disp_hres > 800)
	sysfont = &sys24;
    else
	sysfont = &sys16;

    /*------------------------------------------------------------------*/
    /*  Initialize Mode-specific I/O registers                          */
    /*------------------------------------------------------------------*/
    *(ushort *)PSIZE  = modeinfo->disp_psize;	/* Set up pixel size */
    *(ushort *)DPYTAP = 0;             
    set_dpitch(modeinfo->disp_pitch);
#if GSP_34010
    field_insert(DPYSTRT, 2, 0);    /* LCSTRT = 0 */
    field_insert(DPYSTRT+2, 14, ~(page->DpyStart>>10));
#endif
#if GSP_34020
    *(ulong  *)DPYST20 = PAGE20->DpyStart;
#endif

    /*------------------------------------------------------------------*/
    /*  Initialize B-file registers                                     */
    /*------------------------------------------------------------------*/
    /* Set up screen offset */
    poke_breg(OFFSET, page->BaseAddr);
    /* set up clip rectangle */
    poke_breg(WSTART, 0);               
    poke_breg(WEND,
	 (modeinfo->disp_vres<<16) + (modeinfo->disp_hres) - 0x00010001);

    /*------------------------------------------------------------------*/
    /*  ADD ANY OEM-SPECIFIC INITIALIZATION FOR A SPECIFIED MODE AT     */
    /*  THIS POINT. IT MAY BE DESIRABLE FOR A GIVEN PORT TO DEFINE      */
    /*  ITS OWN ARRAY OF STRUCTURES (ONE FOR EACH MODE) WHICH MAY BE    */
    /*  USED FOR INITIALIZATION IN THIS FUNCTION.                       */
    /*------------------------------------------------------------------*/
    *(ushort *)0xC0002000 = oemdata->CR0;	/* load BGA register 0 */
    *(ushort *)0xC0002010 = oemdata->CR1;	/* load BGA register 1 */
    *(ushort *)0xC0002020 = oemdata->CR2;	/* load BGA register 2 */

    /*------------------------------------------------------------------*/
    /*  Initialize video timing registers and monitor data              */
    /*------------------------------------------------------------------*/
    init_video_regs(monitorinfo);

    /*--------------------------------------------------------------*/
    /*  Load default palette.  Note that the above globals need to  */
    /*	be set up before this function is called.		    */
    /*--------------------------------------------------------------*/
    init_palet();

    /*--------------------------------------------------------------*/
    /* Check whether drawing environment is to be initialized.	    */
    /*--------------------------------------------------------------*/
    if (!InitDraw)
	return (1);	/* no initialization */

    /*--------------------------------------------------------------*/
    /* Hardware System Initialization:				    */
    /*	 -- Globally disable all interrupts (IE=0 in status reg.)   */
    /*	 -- Individually disable selected interrupts (INTENB=0)     */
    /*	 -- Enable GSP instruction cache (CD=0) 		    */
    /*	 -- Set up DRAM refresh 				    */
    /* Is this the right place to initialize system functions such  */
    /* as interrupts, cache and DRAM refresh?  Maybe yes, maybe no. */
    /*--------------------------------------------------------------*/
    asm("    DINT");                 /* globally disable interrupts */
    *(ushort *)INTENB = 0;	     /* disable selected interrupts */
    field_insert(CONTROL+15, 1, 0);  /* enable instruction cache */
    field_insert(CONTROL+2, 3, 1);   /* setup DRAM refresh control */

    /*--------------------------------------------------------------*/
    /*	Set up CONTROL register as follows:			    */
    /*	T = 0:		Disable pixel transparency		    */
    /*	W = 3:		Enable window clipping, but not WV interrupt*/
    /*	PBH = PBV = 0:	Array move starts at upper left pixel	    */
    /*	PP = 0: 	Select replace operation		    */
    /*--------------------------------------------------------------*/
    *(ushort *)CONTROL &= ~(TRN_MASK | PBH_MASK | PBV_MASK | PPOP_MASK);
    *(ushort *)CONTROL |= WDW_MASK;

    /*--------------------------------------------------------------*/
    /*	Clear PMASK register to enable all planes		    */
    /*--------------------------------------------------------------*/
    *(ulong *)PMASK = 0;

    /*--------------------------------------------------------------*/
    /*	Set COLOR0 to black and COLOR1 to white.  These must be     */
    /*	initialized AFTER the call that loads the default palette.  */
    /*--------------------------------------------------------------*/
    set_fcolor(get_nearest_color(0xC0, 0xC0, 0xC0, 0xC0));
    set_bcolor(get_nearest_color(0, 0, 0, 0));

    /*--------------------------------------------------------------*/
    /*	Initialize drawing environment				    */
    /*--------------------------------------------------------------*/
    env.srcbm	  = env.dstbm = 0;
    env.xyorigin  = 0;
    env.pensize   = 0x00010001l;
    env.stylemask = -1;
    pattern.width = pattern.height = pattern.depth = 0;
    pattern.data = (PTR)0;
    pattern.hsrv = null_patn_line;
    pattern.srv = 0;

    /*--------------------------------------------------------------*/
    /*	Initialize text structure				    */
    /*--------------------------------------------------------------*/
    init_text();

    return (1);
}

