/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1987,1988
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:screen_conf.c 12.0$ */
/* $ACIS:screen_conf.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/cacons/RCS/screen_conf.c,v $ */

#if !defined(lint) && !defined(NO_RCS_HDRS)
static char *rcsid = "$Header:screen_conf.c 12.0$";
#endif

#include "../h/param.h"
#include "../h/conf.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/errno.h"
#include "../h/ioctl.h"
#include "../h/tty.h"
#include "../machinecons/screen_conf.h"
#include "../machinecons/consdefs.h"
#include "../machinecons/consvars.h"
#include "../machinecons/buf_emul.h"
#ifdef ATR
#include "../ca_atr/kls.h"
#include "../ca_atr/pcif.h"
#include "../pc_code/vga.h"
extern struct postconfig config;
#endif ATR
#ifdef IBMRTPC
#include "../machinecons/kls.h"
#endif IBMRTPC

#ifdef KERNEL
#include "../machine/io.h"                /* for DISPLAY */
int nodev();
#else
 #include "sa.h"
#define nodev 0
#endif

/* Common routines for table */
int screen_probe();			/* Generic screen probe routine */
int nulldev();				/* Returns False (0) */
int nodev();				/* Returns NODEV */
int noloc();				/* set u.u_error and print msg */

#include "xtenemul.h"			/* to know if we need "loc" routines */

#if defined(IBMRTPC) || defined(AT)
#include "aed.h"
#if NAED > 0
int aed_probe();
int aed_screen_init();
int aed_screen_putc();
#ifndef MINIROOT
int aed_screen_print();
#else
#define aed_screen_print nulldev
#endif /* !MINIROOT */
int aed_pos_cursor();
int aed_screen_blank();
int aed_screen_move();
int aed_color_table();
int aed_put_status();
#else
#define aed_probe nulldev
#define aed_screen_init nodev
#define aed_screen_putc nodev
#define aed_screen_print nodev
#define aed_pos_cursor nodev
#define aed_screen_blank nodev
#define aed_screen_move nodev
#define aed_color_table nodev
#define aed_put_status nodev
#endif NAED

#if NAED > 0 && NXTENEMUL > 0
int aed_show_loc();
int aed_hide_loc();
int aed_pos_loc();
int aed_load_loc();
int aed_apa_init();
#else
#define aed_show_loc nodev
#define aed_hide_loc nodev
#define aed_pos_loc nodev
#define aed_load_loc noloc
#define aed_apa_init nodev
#endif

#include "apasixteen.h"
#if NAPASIXTEEN > 0
int apa16_probe();
int apa16_screen_init();
int apa16_screen_putc();
int apa16_pos_cursor();
int apa16_screen_blank();
int apa16_screen_move();
int apa16_color_table();
#ifndef MINIROOT
int apa16_screen_print();
#else
#define apa16_screen_print nulldev
#endif /* !MINIROOT */
#else
#define apa16_probe nulldev
#define apa16_screen_init nodev
#define apa16_screen_putc nodev
#define apa16_screen_print nodev
#define apa16_pos_cursor nodev
#define apa16_screen_blank nodev
#define apa16_screen_move nodev
#define apa16_color_table nodev
#endif NAPASIXTEEN

#if NAPASIXTEEN > 0 && NXTENEMUL > 0 
int apa16_show_loc();
int apa16_hide_loc();
int apa16_pos_loc();
int apa16_load_loc();
int apa16_init_loc();
#else
#define apa16_show_loc nodev
#define apa16_hide_loc nodev
#define apa16_pos_loc nodev
#define apa16_load_loc noloc
#define apa16_init_loc nodev
#endif

#include "apaeightc.h"
#if NAPAEIGHTC > 0
int apa8C_probe();
int apa8C_screen_init();
int apa8C_screen_putc();
int apa8C_pos_cursor();
int apa8C_screen_blank();
int apa8C_screen_move();
int apa8C_color_table();
#ifndef MINIROOT
int apa8C_screen_print();
#else
#define apa8C_screen_print nulldev
#endif /* !MINIROOT */
#else
#define apa8C_probe nulldev
#define apa8C_screen_init nodev
#define apa8C_screen_putc nodev
#define apa8C_screen_print nodev
#define apa8C_pos_cursor nodev
#define apa8C_screen_blank nodev
#define apa8C_screen_move nodev
#define apa8C_color_table nodev
#endif NAPAEIGHTC

#if NAPAEIGHTC > 0 && NXTENEMUL > 0 
int apa8C_show_loc();
int apa8C_hide_loc();
int apa8C_pos_loc();
int apa8C_load_loc();
int apa8C_init_loc();
#else
#define apa8C_show_loc nodev
#define apa8C_hide_loc nodev
#define apa8C_pos_loc nodev
#define apa8C_load_loc noloc
#define apa8C_init_loc nodev
#endif

#include "apaeight.h"
#if NAPAEIGHT > 0
int apa8_probe();
int apa8_screen_init();
int apa8_screen_putc();
int apa8_pos_cursor();
int apa8_screen_blank();
int apa8_screen_move();
int apa8_color_table();
#ifndef MINIROOT
int apa8_screen_print();
#else
#define apa8_screen_print nulldev
#endif /* !MINIROOT */
#else
#define apa8_probe nulldev
#define apa8_screen_init nodev
#define apa8_screen_putc nodev
#define apa8_screen_print nodev
#define apa8_pos_cursor nodev
#define apa8_pos_loc nodev
#define apa8_screen_blank nodev
#define apa8_screen_move nodev
#define apa8_color_table nodev
#endif NAPAEIGHT

