/*
 * $Date: $
 * $Source: $
 * $Revision: $
 * $State: $
 *
 * $Log: $
 */

#ifndef _EMU_VIDEO_H
#define _EMU_VIDEO_H

#include "emu_defs.h"

/***********************************************************************/
/* Here's an idea to clean up the video code: Build a 'virtual' video
   support, a bit like the VFS in the linux kernel.
   The following structure defines the currently active video routines.
   There should be one such structure for each 'video front end',
   i.e. terminal, ncurses, console, X.
   The pointer 'Video' will be initialized at startup to point to
   the video_system struct of the active frontend and Video->init
   will then be called. The other contents don't have to be valid
   before Video->init() but the recommended method is to define
   them statically.

   Most of the function pointers defined here can be set to NULL for
   no special handling.
   functions returning int should return zero for normal completion,
   non-zero on error (unless specified otherwise).

   The contents of this struct should only be changed by init, cleanup
   and (maybe) setmode.

   is_mapped:      true if video ram is directly mapped and update_screen is
                   not needed
   init:           does all front-end setup (map memory, open XWindow, etc.)
   close:          does all front-end cleanup
   setmode:        ???
   update_screen:  partially update screen and cursor from video memory
   update_cursor:  update cursor position & shape.  called *only* if
                   update_screen does not exist or is not done because
                   the video memory is clean.
*/


struct video_system {
  Boolean is_mapped;
  int     (*init)(void);
  void    (*close)(void);
  int     (*setmode)(int type, int xsize,int ysize);
  int     (*update_screen)(void);
  void    (*update_cursor)(void);
};

/**********************************************************************/

/**********************************************************************/

#if CONFIG_DUALMON && CONFIG_VIDEO_CHECK_DIRTY
  #error "Currently CONFIG_DUALMON can't be used together with CONFIG_VIDEO_CHECK_DIRTY"
#endif


/**********************************************************************/
typedef struct { Bit8u end, start; } cshape;

#define CURSOR_START(c) ((int)((cshape*)&c)->start)
#define CURSOR_END(c)   ((int)((cshape*)&c)->end)
#define NO_CURSOR       0x0100

#define MAX_COLUMNS     132
#define MAX_LINES       60

/**********************************************************************/
/* macros for accessing video memory. w is an ushort* 
   to a character cell, attr is a byte.
*/

#define CHAR(w) ((Bit8s)READ_BYTE(w))
#define ATTR(w) ((Bit8u)READ_BYTE(((Bit8u *)(w))+1))

#define ATTR_FG(attr) (attr & 0x0F)
#define ATTR_BG(attr) (attr >> 4)

/**********************************************************************/
/* scroll queue */

#if CONFIG_USE_SCROLL_QUEUE

struct scroll_entry {
   Bit16u x0,y0,x1,y1;
   Bit16u n;
   Bit8u  attr;
};

#define SQ_MAXLENGTH 5

struct scroll_entry scroll_queue[SQ_MAXLENGTH+1];
int sq_head,sq_tail;

struct scroll_entry *get_scroll_queue();
void clear_scroll_queue();

extern int video_update_lock;

#define VIDEO_UPDATE_LOCK() video_update_lock++;
#define VIDEO_UPDATE_UNLOCK() video_update_lock--;

#else
#define video_update_lock 0
#define VIDEO_UPDATE_LOCK()
#define VIDEO_UPDATE_UNLOCK()
#define clear_scroll_queue()
#endif

/**********************************************************************/
/* Character set defines */
#define CHARSET_LATIN	1
#define CHARSET_IBM	2
#define CHARSET_FULLIBM	3

/* Various defines for all common video adapters */
#define CARD_VGA	1
#define CARD_EGA	2
#define CARD_CGA	3
#define CARD_MDA	4

/* The various VGA chipsets */
#define CHIPSET_DETECT     0
#define CHIPSET_EGA        1
#define CHIPSET_VGA        2
#define CHIPSET_ARK        3
#define CHIPSET_ATI        4
#define CHIPSET_CIRRUS     5
#define CHIPSET_ET3000     6
#define CHIPSET_ET4000     7
#define CHIPSET_GVGA6400   8
#define CHIPSET_MACH32     9
#define CHIPSET_OAK        10
#define CHIPSET_PARADISE   11
#define CHIPSET_S3         12
#define CHIPSET_TVGA8900   13

/**********************************************************************/
EXTERN struct video_system *Video INIT(NULL);
EXTERN ushort *screen_adr;   /* pointer to video memory of current page */
                             /* currently displayed page (was scrbuf) */
EXTERN ushort *prev_screen;  /* pointer to currently displayed screen   */
                             /* used&updated by Video->update_screen    */

EXTERN Bit32u virt_text_base INIT(0);
EXTERN Bit32u phys_text_base INIT(0);
EXTERN int    video_combo    INIT(0);
EXTERN int    video_subsys;
EXTERN Bit32u graph_base     INIT(0xA0000);
EXTERN Bit32u graph_size     INIT(0x20000);

