diff options
Diffstat (limited to 'xorg-server/hw/kdrive/vesa')
-rw-r--r-- | xorg-server/hw/kdrive/vesa/Makefile.am | 33 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/Makefile.in | 717 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vbe.c | 706 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vbe.h | 165 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vesa.c | 1823 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vesa.h | 295 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vesainit.c | 92 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vga.c | 242 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vga.h | 59 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vm86.c | 764 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/vesa/vm86.h | 180 |
11 files changed, 5076 insertions, 0 deletions
diff --git a/xorg-server/hw/kdrive/vesa/Makefile.am b/xorg-server/hw/kdrive/vesa/Makefile.am new file mode 100644 index 000000000..4225dcfbc --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/Makefile.am @@ -0,0 +1,33 @@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +noinst_LIBRARIES = libvesa.a + +bin_PROGRAMS = Xvesa + +libvesa_a_SOURCES = \ + vesa.c \ + vesa.h \ + vbe.c \ + vbe.h \ + vga.c \ + vga.h \ + vm86.c \ + vm86.h + +Xvesa_SOURCES = \ + vesainit.c + +Xvesa_LDADD = \ + libvesa.a \ + @KDRIVE_LIBS@ + +Xvesa_DEPENDENCIES = \ + libvesa.a \ + @KDRIVE_LOCAL_LIBS@ + +Xvesa_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) + +relink: + rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS) diff --git a/xorg-server/hw/kdrive/vesa/Makefile.in b/xorg-server/hw/kdrive/vesa/Makefile.in new file mode 100644 index 000000000..0531ce07b --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/Makefile.in @@ -0,0 +1,717 @@ +# Makefile.in generated by automake 1.10.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = Xvesa$(EXEEXT) +subdir = hw/kdrive/vesa +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/do-not-use-config.h \ + $(top_builddir)/include/xorg-server.h \ + $(top_builddir)/include/dix-config.h \ + $(top_builddir)/include/xgl-config.h \ + $(top_builddir)/include/xorg-config.h \ + $(top_builddir)/include/xkb-config.h \ + $(top_builddir)/include/xwin-config.h \ + $(top_builddir)/include/kdrive-config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) +ARFLAGS = cru +libvesa_a_AR = $(AR) $(ARFLAGS) +libvesa_a_LIBADD = +am_libvesa_a_OBJECTS = vesa.$(OBJEXT) vbe.$(OBJEXT) vga.$(OBJEXT) \ + vm86.$(OBJEXT) +libvesa_a_OBJECTS = $(am_libvesa_a_OBJECTS) +am__installdirs = "$(DESTDIR)$(bindir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_Xvesa_OBJECTS = vesainit.$(OBJEXT) +Xvesa_OBJECTS = $(am_Xvesa_OBJECTS) +Xvesa_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(Xvesa_LDFLAGS) \ + $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libvesa_a_SOURCES) $(Xvesa_SOURCES) +DIST_SOURCES = $(libvesa_a_SOURCES) $(Xvesa_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ADMIN_MAN_DIR = @ADMIN_MAN_DIR@ +ADMIN_MAN_SUFFIX = @ADMIN_MAN_SUFFIX@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +APPDEFAULTDIR = @APPDEFAULTDIR@ +APPLE_APPLICATIONS_DIR = @APPLE_APPLICATIONS_DIR@ +APP_MAN_DIR = @APP_MAN_DIR@ +APP_MAN_SUFFIX = @APP_MAN_SUFFIX@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASE_FONT_PATH = @BASE_FONT_PATH@ +BUILD_DATE = @BUILD_DATE@ +BUILD_TIME = @BUILD_TIME@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DARWIN_LIBS = @DARWIN_LIBS@ +DBUS_CFLAGS = @DBUS_CFLAGS@ +DBUS_LIBS = @DBUS_LIBS@ +DEFAULT_LIBRARY_PATH = @DEFAULT_LIBRARY_PATH@ +DEFAULT_LOGPREFIX = @DEFAULT_LOGPREFIX@ +DEFAULT_MODULE_PATH = @DEFAULT_MODULE_PATH@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DGA_CFLAGS = @DGA_CFLAGS@ +DGA_LIBS = @DGA_LIBS@ +DIX_CFLAGS = @DIX_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DMXEXAMPLES_DEP_CFLAGS = @DMXEXAMPLES_DEP_CFLAGS@ +DMXEXAMPLES_DEP_LIBS = @DMXEXAMPLES_DEP_LIBS@ +DMXMODULES_CFLAGS = @DMXMODULES_CFLAGS@ +DMXMODULES_LIBS = @DMXMODULES_LIBS@ +DMXXIEXAMPLES_DEP_CFLAGS = @DMXXIEXAMPLES_DEP_CFLAGS@ +DMXXIEXAMPLES_DEP_LIBS = @DMXXIEXAMPLES_DEP_LIBS@ +DMXXMUEXAMPLES_DEP_CFLAGS = @DMXXMUEXAMPLES_DEP_CFLAGS@ +DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@ +DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ +DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ +DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@ +DRIPROTO_LIBS = @DRIPROTO_LIBS@ +DRIVER_MAN_DIR = @DRIVER_MAN_DIR@ +DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ +DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ +DSYMUTIL = @DSYMUTIL@ +DTRACE = @DTRACE@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FFLAGS = @FFLAGS@ +FILE_MAN_DIR = @FILE_MAN_DIR@ +FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ +FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ +FREETYPE_LIBS = @FREETYPE_LIBS@ +GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@ +GLX_DEFINES = @GLX_DEFINES@ +GL_CFLAGS = @GL_CFLAGS@ +GL_LIBS = @GL_LIBS@ +GREP = @GREP@ +HAL_CFLAGS = @HAL_CFLAGS@ +HAL_LIBS = @HAL_LIBS@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +KDRIVE_CFLAGS = @KDRIVE_CFLAGS@ +KDRIVE_INCS = @KDRIVE_INCS@ +KDRIVE_LIBS = @KDRIVE_LIBS@ +KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ +KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ +KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ +LAUNCHD = @LAUNCHD@ +LDFLAGS = @LDFLAGS@ +LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ +LIBDRM_LIBS = @LIBDRM_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIB_MAN_DIR = @LIB_MAN_DIR@ +LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ +LINUXDOC = @LINUXDOC@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MAKE_HTML = @MAKE_HTML@ +MAKE_PDF = @MAKE_PDF@ +MAKE_PS = @MAKE_PS@ +MAKE_TEXT = @MAKE_TEXT@ +MESA_SOURCE = @MESA_SOURCE@ +MISC_MAN_DIR = @MISC_MAN_DIR@ +MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ +MKDIR_P = @MKDIR_P@ +MKFONTDIR = @MKFONTDIR@ +MKFONTSCALE = @MKFONTSCALE@ +NMEDIT = @NMEDIT@ +OBJC = @OBJC@ +OBJCCLD = @OBJCCLD@ +OBJCDEPMODE = @OBJCDEPMODE@ +OBJCFLAGS = @OBJCFLAGS@ +OBJCLINK = @OBJCLINK@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ +OPENSSL_LIBS = @OPENSSL_LIBS@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCIACCESS_CFLAGS = @PCIACCESS_CFLAGS@ +PCIACCESS_LIBS = @PCIACCESS_LIBS@ +PCI_TXT_IDS_PATH = @PCI_TXT_IDS_PATH@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PROJECTROOT = @PROJECTROOT@ +PS2PDF = @PS2PDF@ +RANLIB = @RANLIB@ +RAWCPP = @RAWCPP@ +RAWCPPFLAGS = @RAWCPPFLAGS@ +SED = @SED@ +SERVER_MISC_CONFIG_PATH = @SERVER_MISC_CONFIG_PATH@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOLARIS_ASM_CFLAGS = @SOLARIS_ASM_CFLAGS@ +SOLARIS_INOUT_ARCH = @SOLARIS_INOUT_ARCH@ +STRIP = @STRIP@ +TSLIB_CFLAGS = @TSLIB_CFLAGS@ +TSLIB_LIBS = @TSLIB_LIBS@ +UTILS_SYS_LIBS = @UTILS_SYS_LIBS@ +VENDOR_MAN_VERSION = @VENDOR_MAN_VERSION@ +VENDOR_NAME = @VENDOR_NAME@ +VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ +VENDOR_RELEASE = @VENDOR_RELEASE@ +VERSION = @VERSION@ +X11APP_ARCHS = @X11APP_ARCHS@ +X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ +X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XDMCP_CFLAGS = @XDMCP_CFLAGS@ +XDMCP_LIBS = @XDMCP_LIBS@ +XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ +XDMXCONFIG_DEP_LIBS = @XDMXCONFIG_DEP_LIBS@ +XDMX_CFLAGS = @XDMX_CFLAGS@ +XDMX_LIBS = @XDMX_LIBS@ +XDMX_SYS_LIBS = @XDMX_SYS_LIBS@ +XEGLMODULES_CFLAGS = @XEGLMODULES_CFLAGS@ +XEGL_LIBS = @XEGL_LIBS@ +XEGL_SYS_LIBS = @XEGL_SYS_LIBS@ +XEPHYR_CFLAGS = @XEPHYR_CFLAGS@ +XEPHYR_DRI_LIBS = @XEPHYR_DRI_LIBS@ +XEPHYR_INCS = @XEPHYR_INCS@ +XEPHYR_LIBS = @XEPHYR_LIBS@ +XF86CONFIGFILE = @XF86CONFIGFILE@ +XF86MISC_CFLAGS = @XF86MISC_CFLAGS@ +XF86MISC_LIBS = @XF86MISC_LIBS@ +XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ +XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ +XGLMODULES_CFLAGS = @XGLMODULES_CFLAGS@ +XGLMODULES_LIBS = @XGLMODULES_LIBS@ +XGLXMODULES_CFLAGS = @XGLXMODULES_CFLAGS@ +XGLXMODULES_LIBS = @XGLXMODULES_LIBS@ +XGLX_LIBS = @XGLX_LIBS@ +XGLX_SYS_LIBS = @XGLX_SYS_LIBS@ +XGL_LIBS = @XGL_LIBS@ +XGL_MODULE_PATH = @XGL_MODULE_PATH@ +XGL_SYS_LIBS = @XGL_SYS_LIBS@ +XKB_BASE_DIRECTORY = @XKB_BASE_DIRECTORY@ +XKB_BIN_DIRECTORY = @XKB_BIN_DIRECTORY@ +XKB_COMPILED_DIR = @XKB_COMPILED_DIR@ +XKM_OUTPUT_DIR = @XKM_OUTPUT_DIR@ +XLIB_CFLAGS = @XLIB_CFLAGS@ +XLIB_LIBS = @XLIB_LIBS@ +XNESTMODULES_CFLAGS = @XNESTMODULES_CFLAGS@ +XNESTMODULES_LIBS = @XNESTMODULES_LIBS@ +XNEST_LIBS = @XNEST_LIBS@ +XNEST_SYS_LIBS = @XNEST_SYS_LIBS@ +XORGCFG_DEP_CFLAGS = @XORGCFG_DEP_CFLAGS@ +XORGCFG_DEP_LIBS = @XORGCFG_DEP_LIBS@ +XORGCONFIG_DEP_CFLAGS = @XORGCONFIG_DEP_CFLAGS@ +XORGCONFIG_DEP_LIBS = @XORGCONFIG_DEP_LIBS@ +XORG_CFLAGS = @XORG_CFLAGS@ +XORG_INCS = @XORG_INCS@ +XORG_LIBS = @XORG_LIBS@ +XORG_MODULES_CFLAGS = @XORG_MODULES_CFLAGS@ +XORG_MODULES_LIBS = @XORG_MODULES_LIBS@ +XORG_OS = @XORG_OS@ +XORG_OS_SUBDIR = @XORG_OS_SUBDIR@ +XORG_SYS_LIBS = @XORG_SYS_LIBS@ +XPRINTMODULES_CFLAGS = @XPRINTMODULES_CFLAGS@ +XPRINTMODULES_LIBS = @XPRINTMODULES_LIBS@ +XPRINTPROTO_CFLAGS = @XPRINTPROTO_CFLAGS@ +XPRINTPROTO_LIBS = @XPRINTPROTO_LIBS@ +XPRINT_CFLAGS = @XPRINT_CFLAGS@ +XPRINT_LIBS = @XPRINT_LIBS@ +XPRINT_SYS_LIBS = @XPRINT_SYS_LIBS@ +XRESEXAMPLES_DEP_CFLAGS = @XRESEXAMPLES_DEP_CFLAGS@ +XRESEXAMPLES_DEP_LIBS = @XRESEXAMPLES_DEP_LIBS@ +XSDL_INCS = @XSDL_INCS@ +XSDL_LIBS = @XSDL_LIBS@ +XSERVERCFLAGS_CFLAGS = @XSERVERCFLAGS_CFLAGS@ +XSERVERCFLAGS_LIBS = @XSERVERCFLAGS_LIBS@ +XSERVERLIBS_CFLAGS = @XSERVERLIBS_CFLAGS@ +XSERVERLIBS_LIBS = @XSERVERLIBS_LIBS@ +XSERVER_LIBS = @XSERVER_LIBS@ +XSERVER_SYS_LIBS = @XSERVER_SYS_LIBS@ +XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ +XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ +XVFB_LIBS = @XVFB_LIBS@ +XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ +XWINMODULES_LIBS = @XWINMODULES_LIBS@ +XWIN_LIBS = @XWIN_LIBS@ +XWIN_SERVER_NAME = @XWIN_SERVER_NAME@ +XWIN_SYS_LIBS = @XWIN_SYS_LIBS@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +__XCONFIGFILE__ = @__XCONFIGFILE__@ +abi_ansic = @abi_ansic@ +abi_extension = @abi_extension@ +abi_font = @abi_font@ +abi_videodrv = @abi_videodrv@ +abi_xinput = @abi_xinput@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +driverdir = @driverdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +extdir = @extdir@ +ft_config = @ft_config@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +launchagentsdir = @launchagentsdir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +logdir = @logdir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +moduledir = @moduledir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sdkdir = @sdkdir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +xglmoduledir = @xglmoduledir@ +xpconfigdir = @xpconfigdir@ +INCLUDES = \ + @KDRIVE_INCS@ \ + @KDRIVE_CFLAGS@ + +noinst_LIBRARIES = libvesa.a +libvesa_a_SOURCES = \ + vesa.c \ + vesa.h \ + vbe.c \ + vbe.h \ + vga.c \ + vga.h \ + vm86.c \ + vm86.h + +Xvesa_SOURCES = \ + vesainit.c + +Xvesa_LDADD = \ + libvesa.a \ + @KDRIVE_LIBS@ + +Xvesa_DEPENDENCIES = \ + libvesa.a \ + @KDRIVE_LOCAL_LIBS@ + +Xvesa_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign hw/kdrive/vesa/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --foreign hw/kdrive/vesa/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) +libvesa.a: $(libvesa_a_OBJECTS) $(libvesa_a_DEPENDENCIES) + -rm -f libvesa.a + $(libvesa_a_AR) libvesa.a $(libvesa_a_OBJECTS) $(libvesa_a_LIBADD) + $(RANLIB) libvesa.a +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +Xvesa$(EXEEXT): $(Xvesa_OBJECTS) $(Xvesa_DEPENDENCIES) + @rm -f Xvesa$(EXEEXT) + $(Xvesa_LINK) $(Xvesa_OBJECTS) $(Xvesa_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vbe.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vesa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vesainit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vga.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vm86.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LIBRARIES) $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool \ + clean-noinstLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool clean-noinstLIBRARIES ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-binPROGRAMS + + +relink: + rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS) +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/xorg-server/hw/kdrive/vesa/vbe.c b/xorg-server/hw/kdrive/vesa/vbe.c new file mode 100644 index 000000000..cedefe9fc --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vbe.c @@ -0,0 +1,706 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vesa.h" + +int +VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib) +{ + int code; + int mark; + int vib_base; + VbeInfoBlock *vib_low; + + mark = Vm86MarkMemory (vi); + vib_base = Vm86AllocateMemory (vi, sizeof (VbeInfoBlock)); + vib_low = (VbeInfoBlock*)&(LM(vi, vib_base)); + vi->vms.regs.eax = 0x4F00; + vi->vms.regs.es = POINTER_SEGMENT(vib_base); + vi->vms.regs.edi = POINTER_OFFSET(vib_base); + memcpy(vib_low->VbeSignature, "VBE2", 4); + code = VbeDoInterrupt10(vi); + if(code >= 0) + { + if(memcmp(vib_low->VbeSignature, "VESA", 4) == 0) + *vib = *vib_low; + else + code = -1; + } + Vm86ReleaseMemory (vi, mark); + return code; +} + +int +VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib) +{ + int code; + int mark; + int vmib_base; + VbeModeInfoBlock *vmib_low; + + mark = Vm86MarkMemory (vi); + + vmib_base = Vm86AllocateMemory (vi, sizeof (VbeModeInfoBlock)); + vmib_low = (VbeModeInfoBlock*)&(LM(vi, vmib_base)); + + vi->vms.regs.eax = 0x4F01; + vi->vms.regs.ecx = mode&0xFFFF; + vi->vms.regs.es = POINTER_SEGMENT(vmib_base); + vi->vms.regs.edi = POINTER_OFFSET(vmib_base); + code = VbeDoInterrupt10(vi); + + if(code >= 0) + *vmib = *vmib_low; + Vm86ReleaseMemory (vi, mark); + return code; +} + +static int +VbeReportVib(Vm86InfoPtr vi, VbeInfoBlock *vib) +{ + U32 i, p; + unsigned char c; + int error = 0; + + ErrorF("VBE version %c.%c (", + ((vib->VbeVersion >> 8) & 0xFF) + '0', + (vib->VbeVersion & 0xFF)+'0'); + p = vib->OemStringPtr; + for(i = 0; 1; i++) { + c = Vm86Memory(vi, MAKE_POINTER_1(p+i)); + if(!c) break; + if (c >= ' ') + ErrorF("%c", c); + if (i > 32000) { + error = 1; + break; + } + } + ErrorF(")\n"); + ErrorF("DAC is %s, controller is %sVGA compatible%s\n", + (vib->Capabilities[0]&1)?"switchable":"fixed", + (vib->Capabilities[0]&2)?"not ":"", + (vib->Capabilities[0]&3)?", RAMDAC causes snow":""); + ErrorF("Total memory: %lu kilobytes\n", 64L*vib->TotalMemory); + if(error) + return -1; + return 0; +} + +#if 0 +static int +VbeReportModeInfo(Vm86InfoPtr vi, U16 mode, VbeModeInfoBlock *vmib) +{ + int supported = (vmib->ModeAttributes&0x1)?1:0; + int colour = (vmib->ModeAttributes&0x8)?1:0; + int graphics = (vmib->ModeAttributes&0x10)?1:0; + int vga_compatible = !((vmib->ModeAttributes&0x20)?1:0); + int linear_fb = (vmib->ModeAttributes&0x80)?1:0; + + ErrorF("0x%04X: %dx%dx%d%s", + (unsigned)mode, + (int)vmib->XResolution, (int)vmib->YResolution, + (int)vmib->BitsPerPixel, + colour?"":" (monochrome)", + graphics?"":" (graphics)", + vga_compatible?"":" (vga compatible)", + linear_fb?"":" (linear frame buffer)"); + switch(vmib->MemoryModel) { + case 0: + ErrorF(" text mode (%dx%d)", + (int)vmib->XCharSize, (int)vmib->YCharSize); + break; + case 1: + ErrorF(" CGA graphics"); + break; + case 2: + ErrorF(" Hercules graphics"); + break; + case 3: + ErrorF(" Planar (%d planes)", vmib->NumberOfPlanes); + break; + case 4: + ErrorF(" PseudoColor"); + break; + case 5: + ErrorF(" Non-chain 4, 256 colour"); + break; + case 6: + if(vmib->DirectColorModeInfo & 1) + ErrorF(" DirectColor"); + else + ErrorF(" TrueColor"); + ErrorF(" [%d:%d:%d:%d]", + vmib->RedMaskSize, vmib->GreenMaskSize, vmib->BlueMaskSize, + vmib->RsvdMaskSize); + if(vmib->DirectColorModeInfo & 2) + ErrorF(" (reserved bits are reserved)"); + break; + case 7: ErrorF("YUV"); + break; + default: + ErrorF("unknown MemoryModel 0x%X ", vmib->MemoryModel); + } + if(!supported) + ErrorF(" (unsupported)"); + else if(!linear_fb) + ErrorF(" (no linear framebuffer)"); + ErrorF("\n"); + return 0; +} +#endif + +void +VbeReportInfo (Vm86InfoPtr vi) +{ + VbeInfoBlock vib; + int code; + + code = VbeGetVib (vi, &vib); + if (code >= 0) + VbeReportVib(vi, &vib); +} + +int +VbeGetNmode (Vm86InfoPtr vi) +{ + VbeInfoBlock vib; + int code; + unsigned int p; + int n; + int mode; + + code = VbeGetVib (vi, &vib); + if (code >= 0) + { + p = MAKE_POINTER_1(vib.VideoModePtr); + for (n = 0; ; n++) + { + mode = Vm86MemoryW(vi, p); + if (mode == 0xffff) + break; + p += 2; + } + code = n; + } + return code; +} + +int +VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode) +{ + VbeInfoBlock vib; + int code; + unsigned int p; + int n; + int mode; + VbeModeInfoBlock vmib; + + code = VbeGetVib (vi, &vib); + if (code < 0) + return code; + + memset (modes, '\0', nmode * sizeof (VesaModeRec)); + + p = MAKE_POINTER_1(vib.VideoModePtr); + for (n = 0; n < nmode; n++) + { + mode = Vm86MemoryW(vi, p); + if (mode == 0xffff) + break; + modes[n].mode = mode; + modes[n].vbe = 1; + p += 2; + } + + nmode = n; + + for (n = 0; n < nmode; n++) + { + code = VbeGetVmib (vi, modes[n].mode, &vmib); + if (code >= 0) + { + modes[n].ModeAttributes = vmib.ModeAttributes; + modes[n].NumberOfPlanes = vmib.NumberOfPlanes; + modes[n].BitsPerPixel = vmib.BitsPerPixel; + modes[n].MemoryModel = vmib.MemoryModel; + modes[n].RedMaskSize = vmib.RedMaskSize; + modes[n].RedFieldPosition = vmib.RedFieldPosition; + modes[n].GreenMaskSize = vmib.GreenMaskSize; + modes[n].GreenFieldPosition = vmib.GreenFieldPosition; + modes[n].BlueMaskSize = vmib.BlueMaskSize; + modes[n].BlueFieldPosition = vmib.BlueFieldPosition; + modes[n].RsvdMaskSize = vmib.RsvdMaskSize; + modes[n].RsvdFieldPosition = vmib.RsvdFieldPosition; + modes[n].DirectColorModeInfo = vmib.DirectColorModeInfo; + modes[n].XResolution = vmib.XResolution; + modes[n].YResolution = vmib.YResolution; + modes[n].BytesPerScanLine = vmib.BytesPerScanLine; + } + } + + return nmode; +} + +VbeInfoPtr +VbeInit (Vm86InfoPtr vi) +{ + VbeInfoPtr vbe; + int code; + VbeInfoBlock vib; + + code = VbeGetVib (vi, &vib); + if (code < 0) + return 0; + + vbe = xalloc (sizeof (VbeInfoRec)); + if (!vbe) + return 0; + vbe->palette_format = 6; + vbe->palette_wait = TRUE; + return vbe; +} + +void +VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe) +{ + xfree (vbe); +} + +int +VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct) +{ + int code; + VbeInfoBlock vib; + int palette_wait = 0, palette_hi = 0; + + code = VbeGetVib (vi, &vib); + if (code < 0) + return -1; + + code = VbeGetVmib (vi, mode, &vbe->vmib); + if (code < 0) + return -1; + + mode = (mode & 0xffff) &~ 0x8000; + if (linear) + mode |= 0x4000; + + vi->vms.regs.eax = 0x4F02; + vi->vms.regs.ebx = mode; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + + vbe->windowA_offset = vbe->windowB_offset = -1; + vbe->last_window = 1; + + if (!direct) + { + if(vib.Capabilities[0] & 1) + palette_hi = 1; + if(vib.Capabilities[0] & 4) + palette_wait = 1; + + if(palette_hi || palette_wait) + VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait); + } + + return 0; +} + +int +VbeGetMode(Vm86InfoPtr vi, int *mode) +{ + int code; + + vi->vms.regs.eax = 0x4F03; + code = VbeDoInterrupt10(vi); + if(code < 0) + return - 1; + *mode = vi->vms.regs.ebx & 0xFFFF; + return 0; +} + +void * +VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys) +{ + U8 *fb; + VbeInfoBlock vib; + VbeModeInfoBlock vmib; + int size; + int pagesize = getpagesize(); + int before, after; + + if (VbeGetVib (vi, &vib) < 0) + return 0; + + if (VbeGetVmib (vi, mode, &vmib) < 0) + return 0; + + size = 1024 * 64L * vib.TotalMemory; + + *ret_size = size; + *ret_phys = vmib.PhysBasePtr; + + before = vmib.PhysBasePtr % pagesize; + after = pagesize - ((vmib.PhysBasePtr + size) % pagesize); + if(after == pagesize) + after = 0; + + fb = KdMapDevice (vmib.PhysBasePtr - before, before + size + after); + + if(fb == 0) + { + ErrorF("Failed to map framebuffer\n"); + return NULL; + } + + KdSetMappedMode (vmib.PhysBasePtr - before, before + size + after, + KD_MAPPED_MODE_FRAMEBUFFER); + + return fb + before; +} + +void +VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb) +{ + VbeInfoBlock vib; + VbeModeInfoBlock vmib; + int size; + int pagesize = getpagesize(); + int before, after; + + if (VbeGetVib (vi, &vib) < 0) + return; + + if (VbeGetVmib (vi, mode, &vmib) < 0) + return; + + size = 1024 * 64L * vib.TotalMemory; + + before = vmib.PhysBasePtr % pagesize; + after = pagesize - ((vmib.PhysBasePtr + size) % pagesize); + if(after == pagesize) + after = 0; + + fb = (void *) ((char *) fb - before); + + KdUnmapDevice (fb, before + size + after); + KdResetMappedMode (vmib.PhysBasePtr - before, before + size + after, + KD_MAPPED_MODE_FRAMEBUFFER); +} + +int +VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int mark; + int palette_base; + int i, code; + + if(number == 0) + return 0; + + if(first < 0 || number < 0 || first + number > 256) { + ErrorF("Cannot set %d, %d palette entries\n", first, number); + return -1; + } + if(vbe->palette_format < 6 || vbe->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vbe->palette_format); + return -1; + } + + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 4 * 256); + + palette_scratch = &LM(vi, palette_base); + + for(i=0; i<number*4; i++) + palette_scratch[i] = entries[i] >> (8 - vbe->palette_format); + + vi->vms.regs.eax = 0x4F09; + if(vbe->palette_wait) + vi->vms.regs.ebx = 0x80; + else + vi->vms.regs.ebx = 0x00; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edi = POINTER_OFFSET(palette_base); + code = VbeDoInterrupt10(vi); + Vm86ReleaseMemory (vi, mark); + + if(code < 0) + return -1; + return 0; +} + +int +VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int mark; + int palette_base; + int i, code; + + if(number == 0) + return 0; + + if(first < 0 || number < 0 || first + number > 256) { + ErrorF("Cannot get %d, %d palette entries\n", first, number); + return -1; + } + if(vbe->palette_format < 6 || vbe->palette_format > 8) { + ErrorF("Impossible palette format %d\n", vbe->palette_format); + return -1; + } + + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 4 * 256); + + palette_scratch = &LM(vi, palette_base); + + vi->vms.regs.eax = 0x4F09; + vi->vms.regs.ebx = 0x01; + vi->vms.regs.ecx = number; + vi->vms.regs.edx = first; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edi = POINTER_OFFSET(palette_base); + code = VbeDoInterrupt10(vi); + if(code >= 0) + { + for(i=0; i<number*4; i++) + entries[i] = palette_scratch[i] << (8-vbe->palette_format); + } + Vm86ReleaseMemory (vi, mark); + + return 0; +} + +int +VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait) +{ + int code; + + if(bits < 6 || bits > 8) { + ErrorF("Impossible palette format %d\n", bits); + return -1; + } + if(bits != vbe->palette_format) + { + vbe->palette_format = 0; + vi->vms.regs.eax = 0x4F08; + vi->vms.regs.ebx = bits << 8; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + vbe->palette_format = bits; + } + vbe->palette_wait = wait; + return 0; +} + +static int +VbeReallySetWindow(Vm86InfoPtr vi, U8 window, U16 winnum) +{ + int code; + vi->vms.regs.eax = 0x4F05; + vi->vms.regs.ebx = window; + vi->vms.regs.edx = winnum; + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + return 0; +} + +void * +VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return) +{ + int window_size = vbe->vmib.WinSize * 1024; + int code; + int winnum; + + if(vbe->windowA_offset >= 0) + if(vbe->windowA_offset <= offset && vbe->windowA_offset + window_size > offset) + if(vbe->vmib.WinAAttributes & purpose) + goto windowA; + + if(vbe->windowB_offset >= 0) + if(vbe->windowB_offset <= offset && vbe->windowB_offset + window_size > offset) + if(vbe->vmib.WinBAttributes & purpose) + goto windowB; + + if(!(vbe->vmib.WinBAttributes & purpose) || + !(vbe->vmib.WinBAttributes & VBE_WINDOW_RELOCATE)) + goto set_windowA; + + if(!(vbe->vmib.WinAAttributes & purpose) || + !(vbe->vmib.WinAAttributes & VBE_WINDOW_RELOCATE)) + goto set_windowB; + + if(vbe->last_window) + goto set_windowA; + else + goto set_windowB; + +set_windowA: + winnum = offset / (vbe->vmib.WinGranularity * 1024); + code = VbeReallySetWindow(vi, 0, winnum); + if(code < 0) { + ErrorF("Couldn't set window A to %d*%d\n", + (int)winnum, (int)vbe->vmib.WinGranularity); + return NULL; + } + vbe->windowA_offset = winnum * vbe->vmib.WinGranularity * 1024; +windowA: + vbe->last_window = 0; + *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowA_offset); + return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinASegment, 0)))) + offset - vbe->windowA_offset; + +set_windowB: + winnum = offset / (vbe->vmib.WinGranularity * 1024); + code = VbeReallySetWindow(vi, 1, winnum); + if(code < 0) { + ErrorF("Couldn't set window B to %d*%d\n", + (int)winnum, (int)vbe->vmib.WinGranularity); + return NULL; + } + vbe->windowB_offset = winnum * vbe->vmib.WinGranularity * 1024; +windowB: + vbe->last_window = 1; + *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowB_offset); + return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinBSegment, 0)))) + offset - vbe->windowB_offset; +} + +static const int VbeDPMSModes[4] = { + 0x00, /* KD_DPMS_NORMAL */ + 0x01, /* KD_DPMS_STANDBY */ + 0x02, /* KD_DPMS_SUSPEND */ + 0x04, /* KD_DPMS_POWERDOWN */ +}; + +Bool +VbeDPMS(Vm86InfoPtr vi, int mode) +{ + int code; + + /* + * Check which modes are supported + */ + vi->vms.regs.eax = 0x4f10; + vi->vms.regs.ebx = 0x0000; + vi->vms.regs.es = 0; + vi->vms.regs.edi = 0; + code = VbeDoInterrupt10 (vi); + if (code < 0) + { + ErrorF ("No DPMS Support %d\n", code); + return FALSE; + } + /* Skip this stage if it's not supported */ + if (((vi->vms.regs.ebx >> 4) & VbeDPMSModes[mode]) != VbeDPMSModes[mode]) + return FALSE; + + /* Select this mode */ + vi->vms.regs.eax = 0x4f10; + vi->vms.regs.ebx = (VbeDPMSModes[mode] << 8) | 0x01; + code = VbeDoInterrupt10 (vi); + if (code < 0) + { + ErrorF ("DPMS failed %d\n", code); + return FALSE; + } + + return TRUE; +} + +Bool +VbeBoot(Vm86InfoPtr vi) +{ + int code; + int bus = 1; + int device = 0; + int function = 0; + + vi->vms.regs.eax = (bus << 8) | (device << 3) | (function & 0x7); + code = VbeDoInterruptE6 (vi); + ErrorF ("Boot: %d\n", code); + return TRUE; +} + +int +VbeDoInterrupt10(Vm86InfoPtr vi) +{ + int code; + int oldax; + + oldax = vi->vms.regs.eax & 0xFFFF; + + code = Vm86DoInterrupt(vi, 0x10); + if(code < 0) + return -1; + + if((vi->vms.regs.eax & 0xFFFF) != 0x4F && (oldax & 0xFF00) == 0x4F00) { + ErrorF("Int 10h (0x%04X) failed: 0x%04X", + oldax, vi->vms.regs.eax & 0xFFFF); + if((oldax & 0xFF00) == 0x4F00) { + switch((vi->vms.regs.eax & 0xFF00)>>8) { + case 0: + ErrorF(" (success)\n"); + return 0; + case 1: + ErrorF(" (function call failed)\n"); + break; + case 2: + ErrorF(" (function not supported on this hardware)\n"); + break; + case 3: + ErrorF(" (function call invalid in this video mode)\n"); + break; + default: + ErrorF(" (unknown error)\n"); + break; + } return -1; + } else { + ErrorF("\n"); + } + } + return code; +} + +int +VbeDoInterruptE6(Vm86InfoPtr vi) +{ + int code; + int oldax; + + oldax = vi->vms.regs.eax & 0xffff; + + code = Vm86DoPOST (vi); + ErrorF("POST (0x%04X): 0x%04X\n", + oldax, vi->vms.regs.eax & 0xffff); + return code; +} diff --git a/xorg-server/hw/kdrive/vesa/vbe.h b/xorg-server/hw/kdrive/vesa/vbe.h new file mode 100644 index 000000000..f67fbbe42 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vbe.h @@ -0,0 +1,165 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef _VBE_H +#define _VBE_H + +#define VBE_WINDOW_RELOCATE 1 +#define VBE_WINDOW_READ 2 +#define VBE_WINDOW_WRITE 4 + +typedef struct _VbeInfoBlock { + U8 VbeSignature[4]; /* VBE Signature */ + U16 VbeVersion; /* VBE Version */ + U32 OemStringPtr; /* Pointer to OEM String */ + U8 Capabilities[4]; /* Capabilities of graphics controller */ + U32 VideoModePtr; /* Pointer to VideoModeList */ + U16 TotalMemory; /* Number of 64kb memory blocks */ +/* Added for VBE 2.0 */ + U16 OemSoftwareRev; /* VBE implementation Software revision */ + U32 OemVendorNamePtr; /* Pointer to Vendor Name String */ + U32 OemProductNamePtr; /* Pointer to Product Name String */ + U32 OemProductRevPtr; /* Pointer to Product Revision String */ + U8 Reserved[222]; /* Reserved for VBE implementation */ + U8 OemData[256]; /* Data Area for OEM Strings*/ +} __attribute__((packed)) VbeInfoBlock; + +typedef struct _VbeModeInfoBlock { +/* Mandatory information for all VBE revisions */ + U16 ModeAttributes; /* mode attributes */ + U8 WinAAttributes; /* window A attributes */ + U8 WinBAttributes; /* window B attributes */ + U16 WinGranularity; /* window granularity */ + U16 WinSize; /* window size */ + U16 WinASegment; /* window A start segment */ + U16 WinBSegment; /* window B start segment */ + U32 WinFuncPtr; /* pointer to window function */ + U16 BytesPerScanLine; /* bytes per scan line */ +/* Mandatory information for VBE 1.2 and above */ + U16 XResolution; /* horizontal resolution */ + U16 YResolution; /* vertical resolution */ + U8 XCharSize; /* character cell width in pixels */ + U8 YCharSize; /* character cell height in pixels */ + U8 NumberOfPlanes; /* number of memory planes */ + U8 BitsPerPixel; /* bits per pixel */ + U8 NumberOfBanks; /* number of banks */ + U8 MemoryModel; /* memory model type */ + U8 BankSize; /* bank size in KB */ + U8 NumberOfImagePages; /* number of images */ + U8 Reserved; /* reserved for page function */ +/* Direct Color fields (required for direct/6 and YUV/7 memory models) */ + U8 RedMaskSize; /* size of direct color red mask in bits */ + U8 RedFieldPosition; /* bit position of lsb of red mask */ + U8 GreenMaskSize; /* size of direct color green mask in bits */ + U8 GreenFieldPosition; /* bit position of lsb of green mask */ + U8 BlueMaskSize; /* size of direct color blue mask in bits */ + U8 BlueFieldPosition; /* bit position of lsb of blue mask */ + U8 RsvdMaskSize; /* size of direct color reserved mask bits*/ + U8 RsvdFieldPosition; /* bit position of lsb of reserved mask */ + U8 DirectColorModeInfo; /* direct color mode attributes */ +/* Mandatory information for VBE 2.0 and above */ + U32 PhysBasePtr; /* physical address for flat memory fb */ + U32 OffScreenMemOffset; /* pointer to start of off screen memory */ + U16 OffScreenMemSize; /* amount of off screen memory in 1k units */ + U8 Reserved2[206]; /* remainder of ModeInfoBlock */ +} __attribute__((packed)) VbeModeInfoBlock; + +typedef struct _VbeInfoRec { + U8 palette_format; + int palette_wait; + int windowA_offset; + int windowB_offset; + int window_size; + int last_window; + VbeModeInfoBlock vmib; +} VbeInfoRec, *VbeInfoPtr; + +typedef struct _SupVbeInfoBlock { + U8 SupVbeSignature[7]; /* Supplemental VBE Signature */ + U16 SupVbeVersion; /* Supplemental VBE Version*/ + U8 SupVbeSubFunc[8]; /* Bitfield of supported subfunctions */ + U16 OemSoftwareRev; /* OEM Software revision */ + U32 OemVendorNamePtr; /* Pointer to Vendor Name String */ + U32 OemProductNamePtr; /* Pointer to Product Name String */ + U32 OemProductRevPtr; /* Pointer to Product Revision String */ + U32 OemStringPtr; /* Pointer to OEM String */ + U8 Reserved[221]; /* Reserved */ +} __attribute__((packed)) SupVbeInfoBlock; + +int +VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib); + +int +VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib); + +void +VbeReportInfo (Vm86InfoPtr vi); + +int +VbeGetNmode (Vm86InfoPtr vi); + +int +VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode); + +VbeInfoPtr +VbeInit (Vm86InfoPtr vi); + +void +VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe); + +int +VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct); + +int +VbeGetMode(Vm86InfoPtr vi, int *mode); + +void * +VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys); + +void +VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb); + +int +VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries); + +int +VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries); + +int +VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait); + +void * +VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return); + +Bool +VbeDPMS(Vm86InfoPtr vi, int mode); + +int +VbeDoInterrupt10(Vm86InfoPtr vi); + +Bool +VbeBoot(Vm86InfoPtr vi); + +int +VbeDoInterruptE6(Vm86InfoPtr vi); + +#endif diff --git a/xorg-server/hw/kdrive/vesa/vesa.c b/xorg-server/hw/kdrive/vesa/vesa.c new file mode 100644 index 000000000..d6fa5eb06 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vesa.c @@ -0,0 +1,1823 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vesa.h" +#include "vga.h" +#include "vbe.h" +#ifdef RANDR +#include <randrstr.h> +#endif + +int vesa_video_mode = 0; +Bool vesa_force_mode = FALSE; +Bool vesa_swap_rgb = FALSE; +Bool vesa_shadow = FALSE; +Bool vesa_linear_fb = TRUE; +Bool vesa_restore = FALSE; +Bool vesa_verbose = FALSE; +Bool vesa_force_text = FALSE; +Bool vesa_restore_font = TRUE; +Bool vesa_map_holes = TRUE; +Bool vesa_boot = FALSE; + +#define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver) + +#define vesaWidth(scr,vmib) ((vmib)->XResolution) +#define vesaHeight(scr,vmib) ((vmib)->YResolution) + +static Bool +vesaComputeFramebufferMapping (KdScreenInfo *screen); + +static Bool +vesaMapFramebuffer (KdScreenInfo *screen); + +static Bool +vesaModeSupportable (VesaModePtr mode, Bool complain) +{ + if((mode->ModeAttributes & 0x10) == 0) { + if(complain) + ErrorF("Text mode specified.\n"); + return FALSE; + } + if(mode->MemoryModel != 0x06 && mode->MemoryModel != 0x04 && mode->MemoryModel != 0x03) { + if(complain) + ErrorF("Unsupported memory model 0x%X\n", mode->MemoryModel); + return FALSE; + } + if((mode->ModeAttributes & 0x80) == 0) { + if ((mode->ModeAttributes & 0x40) != 0) { + if(complain) + ErrorF("Neither linear nor windowed framebuffer available in this mode\n"); + return FALSE; + } + } + if(!(mode->ModeAttributes & 1)) { + if(complain) + ErrorF("Mode not supported on this hardware\n"); + return FALSE; + } + return TRUE; +} + +static Bool +vesaModeSupported (VesaCardPrivPtr priv, VesaModePtr mode, Bool complain) +{ + if (!priv->vbeInfo && mode->vbe) { + if (complain) + ErrorF("VBE bios mode not usable.\n"); + return FALSE; + } + return vesaModeSupportable (mode, complain); +} + +void +vesaReportMode (VesaModePtr mode) +{ + int supported = (mode->ModeAttributes&MODE_SUPPORTED)?1:0; + int colour = (mode->ModeAttributes&MODE_COLOUR)?1:0; + int graphics = (mode->ModeAttributes&MODE_GRAPHICS)?1:0; + int vga_compatible = !((mode->ModeAttributes&MODE_VGA)?1:0); + int linear_fb = (mode->ModeAttributes&MODE_LINEAR)?1:0; + + ErrorF("0x%04X: %dx%dx%d%s%s", + (unsigned)mode->mode, + (int)mode->XResolution, (int)mode->YResolution, + vesaDepth (mode), + colour?"":" (monochrome)", + graphics?"":" (graphics)", + vga_compatible?"":" (vga compatible)", + linear_fb?"":" (linear frame buffer)"); + switch(mode->MemoryModel) { + case MEMORY_TEXT: + ErrorF(" text mode"); + break; + case MEMORY_CGA: + ErrorF(" CGA graphics"); + break; + case MEMORY_HERCULES: + ErrorF(" Hercules graphics"); + break; + case MEMORY_PLANAR: + ErrorF(" Planar (%d planes)", mode->NumberOfPlanes); + break; + case MEMORY_PSEUDO: + ErrorF(" PseudoColor"); + break; + case MEMORY_NONCHAIN: + ErrorF(" Non-chain 4, 256 colour"); + break; + case MEMORY_DIRECT: + if(mode->DirectColorModeInfo & MODE_DIRECT) + ErrorF(" DirectColor"); + else + ErrorF(" TrueColor"); + ErrorF(" [%d:%d:%d:%d]", + mode->RedMaskSize, mode->GreenMaskSize, mode->BlueMaskSize, + mode->RsvdMaskSize); + if(mode->DirectColorModeInfo & 2) + ErrorF(" (reserved bits are reserved)"); + break; + case MEMORY_YUV: + ErrorF("YUV"); + break; + default: + ErrorF("unknown MemoryModel 0x%X ", mode->MemoryModel); + } + if(!supported) + ErrorF(" (unsupported)"); + else if(!linear_fb) + ErrorF(" (no linear framebuffer)"); + ErrorF("\n"); +} + +VesaModePtr +vesaGetModes (Vm86InfoPtr vi, int *ret_nmode) +{ + VesaModePtr modes; + int nmode, nmodeVbe, nmodeVga; + int code; + + code = VgaGetNmode (vi); + if (code <= 0) + nmodeVga = 0; + else + nmodeVga = code; + + code = VbeGetNmode (vi); + if (code <= 0) + nmodeVbe = 0; + else + nmodeVbe = code; + + nmode = nmodeVga + nmodeVbe; + if (nmode <= 0) + return 0; + + modes = xalloc (nmode * sizeof (VesaModeRec)); + + memset (modes, '\0', nmode * sizeof (VesaModeRec)); + + if (nmodeVga) + { + code = VgaGetModes (vi, modes, nmodeVga); + if (code <= 0) + nmodeVga = 0; + else + nmodeVga = code; + } + + if (nmodeVbe) + { + code = VbeGetModes (vi, modes + nmodeVga, nmodeVbe); + if (code <= 0) + nmodeVbe = 0; + else + nmodeVbe = code; + } + + nmode = nmodeVga + nmodeVbe; + + if (nmode == 0) + { + xfree (modes); + modes = 0; + return 0; + } + *ret_nmode = nmode; + return modes; +} + +Bool +vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv) +{ + priv->vi = Vm86Setup(vesa_map_holes); + if(!priv->vi) + goto fail; + + if (vesa_boot) + VbeBoot (priv->vi); + + priv->modes = vesaGetModes (priv->vi, &priv->nmode); + + if (!priv->modes) + goto fail; + + priv->vbeInfo = VbeInit (priv->vi); + + card->driver = priv; + + return TRUE; + +fail: + if(priv->vi) + Vm86Cleanup(priv->vi); + return FALSE; +} + +void +vesaListModes (void) +{ + Vm86InfoPtr vi; + VesaModePtr modes; + int nmode; + int n; + + vi = Vm86Setup (vesa_map_holes); + if (!vi) + { + ErrorF ("Can't setup vm86\n"); + } + else + { + modes = vesaGetModes (vi, &nmode); + if (!modes) + { + ErrorF ("No modes available\n"); + } + else + { + VbeReportInfo (vi); + for (n = 0; n < nmode; n++) + { + if (vesa_force_mode || vesaModeSupportable (modes+n, 0)) + vesaReportMode (modes+n); + } + xfree (modes); + } + Vm86Cleanup (vi); + } +} + +void +vesaTestMode (void) +{ + Vm86InfoPtr vi; + VesaModePtr modes; + VesaModePtr mode; + VbeInfoPtr vbeInfo; + int nmode; + int n; + + vi = Vm86Setup (vesa_map_holes); + if (!vi) + { + ErrorF ("Can't setup vm86\n"); + return; + } + modes = vesaGetModes (vi, &nmode); + if (!modes) + { + ErrorF ("No modes available\n"); + return; + } + VbeReportInfo (vi); + vbeInfo = VbeInit (vi); + for (n = 0; n < nmode; n++) + { + if (modes[n].mode == vesa_video_mode) + break; + } + if (n == nmode) + { + ErrorF ("no mode specified\n"); + return; + } + mode = &modes[n]; + if (mode->vbe) + { + ErrorF ("Enable VBE mode 0x%x\n", mode->mode); + VbeSetMode(vi, vbeInfo, mode->mode, FALSE, FALSE); + } + else + { + ErrorF ("Enable BIOS mode 0x%x\n", mode->mode); + VgaSetMode (vi, mode->mode); + } + sleep (2); + ErrorF ("Restore BIOS mode 0x%x\n", 3); + VgaSetMode (vi, 3); + xfree (modes); + Vm86Cleanup (vi); +} + +Bool +vesaCardInit(KdCardInfo *card) +{ + VesaCardPrivPtr priv; + + priv = xalloc(sizeof(VesaCardPrivRec)); + if(!priv) + return FALSE; + + if (!vesaInitialize (card, priv)) + { + xfree(priv); + return FALSE; + } + + return TRUE; +} + +int +vesaDepth (VesaModePtr mode) +{ + if (mode->MemoryModel == MEMORY_DIRECT) + return (mode->RedMaskSize + + mode->GreenMaskSize + + mode->BlueMaskSize); + else + return mode->BitsPerPixel; +} + +Bool +vesaModeGood (KdScreenInfo *screen, + VesaModePtr a) +{ + if (vesaWidth(screen,a) <= screen->width && + vesaHeight(screen,a) <= screen->height && + vesaDepth (a) >= screen->fb[0].depth) + { + return TRUE; + } + return FALSE; +} + +#define vabs(a) ((a) >= 0 ? (a) : -(a)) + +int +vesaSizeError (KdScreenInfo *screen, + VesaModePtr a) +{ + int xdist, ydist; + xdist = vabs (screen->width - vesaWidth(screen,a)); + ydist = vabs (screen->height - vesaHeight(screen,a)); + return xdist * xdist + ydist * ydist; +} + +Bool +vesaModeBetter (KdScreenInfo *screen, + VesaModePtr a, + VesaModePtr b) +{ + int aerr, berr; + + if (vesaModeGood (screen, a)) + { + if (!vesaModeGood (screen, b)) + return TRUE; + } + else + { + if (vesaModeGood (screen, b)) + return FALSE; + } + aerr = vesaSizeError (screen, a); + berr = vesaSizeError (screen, b); + if (aerr < berr) + return TRUE; + if (berr < aerr) + return FALSE; + if (vabs (screen->fb[0].depth - vesaDepth (a)) < + vabs (screen->fb[0].depth - vesaDepth (b))) + return TRUE; + if (a->BitsPerPixel == 32 && b->BitsPerPixel == 24) + return TRUE; + return FALSE; +} + +VesaModePtr +vesaSelectMode (KdScreenInfo *screen) +{ + VesaCardPrivPtr priv = screen->card->driver; + int i, best; + + if (vesa_video_mode) + { + for (best = 0; best < priv->nmode; best++) + if (priv->modes[best].mode == vesa_video_mode && + (vesaModeSupported (priv, &priv->modes[best], FALSE) || + vesa_force_mode)) + return &priv->modes[best]; + } + for (best = 0; best < priv->nmode; best++) + { + if (vesaModeSupported (priv, &priv->modes[best], FALSE)) + break; + } + if (best == priv->nmode) + return 0; + for (i = best + 1; i < priv->nmode; i++) + if (vesaModeSupported (priv, &priv->modes[i], FALSE) && + vesaModeBetter (screen, &priv->modes[i], + &priv->modes[best])) + best = i; + return &priv->modes[best]; +} + +Bool +vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr) +{ + VesaModePtr mode; + + screen->driver = pscr; + + if (!screen->width || !screen->height) + { + screen->width = 640; + screen->height = 480; + } + if (!screen->fb[0].depth) + screen->fb[0].depth = 4; + + if (vesa_verbose) + ErrorF ("Mode requested %dx%dx%d\n", + screen->width, screen->height, screen->fb[0].depth); + + mode = vesaSelectMode (screen); + + if (!mode) + { + if (vesa_verbose) + ErrorF ("No selectable mode\n"); + return FALSE; + } + pscr->mode = *mode; + + if (vesa_verbose) + { + ErrorF ("\t"); + vesaReportMode (&pscr->mode); + } + + pscr->randr = screen->randr; + pscr->shadow = vesa_shadow; + pscr->origDepth = screen->fb[0].depth; + /* + * Compute visual support for the selected depth + */ + + switch (pscr->mode.MemoryModel) { + case MEMORY_DIRECT: + /* TrueColor or DirectColor */ + screen->fb[0].visuals = (1 << TrueColor); + screen->fb[0].redMask = + FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize); + screen->fb[0].greenMask = + FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize); + screen->fb[0].blueMask = + FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize); + break; + case MEMORY_PSEUDO: + /* PseudoColor */ + screen->fb[0].visuals = ((1 << StaticGray) | + (1 << GrayScale) | + (1 << StaticColor) | + (1 << PseudoColor) | + (1 << TrueColor) | + (1 << DirectColor)); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + case MEMORY_PLANAR: + /* 4 plane planar */ + if (pscr->mode.ModeAttributes & MODE_COLOUR) + screen->fb[0].visuals = (1 << StaticColor); + else + screen->fb[0].visuals = (1 << StaticGray); + screen->fb[0].blueMask = 0x00; + screen->fb[0].greenMask = 0x00; + screen->fb[0].redMask = 0x00; + break; + default: + ErrorF("Unsupported VESA MemoryModel 0x%02X\n", + pscr->mode.MemoryModel); + return FALSE; + } + screen->rate = 72; + + if (!vesaComputeFramebufferMapping (screen)) + return FALSE; + if (!vesaMapFramebuffer (screen)) + return FALSE; + return TRUE; +} + +Bool +vesaScreenInit(KdScreenInfo *screen) +{ + VesaScreenPrivPtr pscr; + + pscr = xcalloc (1, sizeof (VesaScreenPrivRec)); + if (!pscr) + return FALSE; + if (!vesaScreenInitialize (screen, pscr)) + return FALSE; + return TRUE; +} + +void * +vesaSetWindowPlanar(ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + static int plane; + int winSize; + void *base; + + plane = offset & 3; + VgaSetWritePlaneMask (priv->vi, (1 << plane)); + offset = offset >> 2; + if (pscr->mode.vbe) + { + base = VbeSetWindow (priv->vi, + priv->vbeInfo, + pscr->mode.BytesPerScanLine * row + offset, + mode, + &winSize); + } + else + { + base = VgaSetWindow (priv->vi, + pscr->mode.mode, + pscr->mode.BytesPerScanLine * row + offset, + mode, + &winSize); + } + *size = (CARD32) winSize; + return base; +} + +void * +vesaSetWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + + *size = pscr->mode.BytesPerScanLine; + return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset; +} + +void * +vesaSetWindowWindowed (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int winSize; + void *base; + + if (pscr->mode.vbe) + { + base = VbeSetWindow (priv->vi, + priv->vbeInfo, + pscr->mode.BytesPerScanLine * row + offset, + mode, + &winSize); + } + else + { + base = VgaSetWindow (priv->vi, + pscr->mode.mode, + pscr->mode.BytesPerScanLine * row + offset, + mode, + &winSize); + } + *size = (CARD32) winSize; + return base; +} + +void * +vesaWindowPlanar (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + + if (!pScreenPriv->enabled) + return 0; + return vesaSetWindowPlanar (pScreen, row, offset, mode, size); +} + +void * +vesaWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + + if (!pScreenPriv->enabled) + return 0; + return vesaSetWindowLinear (pScreen, row, offset, mode, size); +} + +void * +vesaWindowWindowed (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + + if (!pScreenPriv->enabled) + return 0; + return vesaSetWindowWindowed (pScreen, row, offset, mode, size); +} + +#define vesaInvertBits32(v) { \ + v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \ + v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \ + v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \ +} + +void * +vesaWindowCga (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int line; + + if (!pScreenPriv->enabled) + return 0; + *size = pscr->mode.BytesPerScanLine; + line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine; + return (CARD8 *) pscr->fb + line + offset; +} + +void +vesaUpdateMono (ScreenPtr pScreen, + shadowBufPtr pBuf) +{ + RegionPtr damage = shadowDamage(pBuf); + PixmapPtr pShadow = pBuf->pPixmap; + int nbox = REGION_NUM_RECTS (damage); + BoxPtr pbox = REGION_RECTS (damage); + FbBits *shaBase, *shaLine, *sha; + FbStride shaStride; + int scrBase, scrLine, scr; + int shaBpp; + int shaXoff, shaYoff; /* XXX assumed to be zero */ + int x, y, w, h, width; + int i; + FbBits *winBase = 0, *win; + CARD32 winSize; + FbBits bits; + + fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff); + while (nbox--) + { + x = pbox->x1 * shaBpp; + y = pbox->y1; + w = (pbox->x2 - pbox->x1) * shaBpp; + h = pbox->y2 - pbox->y1; + + scrLine = (x >> FB_SHIFT); + shaLine = shaBase + y * shaStride + (x >> FB_SHIFT); + + x &= FB_MASK; + w = (w + x + FB_MASK) >> FB_SHIFT; + + while (h--) + { + winSize = 0; + scrBase = 0; + width = w; + scr = scrLine; + sha = shaLine; + while (width) { + /* how much remains in this window */ + i = scrBase + winSize - scr; + if (i <= 0 || scr < scrBase) + { + winBase = (FbBits *) (*pBuf->window) (pScreen, + y, + scr * sizeof (FbBits), + SHADOW_WINDOW_WRITE, + &winSize, + pBuf->closure); + if(!winBase) + return; + scrBase = scr; + winSize /= sizeof (FbBits); + i = winSize; + } + win = winBase + (scr - scrBase); + if (i > width) + i = width; + width -= i; + scr += i; + while (i--) + { + bits = *sha++; + vesaInvertBits32(bits); + *win++ = bits; + } + } + shaLine += shaStride; + y++; + } + pbox++; + } +} + +static const CARD16 vga16Colors[16][3] = { + { 0, 0, 0, }, /* 0 */ + { 0, 0, 0xAA,}, /* 1 */ + { 0, 0xAA,0, }, /* 2 */ + { 0, 0xAA,0xAA,}, /* 3 */ + { 0xAA,0, 0, }, /* 4 */ + { 0xAA,0, 0xAA,}, /* 5 */ + { 0xAA,0x55,0, }, /* 6 */ + { 0xAA,0xAA,0xAA,}, /* 7 */ + { 0x55,0x55,0x55,}, /* 8 */ + { 0x55,0x55,0xFF,}, /* 9 */ + { 0x55,0xFF,0x55,}, /* 10 */ + { 0x55,0xFF,0xFF,}, /* 11 */ + { 0xFF,0x55,0x55,}, /* 12 */ + { 0xFF,0x55,0xFF,}, /* 13 */ + { 0xFF,0xFF,0x55,}, /* 14 */ + { 0xFF,0xFF,0xFF,}, /* 15 */ +}; + +Bool +vesaCreateColormap16 (ColormapPtr pmap) +{ + int i, j; + + if (pmap->pVisual->ColormapEntries == 16) + for (i = 0; i < pmap->pVisual->ColormapEntries; i++) + { + j = i & 0xf; + pmap->red[i].co.local.red = (vga16Colors[j][0]<<8)|vga16Colors[j][0]; + pmap->red[i].co.local.green = (vga16Colors[j][1]<<8)|vga16Colors[j][1]; + pmap->red[i].co.local.blue = (vga16Colors[j][2]<<8)|vga16Colors[j][2]; + } + return TRUE; +} + +void +vesaSetScreenSizes (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + VesaScreenPrivPtr pscr = screen->driver; + + if (pscr->randr & (RR_Rotate_0|RR_Rotate_180)) + { + pScreen->width = pscr->mode.XResolution; + pScreen->height = pscr->mode.YResolution; + pScreen->mmWidth = screen->width_mm; + pScreen->mmHeight = screen->height_mm; + } + else + { + pScreen->width = pscr->mode.YResolution; + pScreen->height = pscr->mode.XResolution; + pScreen->mmWidth = screen->height_mm; + pScreen->mmHeight = screen->width_mm; + } +} + +Bool +vesaSetShadow (ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + ShadowUpdateProc update; + ShadowWindowProc window = 0; + + if (pscr->randr != RR_Rotate_0) + update = shadowUpdateRotatePacked; + else + update = shadowUpdatePacked; + switch (pscr->mapping) { + case VESA_LINEAR: + window = vesaWindowLinear; + break; + case VESA_WINDOWED: + window = vesaWindowWindowed; + break; + case VESA_PLANAR: + if (pScreenPriv->screen->fb[0].bitsPerPixel == 8) + update = shadowUpdatePlanar4x8; + else + update = shadowUpdatePlanar4; + window = vesaWindowPlanar; + break; + case VESA_MONO: + update = vesaUpdateMono; + if (pscr->mode.mode < 8) + window = vesaWindowCga; + else + window = vesaWindowLinear; + break; + } + + return KdShadowSet (pScreen, pscr->randr, update, window); +} + +static Bool +vesaComputeFramebufferMapping (KdScreenInfo *screen) +{ + VesaScreenPrivPtr pscr = screen->driver; + int depth, bpp, fbbpp; + Pixel allbits; + KdPointerMatrix m; + + if (vesa_linear_fb) + { + pscr->mapping = VESA_LINEAR; + pscr->shadow = FALSE; + } + else + { + pscr->mapping = VESA_WINDOWED; + pscr->shadow = TRUE; + } + + depth = vesaDepth (&pscr->mode); + bpp = pscr->mode.BitsPerPixel; + + if (bpp > 24) + bpp = 32; + else if (bpp > 16) + bpp = 24; + else if (bpp > 8) + bpp = 16; + else if (bpp > 4) + bpp = 8; + else if (bpp > 1) + bpp = 4; + else + bpp = 1; + fbbpp = bpp; + + switch (pscr->mode.MemoryModel) { + case MEMORY_DIRECT: + allbits = (screen->fb[0].redMask | + screen->fb[0].greenMask | + screen->fb[0].blueMask); + depth = 32; + while (depth && !(allbits & (1 << (depth - 1)))) + depth--; + if (vesa_verbose) + ErrorF ("\tTrue Color %d/%d red 0x%x green 0x%x blue 0x%x\n", + bpp, depth, + screen->fb[0].redMask, + screen->fb[0].greenMask, + screen->fb[0].blueMask); + break; + case MEMORY_PSEUDO: + if (vesa_verbose) + ErrorF ("\tPseudo Color bpp %d depth %d\n", + bpp, depth); + break; + case MEMORY_PLANAR: + if (bpp == 4) + { + bpp = screen->fb[0].bitsPerPixel; + if (bpp != 8) + bpp = 4; + depth = bpp; + } + if (bpp == 1) + { + pscr->mapping = VESA_MONO; + if (vesa_verbose) + ErrorF ("\tMonochrome\n"); + } + else + { + pscr->mapping = VESA_PLANAR; + if (vesa_verbose) + ErrorF ("\tStatic color bpp %d depth %d\n", + bpp, depth); + } + pscr->randr = RR_Rotate_0; + pscr->shadow = TRUE; + break; + default: + return FALSE; + } + + switch (fbbpp) { + case 8: + case 16: + case 32: + break; + default: + pscr->randr = RR_Rotate_0; + break; + } + + if (pscr->randr != RR_Rotate_0) + pscr->shadow = TRUE; + + if (vesa_shadow) + pscr->shadow = vesa_shadow; + + if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR)) + { + pscr->mapping = VESA_WINDOWED; + pscr->shadow = TRUE; + } + KdComputePointerMatrix (&m, pscr->randr, + pscr->mode.XResolution, pscr->mode.YResolution); + + KdSetPointerMatrix (&m); + + screen->width = pscr->mode.XResolution; + screen->height = pscr->mode.YResolution; + screen->fb[0].depth = depth; + screen->fb[0].bitsPerPixel = bpp; + + return TRUE; +} + +static Bool +vesaMapFramebuffer (KdScreenInfo *screen) +{ + VesaCardPrivPtr priv = screen->card->driver; + VesaScreenPrivPtr pscr = screen->driver; + + if (pscr->mapped) + return TRUE; + switch (pscr->mapping) { + case VESA_MONO: + case VESA_LINEAR: + if (pscr->mode.vbe) + pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo, + pscr->mode.mode, + &pscr->fb_size, + &pscr->fb_phys); + else + pscr->fb = VgaMapFramebuffer (priv->vi, + pscr->mode.mode, + &pscr->fb_size, + &pscr->fb_phys); + if (!pscr->fb) + return FALSE; + break; + case VESA_WINDOWED: + pscr->fb = NULL; + break; + case VESA_PLANAR: + pscr->fb = NULL; + break; + } + + screen->memory_base = pscr->fb; + screen->memory_size = pscr->fb_size; + + if (pscr->shadow) + { + if (!KdShadowFbAlloc (screen, 0, + pscr->randr & (RR_Rotate_90|RR_Rotate_270))) + return FALSE; + screen->off_screen_base = screen->memory_size; + } + else + { + screen->fb[0].frameBuffer = (CARD8 *) (pscr->fb); + screen->fb[0].byteStride = pscr->mode.BytesPerScanLine; + screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) / + screen->fb[0].bitsPerPixel); + screen->off_screen_base = screen->fb[0].byteStride * screen->height; + } + pscr->mapped = TRUE; + + return TRUE; +} + +static void +vesaUnmapFramebuffer (KdScreenInfo *screen) +{ + VesaCardPrivPtr priv = screen->card->driver; + VesaScreenPrivPtr pscr = screen->driver; + + if (!pscr->mapped) + return; + + pscr->mapped = FALSE; + KdShadowFbFree (screen, 0); + if (pscr->fb) + { + if (pscr->mode.vbe) + VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb); + else + VgaUnmapFramebuffer (priv->vi); + pscr->fb = 0; + } +} + +#ifdef RANDR +Bool +vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) +{ + KdScreenPriv(pScreen); + VesaModePtr modes, mode; + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int nmode; + int n; + RRScreenSizePtr pSize; + + *rotations = (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270| + RR_Reflect_X|RR_Reflect_Y); + /* + * Get mode information from BIOS -- every time in case + * something changes, like an external monitor is plugged in + */ + modes = vesaGetModes (priv->vi, &nmode); + if (!modes) + return FALSE; + if (priv->modes) + xfree (priv->modes); + priv->modes = modes; + priv->nmode = nmode; + for (n = 0; n < nmode; n++) + { + mode = &priv->modes[n]; + if (vesaModeSupported (priv, mode, FALSE)) + { + /* + * XXX limit reported modes to those matching the current + * format + */ + if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes && + mode->BitsPerPixel == pscr->mode.BitsPerPixel && + mode->MemoryModel == pscr->mode.MemoryModel && + mode->RedMaskSize == pscr->mode.RedMaskSize && + mode->RedFieldPosition == pscr->mode.RedFieldPosition && + mode->GreenMaskSize == pscr->mode.GreenMaskSize && + mode->GreenFieldPosition == pscr->mode.GreenFieldPosition && + mode->BlueMaskSize == pscr->mode.BlueMaskSize && + mode->BlueFieldPosition == pscr->mode.BlueFieldPosition) + { + int width, height, width_mm, height_mm; + if (screen->randr & (RR_Rotate_0|RR_Rotate_180)) + { + width = mode->XResolution; + height = mode->YResolution; + width_mm = screen->width_mm; + height_mm = screen->height_mm; + } + else + { + width = mode->YResolution; + height = mode->XResolution; + width_mm = screen->height_mm; + height_mm = screen->width_mm; + } + pSize = RRRegisterSize (pScreen, + width, height, + width_mm, height_mm); + if (mode->XResolution == screen->width && + mode->YResolution == screen->height) + { + int randr = KdSubRotation (pscr->randr, screen->randr); + RRSetCurrentConfig (pScreen, randr, 0, pSize); + } + } + } + } + return TRUE; +} + +Bool +vesaRandRSetConfig (ScreenPtr pScreen, + Rotation randr, + int rate, + RRScreenSizePtr pSize) +{ + KdScreenPriv(pScreen); + VesaModePtr mode = 0; + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int n; + Bool wasEnabled = pScreenPriv->enabled; + Bool ret = FALSE; + VesaScreenPrivRec oldscr; + int oldwidth; + int oldheight; + int oldmmwidth; + int oldmmheight; + int newwidth, newheight; + + if (screen->randr & (RR_Rotate_0|RR_Rotate_180)) + { + newwidth = pSize->width; + newheight = pSize->height; + } + else + { + newwidth = pSize->height; + newheight = pSize->width; + } + for (n = 0; n < priv->nmode; n++) + { + mode = &priv->modes[n]; + if (vesaModeSupported (priv, mode, FALSE)) + { + /* + * XXX all we have to match is the size + */ + if (mode->XResolution == newwidth && + mode->YResolution == newheight && + mode->NumberOfPlanes == pscr->mode.NumberOfPlanes && + mode->BitsPerPixel == pscr->mode.BitsPerPixel && + mode->RedMaskSize == pscr->mode.RedMaskSize && + mode->RedFieldPosition == pscr->mode.RedFieldPosition && + mode->GreenMaskSize == pscr->mode.GreenMaskSize && + mode->GreenFieldPosition == pscr->mode.GreenFieldPosition && + mode->BlueMaskSize == pscr->mode.BlueMaskSize && + mode->BlueFieldPosition == pscr->mode.BlueFieldPosition) + break; + } + } + if (n == priv->nmode) + goto bail0; + + if (wasEnabled) + KdDisableScreen (pScreen); + + if (mode->mode != pscr->mode.mode) + { + ret = vesaSetMode (pScreen, mode); + if (!ret) + goto bail1; + } + + oldscr = *pscr; + + oldwidth = screen->width; + oldheight = screen->height; + oldmmwidth = pScreen->mmWidth; + oldmmheight = pScreen->mmHeight; + + /* + * Set new configuration + */ + + pscr->mode = *mode; + pscr->randr = KdAddRotation (screen->randr, randr); + + /* + * Can't rotate some formats + */ + switch (screen->fb[0].bitsPerPixel) { + case 8: + case 16: + case 32: + break; + default: + if (pscr->randr) + goto bail2; + break; + } + + KdOffscreenSwapOut (screen->pScreen); + + vesaUnmapFramebuffer (screen); + + if (!vesaComputeFramebufferMapping (screen)) + goto bail3; + + if (!vesaMapFramebuffer (screen)) + goto bail3; + + vesaSetScreenSizes (screen->pScreen); + + if (!vesaSetShadow (screen->pScreen)) + goto bail4; + + /* + * Set frame buffer mapping + */ + (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), + pScreen->width, + pScreen->height, + screen->fb[0].depth, + screen->fb[0].bitsPerPixel, + screen->fb[0].byteStride, + screen->fb[0].frameBuffer); + + /* set the subpixel order */ + KdSetSubpixelOrder (pScreen, pscr->randr); + + if (wasEnabled) + KdEnableScreen (pScreen); + + return TRUE; + +bail4: + vesaUnmapFramebuffer (screen); + *pscr = oldscr; + (void) vesaComputeFramebufferMapping (screen); + (void) vesaMapFramebuffer (screen); + +bail3: + pScreen->width = oldwidth; + pScreen->height = oldheight; + pScreen->mmWidth = oldmmwidth; + pScreen->mmHeight = oldmmheight; + +bail2: + *pscr = oldscr; + + (void) vesaSetMode (pScreen, &pscr->mode); +bail1: + if (wasEnabled) + KdEnableScreen (pScreen); +bail0: + + return FALSE; +} + +Bool +vesaRandRInit (ScreenPtr pScreen) +{ + rrScrPrivPtr pScrPriv; + + if (!RRScreenInit (pScreen)) + return FALSE; + + pScrPriv = rrGetScrPriv(pScreen); + pScrPriv->rrGetInfo = vesaRandRGetInfo; + pScrPriv->rrSetConfig = vesaRandRSetConfig; + return TRUE; +} +#endif + +Bool +vesaInitScreen(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + switch (pscr->mapping) { + case VESA_PLANAR: + pScreen->CreateColormap = vesaCreateColormap16; + break; + } + return TRUE; +} + +Bool +vesaFinishInitScreen (ScreenPtr pScreen) +{ + if (!shadowSetup (pScreen)) + return FALSE; + +#ifdef RANDR + if (!vesaRandRInit (pScreen)) + return FALSE; +#endif + + return TRUE; +} + +Bool +vesaCreateResources (ScreenPtr pScreen) +{ + return vesaSetShadow (pScreen); +} + +Bool +vesaSetMode (ScreenPtr pScreen, + VesaModePtr mode) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + int code; + + if (mode->vbe) + { + if (vesa_verbose) + ErrorF ("Enable VBE mode 0x%x\n", mode->mode); + code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode, + pscr->mapping == VESA_LINEAR, + mode->MemoryModel == MEMORY_DIRECT); + } + else + { + if (vesa_verbose) + ErrorF ("Enable BIOS mode 0x%x\n", mode->mode); + code = VgaSetMode (priv->vi, mode->mode); + } + + if(code < 0) + return FALSE; + + return TRUE; +} + +Bool +vesaEnable(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + KdScreenInfo *screen = pScreenPriv->screen; + int i; + CARD32 size; + char *p; + Bool was_mapped = pscr->mapped; + + if (!vesaMapFramebuffer (screen)) + return FALSE; + + if (!vesaSetMode (pScreen, &pscr->mode)) + return FALSE; + + switch (pscr->mapping) { + case VESA_MONO: + VgaSetWritePlaneMask (priv->vi, 0x1); + case VESA_LINEAR: + if (vesa_restore_font) + memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE); + break; + case VESA_WINDOWED: + if (vesa_restore_font) + { + for (i = 0; i < VESA_TEXT_SAVE;) + { + p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_READ, &size); + if(!p) { + ErrorF("Couldn't set window for saving VGA font\n"); + break; + } + if(i + size > VESA_TEXT_SAVE) + size = VESA_TEXT_SAVE - i; + memcpy(((char*)priv->text) + i, p, size); + i += size; + } + } + break; + case VESA_PLANAR: + if (vesa_restore_font) + { + for (i = 0; i < 4; i++) + { + p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_READ, &size); + memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p, + (VESA_TEXT_SAVE/4)); + } + } + break; + } + if (!was_mapped) + { + (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), + pScreen->width, + pScreen->height, + screen->fb[0].depth, + screen->fb[0].bitsPerPixel, + screen->fb[0].byteStride, + screen->fb[0].frameBuffer); + } + return TRUE; +} + +#ifndef TOSHIBA_SMM + +# ifdef linux +# define TOSHIBA_SMM 1 +# endif + +# ifndef TOSHIBA_SMM +# define TOSHIBA_SMM 0 +# endif + +#endif + +#if TOSHIBA_SMM +/* + * Toshiba laptops use a special interface to operate the backlight + */ +#include <sys/ioctl.h> +#define TOSH_PROC "/proc/toshiba" +#define TOSH_DEVICE "/dev/toshiba" +#define TOSH_SMM _IOWR('t', 0x90, SMMRegisters) + +typedef struct { + unsigned int eax; + unsigned int ebx __attribute__ ((packed)); + unsigned int ecx __attribute__ ((packed)); + unsigned int edx __attribute__ ((packed)); + unsigned int esi __attribute__ ((packed)); + unsigned int edi __attribute__ ((packed)); +} SMMRegisters; + +#define HCI_BACKLIGHT 0x0002 +#define HCI_DISABLE 0x0000 +#define HCI_ENABLE 0x0001 +#define HCI_GET 0xfe00, +#define HCI_SET 0xff00 + +Bool +toshibaDPMS (ScreenPtr pScreen, int mode) +{ + SMMRegisters regs; + static int fd; + + if (!fd) + fd = open (TOSH_DEVICE, 2); + if (fd < 0) + return FALSE; + regs.eax = HCI_SET; + regs.ebx = HCI_BACKLIGHT; + regs.ecx = mode ? HCI_DISABLE : HCI_ENABLE; + if (ioctl (fd, TOSH_SMM, ®s) < 0) + return FALSE; + return TRUE; +} +#endif /* TOSHIBA_SMM */ + +Bool +vesaDPMS (ScreenPtr pScreen, int mode) +{ + KdScreenPriv(pScreen); + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + +#if TOSHIBA_SMM + if (toshibaDPMS (pScreen, mode)) + return TRUE; +#endif + if (pscr->mode.vbe) + return VbeDPMS (priv->vi, mode); + return FALSE; +} + +void +vesaDisable(ScreenPtr pScreen) +{ + KdScreenPriv(pScreen); + KdScreenInfo *screen = pScreenPriv->screen; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + VesaScreenPrivPtr pscr = screen->driver; + int i=0; + CARD32 size; + char *p; + + if (vesa_restore_font) { + switch (pscr->mapping) { + case VESA_LINEAR: + case VESA_MONO: + memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE); + break; + case VESA_WINDOWED: + while(i < VESA_TEXT_SAVE) { + p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_WRITE, &size); + if(!p) { + ErrorF("Couldn't set window for restoring VGA font\n"); + break; + } + if(i + size > VESA_TEXT_SAVE) + size = VESA_TEXT_SAVE - i; + memcpy(p, ((char*)priv->text) + i, size); + i += size; + } + break; + case VESA_PLANAR: + for (i = 0; i < 4; i++) + { + p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_WRITE, &size); + memcpy (p, + ((char *)priv->text) + i * (VESA_TEXT_SAVE/4), + (VESA_TEXT_SAVE/4)); + } + break; + } + } + vesaUnmapFramebuffer (screen); +} + +void +vesaPreserve(KdCardInfo *card) +{ + VesaCardPrivPtr priv = card->driver; + + /* The framebuffer might not be valid at this point, so we cannot + save the VGA fonts now; we do it in vesaEnable. */ + + if (VbeGetMode (priv->vi, &priv->old_vbe_mode) < 0) + priv->old_vbe_mode = -1; + + if (VgaGetMode (priv->vi, &priv->old_vga_mode) < 0) + priv->old_vga_mode = -1; + + if (vesa_verbose) + ErrorF ("Previous modes: VBE 0x%x BIOS 0x%x\n", + priv->old_vbe_mode, priv->old_vga_mode); +} + +void +vesaRestore(KdCardInfo *card) +{ + VesaCardPrivPtr priv = card->driver; + int n; + + if (vesa_force_text) + { + if (vesa_verbose) + ErrorF ("Forcing switch back to mode 3 text\n"); + priv->old_vbe_mode = -1; + priv->old_vga_mode = 3; + } + for (n = 0; n < priv->nmode; n++) + if (priv->modes[n].vbe && priv->modes[n].mode == (priv->old_vbe_mode&0x3fff)) + break; + + if (n < priv->nmode) + { + if (vesa_verbose) + ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode); + VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0); + } + else + { + if (vesa_verbose) + ErrorF ("Restore BIOS mode 0x%x\n", priv->old_vga_mode); + VgaSetMode (priv->vi, priv->old_vga_mode); + } +} + +void +vesaCardFini(KdCardInfo *card) +{ + VesaCardPrivPtr priv = card->driver; + + if (priv->vbeInfo) + VbeCleanup (priv->vi, priv->vbeInfo); + if (priv->modes) + xfree (priv->modes); + Vm86Cleanup(priv->vi); +} + +void +vesaScreenFini(KdScreenInfo *screen) +{ + VesaScreenPrivPtr pscr = screen->driver; + + KdShadowFbFree (screen, 0); + vesaUnmapFramebuffer (screen); + screen->fb[0].depth = pscr->origDepth; +} + +int +vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries) +{ + if (priv->vga_palette) + return VgaSetPalette (priv->vi, first, number, entries); + else + return VbeSetPalette (priv->vi, priv->vbeInfo, first, number, entries); +} + + +int +vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries) +{ + int code; + + if (priv->vga_palette) + code = VgaGetPalette (priv->vi, first, number, entries); + else + { + code = VbeGetPalette (priv->vi, priv->vbeInfo, first, number, entries); + if (code < 0) + { + priv->vga_palette = 1; + code = VgaGetPalette (priv->vi, first, number, entries); + } + } + return code; +} + +void +vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + int p; + CARD8 *scratch; + int red, green, blue; + int min, max; + + if (vesa_swap_rgb) + { + red = 2; + green = 1; + blue = 0; + } + else + { + red = 0; + green = 1; + blue = 2; + } + + min = 256; + max = 0; + while (n--) + { + p = pdefs->pixel; + if (p < min) + min = p; + if (p > max) + max = p; + scratch = priv->cmap + (p * 4); + scratch[red] = pdefs->red >> 8; + scratch[green] = pdefs->green >> 8; + scratch[blue] = pdefs->blue >> 8; + scratch[3] = 0; + pdefs++; + if (pscr->mapping == VESA_PLANAR) + { + /* + * VGA modes are strange; this code covers all + * possible modes by duplicating the color information + * however the attribute registers might be set + */ + if (p < 16) + { + vesaSetPalette (priv, p, 1, scratch); + if (p >= 8) + vesaSetPalette (priv, p+0x30, 1, scratch); + else if (p == 6) + vesaSetPalette (priv, 0x14, 1, scratch); + } + } + } + if (pscr->mapping != VESA_PLANAR) + vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4); +} + +void +vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs) +{ + KdScreenPriv(pScreen); + VesaScreenPrivPtr pscr = pScreenPriv->screen->driver; + VesaCardPrivPtr priv = pScreenPriv->card->driver; + int i; + int red, green, blue; + int min, max; + int p; + CARD8 *scratch; + + if (vesa_swap_rgb) + { + red = 2; + green = 1; + blue = 0; + } + else + { + red = 0; + green = 1; + blue = 2; + } + + min = 256; + max = 0; + for(i = 0; i < n; i++) + { + p = pdefs[i].pixel; + if (p < min) + min = p; + if (p > max) + max = p; + if (pscr->mapping == VESA_PLANAR) + vesaGetPalette (priv, p, 1, priv->cmap + p * 4); + } + if (pscr->mapping != VESA_PLANAR) + vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4); + for (i = 0; i < n; i++) + { + p = pdefs[i].pixel; + scratch = priv->cmap + p * 4; + pdefs[i].red = scratch[red]<<8; + pdefs[i].green = scratch[green]<<8; + pdefs[i].blue = scratch[blue]<<8; + } +} + +void +vesaUseMsg (void) +{ + ErrorF("\nTinyX VESA Usage:\n"); + ErrorF("-mode VESA video mode to use (Be careful!)\n"); + ErrorF("-listmodes List supported video modes\n"); + ErrorF("-force Attempt even unsupported modes\n"); + ErrorF("-shadow Always use shadow framebuffer (May increase performance)\n"); + ErrorF("-nolinear Never use linear framebuffer (Not useful)\n"); + ErrorF("-swaprgb Use if colors are wrong in PseudoColor and 16 color modes\n"); + ErrorF("-map-holes Use contiguous memory map (For seg fault with rare BIOS)\n"); + ErrorF("-verbose Emit diagnostic messages during BIOS initialization\n"); + ErrorF("-force-text Always use standard 25x80 text mode on server exit or VT switch\n"); + ErrorF("-boot Soft boot video card\n"); + /* XXX: usage for -vesatest, -no-map-holes (don't need?), + * XXX: and -trash-font. Also in man page. */ +} + +int +vesaProcessArgument (int argc, char **argv, int i) +{ + if(!strcmp(argv[i], "-mode")) { + if(i+1 < argc) { + vesa_video_mode = strtol(argv[i+1], NULL, 0); + } else + UseMsg(); + return 2; + } else if(!strcmp(argv[i], "-force")) { + vesa_force_mode = TRUE; + return 1; + } else if(!strcmp(argv[i], "-listmodes")) { + vesaListModes(); + exit(0); + } else if(!strcmp(argv[i], "-vesatest")) { + vesaTestMode(); + exit (0); + } else if(!strcmp(argv[i], "-swaprgb")) { + vesa_swap_rgb = TRUE; + return 1; + } else if(!strcmp(argv[i], "-shadow")) { + vesa_shadow = TRUE; + return 1; + } else if(!strcmp(argv[i], "-nolinear")) { + vesa_linear_fb = FALSE; + return 1; + } else if(!strcmp(argv[i], "-verbose")) { + vesa_verbose = TRUE; + return 1; + } else if(!strcmp(argv[i], "-force-text")) { + vesa_force_text = TRUE; + return 1; + } else if(!strcmp(argv[i], "-map-holes")) { + vesa_map_holes = TRUE; + return 1; + } else if(!strcmp(argv[i], "-no-map-holes")) { + vesa_map_holes = FALSE; + return 1; + } else if(!strcmp(argv[i], "-trash-font")) { + vesa_restore_font = FALSE; + return 1; + } else if(!strcmp(argv[i], "-boot")) { + vesa_boot = TRUE; + return 1; + } + + return 0; +} diff --git a/xorg-server/hw/kdrive/vesa/vesa.h b/xorg-server/hw/kdrive/vesa/vesa.h new file mode 100644 index 000000000..f6b21e9f5 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vesa.h @@ -0,0 +1,295 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef _VESA_H_ +#define _VESA_H_ + +#include "kdrive.h" +#include "shadow.h" +#include "vm86.h" +#ifdef RANDR +#include "randrstr.h" +#endif + +#define VESA_TEXT_SAVE (64*1024) + +#define MODE_SUPPORTED 0x01 +#define MODE_COLOUR 0x08 +#define MODE_GRAPHICS 0x10 +#define MODE_VGA 0x20 +#define MODE_LINEAR 0x80 + +#define MODE_DIRECT 0x1 + +#define MEMORY_TEXT 0 +#define MEMORY_CGA 1 +#define MEMORY_HERCULES 2 +#define MEMORY_PLANAR 3 +#define MEMORY_PSEUDO 4 +#define MEMORY_NONCHAIN 5 +#define MEMORY_DIRECT 6 +#define MEMORY_YUV 7 + +typedef struct _VesaMode { + int mode; /* mode number */ + int vbe; /* a VBE mode */ + int ModeAttributes; /* mode attributes */ + int NumberOfPlanes; /* number of memory planes */ + int BitsPerPixel; /* bits per pixel */ + int MemoryModel; /* memory model type */ + int RedMaskSize; /* size of direct color red mask in bits */ + int RedFieldPosition; /* bit position of lsb of red mask */ + int GreenMaskSize; /* size of direct color green mask in bits */ + int GreenFieldPosition; /* bit position of lsb of green mask */ + int BlueMaskSize; /* size of direct color blue mask in bits */ + int BlueFieldPosition; /* bit position of lsb of blue mask */ + int RsvdMaskSize; /* size of direct color reserved mask bits*/ + int RsvdFieldPosition; /* bit position of lsb of reserved mask */ + int DirectColorModeInfo; /* direct color mode attributes */ + int XResolution; /* horizontal resolution */ + int YResolution; /* vertical resolution */ + int BytesPerScanLine; /* bytes per scan line */ +} VesaModeRec, *VesaModePtr; + +#include "vbe.h" +#include "vga.h" + +typedef struct _VesaCardPriv { + int vbe; + VesaModePtr modes; + int nmode; + Vm86InfoPtr vi; + int vga_palette; + int old_vbe_mode; + int old_vga_mode; + VbeInfoPtr vbeInfo; + char text[VESA_TEXT_SAVE]; + CARD8 cmap[256*4]; +} VesaCardPrivRec, *VesaCardPrivPtr; + +#define VESA_LINEAR 0 +#define VESA_WINDOWED 1 +#define VESA_PLANAR 2 +#define VESA_MONO 3 + +typedef struct _VesaScreenPriv { + VesaModeRec mode; + Bool shadow; + Rotation randr; + int mapping; + int origDepth; + void *fb; + int fb_size; + CARD32 fb_phys; + PixmapPtr pShadow; + Bool mapped; +} VesaScreenPrivRec, *VesaScreenPrivPtr; + +extern int vesa_video_mode; +extern Bool vesa_force_mode; + +void +vesaReportMode (VesaModePtr mode); + +VesaModePtr +vesaGetModes (Vm86InfoPtr vi, int *ret_nmode); + +void +vesaTestMode (void); + +void * +vesaSetWindowPlanar(ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size); + +void * +vesaSetWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size); + +void * +vesaSetWindowWindowed (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size); + +void * +vesaWindowPlanar (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure); + +void * +vesaWindowLinear (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure); + +void * +vesaWindowWindowed (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure); + +void * +vesaWindowCga (ScreenPtr pScreen, + CARD32 row, + CARD32 offset, + int mode, + CARD32 *size, + void *closure); + +void +vesaUpdateMono (ScreenPtr pScreen, + shadowBufPtr pBuf); + +Bool +vesaCreateColormap16 (ColormapPtr pmap); + +void +vesaSetScreenSizes (ScreenPtr pScreen); + +Bool +vesaSetShadow (ScreenPtr pScreen); + + +void +vesaListModes(void); + +Bool +vesaInitialize(KdCardInfo *card, VesaCardPrivPtr priv); + +Bool +vesaCardInit(KdCardInfo *card); + +int +vesaDepth (VesaModePtr mode); + +Bool +vesaModeGood (KdScreenInfo *screen, + VesaModePtr a); + +int +vesaSizeError (KdScreenInfo *screen, + VesaModePtr a); + +Bool +vesaModeBetter (KdScreenInfo *screen, + VesaModePtr a, + VesaModePtr b); + +VesaModePtr +vesaSelectMode (KdScreenInfo *screen); + +Bool +vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv); + +Bool +vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr); + +Bool +vesaScreenInit(KdScreenInfo *screen); + +PixmapPtr +vesaGetPixmap (ScreenPtr pScreen); + +Bool +vesaInitScreen(ScreenPtr pScreen); + +Bool +vesaFinishInitScreen(ScreenPtr pScreen); + +Bool +vesaCreateResources (ScreenPtr pScreen); + +Bool +vesaSetMode (ScreenPtr pScreen, + VesaModePtr mode); + +Bool +vesaEnable(ScreenPtr pScreen); + +Bool +vesaDPMS (ScreenPtr pScreen, int mode); + +void +vesaDisable(ScreenPtr pScreen); + +void +vesaPreserve(KdCardInfo *card); + +void +vesaRestore(KdCardInfo *card); + +void +vesaCardFini(KdCardInfo *card); + +void +vesaScreenFini(KdScreenInfo *screen); + +int +vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries); + +int +vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries); + +void +vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); + +void +vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs); + +void +vesaUseMsg (void); + +int +vesaProcessArgument (int argc, char **argv, int i); + +#ifdef RANDR +Bool +vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations); + +Bool +vesaRandRSetConfig (ScreenPtr pScreen, + Rotation randr, + int rate, + RRScreenSizePtr pSize); +Bool +vesaRandRInit (ScreenPtr pScreen); + +#endif + +Bool +toshibaDPMS (ScreenPtr pScreen, int mode); + +#endif /* _VESA_H_ */ diff --git a/xorg-server/hw/kdrive/vesa/vesainit.c b/xorg-server/hw/kdrive/vesa/vesainit.c new file mode 100644 index 000000000..a5e216cfd --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vesainit.c @@ -0,0 +1,92 @@ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vesa.h" + +const KdCardFuncs vesaFuncs = { + vesaCardInit, /* cardinit */ + vesaScreenInit, /* scrinit */ + vesaInitScreen, /* initScreen */ + vesaFinishInitScreen, /* finishInitScreen */ + vesaCreateResources, /* createRes */ + vesaPreserve, /* preserve */ + vesaEnable, /* enable */ + vesaDPMS, /* dpms */ + vesaDisable, /* disable */ + vesaRestore, /* restore */ + vesaScreenFini, /* scrfini */ + vesaCardFini, /* cardfini */ + + 0, /* initCursor */ + 0, /* enableCursor */ + 0, /* disableCursor */ + 0, /* finiCursor */ + 0, /* recolorCursor */ + + 0, /* initAccel */ + 0, /* enableAccel */ + 0, /* disableAccel */ + 0, /* finiAccel */ + + vesaGetColors, /* getColors */ + vesaPutColors, /* putColors */ +}; + +void +InitCard(char *name) +{ + KdCardAttr attr; + KdCardInfoAdd((KdCardFuncs *) &vesaFuncs, &attr, 0); +} + +void +InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) +{ + KdInitOutput (pScreenInfo, argc, argv); +} + +void +InitInput (int argc, char **argv) +{ + KdOsAddInputDrivers(); + KdInitInput(); +} + +void +ddxUseMsg (void) +{ + KdUseMsg(); + vesaUseMsg(); +} + +int +ddxProcessArgument (int argc, char **argv, int i) +{ + int ret; + + if (!(ret = vesaProcessArgument (argc, argv, i))) + ret = KdProcessArgument(argc, argv, i); + return ret; +} diff --git a/xorg-server/hw/kdrive/vesa/vga.c b/xorg-server/hw/kdrive/vesa/vga.c new file mode 100644 index 000000000..0367a5f06 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vga.c @@ -0,0 +1,242 @@ +/* + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vesa.h" + +static const VesaModeRec vgaModes[] = { + { + 6, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR, + 1, 1, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 640, 200, 80, + }, + { + 0xd, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR, + 4, 4, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 320, 200, 40, + }, + { + 0xe, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR, + 4, 4, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 640, 200, 80, + }, + { + 0x10, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR, + 4, 4, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 640, 350, 80, + }, + { + 0x11, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR, + 1, 1, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 640, 480, 80, + }, + { + 0x12, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR, + 4, 4, MEMORY_PLANAR, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 640, 480, 80, + }, + { + 0x13, 0, + MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR | MODE_LINEAR, + 8, 8, MEMORY_PSEUDO, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 320, 200, 320, + }, +}; + +#define NUM_VGA_MODE (sizeof vgaModes / sizeof vgaModes[0]) + +int +VgaGetNmode (Vm86InfoPtr vi) +{ + return NUM_VGA_MODE; +} + +int +VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode) +{ + if (nmode > NUM_VGA_MODE) + nmode = NUM_VGA_MODE; + memcpy (mode, vgaModes, nmode * sizeof (VesaModeRec)); + return nmode; +} + +int +VgaSetMode(Vm86InfoPtr vi, int mode) +{ + int code; + + vi->vms.regs.eax = mode & 0x7f; + code = Vm86DoInterrupt (vi, 0x10); + if(code < 0) + return -1; + return 0; +} + +int +VgaGetMode (Vm86InfoPtr vi, int *mode) +{ + *mode = Vm86Memory (vi, 0x449); + return 0; +} + +void +VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask) +{ + asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4)); + asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5)); +} + +void +VgaSetReadPlaneMap(Vm86InfoPtr vi, int map) +{ + asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce)); + asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf)); +} + +int +VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int mark; + int palette_base; + int i, j, code; + + if(number == 0) + return 0; + + if(first < 0 || number < 0 || first + number > 256) { + ErrorF("Cannot set %d, %d palette entries\n", first, number); + return -1; + } + + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 3 * 256); + + palette_scratch = &LM(vi, palette_base); + + vi->vms.regs.eax = 0x1012; + vi->vms.regs.ebx = first; + vi->vms.regs.ecx = number; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edx = POINTER_OFFSET(palette_base); + j = 0; + i = 0; + while (number--) + { + palette_scratch[j++] = entries[i++] >> 2; + palette_scratch[j++] = entries[i++] >> 2; + palette_scratch[j++] = entries[i++] >> 2; + i++; + } + code = Vm86DoInterrupt(vi, 0x10); + Vm86ReleaseMemory (vi, mark); + + if(code < 0) + return -1; + return 0; +} + +int +VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries) +{ + U8 *palette_scratch; + int mark; + int palette_base; + int i, j, code; + + if(number == 0) + return 0; + + if(first < 0 || number < 0 || first + number > 256) { + ErrorF("Cannot get %d, %d palette entries\n", first, number); + return -1; + } + + mark = Vm86MarkMemory (vi); + palette_base = Vm86AllocateMemory (vi, 3 * 256); + + palette_scratch = &LM(vi, palette_base); + + vi->vms.regs.eax = 0x1017; + vi->vms.regs.ebx = first; + vi->vms.regs.ecx = number; + vi->vms.regs.es = POINTER_SEGMENT(palette_base); + vi->vms.regs.edx = POINTER_OFFSET(palette_base); + + code = VbeDoInterrupt10(vi); + if(code < 0) + return -1; + + j = 0; + i = 0; + while (number--) + { + entries[i++] = palette_scratch[j++] << 2; + entries[i++] = palette_scratch[j++] << 2; + entries[i++] = palette_scratch[j++] << 2; + entries[i++] = 0; + } + + Vm86ReleaseMemory (vi, mark); + + return 0; +} + +#define VGA_FB(vm) ((vm) < 8 ? 0xb8000 : 0xa0000) + +void * +VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size) +{ + *size = 0x10000 - bytes; + return &LM(vi,VGA_FB(vmode) + bytes); +} + +void * +VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *ret_phys) +{ + if (VGA_FB(vmode) == 0xa0000) + *size = 0x10000; + else + *size = 0x4000; + *ret_phys = VGA_FB(vmode); + return &LM(vi,VGA_FB(vmode)); +} + +void +VgaUnmapFramebuffer (Vm86InfoPtr vi) +{ +} diff --git a/xorg-server/hw/kdrive/vesa/vga.h b/xorg-server/hw/kdrive/vesa/vga.h new file mode 100644 index 000000000..9a368cef7 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vga.h @@ -0,0 +1,59 @@ +/* + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _VGA_H_ +#define _VGA_H_ + +int +VgaGetNmode (Vm86InfoPtr vi); + +int +VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode); + +int +VgaSetMode(Vm86InfoPtr vi, int mode); + +int +VgaGetMode (Vm86InfoPtr vi, int *mode); + +void +VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask); + +void +VgaSetReadPlaneMap(Vm86InfoPtr vi, int map); + +int +VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries); + +int +VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries); + +void * +VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size); + +void * +VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *phys); + +void +VgaUnmapFramebuffer (Vm86InfoPtr vi); + +#endif /* _VGA_H_ */ diff --git a/xorg-server/hw/kdrive/vesa/vm86.c b/xorg-server/hw/kdrive/vesa/vm86.c new file mode 100644 index 000000000..0f7bb2262 --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vm86.c @@ -0,0 +1,764 @@ +/* + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif +#include "vm86.h" + +#define PUSHW(vi, i) \ +{ vi->vms.regs.esp -= 2;\ + LMW(vi,MAKE_POINTER(vi->vms.regs.ss, vi->vms.regs.esp)) = i;} + +static int vm86old(struct vm86_struct *vms); +static int vm86_loop(Vm86InfoPtr vi); + +static const U8 rev_ints[32] = +{ 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x80, +}; + +static const U8 retcode_data[2] = +{ 0xCD, 0xFF }; + +Vm86InfoPtr +Vm86Setup(int mapHoles) +{ + int devmem = -1, devzero = -1; + void *magicMem, *loMem, *hiMem; + void *hole1, *hole2; + U32 stack_base, ret_code; + Vm86InfoPtr vi = NULL; + + devmem = open("/dev/mem", O_RDWR); + if(devmem < 0) { + perror("open /dev/mem"); + goto fail; + } + + devzero = open("/dev/zero", O_RDWR); + if(devzero < 0) { + perror("open /dev/zero"); + goto fail; + } + + magicMem = MAP_FAILED; + loMem = MAP_FAILED; + hiMem = MAP_FAILED; + hole1 = MAP_FAILED; + hole2 = MAP_FAILED; + + + magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devmem, MAGICMEM_BASE); + + if(magicMem == MAP_FAILED) { + ErrorF("Couldn't map magic memory\n"); + goto unmapfail; + } + + if(mapHoles) { + hole1 = mmap((void*)HOLE1_BASE, HOLE1_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, HOLE1_BASE); + + if(hole1 == MAP_FAILED) { + ErrorF("Couldn't map first hole\n"); + goto unmapfail; + } + } + + loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, LOMEM_BASE); + if(loMem == MAP_FAILED) { + ErrorF("Couldn't map low memory\n"); + munmap(magicMem, MAGICMEM_SIZE); + goto unmapfail; + } + + if(mapHoles) { + hole2 = mmap((void*)HOLE2_BASE, HOLE2_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_FIXED, devzero, HOLE2_BASE); + + if(hole2 == MAP_FAILED) { + ErrorF("Couldn't map first hole\n"); + goto unmapfail; + } + } + + hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, + devmem, HIMEM_BASE); + if(hiMem == MAP_FAILED) { + ErrorF("Couldn't map high memory\n"); + goto unmapfail; + } + + vi = xalloc(sizeof(Vm86InfoRec)); + if (!vi) + goto unmapfail; + + vi->magicMem = magicMem; + vi->hole1 = hole1; + vi->loMem = loMem; + vi->hole2 = hole2; + vi->hiMem = hiMem; + vi->brk = LOMEM_BASE; + + stack_base = Vm86AllocateMemory(vi, STACK_SIZE); + if(stack_base == ALLOC_FAIL) + goto unmapfail; + ret_code = Vm86AllocateMemory(vi, sizeof(retcode_data)); + if(ret_code == ALLOC_FAIL) + goto unmapfail; + + vi->stack_base = stack_base; + vi->ret_code = ret_code; + + memset(&vi->vms, 0, sizeof(struct vm86_struct)); + vi->vms.flags = 0; + vi->vms.screen_bitmap = 0; + vi->vms.cpu_type = CPU_586; + memcpy(&vi->vms.int_revectored, rev_ints, sizeof(rev_ints)); + + iopl(3); + + if(devmem >= 0) + close(devmem); + if(devzero >= 0) + close(devzero); + + return vi; + +unmapfail: + if(magicMem != MAP_FAILED) munmap(magicMem, MAGICMEM_SIZE); + if(hole1 != MAP_FAILED) munmap(hole1, HOLE1_SIZE); + if(loMem != MAP_FAILED) munmap(loMem, LOMEM_SIZE); + if(hole2 != MAP_FAILED) munmap(hole2, HOLE2_SIZE); + if(hiMem != MAP_FAILED) munmap(hiMem, HIMEM_SIZE); +fail: + if(devmem >= 0) + close(devmem); + if(devzero >= 0) + close(devzero); + if(vi) + xfree(vi); + return NULL; +} + +void +Vm86Cleanup(Vm86InfoPtr vi) +{ + if(vi->magicMem != MAP_FAILED) munmap(vi->magicMem, MAGICMEM_SIZE); + if(vi->hole1 != MAP_FAILED) munmap(vi->hole1, HOLE1_SIZE); + if(vi->loMem != MAP_FAILED) munmap(vi->loMem, LOMEM_SIZE); + if(vi->hole2 != MAP_FAILED) munmap(vi->hole2, HOLE2_SIZE); + if(vi->hiMem != MAP_FAILED) munmap(vi->hiMem, HIMEM_SIZE); + xfree(vi); +} + +int +Vm86DoInterrupt(Vm86InfoPtr vi, int num) +{ + U16 seg, off; + int code; + + if(num < 0 || num>256) { + ErrorF("Interrupt %d doesn't exist\n"); + return -1; + } + seg = MMW(vi,num * 4 + 2); + off = MMW(vi,num * 4); + if(MAKE_POINTER(seg, off) < ROM_BASE || + MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) { + ErrorF("Interrupt pointer (seg %x off %x) doesn't point at ROM\n", + seg, off); + return -1; + } + memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data)); + vi->vms.regs.eflags = IF_MASK | IOPL_MASK; + vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base); + vi->vms.regs.esp = STACK_SIZE; + PUSHW(vi, IF_MASK | IOPL_MASK); + PUSHW(vi, POINTER_SEGMENT(vi->ret_code)); + PUSHW(vi, POINTER_OFFSET(vi->ret_code)); + vi->vms.regs.cs = seg; + vi->vms.regs.eip = off; + OsBlockSignals (); + code = vm86_loop(vi); + OsReleaseSignals (); + if(code != 0) + return -1; + else + return 0; +} + +int +Vm86DoPOST(Vm86InfoPtr vi) +{ + U16 seg, off; + int code; + + seg = 0xC000; + off = 3; + if(MAKE_POINTER(seg, off) < ROM_BASE || + MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) { + ErrorF("BIOS pointer (seg %x off %x) doesn't point at ROM\n", + seg, off); + return -1; + } + memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data)); + vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base); + vi->vms.regs.esp = STACK_SIZE; + PUSHW(vi, POINTER_SEGMENT(vi->ret_code)); + PUSHW(vi, POINTER_OFFSET(vi->ret_code)); + vi->vms.regs.cs = seg; + vi->vms.regs.eip = off; + OsBlockSignals (); + code = vm86_loop(vi); + OsReleaseSignals (); + if(code != 0) + return -1; + else + return 0; +} + +#define DEBUG_VBE 0 +#if DEBUG_VBE +#define DBG(x) ErrorF x; usleep(10*1000) +#else +#define DBG(x) +#endif + +static inline U8 +vm86_inb(U16 port) +{ + U8 value; + + if (port != 0x3da) + { + DBG(("inb 0x%04x", port)); + } + asm volatile ("inb %w1,%b0" : "=a" (value) : "d" (port)); + if (port != 0x3da) + { + DBG((" = 0x%02x\n", value)); + } + return value; +} + +static inline U16 +vm86_inw(U16 port) +{ + U16 value; + DBG(("inw 0x%04x", port)); + asm volatile ("inw %w1,%w0" : "=a" (value) : "d" (port)); + DBG((" = 0x%04x\n", value)); + return value; +} + +static inline U32 +vm86_inl(U16 port) +{ + U32 value; + DBG(("inl 0x%04x", port)); + asm volatile ("inl %w1,%0" : "=a" (value) : "d" (port)); + DBG((" = 0x%08x\n", value)); + return value; +} + +static inline void +vm86_outb(U16 port, U8 value) +{ +#if 0 + static U8 CR; + + if (port == 0x3d4) + CR = value; + if (port == 0x3d5 && CR == 0xa4) + { + DBG(("outb 0x%04x = 0x%02x (skipped)\n", port, value)); + return; + } +#endif + DBG(("outb 0x%04x = 0x%02x\n", port, value)); + asm volatile ("outb %b0,%w1" : : "a" (value), "d" (port)); +} + +static inline void +vm86_outw(U16 port, U16 value) +{ + DBG(("outw 0x%04x = 0x%04x\n", port, value)); + asm volatile ("outw %w0,%w1" : : "a" (value), "d" (port)); +} + +static inline void +vm86_outl(U16 port, U32 value) +{ + DBG(("outl 0x%04x = 0x%08x\n", port, value)); + asm volatile ("outl %0,%w1" : : "a" (value), "d" (port)); +} + +#define SEG_CS 1 +#define SEG_DS 2 +#define SEG_ES 3 +#define SEG_SS 4 +#define SEG_GS 5 +#define SEG_FS 6 +#define REP 1 +#define REPNZ 2 +#define SET_8(_x, _y) (_x) = ((_x) & ~0xFF) | ((_y) & 0xFF); +#define SET_16(_x, _y) (_x) = ((_x) & ~0xFFFF) | ((_y) & 0xFFFF); +#define INC_IP(_i) SET_16(regs->eip, (regs->eip + _i)) +#define AGAIN INC_IP(1); goto again; + +static int +vm86_emulate(Vm86InfoPtr vi) +{ + struct vm86_regs *regs = &vi->vms.regs; + U8 opcode; + int size; + int pref_seg = 0, pref_rep = 0, pref_66 = 0, pref_67 = 0; + + again: + if(!Vm86IsMemory(vi, MAKE_POINTER(regs->cs, regs->eip))) { + ErrorF("Trying to execute unmapped memory\n"); + return -1; + } + opcode = Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip)); + switch(opcode) { + case 0x2E: pref_seg = SEG_CS; AGAIN; + case 0x3E: pref_seg = SEG_DS; AGAIN; + case 0x26: pref_seg = SEG_ES; AGAIN; + case 0x36: pref_seg = SEG_SS; AGAIN; + case 0x65: pref_seg = SEG_GS; AGAIN; + case 0x64: pref_seg = SEG_FS; AGAIN; + case 0x66: pref_66 = 1; AGAIN; + case 0x67: pref_67 = 1; AGAIN; + case 0xF2: pref_rep = REPNZ; AGAIN; + case 0xF3: pref_rep = REP; AGAIN; + + case 0xEC: /* IN AL, DX */ + SET_8(regs->eax, vm86_inb(regs->edx & 0xFFFF)); + INC_IP(1); + break; + case 0xED: /* IN AX, DX */ + if(pref_66) + regs->eax = vm86_inl(regs->edx & 0xFFFF); + else + SET_16(regs->eax, vm86_inw(regs->edx & 0xFFFF)); + INC_IP(1); + break; + case 0xE4: /* IN AL, imm8 */ + SET_8(regs->eax, + vm86_inb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)))); + INC_IP(2); + break; + case 0xE5: /* IN AX, imm8 */ + if(pref_66) + regs->eax = + vm86_inl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1))); + else + SET_16(regs->eax, + vm86_inw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)))); + INC_IP(2); + break; + case 0x6C: /* INSB */ + case 0x6D: /* INSW */ + if(opcode == 0x6C) { + Vm86WriteMemory(vi, MAKE_POINTER(regs->es, regs->edi), + vm86_inb(regs->edx & 0xFFFF)); + size = 1; + } else if(pref_66) { + Vm86WriteMemoryL(vi, MAKE_POINTER(regs->es, regs->edi), + vm86_inl(regs->edx & 0xFFFF)); + size = 4; + } else { + Vm86WriteMemoryW(vi, MAKE_POINTER(regs->es, regs->edi), + vm86_inw(regs->edx & 0xFFFF)); + size = 2; + } + if(regs->eflags & (1<<10)) + regs->edi -= size; + else + regs->edi += size; + if(pref_rep) { + if(pref_66) { + regs->ecx--; + if(regs->ecx != 0) + goto again; + } else { + SET_16(regs->ecx, regs->ecx - 1); + if((regs->ecx & 0xFFFF) != 0) + goto again; + } + } + INC_IP(1); + break; + + case 0xEE: /* OUT DX, AL */ + vm86_outb(regs->edx & 0xFFFF, regs->eax & 0xFF); + INC_IP(1); + break; + case 0xEF: /* OUT DX, AX */ + if(pref_66) + vm86_outl(regs->edx & 0xFFFF, regs->eax); + else + vm86_outw(regs->edx & 0xFFFF, regs->eax & 0xFFFF); + INC_IP(1); + break; + case 0xE6: /* OUT imm8, AL */ + vm86_outb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), + regs->eax & 0xFF); + INC_IP(2); + break; + case 0xE7: /* OUT imm8, AX */ + if(pref_66) + vm86_outl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), + regs->eax); + else + vm86_outw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)), + regs->eax & 0xFFFF); + INC_IP(2); + break; + case 0x6E: /* OUTSB */ + case 0x6F: /* OUTSW */ + if(opcode == 0x6E) { + vm86_outb(regs->edx & 0xFFFF, + Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi))); + size = 1; + } else if(pref_66) { + vm86_outl(regs->edx & 0xFFFF, + Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi))); + size = 4; + } else { + vm86_outw(regs->edx & 0xFFFF, + Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi))); + size = 2; + } + if(regs->eflags & (1<<10)) + regs->edi -= size; + else + regs->edi += size; + if(pref_rep) { + if(pref_66) { + regs->ecx--; + if(regs->ecx != 0) + goto again; + } else { + SET_16(regs->ecx, regs->ecx - 1); + if((regs->ecx & 0xFFFF) != 0) + goto again; + } + } + INC_IP(1); + break; + + case 0x0F: + ErrorF("Hit 0F trap in VM86 code\n"); + return -1; + case 0xF0: + ErrorF("Hit lock prefix in VM86 code\n"); + return -1; + case 0xF4: + ErrorF("Hit HLT in VM86 code\n"); + return -1; + + default: + ErrorF("Unhandled GP fault in VM86 code (opcode = 0x%02X)\n", + opcode); + return -1; + } + return 0; +} +#undef SEG_CS +#undef SEG_DS +#undef SEG_ES +#undef SEG_SS +#undef SEG_GS +#undef SEG_FS +#undef REP +#undef REPNZ +#undef SET_8 +#undef SET_16 +#undef INC_IP +#undef AGAIN + +static int +vm86_loop(Vm86InfoPtr vi) +{ + int code; + + while(1) { + code = vm86old(&vi->vms); + switch(VM86_TYPE(code)) { + case VM86_SIGNAL: + continue; + case VM86_UNKNOWN: + code = vm86_emulate(vi); + if(code < 0) { + Vm86Debug(vi); + return -1; + } + break; + case VM86_INTx: + if(VM86_ARG(code) == 0xFF) + return 0; + else { + PUSHW(vi, vi->vms.regs.eflags) + PUSHW(vi, vi->vms.regs.cs); + PUSHW(vi, vi->vms.regs.eip); + vi->vms.regs.cs = MMW(vi,VM86_ARG(code) * 4 + 2); + vi->vms.regs.eip = MMW(vi,VM86_ARG(code) * 4); + } + break; + case VM86_STI: + ErrorF("VM86 code enabled interrupts\n"); + Vm86Debug(vi); + return -1; + default: + if(code < 0) { + if(errno == ENOSYS) { + ErrorF("No vm86 support. Are you running on AMD64?\n"); + } else { + ErrorF("vm86 failed (%s).\n", strerror(errno)); + Vm86Debug(vi); + } + } else { + ErrorF("Unexpected result code 0x%X from vm86\n", code); + Vm86Debug(vi); + } + return -1; + } + } +} + +int +Vm86IsMemory(Vm86InfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return 1; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return 1; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return 1; + else + return 0; +} + +U8 +Vm86Memory(Vm86InfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return MM(vi, i); + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return LM(vi, i); + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return HM(vi, i); + else { + ErrorF("Reading unmapped memory at 0x%08X\n", i); + return 0; + } +} + +U16 +Vm86MemoryW(Vm86InfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return MMW(vi, i); + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return LMW(vi, i); + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return HMW(vi, i); + else { + ErrorF("Reading unmapped memory at 0x%08X\n", i); + return 0; + } +} + +U32 +Vm86MemoryL(Vm86InfoPtr vi, U32 i) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + return MML(vi, i); + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + return LML(vi, i); + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + return HML(vi, i); + else { + ErrorF("Reading unmapped memory at 0x%08X\n", i); + return 0; + } +} + +void +Vm86WriteMemory(Vm86InfoPtr vi, U32 i, U8 val) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + MM(vi, i) = val; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + LM(vi, i) = val; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + HM(vi, i) = val; + else { + ErrorF("Writing unmapped memory at 0x%08X\n", i); + } +} + +void +Vm86WriteMemoryW(Vm86InfoPtr vi, U32 i, U16 val) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + MMW(vi, i) = val; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + LMW(vi, i) = val; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + HMW(vi, i) = val; + else { + ErrorF("Writing unmapped memory at 0x%08X\n", i); + } +} + +void +Vm86WriteMemoryL(Vm86InfoPtr vi, U32 i, U32 val) +{ + if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE) + MML(vi, i) = val; + else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE) + LML(vi, i) = val; + else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE) + HML(vi, i) = val; + else { + ErrorF("Writing unmapped memory at 0x%08X\n", i); + } +} + +int +Vm86AllocateMemory(Vm86InfoPtr vi, int n) +{ + int ret; + if(n<0) { + ErrorF("Asked to allocate negative amount of memory\n"); + return vi->brk; + } + + n = (n + 15) & ~15; + if(vi->brk + n > LOMEM_BASE + LOMEM_SIZE) { + ErrorF("Out of low memory\n"); + exit(2); + } + ret = vi->brk; + vi->brk += n; + return ret; +} + +int +Vm86MarkMemory (Vm86InfoPtr vi) +{ + return vi->brk; +} + +void +Vm86ReleaseMemory (Vm86InfoPtr vi, int mark) +{ + vi->brk = mark; +} + +static int +vm86old(struct vm86_struct *vm) +{ + int res; + + asm volatile ( + "pushl %%ebx\n\t" + "movl %2, %%ebx\n\t" + "movl %1,%%eax\n\t" + "int $0x80\n\t" + "popl %%ebx" + : "=a" (res) : "n" (113), "r" (vm)); + if(res < 0) { + errno = -res; + res = -1; + } else + errno = 0; + return res; +} + +void +Vm86Debug(Vm86InfoPtr vi) +{ + struct vm86_regs *regs = &vi->vms.regs; + int i; + + ErrorF("eax=0x%08lX ebx=0x%08lX ecx=0x%08lX edx=0x%08lX\n", + regs->eax, regs->ebx, regs->ecx, regs->edx); + ErrorF("esi=0x%08lX edi=0x%08lX ebp=0x%08lX\n", + regs->esi, regs->edi, regs->ebp); + ErrorF("eip=0x%08lX esp=0x%08lX eflags=0x%08lX\n", + regs->eip, regs->esp, regs->eflags); + ErrorF("cs=0x%04lX ds=0x%04lX es=0x%04lX fs=0x%04lX gs=0x%04lX\n", + regs->cs, regs->ds, regs->es, regs->fs, regs->gs); + for(i=-7; i<8; i++) { + ErrorF(" %s%02X", + i==0?"->":"", + Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip + i))); + } + ErrorF("\n"); +} + +#ifdef NOT_IN_X_SERVER +static void +ErrorF(char *f, ...) +{ + va_list args; + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); +} +#endif diff --git a/xorg-server/hw/kdrive/vesa/vm86.h b/xorg-server/hw/kdrive/vesa/vm86.h new file mode 100644 index 000000000..81693081a --- /dev/null +++ b/xorg-server/hw/kdrive/vesa/vm86.h @@ -0,0 +1,180 @@ +/* + * Copyright © 2000 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ +/* +Copyright (c) 2000 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#ifndef _VM86_H_ +#define _VM86_H_ + +#include <stdlib.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/vm86.h> +#include <sys/io.h> + +#ifdef NOT_IN_X_SERVER +#include <stdio.h> +#include <stdarg.h> +#include <malloc.h> +static void ErrorF(char*, ...); +#define xalloc(a) malloc(a) +#define xcalloc(a,b) calloc(a,b) +#define xfree(a) free(a) +#else +#include <X11/X.h> +#include <X11/Xproto.h> +#include <X11/Xos.h> +#include "os.h" +#endif + +#ifndef IF_MASK +#define IF_MASK X86_EFLAGS_IF +#endif +#ifndef IOPL_MASK +#define IOPL_MASK X86_EFLAGS_IOPL +#endif + +typedef unsigned char U8; +typedef unsigned short U16; +typedef unsigned int U32; + +/* The whole addressable memory */ +#define SYSMEM_BASE 0x00000 +#define SYSMEM_SIZE 0x100000 + +/* Interrupt vectors and BIOS data area */ +/* This is allocated privately from /dev/mem */ +#define MAGICMEM_BASE 0x00000 +#define MAGICMEM_SIZE 0x01000 + +/* The low memory, allocated privately from /dev/zero */ +/* 64KB should be enough for anyone, as they used to say */ +#define LOMEM_BASE 0x10000 +#define LOMEM_SIZE 0x10000 + +/* The video memory and BIOS ROM, allocated shared from /dev/mem */ +#define HIMEM_BASE 0xA0000 +#define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE) + +#define HOLE1_BASE (MAGICMEM_BASE + MAGICMEM_SIZE) +#define HOLE1_SIZE (LOMEM_BASE - HOLE1_BASE) + +#define HOLE2_BASE (LOMEM_BASE + LOMEM_SIZE) +#define HOLE2_SIZE (HIMEM_BASE - HOLE2_BASE) + +/* The BIOS ROM */ +#define ROM_BASE 0xC0000 +#define ROM_SIZE 0x30000 + +#define STACK_SIZE 0x1000 + +#define POINTER_SEGMENT(ptr) (((unsigned int)ptr)>>4) +#define POINTER_OFFSET(ptr) (((unsigned int)ptr)&0x000F) +#define MAKE_POINTER(seg, off) (((((unsigned int)(seg))<<4) + (unsigned int)(off))) +#define MAKE_POINTER_1(lw) MAKE_POINTER(((lw)&0xFFFF0000)/0x10000, (lw)&0xFFFF) +#define ALLOC_FAIL ((U32)-1) + +typedef struct _Vm86InfoRec { + void *magicMem, *loMem, *hiMem; + void *hole1, *hole2; + U32 brk; + struct vm86_struct vms; + U32 ret_code, stack_base; +} Vm86InfoRec, *Vm86InfoPtr; + +#define LM(vi,i) (((char*)vi->loMem)[i-LOMEM_BASE]) +#define LMW(vi,i) (*(U16*)(&LM(vi,i))) +#define LML(vi,i) (*(U32*)(&LM(vi,i))) +#define MM(vi,i) (((char*)vi->magicMem)[i-MAGICMEM_BASE]) +#define MMW(vi,i) (*(U16*)(&MM(vi,i))) +#define MML(vi,i) (*(U32*)(&MM(vi,i))) +#define HM(vi,i) (((char*)vi->hiMem)[i-HIMEM_BASE]) +#define HMW(vi,i) (*(U16*)(&MM(vi,i))) +#define HML(vi,i) (*(U32*)(&MM(vi,i))) + +Vm86InfoPtr +Vm86Setup(int); + +void +Vm86Cleanup(Vm86InfoPtr vi); + +int +Vm86DoInterrupt(Vm86InfoPtr vi, int num); + +int +Vm86DoPOST(Vm86InfoPtr vi); + +int +Vm86IsMemory(Vm86InfoPtr vi, U32 i); + +U8 +Vm86Memory(Vm86InfoPtr, U32); + +U16 +Vm86MemoryW(Vm86InfoPtr, U32); + +U32 +Vm86MemoryL(Vm86InfoPtr, U32); + +void +Vm86WriteMemory(Vm86InfoPtr, U32, U8); + +void +Vm86WriteMemoryW(Vm86InfoPtr, U32, U16); + +void +Vm86WriteMemoryL(Vm86InfoPtr, U32, U32); + +int +Vm86AllocateMemory(Vm86InfoPtr, int); + +int +Vm86MarkMemory (Vm86InfoPtr vi); + +void +Vm86ReleaseMemory (Vm86InfoPtr vi, int mark); + +void +Vm86Debug(Vm86InfoPtr vi); + +#endif /* _VM86_H_ */ |