#if NAPAEIGHT > 0 && NXTENEMUL > 0 
int apa8_show_loc();
int apa8_hide_loc();
int apa8_pos_loc();
int apa8_load_loc();
int apa8_init_loc();
#else
#define apa8_show_loc nodev
#define apa8_hide_loc nodev
#define apa8_pos_loc nodev
#define apa8_init_loc nodev
#define apa8_load_loc noloc
#endif

#include "ega.h"
#if NEGA > 0
int ega_probe();
int ega_screen_init();
int ega_screen_putc();
int ega_pos_cursor();
#define ega_pos_loc nodev
int ega_screen_blank();
int ega_screen_move();
#ifndef MINIROOT
int ega_screen_print();
#else
#define ega_screen_print nulldev
#endif /* !MINIROOT */
int ega_color_table();
extern int ega_screen_type;
#else
#define ega_probe nulldev
#define ega_screen_init nodev
#define ega_screen_putc nodev
#define ega_screen_print nodev
#define ega_pos_cursor nodev
#define ega_pos_loc nodev
#define ega_screen_blank nodev
#define ega_screen_move nodev
#define ega_color_table nodev
#endif NEGA

#include "mono.h"
#if NMONO > 0

int mono_probe();
int mono_screen_init();
int mono_screen_putc();
#ifndef MINIROOT
int mono_screen_print();
#else
#define mono_screen_print nulldev
#endif /* !MINIROOT */
int mono_pos_cursor();
#define mono_pos_loc nodev
int mono_screen_blank();
int mono_screen_move();
int mono_color_table();
#else
#define mono_probe nulldev
#define mono_screen_init nodev
#define mono_screen_putc nodev
#define mono_screen_print nodev
#define mono_pos_cursor nodev
#define mono_pos_loc nodev
#define mono_screen_blank nodev
#define mono_screen_move nodev
#define mono_color_table nodev
#endif NMONO

#include "mpel.h"
#if NMPEL > 0
int mpel_probe();
int mpel_screen_init();
int mpel_screen_putc();
#ifndef MINIROOT
int mpel_screen_print();
#else
#define mpel_screen_print nulldev
#endif /* !MINIROOT */
int mpel_pos_cursor();
int mpel_screen_blank();
int mpel_screen_move();
int mpel_color_table();
#else
#define mpel_probe nulldev
#define mpel_screen_init nodev
#define mpel_screen_putc nodev
#define mpel_screen_print nodev
#define mpel_pos_cursor nodev
#define mpel_screen_blank nodev
#define mpel_screen_move nodev
#define mpel_color_table nodev
#endif NMPEL
#define NVGA	0
#define NIBMVBARMMDXIV 0
#endif IBMRTPC

#if defined(ATR) && !defined(AT)
#include "vga.h"
#include "pcbios.h"
#if NVGA > 0
int vga_probe();
int vga_screen_init();
int vga_screen_putc();
int vga_pos_cursor();
#define vga_pos_loc nodev
int vga_screen_blank();
int vga_screen_move();
int vga_screen_print();
int vga_color_table();
int vga_screen_save();
int vga_screen_restore();
#else
#define vga_probe nulldev
#define vga_screen_init nodev
#define vga_screen_putc nodev
#define vga_screen_print nodev
#define vga_pos_cursor nodev
#define vga_pos_loc nodev
#define vga_screen_blank nodev
#define vga_screen_move nodev
#define vga_color_table nodev
#define vga_screen_save nodev
#define vga_screen_restore nodev
#endif NVGA > 0
#include "ibmvbarmmmdxiv.h"
#if  (NIBMVBARMMMDXIV > 0) 
int ibm8514_probe();
int ibm8514_screen_init();
int ibm8514_screen_putc();
int ibm8514_pos_cursor();
#define ibm8514_pos_loc nodev
int ibm8514_screen_blank();
int ibm8514_screen_move();
int ibm8514_screen_print();
int ibm8514_color_table();
int ibm8514_screen_save();
int ibm8514_screen_restore();
#else
#define ibm8514_probe nulldev
#define ibm8514_screen_init nodev
#define ibm8514_screen_putc nodev
#define ibm8514_screen_print nodev
#define ibm8514_pos_cursor nodev
#define ibm8514_pos_loc nodev
#define ibm8514_screen_blank nodev
#define ibm8514_screen_move nodev
#define ibm8514_color_table nodev
#define ibm8514_screen_save nodev
#define ibm8514_screen_restore nodev
#endif (NIBMVBARMMMDXIV > 0)
#define NEGA 0
#endif ATR

int screen_sw_size = sizeof (struct screen_sw);