EXTERN int video_mode      INIT(0);
EXTERN int video_page      INIT(0); 
EXTERN int char_blink      INIT(0);
EXTERN int co              INIT(80);
EXTERN int li              INIT(25);
EXTERN int cursor_col      INIT(0);
EXTERN int cursor_row      INIT(0);
EXTERN int cursor_blink    INIT(1);
EXTERN ushort cursor_shape INIT(0xe0f);
EXTERN int font_height     INIT(16);
EXTERN int vga_font_height INIT(16);  /* current EMULATED setting for vga font height */
EXTERN int std_font_height INIT(16);  /* font height set by int10,0 mode 3 */
EXTERN int text_scanlines  INIT(400);   /* # of scan lines in textmodes */
                             /* these have effect only on video mode sets! */
EXTERN unsigned int screen_mask;  /* bit mask for vm86s.screen_bitmap */

#define TEXT_SIZE	(li*co*2) /* 4096 text page size */
#define PAGE_ADDR(pg)	(caddr_t)(virt_text_base + (pg*TEXT_SIZE))
#define SCREEN_ADR(s)	((Bit16u *)(virt_text_base + (s*TEXT_SIZE)))

/* Defines for Monochrome Display Adapter */

#define MDA_INIT_SCREEN_MODE   7 /* 80x25 MDA monochrome */
#define MDA_CONF_SCREEN_MODE   (3<<4)	/* for int 11h info     */
#define MDA_VIDEO_COMBO        1
#define MDA_VIDEO_SUBSYS       1 /* 1=mono               */
#define MDA_PHYS_TEXT_BASE     0xB0000
#define MDA_VIRT_TEXT_BASE     0xB0000
#define MDA_CARD_BASE          0xB0000
#define MDA_CARD_SIZE          0x10000
#define MDA_BASE_CRTC          0x3b4

/* Defines for Color Graphics Adapter */

#define CGA_INIT_SCREEN_MODE   3 /* 80x25 VGA color */
#define CGA_CONF_SCREEN_MODE   (2<<4)	/* (2<<4)=80x25 color CGA/EGA/VGA */
#define CGA_VIDEO_COMBO        4 /* 4=EGA (ok), 8=VGA (not ok?) */
#define CGA_VIDEO_SUBSYS       0 /* 0=color */
#define CGA_PHYS_TEXT_BASE     0xB8000
#define CGA_VIRT_TEXT_BASE     0xB8000
#define CGA_CARD_BASE          0xB8000
#define CGA_CARD_SIZE          0x08000
#define CGA_BASE_CRTC          0x3d4

/* Defines for Enhanched Graphics Adapter, same as CGA */

#define EGA_INIT_SCREEN_MODE   3 /* 80x25 VGA color */
#define EGA_CONF_SCREEN_MODE   (2<<4)	/* (2<<4)=80x25 color CGA/EGA/VGA */
#define EGA_VIDEO_COMBO        4 /* 4=EGA (ok), 8=VGA (not ok?) */
#define EGA_VIDEO_SUBSYS       0 /* 0=color */
#define EGA_PHYS_TEXT_BASE     0xB8000
#define EGA_VIRT_TEXT_BASE     0xB8000
#define EGA_CARD_BASE          0xB0000
#define EGA_CARD_SIZE          0x10000
#define EGA_BASE_CRTC          0x3d4

/* Defines for Video Graphic Array, same as CGA */

#define VGA_INIT_SCREEN_MODE   3 /* 80x25 VGA color */
#define VGA_CONF_SCREEN_MODE   (2<<4)	/* (2<<4)=80x25 color CGA/EGA/VGA */
#define VGA_VIDEO_COMBO        8 /* 4=EGA (ok), 8=VGA (not ok?) */
#define VGA_VIDEO_SUBSYS       0 /* 0=color */
#define VGA_PHYS_TEXT_BASE     0xB8000
#define VGA_VIRT_TEXT_BASE     0xB8000
#define VGA_CARD_BASE          0xA0000
#define VGA_CARD_SIZE          0x20000
#define VGA_BASE_CRTC          0x3d4

extern void fake_video_port_init(void);
extern void fake_video_port_reset(void);

extern Bit8u video_port_in(Bit32u port);
extern void  video_port_out(Bit32u port, Bit8u byte);

extern void  video_config_init(void);
extern void  video_config_reset(void);

extern void clear_screen(int s,int att);
extern void gettermcap(int);
extern void scr_state_init(void);
extern void get_screen_size(void);

#define scrollup(x0,y0,x1,y1,l,att) Scroll(x0,y0,x1,y1,l,att)
#define scrolldn(x0,y0,x1,y1,l,att) Scroll(x0,y0,x1,y1,-(l),att)

extern void Scroll(Bit16u *sadr,int x0,int y0,int x1,int y1,int n,int attr);

#endif /* _EMU_VIDEO_H */

