/*************************************************************
 *
 * OVERSCAN.H         (c)1990  K.Isakovic   Berlin, 12.03.90
 *
 *************************************************************
 *    HEADER-File for the OverScan-Xbios-Extensions
 *
 * The special OverScan Xbios functions have no effect under
 * `normal conditions'. They do not produce any bombs or
 * error messages. They are just ignored.
 *
 * The function numbers changed since the last OverScan versions,
 * because TT-TOS needs the numbers 84-90. The old numbers are
 * still processed.
 *
 * for TurboC 1.1
 *
 * updated for LATTICE C V5.5 by David Nash
 * SCREEN -> OSCAN_SCREEN
 * OVERPATCH -> OSCAN_PATCH
 */ 
/*#include <tos.h> */

typedef struct 
{
 short	width;            /* width in pels                   */
 short	height;           /* height in pels                  */
 short	bytes_per_line;   /* bytes per screen line           */
 long		length_of_screen; /* screen length in bytes          */
 long		physbase_offset;  /* screen start offset != Physbase */
 long		logbase_offset;   /* screen start offset != Logbase  */
} OSCAN_SCREEN;

typedef struct
{
 short  low_w  ,mid_w  ,high_w;   /* width in pels                 */
 short  low_h  ,mid_h  ,high_h;   /* height in pels                */
 long low_off,mid_off,high_off; /* screen offset != Logbase      */
 long mono_add,color_add;       /* additional memory requirement */
 char clear_scan;               /* scan code of clear function   */
 char clear_shift;              /* shift code of clear function  */
 char setup_shift;              /* shift code for setup (mask)   */
 char invert_shift;             /* shift code to invert mode     */
 char abort_shift;              /* shift code to cancel          */
} OSCAN_PATCH;

int Oscanis(void)
{
  return (int)xbios(4200) ;
}
/*
 * Returns either 4200 or version number. Version 1.8 (the first
 * supporting Xbios) returns $0108 (HEX!). The present version 3.0
 * yields $300 etc. A return value of 4200 corresponds to version
 * 10.68 and would therefore never appear.
 * 
 */
 
OSCAN_SCREEN *Oscantab(int Res)
{
 return (OSCAN_SCREEN *)xbios(4201,Res) ;
}
/*
 * Returns a pointer to the data structure OSCAN_SCREEN. Res tells, for
 * which of the resolutions the pointer is required. For each
 * resolution a different pointer is returned.
 * The following values are valid:
 *    Res  0 -> Low
 *    Res  1 -> Mid
 *    Res  2 -> High
 *    Res -1 -> Current resolution. The switch position is 
 *              considered.
 * The data structure is updated with every call of Oscantab().
 */
 
int Oscanphy(int Mode)
{
 return (int)xbios(4202,Mode);
}
/*    
 * This function sets the Physbase emulator's mode. If the emulator
 * is turned on, the value of Logbase is returned.
 *
 *    Mode  0 -> PhysbaseEmulator off
 *    Mode  1 -> PhysbaseEmulator on  (default)
 *    Mode -1 -> get state
 *
 * IMPORTANT!
 *------------
 *   You must turn on the Physbase emulator before programme 
 *   termination!
 */

int Oscanscr(int Mode)
{
  return (int)xbios(4203,Mode);
}
/*    
 * This function enables or disables the `Setscreen' call.
 * Normally, relocation of the screen or changing the resolution
 * is not allowed with OverScan.
 *
 *    Mode  0 -> enable Setscreen
 *    Mode  1 -> DISABLE Setscreen (default)
 *    Mode -1 -> get state
 * The current state is returned.
 *
 * If you want to change the screen memory address, you must not
 * destroy the offset between Logbase and Physbase.
 *
 * IMPORTANT!
 *------------
 *   You must disable the Setscreen call before programme termination!
 */

int Oscanvb(int Mode)
{
  return (int)xbios(4204,Mode);
}
/*
 * This function may disable the VB Randtest routine and the test
 * for Shift/Shift/Clear in the IKBD interrupt.
 * These tests cost 1-2% cpu time, what might be too much for time
 * critical MIDI routines or animations.
 *
 *    Mode  0 -> disable tests
 *    Mode  1 -> enable tests  (default)
 *    Mode -1 -> get state
 * The current state is returned.
 *
 * IMPORTANT!
 *------------
 *  You have to enable the tests before programme termination.
 */

OSCAN_PATCH *Oscanpatch(void)
{
  return (OSCAN_PATCH *)xbios(4205);
}
/*
 * Returns a pointer to the OverScan patch area.
 */
 
int Oscanswitch(int Mode)
{
  return (int)xbios(4206,Mode);
}
/*
 * This is the most powerful function OverScan provides. It
 * switches the current mode. Not only the hardware is switched
 * but all GEM variables are updated and the screen contents are
 * copied.
 *
 *    Mode  0 -> normal mode
 *    Mode  1 -> OverScan
 *    Mode -1 -> get state
 * The current state is returned.
 */


/*************************************************************
 *  Utility function to create a second screen page
 *  Works without OverScan also
 */
int OverscanScreen(long *Block,long *NewLog,long *NewPhy,int Res)
{
/*  Block     pointer to the memory area returned by Malloc
 *  NewLog    pointer to Logbase value of the new screen page
 *  NewPhy    pointer to Physbase value of the new screen page
 *  Rez       required resolution for the new screen page
 *
 *  If no memory is available for the second screen page, Block
 *  is negative and the function returns 0. Otherwise 1 is returned.
 */
  if ((int)Oscanis()!= 4200)             /* test OverScan version */
    {
    OSCAN_SCREEN *Over;

    Over   = Oscantab(Res);                         /* get values */
    *Block = (long)Malloc(Over->length_of_screen);  /* memory     */
    if (*Block > 0)
      {
      *NewLog = ((*Block+256L)&0xffff00L) + Over->logbase_offset;
      *NewPhy = ((*Block+256L)&0xffff00L) + Over->physbase_offset;
      return 1;
      }
    }
  else
    {
    *Block  = (long)Malloc(32256L);               /* wo/ OverScan */
    if (*Block>0)
      {
      *NewLog = (*Block+256L)&0xffff00L;
      *NewPhy = *NewLog;
      return 1;
      }
    }
  return 0;
}

/*************************************************************
 * Utility function to get Logbase/Physbase values
 * Works without OverScan also
 */
void OscanLogPhy(long *CurLog,long *CurPhy)
{
int Emulator;

 Emulator = Oscanphy(-1);       /* save old state               */
 Oscanphy(0);                   /* Physbase emulator off        */
 *CurLog = (long)Logbase();
 *CurPhy = (long)Physbase();
 Oscanphy(Emulator);            /* restore old state            */
}