/*  Console screen switch table to support different heads */
struct screen_sw screen_sw[] = {
/*  ENTRY	NAME		PROBE
	INIT			PUTC			POS_CUR
	BLANK			MOVE			PRINT
	RWADDR			LINES	WIDTH	VBITS	HBITS FLAGS
	DEF_OUTE		POS_LOC 		LOAD_LOC
	SHOW_LOC		HIDE_LOC		APA_INIT
	LOGO_CHAR		COLOR_TABLE		COLOR_TABLE_SIZE
	PUT_STATUS		ADDR
*/
{ /* 0 */	"GENERIC   ",   nulldev,
	nulldev,		nulldev,		nulldev,
	nulldev,		nulldev,		nulldev,
	C 0x00000000,		0,	0,	0,	0,	0,
	0,			nulldev,		nulldev,
	nulldev,		nulldev,		nulldev,
	0,			nulldev,		0,
	nulldev,		0,		nodev,	nodev,
},
#if defined(IBMRTPC) || defined(AT)
{ /* 1 */	"aed       ",   aed_probe,
	aed_screen_init,	aed_screen_putc,	aed_pos_cursor,
	aed_screen_blank,	aed_screen_move,	aed_screen_print,
	C ( 0xA4020 + MEM_BASE),	53,	80,	800,	1024,	0,
#ifndef MINIROOT
	E_STDOUTPUT,		aed_pos_loc,		aed_load_loc,
#else
	E_IBMOUTPUT,		aed_pos_loc,		aed_load_loc,
#endif /* !MINIROOT */
	aed_show_loc,		aed_hide_loc,		aed_apa_init,
	'm',                    aed_color_table,        2,
	aed_put_status, 	C ( 0xA4020 + MEM_BASE),		nodev,	nodev,
},

{ /* 2 */	"apa16     ",   apa16_probe,
	apa16_screen_init,	apa16_screen_putc,	apa16_pos_cursor,
	apa16_screen_blank,	apa16_screen_move,	apa16_screen_print,
	C 0xf4d80000,		33,	80,	768,	1024,	0,
	E_IBMOUTPUT,		apa16_pos_loc,		apa16_load_loc,
	apa16_show_loc, 	apa16_hide_loc, 	apa16_init_loc,
	0x1F,			apa16_color_table,	2,
	nulldev,		C ( 0x00D80000 + MEM_BASE),		nodev,	nodev,
},

{ /* 3 */	"apa8c     ",   apa8C_probe,
	apa8C_screen_init,	apa8C_screen_putc,	apa8C_pos_cursor,
	apa8C_screen_blank,	apa8C_screen_move,	apa8C_screen_print,
	C 0xf4d20000,		32,	80,	512,	720,	0,
	E_IBMOUTPUT,		apa8C_pos_loc,		apa8C_load_loc,
	apa8C_show_loc, 	apa8C_hide_loc, 	apa8C_init_loc,
	0x1F,			apa8C_color_table,	16,
	nulldev,		C ( 0x00D20000 + MEM_BASE),		nodev,	nodev,
},

{ /* 4 */	"apa8      ",   apa8_probe,
	apa8_screen_init,	apa8_screen_putc,	apa8_pos_cursor,
	apa8_screen_blank,	apa8_screen_move,	apa8_screen_print,
	C 0xf4d00000,		32,	80,	512,	720,	0,
	E_IBMOUTPUT,		apa8_pos_loc,		apa8_load_loc,
	apa8_show_loc,		apa8_hide_loc,		apa8_init_loc,
	0x1F,			apa8_color_table,	2,
	nulldev,		C ( 0x00D00000 + MEM_BASE),		nodev,	nodev,
},

{ /* 5 */	"ega       ",   ega_probe,
	ega_screen_init,	ega_screen_putc,	ega_pos_cursor,
	ega_screen_blank,	ega_screen_move,	ega_screen_print,
	C (0xb8000 + MEM_BASE),	25,	80,	350,	640,	0,
	E_IBMOUTPUT,		nulldev,		noloc,
	nulldev,		nulldev,		nulldev,
	0xDC,			ega_color_table,	8,
	nulldev,		C ( 0x000B8000 + MEM_BASE),		nodev,	nodev,
},

{ /* 6 */	"monochrome",   mono_probe,
	mono_screen_init,	mono_screen_putc,	mono_pos_cursor,
	mono_screen_blank,	mono_screen_move,	mono_screen_print,
	C (0xb0000 + MEM_BASE),	25,	80,	25,	80,	0,
	E_IBMOUTPUT,		nulldev,		noloc,
	nulldev,		nulldev,		nulldev,
	0xDC,			mono_color_table,	2,
	nulldev,		C ( 0x000b0000 + MEM_BASE),		nodev,	nodev,
},
{ /* 7 */	"megapel   ",	mpel_probe,
	mpel_screen_init,	mpel_screen_putc,	mpel_pos_cursor,
	mpel_screen_blank,	mpel_screen_move,	mpel_screen_print,
	C 0xf4c00000,		34,	80,	1024,	1024,	0,
	E_IBMOUTPUT,		nulldev,		noloc,
	nulldev,		nulldev,		nulldev,
	0x1f,			mpel_color_table,	256,
	nulldev,		(C 0x0c00000 + MEM_BASE),		nodev,	nodev,
},
#endif IBMRTPC
#if defined(ATR) && !defined(AT)
{ /* 1 */	"vga       ",   vga_probe,
	vga_screen_init,	vga_screen_putc,	vga_pos_cursor,
	vga_screen_blank,	vga_screen_move,	vga_screen_print,
	C 0xd00c8000,		25,	80,	350,	640,	0,
	E_IBMOUTPUT,		nulldev,		noloc,
	nulldev,		nulldev,		nulldev,
	0xDC,			vga_color_table,	8,
	nulldev,		C ( 0xd00c8000),	vga_screen_save,
	vga_screen_restore,
},

{ /* 2 */	"ibm8514   ",    ibm8514_probe,
	ibm8514_screen_init,	 ibm8514_screen_putc,	ibm8514_pos_cursor,
	ibm8514_screen_blank,	 ibm8514_screen_move,	ibm8514_screen_print,
	C 0xd00e46e8,		42,	80,	768,	1024,	0,
	E_IBMOUTPUT,		nulldev,		noloc,
	nulldev,		nulldev,		nulldev,
	0xDC,			ibm8514_color_table,	256,
	nulldev,		C ( 0xd00e46e8),	ibm8514_screen_save,
	ibm8514_screen_restore,
},
#endif
{ /* 8 or 3 */	"DUMMY     ",   nulldev,
	nulldev,		nulldev,		nulldev,
	nulldev,		nulldev,		nulldev,
	C 0x00000000,		0,	0,	0,	0,	0,
	E_IBMOUTPUT,		nulldev,		nulldev,
	nulldev,		nulldev,		nulldev,
	0,			nulldev,		0,
	nulldev,		C ( 0x00000000),	nodev,
	nodev,
},

};

/* number of entries in screen_sw table */
int NSCREEN = sizeof (screen_sw) / sizeof (screen_sw[0]);

/* No ansi emulator right now */
#define ansie_open nodev
#define ansie_close nodev
#define ansie_write nodev
#define ansie_ioctl nodev
#define ansie_putc nodev
#define ansie_put_status nodev
#define ansie_color_table nodev
#define ansie_save nodev
#define ansie_restore nodev

/*#include "mac.h"*/
#if NMAC > 0
int mace_open(), mace_close(), mace_read(), mace_write();
int mace_ioctl(), mace_rint(), mace_putc();
#else
#define mace_open nodev
#define mace_close nodev
#define mace_read nodev
#define mace_write nodev
#define mace_ioctl nodev
#define mace_rint nodev
#define mace_putc nodev
#define mace_select nodev
#endif

#ifndef MINIROOT
int stdoe_open(), stde_close(), stde_write(), stde_ioctl(), stde_putc(), stde_put_status(), stde_select(), stde_color_table();
#else
#define stdoe_open nulldev
#define stde_close nulldev
#define stde_write nulldev
#define stde_ioctl nulldev
#define stde_putc nulldev
#define stde_put_status nulldev
#define stde_select nulldev
#define stde_color_table nulldev
#endif /* !MINIROOT */

int kbde_open(), kbde_close(), kbde_read(), kbde_ioctl(), kbde_rint(), kbde_select();

#include "apaeight.h"
#include "apaeightc.h"
#include "apasixteen.h"
#include "mono.h"
#include "ega.h"
#include "mpel.h"
#ifdef ATR
#include "vga.h"
#include "ibmvbarmmmdxiv.h"
#include "pcbios.h"
#else
#define NVGA 0
#define NPCBIOS 0
#define NIBMVBARMMMDXIV 0
#endif
#if (NAPAEIGHT > 0) || (NAPAEIGHTC > 0) || (NAPASIXTEEN > 0) ||       \
    (NMONO > 0) || (NEGA > 0) || (NVGA > 0) ||     \
    (NIBMVBARMMMDXIV > 0) || (NMPEL > 0)
int ibme_open(), ibme_close(), ibme_write(), ibme_ioctl(), ibme_putc(),
 ibme_put_status(), ibme_color_table();
#ifdef ATR
int ibme_save(),ibme_restore();
#endif ATR
#else
#define ibme_open	nodev
#define ibme_close	nodev
#define ibme_write	nodev
#define ibme_ioctl	nodev
#define ibme_putc	nodev
#define ibme_put_status nodev
#define ibme_color_table nodev
#ifdef ATR
#define	ibme_save	nodev
#define ibme_restore	nodev
#endif ATR
#endif NEED EMULATOR

#include "xemul.h"
#if NXEMUL > 0
int x_open(), x_close(), x_read(),  x_write(), x_ioctl(), x_rint(),  x_putc(),	x_select();
#else
#define x_open		nodev
#define x_close 	nodev
#define x_read		nodev
#define x_write 	nodev
#define x_ioctl 	nodev
#define x_rint		nodev
#define x_putc		nodev
#define x_select	nodev
#endif NXEMUL

int buf_open(), buf_write(), buf_putc(), buf_ioctl();
#ifdef ATR
int buf_save(),buf_restore();
#endif

#include "aed.h"
#if NAED > 0
int	aedopen(), aedclose(), aedwrite(), aedread(), aedioctl();
#else
#define aedopen nodev
#define aedclose nodev
#define aedwrite nodev
#define aedread nodev
#define aedioctl nodev
#endif

struct emulsw emulsw[] =
{
	/*	Open		Close		Read		Write
		Ioctl		rint		putc		select
		putstatus	colortable	save		restore */
/* 0 */ {
		kbde_open,	kbde_close,	kbde_read,	nulldev,
		kbde_ioctl,	kbde_rint,	nulldev,	stde_select,
		nulldev,	nulldev,
#ifdef ATR
						nodev,		nodev,
#endif ATR
	},
/* 1 */ {
		stdoe_open,	stde_close,	nulldev,	stde_write,
		stde_ioctl,	nodev,		stde_putc,	nulldev,
		stde_put_status, stde_color_table,
#ifdef ATR
						nodev,		nodev,
#endif ATR
	},
/* 2 */ {
		ibme_open,	ibme_close,	nulldev,	ibme_write,
		ibme_ioctl,	nodev,		ibme_putc,	nulldev,
		ibme_put_status,ibme_color_table,
#ifdef ATR
						ibme_save,	ibme_restore,
#endif ATR
	},
/* 3 */ {
		ansie_open,	ansie_close,	nulldev,	ansie_write,
		ansie_ioctl,	nodev,		ansie_putc,	nulldev,
		ansie_put_status,ansie_color_table,
#ifdef ATR
						ansie_save,	ansie_restore,
#endif ATR
	},
/* 4 */ {
		x_open, 	x_close,	x_read, 	nulldev,
		x_ioctl,	x_rint, 	nulldev,	x_select,
		nulldev,	nulldev,
#ifdef ATR
						nodev,		nodev,
#endif ATR
	},
/* 5 */ {
		buf_open,	nulldev,	nulldev,	buf_write,
		buf_ioctl,	nodev,		buf_putc,	nulldev,
		nulldev,	nulldev,
#ifdef ATR
						buf_save,	buf_restore,
#endif ATR
	},
/* 6 */ {
		aedopen,	aedclose,	nulldev,	aedwrite,
		aedioctl,	nodev,		buf_putc,	nulldev,
		nulldev,	nulldev,
#ifdef ATR
						buf_save,	buf_restore,
#endif ATR
	},

#ifdef nodef
/* 7 */ {
		mace_open,	mace_close,	mace_read,	nulldev,
		stde_ioctl,	mace_rint,	nulldev,	nulldev,
		nulldev,	nulldev,
	},
/* 8 */ {
		nulldev,	nulldev,	nulldev,	mace_write,
		mace_ioctl,	nodev,		mace_putc,	nulldev,
		nulldev,	nulldev,
	},
/* 9 */ {
		nodev,		nodev,		nodev,		nulldev,
		nodev,		nodev,		nulldev,	nodev,
		nulldev,	nulldev,
	},
#endif
};

int NEMUL = sizeof (emulsw) / sizeof (emulsw[0]);

screen_init(tp, si)
register struct tty *tp;
register SCREEN_INFO *si;
{
	register int i;
	register char *rwaddr;

EDEBUG (0x01, aed_pr ("IN screen_init\n"));

	cons_if = CONS_GEN;
	cons_display = NO_ENTRY;
	for (i = 0; i < NSCREEN; i++, si++) {
		if (screen_sw[i].init && (screen_sw[i].init != nodev) &&
			(rwaddr = screen_sw[i].rwaddr) != 0) {
			if ((*screen_sw[i].probe)(rwaddr)) {
				screen_sw[i].flags |= CONSDEV_PRESENT;
EDEBUG (0x01, aed_pr ("init %d\n", i));
				(*screen_sw[i].init)();
				if (screen_sw[i].flags == 0) {
					printf("BAD (%s) screen found\n",
						screen_sw[i].name);
					continue;
				}
				screen_sw[i].flags |= (CONSDEV_INIT | CONSDEV_BOTH);
				WS = i;
				if (cons_display == NO_ENTRY)
				    cons_display = i;
				printf ("Inited (%s) screen\n",
					screen_sw[i].name);

			}
			delay(3);
		}
	}
	/*
	 * if we haven't made a choice, or if our choice does not exist then
	 * look for any alive screen.
	 */
	if (cons_display == NO_ENTRY ||
		(screen_sw[cons_display].flags & CONSDEV_ALIVE) == 0) {
		cons_display = NO_ENTRY;	  /* just in case */
		for (i = 0; i < NSCREEN; i++)
			if ((screen_sw[i].flags & CONSDEV_ALIVE) == CONSDEV_ALIVE) {
				cons_display = i;
				break;
			}
	}

/*
 * loop thru the other screens and print message for the screen we are
 * going to use just in case the user is looking at the wrong one.
 */
	for (i = 0; i < NSCREEN; i++) {
		if (i != cons_display && ((screen_sw[i].flags & CONSDEV_ALIVE) == CONSDEV_ALIVE))
			{
			register struct tty *tp = &cons[i];
			si = &cons_info[i];
#ifdef ATR
/* Set the window for the message to the screen */
			set_128_window(screen_addr(i));
#endif ATR
			sichars(i, CE_DEFAULT, si);
			(*emulsw[si->oute.emulator].e_open)(i, tp, si);
			put_status(si, 0,"Console focus is on ");
			put_status(si, 20,screen_sw[cons_display].name);
			(*emulsw[si->oute.emulator].e_close)(tp, si);
			}
	}
#ifdef ATR
/* Reset the window for the Console */
	set_128_window(screen_addr(cons_display));
#endif ATR

	if (cons_display == NO_ENTRY) {
		DISPLAY(0x99);		  /* no screen on system! */
		delay(1000);
		cons_display = CONS_DUMMY; /* keep going anyway */
		screen_sw[CONS_DUMMY].flags |= CONSDEV_ALIVE;
	}
EDEBUG (0x01, aed_pr ("cons_display %d\n", cons_display));
}

#define TEST_PAT 0x65

screen_probe(rwaddr)
register char *rwaddr;
{
	PUT_PC1B(*rwaddr, TEST_PAT);
	delay(3);
	return (GET_PC1B(*rwaddr) == TEST_PAT);
}

#define SPLRETURN(r) { splx(s); return(r); }
/*
 * switch input focus to screen "n" or to next screen (if n < 0)
 */
cons_focus(n)
int n;
{
	register int j,i;
	register SCREEN_INFO *si = NULL;
	register struct tty *tp;
#ifdef ATR
	register int s = spl5();
#else 
	register int s = spl1();
#endif ATR

	if (n >= NSCREEN)
		SPLRETURN (-1); 	  /* can't do it */

	if (n == SCREEN_SWITCH || n == SCREEN_SWITCH_RELOAD) {
		for (j = cons_display + 1; j != cons_display; j = (j + 1) % NSCREEN) {
			if (((screen_sw[j].flags & CONSDEV_INBITS) == CONSDEV_ALIVE) &&
			    (cons[j].t_state & TS_ISOPEN)) {
				break;
			}
		}
/* if only /dev/console is open switch output focus as well */
		if (cons_if == CONS_GEN) {
			for (j = cons_display + 1; j != cons_display;
							j = (j + 1) % NSCREEN) {
				if ((screen_sw[j].flags & CONSDEV_ALIVE) ==
								CONSDEV_ALIVE) {
				   /* close old screen */
				   si = &cons_info[cons_display];
				   tp = &cons[CONS_GEN];
				   (*emulsw[si->oute.emulator].e_close)(tp,si);
				   si = &cons_info[j];
				   sichars(j, CE_DEFAULT, si);
				   (*emulsw[si->oute.emulator].e_open)(j,tp,si);
				   sichars(j, CE_DEFAULT, &cons_info[CONS_GEN]);
				   break;
				}
			}
		}
	} else if (n < 0) {
		SPLRETURN (-1); 	/* Not a valid request */
	} else {
		if (((screen_sw[n].flags & CONSDEV_ALIVE) == CONSDEV_ALIVE) &&
		    (cons[n].t_state & TS_ISOPEN))
			j = n;
		else
			SPLRETURN (-1);
	}

	/*
	 * screen_init can be cleared to force an init which (might) force
	 * a micro-code reload
	 */
	if (n == SCREEN_SWITCH_RELOAD) {
		screen_sw[j].flags &= ~CONSDEV_INIT;
		(*screen_sw[j].init)();
		screen_sw[j].flags |= CONSDEV_INIT;
	}

	for (i = 0; i < NSCREEN; i++) {
		if ((screen_sw[i].flags & CONSDEV_ALIVE) == CONSDEV_ALIVE) {
			si = &cons_info[i];
			tp = &cons[i];
			if ((tp->t_state & TS_ISOPEN) || (i==j)) {
#ifdef ATR
			    set_128_window(screen_addr(i));
#endif ATR
			    put_status(si, 0,"Console focus is on ");
			    put_status(si, 20,screen_sw[j].name);
			} else {
			    if (cons_emul_flag[i] == CE_DEFAULT) {
				sichars(i, CE_DEFAULT, si);
				(*emulsw[si->oute.emulator].e_open)(i,tp, si);
#ifdef ATR
			    set_128_window(screen_addr(i));
#endif ATR
				put_status(si, 0,"Console focus is on ");
				put_status(si, 20,screen_sw[j].name);
				(*emulsw[si->oute.emulator].e_close)(tp, si);
			    }
			}
	}
	}
	/* Set and Return New focus */
#ifdef ATR
	set_128_window(screen_addr(j));
#endif ATR
	if (cons_if != CONS_GEN)
		cons_if=j;
	SPLRETURN (cons_display = j);
}

#ifdef ATR
/*
 * save and restore screens do to hot key hits
 * we return the number of screens that haven't saved yet.
 */
screen_all_save()
{
	int	j, failed = 0;

	for (j = 0; j < NSCREEN+1; j++) {
		if ((screen_sw[j].flags & CONSDEV_ALIVE) ==
							CONSDEV_ALIVE) {
		   if (screen_sw[j].flags & CONSDEV_SAVED)
			continue;
		   if ((*emulsw[cons_info[j].oute.emulator].e_save)
						   (&cons[j],&cons_info[j])) {
			screen_sw[j].flags |= CONSDEV_SAVED;
		   } else {
		        failed++;
		   }
		}
	}

	return(failed);
}

screen_all_restore()
{
	int	j,failed = 0;


	for (j = 0; j < NSCREEN+1; j++) {
		if ((screen_sw[j].flags & CONSDEV_ALIVE) ==
							CONSDEV_ALIVE) {
		   if (!(screen_sw[j].flags & CONSDEV_SAVED))
			continue;
		   if ((*emulsw[cons_info[j].oute.emulator].e_restore)
						   (&cons[j],&cons_info[j])) {
			screen_sw[j].flags &= ~CONSDEV_SAVED;
		   } else {
			failed++;
		   }
		}
	}
	return(failed);
}

screen_in_foreground(display)
	int	display;
{
	int	fg;
	unsigned old_window = get_512_window();
	unsigned vga_win = get_pc_cb(BIOSENT);
	struct vga_params *vga = (struct vga_params *)
				(set_512_window(vga_win)+pcif_512_fw);

	if (config.os_type != OLD_TYPE) {
		/* get the write_status state from the pc_code */
		fg  = (vga->write_status == VGA_WRITE_OK);
	} else {
		fg = 1;
	}
	set_512_window(old_window);
	return(fg);
}

#endif ATR

/*
 * put up a status indicator from the keyboard
 * don't atempt it if the device is not initialized
 */
put_status(si, pos, str)
register SCREEN_INFO *si;
register int pos;
register char *str;
{
	if (screen_sw[WS].flags & CONSDEV_INIT)
		(*emulsw[si->oute.emulator].e_putstatus)(si, pos, str);
}

/*
 * print the current screen (if possible)
 */
print_screen(si, flag)
register SCREEN_INFO *si;
register int flag;
{
	if (flag) {
		screen_sw[WS].flags ^= CONSDEV_LOG;
	}
	(*screen_sw[WS].printscreen)(si, flag);
}


/*
 * reset the screen (by forcing a microcode reload etc. next time it is used
 * mainly used to reload aed microcode.
 */

reset_screen(n)
{
	screen_sw[n].flags &= ~CONSDEV_INIT;
}

siioctl (tp, cmd, data, si)
register struct tty *tp;
int cmd;
caddr_t data;
register SCREEN_INFO *si;
{
	register int error = 0;
	register int save;
	dev_t dev = tp->t_dev;
#ifdef ATR
	int s = spl5();
#else
	int s = spl1();
#endif ATR

	switch (cmd) {

		/* Select which console screen for input focus */
	case CON_SELECT_SCREEN:
		save = cons_display;
		error = cons_focus (*(int *)data);
		*(int *)data = save;

		SPLRETURN (error < 0 ? EINVAL : 0);

		/* get current console screen */
	case CON_GET_SCREEN:
		if (WS == CONS_GEN)
			SPLRETURN(-1);
		*(int *)data = WS;
		break;

		/* Reinitialize screen if it is alive */
	case CON_INIT_SCREEN:
		if (WS == CONS_GEN)
			SPLRETURN(-1);
		if ((save = *(int *)data) < 0) {
			save = WS;
		}
		if ((screen_sw[save].flags & CONSDEV_ALIVE) == CONSDEV_ALIVE) {
			(*screen_sw[save].init)();
			screen_sw[save].flags |= CONSDEV_INIT;
		} else {
			SPLRETURN(EINVAL);
		}

		/* Get the current console switch focus code */
	case CON_GET_FOCUS_CODE:
		*(int *)data = cons_switch_focus_code;
		break;

		/* Set the current console switch focus code */
	case CON_SET_FOCUS_CODE:
		{
		char keys[2];
			save = cons_switch_focus_code;
			cons_switch_focus_code = *(int *)data;
			*(int *)data = save;

			/* Change new switch focus to just make */
			keys[0] = cons_switch_focus_code;
			keys[1] = 0;
			set_key_type(KSETMAKE, keys);

			/* Put old code back to make break */
			keys[0] = save;
			keys[1] = 0;
			set_key_type(KSETMKBRK, keys);
		}
		break;

		/* get screen control flags */
	case SCRIOCGETF:
		{
		struct screen_control devflg;
		devflg.device = (*(struct screen_control *)data).device;
		if (devflg.device < 0 || devflg.device > CONS_DUMMY)
			SPLRETURN(EINVAL);
		devflg.switches = screen_sw[devflg.device].flags;
		(*(struct screen_control *)data).switches = devflg.switches;
		break;
		}

		/* set screen control flags.
		 *	Allow modification of the kernel and user flags only.
		 *  Other flags are modified as a result.
		 */
	case SCRIOCSETC:
		{
		struct screen_control devflg;
		devflg.device = (*(struct screen_control *)data).device;
		devflg.switches = (*(struct screen_control *)data).switches;
		if (devflg.device < 0 || devflg.device > CONS_DUMMY)
			SPLRETURN(EINVAL);

		if (!(screen_sw[devflg.device].flags & CONSDEV_PRESENT))
			SPLRETURN(ENODEV); /* service present devices only */

			/* clear the kernel/user flags and set them as passed */
		screen_sw[devflg.device].flags &= ~CONSDEV_USRCHG;
		screen_sw[devflg.device].flags |= (devflg.switches & CONSDEV_USRCHG);
		/* now clear the INIT flag if kernel is off */
		if (!(screen_sw[devflg.device].flags & CONSDEV_KERNEL))
			screen_sw[devflg.device].flags &= ~CONSDEV_INIT;
		/* now set the INIT flag if kernel is on */
		if (screen_sw[devflg.device].flags & CONSDEV_KERNEL)
			screen_sw[devflg.device].flags |= CONSDEV_INIT;

		break;
		}
	case SCRSETNINP:
		screen_sw[WS].flags |= CONSDEV_NOINPUT;
		break;
		
	case SCRCLRNINP:
		screen_sw[WS].flags &= ~CONSDEV_NOINPUT;
		break;

		/* get input emulator discipline number */
	case EIGETD:
		*(int *)data = si->ine.emulator;
		break;

		/* get output emulator discipline number */
	case EOGETD:
		if (WS == CONS_GEN)
			SPLRETURN(-1);
		*(int *)data = si->oute.emulator;
		break;

		/* set input emulator line discipline */
	case EISETD:
		if ((save=set_emul (dev, tp, (int *)data, si, &si->ine)) == 0)
			if ((cons_if == CONS_GEN) && (screen_sw[WS].flags & CONSDEV_GRA))
				cons_if = cons_display;
		SPLRETURN (save);
/*		break;	*/

		/* set output emulator line discipline */
	case EOSETD:
		if (WS == CONS_GEN)
			SPLRETURN(-1);
		SPLRETURN (set_emul (dev, tp, (int *)data, si, &si->oute));
/*		break;	*/
	/*
	 * Return display info data (was a buf emul ioctl)
 	 */
	case CONSDISPINFO:
		*(unsigned *)data =
#ifdef ATR
		(BUF_CPU_ATR) |
		(BUF_PUT_PCCODE(config.os_type)) |
#endif ATR
#ifdef IBMRTPC
		(BUF_CPU_RTPC) |
#endif IBMRTPC
#if NIBMVBARMMMDXIV > 0
		(BUF_PUT_8514(ibm8514_get_type())) |
#endif 8514
#if NVGA > 0
		(BUF_PUT_VGA(vga_get_type())) |
#endif VGA
#if NEGA > 0
		(BUF_PUT_EGA(ega_screen_type)) |
#endif EGA
				0;
		return(0);
/*		break;	*/

#ifdef ATR
	case CON_ALTCPU_POR:
		if (suser())
			error = pc_req_alt(CB_POR, 0, 0, * (int *) data);
		else
			error = EPERM;
		break;
	case CON_ALTCPU_IPL:
		if (suser())
			error = pc_req_alt(CB_IPL, 0, 0, * (int *) data);
		else
			error = EPERM;
		break;
#endif ATR
	default:
		SPLRETURN (-1);
/*		break;	*/
	}
	SPLRETURN (error);
}

set_emul (dev, tp, data, si, ei)
dev_t dev;
register struct tty *tp;
register int *data;
register SCREEN_INFO *si;
register EMUL_INFO *ei;
{
	register int t;
	register int error = ENXIO;
	int s;

	t = *data;
	*data = ei->emulator;

	/* Illegal Emulator? */
	if ((unsigned) t >= NEMUL)
		return (ENXIO);

#ifdef ATR
	s = spl5();
#else
	s = spl1();
#endif ATR
	if ((ei->emulator != NO_ENTRY) && (ei->emulator != t))
		(*emulsw[ei->emulator].e_close)(tp, si);

	if (t >= 0)
		error = (*emulsw[t].e_open)(dev, tp, si);
	splx(s);

	if (error) {
#ifdef ATR
		s = spl5();
#else
	s = spl1();
#endif ATR
		if (ei->emulator != NO_ENTRY)
			(void) (*emulsw[ei->emulator].e_open)(dev, tp, si);
		splx(s);
		return (error);
	}
	ei->emulator = t;
	return (0);
}

sichars (scr_unit, emul_unit, si)
register int scr_unit;
register int emul_unit;
register SCREEN_INFO *si;
{
	si->ine.unit = si->oute.unit = 0;
	si->ine.rsel = si->oute.rsel = 0;
	si->ine.flag = si->oute.flag = 0;
	si->ine.intr_reason = si->oute.intr_reason = 0;

	/* Set this screen acorrding to minor device of console */
	WS = scr_unit;

	/* Set to emulators determined by symbolic minor device on console */
	switch (emul_unit) {
#ifdef OLDEMUL
	case CE_ANDREW:
		si->ine.emulator = E_STDINPUT;
		si->oute.emulator = E_XOUTPUT;
		break;
	case CE_MAC:
		si->ine.emulator = E_MACINPUT;
		si->oute.emulator = E_MACOUTPUT;
		break;
	case CE_X:
		si->ine.emulator = E_XINPUT;
		si->oute.emulator = E_XOUTPUT;
		break;
#endif OLDEMUL
	case CE_DEFAULT:
		si->ine.emulator = E_KBDINPUT;
		si->oute.emulator = screen_sw[WS].def_oute;
		break;
	default:
		si->ine.emulator = E_KBDINPUT;
		si->oute.emulator = E_BUFOUTPUT;
		break;
	}
	return (0);
}

noloc(d1,d2,si)
	register SCREEN_INFO *si;
{
	u.u_error = ENXIO;
	printf("console device %s doesn't support X10 locator function\n",screen_sw[WS].name);
}

#ifdef ATR
#ifdef SHOW_LOAD
/*
 * take the current load (as a scaled integer *10) and
 * convert to ascii and put on the display 
 */
display_load(a)
{
	register SCREEN_INFO *si = &cons_info[cons_display];
	char *cbuf = "LOAD: x.x ";

	cbuf[5] = (a >= 100) ? (a/100 + '0') : ' ';
	cbuf[6] = (a/10)%10 + '0';
	cbuf[8] = a%10 + '0';
	put_status(si,35,cbuf);
}
#endif SHOW_LOAD
#endif ATR
