DOSBox for Windows, as of 3 May 2009, from the DOSBox CVS on SourceForge. Version 0.72 + many CVS changes, probably close to 0.73 release.

This commit is contained in:
Carl.Kenner 2009-05-02 23:02:35 +00:00
parent 4aae6033fc
commit d64459fd7a
331 changed files with 145873 additions and 150382 deletions

View File

@ -1,548 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
# Main Makefile for DOSBox
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
EXTRA_DIST = autogen.sh
SUBDIRS = src include docs visualc_net
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \
COPYING ChangeLog INSTALL Makefile.am NEWS THANKS acinclude.m4 \
aclocal.m4 config.guess config.h.in config.sub configure \
configure.in depcomp install-sh missing mkinstalldirs
DIST_SUBDIRS = $(SUBDIRS)
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOHEADER)
touch $(srcdir)/config.h.in
distclean-hdr:
-rm -f config.h stamp-h1
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = .
distdir = $(PACKAGE)-$(VERSION)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
$(am__remove_distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
&& rm -f $(distdir).tar.gz \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
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:
-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-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-recursive ctags ctags-recursive dist \
dist-all dist-gzip distcheck distclean distclean-generic \
distclean-hdr distclean-recursive distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am dvi-recursive info \
info-am info-recursive install install-am install-data \
install-data-am install-data-recursive install-exec \
install-exec-am install-exec-recursive install-info \
install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \
ps-recursive tags tags-recursive uninstall uninstall-am \
uninstall-info-am uninstall-info-recursive uninstall-recursive
# 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:

439
README
View File

@ -40,7 +40,7 @@ INDEX:
Type INTRO in DOSBox for a quick tour. Type INTRO in DOSBox for a quick tour.
It is essential that you get familiar with the idea of mounting, It is essential that you get familiar with the idea of mounting,
DOSBox does not automatically make any drive (or parts of it) DOSBox does not automatically make any drive (or a part of it)
accessible to the emulation. accessible to the emulation.
See the FAQ entry "I've got a Z instead of a C at the prompt" as See the FAQ entry "I've got a Z instead of a C at the prompt" as
well as the description of the MOUNT command (section 4). well as the description of the MOUNT command (section 4).
@ -57,14 +57,15 @@ Q: I've got a Z instead of a C at the prompt.
Q: Do I always have to type these commands? Automation? Q: Do I always have to type these commands? Automation?
Q: How do I change to fullscreen? Q: How do I change to fullscreen?
Q: My CD-ROM doesn't work. Q: My CD-ROM doesn't work.
Q: The game/application can't find its CD-ROM.
Q: The mouse doesn't work. Q: The mouse doesn't work.
Q: There is no sound. Q: There is no sound.
Q: The sound stutters or sounds stretched/weird. Q: The sound stutters or sounds stretched/weird.
Q: I can't type \ or : in DOSBox. Q: I can't type \ or : in DOSBox.
Q: The keyboard lags. Q: The keyboard lags.
Q: The cursor always moves into one direction! Q: The cursor always moves into one direction!
Q: The game/application can't find its CD-ROM.
Q: The game/application runs much too slow! Q: The game/application runs much too slow!
Q: The game/application does not run at all/crashes!
Q: Can DOSBox harm my computer? Q: Can DOSBox harm my computer?
Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ. Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ.
Q: What sound hardware does DOSBox presently emulate? Q: What sound hardware does DOSBox presently emulate?
@ -102,18 +103,43 @@ Q: My CD-ROM doesn't work.
A: To mount your CD-ROM in DOSBox you have to specify some additional options A: To mount your CD-ROM in DOSBox you have to specify some additional options
when mounting the CD-ROM. when mounting the CD-ROM.
To enable CD-ROM support (includes MSCDEX): To enable CD-ROM support (includes MSCDEX):
- mount d f:\ -t cdrom - mount d f:\ -t cdrom (windows)
To enable low-level CD-ROM-support (uses ioctl if possible): - mount d /media/cdrom -t cdrom (linux)
- mount d f:\ -t cdrom -usecd 0
To enable low-level SDL-support: In some cases you might want to use a different CD-ROM interface,
- mount d f:\ -t cdrom -usecd 0 -noioctl for example if CD audio does not work:
To enable low-level aspi-support (win98 with aspi-layer installed): To enable SDL-support (does not include low-level CD access!):
- mount d f:\ -t cdrom -usecd 0 -aspi - mount d f:\ -t cdrom -usecd 0 -noioctl
To enable ioctl access using digital audio extraction for CD audio
(windows-only, useful for Vista):
- mount d f:\ -t cdrom -ioctl_dx
To enable ioctl access using MCI for CD audio (windows-only):
- mount d f:\ -t cdrom -ioctl_mci
To force ioctl-only access (windows-only):
- mount d f:\ -t cdrom -ioctl_dio
To enable low-level aspi-support (win98 with aspi-layer installed):
- mount d f:\ -t cdrom -aspi
In the commands: - d driveletter you will get in DOSBox In the commands: - d driveletter you will get in DOSBox
- f:\ location of CD-ROM on your PC. - f:\ location of CD-ROM on your PC.
- 0 The number of the CD-ROM drive, reported by mount -cd - 0 The number of the CD-ROM drive, reported by "mount -cd"
See also the question: The game/application can't find its CD-ROM. (note that this value is only needed when using SDL
for CD audio, otherwise it is ignored)
See also the next question: The game/application can't find its CD-ROM.
Q: The game/application can't find its CD-ROM.
A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the
MSCDEX interface required by DOS games to interface with CD-ROMs.
Also try adding the correct label (-label LABEL) to the mount command,
where LABEL is the CD-label (volume ID) of the CD-ROM.
Under Windows you can specify -ioctl, -aspi or -noioctl. Look at the
description of the mount command in Section 4 for their meaning and the
additional audio-CD related options -ioctl_dx, ioctl_mci, ioctl_dio.
Try creating a CD-ROM image (preferably CUE/BIN pair) and use the
DOSBox-internal IMGMOUNT tool to mount the image (the CUE sheet).
This enables very good low-level CD-ROM support on any operating system.
Q: The mouse doesn't work. Q: The mouse doesn't work.
@ -135,6 +161,9 @@ A: Be sure that the sound is correctly configured in the game. This might be
If you still don't get any sound set the core to normal and use some lower If you still don't get any sound set the core to normal and use some lower
fixed cycles value (like cycles=2000). Also assure that your host operating fixed cycles value (like cycles=2000). Also assure that your host operating
sound does provide sound. sound does provide sound.
In certain cases it might be useful to use a different emulated sound device
like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or
the gravis ultrasound (gus=true).
Q: The sound stutters or sounds stretched/weird. Q: The sound stutters or sounds stretched/weird.
@ -142,52 +171,41 @@ A: You're using too much CPU power to keep DOSBox running at the current speed.
You can lower the cycles, skip frames, reduce the sampling rate of You can lower the cycles, skip frames, reduce the sampling rate of
the respective sound device (see the DOSBox configuration file) or the respective sound device (see the DOSBox configuration file) or
the mixer device. You can also increase the prebuffer in the configfile. the mixer device. You can also increase the prebuffer in the configfile.
If you are using cycles=max or =auto, then make sure that there no If you are using cycles=max or =auto, then make sure that there is no
background processes interfering! (especially if they access the harddisk) background processes interfering! (especially if they access the harddisk)
Q: I can't type \ or : in DOSBox. Q: I can't type \ or : in DOSBox.
A: This is a known problem. It only occurs if your keyboard layout isn't US. A: This can happen in various cases, like your host keyboard layout does not
have a matching DOS layout representation (or it was not correctly detected),
or the key mapping is wrong.
Some possible fixes: Some possible fixes:
1. Switch the keyboard layout of your operating system. 1. Use / instead, or ALT-58 for : and ALT-92 for \.
2. Use / instead. 2. Change the DOS keyboard layout (see Section 7: Keyboard Layout).
3. Open dosbox.conf and change usescancodes=false to usescancodes=true. 3. Add the commands you want to execute to the [autoexec]-section
4. Add the commands you want to execute to the "configfile". of the DOSBox configuration file.
5. Change the DOS keyboard layout (see Section 7 Keyboard Layout). 4. Open the DOSBox configuration file and change the usescancodes entry.
6. Use ALT-58 for : and ALT-92 for \. 5. Switch the keyboard layout of your operating system.
7. for \ try the keys around "enter". For ":" try shift and the keys
between "enter" and "l" (US keyboard layout). Note that if the host layout can not be identified, or keyboardlayout is set
8. Try keyb.com from FreeDOS (http://projects.freedos.net/keyb/). to none in the DOSBox configuration file, the standard US layout is used.
Look for keyb2.0 pre4 as older and newer versions are known to In this configuration try the keys around "enter" for the key \ (backslash),
have a bug in the loader routines. and for the key : (colon) use shift and the keys between "enter" and "l".
Q: The keyboard lags. Q: The keyboard lags.
A: Lower the priority setting in the DOSBox configuration file A: Lower the priority setting in the DOSBox configuration file, for example
like set "priority=normal,normal". You might also want to set "priority=normal,normal". You might also want to try lowering the cycles
try lowering the cycles. (use a fixed cycle count to start with, like cycles=10000).
Q: The cursor always moves into one direction! Q: The cursor always moves into one direction!
A: See if it still happens if you disable the joystick emulation, A: See if it still happens if you disable the joystick emulation,
set joysticktype=none in the [joystick] section of your DOSBox set joysticktype=none in the [joystick] section of your DOSBox
configuration file. Maybe also try unplugging any joystick. configuration file. Maybe also try unplugging any joystick/gamepad.
If you want to use the joystick in the game, try setting timed=false If you want to use the joystick in the game, try setting timed=false
and be sure to calibrate the joystick (both in your OS as well as and be sure to calibrate the joystick (both in your OS as well as
in the game or the game's setup). in the game or the game's setup program).
Q: The game/application can't find its CD-ROM.
A: Be sure to mount the CD-ROM with -t cdrom switch, this will enable the
MSCDEX interface required by DOS games to interface with CD-ROMs.
Also try adding the correct label (-label LABEL). To enable lower-level
CD-ROM support, add the following switch to mount: -usecd #, where # is
the number of your CD-ROM drive reported by mount -cd. Under Windows you
can specify -ioctl, -aspi or -noioctl. Look at the description elsewhere
in this document for their meaning.
Try creating a CD-ROM image (preferably CUE/BIN pair) and use the
DOSBox-internal IMGMOUNT tool to mount the image. This enables very
good low-level CD-ROM support on any operating system.
Q: The game/application runs much too slow! Q: The game/application runs much too slow!
@ -195,6 +213,10 @@ A: Look at the section "How to run resource-demanding games" for more
information. information.
Q: The game/application does not run at all/crashes!
A: Look at Section 10: Troubleshooting
Q: Can DOSBox harm my computer? Q: Can DOSBox harm my computer?
A: DOSBox can not harm your computer more than any other resource demanding A: DOSBox can not harm your computer more than any other resource demanding
program. Increasing the cycles does not overclock your real CPU. program. Increasing the cycles does not overclock your real CPU.
@ -206,6 +228,7 @@ Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ.
A: This is possible! Just create a config file: config -writeconf configfile. A: This is possible! Just create a config file: config -writeconf configfile.
Start your favourite editor and look through the settings. To start DOSBox Start your favourite editor and look through the settings. To start DOSBox
with your new settings: dosbox -conf configfile with your new settings: dosbox -conf configfile
See the description of the config command in Section 4 for more details.
Q: What sound hardware does DOSBox presently emulate? Q: What sound hardware does DOSBox presently emulate?
@ -228,7 +251,7 @@ A: DOSBox emulates several legacy sound devices:
- Adlib - Adlib
Borrowed from MAME, this emulation is almost perfect and includes the Borrowed from MAME, this emulation is almost perfect and includes the
Adlib's ability to almost play digitized sound. Adlib's ability to almost play digitized sound.
- SoundBlaster 16/ SoundBlaster Pro I & II /SoundBlaster I & II - SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II
By default DOSBox provides Soundblaster 16 level 16-bit stereo sound. By default DOSBox provides Soundblaster 16 level 16-bit stereo sound.
You can select a different SoundBlaster version in the configfile of You can select a different SoundBlaster version in the configfile of
DOSBox (See Internal Commands: CONFIG). DOSBox (See Internal Commands: CONFIG).
@ -252,12 +275,12 @@ Q: Great README, but I still don't get it.
A: A look at "The Newbie's pictorial guide to DOSBox" located at A: A look at "The Newbie's pictorial guide to DOSBox" located at
http://vogons.zetafleet.com/viewforum.php?f=39 might help you. http://vogons.zetafleet.com/viewforum.php?f=39 might help you.
Also try the wiki of DOSBox: Also try the wiki of DOSBox:
http://dosbox.sourceforge.net/wiki/ http://www.dosbox.com/wiki/
For more questions read the remainder of this README and/or check For more questions read the remainder of this README and/or check
the site/forum: the site/forum:
http://dosbox.sourceforge.net http://www.dosbox.com
@ -267,13 +290,15 @@ http://dosbox.sourceforge.net
An overview of the command line options you can give to DOSBox. An overview of the command line options you can give to DOSBox.
Windows Users must open cmd.exe or command.com or edit the shortcut to Windows Users must open cmd.exe or command.com or edit the shortcut to
DOSBox.exe for this. dosbox.exe for this.
The options are valid for all operating systems unless noted in the option The options are valid for all operating systems unless noted in the option
description: description:
dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile] dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
[-lang languagefile] [-machine machinetype] [-noconsole] [-lang languagefile] [-machine machinetype] [-noconsole]
[-startmapper] [-noautoexec] [-scaler scaler | -forcescaler scaler] [-startmapper] [-noautoexec] [-securemode]
[-scaler scaler | -forcescaler scaler]
[-version]
dosbox -version dosbox -version
@ -287,7 +312,7 @@ dosbox -version
-c command -c command
Runs the specified command before running "name". Multiple commands Runs the specified command before running "name". Multiple commands
can be specified. Each command should start with "-c", though. can be specified. Each command should start with "-c" though.
A command can be: an Internal Program, a DOS command or an executable A command can be: an Internal Program, a DOS command or an executable
on a mounted drive. on a mounted drive.
@ -297,15 +322,20 @@ dosbox -version
-conf configfile -conf configfile
Start DOSBox with the options specified in "configfile". Start DOSBox with the options specified in "configfile".
Multiple -conf options may be present. Multiple -conf options may be present.
See Chapter 10 for more details. See Section 11 for more details.
-lang languagefile -lang languagefile
Start DOSBox using the language specified in "languagefile". Start DOSBox using the language specified in "languagefile".
-machine machinetype -machine machinetype
Setup DOSBox to emulate a specific type of machine. Valid choices are: Setup DOSBox to emulate a specific type of machine. Valid choices are:
hercules, cga, pcjr, tandy, vga (default). The machinetype affects hercules, cga, pcjr, tandy, svga_s3 (default) as well as the additional
both the videocard and the available soundcards. svga chipsets listed in the help of the DOSBox configuration file.
svga_s3 enables vesa emulation as well.
For some special vga effects the machinetype vgaonly can be used,
note that this disables svga capabilites and might be (considerably)
slower due to the much higher emulation precision.
The machinetype affects both the videocard and the available soundcards.
-noconsole (Windows Only) -noconsole (Windows Only)
Start DOSBox without showing the console window. Output will Start DOSBox without showing the console window. Output will
@ -318,6 +348,11 @@ dosbox -version
-noautoexec -noautoexec
Skips the [autoexec] section of the loaded configuration file. Skips the [autoexec] section of the loaded configuration file.
-securemode
Same as -noautoexec, but adds config.com -securemode at the
bottom of AUTOEXEC.BAT (which in turn disables any changes to how
the drives are mounted inside DOSBox).
-scaler scaler -scaler scaler
Uses the scaler specified by "scaler". See the DOSBox configuration Uses the scaler specified by "scaler". See the DOSBox configuration
file for the available scalers. file for the available scalers.
@ -332,14 +367,14 @@ dosbox -version
Note: If a name/command/configfile/languagefile contains a space, put Note: If a name/command/configfile/languagefile contains a space, put
the whole name/command/configfile/languagefile between quotes the whole name/command/configfile/languagefile between quotes
("command or file name"). If you need to use quotes within quotes ("command or file name"). If you need to use quotes within quotes
(most likely with -c and mount). (most likely with -c and mount):
Windows and OS/2 users can use single quotes inside the double quotes. Windows and OS/2 users can use single quotes inside the double quotes.
Other people should be able to use escaped double quotes inside the Other people should be able to use escaped double quotes inside the
double quotes. double quotes.
win -c "mount c 'c:\program files\'" Windows: -c "mount c 'c:\program files\'"
linux -c "mount c \"/tmp/name with space\"" Linux: -c "mount c \"/tmp/name with space\""
For example: For example (Windows):
dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES"
This mounts c:\atlantis as c:\ and runs atlantis.exe. This mounts c:\atlantis as c:\ and runs atlantis.exe.
@ -393,11 +428,11 @@ MOUNT -u "Emulated Drive letter"
-label drivelabel -label drivelabel
Sets the name of the drive to "drivelabel". Needed on some Sets the name of the drive to "drivelabel". Needed on some
systems if the cd label isn't read correctly. Useful when a systems if the CD-ROM label isn't read correctly (useful when a
program can't find its CD-ROM. If you don't specify a label and no program can't find its CD-ROM). If you don't specify a label and no
lowlevel support is selected (that is omitting the -usecd # and/or lowlevel support is selected (that is omitting the -usecd # and/or
-aspi parameters or specifying -noioctl): -aspi parameters, or specifying -noioctl):
For win32: label is extracted from "Real Drive". For Windows: label is extracted from "Real Drive".
For Linux: label is set to NO_LABEL. For Linux: label is set to NO_LABEL.
If you do specify a label, this label will be kept as long as the drive If you do specify a label, this label will be kept as long as the drive
@ -407,19 +442,29 @@ MOUNT -u "Emulated Drive letter"
Forces use of the aspi layer. Only valid if mounting a CD-ROM under Forces use of the aspi layer. Only valid if mounting a CD-ROM under
Windows systems with an ASPI-Layer. Windows systems with an ASPI-Layer.
-ioctl -ioctl (automatic selection of the CD audio interface)
-ioctl_dx (digital audio extraction used for CD audio)
-ioctl_dio (ioctl calls used for CD audio)
-ioctl_mci (MCI used for CD audio)
Forces use of ioctl commands. Only valid if mounting a CD-ROM under Forces use of ioctl commands. Only valid if mounting a CD-ROM under
a Windows OS which support them (Win2000/XP/NT). a Windows OS which support them (Win2000/XP/NT).
The various choices only differ in the way CD audio is handled,
preferrably -ioctl_dio is used (lowest workload), but this might not
work on all systems so -ioctl_dx (or -ioctl_mci) can be used.
-noioctl -noioctl
Forces use of the SDL CD-ROM layer. Valid on all systems. Forces use of the SDL CD-ROM layer. Valid on all systems.
-usecd number -usecd number
Forces use of SDL CD-ROM support for drive number. Valid on all systems, under windows the -noioctl switch has to be
Number can be found by -cd. Valid on all systems. present to make use of the -usecd switch.
Enables to select the drive that should be used by SDL. Use this if
the wrong or no CD-ROM drive is mounted while using the SDL CD-ROM
interface. "number" can be found by "MOUNT -cd".
-cd -cd
Displays all detected CD-ROM drives and their numbers. Use with -usecd. Displays all CD-ROM drives detected by SDL, and their numbers.
See the information at the -usecd entry above.
-u -u
Removes the mount. Doesn't work for Z:\. Removes the mount. Doesn't work for Z:\.
@ -429,7 +474,7 @@ MOUNT -u "Emulated Drive letter"
Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC. Basically MOUNT allows you to connect real hardware to DOSBox's emulated PC.
So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive C: So MOUNT C C:\GAMES tells DOSBox to use your C:\GAMES directory as drive C:
in DOSBox. It also allows you to change the drive's letter identification in DOSBox. It also allows you to change the drive letter identification
for programs that demand specific drive letters. for programs that demand specific drive letters.
For example: Touche: Adventures of The Fifth Musketeer must be run on your C: For example: Touche: Adventures of The Fifth Musketeer must be run on your C:
@ -441,41 +486,52 @@ MOUNT -u "Emulated Drive letter"
Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same Mounting your entire C drive with MOUNT C C:\ is NOT recommended! The same
is true for mounting the root of any other drive, except for CD-ROMs (due to is true for mounting the root of any other drive, except for CD-ROMs (due to
their read-only nature). Otherwise if you or DOSBox make a mistake you may their read-only nature). Otherwise if you or DOSBox make a mistake you may
loose all your files. lose all your files.
It is recommended to put all your applications/games into a subdirectory It is recommended to put all your applications/games into a subdirectory
and mount that. and mount that.
General MOUNT Examples: General MOUNT Examples:
1. To mount c:\DirX as a floppy : 1. To mount c:\DirX as a floppy :
mount a c:\DirX -t floppy mount a c:\DirX -t floppy
2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox: 2. To mount system CD-ROM drive E as CD-ROM drive D in DOSBox:
mount d e:\ -t cdrom mount d e:\ -t cdrom
3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D 3. To mount system CD-ROM drive at mountpoint /media/cdrom as CD-ROM drive D
in DOSBox: in DOSBox:
mount d /media/cdrom -t cdrom -usecd 0 mount d /media/cdrom -t cdrom -usecd 0
4. To mount a drive with ~870 mb free diskspace (simple version): 4. To mount a drive with ~870 mb free diskspace (simple version):
mount c d:\ -freesize 870 mount c d:\ -freesize 870
5. To mount a drive with ~870 mb free diskspace (experts only, full control): 5. To mount a drive with ~870 mb free diskspace (experts only, full control):
mount c d:\ -size 512,127,16513,13500 mount c d:\ -size 512,127,16513,13500
6. To mount /home/user/dirY as drive C in DOSBox: 6. To mount /home/user/dirY as drive C in DOSBox:
mount c /home/user/dirY mount c /home/user/dirY
7. To mount the directory where DOSBox was started as D in DOSBox: 7. To mount the directory where DOSBox was started as D in DOSBox:
mount d . mount d .
(note the . which represents the directory where DOSBox was started)
MEM MEM
Program to display the amount of free memory. Program to display the amount of free memory.
VER
VER set major_version [minor_version]
Display the current DOSBox version and reported DOS version
(parameterless usage).
Change the reported DOS version with the "set" parameter,
for example: "VER set 6 22" to have DOSBox report DOS 6.22
as version number.
CONFIG -writeconf localfile CONFIG -writeconf localfile
CONFIG -writelang localfile CONFIG -writelang localfile
CONFIG -securemode
CONFIG -set "section property=value" CONFIG -set "section property=value"
CONFIG -get "section property" CONFIG -get "section property"
CONFIG can be used to change or query various settings of DOSBox CONFIG can be used to change or query various settings of DOSBox
during runtime. It can save the current settings and language strings to during runtime. It can save the current settings and language strings to
disk. Information about all possible sections and properties can disk. Information about all possible sections and properties can
be found in section 11 (The Config File). be found in Section 11 (The Config File).
-writeconf localfile -writeconf localfile
Write the current configuration settings to file. "localfile" is Write the current configuration settings to file. "localfile" is
@ -483,7 +539,7 @@ CONFIG -get "section property"
The configuration file controls various settings of DOSBox: The configuration file controls various settings of DOSBox:
the amount of emulated memory, the emulated soundcards and many more the amount of emulated memory, the emulated soundcards and many more
things. It allows access to AUTOEXEC.BAT as well. things. It allows access to AUTOEXEC.BAT as well.
See section 11 (The Config File) for more information. See Section 11 (The Config File) for more information.
-writelang localfile -writelang localfile
Write the current language settings to file. "localfile" is Write the current language settings to file. "localfile" is
@ -491,8 +547,14 @@ CONFIG -get "section property"
The language file controls all visible output of the internal commands The language file controls all visible output of the internal commands
and the internal DOS. and the internal DOS.
-securemode
Switches DOSBox to a more secure mode. In this mode the internal
commands MOUNT, IMGMOUNT and BOOT won't work. It's not possible either
to create a new configfile or languagefile in this mode.
(Warning: you can only undo this mode by restarting DOSBox.)
-set "section property=value" -set "section property=value"
CONFIG will attempt to set the property to new value. At this moment CONFIG will attempt to set the property to new value. Currently
CONFIG can not report whether the command succeeded or not. CONFIG can not report whether the command succeeded or not.
-get "section property" -get "section property"
@ -504,20 +566,20 @@ CONFIG -get "section property"
own preferences for each game. own preferences for each game.
Examples: Examples:
1. To create a configfile in your current directory: 1. To create a configfile in your current directory:
config -writeconf dosbox.conf config -writeconf dosbox.conf
2. To set the cpu cycles to 10000: 2. To set the cpu cycles to 10000:
config -set "cpu cycles=10000" config -set "cpu cycles=10000"
3. To turn ems memory emulation off: 3. To turn ems memory emulation off:
config -set "dos ems=off" config -set "dos ems=off"
4. To check which cpu core is being used. 4. To check which cpu core is being used.
config -get "cpu core" config -get "cpu core"
LOADFIX [-size] [program] [program-parameters] LOADFIX [-size] [program] [program-parameters]
LOADFIX -f LOADFIX -f
Program to reduce the amount of memory available. Useful for old programs Program to reduce the amount of available conventional memory.
which don't expect much memory to be free. Useful for old programs which don't expect much memory to be free.
-size -size
number of kilobytes to "eat up", default = 64kb number of kilobytes to "eat up", default = 64kb
@ -525,14 +587,14 @@ LOADFIX -f
-f -f
frees all previously allocated memory frees all previously allocated memory
Examples: Examples:
1. To start mm2.exe and allocate 64kb memory 1. To start mm2.exe and allocate 64kb memory
(mm2 will have 64 kb less available) : (mm2 will have 64 kb less available) :
loadfix mm2 loadfix mm2
2. To start mm2.exe and allocate 32kb memory : 2. To start mm2.exe and allocate 32kb memory :
loadfix -32 mm2 loadfix -32 mm2
3. To free previous allocated memory : 3. To free previous allocated memory :
loadfix -f loadfix -f
RESCAN RESCAN
@ -547,11 +609,13 @@ MIXER
mixer channel left:right [/NOSHOW] [/LISTMIDI] mixer channel left:right [/NOSHOW] [/LISTMIDI]
channel channel
Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM. Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM [, CDAUDIO].
CDAUDIO is only available if a CD-ROM interface with volume control is
enabled (CD image, ioctl_dx).
left:right left:right
The volume levels in percentages. If you put a D in front it will be The volume levels in percentages. If you put a D in front it will be
in decibel (example mixer gus d-10). in decibel (Example: mixer gus d-10).
/NOSHOW /NOSHOW
Prevents DOSBox from showing the result if you set one Prevents DOSBox from showing the result if you set one
@ -569,20 +633,31 @@ IMGMOUNT
IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format] IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format]
-size [sectorsbytesize, sectorsperhead, heads, cylinders] -size [sectorsbytesize, sectorsperhead, heads, cylinders]
IMGMOUNT DRIVE [imagefile1, .. ,imagefileN] -t iso -fs iso
imagefile imagefile
Location of the image files to mount in DOSBox. The location can Location of the image file to mount in DOSBox. The location can
be on a mounted drive inside DOSBox, or on your real disk. It is be on a mounted drive inside DOSBox, or on your real disk. It is
possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you possible to mount CD-ROM images (ISOs or CUE/BIN) as well, if you
need CD swapping capabilities specify all images in succession. need CD swapping capabilities specify all images in succession
The CDs can be swapped with CTRL-F4 at any time. (see the next entry).
CUE/BIN pairs are the preferred CD-ROM image type as they can
store audio tracks compared to ISOs (which are data-only). For
the CUE/BIN mounting always specify the CUE sheet.
imagefile1, .. ,imagefileN
Location of the image files to mount in DOSBox. Specifying a number
of image files is only allowed for CD-ROM images. The CD's can be
swapped with CTRL-F4 at any time. This is required for games which
use multiple CD-ROMs and require the CD to be switched during the
gameplay at some point.
-t -t
The following are valid image types: The following are valid image types:
floppy: Specifies a floppy image or images. DOSBox will automatically floppy: Specifies a floppy image. DOSBox will automatically identify
identify the disk geometry ( 360K, 1.2MB, 720K, 1.44MB, etc). the disk geometry (360K, 1.2MB, 720K, 1.44MB, etc).
iso: Specifies a CD-ROM iso image. The geometry is automatic and iso: Specifies a CD-ROM iso image. The geometry is automatic and
set for this size. This can be an iso or a cue/bin. set for this size. This can be an iso or a cue/bin pair.
hdd: Specifies a harddrive image. The proper CHS geometry hdd: Specifies a harddrive image. The proper CHS geometry
must be set for this to work. must be set for this to work.
@ -594,18 +669,18 @@ IMGMOUNT
available from inside DOSBox. available from inside DOSBox.
none: DOSBox will make no attempt to read the file system on the disk. none: DOSBox will make no attempt to read the file system on the disk.
This is useful if you need to format it or if you want to boot This is useful if you need to format it or if you want to boot
the disk using the BOOT command. When using the "none" the disk using the BOOT command. When using the "none"
filesystem, you must specify the drive number (2 or 3, filesystem, you must specify the drive number (2 or 3,
where 2 = master, 3 = slave) rather than a drive letter. where 2 = master, 3 = slave) rather than a drive letter.
For example, to mount a 70MB image as the slave drive device, For example, to mount a 70MB image as the slave drive device,
you would type: you would type (without the quotes):
"imgmount 3 d:\test.img -size 512,63,16,142 -fs none" "imgmount 3 d:\test.img -size 512,63,16,142 -fs none"
(without the quotes) Compare this with a mount to read the Compare this with a mount to be able to access the drive
drive in DOSBox, which would read as: within DOSBox, which would read as:
"imgmount e: d:\test.img -size 512,63,16,142" "imgmount e: d:\test.img -size 512,63,16,142"
-size -size
The Cylinders, Heads and Sectors specification of the drive. The Cylinders, Heads and Sectors of the drive.
Required to mount hard drive images. Required to mount hard drive images.
An example how to mount CD-ROM images: An example how to mount CD-ROM images:
@ -634,7 +709,7 @@ BOOT
[-l driveletter] [-l driveletter]
This parameter allows you to specify the drive to boot from. This parameter allows you to specify the drive to boot from.
The default is the A drive, the floppy drive. You can also boot The default is the A drive, the floppy drive. You can also boot
a hard drive image mounted as master by specifying "-l C" a hard drive image mounted as master by specifying "-l C"
without the quotes, or the drive as slave by specifying "-l D" without the quotes, or the drive as slave by specifying "-l D"
@ -654,12 +729,12 @@ IPX
With regard to actually setting up a network, one system needs to be With regard to actually setting up a network, one system needs to be
the server. To set this up, type "IPXNET STARTSERVER" (without the quotes) the server. To set this up, type "IPXNET STARTSERVER" (without the quotes)
in a DOSBox session. The server DOSBox session will in a DOSBox session. The server DOSBox session will automatically add
automatically add itself to the virtual IPX network. For every itself to the virtual IPX network. For every additional computer that
additional computer that should be part of the virtual IPX network, should be part of the virtual IPX network, you'll need to type
you'll need to type "IPXNET CONNECT <computer host name or IP>". "IPXNET CONNECT <computer host name or IP>".
For example, if your server is at bob.dosbox.com, For example, if your server is at bob.dosbox.com, you would type
you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system. "IPXNET CONNECT bob.dosbox.com" on every non-server system.
To play games that need Netbios a file named NETBIOS.EXE from Novell is To play games that need Netbios a file named NETBIOS.EXE from Novell is
needed. Establish the IPX connection as explained above, then run needed. Establish the IPX connection as explained above, then run
@ -749,17 +824,19 @@ KEYB [languagecode [codepage [codepagefile]]]
Examples: Examples:
1) To load the german keyboard layout (automatically uses codepage 858): 1. To load the german keyboard layout (automatically uses codepage 858):
keyb gr keyb gr
2) To load the russian keyboard layout with codepage 866: 2. To load the russian keyboard layout with codepage 866:
keyb ru 866 keyb ru 866
In order to type russian characters press ALT+RIGHT-SHIFT. In order to type russian characters press ALT+RIGHT-SHIFT.
3) To load the french keyboard layout with codepage 850 (where the 3. To load the french keyboard layout with codepage 850 (where the
codepage is defined in EGACPI.DAT): codepage is defined in EGACPI.DAT):
keyb fr 850 EGACPI.DAT keyb fr 850 EGACPI.DAT
4) To load codepage 858 (without a keyboard layout): 4. To load codepage 858 (without a keyboard layout):
keyb none 858 keyb none 858
This can be used to change the codepage for the freedos keyb2 utility. This can be used to change the codepage for the FreeDOS keyb2 utility.
5. To display the current codepage and, if loaded, the keyboard layout:
keyb
@ -772,13 +849,13 @@ For more information use the /? command line switch with the programs.
================ ================
ALT-ENTER Switch to full screen and back. ALT-ENTER Switch to full screen and back.
ALT-PAUSE Pause emulation. ALT-PAUSE Pause emulation (hit ALT-PAUSE again to continue).
CTRL-F1 Start the keymapper. CTRL-F1 Start the keymapper.
CTRL-F4 Change between mounted disk-images. Update directory cache for all drives! CTRL-F4 Change between mounted disk-images. Update directory cache for all drives!
CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing) CTRL-ALT-F5 Start/Stop creating a movie of the screen. (avi video capturing)
CTRL-F5 Save a screenshot. (png) CTRL-F5 Save a screenshot. (PNG format)
CTRL-F6 Start/Stop recording sound output to a wave file. CTRL-F6 Start/Stop recording sound output to a wave file.
CTRL-ALT-F7 Start/Stop recording of OPL commands. CTRL-ALT-F7 Start/Stop recording of OPL commands. (DRO format)
CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands. CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands.
CTRL-F7 Decrease frameskip. CTRL-F7 Decrease frameskip.
CTRL-F8 Increase frameskip. CTRL-F8 Increase frameskip.
@ -788,19 +865,20 @@ CTRL-F11 Slow down emulation (Decrease DOSBox Cycles).
CTRL-F12 Speed up emulation (Increase DOSBox Cycles). CTRL-F12 Speed up emulation (Increase DOSBox Cycles).
ALT-F12 Unlock speed (turbo button). ALT-F12 Unlock speed (turbo button).
These are the default keybindings. They can be changed in the keymapper. (NOTE: Once you increase your DOSBox cycles beyond your computer's maximum
capacity, it will produce the same effect as slowing down the emulation.
This maximum will vary from computer to computer.)
These are the default keybindings. They can be changed in the keymapper
(see Section 6: Mapper).
Saved/recorded files can be found in current_directory/capture Saved/recorded files can be found in current_directory/capture
(can be changed in the configfile). (this can be changed in the DOSBox configuration file).
The directory has to exist prior to starting DOSBox, otherwise nothing The directory has to exist prior to starting DOSBox, otherwise nothing
gets saved/recorded ! gets saved/recorded !
NOTE: Once you increase your DOSBox cycles beyond your computer's maximum
capacity, it will produce the same effect as slowing down the emulation.
This maximum will vary from computer to computer.
========== ==========
6. Mapper: 6. Mapper:
@ -810,10 +888,10 @@ When you start the DOSBox mapper (either with CTRL-F1 or -startmapper as
a command line argument to the DOSBox executable) you are presented with a command line argument to the DOSBox executable) you are presented with
a virtual keyboard and a virtual joystick. a virtual keyboard and a virtual joystick.
These virtual devices correspond to the keys DOSBox will report to the These virtual devices correspond to the keys and events DOSBox will
DOS applications. If you click on a key with your mouse, you can see in report to the DOS applications. If you click on a button with your mouse,
the lower left corner with which event it is associated (EVENT) and to you can see in the lower left corner with which event it is associated
what events it is currently bound. (EVENT) and to what events it is currently bound.
Event: EVENT Event: EVENT
BIND: BIND BIND: BIND
@ -865,32 +943,32 @@ Examples about remapping the joystick:
You have a joystick attached, it is working fine under DOSBox and you You have a joystick attached, it is working fine under DOSBox and you
want to play some keyboard-only game with the joystick (it is assumed want to play some keyboard-only game with the joystick (it is assumed
that the game is controlled by the arrows on the keyboard): that the game is controlled by the arrows on the keyboard):
1) Start the mapper, then click on one of the arrows in the middle 1. Start the mapper, then click on one of the arrows in the middle
of the left part of the screen (right above the Mod1/Mod2 buttons). of the left part of the screen (right above the Mod1/Mod2 buttons).
EVENT should be key_left. Now click on Add and move your joystick EVENT should be key_left. Now click on Add and move your joystick
in the respective direction, this should add an event to the BIND. in the respective direction, this should add an event to the BIND.
2) Repeat the above for the missing three directions, additionally 2. Repeat the above for the missing three directions, additionally
the buttons of the joystick can be remapped as well (fire/jump). the buttons of the joystick can be remapped as well (fire/jump).
3) Click on Save, then on Exit and test it with some game. 3. Click on Save, then on Exit and test it with some game.
You want to swap the y-axis of the joystick because some flightsim uses You want to swap the y-axis of the joystick because some flightsim uses
the up/down joystick movement in a way you don't like, and it is not the up/down joystick movement in a way you don't like, and it is not
configurable in the game itself: configurable in the game itself:
1) Start the mapper and click on Y- in the upper joystick field (this 1. Start the mapper and click on Y- in the upper joystick field (this
is for the first joystick if you have two joysticks attached) or the is for the first joystick if you have two joysticks attached) or the
lower joystick field (second joystick or, if you have only one lower joystick field (second joystick or, if you have only one
joystick attached, the second axes cross). joystick attached, the second axes cross).
EVENT should be jaxis_0_1- (or jaxis_1_1-). EVENT should be jaxis_0_1- (or jaxis_1_1-).
2) Click on Del to remove the current binding, then click Add and move 2. Click on Del to remove the current binding, then click Add and move
your joystick downwards. A new bind should be created. your joystick downwards. A new bind should be created.
3) Repeat this for Y+, save the layout and finally test it with some game. 3. Repeat this for Y+, save the layout and finally test it with some game.
If you change the default mapping, you can save your changes by clicking on If you change the default mapping, you can save your changes by clicking on
"Save". DOSBox will save the mapping to a location specified in the configfile "Save". DOSBox will save the mapping to a location specified in the configuration
(mapperfile=mapper.txt). At startup, DOSBox will load your mapperfile, if it file (the mapperfile= entry). At startup, DOSBox will load your mapperfile,
is present in the configfile. if it is present in the DOSBox configuration file.
@ -899,39 +977,43 @@ is present in the configfile.
=================== ===================
To switch to a different keyboard layout, either the entry "keyboardlayout" To switch to a different keyboard layout, either the entry "keyboardlayout"
in the [dos] section in dosbox.conf can be used, or the internal DOSBox in the [dos] section of the DOSBox configuration file can be used, or the
program keyb.com. Both accept DOS conforming language codes (see below), but internal DOSBox program keyb.com. Both accept DOS conforming language codes
only by using keyb.com a custom codepage can be specified. (see below), but only by using keyb.com a custom codepage can be specified.
The default keyboardlayout=auto currently works under windows only, the
layout is chosen according to the OS layout.
Layout switching Layout switching
DOSBox supports a number of keyboard layouts and codepages by default, DOSBox supports a number of keyboard layouts and codepages by default,
in this case just the layout identifier needs to be specified (like in this case just the layout identifier needs to be specified (like
keyboardlayout=sv in the DOSBox config file, or using "keyb sv" at keyboardlayout=sv in the DOSBox configuration file, or using "keyb sv"
the DOSBox command prompt). at the DOSBox command prompt).
Some keyboard layouts (for example layout GK codepage 869 and layout RU Some keyboard layouts (for example layout GK codepage 869 and layout RU
codepage 808) have support for dual layouts that can be activated by codepage 808) have support for dual layouts that can be activated by
pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT. pressing LEFT-ALT+RIGHT-SHIFT and deactivated by LEFT-ALT+LEFT-SHIFT.
Supported external files Supported external files
The freedos .kl files are supported (freedos keyb2 keyboard layoutfiles) as The FreeDOS .kl files are supported (FreeDOS keyb2 keyboard layoutfiles) as
well as the freedos keyboard.sys/keybrd2.sys/keybrd3.sys libraries which well as the FreeDOS keyboard.sys/keybrd2.sys/keybrd3.sys libraries which
consist of all available .kl files. consist of all available .kl files.
See http://projects.freedos.net/keyb/ for precompiled keyboard layouts if See http://projects.freedos.net/keyb/ for precompiled keyboard layouts if
the DOSBox-integrated layouts don't work for some reason, or updated or the DOSBox-integrated layouts don't work for some reason, or if updated or
new layouts become available. new layouts become available.
Both .CPI (MSDOS/compatible codepage files) and .CPX (freedos UPX-compressed Both .CPI (MS-DOS and compatible codepage files) and .CPX (FreeDOS
codepage files) can be used. Some codepages are compiled into DOSBox, so it UPX-compressed codepage files) can be used. Some codepages are compiled
is mostly not needed to care about external codepage files. If you need into DOSBox, so it is mostly not needed to care about external codepage
a different (or custom) codepage file, copy it into the directory of the files. If you need a different (or custom) codepage file, copy it into
DOSBox configuration file so it is accessible for DOSBox. the directory of the DOSBox configuration file so it is accessible for
DOSBox.
Additional layouts can be added by copying the corresponding .kl file into Additional layouts can be added by copying the corresponding .kl file into
the directory of dosbox.conf and using the first part of the filename as the directory of the DOSBox configuration file and using the first part of
language code. the filename as language code.
Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify Example: For the file UZ.KL (keyboard layout for Uzbekistan) specify
"keyboardlayout=uz" in dosbox.conf. "keyboardlayout=uz" in the DOSBox configuration file.
The integration of keyboard layout packages (like keybrd2.sys) works similar. The integration of keyboard layout packages (like keybrd2.sys) works similar.
@ -1010,7 +1092,7 @@ CPU Cycles
in the DOSBox configuration file specify for example cycles=30000. When in the DOSBox configuration file specify for example cycles=30000. When
running some DOS application you can raise the cycles with CTRL-F12 even running some DOS application you can raise the cycles with CTRL-F12 even
more, but you will be limited by the power of your actual CPU. You can see more, but you will be limited by the power of your actual CPU. You can see
how much free time your true CPU has by looking at the Task Manager in how much free time your real CPU has by looking at the Task Manager in
Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of Windows 2000/XP and the System Monitor in Windows 95/98/ME. Once 100% of
your real CPU time is used there is no further way to speed up DOSBox your real CPU time is used there is no further way to speed up DOSBox
unless you reduce the load generated by the non-CPU parts of DOSBox. unless you reduce the load generated by the non-CPU parts of DOSBox.
@ -1034,7 +1116,7 @@ Graphics emulation
Sound emulation Sound emulation
You can also try to disable the sound through the setup utility of the game You can also try to disable the sound through the setup utility of the game
to reduce load on your CPU further. Setting nosound=true does NOT disable to reduce load on your CPU further. Setting nosound=true does NOT disable
the emulation of sound devices, just the sound output will be disabled. the emulation of sound devices, just the output of sound will be disabled.
Also try to close every program but DOSBox to reserve as much resources Also try to close every program but DOSBox to reserve as much resources
as possible for DOSBox. as possible for DOSBox.
@ -1103,14 +1185,15 @@ You can edit the generated configfile to customize DOSBox.
The file is divided into several sections (the names have [] around it). The file is divided into several sections (the names have [] around it).
Some sections have options you can set. Some sections have options you can set.
# and % indicate comment-lines. # and % indicate comment-lines.
The generated configfile contains the current settings. You can alter them and The DOSBox configuration file contains the current settings. You can
start DOSBox with the -conf switch to load the file and use these settings. alter them and start DOSBox with the -conf switch to load the file and
use these settings.
DOSBox will first parse the settings in ~/.dosboxrc (Linux), DOSBox will first parse the settings in ~/.dosboxrc (Linux),
~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" ~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences"
(MACOSX). Afterwards DOSBox will parse all configfiles specified with the (MACOSX). Afterwards DOSBox will parse all configfiles specified with the
-conf switch. If no configfile is specified with the -conf switch, DOSBox will -conf switch. If no configfile is specified with the -conf switch, DOSBox will
look in the current directory for dosbox.conf. look in the current directory for the DOSBox configuration file.
@ -1147,5 +1230,5 @@ See the THANKS file.
============ ============
See the site: See the site:
http://dosbox.sourceforge.net http://www.dosbox.com
for an email address (The Crew-page). for an email address (The Crew-page).

1
VERSION Normal file
View File

@ -0,0 +1 @@
0.72

View File

@ -323,7 +323,18 @@ AH_TOP([
*/ */
]) ])
AH_BOTTOM([#define INLINE inline]) AH_BOTTOM([#if C_ATTRIBUTE_ALWAYS_INLINE
#define INLINE inline __attribute__((always_inline))
#else
#define INLINE inline
#endif])
AH_BOTTOM([#if C_ATTRIBUTE_FASTCALL
#define DB_FASTCALL __attribute__((fastcall))
#else
#define DB_FASTCALL
#endif])
AH_BOTTOM([#if C_HAS_ATTRIBUTE AH_BOTTOM([#if C_HAS_ATTRIBUTE
#define GCC_ATTRIBUTE(x) __attribute__ ((x)) #define GCC_ATTRIBUTE(x) __attribute__ ((x))

1247
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

1497
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,272 +0,0 @@
/* config.h.in. Generated from configure.in by autoheader. */
/*
* Copyright (C) 2002-2007 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Define to 1 to use inlined memory functions in cpu core */
#undef C_CORE_INLINE
/* Define to 1 to enable internal debugger, requires libcurses */
#undef C_DEBUG
/* Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).
*/
#undef C_DIRECTSERIAL
/* Define to 1 to use x86 dynamic cpu core */
#undef C_DYNAMIC_X86
/* Define to 1 to use recompiling cpu core. Can not be used together with the
dynamic-x86 core */
#undef C_DYNREC
/* Define to 1 to enable floating point emulation */
#undef C_FPU
/* Define to 1 to use a x86 assembly fpu core */
#undef C_FPU_X86
/* Determines if the compilers supports attributes for structures. */
#undef C_HAS_ATTRIBUTE
/* Determines if the compilers supports __builtin_expect for branch
prediction. */
#undef C_HAS_BUILTIN_EXPECT
/* Define to 1 if you have the mprotect function */
#undef C_HAVE_MPROTECT
/* Define to 1 to enable heavy debugging, also have to enable C_DEBUG */
#undef C_HEAVY_DEBUG
/* Define to 1 to enable IPX over Internet networking, requires SDL_net */
#undef C_IPX
/* Define to 1 to enable internal modem support, requires SDL_net */
#undef C_MODEM
/* Define to 1 to use opengl display output support */
#undef C_OPENGL
/* Define to 1 to enable SDL_sound support */
#undef C_SDL_SOUND
/* Define to 1 if you have setpriority support */
#undef C_SET_PRIORITY
/* Define to 1 to enable screenshots, requires libpng */
#undef C_SSHOT
/* The type of cpu this target has */
#undef C_TARGETCPU
/* Define to 1 to use a unaligned memory access */
#undef C_UNALIGNED_MEMORY
/* libm doesn't include powf */
#undef DB_HAVE_NO_POWF
/* environ can be included */
#undef ENVIRON_INCLUDED
/* environ can be linked */
#undef ENVIRON_LINKED
/* Define to 1 to use ALSA for MIDI */
#undef HAVE_ALSA
/* Define to 1 if you have the <ddraw.h> header file. */
#undef HAVE_DDRAW_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `asound' library (-lasound). */
#undef HAVE_LIBASOUND
/* Define to 1 if you have the `m' library (-lm). */
#undef HAVE_LIBM
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Compiling on GNU/Linux */
#undef LINUX
/* Compiling on Mac OS X */
#undef MACOSX
/* Compiling on OS/2 EMX */
#undef OS2
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* The size of `int *', as computed by sizeof. */
#undef SIZEOF_INT_P
/* The size of `unsigned char', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_CHAR
/* The size of `unsigned int', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_INT
/* The size of `unsigned long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG
/* The size of `unsigned long long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG_LONG
/* The size of `unsigned short', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_SHORT
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Version number of package */
#undef VERSION
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
#undef inline
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
#undef size_t
/* Define to `int` if you don't have socklen_t */
#undef socklen_t
#define INLINE inline
#if C_HAS_ATTRIBUTE
#define GCC_ATTRIBUTE(x) __attribute__ ((x))
#else
#define GCC_ATTRIBUTE(x) /* attribute not supported */
#endif
#if C_HAS_BUILTIN_EXPECT
#define GCC_UNLIKELY(x) __builtin_expect((x),0)
#else
#define GCC_UNLIKELY(x) (x)
#endif
typedef double Real64;
#if SIZEOF_UNSIGNED_CHAR != 1
# error "sizeof (unsigned char) != 1"
#else
typedef unsigned char Bit8u;
typedef signed char Bit8s;
#endif
#if SIZEOF_UNSIGNED_SHORT != 2
# error "sizeof (unsigned short) != 2"
#else
typedef unsigned short Bit16u;
typedef signed short Bit16s;
#endif
#if SIZEOF_UNSIGNED_INT == 4
typedef unsigned int Bit32u;
typedef signed int Bit32s;
#elif SIZEOF_UNSIGNED_LONG == 4
typedef unsigned long Bit32u;
typedef signed long Bit32s;
#else
# error "can't find sizeof(type) of 4 bytes!"
#endif
#if SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long Bit64u;
typedef signed long Bit64s;
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long Bit64u;
typedef signed long long Bit64s;
#else
# error "can't find data type of 8 bytes"
#endif
#if SIZEOF_INT_P == 4
typedef Bit32u Bitu;
typedef Bit32s Bits;
#else
typedef Bit64u Bitu;
typedef Bit64s Bits;
#endif

1608
config.sub vendored

File diff suppressed because it is too large Load Diff

14001
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,20 @@ AM_PATH_SDL($SDL_VERSION,
LIBS="$LIBS $SDL_LIBS" LIBS="$LIBS $SDL_LIBS"
CPPFLAGS="$CPPFLAGS $SDL_CFLAGS" CPPFLAGS="$CPPFLAGS $SDL_CFLAGS"
dnl Check if SDL is 1.2.x (1.3 not supported)
AC_MSG_CHECKING([SDL version only being 1.2.X])
AC_COMPILE_IFELSE([
#include "SDL.h"
void blah(){
#if SDL_MINOR_VERSION != 2
#error "Only SDL 1.2 supported"
#endif
;
}
],AC_MSG_RESULT([yes]),[
AC_MSG_RESULT([no])
AC_MSG_ERROR([Only libSDL 1.2.X supported])])
dnl Checks for header files. dnl Checks for header files.
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
@ -96,6 +110,16 @@ AC_MSG_CHECKING(if environ can be linked)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char ** environ;]],[[*environ;]])], AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char ** environ;]],[[*environ;]])],
[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_LINKED,1,[environ can be linked])],AC_MSG_RESULT(no)) [AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_LINKED,1,[environ can be linked])],AC_MSG_RESULT(no))
AC_MSG_CHECKING([if dirent includes d_type])
AC_COMPILE_IFELSE([
#include <sys/types.h>
#include <dirent.h>
void blah(){
struct dirent d_test;
d_test.d_type = 0;
}],[AC_MSG_RESULT(yes);AC_DEFINE(DIRENT_HAS_D_TYPE,1,[struct dirent has d_type])],AC_MSG_RESULT(no))
dnl Check for powf dnl Check for powf
if test x$target = xi386-pc-os2-emx ; then if test x$target = xi386-pc-os2-emx ; then
AC_MSG_CHECKING(for powf in libm); AC_MSG_CHECKING(for powf in libm);
@ -118,6 +142,25 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
typedef struct { } __attribute__((packed)) junk;]], typedef struct { } __attribute__((packed)) junk;]],
[[ ]])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no)) [[ ]])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no))
#Check if the compiler supports certain attributes
OLDCFLAGS="$CFLAGS"
CFLAGS="-Werror"
AH_TEMPLATE([C_ATTRIBUTE_ALWAYS_INLINE],[Determines if the compilers supports always_inline attribute.])
AC_MSG_CHECKING(if compiler allows __attribute__((always_inline)) )
AC_COMPILE_IFELSE([ void __attribute__((always_inline)) test(){}
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_ALWAYS_INLINE)],AC_MSG_RESULT(no))
AH_TEMPLATE([C_ATTRIBUTE_FASTCALL],[Determines if the compilers supports fastcall attribute.])
AC_MSG_CHECKING(if compiler allows __attribute__((fastcall)) )
AC_COMPILE_IFELSE([ void __attribute__((fastcall)) test(){}
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_FASTCALL)],AC_MSG_RESULT(no))
CFLAGS="$OLDCFLAGS"
#Check if the compiler supports __builtin_expect #Check if the compiler supports __builtin_expect
#Switch language to c++ #Switch language to c++
AC_LANG_PUSH(C++) AC_LANG_PUSH(C++)
@ -151,6 +194,7 @@ AH_TEMPLATE(C_HEAVY_DEBUG,[Define to 1 to enable heavy debugging, also have to e
AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
AC_CHECK_HEADER(curses.h,have_curses_h=yes,) AC_CHECK_HEADER(curses.h,have_curses_h=yes,)
AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , ) AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , )
AC_CHECK_LIB(ncurses, initscr, have_ncurses_lib=yes, , )
AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , ) AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , )
if test x$enable_debug = xno; then if test x$enable_debug = xno; then
@ -161,6 +205,12 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
if test x$enable_debug = xheavy ; then if test x$enable_debug = xheavy ; then
AC_DEFINE(C_HEAVY_DEBUG,1) AC_DEFINE(C_HEAVY_DEBUG,1)
fi fi
elif test x$have_ncurses_lib = xyes -a x$have_curses_h = xyes ; then
LIBS="$LIBS -lncurses"
AC_DEFINE(C_DEBUG,1)
if test x$enable_debug = xheavy ; then
AC_DEFINE(C_HEAVY_DEBUG,1)
fi
elif test x$have_pdcurses_lib = xyes -a x$have_curses_h = xyes ; then elif test x$have_pdcurses_lib = xyes -a x$have_curses_h = xyes ; then
LIBS="$LIBS -lpdcurses" LIBS="$LIBS -lpdcurses"
AC_DEFINE(C_DEBUG,1) AC_DEFINE(C_DEBUG,1)
@ -168,7 +218,7 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
AC_DEFINE(C_HEAVY_DEBUG,1) AC_DEFINE(C_HEAVY_DEBUG,1)
fi fi
else else
AC_MSG_WARN([Can't find curses, debug mode disabled]) AC_MSG_ERROR([Can't find curses, which is required for debug mode])
fi fi
],) ],)
@ -399,12 +449,12 @@ case "$target" in
fi fi
;; ;;
*-*-darwin*) *-*-darwin*)
dnl We have a problem here: both MacOS X and Darwin report dnl We have a problem here: both Mac OS X and Darwin report
dnl the same signature "powerpc-apple-darwin*" - so we have dnl the same signature "powerpc-apple-darwin*" - so we have
dnl to do more to distinguish them. dnl to do more to distinguish them.
dnl For now I am lazy and do not add proper detection code. dnl For now I am lazy and do not add proper detection code.
AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X]) AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X])
LIBS="$LIBS -framework AudioUnit" LIBS="$LIBS -framework CoreMidi -framework AudioUnit -framework AudioToolbox"
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;; ;;
*-*-linux*) *-*-linux*)
@ -417,7 +467,8 @@ case "$target" in
dnl directserial detection should be rewritten to test for the needed dnl directserial detection should be rewritten to test for the needed
dnl functions and headers. I currently do not know dnl functions and headers. I currently do not know
dnl which ones are needed for BSD dnl which ones are needed for BSD
dnl AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).]) AC_DEFINE(BSD, 1, [Compiling on BSD])
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
;; ;;
*-*-os2-emx*) *-*-os2-emx*)
AC_DEFINE(OS2, 1, [Compiling on OS/2 EMX]) AC_DEFINE(OS2, 1, [Compiling on OS/2 EMX])
@ -456,6 +507,7 @@ src/hardware/serialport/Makefile
src/ints/Makefile src/ints/Makefile
src/libs/Makefile src/libs/Makefile
src/libs/zmbv/Makefile src/libs/zmbv/Makefile
src/libs/gui_tk/Makefile
src/misc/Makefile src/misc/Makefile
src/shell/Makefile src/shell/Makefile
src/platform/Makefile src/platform/Makefile

479
depcomp
View File

@ -1,479 +0,0 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
# Copyright 1999, 2000, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# `libtool' can also be set to `yes' or `no'.
if test -z "$depfile"; then
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
dir=`echo "$object" | sed 's,/.*$,/,'`
if test "$dir" = "$object"; then
dir=
fi
# FIXME: should be _deps on DOS.
depfile="$dir.deps/$base"
fi
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
tmpdepfile1="$dir.libs/$base.lo.d"
tmpdepfile2="$dir.libs/$base.d"
"$@" -Wc,-MD
else
tmpdepfile1="$dir$base.o.d"
tmpdepfile2="$dir$base.d"
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
if test -f "$tmpdepfile1"; then
tmpdepfile="$tmpdepfile1"
else
tmpdepfile="$tmpdepfile2"
fi
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0

View File

@ -1,337 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
# Main Makefile for DOSBox
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
man_MANS = dosbox.1
EXTRA_DIST = $(man_MANS) README.video PORTING
subdir = docs
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
NROFF = nroff
MANS = $(man_MANS)
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu docs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
man1dir = $(mandir)/man1
install-man1: $(man1_MANS) $(man_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(man1dir)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
else file=$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
done
uninstall-man1:
@$(NORMAL_UNINSTALL)
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
for i in $$l2; do \
case "$$i" in \
*.1*) list="$$list $$i" ;; \
esac; \
done; \
for i in $$list; do \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
1*) ;; \
*) ext='1' ;; \
esac; \
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
inst=`echo $$inst | sed -e 's/^.*\///'`; \
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
rm -f $(DESTDIR)$(man1dir)/$$inst; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(MANS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(man1dir)
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-man
install-exec-am:
install-info: install-info-am
install-man: install-man1
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-man
uninstall-man: uninstall-man1
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-man1 install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
uninstall-am uninstall-info-am uninstall-man uninstall-man1
# 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:

View File

@ -2,13 +2,10 @@ Some notes about porting DOSBox to systems with certain restrictions,
like handheld devices. like handheld devices.
If memory is a constraint: If memory is a constraint:
- in paging.h reduce the size of the TLB: - in paging.h out-comment the USE_FULL_TLB define to enable special
#define TLB_SIZE (64*1024) TLB linking code that uses less memory
the 64 gives access to the first 256mb of linear memory drawback: none (the code is not heavily tested though)
drawback: some protected mode games won't work then
gain: reduces memory requirements about ~15mb gain: reduces memory requirements about ~15mb
TODO: limit vmemory access to the size of the TLB,
otherwise games which use >256mb vaddresses will crash badly
- in render.h lower the scaler integration: - in render.h lower the scaler integration:
#define RENDER_USE_ADVANCED_SCALERS 1 #define RENDER_USE_ADVANCED_SCALERS 1
or or
@ -22,18 +19,17 @@ If memory is a constraint:
~5mb with RENDER_USE_ADVANCED_SCALERS==0 ~5mb with RENDER_USE_ADVANCED_SCALERS==0
- in dos_system.h reduce the drive cache entries: - in dos_system.h reduce the drive cache entries:
#define MAX_OPENDIRS 256 #define MAX_OPENDIRS 256
drawback: some apps might not work whith large directory trees drawback: some apps might not work with large directory trees
gain: ~1mb per mounted drive gain: ~1mb per mounted drive
- remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] ) - remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] )
drawback: no gravis ultrasound drawback: no gravis ultrasound
gain: reduces memory requirements about 1mb gain: reduces memory requirements about 1mb
- in vga.h reduce the size of the emulated graphics memory: - reduce the size of the emulated graphics memory:
#define VGA_MEMORY (1*1024*1024) see the memory sizing in SVGA_Setup_*, especially the defaults
in vga_s3.cpp's SVGA_Setup_S3Trio
drawback: some graphics modes won't work then drawback: some graphics modes won't work then
[EDIT: many modes won't work due to pixel caches] gain: reduces memory requirements
gain: reduces memory requirements about 1mb TODO: fully check this, introduce hard limits
TODO: get this to actually work;
remove the respective svga modes, adapt some svga registers
If speed is a constraint: If speed is a constraint:
- see if the simple core is faster, possibly remove the normal core - see if the simple core is faster, possibly remove the normal core

View File

@ -8,6 +8,7 @@ dosbox \- an x86/DOS emulator with sound/graphics
.B [\-fullscreen] .B [\-fullscreen]
.B [\-startmapper] .B [\-startmapper]
.B [\-noautoexec] .B [\-noautoexec]
.B [\-securemode]
.BI "[\-scaler " scaler ] .BI "[\-scaler " scaler ]
.BI "[\-forcescaler " scaler ] .BI "[\-forcescaler " scaler ]
.BI "[\-conf " configfile ] .BI "[\-conf " configfile ]
@ -41,6 +42,13 @@ A summary of options is included below.
.B \-noautoexec .B \-noautoexec
Skips the [autoexec] section of the loaded configuration file. Skips the [autoexec] section of the loaded configuration file.
.TP .TP
.B \-securemode
.RB "Same as " \-noautoexec ", but adds " "config.com \-securemode"
at the end of
.I AUTOEXEC.BAT
(which in turn disables any changes to how the drives are mounted
.RB "inside " dosbox )
.TP
.BI \-scaler " scaler" .BI \-scaler " scaler"
.RI "Uses the graphical scaler specified by " scaler ". See the configuration" .RI "Uses the graphical scaler specified by " scaler ". See the configuration"
file for the available scalers file for the available scalers
@ -67,7 +75,7 @@ wish to execute on startup. Multiple
.IR langfile . .IR langfile .
.TP .TP
.B \-exit .B \-exit
.BR dosbox " will close itself when the DOS program specified by " file "ends." .BR dosbox " will close itself when the DOS program specified by "file " ends."
.TP .TP
.BI \-machine " machinetype .BI \-machine " machinetype
.RB "Setup " dosbox " to emulate a specific type of machine." .RB "Setup " dosbox " to emulate a specific type of machine."
@ -153,9 +161,19 @@ Display the amount of free memory
.TP .TP
.B CONFIG [\-writeconf] [\-writelang] file .B CONFIG [\-writeconf] [\-writelang] file
.LP .LP
.B CONFIG -securemode
.LP
.RB "Write the current configuration or language settings to " file , .RB "Write the current configuration or language settings to " file ,
which is located on the local filesystem. Not a mounted drive in which is located on the local filesystem. Not a mounted drive in
.BR dosbox . .BR dosbox .
.TP
.B \-securemode
.RB Switches dosbox " to a more secure mode. In this mode the"
.RI "internal commands " MOUNT ", " IMGMOUNT " and " BOOT " won\'t work."
It\'s not possible
either to create a new configfile or languagefile in this mode.
(Warning you can only undo this mode by restarting
.BR dosbox .)
.LP .LP
The configuration file controls various settings of The configuration file controls various settings of
.BR dosbox ": The amount of emulated memory," .BR dosbox ": The amount of emulated memory,"

View File

@ -1,8 +1,10 @@
noinst_HEADERS = \ noinst_HEADERS = \
bios.h \ bios.h \
bios_disk.h \
callback.h \ callback.h \
cpu.h \ cpu.h \
cross.h \ cross.h \
control.h \
debug.h \ debug.h \
dma.h \ dma.h \
dos_inc.h \ dos_inc.h \

View File

@ -1,366 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = \
bios.h \
callback.h \
cpu.h \
cross.h \
debug.h \
dma.h \
dos_inc.h \
dos_system.h \
dosbox.h \
fpu.h \
hardware.h \
inout.h \
joystick.h \
ipx.h \
ipxserver.h \
keyboard.h \
logging.h \
mapper.h \
mem.h \
mixer.h \
modules.h \
mouse.h \
paging.h \
pic.h \
programs.h \
render.h \
regs.h \
render.h \
serialport.h \
setup.h \
shell.h \
support.h \
timer.h \
vga.h \
video.h
subdir = include
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu include/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(HEADERS)
installdirs:
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
info info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-info-am
# 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:

View File

@ -105,66 +105,9 @@
#define MAX_SCAN_CODE 0x58 #define MAX_SCAN_CODE 0x58
/* The Section handling Bios Disk Access */ /* The Section handling Bios Disk Access */
#define BIOS_MAX_DISK 10 //#define BIOS_MAX_DISK 10
#define MAX_SWAPPABLE_DISKS 20 //#define MAX_SWAPPABLE_DISKS 20
struct diskGeo {
Bit32u ksize; /* Size in kilobytes */
Bit16u secttrack; /* Sectors per track */
Bit16u headscyl; /* Heads per cylinder */
Bit16u cylcount; /* Cylinders per side */
Bit16u biosval; /* Type to return from BIOS */
};
extern diskGeo DiskGeometryList[];
#include <stdio.h>
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h"
#endif
class imageDisk {
public:
Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize);
void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize);
Bit8u GetBiosType(void);
Bit32u getSectSize(void);
imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk);
~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } };
bool hardDrive;
bool active;
FILE *diskimg;
Bit8u diskname[512];
Bit8u floppytype;
Bit32u sector_size;
Bit32u heads,cylinders,sectors;
};
void updateDPT(void);
#define MAX_HDD_IMAGES 2
extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES];
extern imageDisk *diskSwap[20];
extern Bits swapPosition;
extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */
extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */
extern DOS_DTA *imgDTA;
void swapInDisks(void);
void swapInNextDisk(void);
bool getSwapRequest(void);
void BIOS_ZeroExtendedSize(bool in); void BIOS_ZeroExtendedSize(bool in);
void char_out(Bit8u chr,Bit32u att,Bit8u page); void char_out(Bit8u chr,Bit32u att,Bit8u page);

85
include/bios_disk.h Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DOSBOX_BIOS_DISK_H
#define DOSBOX_BIOS_DISK_H
#include <stdio.h>
#ifndef DOSBOX_MEM_H
#include "mem.h"
#endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h"
#endif
#ifndef DOSBOX_BIOS_H
#include "bios.h"
#endif
/* The Section handling Bios Disk Access */
#define BIOS_MAX_DISK 10
#define MAX_SWAPPABLE_DISKS 20
struct diskGeo {
Bit32u ksize; /* Size in kilobytes */
Bit16u secttrack; /* Sectors per track */
Bit16u headscyl; /* Heads per cylinder */
Bit16u cylcount; /* Cylinders per side */
Bit16u biosval; /* Type to return from BIOS */
};
extern diskGeo DiskGeometryList[];
class imageDisk {
public:
Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize);
void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize);
Bit8u GetBiosType(void);
Bit32u getSectSize(void);
imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk);
~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } };
bool hardDrive;
bool active;
FILE *diskimg;
Bit8u diskname[512];
Bit8u floppytype;
Bit32u sector_size;
Bit32u heads,cylinders,sectors;
};
void updateDPT(void);
#define MAX_HDD_IMAGES 2
extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES];
extern imageDisk *diskSwap[20];
extern Bits swapPosition;
extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */
extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */
extern DOS_DTA *imgDTA;
void swapInDisks(void);
void swapInNextDisk(void);
bool getSwapRequest(void);
#endif

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: callback.h,v 1.21 2007/06/12 20:22:07 c2woody Exp $ */ /* $Id: callback.h,v 1.23 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_CALLBACK_H #ifndef DOSBOX_CALLBACK_H
#define DOSBOX_CALLBACK_H #define DOSBOX_CALLBACK_H
@ -30,7 +30,8 @@ extern CallBack_Handler CallBack_Handlers[];
enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1, enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,
CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE, CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE,
CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET }; CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
CB_INT21 };
#define CB_MAX 128 #define CB_MAX 128
#define CB_SIZE 32 #define CB_SIZE 32
@ -42,14 +43,14 @@ enum {
extern Bit8u lastint; extern Bit8u lastint;
INLINE RealPt CALLBACK_RealPointer(Bitu callback) { static INLINE RealPt CALLBACK_RealPointer(Bitu callback) {
return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
} }
INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) { static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) {
return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE)); return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
} }
INLINE PhysPt CALLBACK_GetBase(void) { static INLINE PhysPt CALLBACK_GetBase(void) {
return CB_SEG << 4; return CB_SEG << 4;
} }

87
include/control.h Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: control.h,v 1.1 2009/02/01 14:11:45 qbix79 Exp $ */
#ifndef DOSBOX_CONTROL_H
#define DOSBOX_CONTROL_H
#ifdef _MSC_VER
#pragma warning ( disable : 4786 )
#pragma warning ( disable : 4290 )
#endif
#ifndef DOSBOX_PROGRAMS_H
#include "programs.h"
#endif
#ifndef DOSBOX_SETUP_H
#include "setup.h"
#endif
#ifndef CH_LIST
#define CH_LIST
#include <list>
#endif
#ifndef CH_VECTOR
#define CH_VECTOR
#include <vector>
#endif
#ifndef CH_STRING
#define CH_STRING
#include <string>
#endif
class Config{
public:
CommandLine * cmdline;
private:
std::list<Section*> sectionlist;
typedef std::list<Section*>::iterator it;
typedef std::list<Section*>::reverse_iterator reverse_it;
typedef std::list<Section*>::const_iterator const_it;
typedef std::list<Section*>::const_reverse_iterator const_reverse_it;
void (* _start_function)(void);
bool secure_mode; //Sandbox mode
public:
Config(CommandLine * cmd):cmdline(cmd),secure_mode(false){}
~Config();
Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*));
Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false);
Section* GetSection(int index);
Section* GetSection(std::string const&_sectionname) const;
Section* GetSectionFromProperty(char const * const prop) const;
void SetStartUp(void (*_function)(void));
void Init();
void ShutDown();
void StartUp();
bool PrintConfig(char const * const configfilename) const;
bool ParseConfigFile(char const * const configfilename);
void ParseEnv(char ** envp);
bool SecureMode() const { return secure_mode; }
void SwitchToSecureMode() { secure_mode = true; }//can't be undone
};
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: cpu.h,v 1.56 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_CPU_H #ifndef DOSBOX_CPU_H
#define DOSBOX_CPU_H #define DOSBOX_CPU_H
@ -36,6 +38,16 @@
#define CPU_AUTODETERMINE_SHIFT 0x02 #define CPU_AUTODETERMINE_SHIFT 0x02
#define CPU_AUTODETERMINE_MASK 0x03 #define CPU_AUTODETERMINE_MASK 0x03
#define CPU_CYCLES_LOWER_LIMIT 100
#define CPU_ARCHTYPE_MIXED 0xff
#define CPU_ARCHTYPE_386SLOW 0x30
#define CPU_ARCHTYPE_386FAST 0x35
#define CPU_ARCHTYPE_486OLDSLOW 0x40
#define CPU_ARCHTYPE_486NEWSLOW 0x45
#define CPU_ARCHTYPE_PENTIUMSLOW 0x50
/* CPU Cycle Timing */ /* CPU Cycle Timing */
extern Bit32s CPU_Cycles; extern Bit32s CPU_Cycles;
extern Bit32s CPU_CycleLeft; extern Bit32s CPU_CycleLeft;
@ -45,8 +57,13 @@ extern Bit32s CPU_CyclePercUsed;
extern Bit32s CPU_CycleLimit; extern Bit32s CPU_CycleLimit;
extern Bit64s CPU_IODelayRemoved; extern Bit64s CPU_IODelayRemoved;
extern bool CPU_CycleAutoAdjust; extern bool CPU_CycleAutoAdjust;
extern bool CPU_SkipCycleAutoAdjust;
extern Bitu CPU_AutoDetermineMode; extern Bitu CPU_AutoDetermineMode;
extern Bitu CPU_ArchitectureType;
extern Bitu CPU_PrefetchQueueSize;
/* Some common Defines */ /* Some common Defines */
/* A CPU Handler */ /* A CPU Handler */
typedef Bits (CPU_Decoder)(void); typedef Bits (CPU_Decoder)(void);
@ -60,6 +77,13 @@ Bits CPU_Core_Dyn_X86_Run(void);
Bits CPU_Core_Dyn_X86_Trap_Run(void); Bits CPU_Core_Dyn_X86_Trap_Run(void);
Bits CPU_Core_Dynrec_Run(void); Bits CPU_Core_Dynrec_Run(void);
Bits CPU_Core_Dynrec_Trap_Run(void); Bits CPU_Core_Dynrec_Trap_Run(void);
Bits CPU_Core_Prefetch_Run(void);
Bits CPU_Core_Prefetch_Trap_Run(void);
void CPU_Enable_SkipAutoAdjust(void);
void CPU_Disable_SkipAutoAdjust(void);
void CPU_Reset_AutoAdjust(void);
//CPU Stuff //CPU Stuff
@ -120,13 +144,13 @@ void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
#define CPU_INT_NOIOPLCHECK 0x8 #define CPU_INT_NOIOPLCHECK 0x8
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip); void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip);
INLINE void CPU_HW_Interrupt(Bitu num) { static INLINE void CPU_HW_Interrupt(Bitu num) {
CPU_Interrupt(num,0,reg_eip); CPU_Interrupt(num,0,reg_eip);
} }
INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) { static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) {
CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip); CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip);
} }
INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) { static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) {
CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip); CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip);
} }
@ -136,7 +160,7 @@ void CPU_Exception(Bitu which,Bitu error=0);
bool CPU_SetSegGeneral(SegNames seg,Bitu value); bool CPU_SetSegGeneral(SegNames seg,Bitu value);
bool CPU_PopSeg(SegNames seg,bool use32); bool CPU_PopSeg(SegNames seg,bool use32);
void CPU_CPUID(void); bool CPU_CPUID(void);
Bitu CPU_Pop16(void); Bitu CPU_Pop16(void);
Bitu CPU_Pop32(void); Bitu CPU_Pop32(void);
void CPU_Push16(Bitu value); void CPU_Push16(Bitu value);
@ -150,6 +174,7 @@ void CPU_SetFlags(Bitu word,Bitu mask);
#define EXCEPTION_NP 11 #define EXCEPTION_NP 11
#define EXCEPTION_SS 12 #define EXCEPTION_SS 12
#define EXCEPTION_GP 13 #define EXCEPTION_GP 13
#define EXCEPTION_PF 14
#define CR0_PROTECTION 0x00000001 #define CR0_PROTECTION 0x00000001
#define CR0_MONITORPROCESSOR 0x00000002 #define CR0_MONITORPROCESSOR 0x00000002
@ -303,16 +328,9 @@ class Descriptor
public: public:
Descriptor() { saved.fill[0]=saved.fill[1]=0; } Descriptor() { saved.fill[0]=saved.fill[1]=0; }
void Load(PhysPt address) { void Load(PhysPt address);
Bit32u* data = (Bit32u*)&saved; void Save(PhysPt address);
*data = mem_readd(address);
*(data+1) = mem_readd(address+4);
}
void Save(PhysPt address) {
Bit32u* data = (Bit32u*)&saved;
mem_writed(address,*data);
mem_writed(address+4,*(data+1));
}
PhysPt GetBase (void) { PhysPt GetBase (void) {
return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15; return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15;
} }
@ -433,6 +451,7 @@ public:
struct CPUBlock { struct CPUBlock {
Bitu cpl; /* Current Privilege */ Bitu cpl; /* Current Privilege */
Bitu mpl;
Bitu cr0; Bitu cr0;
bool pmode; /* Is Protected mode enabled */ bool pmode; /* Is Protected mode enabled */
GDTDescriptorTable gdt; GDTDescriptorTable gdt;
@ -459,15 +478,15 @@ struct CPUBlock {
extern CPUBlock cpu; extern CPUBlock cpu;
INLINE void CPU_SetFlagsd(Bitu word) { static INLINE void CPU_SetFlagsd(Bitu word) {
Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL; Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL;
CPU_SetFlags(word,mask); CPU_SetFlags(word,mask);
}; }
INLINE void CPU_SetFlagsw(Bitu word) { static INLINE void CPU_SetFlagsw(Bitu word) {
Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff; Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff;
CPU_SetFlags(word,mask); CPU_SetFlags(word,mask);
}; }
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: cross.h,v 1.18 2007/01/08 19:45:37 qbix79 Exp $ */ /* $Id: cross.h,v 1.21 2009/03/14 18:02:34 qbix79 Exp $ */
#ifndef DOSBOX_CROSS_H #ifndef DOSBOX_CROSS_H
#define DOSBOX_CROSS_H #define DOSBOX_CROSS_H
@ -28,6 +28,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <string>
#if defined (_MSC_VER) /* MS Visual C++ */ #if defined (_MSC_VER) /* MS Visual C++ */
#include <direct.h> #include <direct.h>
@ -66,4 +67,42 @@
static inline float powf (float x, float y) { return (float) pow (x,y); } static inline float powf (float x, float y) { return (float) pow (x,y); }
#endif #endif
class Cross {
public:
static void GetPlatformConfigDir(std::string& in);
static void GetPlatformConfigName(std::string& in);
static void CreatePlatformConfigDir(std::string& in);
static void ResolveHomedir(std::string & temp_line);
static void CreateDir(std::string const& temp);
};
#if defined (WIN32)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from
#include <windows.h>
typedef struct dir_struct {
HANDLE handle;
char base_path[MAX_PATH+4];
WIN32_FIND_DATA search_data;
} dir_information;
#else
//#include <sys/types.h> //Included above
#include <dirent.h>
typedef struct dir_struct {
DIR* dir;
char base_path[CROSS_LEN];
} dir_information;
#endif
dir_information* open_directory(const char* dirname);
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory);
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory);
void close_directory(dir_information* dirp);
#endif #endif

View File

@ -24,6 +24,7 @@ void DEBUG_Enable(bool pressed);
void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off); void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off);
bool DEBUG_ExitLoop(void); bool DEBUG_ExitLoop(void);
void DEBUG_RefreshPage(char scroll); void DEBUG_RefreshPage(char scroll);
Bitu DEBUG_EnableDebugger(void);
extern Bitu cycle_count; extern Bitu cycle_count;
extern Bitu debugCallback; extern Bitu debugCallback;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: dma.h,v 1.17 2007/01/08 19:45:37 qbix79 Exp $ */ /* $Id: dma.h,v 1.18 2008/09/13 20:04:28 c2woody Exp $ */
#ifndef DOSBOX_DMA_H #ifndef DOSBOX_DMA_H
#define DOSBOX_DMA_H #define DOSBOX_DMA_H
@ -46,6 +46,7 @@ public:
Bit8u trantype; Bit8u trantype;
bool masked; bool masked;
bool tcount; bool tcount;
bool request;
DMA_CallBack callback; DMA_CallBack callback;
DmaChannel(Bit8u num, bool dma16); DmaChannel(Bit8u num, bool dma16);
@ -59,6 +60,8 @@ public:
void Register_Callback(DMA_CallBack _cb) { void Register_Callback(DMA_CallBack _cb) {
callback = _cb; callback = _cb;
SetMask(masked); SetMask(masked);
if (callback) Raise_Request();
else Clear_Request();
} }
void ReachedTC(void) { void ReachedTC(void) {
tcount=true; tcount=true;
@ -68,6 +71,12 @@ public:
pagenum=val; pagenum=val;
pagebase=(pagenum >> DMA16) << (16+DMA16); pagebase=(pagenum >> DMA16) << (16+DMA16);
} }
void Raise_Request(void) {
request=true;
}
void Clear_Request(void) {
request=false;
}
Bitu Read(Bitu size, Bit8u * buffer); Bitu Read(Bitu size, Bit8u * buffer);
Bitu Write(Bitu size, Bit8u * buffer); Bitu Write(Bitu size, Bit8u * buffer);
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: dos_inc.h,v 1.70 2007/07/20 18:53:52 qbix79 Exp $ */ /* $Id: dos_inc.h,v 1.77 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_DOS_INC_H #ifndef DOSBOX_DOS_INC_H
#define DOSBOX_DOS_INC_H #define DOSBOX_DOS_INC_H
@ -77,13 +77,16 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
#define DOS_DEVICES 10 #define DOS_DEVICES 10
#define DOS_INFOBLOCK_SEG 0x80 // dos swappable area is 0x320 bytes beyond the sysvars table
#define DOS_CDS_SEG 0x90 // device driver chain is inside sysvars
#define DOS_CONSTRING_SEG 0xa0 #define DOS_INFOBLOCK_SEG 0x80 // sysvars (list of lists)
#define DOS_CONDRV_SEG 0xa4 #define DOS_CONDRV_SEG 0xa0
#define DOS_SDA_SEG 0xb2 #define DOS_CONSTRING_SEG 0xa8
#define DOS_SDA_SEG 0xb2 // dos swappable area
#define DOS_SDA_OFS 0 #define DOS_SDA_OFS 0
#define DOS_MEM_START 0x102 //First Segment that DOS can use #define DOS_CDS_SEG 0x108
#define DOS_FIRST_SHELL 0x118
#define DOS_MEM_START 0x158 //First Segment that DOS can use
#define DOS_PRIVATE_SEGMENT 0xc800 #define DOS_PRIVATE_SEGMENT 0xc800
#define DOS_PRIVATE_SEGMENT_END 0xd000 #define DOS_PRIVATE_SEGMENT_END 0xd000
@ -110,6 +113,7 @@ bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount); bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount);
bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type); bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type);
bool DOS_CloseFile(Bit16u handle); bool DOS_CloseFile(Bit16u handle);
bool DOS_FlushFile(Bit16u handle);
bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry); bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry); bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry);
bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate); bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate);
@ -150,7 +154,7 @@ void DOS_SetupDevices(void);
bool DOS_NewPSP(Bit16u pspseg,Bit16u size); bool DOS_NewPSP(Bit16u pspseg,Bit16u size);
bool DOS_ChildPSP(Bit16u pspseg,Bit16u size); bool DOS_ChildPSP(Bit16u pspseg,Bit16u size);
bool DOS_Execute(char * name,PhysPt block,Bit8u flags); bool DOS_Execute(char * name,PhysPt block,Bit8u flags);
bool DOS_Terminate(bool tsr); bool DOS_Terminate(bool tsr,Bit8u exitcode);
/* Memory Handling Routines */ /* Memory Handling Routines */
void DOS_SetupMemory(void); void DOS_SetupMemory(void);
@ -204,18 +208,18 @@ enum {
}; };
INLINE Bit16u long2para(Bit32u size) { static INLINE Bit16u long2para(Bit32u size) {
if (size>0xFFFF0) return 0xffff; if (size>0xFFFF0) return 0xffff;
if (size&0xf) return (Bit16u)((size>>4)+1); if (size&0xf) return (Bit16u)((size>>4)+1);
else return (Bit16u)(size>>4); else return (Bit16u)(size>>4);
} }
INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) { static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) {
return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f); return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f);
} }
INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) { static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f); return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f);
} }
@ -250,7 +254,7 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
class MemStruct { class MemStruct {
public: public:
INLINE Bitu GetIt(Bitu size,PhysPt addr) { Bitu GetIt(Bitu size,PhysPt addr) {
switch (size) { switch (size) {
case 1:return mem_readb(pt+addr); case 1:return mem_readb(pt+addr);
case 2:return mem_readw(pt+addr); case 2:return mem_readw(pt+addr);
@ -258,16 +262,16 @@ public:
} }
return 0; return 0;
} }
INLINE void SaveIt(Bitu size,PhysPt addr,Bitu val) { void SaveIt(Bitu size,PhysPt addr,Bitu val) {
switch (size) { switch (size) {
case 1:mem_writeb(pt+addr,(Bit8u)val);break; case 1:mem_writeb(pt+addr,(Bit8u)val);break;
case 2:mem_writew(pt+addr,(Bit16u)val);break; case 2:mem_writew(pt+addr,(Bit16u)val);break;
case 4:mem_writed(pt+addr,(Bit32u)val);break; case 4:mem_writed(pt+addr,(Bit32u)val);break;
} }
} }
INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);} void SetPt(Bit16u seg) { pt=PhysMake(seg,0);}
INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);} void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);}
INLINE void SetPt(RealPt addr) { pt=Real2Phys(addr);} void SetPt(RealPt addr) { pt=Real2Phys(addr);}
protected: protected:
PhysPt pt; PhysPt pt;
}; };
@ -502,6 +506,7 @@ public:
bool Extended(void); bool Extended(void);
void GetAttr(Bit8u & attr); void GetAttr(Bit8u & attr);
void SetAttr(Bit8u attr); void SetAttr(Bit8u attr);
bool Valid(void);
private: private:
bool extended; bool extended;
PhysPt real_pt; PhysPt real_pt;
@ -630,7 +635,7 @@ struct DOS_Block {
extern DOS_Block dos; extern DOS_Block dos;
INLINE Bit8u RealHandle(Bit16u handle) { static Bit8u RealHandle(Bit16u handle) {
DOS_PSP psp(dos.psp()); DOS_PSP psp(dos.psp());
return psp.GetFileHandle(handle); return psp.GetFileHandle(handle);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: dos_system.h,v 1.40 2007/06/13 07:25:14 qbix79 Exp $ */ /* $Id: dos_system.h,v 1.47 2009/03/04 21:08:22 c2woody Exp $ */
#ifndef DOSBOX_DOS_SYSTEM_H #ifndef DOSBOX_DOS_SYSTEM_H
#define DOSBOX_DOS_SYSTEM_H #define DOSBOX_DOS_SYSTEM_H
@ -48,7 +48,8 @@ enum {
DOS_ATTR_SYSTEM= 0x04, DOS_ATTR_SYSTEM= 0x04,
DOS_ATTR_VOLUME= 0x08, DOS_ATTR_VOLUME= 0x08,
DOS_ATTR_DIRECTORY= 0x10, DOS_ATTR_DIRECTORY= 0x10,
DOS_ATTR_ARCHIVE= 0x20 DOS_ATTR_ARCHIVE= 0x20,
DOS_ATTR_DEVICE= 0x40
}; };
struct FileStat_Block { struct FileStat_Block {
@ -129,7 +130,7 @@ public:
DOS_Drive_Cache (const char* path); DOS_Drive_Cache (const char* path);
~DOS_Drive_Cache (void); ~DOS_Drive_Cache (void);
typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV }; enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
void SetBaseDir (const char* path); void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; }; void SetDirSort (TDirSort sort) { sortDirType = sort; };
@ -148,7 +149,7 @@ public:
void DeleteEntry (const char* path, bool ignoreLastDir = false); void DeleteEntry (const char* path, bool ignoreLastDir = false);
void EmptyCache (void); void EmptyCache (void);
void SetLabel (const char* name,bool allowupdate=true); void SetLabel (const char* name,bool cdrom,bool allowupdate);
char* GetLabel (void) { return label; }; char* GetLabel (void) { return label; };
class CFileInfo { class CFileInfo {
@ -178,14 +179,15 @@ private:
bool RemoveTrailingDot (char* shortname); bool RemoveTrailingDot (char* shortname);
Bits GetLongName (CFileInfo* info, char* shortname); Bits GetLongName (CFileInfo* info, char* shortname);
void CreateShortName (CFileInfo* dir, CFileInfo* info); void CreateShortName (CFileInfo* dir, CFileInfo* info);
Bit16u CreateShortNameID (CFileInfo* dir, const char* name); Bitu CreateShortNameID (CFileInfo* dir, const char* name);
int CompareShortname (const char* compareName, const char* shortName); int CompareShortname (const char* compareName, const char* shortName);
bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr); bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr);
bool IsCachedIn (CFileInfo* dir); bool IsCachedIn (CFileInfo* dir);
CFileInfo* FindDirInfo (const char* path, char* expandedPath); CFileInfo* FindDirInfo (const char* path, char* expandedPath);
bool RemoveSpaces (char* str); bool RemoveSpaces (char* str);
bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id); bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id);
void CreateEntry (CFileInfo* dir, const char* name); void CreateEntry (CFileInfo* dir, const char* name, bool query_directory);
void CopyEntry (CFileInfo* dir, CFileInfo* from);
Bit16u GetFreeID (CFileInfo* dir); Bit16u GetFreeID (CFileInfo* dir);
void Clear (void); void Clear (void);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: dosbox.h,v 1.31 2008/01/09 20:34:21 c2woody Exp $ */
#ifndef DOSBOX_DOSBOX_H #ifndef DOSBOX_DOSBOX_H
#define DOSBOX_DOSBOX_H #define DOSBOX_DOSBOX_H
@ -44,12 +46,16 @@ enum MachineType {
MCH_CGA, MCH_CGA,
MCH_TANDY, MCH_TANDY,
MCH_PCJR, MCH_PCJR,
MCH_EGA,
MCH_VGA MCH_VGA
}; };
enum SVGACards { enum SVGACards {
SVGA_None, SVGA_None,
SVGA_S3Trio SVGA_S3Trio,
SVGA_TsengET4K,
SVGA_TsengET3K,
SVGA_ParadisePVGA1A
}; };
extern SVGACards svgaCard; extern SVGACards svgaCard;
@ -57,7 +63,11 @@ extern MachineType machine;
extern bool SDLNetInited; extern bool SDLNetInited;
#define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR)) #define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR))
#define IS_EGAVGA_ARCH ((machine==MCH_EGA) || (machine==MCH_VGA))
#define IS_VGA_ARCH (machine==MCH_VGA)
#define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR #define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR
#define EGAVGA_ARCH_CASE MCH_EGA: case MCH_VGA
#define VGA_ARCH_CASE MCH_VGA
#ifndef DOSBOX_LOGGING_H #ifndef DOSBOX_LOGGING_H
#include "logging.h" #include "logging.h"

View File

@ -108,44 +108,44 @@ extern FPU_rec fpu;
Bit16u FPU_GetTag(void); Bit16u FPU_GetTag(void);
void FPU_FLDCW(PhysPt addr); void FPU_FLDCW(PhysPt addr);
INLINE void FPU_SetTag(Bit16u tag){ static INLINE void FPU_SetTag(Bit16u tag){
for(Bitu i=0;i<8;i++) for(Bitu i=0;i<8;i++)
fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3); fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3);
} }
INLINE void FPU_SetCW(Bitu word){ static INLINE void FPU_SetCW(Bitu word){
fpu.cw = (Bit16u)word; fpu.cw = (Bit16u)word;
fpu.cw_mask_all = (Bit16u)(word | 0x3f); fpu.cw_mask_all = (Bit16u)(word | 0x3f);
fpu.round = (FPU_Round)((word >> 10) & 3); fpu.round = (FPU_Round)((word >> 10) & 3);
} }
INLINE Bitu FPU_GET_TOP(void) { static INLINE Bitu FPU_GET_TOP(void) {
return (fpu.sw & 0x3800)>>11; return (fpu.sw & 0x3800)>>11;
} }
INLINE void FPU_SET_TOP(Bitu val){ static INLINE void FPU_SET_TOP(Bitu val){
fpu.sw &= ~0x3800; fpu.sw &= ~0x3800;
fpu.sw |= (val&7)<<11; fpu.sw |= (val&7)<<11;
} }
INLINE void FPU_SET_C0(Bitu C){ static INLINE void FPU_SET_C0(Bitu C){
fpu.sw &= ~0x0100; fpu.sw &= ~0x0100;
if(C) fpu.sw |= 0x0100; if(C) fpu.sw |= 0x0100;
} }
INLINE void FPU_SET_C1(Bitu C){ static INLINE void FPU_SET_C1(Bitu C){
fpu.sw &= ~0x0200; fpu.sw &= ~0x0200;
if(C) fpu.sw |= 0x0200; if(C) fpu.sw |= 0x0200;
} }
INLINE void FPU_SET_C2(Bitu C){ static INLINE void FPU_SET_C2(Bitu C){
fpu.sw &= ~0x0400; fpu.sw &= ~0x0400;
if(C) fpu.sw |= 0x0400; if(C) fpu.sw |= 0x0400;
} }
INLINE void FPU_SET_C3(Bitu C){ static INLINE void FPU_SET_C3(Bitu C){
fpu.sw &= ~0x4000; fpu.sw &= ~0x4000;
if(C) fpu.sw |= 0x4000; if(C) fpu.sw |= 0x4000;
} }

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: inout.h,v 1.11 2007/06/12 20:22:07 c2woody Exp $ */ /* $Id: inout.h,v 1.12 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_INOUT_H #ifndef DOSBOX_INOUT_H
#define DOSBOX_INOUT_H #define DOSBOX_INOUT_H
@ -68,10 +68,10 @@ public:
~IO_WriteHandleObject(); ~IO_WriteHandleObject();
}; };
INLINE void IO_Write(Bitu port,Bit8u val) { static INLINE void IO_Write(Bitu port,Bit8u val) {
IO_WriteB(port,val); IO_WriteB(port,val);
} }
INLINE Bit8u IO_Read(Bitu port){ static INLINE Bit8u IO_Read(Bitu port){
return (Bit8u)IO_ReadB(port); return (Bit8u)IO_ReadB(port);
} }

View File

@ -3,19 +3,19 @@
enum LOG_TYPES { enum LOG_TYPES {
LOG_ALL, LOG_ALL,
LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10, LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10,
LOG_SB,LOG_DMA, LOG_SB,LOG_DMACONTROL,
LOG_FPU,LOG_CPU,LOG_PAGING, LOG_FPU,LOG_CPU,LOG_PAGING,
LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC, LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC,
LOG_PIT,LOG_KEYBOARD,LOG_PIC, LOG_PIT,LOG_KEYBOARD,LOG_PIC,
LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC, LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC,
LOG_IO, LOG_IO,
LOG_MAX, LOG_MAX
}; };
enum LOG_SEVERITIES { enum LOG_SEVERITIES {
LOG_NORMAL, LOG_NORMAL,
LOG_WARN, LOG_WARN,
LOG_ERROR, LOG_ERROR
}; };
#if C_DEBUG #if C_DEBUG
@ -53,7 +53,7 @@ struct LOG
void operator()(char const* , char const* , double ,double ) { } void operator()(char const* , char const* , double ,double ) { }
void operator()(char const* , double , char const* ) { } void operator()(char const* , double , char const* ) { }
void operator()(char const* , double , double, char const* ) { } void operator()(char const* , double , double, char const* ) { }
void operator()(char const* , char const*, char const*) { }
}; //add missing operators to here }; //add missing operators to here

View File

@ -21,7 +21,7 @@
enum MapKeys { enum MapKeys {
MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12, MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12,
MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause, MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause
}; };

View File

@ -59,62 +59,62 @@ MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where);
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY) #if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
INLINE Bit8u host_readb(HostPt off) { static INLINE Bit8u host_readb(HostPt off) {
return off[0]; return off[0];
}; }
INLINE Bit16u host_readw(HostPt off) { static INLINE Bit16u host_readw(HostPt off) {
return off[0] | (off[1] << 8); return off[0] | (off[1] << 8);
}; }
INLINE Bit32u host_readd(HostPt off) { static INLINE Bit32u host_readd(HostPt off) {
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24); return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
}; }
INLINE void host_writeb(HostPt off,Bit8u val) { static INLINE void host_writeb(HostPt off,Bit8u val) {
off[0]=val; off[0]=val;
}; }
INLINE void host_writew(HostPt off,Bit16u val) { static INLINE void host_writew(HostPt off,Bit16u val) {
off[0]=(Bit8u)(val); off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8); off[1]=(Bit8u)(val >> 8);
}; }
INLINE void host_writed(HostPt off,Bit32u val) { static INLINE void host_writed(HostPt off,Bit32u val) {
off[0]=(Bit8u)(val); off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8); off[1]=(Bit8u)(val >> 8);
off[2]=(Bit8u)(val >> 16); off[2]=(Bit8u)(val >> 16);
off[3]=(Bit8u)(val >> 24); off[3]=(Bit8u)(val >> 24);
}; }
#else #else
INLINE Bit8u host_readb(HostPt off) { static INLINE Bit8u host_readb(HostPt off) {
return *(Bit8u *)off; return *(Bit8u *)off;
}; }
INLINE Bit16u host_readw(HostPt off) { static INLINE Bit16u host_readw(HostPt off) {
return *(Bit16u *)off; return *(Bit16u *)off;
}; }
INLINE Bit32u host_readd(HostPt off) { static INLINE Bit32u host_readd(HostPt off) {
return *(Bit32u *)off; return *(Bit32u *)off;
}; }
INLINE void host_writeb(HostPt off,Bit8u val) { static INLINE void host_writeb(HostPt off,Bit8u val) {
*(Bit8u *)(off)=val; *(Bit8u *)(off)=val;
}; }
INLINE void host_writew(HostPt off,Bit16u val) { static INLINE void host_writew(HostPt off,Bit16u val) {
*(Bit16u *)(off)=val; *(Bit16u *)(off)=val;
}; }
INLINE void host_writed(HostPt off,Bit32u val) { static INLINE void host_writed(HostPt off,Bit32u val) {
*(Bit32u *)(off)=val; *(Bit32u *)(off)=val;
}; }
#endif #endif
INLINE void var_write(Bit8u * var, Bit8u val) { static INLINE void var_write(Bit8u * var, Bit8u val) {
host_writeb((HostPt)var, val); host_writeb((HostPt)var, val);
} }
INLINE void var_write(Bit16u * var, Bit16u val) { static INLINE void var_write(Bit16u * var, Bit16u val) {
host_writew((HostPt)var, val); host_writew((HostPt)var, val);
} }
INLINE void var_write(Bit32u * var, Bit32u val) { static INLINE void var_write(Bit32u * var, Bit32u val) {
host_writed((HostPt)var, val); host_writed((HostPt)var, val);
} }
@ -128,23 +128,23 @@ void mem_writeb(PhysPt pt,Bit8u val);
void mem_writew(PhysPt pt,Bit16u val); void mem_writew(PhysPt pt,Bit16u val);
void mem_writed(PhysPt pt,Bit32u val); void mem_writed(PhysPt pt,Bit32u val);
INLINE void phys_writeb(PhysPt addr,Bit8u val) { static INLINE void phys_writeb(PhysPt addr,Bit8u val) {
host_writeb(MemBase+addr,val); host_writeb(MemBase+addr,val);
} }
INLINE void phys_writew(PhysPt addr,Bit16u val){ static INLINE void phys_writew(PhysPt addr,Bit16u val){
host_writew(MemBase+addr,val); host_writew(MemBase+addr,val);
} }
INLINE void phys_writed(PhysPt addr,Bit32u val){ static INLINE void phys_writed(PhysPt addr,Bit32u val){
host_writed(MemBase+addr,val); host_writed(MemBase+addr,val);
} }
INLINE Bit8u phys_readb(PhysPt addr) { static INLINE Bit8u phys_readb(PhysPt addr) {
return host_readb(MemBase+addr); return host_readb(MemBase+addr);
} }
INLINE Bit16u phys_readw(PhysPt addr){ static INLINE Bit16u phys_readw(PhysPt addr){
return host_readw(MemBase+addr); return host_readw(MemBase+addr);
} }
INLINE Bit32u phys_readd(PhysPt addr){ static INLINE Bit32u phys_readd(PhysPt addr){
return host_readd(MemBase+addr); return host_readd(MemBase+addr);
} }
@ -161,57 +161,57 @@ void mem_strcpy(PhysPt dest,PhysPt src);
/* The folowing functions are all shortcuts to the above functions using physical addressing */ /* The folowing functions are all shortcuts to the above functions using physical addressing */
INLINE Bit8u real_readb(Bit16u seg,Bit16u off) { static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) {
return mem_readb((seg<<4)+off); return mem_readb((seg<<4)+off);
} }
INLINE Bit16u real_readw(Bit16u seg,Bit16u off) { static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) {
return mem_readw((seg<<4)+off); return mem_readw((seg<<4)+off);
} }
INLINE Bit32u real_readd(Bit16u seg,Bit16u off) { static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) {
return mem_readd((seg<<4)+off); return mem_readd((seg<<4)+off);
} }
INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) { static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) {
mem_writeb(((seg<<4)+off),val); mem_writeb(((seg<<4)+off),val);
} }
INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) { static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) {
mem_writew(((seg<<4)+off),val); mem_writew(((seg<<4)+off),val);
} }
INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) { static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) {
mem_writed(((seg<<4)+off),val); mem_writed(((seg<<4)+off),val);
} }
INLINE Bit16u RealSeg(RealPt pt) { static INLINE Bit16u RealSeg(RealPt pt) {
return (Bit16u)(pt>>16); return (Bit16u)(pt>>16);
} }
INLINE Bit16u RealOff(RealPt pt) { static INLINE Bit16u RealOff(RealPt pt) {
return (Bit16u)(pt&0xffff); return (Bit16u)(pt&0xffff);
} }
INLINE PhysPt Real2Phys(RealPt pt) { static INLINE PhysPt Real2Phys(RealPt pt) {
return (RealSeg(pt)<<4) +RealOff(pt); return (RealSeg(pt)<<4) +RealOff(pt);
} }
INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) { static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) {
return (seg<<4)+off; return (seg<<4)+off;
} }
INLINE RealPt RealMake(Bit16u seg,Bit16u off) { static INLINE RealPt RealMake(Bit16u seg,Bit16u off) {
return (seg<<16)+off; return (seg<<16)+off;
} }
INLINE void RealSetVec(Bit8u vec,RealPt pt) { static INLINE void RealSetVec(Bit8u vec,RealPt pt) {
mem_writed(vec<<2,pt); mem_writed(vec<<2,pt);
} }
INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) { static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) {
old = mem_readd(vec<<2); old = mem_readd(vec<<2);
mem_writed(vec<<2,pt); mem_writed(vec<<2,pt);
} }
INLINE RealPt RealGetVec(Bit8u vec) { static INLINE RealPt RealGetVec(Bit8u vec) {
return mem_readd(vec<<2); return mem_readd(vec<<2);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: mixer.h,v 1.19 2009/04/28 21:48:24 harekiet Exp $ */
#ifndef DOSBOX_MIXER_H #ifndef DOSBOX_MIXER_H
#define DOSBOX_MIXER_H #define DOSBOX_MIXER_H
@ -33,7 +35,7 @@ enum BlahModes {
enum MixerModes { enum MixerModes {
M_8M,M_8S, M_8M,M_8S,
M_16M,M_16S, M_16M,M_16S
}; };
#define MIXER_BUFSIZE (16*1024) #define MIXER_BUFSIZE (16*1024)
@ -46,25 +48,38 @@ extern Bit8u MixTemp[MIXER_BUFSIZE];
class MixerChannel { class MixerChannel {
public: public:
void SetVolume(float _left,float _right); void SetVolume(float _left,float _right);
void SetScale( float f );
void UpdateVolume(void); void UpdateVolume(void);
void SetFreq(Bitu _freq); void SetFreq(Bitu _freq);
void Mix(Bitu _needed); void Mix(Bitu _needed);
void AddSilence(void); //Fill up until needed void AddSilence(void); //Fill up until needed
template<bool _8bit,bool stereo,bool signeddata>
void AddSamples(Bitu len,void * data); template<class Type,bool stereo,bool signeddata,bool nativeorder>
void AddSamples_m8(Bitu len,Bit8u * data); void AddSamples(Bitu len, const Type* data);
void AddSamples_s8(Bitu len,Bit8u * data);
void AddSamples_m8s(Bitu len,Bit8s * data); void AddSamples_m8(Bitu len, const Bit8u * data);
void AddSamples_s8s(Bitu len,Bit8s * data); void AddSamples_s8(Bitu len, const Bit8u * data);
void AddSamples_m16(Bitu len,Bit16s * data); void AddSamples_m8s(Bitu len, const Bit8s * data);
void AddSamples_s16(Bitu len,Bit16s * data); void AddSamples_s8s(Bitu len, const Bit8s * data);
void AddSamples_m16u(Bitu len,Bit16u * data); void AddSamples_m16(Bitu len, const Bit16s * data);
void AddSamples_s16u(Bitu len,Bit16u * data); void AddSamples_s16(Bitu len, const Bit16s * data);
void AddSamples_m16u(Bitu len, const Bit16u * data);
void AddSamples_s16u(Bitu len, const Bit16u * data);
void AddSamples_m32(Bitu len, const Bit32s * data);
void AddSamples_s32(Bitu len, const Bit32s * data);
void AddSamples_m16_nonnative(Bitu len, const Bit16s * data);
void AddSamples_s16_nonnative(Bitu len, const Bit16s * data);
void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data);
void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data);
void AddSamples_m32_nonnative(Bitu len, const Bit32s * data);
void AddSamples_s32_nonnative(Bitu len, const Bit32s * data);
void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data
void FillUp(void); void FillUp(void);
void Enable(bool _yesno); void Enable(bool _yesno);
MIXER_Handler handler; MIXER_Handler handler;
float volmain[2]; float volmain[2];
float scale;
Bit32s volmul[2]; Bit32s volmul[2];
Bitu freq_add,freq_index; Bitu freq_add,freq_index;
Bitu done,needed; Bitu done,needed;

View File

@ -16,17 +16,21 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: mouse.h,v 1.13 2007/01/08 19:45:37 qbix79 Exp $ */ /* $Id: mouse.h,v 1.14 2008/03/08 22:04:44 c2woody Exp $ */
#ifndef DOSBOX_MOUSE_H #ifndef DOSBOX_MOUSE_H
#define DOSBOX_MOUSE_H #define DOSBOX_MOUSE_H
void Mouse_ShowCursor(void); void Mouse_ShowCursor(void);
void Mouse_HideCursor(void); void Mouse_HideCursor(void);
bool Mouse_SetPS2State(bool use); bool Mouse_SetPS2State(bool use);
void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs); void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs);
void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate); void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate);
void Mouse_CursorSet(float x,float y); void Mouse_CursorSet(float x,float y);
void Mouse_ButtonPressed(Bit8u button); void Mouse_ButtonPressed(Bit8u button);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: paging.h,v 1.25 2007/06/12 20:22:07 c2woody Exp $ */ /* $Id: paging.h,v 1.32 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_PAGING_H #ifndef DOSBOX_PAGING_H
#define DOSBOX_PAGING_H #define DOSBOX_PAGING_H
@ -28,11 +28,23 @@
#include "mem.h" #include "mem.h"
#endif #endif
// disable this to reduce the size of the TLB
// NOTE: does not work with the dynamic core (dynrec is fine)
#define USE_FULL_TLB
class PageDirectory; class PageDirectory;
#define MEM_PAGE_SIZE (4096) #define MEM_PAGE_SIZE (4096)
#define XMS_START (0x110) #define XMS_START (0x110)
#if defined(USE_FULL_TLB)
#define TLB_SIZE (1024*1024) #define TLB_SIZE (1024*1024)
#else
#define TLB_SIZE 65536 // This must a power of 2 and greater then LINK_START
#define BANK_SHIFT 28
#define BANK_MASK 0xffff // always the same as TLB_SIZE-1?
#define TLB_BANKS ((1024*1024/TLB_SIZE)-1)
#endif
#define PFLAG_READABLE 0x1 #define PFLAG_READABLE 0x1
#define PFLAG_WRITEABLE 0x2 #define PFLAG_WRITEABLE 0x2
@ -57,9 +69,9 @@ public:
virtual void writed(PhysPt addr,Bitu val); virtual void writed(PhysPt addr,Bitu val);
virtual HostPt GetHostReadPt(Bitu phys_page); virtual HostPt GetHostReadPt(Bitu phys_page);
virtual HostPt GetHostWritePt(Bitu phys_page); virtual HostPt GetHostWritePt(Bitu phys_page);
virtual bool readb_checked(PhysPt addr, Bitu * val); virtual bool readb_checked(PhysPt addr,Bit8u * val);
virtual bool readw_checked(PhysPt addr, Bitu * val); virtual bool readw_checked(PhysPt addr,Bit16u * val);
virtual bool readd_checked(PhysPt addr, Bitu * val); virtual bool readd_checked(PhysPt addr,Bit32u * val);
virtual bool writeb_checked(PhysPt addr,Bitu val); virtual bool writeb_checked(PhysPt addr,Bitu val);
virtual bool writew_checked(PhysPt addr,Bitu val); virtual bool writew_checked(PhysPt addr,Bitu val);
virtual bool writed_checked(PhysPt addr,Bitu val); virtual bool writed_checked(PhysPt addr,Bitu val);
@ -76,12 +88,14 @@ void PAGING_InitTLB(void);
void PAGING_ClearTLB(void); void PAGING_ClearTLB(void);
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page); void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page);
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages); void PAGING_UnlinkPages(Bitu lin_page,Bitu pages);
/* This maps the page directly, only use when paging is disabled */ /* This maps the page directly, only use when paging is disabled */
void PAGING_MapPage(Bitu lin_page,Bitu phys_page); void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
bool PAGING_MakePhysPage(Bitu & page); bool PAGING_MakePhysPage(Bitu & page);
bool PAGING_ForcePageInit(Bitu lin_addr);
void MEM_SetLFB( Bitu page, Bitu pages, PageHandler *handler); void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler);
void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler); void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler);
void MEM_ResetPageHandler(Bitu phys_page, Bitu pages); void MEM_ResetPageHandler(Bitu phys_page, Bitu pages);
@ -126,6 +140,16 @@ union X86PageEntry {
X86_PageEntryBlock block; X86_PageEntryBlock block;
}; };
#if !defined(USE_FULL_TLB)
typedef struct {
HostPt read;
HostPt write;
PageHandler * readhandler;
PageHandler * writehandler;
Bit32u phys_page;
} tlb_entry;
#endif
struct PagingBlock { struct PagingBlock {
Bitu cr3; Bitu cr3;
Bitu cr2; Bitu cr2;
@ -133,12 +157,18 @@ struct PagingBlock {
Bitu page; Bitu page;
PhysPt addr; PhysPt addr;
} base; } base;
#if defined(USE_FULL_TLB)
struct { struct {
HostPt read[TLB_SIZE]; HostPt read[TLB_SIZE];
HostPt write[TLB_SIZE]; HostPt write[TLB_SIZE];
PageHandler * handler[TLB_SIZE]; PageHandler * readhandler[TLB_SIZE];
PageHandler * writehandler[TLB_SIZE];
Bit32u phys_page[TLB_SIZE]; Bit32u phys_page[TLB_SIZE];
} tlb; } tlb;
#else
tlb_entry tlbh[TLB_SIZE];
tlb_entry *tlbh_banks[TLB_BANKS];
#endif
struct { struct {
Bitu used; Bitu used;
Bit32u entries[PAGING_LINKS]; Bit32u entries[PAGING_LINKS];
@ -153,15 +183,6 @@ extern PagingBlock paging;
PageHandler * MEM_GetPageHandler(Bitu phys_page); PageHandler * MEM_GetPageHandler(Bitu phys_page);
/* Use this helper function to access linear addresses in readX/writeX functions */
INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
return (paging.tlb.phys_page[linePage>>12]<<12);
}
INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff);
}
/* Unaligned address handlers */ /* Unaligned address handlers */
Bit16u mem_unalignedreadw(PhysPt address); Bit16u mem_unalignedreadw(PhysPt address);
@ -169,173 +190,176 @@ Bit32u mem_unalignedreadd(PhysPt address);
void mem_unalignedwritew(PhysPt address,Bit16u val); void mem_unalignedwritew(PhysPt address,Bit16u val);
void mem_unalignedwrited(PhysPt address,Bit32u val); void mem_unalignedwrited(PhysPt address,Bit32u val);
bool mem_unalignedreadw_checked_x86(PhysPt address,Bit16u * val); bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val);
bool mem_unalignedreadd_checked_x86(PhysPt address,Bit32u * val); bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val);
bool mem_unalignedwritew_checked_x86(PhysPt address,Bit16u val); bool mem_unalignedwritew_checked(PhysPt address,Bit16u val);
bool mem_unalignedwrited_checked_x86(PhysPt address,Bit32u val); bool mem_unalignedwrited_checked(PhysPt address,Bit32u val);
#if defined(USE_FULL_TLB)
static INLINE HostPt get_tlb_read(PhysPt address) {
return paging.tlb.read[address>>12];
}
static INLINE HostPt get_tlb_write(PhysPt address) {
return paging.tlb.write[address>>12];
}
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
return paging.tlb.readhandler[address>>12];
}
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
return paging.tlb.writehandler[address>>12];
}
/* Use these helper functions to access linear addresses in readX/writeX functions */
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
return (paging.tlb.phys_page[linePage>>12]<<12);
}
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff);
}
#else
void PAGING_InitTLBBank(tlb_entry **bank);
static INLINE tlb_entry *get_tlb_entry(PhysPt address) {
Bitu index=(address>>12);
if (TLB_BANKS && (index > TLB_SIZE)) {
Bitu bank=(address>>BANK_SHIFT) - 1;
if (!paging.tlbh_banks[bank])
PAGING_InitTLBBank(&paging.tlbh_banks[bank]);
return &paging.tlbh_banks[bank][index & BANK_MASK];
}
return &paging.tlbh[index];
}
static INLINE HostPt get_tlb_read(PhysPt address) {
return get_tlb_entry(address)->read;
}
static INLINE HostPt get_tlb_write(PhysPt address) {
return get_tlb_entry(address)->write;
}
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
return get_tlb_entry(address)->readhandler;
}
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
return get_tlb_entry(address)->writehandler;
}
/* Use these helper functions to access linear addresses in readX/writeX functions */
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
tlb_entry *entry = get_tlb_entry(linePage);
return (entry->phys_page<<12);
}
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
tlb_entry *entry = get_tlb_entry(linAddr);
return (entry->phys_page<<12)|(linAddr&0xfff);
}
#endif
/* Special inlined memory reading/writing */ /* Special inlined memory reading/writing */
INLINE Bit8u mem_readb_inline(PhysPt address) { static INLINE Bit8u mem_readb_inline(PhysPt address) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address); if (tlb_addr) return host_readb(tlb_addr+address);
else return (Bit8u)paging.tlb.handler[index]->readb(address); else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
} }
INLINE Bit16u mem_readw_inline(PhysPt address) { static INLINE Bit16u mem_readw_inline(PhysPt address) {
if (!(address & 1)) { if ((address & 0xfff)<0xfff) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readw(tlb_addr+address);
if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address); else return (Bit16u)(get_tlb_readhandler(address))->readw(address);
else return (Bit16u) paging.tlb.handler[index]->readw(address);
} else return mem_unalignedreadw(address); } else return mem_unalignedreadw(address);
} }
INLINE Bit32u mem_readd_inline(PhysPt address) { static INLINE Bit32u mem_readd_inline(PhysPt address) {
if (!(address & 3)) { if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (tlb_addr) return host_readd(tlb_addr+address);
if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address); else return (get_tlb_readhandler(address))->readd(address);
else return paging.tlb.handler[index]->readd(address);
} else return mem_unalignedreadd(address); } else return mem_unalignedreadd(address);
} }
INLINE void mem_writeb_inline(PhysPt address,Bit8u val) { static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writeb(tlb_addr+address,val);
if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val); else (get_tlb_writehandler(address))->writeb(address,val);
else paging.tlb.handler[index]->writeb(address,val);
} }
INLINE void mem_writew_inline(PhysPt address,Bit16u val) { static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
if (!(address & 1)) { if ((address & 0xfff)<0xfff) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writew(tlb_addr+address,val);
if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val); else (get_tlb_writehandler(address))->writew(address,val);
else paging.tlb.handler[index]->writew(address,val);
} else mem_unalignedwritew(address,val); } else mem_unalignedwritew(address,val);
} }
INLINE void mem_writed_inline(PhysPt address,Bit32u val) { static INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
if (!(address & 3)) { if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (tlb_addr) host_writed(tlb_addr+address,val);
if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val); else (get_tlb_writehandler(address))->writed(address,val);
else paging.tlb.handler[index]->writed(address,val);
} else mem_unalignedwrited(address,val); } else mem_unalignedwrited(address,val);
} }
INLINE Bit16u mem_readw_dyncorex86(PhysPt address) { static INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) {
if ((address & 0xfff)<0xfff) { HostPt tlb_addr=get_tlb_read(address);
Bitu index=(address>>12); if (tlb_addr) {
*val=host_readb(tlb_addr+address);
if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address);
else return (Bit16u)paging.tlb.handler[index]->readw(address);
} else return mem_unalignedreadw(address);
}
INLINE Bit32u mem_readd_dyncorex86(PhysPt address) {
if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12);
if (paging.tlb.read[index]) return host_readd(paging.tlb.read[index]+address);
else return paging.tlb.handler[index]->readd(address);
} else return mem_unalignedreadd(address);
}
INLINE void mem_writew_dyncorex86(PhysPt address,Bit16u val) {
if ((address & 0xfff)<0xfff) {
Bitu index=(address>>12);
if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val);
else paging.tlb.handler[index]->writew(address,val);
} else mem_unalignedwritew(address,val);
}
INLINE void mem_writed_dyncorex86(PhysPt address,Bit32u val) {
if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12);
if (paging.tlb.write[index]) host_writed(paging.tlb.write[index]+address,val);
else paging.tlb.handler[index]->writed(address,val);
} else mem_unalignedwrited(address,val);
}
INLINE bool mem_readb_checked_x86(PhysPt address, Bit8u * val) {
Bitu index=(address>>12);
if (paging.tlb.read[index]) {
*val=host_readb(paging.tlb.read[index]+address);
return false; return false;
} else { } else return (get_tlb_readhandler(address))->readb_checked(address, val);
Bitu uval;
bool retval;
retval=paging.tlb.handler[index]->readb_checked(address, &uval);
*val=(Bit8u)uval;
return retval;
}
} }
INLINE bool mem_readw_checked_x86(PhysPt address, Bit16u * val) { static INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) {
if ((address & 0xfff)<0xfff) { if ((address & 0xfff)<0xfff) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (paging.tlb.read[index]) { if (tlb_addr) {
*val=host_readw(paging.tlb.read[index]+address); *val=host_readw(tlb_addr+address);
return false; return false;
} else { } else return (get_tlb_readhandler(address))->readw_checked(address, val);
Bitu uval; } else return mem_unalignedreadw_checked(address, val);
bool retval;
retval=paging.tlb.handler[index]->readw_checked(address, &uval);
*val=(Bit16u)uval;
return retval;
}
} else return mem_unalignedreadw_checked_x86(address, val);
} }
static INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) {
INLINE bool mem_readd_checked_x86(PhysPt address, Bit32u * val) {
if ((address & 0xfff)<0xffd) { if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (paging.tlb.read[index]) { if (tlb_addr) {
*val=host_readd(paging.tlb.read[index]+address); *val=host_readd(tlb_addr+address);
return false; return false;
} else { } else return (get_tlb_readhandler(address))->readd_checked(address, val);
Bitu uval; } else return mem_unalignedreadd_checked(address, val);
bool retval;
retval=paging.tlb.handler[index]->readd_checked(address, &uval);
*val=(Bit32u)uval;
return retval;
}
} else return mem_unalignedreadd_checked_x86(address, val);
} }
INLINE bool mem_writeb_checked_x86(PhysPt address,Bit8u val) { static INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (paging.tlb.write[index]) { if (tlb_addr) {
host_writeb(paging.tlb.write[index]+address,val); host_writeb(tlb_addr+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writeb_checked(address,val); } else return (get_tlb_writehandler(address))->writeb_checked(address,val);
} }
INLINE bool mem_writew_checked_x86(PhysPt address,Bit16u val) { static INLINE bool mem_writew_checked(PhysPt address,Bit16u val) {
if ((address & 0xfff)<0xfff) { if ((address & 0xfff)<0xfff) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (paging.tlb.write[index]) { if (tlb_addr) {
host_writew(paging.tlb.write[index]+address,val); host_writew(tlb_addr+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writew_checked(address,val); } else return (get_tlb_writehandler(address))->writew_checked(address,val);
} else return mem_unalignedwritew_checked_x86(address,val); } else return mem_unalignedwritew_checked(address,val);
} }
INLINE bool mem_writed_checked_x86(PhysPt address,Bit32u val) { static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) {
if ((address & 0xfff)<0xffd) { if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (paging.tlb.write[index]) { if (tlb_addr) {
host_writed(paging.tlb.write[index]+address,val); host_writed(tlb_addr+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writed_checked(address,val); } else return (get_tlb_writehandler(address))->writed_checked(address,val);
} else return mem_unalignedwrited_checked_x86(address,val); } else return mem_unalignedwrited_checked(address,val);
} }

View File

@ -36,19 +36,19 @@ extern Bitu PIC_IRQCheck;
extern Bitu PIC_IRQActive; extern Bitu PIC_IRQActive;
extern Bitu PIC_Ticks; extern Bitu PIC_Ticks;
INLINE float PIC_TickIndex(void) { static INLINE float PIC_TickIndex(void) {
return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax; return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax;
} }
INLINE Bits PIC_TickIndexND(void) { static INLINE Bits PIC_TickIndexND(void) {
return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles; return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles;
} }
INLINE Bits PIC_MakeCycles(double amount) { static INLINE Bits PIC_MakeCycles(double amount) {
return (Bits)(CPU_CycleMax*amount); return (Bits)(CPU_CycleMax*amount);
} }
INLINE double PIC_FullIndex(void) { static INLINE double PIC_FullIndex(void) {
return PIC_Ticks+(double)PIC_TickIndex(); return PIC_Ticks+(double)PIC_TickIndex();
} }

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: programs.h,v 1.18 2009/03/11 20:18:37 qbix79 Exp $ */
#ifndef DOSBOX_PROGRAMS_H #ifndef DOSBOX_PROGRAMS_H
#define DOSBOX_PROGRAMS_H #define DOSBOX_PROGRAMS_H
@ -25,10 +27,41 @@
#ifndef DOSBOX_DOS_INC_H #ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h" #include "dos_inc.h"
#endif #endif
#ifndef DOSBOX_SETUP_H
#include "setup.h" #ifndef CH_LIST
#define CH_LIST
#include <list>
#endif #endif
#ifndef CH_STRING
#define CH_STRING
#include <string>
#endif
class CommandLine {
public:
CommandLine(int argc,char const * const argv[]);
CommandLine(char const * const name,char const * const cmdline);
const char * GetFileName(){ return file_name.c_str();}
bool FindExist(char const * const name,bool remove=false);
bool FindHex(char const * const name,int & value,bool remove=false);
bool FindInt(char const * const name,int & value,bool remove=false);
bool FindString(char const * const name,std::string & value,bool remove=false);
bool FindCommand(unsigned int which,std::string & value);
bool FindStringBegin(char const * const begin,std::string & value, bool remove=false);
bool FindStringRemain(char const * const name,std::string & value);
bool GetStringRemain(std::string & value);
unsigned int GetCount(void);
void Shift(unsigned int amount=1);
Bit16u Get_arglength();
private:
typedef std::list<std::string>::iterator cmd_it;
std::list<std::string> cmds;
std::string file_name;
bool FindEntry(char const * const name,cmd_it & it,bool neednext=false);
};
class Program { class Program {
public: public:
@ -46,6 +79,8 @@ public:
Bitu GetEnvCount(void); Bitu GetEnvCount(void);
bool SetEnv(const char * entry,const char * new_string); bool SetEnv(const char * entry,const char * new_string);
void WriteOut(const char * format,...); /* Write to standard output */ void WriteOut(const char * format,...); /* Write to standard output */
void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */
void ChangeToLongCmd();
}; };

View File

@ -93,20 +93,20 @@ struct CPU_Regs {
extern Segments Segs; extern Segments Segs;
extern CPU_Regs cpu_regs; extern CPU_Regs cpu_regs;
INLINE PhysPt SegPhys(SegNames index) { static INLINE PhysPt SegPhys(SegNames index) {
return Segs.phys[index]; return Segs.phys[index];
} }
INLINE Bit16u SegValue(SegNames index) { static INLINE Bit16u SegValue(SegNames index) {
return (Bit16u)Segs.val[index]; return (Bit16u)Segs.val[index];
} }
INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) { static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
return RealMake(SegValue(index),off); return RealMake(SegValue(index),off);
} }
INLINE void SegSet16(Bitu index,Bit16u val) { static INLINE void SegSet16(Bitu index,Bit16u val) {
Segs.val[index]=val; Segs.val[index]=val;
Segs.phys[index]=val << 4; Segs.phys[index]=val << 4;
} }
@ -118,7 +118,7 @@ enum {
enum { enum {
REGI_AL, REGI_CL, REGI_DL, REGI_BL, REGI_AL, REGI_CL, REGI_DL, REGI_BL,
REGI_AH, REGI_CH, REGI_DH, REGI_BH, REGI_AH, REGI_CH, REGI_DH, REGI_BH
}; };

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: serialport.h,v 1.14 2007/01/13 08:35:49 qbix79 Exp $ */ /* $Id: serialport.h,v 1.16 2009/02/01 14:11:45 qbix79 Exp $ */
#ifndef DOSBOX_SERIALPORT_H #ifndef DOSBOX_SERIALPORT_H
#define DOSBOX_SERIALPORT_H #define DOSBOX_SERIALPORT_H
@ -35,9 +35,12 @@
#ifndef DOSBOX_TIMER_H #ifndef DOSBOX_TIMER_H
#include "timer.h" #include "timer.h"
#endif #endif
#ifndef DOSBOX_DOS_INC_H
#include "dos_inc.h" #include "dos_inc.h"
#include "setup.h" #endif
#ifndef DOSBOX_PROGRAMS_H
#include "programs.h"
#endif
#if SERIAL_DEBUG #if SERIAL_DEBUG
#include "hardware.h" #include "hardware.h"
@ -167,7 +170,7 @@ public:
void Init_Registers(); void Init_Registers();
bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout); bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout);
bool Getchar(Bit8u* data, bool wait_dsr, Bitu timeout); bool Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout);
private: private:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,113 +16,207 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: setup.h,v 1.27 2007/06/14 08:23:46 qbix79 Exp $ */ /* $Id: setup.h,v 1.40 2009/02/15 20:01:08 qbix79 Exp $ */
#ifndef DOSBOX_SETUP_H #ifndef DOSBOX_SETUP_H
#define DOSBOX_SETUP_H #define DOSBOX_SETUP_H
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning ( disable : 4786 ) #pragma warning ( disable : 4786 )
#pragma warning ( disable : 4290 )
#endif #endif
#ifndef DOSBOX_CROSS_H
#include "cross.h" #ifndef CH_LIST
#endif #define CH_LIST
#include <string>
#include <list> #include <list>
#endif
class CommandLine { #ifndef CH_VECTOR
public: #define CH_VECTOR
CommandLine(int argc,char const * const argv[]); #include <vector>
CommandLine(char const * const name,char const * const cmdline); #endif
const char * GetFileName(){ return file_name.c_str();}
bool FindExist(char const * const name,bool remove=false); #ifndef CH_STRING
bool FindHex(char const * const name,int & value,bool remove=false); #define CH_STRING
bool FindInt(char const * const name,int & value,bool remove=false); #include <string>
bool FindString(char const * const name,std::string & value,bool remove=false); #endif
bool FindCommand(unsigned int which,std::string & value);
bool FindStringBegin(char const * const begin,std::string & value, bool remove=false);
bool FindStringRemain(char const * const name,std::string & value); class Hex {
bool GetStringRemain(std::string & value);
unsigned int GetCount(void);
void Shift(unsigned int amount=1);
private: private:
typedef std::list<std::string>::iterator cmd_it; int _hex;
std::list<std::string> cmds; public:
std::string file_name; Hex(int in):_hex(in) { };
bool FindEntry(char const * const name,cmd_it & it,bool neednext=false); Hex():_hex(0) { };
bool operator==(Hex const& other) {return _hex == other._hex;}
operator int () const { return _hex; }
}; };
union Value{ class Value {
int _hex; /*
* Multitype storage container that is aware of the currently stored type in it.
* Value st = "hello";
* Value in = 1;
* st = 12 //Exception
* in = 12 //works
*/
private:
Hex _hex;
bool _bool; bool _bool;
int _int; int _int;
std::string* _string; std::string* _string;
float _float; double _double;
public:
class WrongType { }; // Conversion error class
enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type;
/* Constructors */
Value() :_string(0), type(V_NONE) { };
Value(Hex in) :_hex(in), type(V_HEX) { };
Value(int in) :_int(in), type(V_INT) { };
Value(bool in) :_bool(in), type(V_BOOL) { };
Value(double in) :_double(in), type(V_DOUBLE) { };
Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { };
Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { };
Value(Value const& in):_string(0) {plaincopy(in);}
~Value() { destroy();};
Value(std::string const& in,Etype _t) :_string(0),type(V_NONE) {SetValue(in,_t);}
/* Assigment operators */
Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));}
Value& operator= (int in) throw(WrongType) { return copy(Value(in));}
Value& operator= (bool in) throw(WrongType) { return copy(Value(in));}
Value& operator= (double in) throw(WrongType) { return copy(Value(in));}
Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));}
Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));}
Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));}
bool operator== (Value const & other);
operator bool () const throw(WrongType);
operator Hex () const throw(WrongType);
operator int () const throw(WrongType);
operator double () const throw(WrongType);
operator char const* () const throw(WrongType);
void SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType);
std::string ToString() const;
private:
void destroy() throw();
Value& copy(Value const& in) throw(WrongType);
void plaincopy(Value const& in) throw();
void set_hex(std::string const& in);
void set_int(std::string const&in);
void set_bool(std::string const& in);
void set_string(std::string const& in);
void set_double(std::string const& in);
}; };
class Property { class Property {
public: public:
Property(char const * const _propname):propname(_propname) { } struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};};
virtual void SetValue(char* input)=0; const std::string propname;
virtual void GetValuestring(char* str) const=0;
Value GetValue() const { return value;} Property(std::string const& _propname, Changeable::Value when):propname(_propname),change(when) { }
void Set_values(const char * const * in);
void Set_help(std::string const& str);
char const* Get_help();
virtual void SetValue(std::string const& str)=0;
Value const& GetValue() const { return value;}
Value const& Get_Default_Value() const { return default_value; }
//CheckValue returns true if value is in suggested_values;
//Type specific properties are encouraged to override this and check for type
//specific features.
virtual bool CheckValue(Value const& in, bool warn);
//Set interval value to in or default if in is invalid. force always sets the value.
void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;}
virtual ~Property(){ } virtual ~Property(){ }
std::string propname; virtual const std::vector<Value>& GetValues() const;
Value::Etype Get_type(){return default_value.type;}
protected:
Value value; Value value;
std::vector<Value> suggested_values;
typedef std::vector<Value>::iterator iter;
Value default_value;
const Changeable::Value change;
}; };
class Prop_int:public Property { class Prop_int:public Property {
public: public:
Prop_int(char const * const _propname, int _value):Property(_propname) { Prop_int(std::string const& _propname,Changeable::Value when, int _value)
value._int=_value; :Property(_propname,when) {
default_value = value = _value;
min = max = -1;
} }
void SetValue(char* input); Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value)
void GetValuestring(char* str) const; :Property(_propname,when) {
default_value = value = _value;
min = _min;
max = _max;
}
void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;}
void SetValue(std::string const& in);
~Prop_int(){ } ~Prop_int(){ }
virtual bool CheckValue(Value const& in, bool warn);
private:
Value min,max;
}; };
class Prop_float:public Property {
class Prop_double:public Property {
public: public:
Prop_float(char const * const _propname, float _value):Property(_propname){ Prop_double(std::string const & _propname, Changeable::Value when, double _value)
value._float=_value; :Property(_propname,when){
default_value = value = _value;
} }
void SetValue(char* input); void SetValue(std::string const& input);
void GetValuestring(char* str) const; ~Prop_double(){ }
~Prop_float(){ }
}; };
class Prop_bool:public Property { class Prop_bool:public Property {
public: public:
Prop_bool(char const * const _propname, bool _value):Property(_propname) { Prop_bool(std::string const& _propname, Changeable::Value when, bool _value)
value._bool=_value; :Property(_propname,when) {
default_value = value = _value;
} }
void SetValue(char* input); void SetValue(std::string const& in);
void GetValuestring(char* str) const;
~Prop_bool(){ } ~Prop_bool(){ }
}; };
class Prop_string:public Property{ class Prop_string:public Property{
public: public:
Prop_string(char const * const _propname, char const * const _value):Property(_propname) { Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value)
value._string=new std::string(_value); :Property(_propname,when) {
default_value = value = _value;
} }
~Prop_string(){ void SetValue(std::string const& in);
delete value._string; virtual bool CheckValue(Value const& in, bool warn);
} ~Prop_string(){ }
void SetValue(char* input);
void GetValuestring(char* str) const;
}; };
class Prop_hex:public Property { class Prop_path:public Prop_string{
public: public:
Prop_hex(char const * const _propname, int _value):Property(_propname) { std::string realpath;
value._hex=_value; Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value)
:Prop_string(_propname,when,_value) {
default_value = value = _value;
realpath = _value;
} }
void SetValue(char* input); void SetValue(std::string const& in);
~Prop_hex(){ } ~Prop_path(){ }
void GetValuestring(char* str) const;
}; };
class Prop_hex:public Property {
public:
Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value)
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
~Prop_hex(){ }
};
#define NO_SUCH_PROPERTY "PROP_NOT_EXIST"
class Section { class Section {
private: private:
typedef void (*SectionFunction)(Section*); typedef void (*SectionFunction)(Section*);
@ -140,7 +234,7 @@ private:
std::list<Function_wrapper> destroyfunctions; std::list<Function_wrapper> destroyfunctions;
std::string sectionname; std::string sectionname;
public: public:
Section(char const * const _sectionname):sectionname(_sectionname) { } Section(std::string const& _sectionname):sectionname(_sectionname) { }
void AddInitFunction(SectionFunction func,bool canchange=false); void AddInitFunction(SectionFunction func,bool canchange=false);
void AddDestroyFunction(SectionFunction func,bool canchange=false); void AddDestroyFunction(SectionFunction func,bool canchange=false);
@ -148,75 +242,79 @@ public:
void ExecuteDestroy(bool destroyall=true); void ExecuteDestroy(bool destroyall=true);
const char* GetName() const {return sectionname.c_str();} const char* GetName() const {return sectionname.c_str();}
virtual char const * GetPropValue(char const * const _property) const =0; virtual std::string GetPropValue(std::string const& _property) const =0;
virtual void HandleInputline(char * _line)=0; virtual void HandleInputline(std::string const& _line)=0;
virtual void PrintData(FILE* outfile) const =0; virtual void PrintData(FILE* outfile) const =0;
virtual ~Section() { /*Children must call executedestroy ! */} virtual ~Section() { /*Children must call executedestroy ! */}
}; };
class Prop_multival;
class Prop_multival_remain;
class Section_prop:public Section { class Section_prop:public Section {
private: private:
std::list<Property*> properties; std::list<Property*> properties;
typedef std::list<Property*>::iterator it; typedef std::list<Property*>::iterator it;
typedef std::list<Property*>::const_iterator const_it; typedef std::list<Property*>::const_iterator const_it;
public:
Section_prop(char const * const _sectionname):Section(_sectionname){}
void Add_int(char const * const _propname, int _value=0);
void Add_string(char const * const _propname, char const * const _value=NULL);
void Add_bool(char const * const _propname, bool _value=false);
void Add_hex(char const * const _propname, int _value=0);
void Add_float(char const * const _propname, float _value=0.0);
int Get_int(char const * const _propname) const; public:
const char* Get_string(char const * const _propname) const; Section_prop(std::string const& _sectionname):Section(_sectionname){}
bool Get_bool(char const * const _propname) const; Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0);
int Get_hex(char const * const _propname) const; Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
float Get_float(char const * const _propname) const; Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
void HandleInputline(char *gegevens); Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false);
Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0);
// void Add_double(char const * const _propname, double _value=0.0);
Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
Property* Get_prop(int index);
int Get_int(std::string const& _propname) const;
const char* Get_string(std::string const& _propname) const;
bool Get_bool(std::string const& _propname) const;
Hex Get_hex(std::string const& _propname) const;
double Get_double(std::string const& _propname) const;
Prop_path* Get_path(std::string const& _propname) const;
Prop_multival* Get_multival(std::string const& _propname) const;
Prop_multival_remain* Get_multivalremain(std::string const& _propname) const;
void HandleInputline(std::string const& gegevens);
void PrintData(FILE* outfile) const; void PrintData(FILE* outfile) const;
virtual char const * GetPropValue(char const * const _property) const; virtual std::string GetPropValue(std::string const& _property) const;
//ExecuteDestroy should be here else the destroy functions use destroyed properties //ExecuteDestroy should be here else the destroy functions use destroyed properties
virtual ~Section_prop(); virtual ~Section_prop();
}; };
class Section_line: public Section{ class Prop_multival:public Property{
protected:
Section_prop* section;
std::string seperator;
void make_default_value();
public: public:
Section_line(char const * const _sectionname):Section(_sectionname){} Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),seperator(sep) {
~Section_line(){ExecuteDestroy(true);} default_value = value = "";
void HandleInputline(char* gegevens); }
void PrintData(FILE* outfile) const; Section_prop *GetSection() { return section; }
virtual const char* GetPropValue(char const * const _property) const; const Section_prop *GetSection() const { return section; }
std::string data; virtual void SetValue(std::string const& input);
virtual const std::vector<Value>& GetValues() const;
~Prop_multival() { delete section; }
}; //value bevat totale string. setvalue zet elk van de sub properties en checked die.
class Prop_multival_remain:public Prop_multival{
public:
Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ }
virtual void SetValue(std::string const& input);
}; };
class Config{
class Section_line: public Section{
public: public:
CommandLine * cmdline; Section_line(std::string const& _sectionname):Section(_sectionname){}
private: ~Section_line(){ExecuteDestroy(true);}
std::list<Section*> sectionlist; void HandleInputline(std::string const& gegevens);
typedef std::list<Section*>::iterator it; void PrintData(FILE* outfile) const;
typedef std::list<Section*>::reverse_iterator reverse_it; virtual std::string GetPropValue(std::string const& _property) const;
typedef std::list<Section*>::const_iterator const_it; std::string data;
typedef std::list<Section*>::const_reverse_iterator const_reverse_it;
void (* _start_function)(void);
public:
Config(CommandLine * cmd):cmdline(cmd){}
~Config();
Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*));
Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false);
Section* GetSection(char const* const _sectionname) const;
Section* GetSectionFromProperty(char const * const prop) const;
void SetStartUp(void (*_function)(void));
void Init();
void ShutDown();
void StartUp();
void PrintConfig(char const * const configfilename) const;
bool ParseConfigFile(char const * const configfilename);
void ParseEnv(char ** envp);
}; };
class Module_base { class Module_base {

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: shell.h,v 1.21 2007/06/14 08:23:46 qbix79 Exp $ */ /* $Id: shell.h,v 1.26 2009/03/23 10:55:35 qbix79 Exp $ */
#ifndef DOSBOX_SHELL_H #ifndef DOSBOX_SHELL_H
#define DOSBOX_SHELL_H #define DOSBOX_SHELL_H
@ -39,25 +39,28 @@ extern Bitu call_shellstop;
/* first_shell is used to add and delete stuff from the shell env /* first_shell is used to add and delete stuff from the shell env
* by "external" programs. (config) */ * by "external" programs. (config) */
extern Program * first_shell; extern Program * first_shell;
class DOS_Shell;
class DOS_Shell;
class BatchFile { class BatchFile {
public: public:
BatchFile(DOS_Shell * host,char * name, char * cmd_line); BatchFile(DOS_Shell * host,char const* const name, char const * const cmd_line);
~BatchFile(); virtual ~BatchFile();
bool ReadLine(char * line); virtual bool ReadLine(char * line);
bool Goto(char * where); bool Goto(char * where);
void Shift(void); void Shift(void);
Bit16u file_handle; Bit16u file_handle;
Bit32u location;
bool echo; bool echo;
DOS_Shell * shell; DOS_Shell * shell;
BatchFile * prev; BatchFile * prev;
CommandLine * cmd; CommandLine * cmd;
}; };
class AutoexecEditor;
class DOS_Shell : public Program { class DOS_Shell : public Program {
private: private:
friend class AutoexecEditor;
std::list<std::string> l_history, l_completion; std::list<std::string> l_history, l_completion;
char *completion_start; char *completion_start;
@ -122,32 +125,6 @@ struct SHELL_Cmd {
const char * help; /* String with command help */ const char * help; /* String with command help */
}; };
static inline void StripSpaces(char*&args) {
while(args && *args && isspace(*reinterpret_cast<unsigned char*>(args)))
args++;
}
static inline char* ExpandDot(char*args, char* buffer) {
if(*args=='.')
{
if(*(args+1)==0)
{
strcpy(buffer,"*.*");
return buffer;
}
if( (*(args+1)!='.') && (*(args+1)!='\\') )
{
buffer[0]='*';
buffer[1]=0;
strcat(buffer,args);
return buffer;
} else
strcpy (buffer, args);
}
else strcpy(buffer,args);
return buffer;
}
/* Object to manage lines in the autoexec.bat The lines get removed from /* Object to manage lines in the autoexec.bat The lines get removed from
* the file if the object gets destroyed. The environment is updated * the file if the object gets destroyed. The environment is updated
* as well if the line set a a variable */ * as well if the line set a a variable */

View File

@ -16,10 +16,13 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: support.h,v 1.17 2009/04/25 16:25:03 harekiet Exp $ */
#ifndef DOSBOX_SUPPORT_H #ifndef DOSBOX_SUPPORT_H
#define DOSBOX_SUPPORT_H #define DOSBOX_SUPPORT_H
#include <string.h> #include <string.h>
#include <string>
#include <ctype.h> #include <ctype.h>
#ifndef DOSBOX_DOSBOX_H #ifndef DOSBOX_DOSBOX_H
#include "dosbox.h" #include "dosbox.h"
@ -28,10 +31,6 @@
#if defined (_MSC_VER) /* MS Visual C++ */ #if defined (_MSC_VER) /* MS Visual C++ */
#define strcasecmp(a,b) stricmp(a,b) #define strcasecmp(a,b) stricmp(a,b)
#define strncasecmp(a,b,n) _strnicmp(a,b,n) #define strncasecmp(a,b,n) _strnicmp(a,b,n)
// if (stricmp(name,devices[index]->name)==0) return index;
#else
//if (strcasecmp(name,devices[index]->name)==0) return index;
//#define nocasestrcmp(a,b) stricmp(a,b)
#endif #endif
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) #define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
@ -44,6 +43,8 @@ void strreplace(char * str,char o,char n);
char *ltrim(char *str); char *ltrim(char *str);
char *rtrim(char *str); char *rtrim(char *str);
char *trim(char * str); char *trim(char * str);
char * upcase(char * str);
char * lowcase(char * str);
bool ScanCMDBool(char * cmd,char const * const check); bool ScanCMDBool(char * cmd,char const * const check);
char * ScanCMDRemain(char * cmd); char * ScanCMDRemain(char * cmd);
@ -53,15 +54,7 @@ bool IsHexWord(char * word);
Bits ConvDecWord(char * word); Bits ConvDecWord(char * word);
Bits ConvHexWord(char * word); Bits ConvHexWord(char * word);
INLINE char * upcase(char * str) { void upcase(std::string &str);
for (char* idx = str; *idx ; idx++) *idx = toupper(*reinterpret_cast<unsigned char*>(idx)); void lowcase(std::string &str);
return str;
}
INLINE char * lowcase(char * str) {
for(char* idx = str; *idx ; idx++) *idx = tolower(*reinterpret_cast<unsigned char*>(idx));
return str;
}
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: vga.h,v 1.46 2009/03/15 11:28:34 c2woody Exp $ */
#ifndef DOSBOX_VGA_H #ifndef DOSBOX_VGA_H
#define DOSBOX_VGA_H #define DOSBOX_VGA_H
@ -26,12 +28,8 @@
//Don't enable keeping changes and mapping lfb probably... //Don't enable keeping changes and mapping lfb probably...
#define VGA_LFB_MAPPED #define VGA_LFB_MAPPED
//#define VGA_KEEP_CHANGES //#define VGA_KEEP_CHANGES
#define VGA_MEMORY (2*1024*1024)
#define VGA_CHANGE_SHIFT 9 #define VGA_CHANGE_SHIFT 9
//Offset inside VGA_MEMORY that will be used for certain types of caching
#define VGA_CACHE_OFFSET (512*1024)
class PageHandler; class PageHandler;
@ -42,7 +40,7 @@ enum VGAModes {
M_TEXT, M_TEXT,
M_HERC_GFX, M_HERC_TEXT, M_HERC_GFX, M_HERC_TEXT,
M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT, M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT,
M_ERROR, M_ERROR
}; };
@ -56,6 +54,18 @@ enum VGAModes {
#define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R)))) #define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R))))
#define S3_MAX_CLOCK 150000 /* KHz */ #define S3_MAX_CLOCK 150000 /* KHz */
#define S3_XGA_1024 0x00
#define S3_XGA_1152 0x01
#define S3_XGA_640 0x40
#define S3_XGA_800 0x80
#define S3_XGA_1280 0xc0
#define S3_XGA_WMASK (S3_XGA_640|S3_XGA_800|S3_XGA_1024|S3_XGA_1152|S3_XGA_1280)
#define S3_XGA_8BPP 0x00
#define S3_XGA_16BPP 0x10
#define S3_XGA_32BPP 0x30
#define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP)
typedef struct { typedef struct {
bool attrindex; bool attrindex;
} VGA_Internal; } VGA_Internal;
@ -107,6 +117,8 @@ typedef struct {
Bitu height; Bitu height;
Bitu blocks; Bitu blocks;
Bitu address; Bitu address;
Bitu panning;
Bitu bytes_skip;
Bit8u *linear_base; Bit8u *linear_base;
Bitu linear_mask; Bitu linear_mask;
Bitu address_add; Bitu address_add;
@ -120,6 +132,7 @@ typedef struct {
Bitu parts_total; Bitu parts_total;
Bitu parts_lines; Bitu parts_lines;
Bitu parts_left; Bitu parts_left;
Bitu byte_panning_shift;
struct { struct {
double framestart; double framestart;
double vrstart, vrend; // V-retrace double vrstart, vrend; // V-retrace
@ -142,6 +155,7 @@ typedef struct {
Bit8u count,delay; Bit8u count,delay;
Bit8u enabled; Bit8u enabled;
} cursor; } cursor;
bool vret_triggered;
} VGA_Draw; } VGA_Draw;
typedef struct { typedef struct {
@ -155,38 +169,30 @@ typedef struct {
Bit8u mc[64][64]; Bit8u mc[64][64];
} VGA_HWCURSOR; } VGA_HWCURSOR;
typedef union {
Bit32u fullbank;
#ifndef WORDS_BIGENDIAN
struct {
Bit16u lowerbank;
Bit16u bank;
} b;
#else
struct {
Bit16u bank;
Bit16u lowerbank;
} b;
#endif
} VGA_S3_BANK;
typedef struct { typedef struct {
VGA_S3_BANK svga_bank;
Bit8u reg_lock1; Bit8u reg_lock1;
Bit8u reg_lock2; Bit8u reg_lock2;
Bit8u reg_31; Bit8u reg_31;
Bit8u reg_35; Bit8u reg_35;
Bit8u reg_36; // RAM size
Bit8u reg_3a; // 4/8/doublepixel bit in there
Bit8u reg_40; // 8415/A functionality register Bit8u reg_40; // 8415/A functionality register
Bit8u reg_41; // BIOS flags
Bit8u reg_43; Bit8u reg_43;
Bit8u reg_45; // Hardware graphics cursor Bit8u reg_45; // Hardware graphics cursor
Bit8u reg_58; Bit8u reg_50;
Bit8u reg_51; Bit8u reg_51;
Bit8u reg_52;
Bit8u reg_55; Bit8u reg_55;
Bit8u reg_58;
Bit8u reg_6b; // LFB BIOS scratchpad
Bit8u ex_hor_overflow; Bit8u ex_hor_overflow;
Bit8u ex_ver_overflow; Bit8u ex_ver_overflow;
Bit16u la_window; Bit16u la_window;
Bit8u misc_control_2; Bit8u misc_control_2;
Bit8u ext_mem_ctrl; Bit8u ext_mem_ctrl;
Bitu xga_screen_width;
VGAModes xga_color_mode;
struct { struct {
Bit8u r; Bit8u r;
Bit8u n; Bit8u n;
@ -317,11 +323,17 @@ typedef struct {
Bitu first_changed; Bitu first_changed;
Bit8u combine[16]; Bit8u combine[16];
RGBEntry rgb[0x100]; RGBEntry rgb[0x100];
Bit16u xlat16[256];
} VGA_Dac; } VGA_Dac;
typedef struct { typedef struct {
Bitu readStart, writeStart; Bitu readStart, writeStart;
Bitu bankMask; Bitu bankMask;
Bitu bank_read_full;
Bitu bank_write_full;
Bit8u bank_read;
Bit8u bank_write;
Bitu bank_size;
} VGA_SVGA; } VGA_SVGA;
typedef union { typedef union {
@ -330,12 +342,13 @@ typedef union {
} VGA_Latch; } VGA_Latch;
typedef struct { typedef struct {
Bit8u linear[VGA_MEMORY]; Bit8u* linear;
Bit8u* linear_orgptr;
} VGA_Memory; } VGA_Memory;
typedef struct { typedef struct {
//Add a few more just to be safe //Add a few more just to be safe
Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32]; Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */
Bit8u checkMask, frame, writeMask; Bit8u checkMask, frame, writeMask;
bool active; bool active;
Bit32u clearMask; Bit32u clearMask;
@ -353,6 +366,7 @@ typedef struct {
typedef struct { typedef struct {
VGAModes mode; /* The mode the vga system is in */ VGAModes mode; /* The mode the vga system is in */
VGAModes lastmode; VGAModes lastmode;
Bits screenflip;
Bit8u misc_output; Bit8u misc_output;
VGA_Draw draw; VGA_Draw draw;
VGA_Config config; VGA_Config config;
@ -370,6 +384,10 @@ typedef struct {
VGA_TANDY tandy; VGA_TANDY tandy;
VGA_OTHER other; VGA_OTHER other;
VGA_Memory mem; VGA_Memory mem;
Bit32u vmemwrap; /* this is assumed to be power of 2 */
Bit8u* fastmem; /* memory for fast (usually 16-color) rendering, always twice as big as vmemsize */
Bit8u* fastmem_orgptr;
Bit32u vmemsize;
#ifdef VGA_KEEP_CHANGES #ifdef VGA_KEEP_CHANGES
VGA_Changes changes; VGA_Changes changes;
#endif #endif
@ -382,7 +400,7 @@ typedef struct {
void VGA_SetMode(VGAModes mode); void VGA_SetMode(VGAModes mode);
void VGA_DetermineMode(void); void VGA_DetermineMode(void);
void VGA_SetupHandlers(void); void VGA_SetupHandlers(void);
void VGA_StartResize(void); void VGA_StartResize(Bitu delay=50);
void VGA_SetupDrawing(Bitu val); void VGA_SetupDrawing(Bitu val);
void VGA_CheckScanLength(void); void VGA_CheckScanLength(void);
void VGA_ChangedBank(void); void VGA_ChangedBank(void);
@ -394,7 +412,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
/* The VGA Subfunction startups */ /* The VGA Subfunction startups */
void VGA_SetupAttr(void); void VGA_SetupAttr(void);
void VGA_SetupMemory(void); void VGA_SetupMemory(Section* sec);
void VGA_SetupDAC(void); void VGA_SetupDAC(void);
void VGA_SetupCRTC(void); void VGA_SetupCRTC(void);
void VGA_SetupMisc(void); void VGA_SetupMisc(void);
@ -414,15 +432,67 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
void VGA_ActivateHardwareCursor(void); void VGA_ActivateHardwareCursor(void);
void VGA_KillDrawing(void); void VGA_KillDrawing(void);
/* S3 Functions */
Bitu SVGA_S3_GetClock(void);
void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen);
Bitu SVGA_S3_ReadCRTC(Bitu reg,Bitu iolen);
void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen);
Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen);
extern VGA_Type vga; extern VGA_Type vga;
/* Support for modular SVGA implementation */
/* Video mode extra data to be passed to FinishSetMode_SVGA().
This structure will be in flux until all drivers (including S3)
are properly separated. Right now it contains only three overflow
fields in S3 format and relies on drivers re-interpreting those.
For reference:
ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10
hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8
offset is not currently used by drivers (useful only for S3 itself)
It also contains basic int10 mode data - number, vtotal, htotal
*/
typedef struct {
Bit8u ver_overflow;
Bit8u hor_overflow;
Bitu offset;
Bitu modeNo;
Bitu htotal;
Bitu vtotal;
} VGA_ModeExtraData;
// Vector function prototypes
typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen);
typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen);
typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData);
typedef void (*tDetermineMode)();
typedef void (*tSetClock)(Bitu which,Bitu target);
typedef Bitu (*tGetClock)();
typedef bool (*tHWCursorActive)();
typedef bool (*tAcceptsMode)(Bitu modeNo);
struct SVGA_Driver {
tWritePort write_p3d5;
tReadPort read_p3d5;
tWritePort write_p3c5;
tReadPort read_p3c5;
tWritePort write_p3c0;
tReadPort read_p3c1;
tWritePort write_p3cf;
tReadPort read_p3cf;
tFinishSetMode set_video_mode;
tDetermineMode determine_mode;
tSetClock set_clock;
tGetClock get_clock;
tHWCursorActive hardware_cursor_active;
tAcceptsMode accepts_mode;
};
extern SVGA_Driver svga;
void SVGA_Setup_S3Trio(void);
void SVGA_Setup_TsengET4K(void);
void SVGA_Setup_TsengET3K(void);
void SVGA_Setup_ParadisePVGA1A(void);
void SVGA_Setup_Driver(void);
// Amount of video memory required for a mode, implemented in int10_modes.cpp
Bitu VideoModeMemSize(Bitu mode);
extern Bit32u ExpandTable[256]; extern Bit32u ExpandTable[256];
extern Bit32u FillTable[16]; extern Bit32u FillTable[16];
extern Bit32u CGA_2_Table[16]; extern Bit32u CGA_2_Table[16];

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: video.h,v 1.25 2008/08/24 16:43:06 qbix79 Exp $ */
#ifndef DOSBOX_VIDEO_H #ifndef DOSBOX_VIDEO_H
#define DOSBOX_VIDEO_H #define DOSBOX_VIDEO_H
@ -24,7 +26,7 @@
typedef enum { typedef enum {
GFX_CallBackReset, GFX_CallBackReset,
GFX_CallBackStop, GFX_CallBackStop,
GFX_CallBackRedraw, GFX_CallBackRedraw
} GFX_CallBackFunctions_t; } GFX_CallBackFunctions_t;
typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function ); typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function );
@ -65,6 +67,8 @@ void GFX_Stop(void);
void GFX_SwitchFullScreen(void); void GFX_SwitchFullScreen(void);
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch); bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
void GFX_EndUpdate( const Bit16u *changedLines ); void GFX_EndUpdate( const Bit16u *changedLines );
void GFX_GetSize(int &width, int &height, bool &fullscreen);
void GFX_LosingFocus(void);
#if defined (WIN32) #if defined (WIN32)
bool GFX_SDLUsingWinDIB(void); bool GFX_SDLUsingWinDIB(void);

View File

@ -1,294 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
#
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# 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
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "$0: no input file specified" >&2
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d "$dst" ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "$0: $src does not exist" >&2
exit 1
fi
if [ x"$dst" = x ]
then
echo "$0: no destination specified" >&2
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d "$dst" ]
then
dst=$dst/`basename "$src"`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1
shift
if [ ! -d "$pathcomp" ] ;
then
$mkdirprog "$pathcomp"
else
:
fi
pathcomp=$pathcomp/
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd "$dst" &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename "$dst"`
else
:
fi
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
# Now remove or move aside any old file at destination location. We try this
# two ways since rm can't unlink itself on some systems and the destination
# file might be busy for other reasons. In this case, the final cleanup
# might fail but the new file should still install successfully.
{
if [ -f "$dstdir/$dstfile" ]
then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
{
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}

336
missing
View File

@ -1,336 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.4 - GNU automake"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

View File

@ -1,111 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# End:
# mkinstalldirs ends here

View File

@ -0,0 +1,149 @@
!define VER_MAYOR 0
!define VER_MINOR 72
!define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer"
!define COMP_NAME "DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2008 DOSBox Team"
!define DESCRIPTION "DOSBox Installer"
VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0"
VIAddVersionKey "ProductName" "${APP_NAME}"
VIAddVersionKey "CompanyName" "${COMP_NAME}"
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
VIAddVersionKey "FileVersion" "${VER_MAYOR}.${VER_MINOR}.0.0"
VIAddVersionKey "ProductVersion" "${VER_MAYOR}, ${VER_MINOR}, 0, 0"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
; The name of the installer
Name "${APP_NAME}"
; The file to write
OutFile "DOSBox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe"
; The default installation directory
InstallDir "$PROGRAMFILES\DOSBox-${VER_MAYOR}.${VER_MINOR}"
; The text to prompt the user to enter a directory
DirText "This will install DOSBox v${VER_MAYOR}.${VER_MINOR} on your computer. Choose a directory"
SetCompressor /solid lzma
LicenseData COPYING
LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >"
; Else vista enables compatibility mode
RequestExecutionLevel admin
ComponentText "Select components for DOSBox"
; The stuff to install
Section "!Core files" Core
; Set output path to the installation directory.
ClearErrors
SetOutPath $INSTDIR
IfErrors error_createdir
SectionIn RO
; Put file there
CreateDirectory "$INSTDIR\capture"
CreateDirectory "$INSTDIR\zmbv"
File /oname=README.txt README
File /oname=COPYING.txt COPYING
File /oname=THANKS.txt THANKS
File /oname=NEWS.txt NEWS
File /oname=AUTHORS.txt AUTHORS
File /oname=INSTALL.txt INSTALL
File DOSBox.exe
File dosbox.conf
File SDL.dll
File SDL_net.dll
File /oname=zmbv\zmbv.dll zmbv.dll
File /oname=zmbv\zmbv.inf zmbv.inf
File /oname=zmbv\README.txt README.video
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" "notepad.exe" "$INSTDIR\dosbox.conf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\capture"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt"
;change outpath so the working directory gets set to zmbv
SetOutPath "$INSTDIR\zmbv"
; Shortcut creation depends on wether we are 9x of NT
ClearErrors
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors we_9x we_nt
we_nt:
;shortcut for win NT
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
goto end
we_9x:
;shortcut for we_9x
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
end:
SetOutPath $INSTDIR
WriteUninstaller "uninstall.exe"
goto end_section
error_createdir:
MessageBox MB_OK "Can't create DOSBox program directory, aborting."
Abort
goto end_section
end_section:
SectionEnd ; end the section
Section "Desktop Shortcut" SecDesktop
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
SectionEnd ; end the section
UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue."
Section "Uninstall"
Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
; remove registry keys
; remove files
Delete $INSTDIR\README.txt
Delete $INSTDIR\COPYING.txt
Delete $INSTDIR\THANKS.txt
Delete $INSTDIR\NEWS.txt
Delete $INSTDIR\AUTHORS.txt
Delete $INSTDIR\INSTALL.txt
Delete $INSTDIR\DOSBox.exe
Delete $INSTDIR\dosbox.conf
Delete $INSTDIR\SDL.dll
Delete $INSTDIR\SDL_net.dll
Delete $INSTDIR\zmbv\zmbv.dll
Delete $INSTDIR\zmbv\zmbv.inf
Delete $INSTDIR\zmbv\README.txt
;Files left by sdl taking over the console
Delete $INSTDIR\stdout.txt
Delete $INSTDIR\stderr.txt
; MUST REMOVE UNINSTALLER, too
Delete $INSTDIR\uninstall.exe
; remove shortcuts, if any.
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk"
; remove directories used.
RMDir "$INSTDIR\zmbv"
RMDir "$INSTDIR\capture"
RMDir "$INSTDIR"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
SectionEnd
; eof

32
scripts/ega-switch.pl Normal file
View File

@ -0,0 +1,32 @@
#!/usr/bin/perl
use integer;
open (THEFILE,'>','../src/hardware/ega-switch.h')
or die "Can't open my file $!";
print THEFILE "switch (bit_mask) {\n";
for ($i = 0; $i < 256; $i++) {
print THEFILE "\tcase $i:\n";
$b=128;
$add=0;
do {
if ($i & $b) {
print THEFILE "\t{\n";
print THEFILE "\t\tBit8u color=0;\n";
print THEFILE "\t\tif (pixels.b[0] & $b) color|=1;\n";
print THEFILE "\t\tif (pixels.b[1] & $b) color|=2;\n";
print THEFILE "\t\tif (pixels.b[2] & $b) color|=4;\n";
print THEFILE "\t\tif (pixels.b[3] & $b) color|=8;\n";
print THEFILE "\t\t*(write_pixels+$add)=color;\n";
print THEFILE "\t\t*(write_pixels+$add+512*1024)=color;\n";
print THEFILE "\t}\n";
}
$b=$b >> 1;
$add=$add+1;
} until ($b == 0);
print THEFILE "\tbreak;\n";
}
print THEFILE "}\n";
close (THEFILE);

25
scripts/font-switch.pl Normal file
View File

@ -0,0 +1,25 @@
#!/usr/bin/perl
use integer;
open (THEFILE,'>','../src/hardware/font-switch.h')
or die "Can't open my file $!";
print THEFILE "switch (bit_mask) {\n";
for ($i = 0; $i < 256; $i++) {
print THEFILE "\tcase $i:\n";
$b=128;
$add=0;
do {
if ($i & $b) {
print THEFILE "\t\t*(draw+$add)=fg;\n";
} else {
print THEFILE "\t\t*(draw+$add)=bg;\n";
}
$b=$b >> 1;
$add=$add+1;
} until ($b == 0);
print THEFILE "\tbreak;\n";
}
print THEFILE "}\n";
close (THEFILE);

View File

@ -5,16 +5,16 @@ SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform
bin_PROGRAMS = dosbox bin_PROGRAMS = dosbox
if HAVE_WINDRES if HAVE_WINDRES
ico_stuff = dosbox_ico.o ico_stuff = winres.rc
endif endif
.rc.o:
$(WINDRES) -o $@ $<
dosbox_SOURCES = dosbox.cpp dosbox_SOURCES = dosbox.cpp $(ico_stuff)
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \ dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a \ ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a
$(ico_stuff)
EXTRA_DIST = winres.rc dosbox.ico
EXTRA_DIST = dosbox.rc dosbox.ico
dosbox_ico.o: dosbox.rc dosbox.ico
$(WINDRES) dosbox.rc dosbox_ico.o

View File

@ -1,537 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
AM_CPPFLAGS = -I$(top_srcdir)/include
SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform
bin_PROGRAMS = dosbox
@HAVE_WINDRES_TRUE@ico_stuff = dosbox_ico.o
dosbox_SOURCES = dosbox.cpp
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a \
$(ico_stuff)
EXTRA_DIST = dosbox.rc dosbox.ico
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
bin_PROGRAMS = dosbox$(EXEEXT)
PROGRAMS = $(bin_PROGRAMS)
am_dosbox_OBJECTS = dosbox.$(OBJEXT)
dosbox_OBJECTS = $(am_dosbox_OBJECTS)
@HAVE_WINDRES_TRUE@dosbox_DEPENDENCIES = cpu/libcpu.a debug/libdebug.a \
@HAVE_WINDRES_TRUE@ dos/libdos.a fpu/libfpu.a \
@HAVE_WINDRES_TRUE@ hardware/libhardware.a gui/libgui.a \
@HAVE_WINDRES_TRUE@ ints/libints.a misc/libmisc.a \
@HAVE_WINDRES_TRUE@ shell/libshell.a \
@HAVE_WINDRES_TRUE@ hardware/serialport/libserial.a dosbox_ico.o
@HAVE_WINDRES_FALSE@dosbox_DEPENDENCIES = cpu/libcpu.a debug/libdebug.a \
@HAVE_WINDRES_FALSE@ dos/libdos.a fpu/libfpu.a \
@HAVE_WINDRES_FALSE@ hardware/libhardware.a gui/libgui.a \
@HAVE_WINDRES_FALSE@ ints/libints.a misc/libmisc.a \
@HAVE_WINDRES_FALSE@ shell/libshell.a \
@HAVE_WINDRES_FALSE@ hardware/serialport/libserial.a
dosbox_LDFLAGS =
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dosbox.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
DIST_SOURCES = $(dosbox_SOURCES)
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(dosbox_SOURCES)
all: all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(bindir)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
$(INSTALL_PROGRAM_ENV) $(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:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
dosbox$(EXEEXT): $(dosbox_OBJECTS) $(dosbox_DEPENDENCIES)
@rm -f dosbox$(EXEEXT)
$(CXXLINK) $(dosbox_LDFLAGS) $(dosbox_OBJECTS) $(dosbox_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dosbox.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(PROGRAMS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(bindir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
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:
-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-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-binPROGRAMS clean-generic clean-recursive ctags \
ctags-recursive distclean distclean-compile distclean-generic \
distclean-recursive distclean-tags distdir dvi dvi-am \
dvi-recursive info info-am info-recursive install install-am \
install-binPROGRAMS install-data install-data-am \
install-data-recursive install-exec install-exec-am \
install-exec-recursive install-info install-info-am \
install-info-recursive install-man install-recursive \
install-strip installcheck installcheck-am installdirs \
installdirs-am installdirs-recursive maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-recursive \
pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
tags-recursive uninstall uninstall-am uninstall-binPROGRAMS \
uninstall-info-am uninstall-info-recursive uninstall-recursive
dosbox_ico.o: dosbox.rc dosbox.ico
$(WINDRES) dosbox.rc dosbox_ico.o
# 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:

View File

@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \ libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \ paging.cpp lazyflags.h core_normal.cpp core_simple.cpp core_prefetch.cpp \
core_dyn_x86.cpp core_dynrec.cpp core_dyn_x86.cpp core_dynrec.cpp

View File

@ -1,519 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = core_full core_normal core_dyn_x86 core_dynrec
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \
core_dyn_x86.cpp core_dynrec.cpp
subdir = src/cpu
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libcpu_a_AR = $(AR) cru
libcpu_a_LIBADD =
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
modrm.$(OBJEXT) core_full.$(OBJEXT) paging.$(OBJEXT) \
core_normal.$(OBJEXT) core_simple.$(OBJEXT) \
core_dyn_x86.$(OBJEXT) core_dynrec.$(OBJEXT)
libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_dyn_x86.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_dynrec.Po ./$(DEPDIR)/core_full.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_normal.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_simple.Po ./$(DEPDIR)/cpu.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/flags.Po ./$(DEPDIR)/modrm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/paging.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libcpu_a_SOURCES)
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libcpu_a_SOURCES)
all: all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/cpu/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
AR = ar
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcpu.a: $(libcpu_a_OBJECTS) $(libcpu_a_DEPENDENCIES)
-rm -f libcpu.a
$(libcpu_a_AR) libcpu.a $(libcpu_a_OBJECTS) $(libcpu_a_LIBADD)
$(RANLIB) libcpu.a
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_dyn_x86.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_dynrec.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_full.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_normal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_simple.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modrm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paging.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LIBRARIES)
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
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:
-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-recursive
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-noinstLIBRARIES clean-recursive ctags \
ctags-recursive distclean distclean-compile distclean-generic \
distclean-recursive distclean-tags distdir dvi dvi-am \
dvi-recursive info info-am info-recursive install install-am \
install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip installcheck installcheck-am \
installdirs installdirs-am installdirs-recursive \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-recursive pdf pdf-am \
pdf-recursive ps ps-am ps-recursive tags tags-recursive \
uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive
# 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:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: callback.cpp,v 1.37 2007/06/03 16:46:33 c2woody Exp $ */ /* $Id: callback.cpp,v 1.40 2009/03/03 18:30:41 c2woody Exp $ */
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -34,7 +34,7 @@
CallBack_Handler CallBack_Handlers[CB_MAX]; CallBack_Handler CallBack_Handlers[CB_MAX];
char* CallBack_Description[CB_MAX]; char* CallBack_Description[CB_MAX];
static Bitu call_stop,call_idle,call_default; static Bitu call_stop,call_idle,call_default,call_default2;
Bitu call_priv_io; Bitu call_priv_io;
static Bitu illegal_handler(void) { static Bitu illegal_handler(void) {
@ -77,11 +77,11 @@ void CALLBACK_Idle(void) {
static Bitu default_handler(void) { static Bitu default_handler(void) {
LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint); LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint);
return CBRET_NONE; return CBRET_NONE;
}; }
static Bitu stop_handler(void) { static Bitu stop_handler(void) {
return CBRET_STOP; return CBRET_STOP;
}; }
@ -112,13 +112,13 @@ void CALLBACK_SZF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF; Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF;
Bit16u newZF=(val==true) << 6; Bit16u newZF=(val==true) << 6;
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF)); mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF));
}; }
void CALLBACK_SCF(bool val) { void CALLBACK_SCF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE; Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE;
Bit16u newCF=(val==true); Bit16u newCF=(val==true);
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF)); mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF));
}; }
void CALLBACK_SetDescription(Bitu nr, const char* descr) { void CALLBACK_SetDescription(Bitu nr, const char* descr) {
if (descr) { if (descr) {
@ -126,12 +126,12 @@ void CALLBACK_SetDescription(Bitu nr, const char* descr) {
strcpy(CallBack_Description[nr],descr); strcpy(CallBack_Description[nr],descr);
} else } else
CallBack_Description[nr] = 0; CallBack_Description[nr] = 0;
}; }
const char* CALLBACK_GetDescription(Bitu nr) { const char* CALLBACK_GetDescription(Bitu nr) {
if (nr>=CB_MAX) return 0; if (nr>=CB_MAX) return 0;
return CallBack_Description[nr]; return CallBack_Description[nr];
}; }
Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) { Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) {
if (callback>=CB_MAX) if (callback>=CB_MAX)
@ -268,11 +268,12 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds
phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es
phys_writew(physAddress+0x02,(Bit16u)0x6066); // pushad phys_writew(physAddress+0x02,(Bit16u)0x6066); // pushad
phys_writeb(physAddress+0x04,(Bit8u)0xfb); // sti phys_writeb(physAddress+0x04,(Bit8u)0xfc); // cld
phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4 phys_writeb(physAddress+0x05,(Bit8u)0xfb); // sti
phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction phys_writeb(physAddress+0x06,(Bit8u)0xFE); //GRP 4
phys_writew(physAddress+0x07,callback); //The immediate word phys_writeb(physAddress+0x07,(Bit8u)0x38); //Extra Callback instruction
return 0x09; phys_writew(physAddress+0x08,callback); //The immediate word
return 0x0a;
case CB_IRQ12_RET: // ps2 mouse int74 return case CB_IRQ12_RET: // ps2 mouse int74 return
if (use_cb) { if (use_cb) {
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4 phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
@ -403,6 +404,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds
phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction
return 0x0f; */ return 0x0f; */
case CB_INT21:
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03, callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction
return (use_cb?7:3);
default: default:
E_Exit("CALLBACK:Setup:Illegal type %d",type); E_Exit("CALLBACK:Setup:Illegal type %d",type);
} }
@ -512,9 +525,11 @@ void CALLBACK_Init(Section* sec) {
phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38); phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38);
phys_writew(CALLBACK_PhysPointer(call_idle)+14,call_idle); phys_writew(CALLBACK_PhysPointer(call_idle)+14,call_idle);
/* Setup all Interrupt to point to the default handler */ /* Default handlers for unhandled interrupts that have to be non-null */
call_default=CALLBACK_Allocate(); call_default=CALLBACK_Allocate();
CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default");
call_default2=CALLBACK_Allocate();
CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default");
/* Only setup default handler for first half of interrupt table */ /* Only setup default handler for first half of interrupt table */
for (i=0;i<0x40;i++) { for (i=0;i<0x40;i++) {
@ -532,10 +547,11 @@ void CALLBACK_Init(Section* sec) {
} }
// setup a few interrupt handlers that point to bios IRETs by default // setup a few interrupt handlers that point to bios IRETs by default
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
real_writed(0,0x68*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x68*4,CALLBACK_RealPointer(call_default));
real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff
//real_writed(0,0xf*4,0); some games don't like it //real_writed(0,0xf*4,0); some games don't like it
call_priv_io=CALLBACK_Allocate(); call_priv_io=CALLBACK_Allocate();

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: core_dyn_x86.cpp,v 1.34 2007/11/24 17:26:48 c2woody Exp $ */
#include "dosbox.h" #include "dosbox.h"
#if (C_DYNAMIC_X86) #if (C_DYNAMIC_X86)
@ -346,8 +348,7 @@ run_block:
case BR_Link2: case BR_Link2:
{ {
Bitu temp_ip=SegPhys(cs)+reg_eip; Bitu temp_ip=SegPhys(cs)+reg_eip;
Bitu temp_page=temp_ip >> 12; CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip);
CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page];
if (temp_handler->flags & PFLAG_HASCODE) { if (temp_handler->flags & PFLAG_HASCODE) {
block=temp_handler->FindCacheBlock(temp_ip & 4095); block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) goto restart_core; if (!block) goto restart_core;

View File

@ -1,332 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \
dyn_fpu.h dyn_fpu_dh.h
subdir = src/cpu/core_dyn_x86
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/cpu/core_dyn_x86/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(HEADERS)
installdirs:
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
info info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-info-am
# 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:

View File

@ -69,7 +69,7 @@ public:
Bits index=1+(end>>DYN_HASH_SHIFT); Bits index=1+(end>>DYN_HASH_SHIFT);
bool is_current_block=false; bool is_current_block=false;
Bit32u ip_point=SegPhys(cs)+reg_eip; Bit32u ip_point=SegPhys(cs)+reg_eip;
ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
while (index>=0) { while (index>=0) {
Bitu map=0; Bitu map=0;
for (Bitu count=start;count<=end;count++) map+=write_map[count]; for (Bitu count=start;count<=end;count++) map+=write_map[count];

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: decoder.h,v 1.57 2009/03/29 17:32:20 qbix79 Exp $ */
#define X86_DYNFPU_DH_ENABLED #define X86_DYNFPU_DH_ENABLED
#define X86_INLINED_MEMACCESS #define X86_INLINED_MEMACCESS
@ -53,17 +55,26 @@ static struct DynDecode {
static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) { static bool MakeCodePage(Bitu lin_addr,CodePageHandler * &cph) {
Bit8u rdval; Bit8u rdval;
//Ensure page contains memory: //Ensure page contains memory:
if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true;
Bitu lin_page=lin_addr >> 12; PageHandler * handler=get_tlb_readhandler(lin_addr);
PageHandler * handler=paging.tlb.handler[lin_page];
if (handler->flags & PFLAG_HASCODE) { if (handler->flags & PFLAG_HASCODE) {
cph=( CodePageHandler *)handler; cph=( CodePageHandler *)handler;
return false; return false;
} }
if (handler->flags & PFLAG_NOCODE) { if (handler->flags & PFLAG_NOCODE) {
LOG_MSG("DYNX86:Can't run code in this page"); if (PAGING_ForcePageInit(lin_addr)) {
cph=0; return false; handler=get_tlb_readhandler(lin_addr);
if (handler->flags & PFLAG_HASCODE) {
cph=( CodePageHandler *)handler;
return false;
}
}
if (handler->flags & PFLAG_NOCODE) {
LOG_MSG("DYNX86:Can't run code in this page!");
cph=0; return false;
}
} }
Bitu lin_page=lin_addr >> 12;
Bitu phys_page=lin_page; Bitu phys_page=lin_page;
if (!PAGING_MakePhysPage(phys_page)) { if (!PAGING_MakePhysPage(phys_page)) {
LOG_MSG("DYNX86:Can't find physpage"); LOG_MSG("DYNX86:Can't find physpage");
@ -176,9 +187,9 @@ static INLINE void decode_increase_wmapmask(Bitu size) {
static bool decode_fetchb_imm(Bitu & val) { static bool decode_fetchb_imm(Bitu & val) {
if (decode.page.index<4096) { if (decode.page.index<4096) {
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1); decode_increase_wmapmask(1);
decode.code++; decode.code++;
decode.page.index++; decode.page.index++;
@ -190,9 +201,9 @@ static bool decode_fetchb_imm(Bitu & val) {
} }
static bool decode_fetchw_imm(Bitu & val) { static bool decode_fetchw_imm(Bitu & val) {
if (decode.page.index<4095) { if (decode.page.index<4095) {
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2); decode_increase_wmapmask(2);
decode.code+=2; decode.code+=2;
decode.page.index+=2; decode.page.index+=2;
@ -204,9 +215,9 @@ static bool decode_fetchw_imm(Bitu & val) {
} }
static bool decode_fetchd_imm(Bitu & val) { static bool decode_fetchd_imm(Bitu & val) {
if (decode.page.index<4093) { if (decode.page.index<4093) {
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4); decode_increase_wmapmask(4);
decode.code+=4; decode.code+=4;
decode.page.index+=4; decode.page.index+=4;
@ -266,7 +277,7 @@ static INLINE void dyn_set_eip_last(void) {
} }
enum save_info_type {exception, cycle_check, normal, fpu_restore}; enum save_info_type {db_exception, cycle_check, normal, fpu_restore};
static struct { static struct {
@ -298,7 +309,7 @@ static void dyn_check_bool_exception(DynReg * check) {
save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].cycles=decode.cycles;
save_info[used_save_info].eip_change=decode.op_start-decode.code_start; save_info[used_save_info].eip_change=decode.op_start-decode.code_start;
if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff;
save_info[used_save_info].type=exception; save_info[used_save_info].type=db_exception;
used_save_info++; used_save_info++;
} }
@ -310,7 +321,7 @@ static void dyn_check_bool_exception_al(void) {
save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].cycles=decode.cycles;
save_info[used_save_info].eip_change=decode.op_start-decode.code_start; save_info[used_save_info].eip_change=decode.op_start-decode.code_start;
if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff;
save_info[used_save_info].type=exception; save_info[used_save_info].type=db_exception;
used_save_info++; used_save_info++;
} }
@ -337,7 +348,7 @@ static void dyn_check_bool_exception_ne(void) {
save_info[used_save_info].cycles=decode.cycles; save_info[used_save_info].cycles=decode.cycles;
save_info[used_save_info].eip_change=decode.op_start-decode.code_start; save_info[used_save_info].eip_change=decode.op_start-decode.code_start;
if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff; if (!cpu.code.big) save_info[used_save_info].eip_change&=0xffff;
save_info[used_save_info].type=exception; save_info[used_save_info].type=db_exception;
used_save_info++; used_save_info++;
} }
@ -345,7 +356,7 @@ static void dyn_fill_blocks(void) {
for (Bitu sct=0; sct<used_save_info; sct++) { for (Bitu sct=0; sct<used_save_info; sct++) {
gen_fill_branch_long(save_info[sct].branch_pos); gen_fill_branch_long(save_info[sct].branch_pos);
switch (save_info[sct].type) { switch (save_info[sct].type) {
case exception: case db_exception:
dyn_loadstate(&save_info[sct].state); dyn_loadstate(&save_info[sct].state);
decode.cycles=save_info[sct].cycles; decode.cycles=save_info[sct].cycles;
dyn_save_critical_regs(); dyn_save_critical_regs();
@ -386,52 +397,52 @@ static void dyn_fill_blocks(void) {
#if !defined(X86_INLINED_MEMACCESS) #if !defined(X86_INLINED_MEMACCESS)
static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_readb_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); gen_call_function((void *)&mem_readb_checked,"%Dd%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,1,high); gen_mov_host(&core_dyn.readdata,dst,1,high);
} }
static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) { static void dyn_write_byte(DynReg * addr,DynReg * val,Bitu high) {
gen_protectflags(); gen_protectflags();
if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dh",addr,val); if (high) gen_call_function((void *)&mem_writeb_checked,"%Dd%Dh",addr,val);
else gen_call_function((void *)&mem_writeb_checked_x86,"%Dd%Dd",addr,val); else gen_call_function((void *)&mem_writeb_checked,"%Dd%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) {
gen_protectflags(); gen_protectflags();
if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); if (dword) gen_call_function((void *)&mem_readd_checked,"%Dd%Id",addr,&core_dyn.readdata);
else gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); else gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,dword?4:2); gen_mov_host(&core_dyn.readdata,dst,dword?4:2);
} }
static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) { static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) {
gen_protectflags(); gen_protectflags();
if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Dd%Dd",addr,val); if (dword) gen_call_function((void *)&mem_writed_checked,"%Dd%Dd",addr,val);
else gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); else gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) { static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_readb_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); gen_call_function((void *)&mem_readb_checked,"%Ddr%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,1,high); gen_mov_host(&core_dyn.readdata,dst,1,high);
} }
static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) { static void dyn_write_byte_release(DynReg * addr,DynReg * val,Bitu high) {
gen_protectflags(); gen_protectflags();
if (high) gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dh",addr,val); if (high) gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dh",addr,val);
else gen_call_function((void *)&mem_writeb_checked_x86,"%Ddr%Dd",addr,val); else gen_call_function((void *)&mem_writeb_checked,"%Ddr%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) { static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) {
gen_protectflags(); gen_protectflags();
if (dword) gen_call_function((void *)&mem_readd_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); if (dword) gen_call_function((void *)&mem_readd_checked,"%Ddr%Id",addr,&core_dyn.readdata);
else gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); else gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,dword?4:2); gen_mov_host(&core_dyn.readdata,dst,dword?4:2);
} }
static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) { static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) {
gen_protectflags(); gen_protectflags();
if (dword) gen_call_function((void *)&mem_writed_checked_x86,"%Ddr%Dd",addr,val); if (dword) gen_call_function((void *)&mem_writed_checked,"%Ddr%Dd",addr,val);
else gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); else gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
@ -461,13 +472,8 @@ static void dyn_read_intro(DynReg * addr,bool release_addr=true) {
cache_addw(0xc18b); // mov eax,ecx cache_addw(0xc18b); // mov eax,ecx
} }
bool mem_readb_checked_x86x(PhysPt address) { bool mem_readb_checked_dcx86(PhysPt address) {
Bitu index=(address>>12); return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dyn.readdata));
Bitu uval;
bool retval;
retval=paging.tlb.handler[index]->readb_checked(address, &uval);
core_dyn.readdata=(Bit8u)uval;
return retval;
} }
static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) { static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
@ -489,7 +495,7 @@ static void dyn_read_byte(DynReg * addr,DynReg * dst,Bitu high) {
gen_fill_branch(je_loc); gen_fill_branch(je_loc);
cache_addb(0x51); // push ecx cache_addb(0x51); // push ecx
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,4 cache_addw(0xc483); // add esp,4
cache_addb(0x04); cache_addb(0x04);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -527,7 +533,7 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) {
gen_fill_branch(je_loc); gen_fill_branch(je_loc);
cache_addb(0x51); // push ecx cache_addb(0x51); // push ecx
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_readb_checked_x86x) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_readb_checked_dcx86) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,4 cache_addw(0xc483); // add esp,4
cache_addb(0x04); cache_addb(0x04);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -546,20 +552,16 @@ static void dyn_read_byte_release(DynReg * addr,DynReg * dst,Bitu high) {
dst->flags|=DYNFLG_CHANGED; dst->flags|=DYNFLG_CHANGED;
} }
bool mem_readd_checked_x86x(PhysPt address) { bool mem_readd_checked_dcx86(PhysPt address) {
if ((address & 0xfff)<0xffd) { if ((address & 0xfff)<0xffd) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (paging.tlb.read[index]) { if (tlb_addr) {
core_dyn.readdata=host_readd(paging.tlb.read[index]+address); core_dyn.readdata=host_readd(tlb_addr+address);
return false; return false;
} else { } else {
Bitu uval; return get_tlb_readhandler(address)->readd_checked(address, &core_dyn.readdata);
bool retval;
retval=paging.tlb.handler[index]->readd_checked(address, &uval);
core_dyn.readdata=(Bit32u)uval;
return retval;
} }
} else return mem_unalignedreadd_checked_x86(address, &core_dyn.readdata); } else return mem_unalignedreadd_checked(address, &core_dyn.readdata);
} }
static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) { static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) {
@ -589,7 +591,7 @@ static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) {
gen_fill_branch(je_loc); gen_fill_branch(je_loc);
cache_addb(0x51); // push ecx cache_addb(0x51); // push ecx
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,4 cache_addw(0xc483); // add esp,4
cache_addb(0x04); cache_addb(0x04);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -602,7 +604,7 @@ static void dyn_read_word(DynReg * addr,DynReg * dst,bool dword) {
gen_fill_jump(jmp_loc); gen_fill_jump(jmp_loc);
} else { } else {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_readw_checked_x86,"%Dd%Id",addr,&core_dyn.readdata); gen_call_function((void *)&mem_readw_checked,"%Dd%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,2); gen_mov_host(&core_dyn.readdata,dst,2);
} }
@ -635,7 +637,7 @@ static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) {
gen_fill_branch(je_loc); gen_fill_branch(je_loc);
cache_addb(0x51); // push ecx cache_addb(0x51); // push ecx
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_readd_checked_x86x) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_readd_checked_dcx86) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,4 cache_addw(0xc483); // add esp,4
cache_addb(0x04); cache_addb(0x04);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -648,7 +650,7 @@ static void dyn_read_word_release(DynReg * addr,DynReg * dst,bool dword) {
gen_fill_jump(jmp_loc); gen_fill_jump(jmp_loc);
} else { } else {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_readw_checked_x86,"%Ddr%Id",addr,&core_dyn.readdata); gen_call_function((void *)&mem_readw_checked,"%Ddr%Id",addr,&core_dyn.readdata);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dst,2); gen_mov_host(&core_dyn.readdata,dst,2);
} }
@ -709,7 +711,7 @@ static void dyn_write_byte(DynReg * addr,DynReg * val,bool high) {
cache_addb(0x50); // push eax cache_addb(0x50); // push eax
if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8));
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,8 cache_addw(0xc483); // add esp,8
cache_addb(0x08); cache_addb(0x08);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -748,7 +750,7 @@ static void dyn_write_byte_release(DynReg * addr,DynReg * val,bool high) {
cache_addb(0x50); // push eax cache_addb(0x50); // push eax
if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8)); if (GCC_UNLIKELY(high)) cache_addw(0xe086+((genreg->index+(genreg->index<<3))<<8));
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_writeb_checked_x86) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_writeb_checked) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,8 cache_addw(0xc483); // add esp,8
cache_addb(0x08); cache_addb(0x08);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -792,7 +794,7 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) {
cache_addb(0x50+genreg->index); cache_addb(0x50+genreg->index);
cache_addb(0x50); // push eax cache_addb(0x50); // push eax
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,8 cache_addw(0xc483); // add esp,8
cache_addb(0x08); cache_addb(0x08);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -807,7 +809,7 @@ static void dyn_write_word(DynReg * addr,DynReg * val,bool dword) {
gen_fill_jump(jmp_loc); gen_fill_jump(jmp_loc);
} else { } else {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_writew_checked_x86,"%Dd%Dd",addr,val); gen_call_function((void *)&mem_writew_checked,"%Dd%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
} }
@ -841,7 +843,7 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) {
cache_addb(0x50+genreg->index); cache_addb(0x50+genreg->index);
cache_addb(0x50); // push eax cache_addb(0x50); // push eax
cache_addb(0xe8); cache_addb(0xe8);
cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4); cache_addd(((Bit32u)&mem_writed_checked) - (Bit32u)cache.pos-4);
cache_addw(0xc483); // add esp,8 cache_addw(0xc483); // add esp,8
cache_addb(0x08); cache_addb(0x08);
cache_addw(0x012c); // sub al,1 cache_addw(0x012c); // sub al,1
@ -856,7 +858,7 @@ static void dyn_write_word_release(DynReg * addr,DynReg * val,bool dword) {
gen_fill_jump(jmp_loc); gen_fill_jump(jmp_loc);
} else { } else {
gen_protectflags(); gen_protectflags();
gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val); gen_call_function((void *)&mem_writew_checked,"%Ddr%Dd",addr,val);
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
} }
} }
@ -888,10 +890,10 @@ static void dyn_push(DynReg * dynreg) {
gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK)); gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK));
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
if (decode.big_op) { if (decode.big_op) {
gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); gen_call_function((void *)&mem_writed_checked,"%Drd%Dd",DREG(STACK),dynreg);
} else { } else {
//Can just push the whole 32-bit word as operand //Can just push the whole 32-bit word as operand
gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg); gen_call_function((void *)&mem_writew_checked,"%Drd%Dd",DREG(STACK),dynreg);
} }
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
/* everything was ok, change register now */ /* everything was ok, change register now */
@ -906,9 +908,9 @@ static void dyn_pop(DynReg * dynreg,bool checked=true) {
gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS)); gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));
if (checked) { if (checked) {
if (decode.big_op) { if (decode.big_op) {
gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); gen_call_function((void *)&mem_readd_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
} else { } else {
gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata); gen_call_function((void *)&mem_readw_checked,"%Drd%Id",DREG(STACK),&core_dyn.readdata);
} }
dyn_check_bool_exception_al(); dyn_check_bool_exception_al();
gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2); gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2);
@ -1329,6 +1331,68 @@ static void dyn_mov_ev_gw(bool sign) {
} }
} }
static void dyn_cmpxchg_evgv(void) {
dyn_get_modrm();
DynReg * rm_reg=&DynRegs[decode.modrm.reg];
gen_protectflags();
if (decode.modrm.mod<3) {
gen_releasereg(DREG(EAX));
gen_releasereg(DREG(TMPB));
gen_releasereg(rm_reg);
dyn_fill_ea();
dyn_read_word(DREG(EA),DREG(TMPB),decode.big_op);
gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),DREG(TMPB));
Bit8u * branch=gen_create_branch(BR_NZ);
// eax==mem -> mem:=rm_reg
dyn_write_word_release(DREG(EA),rm_reg,decode.big_op);
gen_setzeroflag();
gen_releasereg(DREG(EAX));
gen_releasereg(DREG(TMPB));
gen_releasereg(rm_reg);
Bit8u * jump=gen_create_jump();
gen_fill_branch(branch);
// eax!=mem -> eax:=mem
dyn_write_word_release(DREG(EA),DREG(TMPB),decode.big_op); // cmpxchg always issues write
gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),DREG(TMPB));
gen_clearzeroflag();
gen_releasereg(DREG(EAX));
gen_releasereg(DREG(TMPB));
gen_releasereg(rm_reg);
gen_fill_jump(jump);
} else {
gen_releasereg(DREG(EAX));
gen_releasereg(&DynRegs[decode.modrm.rm]);
gen_releasereg(rm_reg);
gen_dop_word(DOP_CMP,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]);
Bit8u * branch=gen_create_branch(BR_NZ);
// eax==rm -> rm:=rm_reg
gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg);
gen_setzeroflag();
gen_releasereg(DREG(EAX));
gen_releasereg(&DynRegs[decode.modrm.rm]);
gen_releasereg(rm_reg);
Bit8u * jump=gen_create_jump();
gen_fill_branch(branch);
// eax!=rm -> eax:=rm
gen_dop_word(DOP_MOV,decode.big_op,DREG(EAX),&DynRegs[decode.modrm.rm]);
gen_clearzeroflag();
gen_releasereg(DREG(EAX));
gen_releasereg(&DynRegs[decode.modrm.rm]);
gen_releasereg(rm_reg);
gen_fill_jump(jump);
}
}
static void dyn_dshift_ev_gv(bool left,bool immediate) { static void dyn_dshift_ev_gv(bool left,bool immediate) {
dyn_get_modrm(); dyn_get_modrm();
DynReg * rm_reg=&DynRegs[decode.modrm.reg]; DynReg * rm_reg=&DynRegs[decode.modrm.reg];
@ -1591,17 +1655,14 @@ static void dyn_mov_ev_seg(void) {
} }
static void dyn_load_seg(SegNames seg,DynReg * src) { static void dyn_load_seg(SegNames seg,DynReg * src) {
if (cpu.pmode) { gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src);
gen_call_function((void *)&CPU_SetSegGeneral,"%Rd%Id%Drw",DREG(TMPB),seg,src); dyn_check_bool_exception(DREG(TMPB));
dyn_check_bool_exception(DREG(TMPB)); gen_releasereg(DREG(TMPB));
gen_releasereg(DREG(TMPB));
} else gen_call_function((void *)CPU_SetSegGeneral,"%Id%Drw",seg,src);
gen_releasereg(&DynRegs[G_ES+seg]); gen_releasereg(&DynRegs[G_ES+seg]);
} }
static void dyn_load_seg_off_ea(SegNames seg) { static void dyn_load_seg_off_ea(SegNames seg) {
dyn_get_modrm(); if (decode.modrm.mod<3) {
if (GCC_UNLIKELY(decode.modrm.mod<3)) {
dyn_fill_ea(); dyn_fill_ea();
gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2); gen_lea(DREG(TMPB),DREG(EA),0,0,decode.big_op ? 4:2);
dyn_read_word(DREG(TMPB),DREG(TMPB),false); dyn_read_word(DREG(TMPB),DREG(TMPB),false);
@ -1634,18 +1695,12 @@ static void dyn_push_seg(SegNames seg) {
} }
static void dyn_pop_seg(SegNames seg) { static void dyn_pop_seg(SegNames seg) {
if (!cpu.pmode) { gen_releasereg(DREG(ESP));
dyn_pop(DREG(TMPW)); gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op);
dyn_load_seg(seg,DREG(TMPW)); dyn_check_bool_exception(DREG(TMPB));
gen_releasereg(DREG(TMPW)); gen_releasereg(DREG(TMPB));
} else { gen_releasereg(&DynRegs[G_ES+seg]);
gen_releasereg(DREG(ESP)); gen_releasereg(DREG(ESP));
gen_call_function((void *)&CPU_PopSeg,"%Rd%Id%Id",DREG(TMPB),seg,decode.big_op);
dyn_check_bool_exception(DREG(TMPB));
gen_releasereg(DREG(TMPB));
gen_releasereg(&DynRegs[G_ES+seg]);
gen_releasereg(DREG(ESP));
}
} }
static void dyn_pop_ev(void) { static void dyn_pop_ev(void) {
@ -1654,8 +1709,8 @@ static void dyn_pop_ev(void) {
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(); dyn_fill_ea();
// dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op); // dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op);
if (decode.big_op) gen_call_function((void *)&mem_writed_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); if (decode.big_op) gen_call_function((void *)&mem_writed_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW));
else gen_call_function((void *)&mem_writew_dyncorex86,"%Ddr%Dd",DREG(EA),DREG(TMPW)); else gen_call_function((void *)&mem_writew_inline,"%Ddr%Dd",DREG(EA),DREG(TMPW));
} else { } else {
gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW)); gen_dop_word(DOP_MOV,decode.big_op,&DynRegs[decode.modrm.rm],DREG(TMPW));
} }
@ -1683,7 +1738,7 @@ static void dyn_leave(void) {
} }
static void dyn_segprefix(SegNames seg) { static void dyn_segprefix(SegNames seg) {
if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix"); // if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix");
decode.segprefix=&DynRegs[G_ES+seg]; decode.segprefix=&DynRegs[G_ES+seg];
} }
@ -1883,17 +1938,13 @@ static void dyn_interrupt(Bitu num) {
} }
static void dyn_add_iocheck(Bitu access_size) { static void dyn_add_iocheck(Bitu access_size) {
if (cpu.pmode) { gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size);
gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size); dyn_check_bool_exception_al();
dyn_check_bool_exception_al();
}
} }
static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) { static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) {
if (cpu.pmode) { gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size);
gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size); dyn_check_bool_exception_al();
dyn_check_bool_exception_al();
}
} }
#ifdef X86_DYNFPU_DH_ENABLED #ifdef X86_DYNFPU_DH_ENABLED
@ -2008,9 +2059,19 @@ restart_prefix:
case 0xad:dyn_dshift_ev_gv(false,false);break; case 0xad:dyn_dshift_ev_gv(false,false);break;
/* Imul Ev,Gv */ /* Imul Ev,Gv */
case 0xaf:dyn_imul_gvev(0);break; case 0xaf:dyn_imul_gvev(0);break;
/* CMPXCHG */
case 0xb1:dyn_cmpxchg_evgv();break;
/* LFS,LGS */ /* LFS,LGS */
case 0xb4:dyn_load_seg_off_ea(fs);break; case 0xb4:
case 0xb5:dyn_load_seg_off_ea(gs);break; dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(fs);
break;
case 0xb5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(gs);
break;
/* MOVZX Gv,Eb/Ew */ /* MOVZX Gv,Eb/Ew */
case 0xb6:dyn_mov_ev_gb(false);break; case 0xb6:dyn_mov_ev_gb(false);break;
case 0xb7:dyn_mov_ev_gw(false);break; case 0xb7:dyn_mov_ev_gw(false);break;
@ -2197,6 +2258,7 @@ restart_prefix:
dyn_check_bool_exception(DREG(TMPB)); dyn_check_bool_exception(DREG(TMPB));
dyn_flags_host_to_gen(); dyn_flags_host_to_gen();
gen_releasereg(DREG(TMPB)); gen_releasereg(DREG(TMPB));
dyn_check_irqrequest();
break; break;
/* MOV AL,direct addresses */ /* MOV AL,direct addresses */
case 0xa0: case 0xa0:
@ -2261,9 +2323,18 @@ restart_prefix:
//RET near Iw / Ret //RET near Iw / Ret
case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block;
case 0xc3:dyn_ret_near(0);goto finish_block; case 0xc3:dyn_ret_near(0);goto finish_block;
//LES/LDS //LES
case 0xc4:dyn_load_seg_off_ea(es);break; case 0xc4:
case 0xc5:dyn_load_seg_off_ea(ds);break; dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(es);
break;
//LDS
case 0xc5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(ds);
break;
// MOV Eb/Ev,Ib/Iv // MOV Eb/Ev,Ib/Iv
case 0xc6:dyn_mov_ebib();break; case 0xc6:dyn_mov_ebib();break;
case 0xc7:dyn_mov_eviv();break; case 0xc7:dyn_mov_eviv();break;
@ -2474,13 +2545,13 @@ restart_prefix:
case 0xfa: //CLI case 0xfa: //CLI
gen_releasereg(DREG(FLAGS)); gen_releasereg(DREG(FLAGS));
gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB)); gen_call_function((void *)&CPU_CLI,"%Rd",DREG(TMPB));
if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); dyn_check_bool_exception(DREG(TMPB));
gen_releasereg(DREG(TMPB)); gen_releasereg(DREG(TMPB));
break; break;
case 0xfb: //STI case 0xfb: //STI
gen_releasereg(DREG(FLAGS)); gen_releasereg(DREG(FLAGS));
gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB)); gen_call_function((void *)&CPU_STI,"%Rd",DREG(TMPB));
if (cpu.pmode) dyn_check_bool_exception(DREG(TMPB)); dyn_check_bool_exception(DREG(TMPB));
gen_releasereg(DREG(TMPB)); gen_releasereg(DREG(TMPB));
dyn_check_irqrequest(); dyn_check_irqrequest();
if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode

View File

@ -16,47 +16,47 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: dyn_fpu_dh.h,v 1.4 2007/06/14 17:47:24 c2woody Exp $ */ /* $Id: dyn_fpu_dh.h,v 1.5 2007/09/29 13:23:59 c2woody Exp $ */
#include "dosbox.h" #include "dosbox.h"
#if C_FPU #if C_FPU
static void FPU_FLD_16(PhysPt addr) { static void FPU_FLD_16(PhysPt addr) {
dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw_dyncorex86(addr); dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw(addr);
} }
static void FPU_FST_16(PhysPt addr) { static void FPU_FST_16(PhysPt addr) {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.temp.m1); mem_writew(addr,(Bit16u)dyn_dh_fpu.temp.m1);
} }
static void FPU_FLD_32(PhysPt addr) { static void FPU_FLD_32(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); dyn_dh_fpu.temp.m1 = mem_readd(addr);
} }
static void FPU_FST_32(PhysPt addr) { static void FPU_FST_32(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); mem_writed(addr,dyn_dh_fpu.temp.m1);
} }
static void FPU_FLD_64(PhysPt addr) { static void FPU_FLD_64(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); dyn_dh_fpu.temp.m1 = mem_readd(addr);
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
} }
static void FPU_FST_64(PhysPt addr) { static void FPU_FST_64(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); mem_writed(addr,dyn_dh_fpu.temp.m1);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); mem_writed(addr+4,dyn_dh_fpu.temp.m2);
} }
static void FPU_FLD_80(PhysPt addr) { static void FPU_FLD_80(PhysPt addr) {
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr); dyn_dh_fpu.temp.m1 = mem_readd(addr);
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
} }
static void FPU_FST_80(PhysPt addr) { static void FPU_FST_80(PhysPt addr) {
mem_writed_dyncorex86(addr,dyn_dh_fpu.temp.m1); mem_writed(addr,dyn_dh_fpu.temp.m1);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); mem_writed(addr+4,dyn_dh_fpu.temp.m2);
mem_writew_dyncorex86(addr+8,dyn_dh_fpu.temp.m3); mem_writew(addr+8,dyn_dh_fpu.temp.m3);
} }
static void FPU_FLDCW_DH(PhysPt addr){ static void FPU_FLDCW_DH(PhysPt addr){
@ -74,35 +74,35 @@ static void FPU_FNINIT_DH(void){
static void FPU_FSTENV_DH(PhysPt addr){ static void FPU_FSTENV_DH(PhysPt addr){
if(!cpu.code.big) { if(!cpu.code.big) {
mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writew_dyncorex86(addr+2,(Bit16u)dyn_dh_fpu.temp.m2); mem_writew(addr+2,(Bit16u)dyn_dh_fpu.temp.m2);
mem_writew_dyncorex86(addr+4,dyn_dh_fpu.temp.m3); mem_writew(addr+4,dyn_dh_fpu.temp.m3);
} else { } else {
mem_writed_dyncorex86(addr+0,dyn_dh_fpu.temp.m1); mem_writed(addr+0,dyn_dh_fpu.temp.m1);
mem_writew_dyncorex86(addr+0,(Bit16u)dyn_dh_fpu.cw); mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
mem_writed_dyncorex86(addr+4,dyn_dh_fpu.temp.m2); mem_writed(addr+4,dyn_dh_fpu.temp.m2);
mem_writed_dyncorex86(addr+8,dyn_dh_fpu.temp.m3); mem_writed(addr+8,dyn_dh_fpu.temp.m3);
} }
} }
static void FPU_FLDENV_DH(PhysPt addr){ static void FPU_FLDENV_DH(PhysPt addr){
if(!cpu.code.big) { if(!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f; dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f;
dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw_dyncorex86(addr+2); dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw(addr+2);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+4); dyn_dh_fpu.temp.m3 = mem_readw(addr+4);
} else { } else {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp.m1 = mem_readd_dyncorex86(addr)|0x3f; dyn_dh_fpu.temp.m1 = mem_readd(addr)|0x3f;
dyn_dh_fpu.temp.m2 = mem_readd_dyncorex86(addr+4); dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
dyn_dh_fpu.temp.m3 = mem_readw_dyncorex86(addr+8); dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
dyn_dh_fpu.temp.d1 = mem_readw_dyncorex86(addr+10); dyn_dh_fpu.temp.d1 = mem_readw(addr+10);
} }
} }
static void FPU_FSAVE_DH(PhysPt addr){ static void FPU_FSAVE_DH(PhysPt addr){
if (!cpu.code.big) { if (!cpu.code.big) {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw); mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2; addr+=2;
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]); mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]);
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]); mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]);
@ -118,7 +118,7 @@ static void FPU_FSAVE_DH(PhysPt addr){
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]); mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]);
for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]); for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
} else { } else {
mem_writew_dyncorex86(addr,(Bit16u)dyn_dh_fpu.cw); mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
addr+=2; addr+=2;
for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]); for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
} }
@ -126,7 +126,7 @@ static void FPU_FSAVE_DH(PhysPt addr){
static void FPU_FRSTOR_DH(PhysPt addr){ static void FPU_FRSTOR_DH(PhysPt addr){
if (!cpu.code.big) { if (!cpu.code.big) {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f; dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f;
dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++); dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++); dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++);
@ -143,7 +143,7 @@ static void FPU_FRSTOR_DH(PhysPt addr){
dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++); dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++);
for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++); for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
} else { } else {
dyn_dh_fpu.cw = (Bit32u)mem_readw_dyncorex86(addr); dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++); for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
dyn_dh_fpu.temp_state[0]|=0x3f; dyn_dh_fpu.temp_state[0]|=0x3f;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: risc_x86.h,v 1.31 2008/08/06 18:31:26 c2woody Exp $ */
static void gen_init(void); static void gen_init(void);
/* End of needed */ /* End of needed */
@ -268,6 +270,18 @@ static void gen_needcarry(void) {
} }
} }
static void gen_setzeroflag(void) {
if (x86gen.flagsactive) IllegalOption("gen_setzeroflag");
cache_addw(0x0c83); //OR DWORD [ESP],0x40
cache_addw(0x4024);
}
static void gen_clearzeroflag(void) {
if (x86gen.flagsactive) IllegalOption("gen_clearzeroflag");
cache_addw(0x2483); //AND DWORD [ESP],~0x40
cache_addw(0xbf24);
}
static bool skip_flags=false; static bool skip_flags=false;
static void set_skipflags(bool state) { static void set_skipflags(bool state) {
@ -738,8 +752,10 @@ static void gen_call_function(void * func,char const* ops,...) {
if (ops) { if (ops) {
va_list params; va_list params;
va_start(params,ops); va_start(params,ops);
#if defined (MACOSX)
Bitu stack_used=0; Bitu stack_used=0;
bool free_flags=false; bool free_flags=false;
#endif
Bits pindex=0; Bits pindex=0;
while (*ops) { while (*ops) {
if (*ops=='%') { if (*ops=='%') {
@ -925,9 +941,9 @@ static void gen_call_write(DynReg * dr,Bit32u val,Bitu write_size) {
/* Do the actual call to the procedure */ /* Do the actual call to the procedure */
cache_addb(0xe8); cache_addb(0xe8);
switch (write_size) { switch (write_size) {
case 1: cache_addd((Bit32u)mem_writeb_checked_x86 - (Bit32u)cache.pos-4); break; case 1: cache_addd((Bit32u)mem_writeb_checked - (Bit32u)cache.pos-4); break;
case 2: cache_addd((Bit32u)mem_writew_checked_x86 - (Bit32u)cache.pos-4); break; case 2: cache_addd((Bit32u)mem_writew_checked - (Bit32u)cache.pos-4); break;
case 4: cache_addd((Bit32u)mem_writed_checked_x86 - (Bit32u)cache.pos-4); break; case 4: cache_addd((Bit32u)mem_writed_checked - (Bit32u)cache.pos-4); break;
default: IllegalOption("gen_call_write"); default: IllegalOption("gen_call_write");
} }

View File

@ -23,7 +23,7 @@ enum STRING_OP {
STR_LODSB=12,STR_LODSW,STR_LODSD, STR_LODSB=12,STR_LODSW,STR_LODSD,
STR_STOSB=16,STR_STOSW,STR_STOSD, STR_STOSB=16,STR_STOSW,STR_STOSD,
STR_SCASB=20,STR_SCASW,STR_SCASD, STR_SCASB=20,STR_SCASW,STR_SCASD,
STR_CMPSB=24,STR_CMPSW,STR_CMPSD, STR_CMPSB=24,STR_CMPSW,STR_CMPSD
}; };
static void dyn_string(STRING_OP op) { static void dyn_string(STRING_OP op) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: core_dynrec.cpp,v 1.11 2008/09/19 16:48:02 c2woody Exp $ */
#include "dosbox.h" #include "dosbox.h"
#if (C_DYNREC) #if (C_DYNREC)
@ -90,7 +92,7 @@
// access to a general register // access to a general register
#define DRCD_REG(reg) (&cpu_regs.regs[reg].dword) #define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword)
// access to a segment register // access to a segment register
#define DRCD_SEG_VAL(seg) (&Segs.val[seg]) #define DRCD_SEG_VAL(seg) (&Segs.val[seg])
// access to the physical value of a segment register/selector // access to the physical value of a segment register/selector
@ -136,6 +138,7 @@ static struct {
#define X86 0x01 #define X86 0x01
#define X86_64 0x02 #define X86_64 0x02
#define MIPSEL 0x03 #define MIPSEL 0x03
#define ARMV4LE 0x04
#if C_TARGETCPU == X86_64 #if C_TARGETCPU == X86_64
#include "core_dynrec/risc_x64.h" #include "core_dynrec/risc_x64.h"
@ -143,6 +146,8 @@ static struct {
#include "core_dynrec/risc_x86.h" #include "core_dynrec/risc_x86.h"
#elif C_TARGETCPU == MIPSEL #elif C_TARGETCPU == MIPSEL
#include "core_dynrec/risc_mipsel32.h" #include "core_dynrec/risc_mipsel32.h"
#elif C_TARGETCPU == ARMV4LE
#include "core_dynrec/risc_armv4le.h"
#endif #endif
#include "core_dynrec/decoder.h" #include "core_dynrec/decoder.h"
@ -151,8 +156,7 @@ CacheBlockDynRec * LinkBlocks(BlockReturn ret) {
CacheBlockDynRec * block=NULL; CacheBlockDynRec * block=NULL;
// the last instruction was a control flow modifying instruction // the last instruction was a control flow modifying instruction
Bitu temp_ip=SegPhys(cs)+reg_eip; Bitu temp_ip=SegPhys(cs)+reg_eip;
Bitu temp_page=temp_ip >> 12; CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip);
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)paging.tlb.handler[temp_page];
if (temp_handler->flags & PFLAG_HASCODE) { if (temp_handler->flags & PFLAG_HASCODE) {
// see if the target is an already translated block // see if the target is an already translated block
block=temp_handler->FindCacheBlock(temp_ip & 4095); block=temp_handler->FindCacheBlock(temp_ip & 4095);

View File

@ -1,2 +1,5 @@
noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \ noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \
dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \
risc_armv4le.h risc_armv4le-common.h \
risc_armv4le-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h \
risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h

View File

@ -1,332 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \
dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h
subdir = src/cpu/core_dynrec
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/cpu/core_dynrec/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(HEADERS)
installdirs:
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
info info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-info-am
# 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:

View File

@ -117,7 +117,7 @@ public:
bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible
Bit32u ip_point=SegPhys(cs)+reg_eip; Bit32u ip_point=SegPhys(cs)+reg_eip;
ip_point=((paging.tlb.phys_page[ip_point>>12]-phys_page)<<12)+(ip_point&0xfff); ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
while (index>=0) { while (index>=0) {
Bitu map=0; Bitu map=0;
// see if there is still some code in the range // see if there is still some code in the range
@ -145,7 +145,7 @@ public:
if (host_readb(hostmem+addr)==(Bit8u)val) return; if (host_readb(hostmem+addr)==(Bit8u)val) return;
host_writeb(hostmem+addr,val); host_writeb(hostmem+addr,val);
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit8u*)&write_map[addr]) { if (!host_readb(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page if (active_blocks) return; // still some blocks in this page
active_count--; active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero if (!active_count) Release(); // delay page releasing until active_count is zero
@ -162,7 +162,7 @@ public:
if (host_readw(hostmem+addr)==(Bit16u)val) return; if (host_readw(hostmem+addr)==(Bit16u)val) return;
host_writew(hostmem+addr,val); host_writew(hostmem+addr,val);
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit16u*)&write_map[addr]) { if (!host_readw(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page if (active_blocks) return; // still some blocks in this page
active_count--; active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero if (!active_count) Release(); // delay page releasing until active_count is zero
@ -171,7 +171,12 @@ public:
invalidation_map=(Bit8u*)malloc(4096); invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096); memset(invalidation_map,0,4096);
} }
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writew(&invalidation_map[addr],
host_readw(&invalidation_map[addr])+0x101);
#else
(*(Bit16u*)&invalidation_map[addr])+=0x101; (*(Bit16u*)&invalidation_map[addr])+=0x101;
#endif
InvalidateRange(addr,addr+1); InvalidateRange(addr,addr+1);
} }
void writed(PhysPt addr,Bitu val){ void writed(PhysPt addr,Bitu val){
@ -179,7 +184,7 @@ public:
if (host_readd(hostmem+addr)==(Bit32u)val) return; if (host_readd(hostmem+addr)==(Bit32u)val) return;
host_writed(hostmem+addr,val); host_writed(hostmem+addr,val);
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit32u*)&write_map[addr]) { if (!host_readd(&write_map[addr])) {
if (active_blocks) return; // still some blocks in this page if (active_blocks) return; // still some blocks in this page
active_count--; active_count--;
if (!active_count) Release(); // delay page releasing until active_count is zero if (!active_count) Release(); // delay page releasing until active_count is zero
@ -188,14 +193,19 @@ public:
invalidation_map=(Bit8u*)malloc(4096); invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096); memset(invalidation_map,0,4096);
} }
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writed(&invalidation_map[addr],
host_readd(&invalidation_map[addr])+0x1010101);
#else
(*(Bit32u*)&invalidation_map[addr])+=0x1010101; (*(Bit32u*)&invalidation_map[addr])+=0x1010101;
#endif
InvalidateRange(addr,addr+3); InvalidateRange(addr,addr+3);
} }
bool writeb_checked(PhysPt addr,Bitu val) { bool writeb_checked(PhysPt addr,Bitu val) {
addr&=4095; addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return false; if (host_readb(hostmem+addr)==(Bit8u)val) return false;
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit8u*)&write_map[addr]) { if (!host_readb(&write_map[addr])) {
if (!active_blocks) { if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit // no blocks left in this page, still delay the page releasing a bit
active_count--; active_count--;
@ -219,7 +229,7 @@ public:
addr&=4095; addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return false; if (host_readw(hostmem+addr)==(Bit16u)val) return false;
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit16u*)&write_map[addr]) { if (!host_readw(&write_map[addr])) {
if (!active_blocks) { if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit // no blocks left in this page, still delay the page releasing a bit
active_count--; active_count--;
@ -230,7 +240,12 @@ public:
invalidation_map=(Bit8u*)malloc(4096); invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096); memset(invalidation_map,0,4096);
} }
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writew(&invalidation_map[addr],
host_readw(&invalidation_map[addr])+0x101);
#else
(*(Bit16u*)&invalidation_map[addr])+=0x101; (*(Bit16u*)&invalidation_map[addr])+=0x101;
#endif
if (InvalidateRange(addr,addr+1)) { if (InvalidateRange(addr,addr+1)) {
cpu.exception.which=SMC_CURRENT_BLOCK; cpu.exception.which=SMC_CURRENT_BLOCK;
return true; return true;
@ -243,7 +258,7 @@ public:
addr&=4095; addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return false; if (host_readd(hostmem+addr)==(Bit32u)val) return false;
// see if there's code where we are writing to // see if there's code where we are writing to
if (!*(Bit32u*)&write_map[addr]) { if (!host_readd(&write_map[addr])) {
if (!active_blocks) { if (!active_blocks) {
// no blocks left in this page, still delay the page releasing a bit // no blocks left in this page, still delay the page releasing a bit
active_count--; active_count--;
@ -254,7 +269,12 @@ public:
invalidation_map=(Bit8u*)malloc(4096); invalidation_map=(Bit8u*)malloc(4096);
memset(invalidation_map,0,4096); memset(invalidation_map,0,4096);
} }
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
host_writed(&invalidation_map[addr],
host_readd(&invalidation_map[addr])+0x1010101);
#else
(*(Bit32u*)&invalidation_map[addr])+=0x1010101; (*(Bit32u*)&invalidation_map[addr])+=0x1010101;
#endif
if (InvalidateRange(addr,addr+3)) { if (InvalidateRange(addr,addr+3)) {
cpu.exception.which=SMC_CURRENT_BLOCK; cpu.exception.which=SMC_CURRENT_BLOCK;
return true; return true;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: decoder.h,v 1.5 2008/09/19 16:48:02 c2woody Exp $ */
#include "decoder_basic.h" #include "decoder_basic.h"
#include "operators.h" #include "operators.h"
@ -218,8 +220,18 @@ restart_prefix:
case 0xaf:dyn_imul_gvev(0);break; case 0xaf:dyn_imul_gvev(0);break;
case 0xb4:dyn_load_seg_off_ea(DRC_SEG_FS);break; // lfs
case 0xb5:dyn_load_seg_off_ea(DRC_SEG_GS);break; case 0xb4:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_FS);
break;
// lgs
case 0xb5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_GS);
break;
// zero-extending moves // zero-extending moves
case 0xb6:dyn_movx_ev_gb(false);break; case 0xb6:dyn_movx_ev_gb(false);break;
@ -314,11 +326,7 @@ restart_prefix:
case 0x8c:dyn_mov_ev_seg();break; case 0x8c:dyn_mov_ev_seg();break;
// load effective address // load effective address
case 0x8d: case 0x8d:dyn_lea();break;
dyn_get_modrm();
dyn_fill_ea(FC_ADDR,false);
gen_mov_word_from_reg(FC_ADDR,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op);
break;
// move a value from memory or a 16bit register into a segment register // move a value from memory or a 16bit register into a segment register
case 0x8e:dyn_mov_seg_ev();break; case 0x8e:dyn_mov_seg_ev();break;
@ -413,8 +421,17 @@ restart_prefix:
case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block; case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block;
case 0xc3:dyn_ret_near(0);goto finish_block; case 0xc3:dyn_ret_near(0);goto finish_block;
case 0xc4:dyn_load_seg_off_ea(DRC_SEG_ES);break; // les
case 0xc5:dyn_load_seg_off_ea(DRC_SEG_DS);break; case 0xc4:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_ES);
break;
// lds
case 0xc5:
dyn_get_modrm();
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
dyn_load_seg_off_ea(DRC_SEG_DS);break;
// 'mov []/reg8/16/32,imm8/16/32' // 'mov []/reg8/16/32,imm8/16/32'
case 0xc6:dyn_dop_ebib_mov();break; case 0xc6:dyn_dop_ebib_mov();break;
@ -530,11 +547,11 @@ restart_prefix:
case 0xfa: //CLI case 0xfa: //CLI
gen_call_function_raw((void *)&CPU_CLI); gen_call_function_raw((void *)&CPU_CLI);
if (cpu.pmode) dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
break; break;
case 0xfb: //STI case 0xfb: //STI
gen_call_function_raw((void *)&CPU_STI); gen_call_function_raw((void *)&CPU_STI);
if (cpu.pmode) dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: decoder_basic.h,v 1.14 2009/03/29 17:32:20 qbix79 Exp $ */
/* /*
This file provides some definitions and basic level functions This file provides some definitions and basic level functions
@ -29,7 +31,7 @@
// instructions that use one operand // instructions that use one operand
enum SingleOps { enum SingleOps {
SOP_INC,SOP_DEC, SOP_INC,SOP_DEC,
SOP_NOT,SOP_NEG, SOP_NOT,SOP_NEG
}; };
// instructions that use two operand // instructions that use two operand
@ -40,7 +42,7 @@ enum DualOps {
DOP_AND,DOP_OR, DOP_AND,DOP_OR,
DOP_TEST, DOP_TEST,
DOP_MOV, DOP_MOV,
DOP_XCHG, DOP_XCHG
}; };
// shift and rotate functions // shift and rotate functions
@ -48,7 +50,7 @@ enum ShiftOps {
SHIFT_ROL,SHIFT_ROR, SHIFT_ROL,SHIFT_ROR,
SHIFT_RCL,SHIFT_RCR, SHIFT_RCL,SHIFT_RCR,
SHIFT_SHL,SHIFT_SHR, SHIFT_SHL,SHIFT_SHR,
SHIFT_SAL,SHIFT_SAR, SHIFT_SAL,SHIFT_SAR
}; };
// branch conditions // branch conditions
@ -67,7 +69,7 @@ enum StringOps {
STR_LODSB=12,STR_LODSW,STR_LODSD, STR_LODSB=12,STR_LODSW,STR_LODSD,
STR_STOSB=16,STR_STOSW,STR_STOSD, STR_STOSB=16,STR_STOSW,STR_STOSD,
STR_SCASB=20,STR_SCASW,STR_SCASD, STR_SCASB=20,STR_SCASW,STR_SCASD,
STR_CMPSB=24,STR_CMPSW,STR_CMPSD, STR_CMPSB=24,STR_CMPSW,STR_CMPSD
}; };
// repeat prefix type (for string operations) // repeat prefix type (for string operations)
@ -82,7 +84,7 @@ enum LoopTypes {
// rotate operand type // rotate operand type
enum grp2_types { enum grp2_types {
grp2_1,grp2_imm,grp2_cl, grp2_1,grp2_imm,grp2_cl
}; };
// opcode mapping for group1 instructions // opcode mapping for group1 instructions
@ -130,21 +132,29 @@ static struct DynDecode {
static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) { static bool MakeCodePage(Bitu lin_addr,CodePageHandlerDynRec * &cph) {
Bit8u rdval; Bit8u rdval;
//Ensure page contains memory: //Ensure page contains memory:
if (GCC_UNLIKELY(mem_readb_checked_x86(lin_addr,&rdval))) return true; if (GCC_UNLIKELY(mem_readb_checked(lin_addr,&rdval))) return true;
Bitu lin_page=lin_addr >> 12; PageHandler * handler=get_tlb_readhandler(lin_addr);
PageHandler * handler=paging.tlb.handler[lin_page];
if (handler->flags & PFLAG_HASCODE) { if (handler->flags & PFLAG_HASCODE) {
// this is a codepage handler, and the one that we're looking for // this is a codepage handler, and the one that we're looking for
cph=(CodePageHandlerDynRec *)handler; cph=(CodePageHandlerDynRec *)handler;
return false; return false;
} }
if (handler->flags & PFLAG_NOCODE) { if (handler->flags & PFLAG_NOCODE) {
LOG_MSG("DYNREC:Can't run code in this page"); if (PAGING_ForcePageInit(lin_addr)) {
cph=0; handler=get_tlb_readhandler(lin_addr);
return false; if (handler->flags & PFLAG_HASCODE) {
cph=(CodePageHandlerDynRec *)handler;
return false;
}
}
if (handler->flags & PFLAG_NOCODE) {
LOG_MSG("DYNREC:Can't run code in this page");
cph=0;
return false;
}
} }
Bitu lin_page=lin_addr>>12;
Bitu phys_page=lin_page; Bitu phys_page=lin_page;
// find the physical page that the linear page is mapped to // find the physical page that the linear page is mapped to
if (!PAGING_MakePhysPage(phys_page)) { if (!PAGING_MakePhysPage(phys_page)) {
@ -280,10 +290,10 @@ static bool decode_fetchb_imm(Bitu & val) {
if (GCC_UNLIKELY(decode.page.index>=4096)) { if (GCC_UNLIKELY(decode.page.index>=4096)) {
decode_advancepage(); decode_advancepage();
} }
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible // see if position is directly accessible
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1); decode_increase_wmapmask(1);
decode.code++; decode.code++;
decode.page.index++; decode.page.index++;
@ -298,10 +308,10 @@ static bool decode_fetchb_imm(Bitu & val) {
// otherwise val contains the current value read from the position // otherwise val contains the current value read from the position
static bool decode_fetchw_imm(Bitu & val) { static bool decode_fetchw_imm(Bitu & val) {
if (decode.page.index<4095) { if (decode.page.index<4095) {
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible // see if position is directly accessible
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2); decode_increase_wmapmask(2);
decode.code+=2; decode.code+=2;
decode.page.index+=2; decode.page.index+=2;
@ -317,10 +327,10 @@ static bool decode_fetchw_imm(Bitu & val) {
// otherwise val contains the current value read from the position // otherwise val contains the current value read from the position
static bool decode_fetchd_imm(Bitu & val) { static bool decode_fetchd_imm(Bitu & val) {
if (decode.page.index<4093) { if (decode.page.index<4093) {
Bitu index=(decode.code>>12); HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible // see if position is directly accessible
if (paging.tlb.read[index]) { if (tlb_addr) {
val=(Bitu)(paging.tlb.read[index]+decode.code); val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4); decode_increase_wmapmask(4);
decode.code+=4; decode.code+=4;
decode.page.index+=4; decode.page.index+=4;
@ -342,6 +352,89 @@ static void INLINE dyn_get_modrm(void) {
} }
#ifdef DRC_USE_SEGS_ADDR
#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_seg16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_VAL(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs))
#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs))
#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add_seg32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_SEG_PHYS(seg_index)) - (DRC_PTR_SIZE_IM)(&Segs))
#else
#define MOV_SEG_VAL_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_VAL(seg_index),false)
#define MOV_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_mov_word_to_reg(host_reg,DRCD_SEG_PHYS(seg_index),true)
#define ADD_SEG_PHYS_TO_HOST_REG(host_reg, seg_index) gen_add(host_reg,DRCD_SEG_PHYS(seg_index))
#endif
#ifdef DRC_USE_REGS_ADDR
#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_VAL(reg_index)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_regval16_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_regval32_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_to_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword)
#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval16_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,false)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_regval32_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,true)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_regword_from_reg(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_WORD(reg_index,dword)) - (DRC_PTR_SIZE_IM)(&cpu_regs), dword)
#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_regbyte_to_reg_low_canuseword(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_regbyte_from_reg_low(host_reg,(DRC_PTR_SIZE_IM)(DRCD_REG_BYTE(reg_index,high_byte)) - (DRC_PTR_SIZE_IM)(&cpu_regs))
#else
#define MOV_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_VAL(reg_index),true)
#define ADD_REG_VAL_TO_HOST_REG(host_reg, reg_index) gen_add(host_reg,DRCD_REG_VAL(reg_index))
#define MOV_REG_WORD16_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,false),false)
#define MOV_REG_WORD32_TO_HOST_REG(host_reg, reg_index) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,true),true)
#define MOV_REG_WORD_TO_HOST_REG(host_reg, reg_index, dword) gen_mov_word_to_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword)
#define MOV_REG_WORD16_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,false),false)
#define MOV_REG_WORD32_FROM_HOST_REG(host_reg, reg_index) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,true),true)
#define MOV_REG_WORD_FROM_HOST_REG(host_reg, reg_index, dword) gen_mov_word_from_reg(host_reg,DRCD_REG_WORD(reg_index,dword),dword)
#define MOV_REG_BYTE_TO_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte))
#define MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(host_reg, reg_index, high_byte) gen_mov_byte_to_reg_low_canuseword(host_reg,DRCD_REG_BYTE(reg_index,high_byte))
#define MOV_REG_BYTE_FROM_HOST_REG_LOW(host_reg, reg_index, high_byte) gen_mov_byte_from_reg_low(host_reg,DRCD_REG_BYTE(reg_index,high_byte))
#endif
#define DYN_LEA_MEM_MEM(ea_reg, op1, op2, scale, imm) dyn_lea_mem_mem(ea_reg,op1,op2,scale,imm)
#if defined(DRC_USE_REGS_ADDR) && defined(DRC_USE_SEGS_ADDR)
#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_regval(ea_reg,op1_index,op2_index,scale,imm)
#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm)
#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm)
#elif defined(DRC_USE_REGS_ADDR)
#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,DRCD_SEG_PHYS(op1_index),op2_index,scale,imm)
#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_regval_regval(ea_reg,op1_index,op2_index,scale,imm)
#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_regval(ea_reg,op1,op2_index,scale,imm)
#elif defined(DRC_USE_SEGS_ADDR)
#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_segphys_mem(ea_reg,op1_index,DRCD_REG_VAL(op2_index),scale,imm)
#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm)
#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm)
#else
#define DYN_LEA_SEG_PHYS_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_SEG_PHYS(op1_index),DRCD_REG_VAL(op2_index),scale,imm)
#define DYN_LEA_REG_VAL_REG_VAL(ea_reg, op1_index, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,DRCD_REG_VAL(op1_index),DRCD_REG_VAL(op2_index),scale,imm)
#define DYN_LEA_MEM_REG_VAL(ea_reg, op1, op2_index, scale, imm) dyn_lea_mem_mem(ea_reg,op1,DRCD_REG_VAL(op2_index),scale,imm)
#endif
// adjust CPU_Cycles value // adjust CPU_Cycles value
static void dyn_reduce_cycles(void) { static void dyn_reduce_cycles(void) {
@ -476,7 +569,7 @@ static DRC_PTR_SIZE_IM INLINE gen_call_function_mm(void * func,Bitu op1,Bitu op2
enum save_info_type {exception, cycle_check, string_break}; enum save_info_type {db_exception, cycle_check, string_break};
// function that is called on exceptions // function that is called on exceptions
@ -520,7 +613,7 @@ static void dyn_fill_blocks(void) {
for (Bitu sct=0; sct<used_save_info_dynrec; sct++) { for (Bitu sct=0; sct<used_save_info_dynrec; sct++) {
gen_fill_branch_long(save_info_dynrec[sct].branch_pos); gen_fill_branch_long(save_info_dynrec[sct].branch_pos);
switch (save_info_dynrec[sct].type) { switch (save_info_dynrec[sct].type) {
case exception: case db_exception:
// code for exception handling, load cycles and call DynRunException // code for exception handling, load cycles and call DynRunException
decode.cycles=save_info_dynrec[sct].cycles; decode.cycles=save_info_dynrec[sct].cycles;
if (cpu.code.big) gen_call_function_II((void *)&DynRunException,save_info_dynrec[sct].eip_change,save_info_dynrec[sct].cycles); if (cpu.code.big) gen_call_function_II((void *)&DynRunException,save_info_dynrec[sct].eip_change,save_info_dynrec[sct].cycles);
@ -545,7 +638,9 @@ static void dyn_fill_blocks(void) {
static void dyn_closeblock(void) { static void dyn_closeblock(void) {
//Shouldn't create empty block normally but let's do it like this //Shouldn't create empty block normally but let's do it like this
dyn_fill_blocks(); dyn_fill_blocks();
cache_block_before_close();
cache_closeblock(); cache_closeblock();
cache_block_closing(decode.block->cache.start,decode.block->cache.size);
} }
@ -557,7 +652,7 @@ static void dyn_check_exception(HostReg reg) {
// in case of an exception eip will point to the start of the current instruction // in case of an exception eip will point to the start of the current instruction
save_info_dynrec[used_save_info_dynrec].eip_change=decode.op_start-decode.code_start; save_info_dynrec[used_save_info_dynrec].eip_change=decode.op_start-decode.code_start;
if (!cpu.code.big) save_info_dynrec[used_save_info_dynrec].eip_change&=0xffff; if (!cpu.code.big) save_info_dynrec[used_save_info_dynrec].eip_change&=0xffff;
save_info_dynrec[used_save_info_dynrec].type=exception; save_info_dynrec[used_save_info_dynrec].type=db_exception;
used_save_info_dynrec++; used_save_info_dynrec++;
} }
@ -565,98 +660,66 @@ static void dyn_check_exception(HostReg reg) {
bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) DRC_FC;
bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) { bool DRC_CALL_CONV mem_readb_checked_drc(PhysPt address) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_read(address);
if (paging.tlb.read[index]) { if (tlb_addr) {
*((Bit8u*)(&core_dynrec.readdata))=host_readb(paging.tlb.read[index]+address); *((Bit8u*)(&core_dynrec.readdata))=host_readb(tlb_addr+address);
return false; return false;
} else { } else {
Bitu uval; return get_tlb_readhandler(address)->readb_checked(address, (Bit8u*)(&core_dynrec.readdata));
bool retval;
retval=paging.tlb.handler[index]->readb_checked(address, &uval);
*((Bit8u*)(&core_dynrec.readdata))=(Bit8u)uval;
return retval;
} }
} }
bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC; bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) DRC_FC;
bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) { bool DRC_CALL_CONV mem_writeb_checked_drc(PhysPt address,Bit8u val) {
Bitu index=(address>>12); HostPt tlb_addr=get_tlb_write(address);
if (paging.tlb.write[index]) { if (tlb_addr) {
host_writeb(paging.tlb.write[index]+address,val); host_writeb(tlb_addr+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writeb_checked(address,val); } else return get_tlb_writehandler(address)->writeb_checked(address,val);
} }
bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) DRC_FC;
bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) { bool DRC_CALL_CONV mem_readw_checked_drc(PhysPt address) {
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
if (!(address & 1)) {
#else
if ((address & 0xfff)<0xfff) { if ((address & 0xfff)<0xfff) {
#endif HostPt tlb_addr=get_tlb_read(address);
Bitu index=(address>>12); if (tlb_addr) {
if (paging.tlb.read[index]) { *((Bit16u*)(&core_dynrec.readdata))=host_readw(tlb_addr+address);
*((Bit16u*)(&core_dynrec.readdata))=host_readw(paging.tlb.read[index]+address);
return false; return false;
} else { } else return get_tlb_readhandler(address)->readw_checked(address, (Bit16u*)(&core_dynrec.readdata));
Bitu uval; } else return mem_unalignedreadw_checked(address, ((Bit16u*)(&core_dynrec.readdata)));
bool retval;
retval=paging.tlb.handler[index]->readw_checked(address, &uval);
*((Bit16u*)(&core_dynrec.readdata))=(Bit16u)uval;
return retval;
}
} else return mem_unalignedreadw_checked_x86(address, ((Bit16u*)(&core_dynrec.readdata)));
} }
bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC; bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) DRC_FC;
bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) { bool DRC_CALL_CONV mem_readd_checked_drc(PhysPt address) {
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
if (!(address & 3)) {
#else
if ((address & 0xfff)<0xffd) { if ((address & 0xfff)<0xffd) {
#endif HostPt tlb_addr=get_tlb_read(address);
Bitu index=(address>>12); if (tlb_addr) {
if (paging.tlb.read[index]) { *((Bit32u*)(&core_dynrec.readdata))=host_readd(tlb_addr+address);
*((Bit32u*)(&core_dynrec.readdata))=host_readd(paging.tlb.read[index]+address);
return false; return false;
} else { } else return get_tlb_readhandler(address)->readd_checked(address, (Bit32u*)(&core_dynrec.readdata));
Bitu uval; } else return mem_unalignedreadd_checked(address, ((Bit32u*)(&core_dynrec.readdata)));
bool retval;
retval=paging.tlb.handler[index]->readd_checked(address, &uval);
*((Bit32u*)(&core_dynrec.readdata))=(Bit32u)uval;
return retval;
}
} else return mem_unalignedreadd_checked_x86(address, ((Bit32u*)(&core_dynrec.readdata)));
} }
bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC; bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) DRC_FC;
bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) { bool DRC_CALL_CONV mem_writew_checked_drc(PhysPt address,Bit16u val) {
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
if (!(address & 1)) {
#else
if ((address & 0xfff)<0xfff) { if ((address & 0xfff)<0xfff) {
#endif HostPt tlb_addr=get_tlb_write(address);
Bitu index=(address>>12); if (tlb_addr) {
if (paging.tlb.write[index]) { host_writew(tlb_addr+address,val);
host_writew(paging.tlb.write[index]+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writew_checked(address,val); } else return get_tlb_writehandler(address)->writew_checked(address,val);
} else return mem_unalignedwritew_checked_x86(address,val); } else return mem_unalignedwritew_checked(address,val);
} }
bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC; bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) DRC_FC;
bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) { bool DRC_CALL_CONV mem_writed_checked_drc(PhysPt address,Bit32u val) {
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
if (!(address & 3)) {
#else
if ((address & 0xfff)<0xffd) { if ((address & 0xfff)<0xffd) {
#endif HostPt tlb_addr=get_tlb_write(address);
Bitu index=(address>>12); if (tlb_addr) {
if (paging.tlb.write[index]) { host_writed(tlb_addr+address,val);
host_writed(paging.tlb.write[index]+address,val);
return false; return false;
} else return paging.tlb.handler[index]->writed_checked(address,val); } else return get_tlb_writehandler(address)->writed_checked(address,val);
} else return mem_unalignedwrited_checked_x86(address,val); } else return mem_unalignedwrited_checked(address,val);
} }
@ -709,7 +772,7 @@ static void dyn_write_word(HostReg reg_addr,HostReg reg_val,bool dword) {
// effective address calculation helper, op2 has to be present! // effective address calculation helper, op2 has to be present!
// loads op1 into ea_reg and adds the scaled op2 and the immediate to it // loads op1 into ea_reg and adds the scaled op2 and the immediate to it
static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) { static void dyn_lea_mem_mem(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) {
if (scale || imm) { if (scale || imm) {
if (op1!=NULL) { if (op1!=NULL) {
gen_mov_word_to_reg(ea_reg,op1,true); gen_mov_word_to_reg(ea_reg,op1,true);
@ -726,6 +789,79 @@ static void dyn_lea(HostReg ea_reg,void* op1,void* op2,Bitu scale,Bits imm) {
} }
} }
#ifdef DRC_USE_REGS_ADDR
// effective address calculation helper
// loads op1 into ea_reg and adds the scaled op2 and the immediate to it
// op1 is cpu_regs[op1_index], op2 is cpu_regs[op2_index]
static void dyn_lea_regval_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) {
if (scale || imm) {
MOV_REG_VAL_TO_HOST_REG(ea_reg,op1_index);
MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index);
gen_lea(ea_reg,TEMP_REG_DRC,scale,imm);
} else {
MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index);
ADD_REG_VAL_TO_HOST_REG(ea_reg,op1_index);
}
}
// effective address calculation helper
// loads op1 into ea_reg and adds the scaled op2 and the immediate to it
// op2 is cpu_regs[op2_index]
static void dyn_lea_mem_regval(HostReg ea_reg,void* op1,Bitu op2_index,Bitu scale,Bits imm) {
if (scale || imm) {
if (op1!=NULL) {
gen_mov_word_to_reg(ea_reg,op1,true);
MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index);
gen_lea(ea_reg,TEMP_REG_DRC,scale,imm);
} else {
MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index);
gen_lea(ea_reg,scale,imm);
}
} else {
MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index);
if (op1!=NULL) gen_add(ea_reg,op1);
}
}
#endif
#ifdef DRC_USE_SEGS_ADDR
#ifdef DRC_USE_REGS_ADDR
// effective address calculation helper
// loads op1 into ea_reg and adds the scaled op2 and the immediate to it
// op1 is Segs[op1_index], op2 is cpu_regs[op2_index]
static void dyn_lea_segphys_regval(HostReg ea_reg,Bitu op1_index,Bitu op2_index,Bitu scale,Bits imm) {
if (scale || imm) {
MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index);
MOV_REG_VAL_TO_HOST_REG(TEMP_REG_DRC,op2_index);
gen_lea(ea_reg,TEMP_REG_DRC,scale,imm);
} else {
MOV_REG_VAL_TO_HOST_REG(ea_reg,op2_index);
ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index);
}
}
#else
// effective address calculation helper, op2 has to be present!
// loads op1 into ea_reg and adds the scaled op2 and the immediate to it
// op1 is Segs[op1_index]
static void dyn_lea_segphys_mem(HostReg ea_reg,Bitu op1_index,void* op2,Bitu scale,Bits imm) {
if (scale || imm) {
MOV_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index);
gen_mov_word_to_reg(TEMP_REG_DRC,op2,true);
gen_lea(ea_reg,TEMP_REG_DRC,scale,imm);
} else {
gen_mov_word_to_reg(ea_reg,op2,true);
ADD_SEG_PHYS_TO_HOST_REG(ea_reg,op1_index);
}
}
#endif
#endif
// calculate the effective address and store it in ea_reg // calculate the effective address and store it in ea_reg
static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) { static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) {
Bit8u seg_base=DRC_SEG_DS; Bit8u seg_base=DRC_SEG_DS;
@ -738,25 +874,25 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) {
} }
switch (decode.modrm.rm) { switch (decode.modrm.rm) {
case 0:// BX+SI case 0:// BX+SI
dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_ESI),0,imm); DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_ESI,0,imm);
break; break;
case 1:// BX+DI case 1:// BX+DI
dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBX),DRCD_REG(DRC_REG_EDI),0,imm); DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBX,DRC_REG_EDI,0,imm);
break; break;
case 2:// BP+SI case 2:// BP+SI
dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_ESI),0,imm); DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_ESI,0,imm);
seg_base=DRC_SEG_SS; seg_base=DRC_SEG_SS;
break; break;
case 3:// BP+DI case 3:// BP+DI
dyn_lea(ea_reg,DRCD_REG(DRC_REG_EBP),DRCD_REG(DRC_REG_EDI),0,imm); DYN_LEA_REG_VAL_REG_VAL(ea_reg,DRC_REG_EBP,DRC_REG_EDI,0,imm);
seg_base=DRC_SEG_SS; seg_base=DRC_SEG_SS;
break; break;
case 4:// SI case 4:// SI
gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_ESI),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_ESI);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
break; break;
case 5:// DI case 5:// DI
gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EDI),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EDI);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
break; break;
case 6:// imm/BP case 6:// imm/BP
@ -765,13 +901,13 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) {
gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm);
goto skip_extend_word; goto skip_extend_word;
} else { } else {
gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBP),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBP);
gen_add_imm(ea_reg,(Bit32u)imm); gen_add_imm(ea_reg,(Bit32u)imm);
seg_base=DRC_SEG_SS; seg_base=DRC_SEG_SS;
} }
break; break;
case 7: // BX case 7: // BX
gen_mov_word_to_reg(ea_reg,DRCD_REG(DRC_REG_EBX),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,DRC_REG_EBX);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
break; break;
} }
@ -780,7 +916,7 @@ static void dyn_fill_ea(HostReg ea_reg,bool addseg=true) {
skip_extend_word: skip_extend_word:
if (addseg) { if (addseg) {
// add the physical segment value if requested // add the physical segment value if requested
gen_add(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base)); ADD_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
} }
} else { } else {
Bits imm=0; Bits imm=0;
@ -824,14 +960,14 @@ skip_extend_word:
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,(void*)val,true); gen_mov_word_to_reg(ea_reg,(void*)val,true);
} else { } else {
dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,0); DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,0);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} }
} else { } else {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
} else { } else {
dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0);
} }
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} }
@ -844,14 +980,14 @@ skip_extend_word:
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm);
} else { } else {
dyn_lea(ea_reg,NULL,DRCD_REG(scaled_reg),scale,imm); DYN_LEA_MEM_REG_VAL(ea_reg,NULL,scaled_reg,scale,imm);
} }
} else { } else {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
} else { } else {
dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm);
} }
} }
@ -873,19 +1009,19 @@ skip_extend_word:
// succeeded, use the pointer to avoid code invalidation // succeeded, use the pointer to avoid code invalidation
if (!addseg) { if (!addseg) {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} else { } else {
dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,0); DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,0);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} }
} else { } else {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
} else { } else {
dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,0); DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,0);
} }
gen_add(ea_reg,DRCD_REG(base_reg)); ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} }
return; return;
@ -898,19 +1034,19 @@ skip_extend_word:
if (!addseg) { if (!addseg) {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
gen_add_imm(ea_reg,(Bit32u)imm); gen_add_imm(ea_reg,(Bit32u)imm);
} else { } else {
dyn_lea(ea_reg,DRCD_REG(base_reg),DRCD_REG(scaled_reg),scale,imm); DYN_LEA_REG_VAL_REG_VAL(ea_reg,base_reg,scaled_reg,scale,imm);
} }
} else { } else {
if (!scaled_reg_used) { if (!scaled_reg_used) {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
gen_add(ea_reg,DRCD_REG(base_reg)); ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
} else { } else {
dyn_lea(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),DRCD_REG(scaled_reg),scale,imm); DYN_LEA_SEG_PHYS_REG_VAL(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base),scaled_reg,scale,imm);
gen_add(ea_reg,DRCD_REG(base_reg)); ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
} }
} }
@ -927,7 +1063,7 @@ skip_extend_word:
if (!addseg) { if (!addseg) {
gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm); gen_mov_dword_to_reg_imm(ea_reg,(Bit32u)imm);
} else { } else {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
} }
@ -950,11 +1086,11 @@ skip_extend_word:
if (decode_fetchd_imm(val)) { if (decode_fetchd_imm(val)) {
// succeeded, use the pointer to avoid code invalidation // succeeded, use the pointer to avoid code invalidation
if (!addseg) { if (!addseg) {
gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} else { } else {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
gen_add(ea_reg,DRCD_REG(base_reg)); ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
gen_add(ea_reg,(void*)val); gen_add(ea_reg,(void*)val);
} }
return; return;
@ -966,11 +1102,11 @@ skip_extend_word:
} }
if (!addseg) { if (!addseg) {
gen_mov_word_to_reg(ea_reg,DRCD_REG(base_reg),true); MOV_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
} else { } else {
gen_mov_word_to_reg(ea_reg,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : seg_base),true); MOV_SEG_PHYS_TO_HOST_REG(ea_reg,(decode.seg_prefix_used ? decode.seg_prefix : seg_base));
gen_add(ea_reg,DRCD_REG(base_reg)); ADD_REG_VAL_TO_HOST_REG(ea_reg,base_reg);
if (imm) gen_add_imm(ea_reg,(Bit32u)imm); if (imm) gen_add_imm(ea_reg,(Bit32u)imm);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -34,7 +34,7 @@ static void dyn_dop_ebgb(DualOps op) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_byte_canuseword(FC_ADDR,FC_OP1); dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) { if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
@ -42,10 +42,10 @@ static void dyn_dop_ebgb(DualOps op) {
dyn_write_byte(FC_ADDR,FC_RETOP); dyn_write_byte(FC_ADDR,FC_RETOP);
} }
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -53,11 +53,11 @@ static void dyn_dop_ebgb_mov(void) {
dyn_get_modrm(); dyn_get_modrm();
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
dyn_write_byte(FC_ADDR,FC_TMP_BA1); dyn_write_byte(FC_ADDR,FC_TMP_BA1);
} else { } else {
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -69,7 +69,7 @@ static void dyn_dop_ebib_mov(void) {
dyn_write_byte(FC_ADDR,FC_TMP_BA1); dyn_write_byte(FC_ADDR,FC_TMP_BA1);
} else { } else {
gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb()); gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,decode_fetchb());
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -79,16 +79,16 @@ static void dyn_dop_ebgb_xchg(void) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_byte(FC_ADDR,FC_TMP_BA1); dyn_read_byte(FC_ADDR,FC_TMP_BA1);
gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_byte(FC_ADDR,FC_TMP_BA2); dyn_write_byte(FC_ADDR,FC_TMP_BA2);
} else { } else {
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
gen_mov_byte_to_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
gen_mov_byte_from_reg_low(FC_TMP_BA2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -97,14 +97,14 @@ static void dyn_dop_gbeb(DualOps op) {
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_byte_canuseword(FC_ADDR,FC_OP2); dyn_read_byte_canuseword(FC_ADDR,FC_OP2);
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
} }
} }
@ -113,10 +113,10 @@ static void dyn_dop_gbeb_mov(void) {
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_byte(FC_ADDR,FC_TMP_BA1); dyn_read_byte(FC_ADDR,FC_TMP_BA1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
} else { } else {
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.reg&3,(decode.modrm.reg>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.reg&3,(decode.modrm.reg>>2)&1);
} }
} }
@ -126,17 +126,17 @@ static void dyn_dop_evgv(DualOps op) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
gen_protect_addr_reg(); gen_protect_addr_reg();
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) { if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op);
} }
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
} }
@ -144,11 +144,11 @@ static void dyn_dop_evgv_mov(void) {
dyn_get_modrm(); dyn_get_modrm();
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
} }
@ -162,7 +162,7 @@ static void dyn_dop_eviv_mov(void) {
} else { } else {
if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd()); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,decode_fetchd());
else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw()); else gen_mov_word_to_reg_imm(FC_OP1,decode_fetchw());
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
} }
@ -172,26 +172,26 @@ static void dyn_dop_evgv_xchg(void) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
gen_protect_reg(FC_OP1); gen_protect_reg(FC_OP1);
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_OP2,decode.big_op); dyn_write_word(FC_ADDR,FC_OP2,decode.big_op);
gen_restore_reg(FC_OP1); gen_restore_reg(FC_OP1);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op);
} }
} }
static void dyn_xchg_ax(Bit8u reg) { static void dyn_xchg_ax(Bit8u reg) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op);
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,reg,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op);
gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP2,DRC_REG_EAX,decode.big_op);
} }
static void dyn_dop_gvev(DualOps op) { static void dyn_dop_gvev(DualOps op) {
@ -200,17 +200,17 @@ static void dyn_dop_gvev(DualOps op) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP2,decode.big_op); dyn_read_word(FC_ADDR,FC_OP2,decode.big_op);
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) { if ((op!=DOP_CMP) && (op!=DOP_TEST)) {
gen_restore_addr_reg(); gen_restore_addr_reg();
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op);
} }
} else { } else {
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.rm,decode.big_op);
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op);
} }
} }
@ -219,22 +219,22 @@ static void dyn_dop_gvev_mov(void) {
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} }
} }
static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) { static void dyn_dop_byte_imm(DualOps op,Bit8u reg,Bit8u idx) {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx);
gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb()); gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,decode_fetchb());
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx);
} }
static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) { static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(reg,idx)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,reg,idx);
Bitu val; Bitu val;
if (decode_fetchb_imm(val)) { if (decode_fetchb_imm(val)) {
gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val); gen_mov_byte_to_reg_low_canuseword(FC_OP2,(void*)val);
@ -242,7 +242,7 @@ static void dyn_dop_byte_imm_mem(DualOps op,Bit8u reg,Bit8u idx) {
gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val); gen_mov_byte_to_reg_low_imm_canuseword(FC_OP2,(Bit8u)val);
} }
dyn_dop_byte_gencall(op); dyn_dop_byte_gencall(op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(reg,idx)); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,reg,idx);
} }
static void dyn_prep_word_imm(Bit8u reg) { static void dyn_prep_word_imm(Bit8u reg) {
@ -263,23 +263,23 @@ static void dyn_prep_word_imm(Bit8u reg) {
} }
static void dyn_dop_word_imm(DualOps op,Bit8u reg) { static void dyn_dop_word_imm(DualOps op,Bit8u reg) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op);
dyn_prep_word_imm(reg); dyn_prep_word_imm(reg);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op);
} }
static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) { static void dyn_dop_word_imm_old(DualOps op,Bit8u reg,Bitu imm) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op);
if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit32u)imm);
else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm); else gen_mov_word_to_reg_imm(FC_OP2,(Bit16u)imm);
dyn_dop_word_gencall(op,decode.big_op); dyn_dop_word_gencall(op,decode.big_op);
if ((op!=DOP_CMP) && (op!=DOP_TEST)) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); if ((op!=DOP_CMP) && (op!=DOP_TEST)) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op);
} }
static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) { static void dyn_mov_byte_imm(Bit8u reg,Bit8u idx,Bit8u imm) {
gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm); gen_mov_byte_to_reg_low_imm(FC_TMP_BA1,imm);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(reg,idx)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,reg,idx);
} }
static void dyn_mov_word_imm(Bit8u reg) { static void dyn_mov_word_imm(Bit8u reg) {
@ -287,45 +287,45 @@ static void dyn_mov_word_imm(Bit8u reg) {
if (decode.big_op) { if (decode.big_op) {
if (decode_fetchd_imm(val)) { if (decode_fetchd_imm(val)) {
gen_mov_word_to_reg(FC_OP1,(void*)val,true); gen_mov_word_to_reg(FC_OP1,(void*)val,true);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,true),true); MOV_REG_WORD32_FROM_HOST_REG(FC_OP1,reg);
return; return;
} }
} else { } else {
if (decode_fetchw_imm(val)) { if (decode_fetchw_imm(val)) {
gen_mov_word_to_reg(FC_OP1,(void*)val,false); gen_mov_word_to_reg(FC_OP1,(void*)val,false);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,reg);
return; return;
} }
} }
if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP1,(Bit32u)val);
else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val); else gen_mov_word_to_reg_imm(FC_OP1,(Bit16u)val);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,reg,decode.big_op);
} }
static void dyn_sop_word(SingleOps op,Bit8u reg) { static void dyn_sop_word(SingleOps op,Bit8u reg) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op);
dyn_sop_word_gencall(op,decode.big_op); dyn_sop_word_gencall(op,decode.big_op);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op);
} }
static void dyn_mov_byte_al_direct(Bitu imm) { static void dyn_mov_byte_al_direct(Bitu imm) {
gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS));
gen_add_imm(FC_ADDR,imm); gen_add_imm(FC_ADDR,imm);
dyn_read_byte(FC_ADDR,FC_TMP_BA1); dyn_read_byte(FC_ADDR,FC_TMP_BA1);
gen_mov_byte_from_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0);
} }
static void dyn_mov_byte_ax_direct(Bitu imm) { static void dyn_mov_byte_ax_direct(Bitu imm) {
gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS));
gen_add_imm(FC_ADDR,imm); gen_add_imm(FC_ADDR,imm);
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op);
} }
static void dyn_mov_byte_direct_al() { static void dyn_mov_byte_direct_al() {
gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS));
if (decode.big_addr) { if (decode.big_addr) {
Bitu val; Bitu val;
if (decode_fetchd_imm(val)) { if (decode_fetchd_imm(val)) {
@ -336,14 +336,14 @@ static void dyn_mov_byte_direct_al() {
} else { } else {
gen_add_imm(FC_ADDR,decode_fetchw()); gen_add_imm(FC_ADDR,decode_fetchw());
} }
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,DRC_REG_EAX,0);
dyn_write_byte(FC_ADDR,FC_TMP_BA1); dyn_write_byte(FC_ADDR,FC_TMP_BA1);
} }
static void dyn_mov_byte_direct_ax(Bitu imm) { static void dyn_mov_byte_direct_ax(Bitu imm) {
gen_mov_word_to_reg(FC_ADDR,DRCD_SEG_PHYS(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS),true); MOV_SEG_PHYS_TO_HOST_REG(FC_ADDR,(decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS));
gen_add_imm(FC_ADDR,imm); gen_add_imm(FC_ADDR,imm);
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op);
dyn_write_word(FC_ADDR,FC_OP1,decode.big_op); dyn_write_word(FC_ADDR,FC_OP1,decode.big_op);
} }
@ -354,11 +354,11 @@ static void dyn_movx_ev_gb(bool sign) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_byte(FC_ADDR,FC_TMP_BA1); dyn_read_byte(FC_ADDR,FC_TMP_BA1);
gen_extend_byte(sign,FC_TMP_BA1); gen_extend_byte(sign,FC_TMP_BA1);
gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op);
} else { } else {
gen_mov_byte_to_reg_low(FC_TMP_BA1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_TMP_BA1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
gen_extend_byte(sign,FC_TMP_BA1); gen_extend_byte(sign,FC_TMP_BA1);
gen_mov_word_from_reg(FC_TMP_BA1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_TMP_BA1,decode.modrm.reg,decode.big_op);
} }
} }
@ -368,30 +368,37 @@ static void dyn_movx_ev_gw(bool sign) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_OP1,false); dyn_read_word(FC_ADDR,FC_OP1,false);
gen_extend_word(sign,FC_OP1); gen_extend_word(sign,FC_OP1);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_OP1,decode.modrm.rm);
gen_extend_word(sign,FC_OP1); gen_extend_word(sign,FC_OP1);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} }
} }
static void dyn_mov_ev_seg(void) { static void dyn_mov_ev_seg(void) {
dyn_get_modrm(); dyn_get_modrm();
gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(decode.modrm.reg),false); MOV_SEG_VAL_TO_HOST_REG(FC_OP1,decode.modrm.reg);
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_write_word(FC_ADDR,FC_OP1,false); dyn_write_word(FC_ADDR,FC_OP1,false);
} else { } else {
if (decode.big_op) gen_extend_word(false,FC_OP1); if (decode.big_op) gen_extend_word(false,FC_OP1);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
} }
static void dyn_lea(void) {
dyn_get_modrm();
dyn_fill_ea(FC_ADDR,false);
MOV_REG_WORD_FROM_HOST_REG(FC_ADDR,decode.modrm.reg,decode.big_op);
}
static void dyn_push_seg(Bit8u seg) { static void dyn_push_seg(Bit8u seg) {
gen_mov_word_to_reg(FC_OP1,DRCD_SEG_VAL(seg),false); MOV_SEG_VAL_TO_HOST_REG(FC_OP1,seg);
if (decode.big_op) { if (decode.big_op) {
gen_extend_word(false,FC_OP1); gen_extend_word(false,FC_OP1);
gen_call_function_raw((void*)&dynrec_push_dword); gen_call_function_raw((void*)&dynrec_push_dword);
@ -402,11 +409,11 @@ static void dyn_push_seg(Bit8u seg) {
static void dyn_pop_seg(Bit8u seg) { static void dyn_pop_seg(Bit8u seg) {
gen_call_function_II((void *)&CPU_PopSeg,seg,decode.big_op); gen_call_function_II((void *)&CPU_PopSeg,seg,decode.big_op);
if (cpu.pmode) dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
} }
static void dyn_push_reg(Bit8u reg) { static void dyn_push_reg(Bit8u reg) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,reg,decode.big_op);
if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword); if (decode.big_op) gen_call_function_raw((void*)&dynrec_push_dword);
else gen_call_function_raw((void*)&dynrec_push_word); else gen_call_function_raw((void*)&dynrec_push_word);
} }
@ -414,7 +421,7 @@ static void dyn_push_reg(Bit8u reg) {
static void dyn_pop_reg(Bit8u reg) { static void dyn_pop_reg(Bit8u reg) {
if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword);
else gen_call_function_raw((void*)&dynrec_pop_word); else gen_call_function_raw((void*)&dynrec_pop_word);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,reg,decode.big_op);
} }
static void dyn_push_byte_imm(Bit8s imm) { static void dyn_push_byte_imm(Bit8s imm) {
@ -447,13 +454,13 @@ static void dyn_pop_ev(void) {
} else { } else {
if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword); if (decode.big_op) gen_call_function_raw((void*)&dynrec_pop_dword);
else gen_call_function_raw((void*)&dynrec_pop_word); else gen_call_function_raw((void*)&dynrec_pop_word);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
} }
static void dyn_segprefix(Bit8u seg) { static void dyn_segprefix(Bit8u seg) {
if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix"); // if (GCC_UNLIKELY(decode.seg_prefix_used)) IllegalOptionDynrec("dyn_segprefix");
decode.seg_prefix=seg; decode.seg_prefix=seg;
decode.seg_prefix_used=true; decode.seg_prefix_used=true;
} }
@ -465,14 +472,13 @@ static void dyn_segprefix(Bit8u seg) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_RETOP,false); dyn_read_word(FC_ADDR,FC_RETOP,false);
} else { } else {
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm);
} }
gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP); gen_call_function_IR((void *)&CPU_SetSegGeneral,decode.modrm.reg,FC_RETOP);
if (cpu.pmode) dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
} }
static void dyn_load_seg_off_ea(Bit8u seg) { static void dyn_load_seg_off_ea(Bit8u seg) {
dyn_get_modrm();
if (decode.modrm.mod<3) { if (decode.modrm.mod<3) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
gen_protect_addr_reg(); gen_protect_addr_reg();
@ -484,10 +490,10 @@ static void dyn_load_seg_off_ea(Bit8u seg) {
dyn_read_word(FC_ADDR,FC_RETOP,false); dyn_read_word(FC_ADDR,FC_RETOP,false);
gen_call_function_IR((void *)&CPU_SetSegGeneral,seg,FC_RETOP); gen_call_function_IR((void *)&CPU_SetSegGeneral,seg,FC_RETOP);
if (cpu.pmode) dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
gen_restore_reg(FC_OP1); gen_restore_reg(FC_OP1);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,decode.modrm.reg,decode.big_op);
} else { } else {
IllegalOptionDynrec("dyn_load_seg_off_ea"); IllegalOptionDynrec("dyn_load_seg_off_ea");
} }
@ -501,12 +507,12 @@ static void dyn_imul_gvev(Bitu immsize) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
switch (immsize) { switch (immsize) {
case 0: case 0:
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
break; break;
case 1: case 1:
if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb()); if (decode.big_op) gen_mov_dword_to_reg_imm(FC_OP2,(Bit8s)decode_fetchb());
@ -525,7 +531,7 @@ static void dyn_imul_gvev(Bitu immsize) {
if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword); if (decode.big_op) gen_call_function_raw((void*)dynrec_dimul_dword);
else gen_call_function_raw((void*)dynrec_dimul_word); else gen_call_function_raw((void*)dynrec_dimul_word);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.reg,decode.big_op);
} }
static void dyn_dshift_ev_gv(bool left,bool immediate) { static void dyn_dshift_ev_gv(bool left,bool immediate) {
@ -535,11 +541,11 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) {
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
gen_mov_word_to_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb()); if (immediate) gen_mov_byte_to_reg_low_imm(FC_RETOP,decode_fetchb());
else gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_ECX,0)); else MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_ECX,0);
if (decode.big_op) dyn_dpshift_dword_gencall(left); if (decode.big_op) dyn_dpshift_dword_gencall(left);
else dyn_dpshift_word_gencall(left); else dyn_dpshift_word_gencall(left);
@ -547,7 +553,7 @@ static void dyn_dshift_ev_gv(bool left,bool immediate) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op);
} else { } else {
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
} }
@ -611,7 +617,7 @@ static void dyn_grp2_eb(grp2_types type) {
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_byte_canuseword(FC_ADDR,FC_OP1); dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
switch (type) { switch (type) {
case grp2_1: case grp2_1:
@ -627,7 +633,7 @@ static void dyn_grp2_eb(grp2_types type) {
} }
break; break;
case grp2_cl: case grp2_cl:
gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0);
gen_and_imm(FC_OP2,0x1f); gen_and_imm(FC_OP2,0x1f);
dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg); dyn_shift_byte_gencall((ShiftOps)decode.modrm.reg);
break; break;
@ -636,7 +642,7 @@ static void dyn_grp2_eb(grp2_types type) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_byte(FC_ADDR,FC_RETOP); dyn_write_byte(FC_ADDR,FC_RETOP);
} else { } else {
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -647,7 +653,7 @@ static void dyn_grp2_ev(grp2_types type) {
gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
switch (type) { switch (type) {
case grp2_1: case grp2_1:
@ -670,7 +676,7 @@ static void dyn_grp2_ev(grp2_types type) {
} }
break; break;
case grp2_cl: case grp2_cl:
gen_mov_byte_to_reg_low_canuseword(FC_OP2,DRCD_REG_BYTE(DRC_REG_ECX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP2,DRC_REG_ECX,0);
gen_and_imm(FC_OP2,0x1f); gen_and_imm(FC_OP2,0x1f);
dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op); dyn_shift_word_gencall((ShiftOps)decode.modrm.reg,decode.big_op);
break; break;
@ -679,7 +685,7 @@ static void dyn_grp2_ev(grp2_types type) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op);
} else { } else {
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
} }
@ -691,7 +697,7 @@ static void dyn_grp3_eb(void) {
if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg();
dyn_read_byte_canuseword(FC_ADDR,FC_OP1); dyn_read_byte_canuseword(FC_ADDR,FC_OP1);
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
switch (decode.modrm.reg) { switch (decode.modrm.reg) {
case 0x0: // test eb,ib case 0x0: // test eb,ib
@ -724,7 +730,7 @@ static void dyn_grp3_eb(void) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_byte(FC_ADDR,FC_RETOP); dyn_write_byte(FC_ADDR,FC_RETOP);
} else { } else {
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
@ -735,7 +741,7 @@ static void dyn_grp3_ev(void) {
if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg(); if ((decode.modrm.reg==2) || (decode.modrm.reg==3)) gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
switch (decode.modrm.reg) { switch (decode.modrm.reg) {
case 0x0: // test ev,iv case 0x0: // test ev,iv
@ -773,7 +779,7 @@ static void dyn_grp3_ev(void) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op);
} else { } else {
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
} }
@ -791,9 +797,9 @@ static bool dyn_grp4_eb(void) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_byte(FC_ADDR,FC_RETOP); dyn_write_byte(FC_ADDR,FC_RETOP);
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC); dyn_sop_byte_gencall(decode.modrm.reg==0 ? SOP_INC : SOP_DEC);
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
break; break;
case 0x7: //CALBACK Iw case 0x7: //CALBACK Iw
@ -817,7 +823,7 @@ static bool dyn_grp4_ev(void) {
if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg(); if ((decode.modrm.reg<2) || (decode.modrm.reg==3) || (decode.modrm.reg==5)) gen_protect_addr_reg();
dyn_read_word(FC_ADDR,FC_OP1,decode.big_op); dyn_read_word(FC_ADDR,FC_OP1,decode.big_op);
} else { } else {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,decode.modrm.rm,decode.big_op);
} }
switch (decode.modrm.reg) { switch (decode.modrm.reg) {
case 0x0://INC Ev case 0x0://INC Ev
@ -827,7 +833,7 @@ static bool dyn_grp4_ev(void) {
gen_restore_addr_reg(); gen_restore_addr_reg();
dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op); dyn_write_word(FC_ADDR,FC_RETOP,decode.big_op);
} else { } else {
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,decode.modrm.rm,decode.big_op);
} }
break; break;
case 0x2: // CALL Ev case 0x2: // CALL Ev
@ -880,7 +886,7 @@ static bool dyn_grp6(void) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_write_word(FC_ADDR,FC_RETOP,false); dyn_write_word(FC_ADDR,FC_RETOP,false);
} else { } else {
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm);
} }
break; break;
case 0x02: // LLDT case 0x02: // LLDT
@ -891,7 +897,7 @@ static bool dyn_grp6(void) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_RETOP,false); dyn_read_word(FC_ADDR,FC_RETOP,false);
} else { } else {
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm);
} }
gen_extend_word(false,FC_RETOP); gen_extend_word(false,FC_RETOP);
switch (decode.modrm.reg) { switch (decode.modrm.reg) {
@ -978,16 +984,21 @@ static bool dyn_grp7(void) {
dyn_return(BR_Normal); dyn_return(BR_Normal);
dyn_closeblock(); dyn_closeblock();
return true; return true;
case 0x07: // INVLPG
// if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
if (cpu.pmode && cpu.cpl) IllegalOptionDynrec("invlpg nonpriviledged");
gen_call_function_raw((void*)PAGING_ClearTLB);
break;
default: IllegalOptionDynrec("dyn_grp7_1"); default: IllegalOptionDynrec("dyn_grp7_1");
} }
} else { } else {
switch (decode.modrm.reg) { switch (decode.modrm.reg) {
case 0x04: // SMSW case 0x04: // SMSW
gen_call_function_raw((void*)CPU_SMSW); gen_call_function_raw((void*)CPU_SMSW);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,decode.modrm.rm);
break; break;
case 0x06: // LMSW case 0x06: // LMSW
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm);
gen_call_function_R((void*)CPU_LMSW,FC_RETOP); gen_call_function_R((void*)CPU_LMSW,FC_RETOP);
dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
dyn_set_eip_end(); dyn_set_eip_end();
@ -1009,14 +1020,14 @@ static void dyn_larlsl(bool is_lar) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_read_word(FC_ADDR,FC_RETOP,false); dyn_read_word(FC_ADDR,FC_RETOP,false);
} else { } else {
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_RETOP,decode.modrm.rm);
} }
gen_extend_word(false,FC_RETOP); gen_extend_word(false,FC_RETOP);
if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); if (is_lar) gen_call_function((void*)CPU_LAR,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata);
else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); else gen_call_function((void*)CPU_LSL,"%R%A",FC_RETOP,(DRC_PTR_SIZE_IM)&core_dynrec.readdata);
DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true); DRC_PTR_SIZE_IM brnz=gen_create_branch_on_nonzero(FC_RETOP,true);
gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true);
gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.reg,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_OP2,decode.modrm.reg,decode.big_op);
gen_fill_branch(brnz); gen_fill_branch(brnz);
} }
*/ */
@ -1027,12 +1038,12 @@ static void dyn_mov_from_crx(void) {
gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata); gen_call_function_IA((void*)CPU_READ_CRX,decode.modrm.reg,(DRC_PTR_SIZE_IM)&core_dynrec.readdata);
dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true); gen_mov_word_to_reg(FC_OP2,&core_dynrec.readdata,true);
gen_mov_word_from_reg(FC_OP2,DRCD_REG_WORD(decode.modrm.rm,true),true); MOV_REG_WORD32_FROM_HOST_REG(FC_OP2,decode.modrm.rm);
} }
static void dyn_mov_to_crx(void) { static void dyn_mov_to_crx(void) {
dyn_get_modrm(); dyn_get_modrm();
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(decode.modrm.rm,true),true); MOV_REG_WORD32_TO_HOST_REG(FC_RETOP,decode.modrm.rm);
gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP); gen_call_function_IR((void*)CPU_WRITE_CRX,decode.modrm.reg,FC_RETOP);
dyn_check_exception(FC_RETOP); dyn_check_exception(FC_RETOP);
dyn_set_eip_end(); dyn_set_eip_end();
@ -1044,29 +1055,29 @@ static void dyn_mov_to_crx(void) {
static void dyn_cbw(void) { static void dyn_cbw(void) {
if (decode.big_op) { if (decode.big_op) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX);
gen_call_function_raw((void *)&dynrec_cwde); gen_call_function_raw((void *)&dynrec_cwde);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,true),true); MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX);
} else { } else {
gen_mov_byte_to_reg_low_canuseword(FC_OP1,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW_CANUSEWORD(FC_OP1,DRC_REG_EAX,0);
gen_call_function_raw((void *)&dynrec_cbw); gen_call_function_raw((void *)&dynrec_cbw);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX);
} }
} }
static void dyn_cwd(void) { static void dyn_cwd(void) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_EAX,decode.big_op);
if (decode.big_op) { if (decode.big_op) {
gen_call_function_raw((void *)&dynrec_cdq); gen_call_function_raw((void *)&dynrec_cdq);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,true),true); MOV_REG_WORD32_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX);
} else { } else {
gen_call_function_raw((void *)&dynrec_cwd); gen_call_function_raw((void *)&dynrec_cwd);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EDX,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_RETOP,DRC_REG_EDX);
} }
} }
static void dyn_sahf(void) { static void dyn_sahf(void) {
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_OP1,DRC_REG_EAX);
gen_call_function_raw((void *)&dynrec_sahf); gen_call_function_raw((void *)&dynrec_sahf);
InvalidateFlags(); InvalidateFlags();
} }
@ -1107,7 +1118,7 @@ static void dyn_set_byte_on_condition(BranchTypes btype) {
dyn_fill_ea(FC_ADDR); dyn_fill_ea(FC_ADDR);
dyn_write_byte(FC_ADDR,FC_RETOP); dyn_write_byte(FC_ADDR,FC_RETOP);
} else { } else {
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(decode.modrm.rm&3,(decode.modrm.rm>>2)&1)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,decode.modrm.rm&3,(decode.modrm.rm>>2)&1);
} }
} }
*/ */
@ -1132,13 +1143,13 @@ static void dyn_loop(LoopTypes type) {
case LOOP_E: case LOOP_E:
case LOOP_NE: case LOOP_NE:
case LOOP_NONE: case LOOP_NONE:
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
gen_add_imm(FC_OP1,(Bit32u)(-1)); gen_add_imm(FC_OP1,(Bit32u)(-1));
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr); branch2=gen_create_branch_on_zero(FC_OP1,decode.big_addr);
break; break;
case LOOP_JCXZ: case LOOP_JCXZ:
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr); branch2=gen_create_branch_on_nonzero(FC_OP1,decode.big_addr);
break; break;
} }
@ -1146,9 +1157,9 @@ static void dyn_loop(LoopTypes type) {
gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start)); gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start));
if (branch1) { if (branch1) {
gen_fill_branch(branch1); gen_fill_branch(branch1);
gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
gen_add_imm(FC_OP1,(Bit32u)(-1)); gen_add_imm(FC_OP1,(Bit32u)(-1));
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); MOV_REG_WORD_FROM_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
} }
// Branch taken // Branch taken
gen_fill_branch(branch2); gen_fill_branch(branch2);
@ -1238,7 +1249,7 @@ static void dyn_interrupt(Bit8u num) {
static void dyn_string(StringOps op) { static void dyn_string(StringOps op) {
if (decode.rep) gen_mov_word_to_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); if (decode.rep) MOV_REG_WORD_TO_HOST_REG(FC_OP1,DRC_REG_ECX,decode.big_addr);
else gen_mov_dword_to_reg_imm(FC_OP1,1); else gen_mov_dword_to_reg_imm(FC_OP1,1);
gen_mov_word_to_reg(FC_OP2,&cpu.direction,true); gen_mov_word_to_reg(FC_OP2,&cpu.direction,true);
Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS; Bit8u di_base_addr=decode.seg_prefix_used ? decode.seg_prefix : DRC_SEG_DS;
@ -1283,7 +1294,7 @@ static void dyn_string(StringOps op) {
break; break;
default: IllegalOptionDynrec("dyn_string"); default: IllegalOptionDynrec("dyn_string");
} }
if (decode.rep) gen_mov_word_from_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_ECX,decode.big_addr),decode.big_addr); if (decode.rep) MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_ECX,decode.big_addr);
if (op<STR_SCASB) { if (op<STR_SCASB) {
// those string operations are allowed for premature termination // those string operations are allowed for premature termination
@ -1300,69 +1311,69 @@ static void dyn_string(StringOps op) {
static void dyn_read_port_byte_direct(Bit8u port) { static void dyn_read_port_byte_direct(Bit8u port) {
dyn_add_iocheck_var(port,1); dyn_add_iocheck_var(port,1);
gen_call_function_I((void*)&IO_ReadB,port); gen_call_function_I((void*)&IO_ReadB,port);
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
} }
static void dyn_read_port_word_direct(Bit8u port) { static void dyn_read_port_word_direct(Bit8u port) {
dyn_add_iocheck_var(port,decode.big_op?4:2); dyn_add_iocheck_var(port,decode.big_op?4:2);
gen_call_function_I(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),port); gen_call_function_I(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),port);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
} }
static void dyn_write_port_byte_direct(Bit8u port) { static void dyn_write_port_byte_direct(Bit8u port) {
dyn_add_iocheck_var(port,1); dyn_add_iocheck_var(port,1);
gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
gen_extend_byte(false,FC_RETOP); gen_extend_byte(false,FC_RETOP);
gen_call_function_IR((void*)&IO_WriteB,port,FC_RETOP); gen_call_function_IR((void*)&IO_WriteB,port,FC_RETOP);
} }
static void dyn_write_port_word_direct(Bit8u port) { static void dyn_write_port_word_direct(Bit8u port) {
dyn_add_iocheck_var(port,decode.big_op?4:2); dyn_add_iocheck_var(port,decode.big_op?4:2);
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
if (!decode.big_op) gen_extend_word(false,FC_RETOP); if (!decode.big_op) gen_extend_word(false,FC_RETOP);
gen_call_function_IR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),port,FC_RETOP); gen_call_function_IR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),port,FC_RETOP);
} }
static void dyn_read_port_byte(void) { static void dyn_read_port_byte(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR); gen_extend_word(false,FC_ADDR);
if (cpu.pmode) gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,1); dyn_add_iocheck(FC_ADDR,1);
if (cpu.pmode) gen_restore_addr_reg(); gen_restore_addr_reg();
gen_call_function_R((void*)&IO_ReadB,FC_ADDR); gen_call_function_R((void*)&IO_ReadB,FC_ADDR);
gen_mov_byte_from_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_FROM_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
} }
static void dyn_read_port_word(void) { static void dyn_read_port_word(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR); gen_extend_word(false,FC_ADDR);
if (cpu.pmode) gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2); dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
if (cpu.pmode) gen_restore_addr_reg(); gen_restore_addr_reg();
gen_call_function_R(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),FC_ADDR); gen_call_function_R(decode.big_op?((void*)&IO_ReadD):((void*)&IO_ReadW),FC_ADDR);
gen_mov_word_from_reg(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_FROM_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
} }
static void dyn_write_port_byte(void) { static void dyn_write_port_byte(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR); gen_extend_word(false,FC_ADDR);
if (cpu.pmode) gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,1); dyn_add_iocheck(FC_ADDR,1);
gen_mov_byte_to_reg_low(FC_RETOP,DRCD_REG_BYTE(DRC_REG_EAX,0)); MOV_REG_BYTE_TO_HOST_REG_LOW(FC_RETOP,DRC_REG_EAX,0);
gen_extend_byte(false,FC_RETOP); gen_extend_byte(false,FC_RETOP);
if (cpu.pmode) gen_restore_addr_reg(); gen_restore_addr_reg();
gen_call_function_RR((void*)&IO_WriteB,FC_ADDR,FC_RETOP); gen_call_function_RR((void*)&IO_WriteB,FC_ADDR,FC_RETOP);
} }
static void dyn_write_port_word(void) { static void dyn_write_port_word(void) {
gen_mov_word_to_reg(FC_ADDR,DRCD_REG_WORD(DRC_REG_EDX,false),false); MOV_REG_WORD16_TO_HOST_REG(FC_ADDR,DRC_REG_EDX);
gen_extend_word(false,FC_ADDR); gen_extend_word(false,FC_ADDR);
if (cpu.pmode) gen_protect_addr_reg(); gen_protect_addr_reg();
dyn_add_iocheck(FC_ADDR,decode.big_op?4:2); dyn_add_iocheck(FC_ADDR,decode.big_op?4:2);
gen_mov_word_to_reg(FC_RETOP,DRCD_REG_WORD(DRC_REG_EAX,decode.big_op),decode.big_op); MOV_REG_WORD_TO_HOST_REG(FC_RETOP,DRC_REG_EAX,decode.big_op);
if (!decode.big_op) gen_extend_word(false,FC_RETOP); if (!decode.big_op) gen_extend_word(false,FC_RETOP);
if (cpu.pmode) gen_restore_addr_reg(); gen_restore_addr_reg();
gen_call_function_RR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),FC_ADDR,FC_RETOP); gen_call_function_RR(decode.big_op?((void*)&IO_WriteD):((void*)&IO_WriteW),FC_ADDR,FC_RETOP);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -289,8 +289,8 @@ static void dyn_fpu_esc1(){
switch(decode.modrm.reg){ switch(decode.modrm.reg){
case 0x00: /* FLD float*/ case 0x00: /* FLD float*/
gen_call_function_raw((void*)&FPU_PREP_PUSH); gen_call_function_raw((void*)&FPU_PREP_PUSH);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
dyn_fill_ea(FC_OP1); dyn_fill_ea(FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
gen_call_function_RR((void*)&FPU_FLD_F32,FC_OP1,FC_OP2); gen_call_function_RR((void*)&FPU_FLD_F32,FC_OP1,FC_OP2);
break; break;
case 0x01: /* UNKNOWN */ case 0x01: /* UNKNOWN */
@ -532,8 +532,8 @@ static void dyn_fpu_esc5(){
case 0x07: /*FNSTSW */ case 0x07: /*FNSTSW */
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1); gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),true);
dyn_fill_ea(FC_OP1); dyn_fill_ea(FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),true);
gen_call_function_RR((void*)&mem_writew,FC_OP1,FC_OP2); gen_call_function_RR((void*)&mem_writew,FC_OP1,FC_OP2);
break; break;
default: default:
@ -618,7 +618,7 @@ static void dyn_fpu_esc7(){
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true); gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1); gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1);
gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false); gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false);
gen_mov_word_from_reg(FC_OP1,DRCD_REG_WORD(DRC_REG_EAX,false),false); MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,DRC_REG_EAX);
break; break;
default: default:
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm); LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
@ -633,8 +633,8 @@ static void dyn_fpu_esc7(){
switch(decode.modrm.reg){ switch(decode.modrm.reg){
case 0x00: /* FILD Bit16s */ case 0x00: /* FILD Bit16s */
gen_call_function_raw((void*)&FPU_PREP_PUSH); gen_call_function_raw((void*)&FPU_PREP_PUSH);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
dyn_fill_ea(FC_OP1); dyn_fill_ea(FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
gen_call_function_RR((void*)&FPU_FLD_I16,FC_OP1,FC_OP2); gen_call_function_RR((void*)&FPU_FLD_I16,FC_OP1,FC_OP2);
break; break;
case 0x01: case 0x01:
@ -651,14 +651,14 @@ static void dyn_fpu_esc7(){
break; break;
case 0x04: /* FBLD packed BCD */ case 0x04: /* FBLD packed BCD */
gen_call_function_raw((void*)&FPU_PREP_PUSH); gen_call_function_raw((void*)&FPU_PREP_PUSH);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
dyn_fill_ea(FC_OP1); dyn_fill_ea(FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
gen_call_function_RR((void*)&FPU_FBLD,FC_OP1,FC_OP2); gen_call_function_RR((void*)&FPU_FBLD,FC_OP1,FC_OP2);
break; break;
case 0x05: /* FILD Bit64s */ case 0x05: /* FILD Bit64s */
gen_call_function_raw((void*)&FPU_PREP_PUSH); gen_call_function_raw((void*)&FPU_PREP_PUSH);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
dyn_fill_ea(FC_OP1); dyn_fill_ea(FC_OP1);
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
gen_call_function_RR((void*)&FPU_FLD_I64,FC_OP1,FC_OP2); gen_call_function_RR((void*)&FPU_FLD_I64,FC_OP1,FC_OP2);
break; break;
case 0x06: /* FBSTP packed BCD */ case 0x06: /* FBSTP packed BCD */

View File

@ -754,7 +754,7 @@ static Bit8u DRC_CALL_CONV dynrec_rol_byte_simple(Bit8u op1,Bit8u op2) {
static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC; static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) DRC_FC;
static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) { static Bit8u DRC_CALL_CONV dynrec_ror_byte(Bit8u op1,Bit8u op2) {
if (!(op2&0x7)) { if (!(op2&0x7)) {
if (op2&0x10) { if (op2&0x18) {
FillFlagsNoCFOF(); FillFlagsNoCFOF();
SETFLAGBIT(CF,op1>>7); SETFLAGBIT(CF,op1>>7);
SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1));

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-common.h,v 1.2 2008/09/19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (common data/functions) */
// some configuring defines that specify the capabilities of this architecture
// or aspects of the recompiling
// protect FC_ADDR over function calls if necessaray
// #define DRC_PROTECT_ADDR_REG
// try to use non-flags generating functions if possible
#define DRC_FLAGS_INVALIDATION
// try to replace _simple functions by code
#define DRC_FLAGS_INVALIDATION_DCODE
// type with the same size as a pointer
#define DRC_PTR_SIZE_IM Bit32u
// calling convention modifier
#define DRC_CALL_CONV /* nothing */
#define DRC_FC /* nothing */
// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR
#define DRC_USE_REGS_ADDR
// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR
#define DRC_USE_SEGS_ADDR
// register mapping
typedef Bit8u HostReg;
// "lo" registers
#define HOST_r0 0
#define HOST_r1 1
#define HOST_r2 2
#define HOST_r3 3
#define HOST_r4 4
#define HOST_r5 5
#define HOST_r6 6
#define HOST_r7 7
// "hi" registers
#define HOST_r8 8
#define HOST_r9 9
#define HOST_r10 10
#define HOST_r11 11
#define HOST_r12 12
#define HOST_r13 13
#define HOST_r14 14
#define HOST_r15 15
// register aliases
// "lo" registers
#define HOST_a1 HOST_r0
#define HOST_a2 HOST_r1
#define HOST_a3 HOST_r2
#define HOST_a4 HOST_r3
#define HOST_v1 HOST_r4
#define HOST_v2 HOST_r5
#define HOST_v3 HOST_r6
#define HOST_v4 HOST_r7
// "hi" registers
#define HOST_v5 HOST_r8
#define HOST_v6 HOST_r9
#define HOST_v7 HOST_r10
#define HOST_v8 HOST_r11
#define HOST_ip HOST_r12
#define HOST_sp HOST_r13
#define HOST_lr HOST_r14
#define HOST_pc HOST_r15
static void cache_block_closing(Bit8u* block_start,Bitu block_size) {
// GP2X BEGIN
//flush cache
register unsigned long _beg __asm ("a1") = (unsigned long)(block_start); // block start
register unsigned long _end __asm ("a2") = (unsigned long)(block_start+block_size); // block end
register unsigned long _flg __asm ("a3") = 0;
__asm __volatile ("swi 0x9f0002 @ sys_cacheflush"
: // no outputs
: "r" (_beg), "r" (_end), "r" (_flg)
);
// GP2X END
}

View File

@ -0,0 +1,982 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-o3.h,v 1.3 2008/09/19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (size-tweaked arm version) */
// temporary registers
#define temp1 HOST_ip
#define temp2 HOST_v5
#define temp3 HOST_v4
// register that holds function return values
#define FC_RETOP HOST_v3
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
// register that holds the first parameter
#define FC_OP1 HOST_a1
// register that holds the second parameter
#define FC_OP2 HOST_a2
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
// register that holds byte-accessible temporary values
#define FC_TMP_BA2 HOST_a2
// temporary register for LEA
#define TEMP_REG_DRC HOST_v2
#ifdef DRC_USE_REGS_ADDR
// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code
#define FC_REGS_ADDR HOST_v7
#endif
#ifdef DRC_USE_SEGS_ADDR
// used to hold the address of "Segs" - preferably filled in function gen_run_code
#define FC_SEGS_ADDR HOST_v8
#endif
// helper macro
#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) )
// move a full register from reg_src to reg_dst
static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) {
if(reg_src == reg_dst) return;
cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src
}
// helper function
static Bits get_imm_gen_len(Bit32u imm) {
Bits ret;
if (imm == 0) {
return 1;
} else {
ret = 0;
while (imm) {
while ((imm & 3) == 0) {
imm>>=2;
}
ret++;
imm>>=8;
}
return ret;
}
}
// helper function
static Bits get_method_imm_gen_len(Bit32u imm, Bits preffer00, Bits *num) {
Bits num00, num15, numadd, numsub, numret, ret;
num00 = get_imm_gen_len(imm);
num15 = get_imm_gen_len(~imm);
numadd = get_imm_gen_len(imm - ((Bit32u)cache.pos+8));
numsub = get_imm_gen_len(((Bit32u)cache.pos+8) - imm);
if (numsub < numadd && numsub < num00 && numsub < num15) {
ret = 0;
numret = numsub;
} else if (numadd < num00 && numadd < num15) {
ret = 1;
numret = numadd;
} else if (num00 < num15 || (num00 == num15 && preffer00)) {
ret = 2;
numret = num00;
} else {
ret = 3;
numret = num15;
}
if (num != NULL) *num = numret;
return ret;
}
// move a 32bit constant value into dest_reg
static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) {
Bits first, method, scale;
Bit32u imm2, dist;
if (imm == 0) {
cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0
} else if (imm == 0xffffffff) {
cache_addd(0xe3e00000 + (dest_reg << 12)); // mvn dest_reg, #0
} else {
method = get_method_imm_gen_len(imm, 1, NULL);
scale = 0;
first = 1;
if (method == 0) {
dist = ((Bit32u)cache.pos+8) - imm;
while (dist) {
while ((dist & 3) == 0) {
dist>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe2400000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, pc, #((dist & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe2400000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // sub dest_reg, dest_reg, #((dist & 0xff) << scale)
}
dist>>=8;
scale+=8;
}
} else if (method == 1) {
dist = imm - ((Bit32u)cache.pos+8);
if (dist == 0) {
cache_addd(0xe1a00000 + (dest_reg << 12) + HOST_pc); // mov dest_reg, pc
} else {
while (dist) {
while ((dist & 3) == 0) {
dist>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe2800000 + (dest_reg << 12) + (HOST_pc << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, pc, #((dist & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe2800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (dist & 0xff)); // add dest_reg, dest_reg, #((dist & 0xff) << scale)
}
dist>>=8;
scale+=8;
}
}
} else if (method == 2) {
while (imm) {
while ((imm & 3) == 0) {
imm>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale)
}
imm>>=8;
scale+=8;
}
} else {
imm2 = ~imm;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe3e00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mvn dest_reg, #((imm2 & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe3c00000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic dest_reg, dest_reg, #((imm2 & 0xff) << scale)
}
imm2>>=8;
scale+=8;
}
}
}
}
// helper function for gen_mov_word_to_reg
static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) {
// alignment....
if (dword) {
if ((Bit32u)data & 3) {
if ( ((Bit32u)data & 3) == 2 ) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg]
cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2]
cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16
} else {
cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg]
cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1]
cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8
cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3]
cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24
}
} else {
cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg]
}
} else {
if ((Bit32u)data & 1) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg]
cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1]
cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg]
}
}
}
// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)data);
gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1);
}
// move a 16bit constant value into dest_reg
// the upper 16bit of the destination register may be destroyed
static void gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) {
Bits first, scale;
Bit32u imm2;
if (imm == 0) {
cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0
} else {
scale = 0;
first = 1;
imm2 = (Bit32u)imm;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // mov dest_reg, #((imm2 & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // orr dest_reg, dest_reg, #((imm2 & 0xff) << scale)
}
imm2>>=8;
scale+=8;
}
}
}
// helper function for gen_mov_word_from_reg
static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) {
// alignment....
if (dword) {
if ((Bit32u)dest & 3) {
if ( ((Bit32u)dest & 3) == 2 ) {
cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg]
cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16
cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2]
} else {
cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg]
cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8
cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1]
cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16
cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3]
}
} else {
cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg]
}
} else {
if ((Bit32u)dest & 1) {
cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg]
cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8
cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg]
}
}
}
// move 32bit (dword==true) or 16bit (dword==false) of a register into memory
static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1);
}
// move an 8bit value from memory into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)data);
cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1]
}
// move an 8bit value from memory into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) {
gen_mov_byte_to_reg_low(dest_reg, data);
}
// move an 8bit constant value into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) {
cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm)
}
// move an 8bit constant value into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) {
gen_mov_byte_to_reg_low_imm(dest_reg, imm);
}
// move the lowest 8bit of a register into memory
static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1]
}
// convert an 8bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_byte(bool sign,HostReg reg) {
if (sign) {
cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24
cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24
} else {
cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff
}
}
// convert a 16bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_word(bool sign,HostReg reg) {
if (sign) {
cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16
cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16
} else {
cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16
cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16
}
}
// add a 32bit value from memory to a full register
static void gen_add(HostReg reg,void* op) {
gen_mov_word_to_reg(temp3, op, 1);
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3
}
// add a 32bit constant value to a full register
static void gen_add_imm(HostReg reg,Bit32u imm) {
Bits method1, method2, num1, num2, scale, sub;
if(!imm) return;
if (imm == 1) {
cache_addd(0xe2800001 + (reg << 12) + (reg << 16)); // add reg, reg, #1
} else if (imm == 0xffffffff) {
cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1
} else {
method1 = get_method_imm_gen_len(imm, 1, &num1);
method2 = get_method_imm_gen_len(-((Bit32s)imm), 1, &num2);
if (num2 < num1) {
method1 = method2;
imm = (Bit32u)(-((Bit32s)imm));
sub = 1;
} else sub = 0;
if (method1 != 2) {
gen_mov_dword_to_reg_imm(temp3, imm);
if (sub) {
cache_addd(0xe0400000 + (reg << 12) + (reg << 16) + (temp3)); // sub reg, reg, temp3
} else {
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3
}
} else {
scale = 0;
while (imm) {
while ((imm & 3) == 0) {
imm>>=2;
scale+=2;
}
if (sub) {
cache_addd(0xe2400000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // sub reg, reg, #((imm & 0xff) << scale)
} else {
cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale)
}
imm>>=8;
scale+=8;
}
}
}
}
// and a 32bit constant value with a full register
static void gen_and_imm(HostReg reg,Bit32u imm) {
Bits method, scale;
Bit32u imm2;
imm2 = ~imm;
if(!imm2) return;
if (!imm) {
cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0
} else {
method = get_method_imm_gen_len(imm, 0, NULL);
if (method != 3) {
gen_mov_dword_to_reg_imm(temp3, imm);
cache_addd(0xe0000000 + (reg << 12) + (reg << 16) + (temp3)); // and reg, reg, temp3
} else {
scale = 0;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale)
imm2>>=8;
scale+=8;
}
}
}
}
// move a 32bit constant value into memory
static void gen_mov_direct_dword(void* dest,Bit32u imm) {
gen_mov_dword_to_reg_imm(temp3, imm);
gen_mov_word_from_reg(temp3, dest, 1);
}
// move an address into memory
static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) {
gen_mov_direct_dword(dest,(Bit32u)imm);
}
// add an 8bit constant value to a dword memory value
static void gen_add_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, 1, temp1);
if (imm >= 0) {
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm)
} else {
cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm)
}
gen_mov_word_from_reg_helper(temp3, dest, 1, temp1);
}
// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value
static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) {
if(!imm) return;
if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) {
gen_add_direct_byte(dest,(Bit8s)imm);
return;
}
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, dword, temp1);
// maybe use function gen_add_imm
if (dword) {
gen_mov_dword_to_reg_imm(temp2, imm);
} else {
gen_mov_word_to_reg_imm(temp2, (Bit16u)imm);
}
cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2
gen_mov_word_from_reg_helper(temp3, dest, dword, temp1);
}
// subtract an 8bit constant value from a dword memory value
static void gen_sub_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, 1, temp1);
if (imm >= 0) {
cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm)
} else {
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm)
}
gen_mov_word_from_reg_helper(temp3, dest, 1, temp1);
}
// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value
static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) {
if(!imm) return;
if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) {
gen_sub_direct_byte(dest,(Bit8s)imm);
return;
}
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, dword, temp1);
// maybe use function gen_add_imm/gen_sub_imm
if (dword) {
gen_mov_dword_to_reg_imm(temp2, imm);
} else {
gen_mov_word_to_reg_imm(temp2, (Bit16u)imm);
}
cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2
gen_mov_word_from_reg_helper(temp3, dest, dword, temp1);
}
// effective address calculation, destination is dest_reg
// scale_reg is scaled by scale (scale_reg*(2^scale)) and
// added to dest_reg, then the immediate value is added
static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) {
cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale)
gen_add_imm(dest_reg, imm);
}
// effective address calculation, destination is dest_reg
// dest_reg is scaled by scale (dest_reg*(2^scale)),
// then the immediate value is added
static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
if (scale) {
cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale)
}
gen_add_imm(dest_reg, imm);
}
// generate a call to a parameterless function
static void INLINE gen_call_function_raw(void * func) {
cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4]
cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd((Bit32u)func); // .int func
cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1
}
// generate a call to a function with paramcount parameters
// note: the parameters are loaded in the architecture specific way
// using the gen_load_param_ functions below
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
Bit32u proc_addr = (Bit32u)cache.pos;
gen_call_function_raw(func);
return proc_addr;
}
#if (1)
// max of 4 parameters in a1-a4
// load an immediate value as param'th function parameter
static void INLINE gen_load_param_imm(Bitu imm,Bitu param) {
gen_mov_dword_to_reg_imm(param, imm);
}
// load an address as param'th function parameter
static void INLINE gen_load_param_addr(Bitu addr,Bitu param) {
gen_mov_dword_to_reg_imm(param, addr);
}
// load a host-register as param'th function parameter
static void INLINE gen_load_param_reg(Bitu reg,Bitu param) {
gen_mov_regs(param, reg);
}
// load a value from memory as param'th function parameter
static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
gen_mov_word_to_reg(param, (void *)mem, 1);
}
#else
other arm abis
#endif
// jump to an address pointed at by ptr, offset is in imm
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
Bits num1, num2, scale, sub;
Bitu imm2;
gen_mov_word_to_reg(temp3, ptr, 1);
if (imm) {
num1 = get_imm_gen_len(imm);
num2 = get_imm_gen_len(-imm);
if (num2 < num1) {
imm = -imm;
sub = 1;
} else sub = 0;
scale = 0;
imm2 = (Bitu)imm;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
if (sub) {
cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // sub temp3, temp3, #((imm2 & 0xff) << scale)
} else {
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale)
}
imm2>>=8;
scale+=8;
}
}
#if (1)
// (*ptr) should be word aligned
if ((imm & 0x03) == 0) {
cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3]
} else
#endif
{
cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3]
cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1]
cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8
cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2]
cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16
cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3]
cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24
}
cache_addd(0xe12fff10 + (temp1)); // bx temp1
}
// short conditional jump (+-127 bytes) if register is zero
// the destination is set by gen_fill_branch() later
static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) {
if (dword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16
}
cache_addd(0x0a000000); // beq j
return ((Bit32u)cache.pos-4);
}
// short conditional jump (+-127 bytes) if register is nonzero
// the destination is set by gen_fill_branch() later
static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) {
if (dword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16
}
cache_addd(0x1a000000); // bne j
return ((Bit32u)cache.pos-4);
}
// calculate relative offset and fill it into the location pointed to by data
static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) {
#if C_DEBUG
Bits len=(Bit32u)cache.pos-(data+8);
if (len<0) len=-len;
if (len>0x02000000) LOG_MSG("Big jump %d",len);
#endif
*(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff );
}
// conditional jump if register is nonzero
// for isdword==true the 32bit of the register are tested
// for isdword==false the lowest 8bit of the register are tested
static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) {
if (isdword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff
}
cache_addd(0x0a000002); // beq nobranch
cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0]
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd(0); // fill j
// nobranch:
return ((Bit32u)cache.pos-4);
}
// compare 32bit-register against zero and jump if value less/equal than zero
static Bit32u gen_create_branch_long_leqzero(HostReg reg) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
cache_addd(0xca000002); // bgt nobranch
cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0]
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd(0); // fill j
// nobranch:
return ((Bit32u)cache.pos-4);
}
// calculate long relative offset and fill it into the location pointed to by data
static void INLINE gen_fill_branch_long(Bit32u data) {
// this is an absolute branch
*(Bit32u*)data=(Bit32u)cache.pos;
}
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
// adr: 8
cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
// adr: 12
cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)]
cache_addd(0xe28fe004); // add lr, pc, #4
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe12fff10); // bx r0
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
// fill up to 64 bytes
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
// adr: 64
cache_addd((Bit32u)&Segs); // address of "Segs"
// adr: 68
cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs"
}
// return from a function
static void gen_return_function(void) {
cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
}
#ifdef DRC_FLAGS_INVALIDATION
// called when a call to a function can be replaced by a
// call to a simpler function
static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
#ifdef DRC_FLAGS_INVALIDATION_DCODE
// try to avoid function calls but rather directly fill in code
switch (flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_CMPb:
case t_CMPw:
case t_CMPd:
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SHRb:
*(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff
*(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+8)=0xe1a00000; // nop
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SHRw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SHRd:
*(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SARb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24
*(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SARw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16
*(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SARd:
*(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_RORb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_RORw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_RORd:
*(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ROLb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
break;
case t_ROLw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_ROLd:
*(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+8)=0xe1a00000; // nop
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
default:
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func
break;
}
#else
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func
#endif
}
#endif
static void cache_block_before_close(void) { }
#ifdef DRC_USE_SEGS_ADDR
// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #index]
}
// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #index]
}
// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_add_seg32_to_reg(HostReg reg,Bitu index) {
cache_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1
}
#endif
#ifdef DRC_USE_REGS_ADDR
// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index]
}
// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
}
// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) {
if (dword) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index]
}
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index]
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index]
}
// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_add_regval32_to_reg(HostReg reg,Bitu index) {
cache_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2
}
// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero)
static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index]
}
// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
}
// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) {
if (dword) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index]
}
}
// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR
static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) {
cache_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index]
}
#endif

View File

@ -0,0 +1,817 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le-s3.h,v 1.3 2008/09/19 16:48:02 c2woody Exp $ */
/* ARMv4 (little endian) backend by M-HT (speed-tweaked arm version) */
// temporary registers
#define temp1 HOST_ip
#define temp2 HOST_v5
#define temp3 HOST_v4
// register that holds function return values
#define FC_RETOP HOST_v3
// register used for address calculations,
#define FC_ADDR HOST_v1 // has to be saved across calls, see DRC_PROTECT_ADDR_REG
// register that holds the first parameter
#define FC_OP1 HOST_a1
// register that holds the second parameter
#define FC_OP2 HOST_a2
// register that holds byte-accessible temporary values
#define FC_TMP_BA1 HOST_a1
// register that holds byte-accessible temporary values
#define FC_TMP_BA2 HOST_a2
// temporary register for LEA
#define TEMP_REG_DRC HOST_v2
#ifdef DRC_USE_REGS_ADDR
// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code
#define FC_REGS_ADDR HOST_v7
#endif
#ifdef DRC_USE_SEGS_ADDR
// used to hold the address of "Segs" - preferably filled in function gen_run_code
#define FC_SEGS_ADDR HOST_v8
#endif
// helper macro
#define ROTATE_SCALE(x) ( (x)?(32 - x):(0) )
// move a full register from reg_src to reg_dst
static void gen_mov_regs(HostReg reg_dst,HostReg reg_src) {
if(reg_src == reg_dst) return;
cache_addd(0xe1a00000 + (reg_dst << 12) + reg_src); // mov reg_dst, reg_src
}
// move a 32bit constant value into dest_reg
static void gen_mov_dword_to_reg_imm(HostReg dest_reg,Bit32u imm) {
Bits first, scale;
if (imm == 0) {
cache_addd(0xe3a00000 + (dest_reg << 12)); // mov dest_reg, #0
} else {
scale = 0;
first = 1;
while (imm) {
while ((imm & 3) == 0) {
imm>>=2;
scale+=2;
}
if (first) {
cache_addd(0xe3a00000 + (dest_reg << 12) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // mov dest_reg, #((imm & 0xff) << scale)
first = 0;
} else {
cache_addd(0xe3800000 + (dest_reg << 12) + (dest_reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // orr dest_reg, dest_reg, #((imm & 0xff) << scale)
}
imm>>=8;
scale+=8;
}
}
}
// helper function for gen_mov_word_to_reg
static void gen_mov_word_to_reg_helper(HostReg dest_reg,void* data,bool dword,HostReg data_reg) {
// alignment....
if (dword) {
if ((Bit32u)data & 3) {
if ( ((Bit32u)data & 3) == 2 ) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg]
cache_addd(0xe1d000b2 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #2]
cache_addd(0xe1800800 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #16
} else {
cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg]
cache_addd(0xe1d000b1 + (temp2 << 12) + (data_reg << 16)); // ldrh temp2, [data_reg, #1]
cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8
cache_addd(0xe5d00003 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #3]
cache_addd(0xe1800c00 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #24
}
} else {
cache_addd(0xe5900000 + (dest_reg << 12) + (data_reg << 16)); // ldr dest_reg, [data_reg]
}
} else {
if ((Bit32u)data & 1) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (data_reg << 16)); // ldrb dest_reg, [data_reg]
cache_addd(0xe5d00001 + (temp2 << 12) + (data_reg << 16)); // ldrb temp2, [data_reg, #1]
cache_addd(0xe1800400 + (dest_reg << 12) + (dest_reg << 16) + (temp2)); // orr dest_reg, dest_reg, temp2, lsl #8
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (data_reg << 16)); // ldrh dest_reg, [data_reg]
}
}
}
// move a 32bit (dword==true) or 16bit (dword==false) value from memory into dest_reg
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_word_to_reg(HostReg dest_reg,void* data,bool dword) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)data);
gen_mov_word_to_reg_helper(dest_reg, data, dword, temp1);
}
// move a 16bit constant value into dest_reg
// the upper 16bit of the destination register may be destroyed
static void INLINE gen_mov_word_to_reg_imm(HostReg dest_reg,Bit16u imm) {
gen_mov_dword_to_reg_imm(dest_reg, (Bit32u)imm);
}
// helper function for gen_mov_word_from_reg
static void gen_mov_word_from_reg_helper(HostReg src_reg,void* dest,bool dword, HostReg data_reg) {
// alignment....
if (dword) {
if ((Bit32u)dest & 3) {
if ( ((Bit32u)dest & 3) == 2 ) {
cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg]
cache_addd(0xe1a00820 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #16
cache_addd(0xe1c000b2 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #2]
} else {
cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg]
cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8
cache_addd(0xe1c000b1 + (temp2 << 12) + (data_reg << 16)); // strh temp2, [data_reg, #1]
cache_addd(0xe1a00820 + (temp2 << 12) + (temp2)); // mov temp2, temp2, lsr #16
cache_addd(0xe5c00003 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #3]
}
} else {
cache_addd(0xe5800000 + (src_reg << 12) + (data_reg << 16)); // str src_reg, [data_reg]
}
} else {
if ((Bit32u)dest & 1) {
cache_addd(0xe5c00000 + (src_reg << 12) + (data_reg << 16)); // strb src_reg, [data_reg]
cache_addd(0xe1a00420 + (temp2 << 12) + (src_reg)); // mov temp2, src_reg, lsr #8
cache_addd(0xe5c00001 + (temp2 << 12) + (data_reg << 16)); // strb temp2, [data_reg, #1]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (data_reg << 16)); // strh src_reg, [data_reg]
}
}
}
// move 32bit (dword==true) or 16bit (dword==false) of a register into memory
static void gen_mov_word_from_reg(HostReg src_reg,void* dest,bool dword) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_from_reg_helper(src_reg, dest, dword, temp1);
}
// move an 8bit value from memory into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_byte_to_reg_low(HostReg dest_reg,void* data) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)data);
cache_addd(0xe5d00000 + (dest_reg << 12) + (temp1 << 16)); // ldrb dest_reg, [temp1]
}
// move an 8bit value from memory into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_byte_to_reg_low_canuseword(HostReg dest_reg,void* data) {
gen_mov_byte_to_reg_low(dest_reg, data);
}
// move an 8bit constant value into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_byte_to_reg_low_imm(HostReg dest_reg,Bit8u imm) {
cache_addd(0xe3a00000 + (dest_reg << 12) + (imm)); // mov dest_reg, #(imm)
}
// move an 8bit constant value into dest_reg
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_byte_to_reg_low_imm_canuseword(HostReg dest_reg,Bit8u imm) {
gen_mov_byte_to_reg_low_imm(dest_reg, imm);
}
// move the lowest 8bit of a register into memory
static void gen_mov_byte_from_reg_low(HostReg src_reg,void* dest) {
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
cache_addd(0xe5c00000 + (src_reg << 12) + (temp1 << 16)); // strb src_reg, [temp1]
}
// convert an 8bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_byte(bool sign,HostReg reg) {
if (sign) {
cache_addd(0xe1a00c00 + (reg << 12) + (reg)); // mov reg, reg, lsl #24
cache_addd(0xe1a00c40 + (reg << 12) + (reg)); // mov reg, reg, asr #24
} else {
cache_addd(0xe20000ff + (reg << 12) + (reg << 16)); // and reg, reg, #0xff
}
}
// convert a 16bit word to a 32bit dword
// the register is zero-extended (sign==false) or sign-extended (sign==true)
static void gen_extend_word(bool sign,HostReg reg) {
if (sign) {
cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16
cache_addd(0xe1a00840 + (reg << 12) + (reg)); // mov reg, reg, asr #16
} else {
cache_addd(0xe1a00800 + (reg << 12) + (reg)); // mov reg, reg, lsl #16
cache_addd(0xe1a00820 + (reg << 12) + (reg)); // mov reg, reg, lsr #16
}
}
// add a 32bit value from memory to a full register
static void gen_add(HostReg reg,void* op) {
gen_mov_word_to_reg(temp3, op, 1);
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp3)); // add reg, reg, temp3
}
// add a 32bit constant value to a full register
static void gen_add_imm(HostReg reg,Bit32u imm) {
Bits scale;
if(!imm) return;
if (imm == 0xffffffff) {
cache_addd(0xe2400001 + (reg << 12) + (reg << 16)); // sub reg, reg, #1
} else {
scale = 0;
while (imm) {
while ((imm & 3) == 0) {
imm>>=2;
scale+=2;
}
cache_addd(0xe2800000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm & 0xff)); // add reg, reg, #((imm & 0xff) << scale)
imm>>=8;
scale+=8;
}
}
}
// and a 32bit constant value with a full register
static void gen_and_imm(HostReg reg,Bit32u imm) {
Bits scale;
Bit32u imm2;
imm2 = ~imm;
if(!imm2) return;
if (!imm) {
cache_addd(0xe3a00000 + (reg << 12)); // mov reg, #0
} else {
scale = 0;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
cache_addd(0xe3c00000 + (reg << 12) + (reg << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // bic reg, reg, #((imm2 & 0xff) << scale)
imm2>>=8;
scale+=8;
}
}
}
// move a 32bit constant value into memory
static void gen_mov_direct_dword(void* dest,Bit32u imm) {
gen_mov_dword_to_reg_imm(temp3, imm);
gen_mov_word_from_reg(temp3, dest, 1);
}
// move an address into memory
static void INLINE gen_mov_direct_ptr(void* dest,DRC_PTR_SIZE_IM imm) {
gen_mov_direct_dword(dest,(Bit32u)imm);
}
// add an 8bit constant value to a dword memory value
static void gen_add_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, 1, temp1);
if (imm >= 0) {
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // add temp3, temp3, #(imm)
} else {
cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // sub temp3, temp3, #(-imm)
}
gen_mov_word_from_reg_helper(temp3, dest, 1, temp1);
}
// add a 32bit (dword==true) or 16bit (dword==false) constant value to a memory value
static void gen_add_direct_word(void* dest,Bit32u imm,bool dword) {
if(!imm) return;
if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) {
gen_add_direct_byte(dest,(Bit8s)imm);
return;
}
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, dword, temp1);
// maybe use function gen_add_imm
if (dword) {
gen_mov_dword_to_reg_imm(temp2, imm);
} else {
gen_mov_word_to_reg_imm(temp2, (Bit16u)imm);
}
cache_addd(0xe0800000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // add temp3, temp3, temp2
gen_mov_word_from_reg_helper(temp3, dest, dword, temp1);
}
// subtract an 8bit constant value from a dword memory value
static void gen_sub_direct_byte(void* dest,Bit8s imm) {
if(!imm) return;
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, 1, temp1);
if (imm >= 0) {
cache_addd(0xe2400000 + (temp3 << 12) + (temp3 << 16) + ((Bit32s)imm)); // sub temp3, temp3, #(imm)
} else {
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (-((Bit32s)imm))); // add temp3, temp3, #(-imm)
}
gen_mov_word_from_reg_helper(temp3, dest, 1, temp1);
}
// subtract a 32bit (dword==true) or 16bit (dword==false) constant value from a memory value
static void gen_sub_direct_word(void* dest,Bit32u imm,bool dword) {
if(!imm) return;
if (dword && ( (imm<128) || (imm>=0xffffff80) ) ) {
gen_sub_direct_byte(dest,(Bit8s)imm);
return;
}
gen_mov_dword_to_reg_imm(temp1, (Bit32u)dest);
gen_mov_word_to_reg_helper(temp3, dest, dword, temp1);
// maybe use function gen_add_imm/gen_sub_imm
if (dword) {
gen_mov_dword_to_reg_imm(temp2, imm);
} else {
gen_mov_word_to_reg_imm(temp2, (Bit16u)imm);
}
cache_addd(0xe0400000 + (temp3 << 12) + (temp3 << 16) + (temp2)); // sub temp3, temp3, temp2
gen_mov_word_from_reg_helper(temp3, dest, dword, temp1);
}
// effective address calculation, destination is dest_reg
// scale_reg is scaled by scale (scale_reg*(2^scale)) and
// added to dest_reg, then the immediate value is added
static INLINE void gen_lea(HostReg dest_reg,HostReg scale_reg,Bitu scale,Bits imm) {
cache_addd(0xe0800000 + (dest_reg << 12) + (dest_reg << 16) + (scale_reg) + (scale << 7)); // add dest_reg, dest_reg, scale_reg, lsl #(scale)
gen_add_imm(dest_reg, imm);
}
// effective address calculation, destination is dest_reg
// dest_reg is scaled by scale (dest_reg*(2^scale)),
// then the immediate value is added
static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
if (scale) {
cache_addd(0xe1a00000 + (dest_reg << 12) + (dest_reg) + (scale << 7)); // mov dest_reg, dest_reg, lsl #(scale)
}
gen_add_imm(dest_reg, imm);
}
// generate a call to a parameterless function
static void INLINE gen_call_function_raw(void * func) {
cache_addd(0xe5900004 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #4]
cache_addd(0xe2800004 + (HOST_lr << 12) + (HOST_pc << 16)); // add lr, pc, #4
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd((Bit32u)func); // .int func
cache_addd(0xe1a00000 + (FC_RETOP << 12) + HOST_a1); // mov FC_RETOP, a1
}
// generate a call to a function with paramcount parameters
// note: the parameters are loaded in the architecture specific way
// using the gen_load_param_ functions below
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
Bit32u proc_addr = (Bit32u)cache.pos;
gen_call_function_raw(func);
return proc_addr;
}
#if (1)
// max of 4 parameters in a1-a4
// load an immediate value as param'th function parameter
static void INLINE gen_load_param_imm(Bitu imm,Bitu param) {
gen_mov_dword_to_reg_imm(param, imm);
}
// load an address as param'th function parameter
static void INLINE gen_load_param_addr(Bitu addr,Bitu param) {
gen_mov_dword_to_reg_imm(param, addr);
}
// load a host-register as param'th function parameter
static void INLINE gen_load_param_reg(Bitu reg,Bitu param) {
gen_mov_regs(param, reg);
}
// load a value from memory as param'th function parameter
static void INLINE gen_load_param_mem(Bitu mem,Bitu param) {
gen_mov_word_to_reg(param, (void *)mem, 1);
}
#else
other arm abis
#endif
// jump to an address pointed at by ptr, offset is in imm
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
Bits scale;
Bitu imm2;
gen_mov_word_to_reg(temp3, ptr, 1);
if (imm) {
scale = 0;
imm2 = (Bitu)imm;
while (imm2) {
while ((imm2 & 3) == 0) {
imm2>>=2;
scale+=2;
}
cache_addd(0xe2800000 + (temp3 << 12) + (temp3 << 16) + (ROTATE_SCALE(scale) << 7) + (imm2 & 0xff)); // add temp3, temp3, #((imm2 & 0xff) << scale)
imm2>>=8;
scale+=8;
}
}
#if (1)
// (*ptr) should be word aligned
if ((imm & 0x03) == 0) {
cache_addd(0xe5900000 + (temp1 << 12) + (temp3 << 16)); // ldr temp1, [temp3]
} else
#endif
{
cache_addd(0xe5d00000 + (temp1 << 12) + (temp3 << 16)); // ldrb temp1, [temp3]
cache_addd(0xe5d00001 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #1]
cache_addd(0xe1800400 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #8
cache_addd(0xe5d00002 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #2]
cache_addd(0xe1800800 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #16
cache_addd(0xe5d00003 + (temp2 << 12) + (temp3 << 16)); // ldrb temp2, [temp3, #3]
cache_addd(0xe1800c00 + (temp1 << 12) + (temp1 << 16) + (temp2)); // orr temp1, temp1, temp2, lsl #24
}
cache_addd(0xe12fff10 + (temp1)); // bx temp1
}
// short conditional jump (+-127 bytes) if register is zero
// the destination is set by gen_fill_branch() later
static Bit32u gen_create_branch_on_zero(HostReg reg,bool dword) {
if (dword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16
}
cache_addd(0x0a000000); // beq j
return ((Bit32u)cache.pos-4);
}
// short conditional jump (+-127 bytes) if register is nonzero
// the destination is set by gen_fill_branch() later
static Bit32u gen_create_branch_on_nonzero(HostReg reg,bool dword) {
if (dword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe1b00800 + (temp1 << 12) + (reg)); // movs temp1, reg, lsl #16
}
cache_addd(0x1a000000); // bne j
return ((Bit32u)cache.pos-4);
}
// calculate relative offset and fill it into the location pointed to by data
static void INLINE gen_fill_branch(DRC_PTR_SIZE_IM data) {
#if C_DEBUG
Bits len=(Bit32u)cache.pos-(data+8);
if (len<0) len=-len;
if (len>0x02000000) LOG_MSG("Big jump %d",len);
#endif
*(Bit32u*)data=( (*(Bit32u*)data) & 0xff000000 ) | ( ( ((Bit32u)cache.pos - (data+8)) >> 2 ) & 0x00ffffff );
}
// conditional jump if register is nonzero
// for isdword==true the 32bit of the register are tested
// for isdword==false the lowest 8bit of the register are tested
static Bit32u gen_create_branch_long_nonzero(HostReg reg,bool isdword) {
if (isdword) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
} else {
cache_addd(0xe31000ff + (reg << 16)); // tst reg, #0xff
}
cache_addd(0x0a000002); // beq nobranch
cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0]
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd(0); // fill j
// nobranch:
return ((Bit32u)cache.pos-4);
}
// compare 32bit-register against zero and jump if value less/equal than zero
static Bit32u gen_create_branch_long_leqzero(HostReg reg) {
cache_addd(0xe3500000 + (reg << 16)); // cmp reg, #0
cache_addd(0xca000002); // bgt nobranch
cache_addd(0xe5900000 + (temp1 << 12) + (HOST_pc << 16)); // ldr temp1, [pc, #0]
cache_addd(0xe12fff10 + (temp1)); // bx temp1
cache_addd(0); // fill j
// nobranch:
return ((Bit32u)cache.pos-4);
}
// calculate long relative offset and fill it into the location pointed to by data
static void INLINE gen_fill_branch_long(Bit32u data) {
// this is an absolute branch
*(Bit32u*)data=(Bit32u)cache.pos;
}
static void gen_run_code(void) {
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe92d0df0); // stmfd sp!, {v1-v5,v7,v8}
// adr: 8
cache_addd(0xe5900000 + (FC_SEGS_ADDR << 12) + (HOST_pc << 16) + (64 - (8 + 8))); // ldr FC_SEGS_ADDR, [pc, #(&Segs)]
// adr: 12
cache_addd(0xe5900000 + (FC_REGS_ADDR << 12) + (HOST_pc << 16) + (68 - (12 + 8))); // ldr FC_REGS_ADDR, [pc, #(&cpu_regs)]
cache_addd(0xe28fe004); // add lr, pc, #4
cache_addd(0xe92d4000); // stmfd sp!, {lr}
cache_addd(0xe12fff10); // bx r0
cache_addd(0xe8bd0df0); // ldmfd sp!, {v1-v5,v7,v8}
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
// fill up to 64 bytes
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
cache_addd(0xe1a00000); // nop
// adr: 64
cache_addd((Bit32u)&Segs); // address of "Segs"
// adr: 68
cache_addd((Bit32u)&cpu_regs); // address of "cpu_regs"
}
// return from a function
static void gen_return_function(void) {
cache_addd(0xe1a00000 + (HOST_a1 << 12) + FC_RETOP); // mov a1, FC_RETOP
cache_addd(0xe8bd4000); // ldmfd sp!, {lr}
cache_addd(0xe12fff1e); // bx lr
}
#ifdef DRC_FLAGS_INVALIDATION
// called when a call to a function can be replaced by a
// call to a simpler function
static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
#ifdef DRC_FLAGS_INVALIDATION_DCODE
// try to avoid function calls but rather directly fill in code
switch (flags_type) {
case t_ADDb:
case t_ADDw:
case t_ADDd:
*(Bit32u*)pos=0xe0800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // add FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ORb:
case t_ORw:
case t_ORd:
*(Bit32u*)pos=0xe1800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // orr FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ANDb:
case t_ANDw:
case t_ANDd:
*(Bit32u*)pos=0xe0000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // and FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SUBb:
case t_SUBw:
case t_SUBd:
*(Bit32u*)pos=0xe0400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // sub FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_XORb:
case t_XORw:
case t_XORd:
*(Bit32u*)pos=0xe0200000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (HOST_a2); // eor FC_RETOP, a1, a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_CMPb:
case t_CMPw:
case t_CMPd:
case t_TESTb:
case t_TESTw:
case t_TESTd:
*(Bit32u*)pos=0xea000000 + (3); // b (pc+3*4)
break;
case t_INCb:
case t_INCw:
case t_INCd:
*(Bit32u*)pos=0xe2800000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // add FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_DECb:
case t_DECw:
case t_DECd:
*(Bit32u*)pos=0xe2400000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (1); // sub FC_RETOP, a1, #1
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SHLb:
case t_SHLw:
case t_SHLd:
*(Bit32u*)pos=0xe1a00010 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsl a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SHRb:
*(Bit32u*)pos=0xe2000000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0xff); // and FC_RETOP, a1, #0xff
*(Bit32u*)(pos+4)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+8)=0xe1a00000; // nop
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SHRw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1a00020 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=0xe1a00030 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, lsr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SHRd:
*(Bit32u*)pos=0xe1a00030 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, lsr a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_SARb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (24 << 7); // mov FC_RETOP, FC_RETOP, asr #24
*(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SARw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1a00040 + (FC_RETOP << 12) + (FC_RETOP) + (16 << 7); // mov FC_RETOP, FC_RETOP, asr #16
*(Bit32u*)(pos+8)=0xe1a00050 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, asr a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_SARd:
*(Bit32u*)pos=0xe1a00050 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, asr a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_RORb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_RORw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+8)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_RORd:
*(Bit32u*)pos=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
case t_ROLb:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (24 << 7); // mov FC_RETOP, a1, lsl #24
*(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (8 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #8
*(Bit32u*)(pos+12)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+16)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
break;
case t_ROLw:
*(Bit32u*)pos=0xe1a00000 + (FC_RETOP << 12) + (HOST_a1) + (16 << 7); // mov FC_RETOP, a1, lsl #16
*(Bit32u*)(pos+4)=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+8)=0xe1800020 + (FC_RETOP << 12) + (FC_RETOP << 16) + (FC_RETOP) + (16 << 7); // orr FC_RETOP, FC_RETOP, FC_RETOP, lsr #16
*(Bit32u*)(pos+12)=0xe1a00070 + (FC_RETOP << 12) + (FC_RETOP) + (HOST_a2 << 8); // mov FC_RETOP, FC_RETOP, ror a2
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_ROLd:
*(Bit32u*)pos=0xe2600000 + (HOST_a2 << 12) + (HOST_a2 << 16) + (32); // rsb a2, a2, #32
*(Bit32u*)(pos+4)=0xe1a00070 + (FC_RETOP << 12) + (HOST_a1) + (HOST_a2 << 8); // mov FC_RETOP, a1, ror a2
*(Bit32u*)(pos+8)=0xe1a00000; // nop
*(Bit32u*)(pos+12)=0xe1a00000; // nop
*(Bit32u*)(pos+16)=0xe1a00000; // nop
break;
case t_NEGb:
case t_NEGw:
case t_NEGd:
*(Bit32u*)pos=0xe2600000 + (FC_RETOP << 12) + (HOST_a1 << 16) + (0); // rsb FC_RETOP, a1, #0
*(Bit32u*)(pos+4)=0xea000000 + (2); // b (pc+2*4)
break;
default:
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func
break;
}
#else
*(Bit32u*)(pos+12)=(Bit32u)fct_ptr; // simple_func
#endif
}
#endif
static void cache_block_before_close(void) { }
#ifdef DRC_USE_SEGS_ADDR
// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_SEGS_ADDR, #index]
}
// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_SEGS_ADDR, #index]
}
// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_add_seg32_to_reg(HostReg reg,Bitu index) {
cache_addd(0xe5900000 + (temp1 << 12) + (FC_SEGS_ADDR << 16) + (index)); // ldr temp1, [FC_SEGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp1)); // add reg, reg, temp1
}
#endif
#ifdef DRC_USE_REGS_ADDR
// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index]
}
// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
}
// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) {
if (dword) {
cache_addd(0xe5900000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr dest_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1d000b0 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // ldrh dest_reg, [FC_REGS_ADDR, #index]
}
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index]
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) {
cache_addd(0xe5d00000 + (dest_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // ldrb dest_reg, [FC_REGS_ADDR, #index]
}
// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_add_regval32_to_reg(HostReg reg,Bitu index) {
cache_addd(0xe5900000 + (temp2 << 12) + (FC_REGS_ADDR << 16) + (index)); // ldr temp2, [FC_REGS_ADDR, #index]
cache_addd(0xe0800000 + (reg << 12) + (reg << 16) + (temp2)); // add reg, reg, temp2
}
// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero)
static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index]
}
// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
}
// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) {
if (dword) {
cache_addd(0xe5800000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // str src_reg, [FC_REGS_ADDR, #index]
} else {
cache_addd(0xe1c000b0 + (src_reg << 12) + (FC_REGS_ADDR << 16) + ((index & 0xf0) << 4) + (index & 0x0f)); // strh src_reg, [FC_REGS_ADDR, #index]
}
}
// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR
static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) {
cache_addd(0xe5c00000 + (src_reg << 12) + (FC_REGS_ADDR << 16) + (index)); // strb src_reg, [FC_REGS_ADDR, #index]
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: risc_armv4le.h,v 1.2 2008/09/02 20:44:41 c2woody Exp $ */
/* ARMv4 (little endian) backend (switcher) by M-HT */
#include "risc_armv4le-common.h"
// choose your destiny:
#include "risc_armv4le-thumb-niw.h"
//#include "risc_armv4le-thumb-iw.h"
//#include "risc_armv4le-thumb.h"
//#include "risc_armv4le-s3.h"
//#include "risc_armv4le-o3.h"

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: risc_mipsel32.h,v 1.4 2008/09/19 16:48:03 c2woody Exp $ */
/* MIPS32 (little endian) backend by crazyc */ /* MIPS32 (little endian) backend by crazyc */
@ -36,7 +38,12 @@
// calling convention modifier // calling convention modifier
#define DRC_CALL_CONV /* nothing */ #define DRC_CALL_CONV /* nothing */
#define DRC_FC /* nothing */ #define DRC_FC /* nothing */
// use FC_REGS_ADDR to hold the address of "cpu_regs" and to access it using FC_REGS_ADDR
//#define DRC_USE_REGS_ADDR
// use FC_SEGS_ADDR to hold the address of "Segs" and to access it using FC_SEGS_ADDR
//#define DRC_USE_SEGS_ADDR
// register mapping // register mapping
typedef Bit8u HostReg; typedef Bit8u HostReg;
@ -76,6 +83,16 @@ typedef Bit8u HostReg;
// temporary register for LEA // temporary register for LEA
#define TEMP_REG_DRC HOST_t7 #define TEMP_REG_DRC HOST_t7
#ifdef DRC_USE_REGS_ADDR
// used to hold the address of "cpu_regs" - preferably filled in function gen_run_code
#define FC_REGS_ADDR HOST_???
#endif
#ifdef DRC_USE_SEGS_ADDR
// used to hold the address of "Segs" - preferably filled in function gen_run_code
#define FC_SEGS_ADDR HOST_???
#endif
// save some state to improve code gen // save some state to improve code gen
static bool temp1_valid = false; static bool temp1_valid = false;
static Bit32u temp1_value; static Bit32u temp1_value;
@ -630,3 +647,102 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
#endif #endif
} }
#endif #endif
static void cache_block_closing(Bit8u* block_start,Bitu block_size) {
#ifdef PSP
// writeback dcache and invalidate icache
Bit32u inval_start = ((Bit32u)block_start) & ~63;
Bit32u inval_end = (((Bit32u)block_start) + block_size + 64) & ~63;
for (;inval_start < inval_end; inval_start+=64) {
__builtin_allegrex_cache(0x1a, inval_start);
__builtin_allegrex_cache(0x08, inval_start);
}
#endif
}
static void cache_block_before_close(void) { }
#ifdef DRC_USE_SEGS_ADDR
// mov 16bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_seg16_to_reg(HostReg dest_reg,Bitu index) {
// stub
}
// mov 32bit value from Segs[index] into dest_reg using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_mov_seg32_to_reg(HostReg dest_reg,Bitu index) {
// stub
}
// add a 32bit value from Segs[index] to a full register using FC_SEGS_ADDR (index modulo 4 must be zero)
static void gen_add_seg32_to_reg(HostReg reg,Bitu index) {
// stub
}
#endif
#ifdef DRC_USE_REGS_ADDR
// mov 16bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regval16_to_reg(HostReg dest_reg,Bitu index) {
// stub
}
// mov 32bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_to_reg(HostReg dest_reg,Bitu index) {
// stub
}
// move a 32bit (dword==true) or 16bit (dword==false) value from cpu_regs[index] into dest_reg using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
// 16bit moves may destroy the upper 16bit of the destination register
static void gen_mov_regword_to_reg(HostReg dest_reg,Bitu index,bool dword) {
// stub
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function does not use FC_OP1/FC_OP2 as dest_reg as these
// registers might not be directly byte-accessible on some architectures
static void gen_mov_regbyte_to_reg_low(HostReg dest_reg,Bitu index) {
// stub
}
// move an 8bit value from cpu_regs[index] into dest_reg using FC_REGS_ADDR
// the upper 24bit of the destination register can be destroyed
// this function can use FC_OP1/FC_OP2 as dest_reg which are
// not directly byte-accessible on some architectures
static void INLINE gen_mov_regbyte_to_reg_low_canuseword(HostReg dest_reg,Bitu index) {
// stub
}
// add a 32bit value from cpu_regs[index] to a full register using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_add_regval32_to_reg(HostReg reg,Bitu index) {
// stub
}
// move 16bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 2 must be zero)
static void gen_mov_regval16_from_reg(HostReg src_reg,Bitu index) {
// stub
}
// move 32bit of register into cpu_regs[index] using FC_REGS_ADDR (index modulo 4 must be zero)
static void gen_mov_regval32_from_reg(HostReg src_reg,Bitu index) {
// stub
}
// move 32bit (dword==true) or 16bit (dword==false) of a register into cpu_regs[index] using FC_REGS_ADDR (if dword==true index modulo 4 must be zero) (if dword==false index modulo 2 must be zero)
static void gen_mov_regword_from_reg(HostReg src_reg,Bitu index,bool dword) {
// stub
}
// move the lowest 8bit of a register into cpu_regs[index] using FC_REGS_ADDR
static void gen_mov_regbyte_from_reg_low(HostReg src_reg,Bitu index) {
// stub
}
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: risc_x64.h,v 1.11 2008/09/02 20:44:41 c2woody Exp $ */
// some configuring defines that specify the capabilities of this architecture // some configuring defines that specify the capabilities of this architecture
// or aspects of the recompiling // or aspects of the recompiling
@ -671,3 +673,7 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
#endif #endif
} }
#endif #endif
static void cache_block_closing(Bit8u* block_start,Bitu block_size) { }
static void cache_block_before_close(void) { }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: risc_x86.h,v 1.8 2008/09/02 20:44:41 c2woody Exp $ */
// some configuring defines that specify the capabilities of this architecture // some configuring defines that specify the capabilities of this architecture
// or aspects of the recompiling // or aspects of the recompiling
@ -505,3 +507,7 @@ static void gen_fill_function_ptr(Bit8u * pos,void* fct_ptr,Bitu flags_type) {
#endif #endif
} }
#endif #endif
static void cache_block_closing(Bit8u* block_start,Bitu block_size) { }
static void cache_block_before_close(void) { }

View File

@ -1,333 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \
string.h support.h
subdir = src/cpu/core_full
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/cpu/core_full/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(HEADERS)
installdirs:
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
info info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-info-am
# 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:

View File

@ -6,6 +6,9 @@ switch (inst.code.load) {
case L_POPdRM: case L_POPdRM:
inst_op1_d = Pop_32(); inst_op1_d = Pop_32();
goto case_L_MODRM; goto case_L_MODRM;
case L_MODRM_NVM:
if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode;
goto case_L_MODRM;
case_L_MODRM: case_L_MODRM:
case L_MODRM: case L_MODRM:
inst.rm=Fetchb(); inst.rm=Fetchb();
@ -465,7 +468,7 @@ l_M_Ed:
AAS(); AAS();
goto nextopcode; goto nextopcode;
case D_CPUID: case D_CPUID:
CPU_CPUID(); if (!CPU_CPUID()) goto illegalopcode;
goto nextopcode; goto nextopcode;
case D_HLT: case D_HLT:
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);

View File

@ -459,7 +459,6 @@ switch (inst.code.op) {
break; break;
case O_LAR: case O_LAR:
{ {
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
Bitu ar=inst_op2_d; Bitu ar=inst_op2_d;
CPU_LAR(inst_op1_w,ar); CPU_LAR(inst_op1_w,ar);
inst_op1_d=(Bit32u)ar; inst_op1_d=(Bit32u)ar;
@ -467,7 +466,6 @@ switch (inst.code.op) {
break; break;
case O_LSL: case O_LSL:
{ {
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
Bitu limit=inst_op2_d; Bitu limit=inst_op2_d;
CPU_LSL(inst_op1_w,limit); CPU_LSL(inst_op1_w,limit);
inst_op1_d=(Bit32u)limit; inst_op1_d=(Bit32u)limit;
@ -475,7 +473,6 @@ switch (inst.code.op) {
break; break;
case O_ARPL: case O_ARPL:
{ {
if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode;
Bitu new_sel=inst_op1_d; Bitu new_sel=inst_op1_d;
CPU_ARPL(new_sel,inst_op2_d); CPU_ARPL(new_sel,inst_op2_d);
inst_op1_d=(Bit32u)new_sel; inst_op1_d=(Bit32u)new_sel;
@ -588,8 +585,22 @@ switch (inst.code.op) {
inst_op1_d&=~(1 << (inst_op2_d & 31)); inst_op1_d&=~(1 << (inst_op2_d & 31));
break; break;
case O_BSWAP: case O_BSWAP:
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegalopcode;
BSWAP(inst_op1_d); BSWAP(inst_op1_d);
break; break;
case O_CMPXCHG:
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegalopcode;
FillFlags();
if (inst_op1_d==reg_eax) {
inst_op1_d=reg_32(inst.rm_index);
if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf
SETFLAGBIT(ZF,1);
} else {
if (inst.rm<0xc0) SaveMd(inst.rm_eaa,inst_op1_d); // early write-pf
reg_eax=inst_op1_d;
SETFLAGBIT(ZF,0);
}
break;
case O_FPU: case O_FPU:
#if C_FPU #if C_FPU
switch (((inst.rm>=0xc0) << 3) | inst.code.save) { switch (((inst.rm>=0xc0) << 3) | inst.code.save) {

View File

@ -69,7 +69,7 @@ static OpCode OpCodeTable[1024]={
/* 0x60 - 0x67 */ /* 0x60 - 0x67 */
{D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 }, {D_PUSHAw ,0 ,0 ,0 },{D_POPAw ,0 ,0 ,0 },
{L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM ,O_ARPL ,S_Ew ,M_EwGw }, {L_MODRM ,O_BOUNDw ,0 ,M_Gw },{L_MODRM_NVM ,O_ARPL ,S_Ew ,M_EwGw },
{L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs }, {L_PRESEG ,0 ,0 ,fs },{L_PRESEG ,0 ,0 ,gs },
{L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 }, {L_PREOP ,0 ,0 ,0 },{L_PREADD ,0 ,0 ,0 },
/* 0x68 - 0x6f */ /* 0x68 - 0x6f */
@ -183,7 +183,7 @@ static OpCode OpCodeTable[1024]={
/* 0x100 - 0x107 */ /* 0x100 - 0x107 */
{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew }, {L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew },
{L_MODRM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM ,O_LSL ,S_Gw ,M_EwGw }, {L_MODRM_NVM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM_NVM ,O_LSL ,S_Gw ,M_EwGw },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x108 - 0x10f */ /* 0x108 - 0x10f */
@ -528,7 +528,7 @@ static OpCode OpCodeTable[1024]={
/* 0x2f0 - 0x2f7 */ /* 0x2f0 - 0x2f7 */
{D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 }, {D_LOCK ,0 ,0 ,0 },{D_ICEBP ,0 ,0 ,0 },
{L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 }, {L_PREREPNE ,0 ,0 ,0 },{L_PREREP ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 }, {D_HLT ,0 ,0 ,0 },{D_CMC ,0 ,0 ,0 },
{L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP }, {L_MODRM ,8 ,0 ,M_GRP },{L_MODRM ,0xa ,0 ,M_GRP },
/* 0x2f8 - 0x2ff */ /* 0x2f8 - 0x2ff */
{D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 }, {D_CLC ,0 ,0 ,0 },{D_STC ,0 ,0 ,0 },
@ -539,7 +539,7 @@ static OpCode OpCodeTable[1024]={
/* 0x300 - 0x307 */ /* 0x300 - 0x307 */
{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew }, {L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew },
{L_MODRM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM ,O_LSL ,S_Gd ,M_EdGd }, {L_MODRM_NVM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM_NVM ,O_LSL ,S_Gd ,M_EdGd },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x308 - 0x30f */ /* 0x308 - 0x30f */
@ -661,7 +661,7 @@ static OpCode OpCodeTable[1024]={
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx }, {0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx },
/* 0x3b0 - 0x3b7 */ /* 0x3b0 - 0x3b7 */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 }, {0 ,0 ,0 ,0 },{L_MODRM ,O_CMPXCHG ,S_Ed ,M_Ed },
{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt }, {L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,S_Ed ,M_EdGdt },
{L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd }, {L_MODRM ,O_SEGFS ,S_SEGGd,M_Efd },{L_MODRM ,O_SEGGS ,S_SEGGd,M_Efd },
{L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew }, {L_MODRM ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew },

View File

@ -31,6 +31,7 @@
LoadIP(); LoadIP();
} else { } else {
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */ /* Won't interrupt scas and cmps instruction since they can interrupt themselves */
if (inst.code.op<R_SCASB) CPU_Cycles-=count;
count_left=0; count_left=0;
} }
} }

View File

@ -2,7 +2,7 @@ enum {
L_N=0, L_N=0,
L_SKIP, L_SKIP,
/* Grouped ones using MOD/RM */ /* Grouped ones using MOD/RM */
L_MODRM,L_POPwRM,L_POPdRM, L_MODRM,L_MODRM_NVM,L_POPwRM,L_POPdRM,
L_Ib,L_Iw,L_Id, L_Ib,L_Iw,L_Id,
L_Ibx,L_Iwx,L_Idx, //Sign extend L_Ibx,L_Iwx,L_Idx, //Sign extend
@ -46,7 +46,7 @@ enum {
D_CPUID, D_CPUID,
D_HLT,D_CLTS, D_HLT,D_CLTS,
D_LOCK,D_ICEBP, D_LOCK,D_ICEBP,
L_ERROR, L_ERROR
}; };
@ -94,8 +94,8 @@ enum {
O_BTd,O_BTSd,O_BTRd,O_BTCd, O_BTd,O_BTSd,O_BTRd,O_BTCd,
O_BSFw,O_BSRw,O_BSFd,O_BSRd, O_BSFw,O_BSRw,O_BSFd,O_BSRd,
O_BSWAP, O_BSWAP,O_CMPXCHG,
O_FPU, O_FPU
}; };
@ -117,7 +117,7 @@ enum {
S_AIPw,S_C_AIPw, S_AIPw,S_C_AIPw,
S_AIPd,S_C_AIPd, S_AIPd,S_C_AIPd,
S_IP,S_IPIw, S_IP,S_IPIw
}; };
enum { enum {
@ -127,7 +127,7 @@ enum {
R_LODSB,R_LODSW,R_LODSD, R_LODSB,R_LODSW,R_LODSD,
R_STOSB,R_STOSW,R_STOSD, R_STOSB,R_STOSW,R_STOSD,
R_SCASB,R_SCASW,R_SCASD, R_SCASB,R_SCASW,R_SCASD,
R_CMPSB,R_CMPSW,R_CMPSD, R_CMPSB,R_CMPSW,R_CMPSD
}; };
enum { enum {
@ -149,7 +149,7 @@ enum {
M_GRP, M_GRP,
M_GRP_Ib,M_GRP_CL,M_GRP_1, M_GRP_Ib,M_GRP_CL,M_GRP_1,
M_POPw,M_POPd, M_POPw,M_POPd
}; };
struct OpCode { struct OpCode {

View File

@ -169,7 +169,7 @@ restart_opcode:
if (len>16) len=16; if (len>16) len=16;
char tempcode[16*2+1];char * writecode=tempcode; char tempcode[16*2+1];char * writecode=tempcode;
for (;len>0;len--) { for (;len>0;len--) {
sprintf(writecode,"%X",mem_readb(core.cseip++)); sprintf(writecode,"%02X",mem_readb(core.cseip++));
writecode+=2; writecode+=2;
} }
LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode); LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode);

View File

@ -1,333 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \
prefix_66_0f.h string.h
subdir = src/cpu/core_normal
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/cpu/core_normal/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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 $(HEADERS)
installdirs:
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:
-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-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic ctags \
distclean distclean-generic distclean-tags distdir dvi dvi-am \
info info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am tags \
uninstall uninstall-am uninstall-info-am
# 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:

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -142,6 +142,11 @@
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP); if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
cpu.cr0&=(~CR0_TASKSWITCH); cpu.cr0&=(~CR0_TASKSWITCH);
break; break;
CASE_0F_B(0x08) /* INVD */
CASE_0F_B(0x09) /* WBINVD */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
if (cpu.pmode && cpu.cpl) EXCEPTION(EXCEPTION_GP);
break;
CASE_0F_B(0x20) /* MOV Rd.CRx */ CASE_0F_B(0x20) /* MOV Rd.CRx */
{ {
GetRM; GetRM;
@ -220,6 +225,14 @@
if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION(); if (CPU_WRITE_TRX(which,*eard)) RUNEXCEPTION();
} }
break; break;
CASE_0F_B(0x31) /* RDTSC */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegal_opcode;
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)CPU_CycleMax);
reg_edx=(Bit32u)(tsc>>32);
reg_eax=(Bit32u)(tsc&0xffffffff);
}
break;
CASE_0F_W(0x80) /* JO */ CASE_0F_W(0x80) /* JO */
JumpCond16_w(TFLG_O);break; JumpCond16_w(TFLG_O);break;
CASE_0F_W(0x81) /* JNO */ CASE_0F_W(0x81) /* JNO */
@ -291,7 +304,8 @@
if (CPU_PopSeg(fs,false)) RUNEXCEPTION(); if (CPU_PopSeg(fs,false)) RUNEXCEPTION();
break; break;
CASE_0F_B(0xa2) /* CPUID */ CASE_0F_B(0xa2) /* CPUID */
CPU_CPUID();break; if (!CPU_CPUID()) goto illegal_opcode;
break;
CASE_0F_W(0xa3) /* BT Ew,Gw */ CASE_0F_W(0xa3) /* BT Ew,Gw */
{ {
FillFlags();GetRMrw; FillFlags();GetRMrw;
@ -344,7 +358,9 @@
break; break;
CASE_0F_W(0xb2) /* LSS Ew */ CASE_0F_W(0xb2) /* LSS Ew */
{ {
GetRMrw;GetEAa; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION(); if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa); *rmrw=LoadMw(eaa);
break; break;
@ -367,14 +383,18 @@
} }
CASE_0F_W(0xb4) /* LFS Ew */ CASE_0F_W(0xb4) /* LFS Ew */
{ {
GetRMrw;GetEAa; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION(); if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa); *rmrw=LoadMw(eaa);
break; break;
} }
CASE_0F_W(0xb5) /* LGS Ew */ CASE_0F_W(0xb5) /* LGS Ew */
{ {
GetRMrw;GetEAa; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION(); if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa); *rmrw=LoadMw(eaa);
break; break;
@ -497,6 +517,7 @@
} }
CASE_0F_B(0xc0) /* XADD Gb,Eb */ CASE_0F_B(0xc0) /* XADD Gb,Eb */
{ {
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
GetRMrb;Bit8u oldrmrb=*rmrb; GetRMrb;Bit8u oldrmrb=*rmrb;
if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;} if (rm >= 0xc0 ) {GetEArb;*rmrb=*earb;*earb+=oldrmrb;}
else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);} else {GetEAa;*rmrb=LoadMb(eaa);SaveMb(eaa,LoadMb(eaa)+oldrmrb);}
@ -504,25 +525,34 @@
} }
CASE_0F_W(0xc1) /* XADD Gw,Ew */ CASE_0F_W(0xc1) /* XADD Gw,Ew */
{ {
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
GetRMrw;Bit16u oldrmrw=*rmrw; GetRMrw;Bit16u oldrmrw=*rmrw;
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;} if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;*earw+=oldrmrw;}
else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);} else {GetEAa;*rmrw=LoadMw(eaa);SaveMw(eaa,LoadMw(eaa)+oldrmrw);}
break; break;
} }
CASE_0F_B(0xc8) /* BSWAP EAX */ CASE_0F_B(0xc8) /* BSWAP EAX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_eax);break; BSWAP(reg_eax);break;
CASE_0F_B(0xc9) /* BSWAP ECX */ CASE_0F_B(0xc9) /* BSWAP ECX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_ecx);break; BSWAP(reg_ecx);break;
CASE_0F_B(0xca) /* BSWAP EDX */ CASE_0F_B(0xca) /* BSWAP EDX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_edx);break; BSWAP(reg_edx);break;
CASE_0F_B(0xcb) /* BSWAP EBX */ CASE_0F_B(0xcb) /* BSWAP EBX */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_ebx);break; BSWAP(reg_ebx);break;
CASE_0F_B(0xcc) /* BSWAP ESP */ CASE_0F_B(0xcc) /* BSWAP ESP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_esp);break; BSWAP(reg_esp);break;
CASE_0F_B(0xcd) /* BSWAP EBP */ CASE_0F_B(0xcd) /* BSWAP EBP */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_ebp);break; BSWAP(reg_ebp);break;
CASE_0F_B(0xce) /* BSWAP ESI */ CASE_0F_B(0xce) /* BSWAP ESI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_esi);break; BSWAP(reg_esi);break;
CASE_0F_B(0xcf) /* BSWAP EDI */ CASE_0F_B(0xcf) /* BSWAP EDI */
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
BSWAP(reg_edi);break; BSWAP(reg_edi);break;

View File

@ -462,14 +462,18 @@
continue; continue;
CASE_D(0xc4) /* LES */ CASE_D(0xc4) /* LES */
{ {
GetRMrd;GetEAa; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION(); if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION();
*rmrd=LoadMd(eaa); *rmrd=LoadMd(eaa);
break; break;
} }
CASE_D(0xc5) /* LDS */ CASE_D(0xc5) /* LDS */
{ {
GetRMrd;GetEAa; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION(); if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION();
*rmrd=LoadMd(eaa); *rmrd=LoadMd(eaa);
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -235,9 +235,39 @@
RMGdEdOp3(DIMULD,*rmrd); RMGdEdOp3(DIMULD,*rmrd);
break; break;
} }
CASE_0F_D(0xb1) /* CMPXCHG Ed,Gd */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) goto illegal_opcode;
FillFlags();
GetRMrd;
if (rm >= 0xc0) {
GetEArd;
if (*eard==reg_eax) {
*eard=*rmrd;
SETFLAGBIT(ZF,1);
} else {
reg_eax=*eard;
SETFLAGBIT(ZF,0);
}
} else {
GetEAa;
Bit32u val=LoadMd(eaa);
if (val==reg_eax) {
SaveMd(eaa,*rmrd);
SETFLAGBIT(ZF,1);
} else {
SaveMd(eaa,val);
reg_eax=val;
SETFLAGBIT(ZF,0);
}
}
break;
}
CASE_0F_D(0xb2) /* LSS Ed */ CASE_0F_D(0xb2) /* LSS Ed */
{ {
GetRMrd;GetEAa; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION(); if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION();
*rmrd=LoadMd(eaa); *rmrd=LoadMd(eaa);
break; break;
@ -260,14 +290,18 @@
} }
CASE_0F_D(0xb4) /* LFS Ed */ CASE_0F_D(0xb4) /* LFS Ed */
{ {
GetRMrd;GetEAa; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION(); if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION();
*rmrd=LoadMd(eaa); *rmrd=LoadMd(eaa);
break; break;
} }
CASE_0F_D(0xb5) /* LGS Ed */ CASE_0F_D(0xb5) /* LGS Ed */
{ {
GetRMrd;GetEAa; GetRMrd;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION(); if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION();
*rmrd=LoadMd(eaa); *rmrd=LoadMd(eaa);
break; break;
@ -399,6 +433,7 @@
} }
CASE_0F_D(0xc1) /* XADD Gd,Ed */ CASE_0F_D(0xc1) /* XADD Gd,Ed */
{ {
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
GetRMrd;Bit32u oldrmrd=*rmrd; GetRMrd;Bit32u oldrmrd=*rmrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;} if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard+=oldrmrd;}
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);} else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,LoadMd(eaa)+oldrmrd);}

View File

@ -687,14 +687,18 @@
continue; continue;
CASE_W(0xc4) /* LES */ CASE_W(0xc4) /* LES */
{ {
GetRMrw;GetEAa; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION(); if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa); *rmrw=LoadMw(eaa);
break; break;
} }
CASE_W(0xc5) /* LDS */ CASE_W(0xc5) /* LDS */
{ {
GetRMrw;GetEAa; GetRMrw;
if (rm >= 0xc0) goto illegal_opcode;
GetEAa;
if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION(); if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION();
*rmrw=LoadMw(eaa); *rmrw=LoadMw(eaa);
break; break;

View File

@ -5,7 +5,7 @@ enum STRING_OP {
R_LODSB,R_LODSW,R_LODSD, R_LODSB,R_LODSW,R_LODSD,
R_STOSB,R_STOSW,R_STOSD, R_STOSB,R_STOSW,R_STOSD,
R_SCASB,R_SCASW,R_SCASD, R_SCASB,R_SCASW,R_SCASD,
R_CMPSB,R_CMPSW,R_CMPSD, R_CMPSB,R_CMPSW,R_CMPSD
}; };
#define LoadD(_BLAH) _BLAH #define LoadD(_BLAH) _BLAH
@ -34,8 +34,9 @@ static void DoString(STRING_OP type) {
CPU_Cycles=0; CPU_Cycles=0;
LOADIP; //RESET IP to the start LOADIP; //RESET IP to the start
} else { } else {
if ((count<=1) && (CPU_Cycles<=1)) CPU_Cycles--;
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */ /* Won't interrupt scas and cmps instruction since they can interrupt themselves */
if ((count<=1) && (CPU_Cycles<=1)) CPU_Cycles--;
else if (type<R_SCASB) CPU_Cycles-=count;
count_left=0; count_left=0;
} }
} }

View File

@ -76,7 +76,7 @@ static INLINE PhysPt Sib(Bitu mode) {
} }
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6); base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
return base; return base;
}; }
static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; } static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; }
static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; } static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; }

315
src/cpu/core_prefetch.cpp Normal file
View File

@ -0,0 +1,315 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_prefetch.cpp,v 1.1 2008/05/21 21:29:32 c2woody Exp $ */
#include <stdio.h>
#include "dosbox.h"
#include "mem.h"
#include "cpu.h"
#include "lazyflags.h"
#include "inout.h"
#include "callback.h"
#include "pic.h"
#include "fpu.h"
#include "paging.h"
#if C_DEBUG
#include "debug.h"
#endif
#if (!C_CORE_INLINE)
#define LoadMb(off) mem_readb(off)
#define LoadMw(off) mem_readw(off)
#define LoadMd(off) mem_readd(off)
#define SaveMb(off,val) mem_writeb(off,val)
#define SaveMw(off,val) mem_writew(off,val)
#define SaveMd(off,val) mem_writed(off,val)
#else
#include "paging.h"
#define LoadMb(off) mem_readb_inline(off)
#define LoadMw(off) mem_readw_inline(off)
#define LoadMd(off) mem_readd_inline(off)
#define SaveMb(off,val) mem_writeb_inline(off,val)
#define SaveMw(off,val) mem_writew_inline(off,val)
#define SaveMd(off,val) mem_writed_inline(off,val)
#endif
extern Bitu cycle_count;
#if C_FPU
#define CPU_FPU 1 //Enable FPU escape instructions
#endif
#define CPU_PIC_CHECK 1
#define CPU_TRAP_CHECK 1
#define OPCODE_NONE 0x000
#define OPCODE_0F 0x100
#define OPCODE_SIZE 0x200
#define PREFIX_ADDR 0x1
#define PREFIX_REP 0x2
#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR)
#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP)
#define DO_PREFIX_SEG(_SEG) \
BaseDS=SegBase(_SEG); \
BaseSS=SegBase(_SEG); \
core.base_val_ds=_SEG; \
goto restart_opcode;
#define DO_PREFIX_ADDR() \
core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \
(cpu.code.big ^ PREFIX_ADDR); \
core.ea_table=&EATable[(core.prefixes&1) * 256]; \
goto restart_opcode;
#define DO_PREFIX_REP(_ZERO) \
core.prefixes|=PREFIX_REP; \
core.rep_zero=_ZERO; \
goto restart_opcode;
typedef PhysPt (*GetEAHandler)(void);
static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff};
static struct {
Bitu opcode_index;
PhysPt cseip;
PhysPt base_ds,base_ss;
SegNames base_val_ds;
bool rep_zero;
Bitu prefixes;
GetEAHandler * ea_table;
} core;
#define GETIP (core.cseip-SegBase(cs))
#define SAVEIP reg_eip=GETIP;
#define LOADIP core.cseip=(SegBase(cs)+reg_eip);
#define SegBase(c) SegPhys(c)
#define BaseDS core.base_ds
#define BaseSS core.base_ss
#define MAX_PQ_SIZE 32
static Bit8u prefetch_buffer[MAX_PQ_SIZE];
static bool pq_valid=false;
static Bitu pq_start;
static INLINE Bit8u Fetchb() {
Bit8u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start];
if ((core.cseip+1>=pq_start+CPU_PrefetchQueueSize-4) &&
(core.cseip+1<pq_start+CPU_PrefetchQueueSize)) {
Bitu remaining_bytes=pq_start+CPU_PrefetchQueueSize-(core.cseip+1);
for (Bitu i=0; i<remaining_bytes; i++) prefetch_buffer[i]=prefetch_buffer[core.cseip+1-pq_start+i];
for (Bitu i=remaining_bytes; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+1+i);
pq_start=core.cseip+1;
pq_valid=true;
}
} else {
for (Bitu i=0; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+i);
pq_start=core.cseip;
pq_valid=true;
temp=prefetch_buffer[0];
}
/* if (temp!=LoadMb(core.cseip)) {
LOG_MSG("prefetch queue content!=memory at %x:%x",SegValue(cs),reg_eip);
} */
core.cseip+=1;
return temp;
}
static INLINE Bit16u Fetchw() {
Bit16u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip+2<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start]|
(prefetch_buffer[core.cseip-pq_start+1]<<8);
if ((core.cseip+2>=pq_start+CPU_PrefetchQueueSize-4) &&
(core.cseip+2<pq_start+CPU_PrefetchQueueSize)) {
Bitu remaining_bytes=pq_start+CPU_PrefetchQueueSize-(core.cseip+2);
for (Bitu i=0; i<remaining_bytes; i++) prefetch_buffer[i]=prefetch_buffer[core.cseip+2-pq_start+i];
for (Bitu i=remaining_bytes; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+2+i);
pq_start=core.cseip+2;
pq_valid=true;
}
} else {
for (Bitu i=0; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+i);
pq_start=core.cseip;
pq_valid=true;
temp=prefetch_buffer[0] | (prefetch_buffer[1]<<8);
}
/* if (temp!=LoadMw(core.cseip)) {
LOG_MSG("prefetch queue content!=memory at %x:%x",SegValue(cs),reg_eip);
} */
core.cseip+=2;
return temp;
}
static INLINE Bit32u Fetchd() {
Bit32u temp;
if (pq_valid && (core.cseip>=pq_start) && (core.cseip+4<pq_start+CPU_PrefetchQueueSize)) {
temp=prefetch_buffer[core.cseip-pq_start]|
(prefetch_buffer[core.cseip-pq_start+1]<<8)|
(prefetch_buffer[core.cseip-pq_start+2]<<16)|
(prefetch_buffer[core.cseip-pq_start+3]<<24);
if ((core.cseip+4>=pq_start+CPU_PrefetchQueueSize-4) &&
(core.cseip+4<pq_start+CPU_PrefetchQueueSize)) {
Bitu remaining_bytes=pq_start+CPU_PrefetchQueueSize-(core.cseip+4);
for (Bitu i=0; i<remaining_bytes; i++) prefetch_buffer[i]=prefetch_buffer[core.cseip+4-pq_start+i];
for (Bitu i=remaining_bytes; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+4+i);
pq_start=core.cseip+4;
pq_valid=true;
}
} else {
for (Bitu i=0; i<CPU_PrefetchQueueSize; i++) prefetch_buffer[i]=LoadMb(core.cseip+i);
pq_start=core.cseip;
pq_valid=true;
temp=prefetch_buffer[0] | (prefetch_buffer[1]<<8) |
(prefetch_buffer[2]<<16) | (prefetch_buffer[3]<<24);
}
/* if (temp!=LoadMd(core.cseip)) {
LOG_MSG("prefetch queue content!=memory at %x:%x",SegValue(cs),reg_eip);
} */
core.cseip+=4;
return temp;
}
#define Push_16 CPU_Push16
#define Push_32 CPU_Push32
#define Pop_16 CPU_Pop16
#define Pop_32 CPU_Pop32
#include "instructions.h"
#include "core_normal/support.h"
#include "core_normal/string.h"
#define EALookupTable (core.ea_table)
Bits CPU_Core_Prefetch_Run(void) {
bool invalidate_pq=false;
while (CPU_Cycles-->0) {
if (invalidate_pq) {
pq_valid=false;
invalidate_pq=false;
}
LOADIP;
core.opcode_index=cpu.code.big*0x200;
core.prefixes=cpu.code.big;
core.ea_table=&EATable[cpu.code.big*256];
BaseDS=SegBase(ds);
BaseSS=SegBase(ss);
core.base_val_ds=ds;
#if C_DEBUG
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) {
FillFlags();
return debugCallback;
};
#endif
cycle_count++;
#endif
restart_opcode:
Bit8u next_opcode=Fetchb();
invalidate_pq=false;
if (core.opcode_index&OPCODE_0F) invalidate_pq=true;
else switch (next_opcode) {
case 0x70: case 0x71: case 0x72: case 0x73:
case 0x74: case 0x75: case 0x76: case 0x77:
case 0x78: case 0x79: case 0x7a: case 0x7b:
case 0x7c: case 0x7d: case 0x7e: case 0x7f: // jcc
case 0x9a: // call
case 0xc2: case 0xc3: // retn
case 0xc8: // enter
case 0xc9: // leave
case 0xca: case 0xcb: // retf
case 0xcc: // int3
case 0xcd: // int
case 0xce: // into
case 0xcf: // iret
case 0xe0: // loopnz
case 0xe1: // loopz
case 0xe2: // loop
case 0xe3: // jcxz
case 0xe8: // call
case 0xe9: case 0xea: case 0xeb: // jmp
case 0xff:
invalidate_pq=true;
break;
default:
break;
}
switch (core.opcode_index+next_opcode) {
#include "core_normal/prefix_none.h"
#include "core_normal/prefix_0f.h"
#include "core_normal/prefix_66.h"
#include "core_normal/prefix_66_0f.h"
default:
illegal_opcode:
#if C_DEBUG
{
Bitu len=(GETIP-reg_eip);
LOADIP;
if (len>16) len=16;
char tempcode[16*2+1];char * writecode=tempcode;
for (;len>0;len--) {
sprintf(writecode,"%X",mem_readb(core.cseip++));
writecode+=2;
}
LOG(LOG_CPU,LOG_NORMAL)("Illegal/Unhandled opcode %s",tempcode);
}
#endif
CPU_Exception(6,0);
invalidate_pq=true;
continue;
}
SAVEIP;
}
FillFlags();
return CBRET_NONE;
decode_end:
SAVEIP;
FillFlags();
return CBRET_NONE;
}
Bits CPU_Core_Prefetch_Trap_Run(void) {
Bits oldCycles = CPU_Cycles;
CPU_Cycles = 1;
cpu.trap_skip = false;
Bits ret=CPU_Core_Prefetch_Run();
if (!cpu.trap_skip) CPU_HW_Interrupt(1);
CPU_Cycles = oldCycles-1;
cpudecoder = &CPU_Core_Prefetch_Run;
return ret;
}
void CPU_Core_Prefetch_Init(void) {
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2009 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: cpu.cpp,v 1.103 2007/08/09 19:52:32 c2woody Exp $ */ /* $Id: cpu.cpp,v 1.116 2009/03/16 18:10:08 c2woody Exp $ */
#include <assert.h> #include <assert.h>
#include <sstream> #include <sstream>
@ -26,6 +26,7 @@
#include "debug.h" #include "debug.h"
#include "mapper.h" #include "mapper.h"
#include "setup.h" #include "setup.h"
#include "programs.h"
#include "paging.h" #include "paging.h"
#include "lazyflags.h" #include "lazyflags.h"
#include "support.h" #include "support.h"
@ -57,8 +58,15 @@ Bit32s CPU_CycleUp = 0;
Bit32s CPU_CycleDown = 0; Bit32s CPU_CycleDown = 0;
Bit64s CPU_IODelayRemoved = 0; Bit64s CPU_IODelayRemoved = 0;
CPU_Decoder * cpudecoder; CPU_Decoder * cpudecoder;
bool CPU_CycleAutoAdjust; bool CPU_CycleAutoAdjust = false;
Bitu CPU_AutoDetermineMode; bool CPU_SkipCycleAutoAdjust = false;
Bitu CPU_AutoDetermineMode = 0;
Bitu CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
Bitu CPU_flag_id_toggle=0;
Bitu CPU_PrefetchQueueSize=0;
void CPU_Core_Full_Init(void); void CPU_Core_Full_Init(void);
void CPU_Core_Normal_Init(void); void CPU_Core_Normal_Init(void);
@ -110,6 +118,22 @@ void CPU_Core_Dynrec_Cache_Close(void);
#endif #endif
void Descriptor::Load(PhysPt address) {
cpu.mpl=0;
Bit32u* data = (Bit32u*)&saved;
*data = mem_readd(address);
*(data+1) = mem_readd(address+4);
cpu.mpl=3;
}
void Descriptor:: Save(PhysPt address) {
cpu.mpl=0;
Bit32u* data = (Bit32u*)&saved;
mem_writed(address,*data);
mem_writed(address+4,*(data+1));
cpu.mpl=03;
}
void CPU_Push16(Bitu value) { void CPU_Push16(Bitu value) {
Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask); Bit32u new_esp=(reg_esp&cpu.stack.notmask)|((reg_esp-2)&cpu.stack.mask);
mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value); mem_writew(SegPhys(ss) + (new_esp & cpu.stack.mask) ,value);
@ -144,8 +168,10 @@ PhysPt SelBase(Bitu sel) {
} }
} }
void CPU_SetFlags(Bitu word,Bitu mask) { void CPU_SetFlags(Bitu word,Bitu mask) {
reg_flags=(reg_flags & ~mask)|(word & mask)|2|FLAG_ID; mask|=CPU_flag_id_toggle; // ID-flag can be toggled on cpuid-supporting CPUs
reg_flags=(reg_flags & ~mask)|(word & mask)|2;
cpu.direction=1-((reg_flags & FLAG_DF) >> 9); cpu.direction=1-((reg_flags & FLAG_DF) >> 9);
} }
@ -201,6 +227,50 @@ bool CPU_PUSHF(Bitu use32) {
return false; return false;
} }
void CPU_CheckSegments(void) {
bool needs_invalidation=false;
Descriptor desc;
if (!cpu.gdt.GetDescriptor(SegValue(es),desc)) needs_invalidation=true;
else switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) needs_invalidation=true; break;
default: break; }
if (needs_invalidation) CPU_SetSegGeneral(es,0);
needs_invalidation=false;
if (!cpu.gdt.GetDescriptor(SegValue(ds),desc)) needs_invalidation=true;
else switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) needs_invalidation=true; break;
default: break; }
if (needs_invalidation) CPU_SetSegGeneral(ds,0);
needs_invalidation=false;
if (!cpu.gdt.GetDescriptor(SegValue(fs),desc)) needs_invalidation=true;
else switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) needs_invalidation=true; break;
default: break; }
if (needs_invalidation) CPU_SetSegGeneral(fs,0);
needs_invalidation=false;
if (!cpu.gdt.GetDescriptor(SegValue(gs),desc)) needs_invalidation=true;
else switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) needs_invalidation=true; break;
default: break; }
if (needs_invalidation) CPU_SetSegGeneral(gs,0);
}
class TaskStateSegment { class TaskStateSegment {
public: public:
TaskStateSegment() { TaskStateSegment() {
@ -210,12 +280,16 @@ public:
return valid; return valid;
} }
Bitu Get_back(void) { Bitu Get_back(void) {
return mem_readw(base); cpu.mpl=0;
Bit16u backlink=mem_readw(base);
cpu.mpl=3;
return backlink;
} }
void SaveSelector(void) { void SaveSelector(void) {
cpu.gdt.SetDescriptor(selector,desc); cpu.gdt.SetDescriptor(selector,desc);
} }
void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) { void Get_SSx_ESPx(Bitu level,Bitu & _ss,Bitu & _esp) {
cpu.mpl=0;
if (is386) { if (is386) {
PhysPt where=base+offsetof(TSS_32,esp0)+level*8; PhysPt where=base+offsetof(TSS_32,esp0)+level*8;
_esp=mem_readd(where); _esp=mem_readd(where);
@ -225,6 +299,7 @@ public:
_esp=mem_readw(where); _esp=mem_readw(where);
_ss=mem_readw(where+2); _ss=mem_readw(where+2);
} }
cpu.mpl=3;
} }
bool SetSelector(Bitu new_sel) { bool SetSelector(Bitu new_sel) {
valid=false; valid=false;
@ -305,6 +380,14 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) {
new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt)); new_ldt=mem_readw(new_tss.base+offsetof(TSS_32,ldt));
} else { } else {
E_Exit("286 task switch"); E_Exit("286 task switch");
new_cr3=0;
new_eip=0;
new_eflags=0;
new_eax=0; new_ecx=0; new_edx=0; new_ebx=0;
new_esp=0; new_ebp=0; new_edi=0; new_esi=0;
new_es=0; new_cs=0; new_ss=0; new_ds=0; new_fs=0; new_gs=0;
new_ldt=0;
} }
/* Check if we need to clear busy bit of old TASK */ /* Check if we need to clear busy bit of old TASK */
@ -424,7 +507,9 @@ doconforming:
CPU_SetSegGeneral(ds,new_ds); CPU_SetSegGeneral(ds,new_ds);
CPU_SetSegGeneral(fs,new_fs); CPU_SetSegGeneral(fs,new_fs);
CPU_SetSegGeneral(gs,new_gs); CPU_SetSegGeneral(gs,new_gs);
if (!cpu_tss.SetSelector(new_tss_selector)) LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector); if (!cpu_tss.SetSelector(new_tss_selector)) {
LOG(LOG_CPU,LOG_NORMAL)("TaskSwitch: set tss selector %X failed",new_tss_selector);
}
// cpu_tss.desc.SetBusy(true); // cpu_tss.desc.SetBusy(true);
// cpu_tss.SaveSelector(); // cpu_tss.SaveSelector();
// LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags); // LOG_MSG("Task CPL %X CS:%X IP:%X SS:%X SP:%X eflags %x",cpu.cpl,SegValue(cs),reg_eip,SegValue(ss),reg_esp,reg_flags);
@ -433,6 +518,7 @@ doconforming:
bool CPU_IO_Exception(Bitu port,Bitu size) { bool CPU_IO_Exception(Bitu port,Bitu size) {
if (cpu.pmode && ((GETFLAG_IOPL<cpu.cpl) || GETFLAG(VM))) { if (cpu.pmode && ((GETFLAG_IOPL<cpu.cpl) || GETFLAG(VM))) {
cpu.mpl=0;
if (!cpu_tss.is386) goto doexception; if (!cpu_tss.is386) goto doexception;
PhysPt bwhere=cpu_tss.base+0x66; PhysPt bwhere=cpu_tss.base+0x66;
Bitu ofs=mem_readw(bwhere); Bitu ofs=mem_readw(bwhere);
@ -441,9 +527,11 @@ bool CPU_IO_Exception(Bitu port,Bitu size) {
Bitu map=mem_readw(bwhere); Bitu map=mem_readw(bwhere);
Bitu mask=(0xffff>>(16-size)) << (port&7); Bitu mask=(0xffff>>(16-size)) << (port&7);
if (map & mask) goto doexception; if (map & mask) goto doexception;
cpu.mpl=3;
} }
return false; return false;
doexception: doexception:
cpu.mpl=3;
LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port); LOG(LOG_CPU,LOG_NORMAL)("IO Exception port %X",port);
return CPU_PrepareException(EXCEPTION_GP,0); return CPU_PrepareException(EXCEPTION_GP,0);
} }
@ -497,8 +585,8 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) {
return; return;
} }
} }
Descriptor gate;
Descriptor gate;
if (!cpu.idt.GetDescriptor(num<<3,gate)) { if (!cpu.idt.GetDescriptor(num<<3,gate)) {
// zone66 // zone66
CPU_Exception(EXCEPTION_GP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1); CPU_Exception(EXCEPTION_GP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1);
@ -511,14 +599,15 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) {
return; return;
} }
CPU_CHECK_COND(!gate.saved.seg.p,
"INT:Gate segment not present",
EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1)
switch (gate.Type()) { switch (gate.Type()) {
case DESC_286_INT_GATE: case DESC_386_INT_GATE: case DESC_286_INT_GATE: case DESC_386_INT_GATE:
case DESC_286_TRAP_GATE: case DESC_386_TRAP_GATE: case DESC_286_TRAP_GATE: case DESC_386_TRAP_GATE:
{ {
CPU_CHECK_COND(!gate.saved.seg.p,
"INT:Gate segment not present",
EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1)
Descriptor cs_desc; Descriptor cs_desc;
Bitu gate_sel=gate.GetSelector(); Bitu gate_sel=gate.GetSelector();
Bitu gate_off=gate.GetOffset(); Bitu gate_off=gate.GetOffset();
@ -640,8 +729,9 @@ do_interrupt:
cpu.code.big=cs_desc.Big()>0; cpu.code.big=cs_desc.Big()>0;
reg_eip=gate_off; reg_eip=gate_off;
if (!(gate.Type()&1)) if (!(gate.Type()&1)) {
SETFLAGBIT(IF,false); SETFLAGBIT(IF,false);
}
SETFLAGBIT(TF,false); SETFLAGBIT(TF,false);
SETFLAGBIT(NT,false); SETFLAGBIT(NT,false);
SETFLAGBIT(VM,false); SETFLAGBIT(VM,false);
@ -649,6 +739,10 @@ do_interrupt:
return; return;
} }
case DESC_TASK_GATE: case DESC_TASK_GATE:
CPU_CHECK_COND(!gate.saved.seg.p,
"INT:Gate segment not present",
EXCEPTION_NP,num*8+2+(type&CPU_INT_SOFTWARE)?0:1)
CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip); CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip);
if (type & CPU_INT_HAS_ERROR) { if (type & CPU_INT_HAS_ERROR) {
//TODO Be sure about this, seems somewhat unclear //TODO Be sure about this, seems somewhat unclear
@ -687,15 +781,29 @@ void CPU_IRET(bool use32,Bitu oldeip) {
return; return;
} else { } else {
if (use32) { if (use32) {
reg_eip=CPU_Pop32(); Bit32u new_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask));
SegSet16(cs,CPU_Pop32()); Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
Bit32u new_cs=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask));
tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask);
Bit32u new_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask));
reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask);
reg_eip=new_eip;
SegSet16(cs,(Bit16u)(new_cs&0xffff));
/* IOPL can not be modified in v86 mode by IRET */ /* IOPL can not be modified in v86 mode by IRET */
CPU_SetFlags(CPU_Pop32(),FMASK_NORMAL|FLAG_NT); CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT);
} else { } else {
reg_eip=CPU_Pop16(); Bit16u new_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
SegSet16(cs,CPU_Pop16()); Bit32u tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask);
Bit16u new_cs=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask);
Bit16u new_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
reg_esp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask);
reg_eip=(Bit32u)new_eip;
SegSet16(cs,new_cs);
/* IOPL can not be modified in v86 mode by IRET */ /* IOPL can not be modified in v86 mode by IRET */
CPU_SetFlags(CPU_Pop16(),FMASK_NORMAL|FLAG_NT); CPU_SetFlags(new_flags,FMASK_NORMAL|FLAG_NT);
} }
cpu.code.big=false; cpu.code.big=false;
DestroyConditionFlags(); DestroyConditionFlags();
@ -708,18 +816,26 @@ void CPU_IRET(bool use32,Bitu oldeip) {
CPU_CHECK_COND(!cpu_tss.IsValid(), CPU_CHECK_COND(!cpu_tss.IsValid(),
"TASK Iret without valid TSS", "TASK Iret without valid TSS",
EXCEPTION_TS,cpu_tss.selector & 0xfffc) EXCEPTION_TS,cpu_tss.selector & 0xfffc)
if (!cpu_tss.desc.IsBusy()) LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy"); if (!cpu_tss.desc.IsBusy()) {
LOG(LOG_CPU,LOG_ERROR)("TASK Iret:TSS not busy");
}
Bitu back_link=cpu_tss.Get_back(); Bitu back_link=cpu_tss.Get_back();
CPU_SwitchTask(back_link,TSwitch_IRET,oldeip); CPU_SwitchTask(back_link,TSwitch_IRET,oldeip);
return; return;
} }
Bitu n_cs_sel,n_eip,n_flags; Bitu n_cs_sel,n_eip,n_flags;
Bit32u tempesp;
if (use32) { if (use32) {
// commit point n_eip=mem_readd(SegPhys(ss) + (reg_esp & cpu.stack.mask));
n_eip=CPU_Pop32(); tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+4)&cpu.stack.mask);
n_cs_sel=CPU_Pop32() & 0xffff; n_cs_sel=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff;
n_flags=CPU_Pop32(); tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask);
n_flags=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask));
tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask);
if ((n_flags & FLAG_VM) && (cpu.cpl==0)) { if ((n_flags & FLAG_VM) && (cpu.cpl==0)) {
// commit point
reg_esp=tempesp;
reg_eip=n_eip & 0xffff; reg_eip=n_eip & 0xffff;
Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs; Bitu n_ss,n_esp,n_es,n_ds,n_fs,n_gs;
n_esp=CPU_Pop32(); n_esp=CPU_Pop32();
@ -746,9 +862,14 @@ void CPU_IRET(bool use32,Bitu oldeip) {
} }
if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0"); if (n_flags & FLAG_VM) E_Exit("IRET from pmode to v86 with CPL!=0");
} else { } else {
n_eip=CPU_Pop16(); n_eip=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
n_cs_sel=CPU_Pop16(); tempesp=(reg_esp&cpu.stack.notmask)|((reg_esp+2)&cpu.stack.mask);
n_flags=(reg_flags & 0xffff0000) | CPU_Pop16(); n_cs_sel=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask);
n_flags=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
n_flags|=(reg_flags & 0xffff0000);
tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask);
if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret"); if (n_flags & FLAG_VM) E_Exit("VM Flag in 16-bit iret");
} }
CPU_CHECK_COND((n_cs_sel & 0xfffc)==0, CPU_CHECK_COND((n_cs_sel & 0xfffc)==0,
@ -785,6 +906,9 @@ void CPU_IRET(bool use32,Bitu oldeip) {
if (n_cs_rpl==cpu.cpl) { if (n_cs_rpl==cpu.cpl) {
/* Return to same level */ /* Return to same level */
// commit point
reg_esp=tempesp;
Segs.phys[cs]=n_cs_desc.GetBase(); Segs.phys[cs]=n_cs_desc.GetBase();
cpu.code.big=n_cs_desc.Big()>0; cpu.code.big=n_cs_desc.Big()>0;
Segs.val[cs]=n_cs_sel; Segs.val[cs]=n_cs_sel;
@ -799,11 +923,13 @@ void CPU_IRET(bool use32,Bitu oldeip) {
/* Return to outer level */ /* Return to outer level */
Bitu n_ss,n_esp; Bitu n_ss,n_esp;
if (use32) { if (use32) {
n_esp=CPU_Pop32(); n_esp=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask));
n_ss=CPU_Pop32() & 0xffff; tempesp=(tempesp&cpu.stack.notmask)|((tempesp+4)&cpu.stack.mask);
n_ss=mem_readd(SegPhys(ss) + (tempesp & cpu.stack.mask)) & 0xffff;
} else { } else {
n_esp=CPU_Pop16(); n_esp=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
n_ss=CPU_Pop16(); tempesp=(tempesp&cpu.stack.notmask)|((tempesp+2)&cpu.stack.mask);
n_ss=mem_readw(SegPhys(ss) + (tempesp & cpu.stack.mask));
} }
CPU_CHECK_COND((n_ss & 0xfffc)==0, CPU_CHECK_COND((n_ss & 0xfffc)==0,
"IRET:Outer level:SS selector zero", "IRET:Outer level:SS selector zero",
@ -831,6 +957,8 @@ void CPU_IRET(bool use32,Bitu oldeip) {
"IRET:Outer level:Stack segment not present", "IRET:Outer level:Stack segment not present",
EXCEPTION_NP,n_ss & 0xfffc) EXCEPTION_NP,n_ss & 0xfffc)
// commit point
Segs.phys[cs]=n_cs_desc.GetBase(); Segs.phys[cs]=n_cs_desc.GetBase();
cpu.code.big=n_cs_desc.Big()>0; cpu.code.big=n_cs_desc.Big()>0;
Segs.val[cs]=n_cs_sel; Segs.val[cs]=n_cs_sel;
@ -858,35 +986,7 @@ void CPU_IRET(bool use32,Bitu oldeip) {
} }
// borland extender, zrdx // borland extender, zrdx
Descriptor desc; CPU_CheckSegments();
cpu.gdt.GetDescriptor(SegValue(es),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(ds),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(fs),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(gs),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break;
default: break; }
LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big); LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big);
} }
@ -980,8 +1080,8 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip) {
CPU_CHECK_COND((selector & 0xfffc)==0, CPU_CHECK_COND((selector & 0xfffc)==0,
"CALL:CS selector zero", "CALL:CS selector zero",
EXCEPTION_GP,0) EXCEPTION_GP,0)
Descriptor call;
Bitu rpl=selector & 3; Bitu rpl=selector & 3;
Descriptor call;
CPU_CHECK_COND(!cpu.gdt.GetDescriptor(selector,call), CPU_CHECK_COND(!cpu.gdt.GetDescriptor(selector,call),
"CALL:CS beyond limits", "CALL:CS beyond limits",
EXCEPTION_GP,selector & 0xfffc) EXCEPTION_GP,selector & 0xfffc)
@ -1048,16 +1148,17 @@ call_code:
CPU_CHECK_COND(n_cs_dpl>cpu.cpl, CPU_CHECK_COND(n_cs_dpl>cpu.cpl,
"CALL:Gate:CS DPL>CPL", "CALL:Gate:CS DPL>CPL",
EXCEPTION_GP,n_cs_sel & 0xfffc) EXCEPTION_GP,n_cs_sel & 0xfffc)
Bitu n_cs_rpl = n_cs_sel & 3;
CPU_CHECK_COND(!n_cs_desc.saved.seg.p,
"CALL:Gate:CS not present",
EXCEPTION_NP,n_cs_sel & 0xfffc)
Bitu n_eip = call.GetOffset(); Bitu n_eip = call.GetOffset();
switch (n_cs_desc.Type()) { switch (n_cs_desc.Type()) {
case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA: case DESC_CODE_N_NC_A:case DESC_CODE_N_NC_NA:
case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA: case DESC_CODE_R_NC_A:case DESC_CODE_R_NC_NA:
/* Check if we goto inner priviledge */ /* Check if we goto inner priviledge */
if (n_cs_dpl < cpu.cpl) { if (n_cs_dpl < cpu.cpl) {
CPU_CHECK_COND(!n_cs_desc.saved.seg.p,
"CALL:Gate:CS not present",
EXCEPTION_NP,n_cs_sel & 0xfffc)
/* Get new SS:ESP out of TSS */ /* Get new SS:ESP out of TSS */
Bitu n_ss_sel,n_esp; Bitu n_ss_sel,n_esp;
Descriptor n_ss_desc; Descriptor n_ss_desc;
@ -1089,6 +1190,7 @@ call_code:
Bitu o_ss = SegValue(ss); Bitu o_ss = SegValue(ss);
PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask); PhysPt o_stack = SegPhys(ss)+(reg_esp & cpu.stack.mask);
// catch pagefaults // catch pagefaults
if (call.saved.gate.paramcount&31) { if (call.saved.gate.paramcount&31) {
if (call.Type()==DESC_386_CALL_GATE) { if (call.Type()==DESC_386_CALL_GATE) {
@ -1172,10 +1274,15 @@ call_code:
case DESC_386_TSS_A: case DESC_386_TSS_A:
CPU_CHECK_COND(call.DPL()<cpu.cpl, CPU_CHECK_COND(call.DPL()<cpu.cpl,
"CALL:TSS:dpl<cpl", "CALL:TSS:dpl<cpl",
EXCEPTION_TS,selector & 0xfffc) EXCEPTION_GP,selector & 0xfffc)
CPU_CHECK_COND(call.DPL()<rpl, CPU_CHECK_COND(call.DPL()<rpl,
"CALL:TSS:dpl<rpl", "CALL:TSS:dpl<rpl",
EXCEPTION_GP,selector & 0xfffc) EXCEPTION_GP,selector & 0xfffc)
CPU_CHECK_COND(!call.saved.seg.p,
"CALL:TSS:Segment not present",
EXCEPTION_NP,selector & 0xfffc)
LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector); LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector);
CPU_SwitchTask(selector,TSwitch_CALL_INT,oldeip); CPU_SwitchTask(selector,TSwitch_CALL_INT,oldeip);
break; break;
@ -1353,35 +1460,7 @@ RET_same_level:
reg_sp=(n_esp & 0xffff)+bytes; reg_sp=(n_esp & 0xffff)+bytes;
} }
Descriptor desc; CPU_CheckSegments();
cpu.gdt.GetDescriptor(SegValue(es),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(es,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(ds),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(ds,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(fs),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(fs,0); break;
default: break; }
cpu.gdt.GetDescriptor(SegValue(gs),desc);
switch (desc.Type()) {
case DESC_DATA_EU_RO_NA: case DESC_DATA_EU_RO_A: case DESC_DATA_EU_RW_NA: case DESC_DATA_EU_RW_A:
case DESC_DATA_ED_RO_NA: case DESC_DATA_ED_RO_A: case DESC_DATA_ED_RW_NA: case DESC_DATA_ED_RW_A:
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA: case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
if (cpu.cpl>desc.DPL()) CPU_SetSegGeneral(gs,0); break;
default: break; }
// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL()); // LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL());
return; return;
@ -1523,6 +1602,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value) {
/* Check if privileged to access control registers */ /* Check if privileged to access control registers */
if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0); if (cpu.pmode && (cpu.cpl>0)) return CPU_PrepareException(EXCEPTION_GP,0);
if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0); if ((cr==1) || (cr>4)) return CPU_PrepareException(EXCEPTION_UD,0);
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) {
if (cr==4) return CPU_PrepareException(EXCEPTION_UD,0);
}
CPU_SET_CRX(cr,value); CPU_SET_CRX(cr,value);
return false; return false;
} }
@ -1530,7 +1612,9 @@ bool CPU_WRITE_CRX(Bitu cr,Bitu value) {
Bitu CPU_GET_CRX(Bitu cr) { Bitu CPU_GET_CRX(Bitu cr) {
switch (cr) { switch (cr) {
case 0: case 0:
return cpu.cr0; if (CPU_ArchitectureType>=CPU_ARCHTYPE_PENTIUMSLOW) return cpu.cr0;
else if (CPU_ArchitectureType>=CPU_ARCHTYPE_486OLDSLOW) return (cpu.cr0 & 0xe005003f);
else return (cpu.cr0 | 0x7ffffff0);
case 2: case 2:
return paging.cr2; return paging.cr2;
case 3: case 3:
@ -1567,7 +1651,11 @@ bool CPU_WRITE_DRX(Bitu dr,Bitu value) {
break; break;
case 5: case 5:
case 7: case 7:
cpu.drx[7]=(value|0x400) & 0xffff2fff; if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) {
cpu.drx[7]=(value|0x400) & 0xffff2fff;
} else {
cpu.drx[7]=(value|0x400);
}
break; break;
default: default:
LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV DR%d,%X",dr,value); LOG(LOG_CPU,LOG_ERROR)("Unhandled MOV DR%d,%X",dr,value);
@ -1915,7 +2003,8 @@ bool CPU_PopSeg(SegNames seg,bool use32) {
return false; return false;
} }
void CPU_CPUID(void) { bool CPU_CPUID(void) {
if (CPU_ArchitectureType<CPU_ARCHTYPE_486NEWSLOW) return false;
switch (reg_eax) { switch (reg_eax) {
case 0: /* Vendor ID String and maximum level? */ case 0: /* Vendor ID String and maximum level? */
reg_eax=1; /* Maximum level */ reg_eax=1; /* Maximum level */
@ -1924,15 +2013,30 @@ void CPU_CPUID(void) {
reg_ecx='n' | ('t' << 8) | ('e' << 16) | ('l'<< 24); reg_ecx='n' | ('t' << 8) | ('e' << 16) | ('l'<< 24);
break; break;
case 1: /* get processor type/family/model/stepping and feature flags */ case 1: /* get processor type/family/model/stepping and feature flags */
reg_eax=0x402; /* intel 486 sx? */ if ((CPU_ArchitectureType==CPU_ARCHTYPE_486NEWSLOW) ||
reg_ebx=0; /* Not Supported */ (CPU_ArchitectureType==CPU_ARCHTYPE_MIXED)) {
reg_ecx=0; /* No features */ reg_eax=0x402; /* intel 486dx */
reg_edx=1; /* FPU */ reg_ebx=0; /* Not Supported */
reg_ecx=0; /* No features */
reg_edx=0x00000001; /* FPU */
} else if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) {
reg_eax=0x513; /* intel pentium */
reg_ebx=0; /* Not Supported */
reg_ecx=0; /* No features */
reg_edx=0x00000011; /* FPU+TimeStamp/RDTSC */
} else {
return false;
}
break; break;
default: default:
LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax); LOG(LOG_CPU,LOG_ERROR)("Unhandled CPUID Function %x",reg_eax);
reg_eax=0;
reg_ebx=0;
reg_ecx=0;
reg_edx=0;
break; break;
} }
return true;
} }
static Bits HLT_Decode(void) { static Bits HLT_Decode(void) {
@ -2029,6 +2133,29 @@ static void CPU_CycleDecrease(bool pressed) {
} }
} }
void CPU_Enable_SkipAutoAdjust(void) {
if (CPU_CycleAutoAdjust) {
CPU_CycleMax /= 2;
if (CPU_CycleMax < CPU_CYCLES_LOWER_LIMIT)
CPU_CycleMax = CPU_CYCLES_LOWER_LIMIT;
}
CPU_SkipCycleAutoAdjust=true;
}
void CPU_Disable_SkipAutoAdjust(void) {
CPU_SkipCycleAutoAdjust=false;
}
extern Bit32s ticksDone;
extern Bit32u ticksScheduled;
void CPU_Reset_AutoAdjust(void) {
CPU_IODelayRemoved = 0;
ticksDone = 0;
ticksScheduled = 0;
}
class CPU: public Module_base { class CPU: public Module_base {
private: private:
static bool inited; static bool inited;
@ -2038,8 +2165,8 @@ public:
Change_Config(configuration); Change_Config(configuration);
return; return;
} }
// Section_prop * section=static_cast<Section_prop *>(configuration);
inited=true; inited=true;
Section_prop * section=static_cast<Section_prop *>(configuration);
reg_eax=0; reg_eax=0;
reg_ebx=0; reg_ebx=0;
reg_ecx=0; reg_ecx=0;
@ -2071,7 +2198,11 @@ public:
cpu.drx[i]=0; cpu.drx[i]=0;
cpu.trx[i]=0; cpu.trx[i]=0;
} }
cpu.drx[6]=0xffff1ff0; if (CPU_ArchitectureType==CPU_ARCHTYPE_PENTIUMSLOW) {
cpu.drx[6]=0xffff0ff0;
} else {
cpu.drx[6]=0xffff1ff0;
}
cpu.drx[7]=0x00000400; cpu.drx[7]=0x00000400;
/* Init the cpu cores */ /* Init the cpu cores */
@ -2093,17 +2224,18 @@ public:
CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE; CPU_AutoDetermineMode=CPU_AUTODETERMINE_NONE;
CPU_CycleLeft=0;//needed ? CPU_CycleLeft=0;//needed ?
CPU_Cycles=0; CPU_Cycles=0;
CPU_SkipCycleAutoAdjust=false;
std::string str; Prop_multival* p = section->Get_multival("cycles");
CommandLine cmd(0,section->Get_string("cycles")); std::string type = p->GetSection()->Get_string("type");
cmd.FindCommand(1,str); std::string str ;
CommandLine cmd(0,p->GetSection()->Get_string("parameters"));
if (str=="max") { if (type=="max") {
CPU_CycleMax=0; CPU_CycleMax=0;
CPU_CyclePercUsed=100; CPU_CyclePercUsed=100;
CPU_CycleAutoAdjust=true; CPU_CycleAutoAdjust=true;
CPU_CycleLimit=-1; CPU_CycleLimit=-1;
for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { for (Bitu cmdnum=1; cmdnum<=cmd.GetCount(); cmdnum++) {
if (cmd.FindCommand(cmdnum,str)) { if (cmd.FindCommand(cmdnum,str)) {
if (str.find('%')==str.length()-1) { if (str.find('%')==str.length()-1) {
str.erase(str.find('%')); str.erase(str.find('%'));
@ -2123,12 +2255,12 @@ public:
} }
} }
} else { } else {
if (str=="auto") { if (type=="auto") {
CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CYCLES;
CPU_CycleMax=3000; CPU_CycleMax=3000;
CPU_OldCycleMax=3000; CPU_OldCycleMax=3000;
CPU_CyclePercUsed=100; CPU_CyclePercUsed=100;
for (Bitu cmdnum=2; cmdnum<=cmd.GetCount(); cmdnum++) { for (Bitu cmdnum=0; cmdnum<=cmd.GetCount(); cmdnum++) {
if (cmd.FindCommand(cmdnum,str)) { if (cmd.FindCommand(cmdnum,str)) {
if (str.find('%')==str.length()-1) { if (str.find('%')==str.length()-1) {
str.erase(str.find('%')); str.erase(str.find('%'));
@ -2155,54 +2287,100 @@ public:
} }
} }
} }
} else { } else if(type =="fixed") {
cmd.FindCommand(1,str);
int rmdval=0; int rmdval=0;
std::istringstream stream(str); std::istringstream stream(str);
stream >> rmdval; stream >> rmdval;
CPU_CycleMax=(Bit32s)rmdval; CPU_CycleMax=(Bit32s)rmdval;
} else {
std::istringstream stream(type);
int rmdval=0;
stream >> rmdval;
if(rmdval) CPU_CycleMax=(Bit32s)rmdval;
} }
CPU_CycleAutoAdjust=false; CPU_CycleAutoAdjust=false;
} }
CPU_CycleUp=section->Get_int("cycleup"); CPU_CycleUp=section->Get_int("cycleup");
CPU_CycleDown=section->Get_int("cycledown"); CPU_CycleDown=section->Get_int("cycledown");
const char * core=section->Get_string("core"); std::string core(section->Get_string("core"));
cpudecoder=&CPU_Core_Normal_Run; cpudecoder=&CPU_Core_Normal_Run;
if (!strcasecmp(core,"normal")) { if (core == "normal") {
cpudecoder=&CPU_Core_Normal_Run; cpudecoder=&CPU_Core_Normal_Run;
} else if (!strcasecmp(core,"simple")) { } else if (core =="simple") {
cpudecoder=&CPU_Core_Simple_Run; cpudecoder=&CPU_Core_Simple_Run;
} else if (!strcasecmp(core,"full")) { } else if (core == "full") {
cpudecoder=&CPU_Core_Full_Run; cpudecoder=&CPU_Core_Full_Run;
} } else if (core == "auto") {
cpudecoder=&CPU_Core_Normal_Run;
#if (C_DYNAMIC_X86) #if (C_DYNAMIC_X86)
else if (!strcasecmp(core,"dynamic")) { CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE;
}
else if (core == "dynamic") {
cpudecoder=&CPU_Core_Dyn_X86_Run; cpudecoder=&CPU_Core_Dyn_X86_Run;
CPU_Core_Dyn_X86_SetFPUMode(true); CPU_Core_Dyn_X86_SetFPUMode(true);
} else if (!strcasecmp(core,"dynamic_nodhfpu")) { } else if (core == "dynamic_nodhfpu") {
cpudecoder=&CPU_Core_Dyn_X86_Run; cpudecoder=&CPU_Core_Dyn_X86_Run;
CPU_Core_Dyn_X86_SetFPUMode(false); CPU_Core_Dyn_X86_SetFPUMode(false);
} else if (!strcasecmp(core,"auto")) {
cpudecoder=&CPU_Core_Normal_Run;
CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE;
}
#elif (C_DYNREC) #elif (C_DYNREC)
else if (!strcasecmp(core,"dynamic")) {
cpudecoder=&CPU_Core_Dynrec_Run;
} else if (!strcasecmp(core,"auto")) {
cpudecoder=&CPU_Core_Normal_Run;
CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE; CPU_AutoDetermineMode|=CPU_AUTODETERMINE_CORE;
} }
else if (core == "dynamic") {
cpudecoder=&CPU_Core_Dynrec_Run;
#else
#endif #endif
else {
LOG_MSG("CPU:Unknown core type %s, switching back to normal.",core);
} }
#if (C_DYNAMIC_X86) #if (C_DYNAMIC_X86)
CPU_Core_Dyn_X86_Cache_Init(!strcasecmp(core,"dynamic") || !strcasecmp(core,"dynamic_nodhfpu")); CPU_Core_Dyn_X86_Cache_Init((core == "dynamic") || (core == "dynamic_nodhfpu"));
#elif (C_DYNREC) #elif (C_DYNREC)
CPU_Core_Dynrec_Cache_Init(!strcasecmp(core,"dynamic")); CPU_Core_Dynrec_Cache_Init( core == "dynamic" );
#endif #endif
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
std::string cputype(section->Get_string("cputype"));
if (cputype == "auto") {
CPU_ArchitectureType = CPU_ARCHTYPE_MIXED;
} else if (cputype == "386") {
CPU_ArchitectureType = CPU_ARCHTYPE_386FAST;
} else if (cputype == "386_prefetch") {
CPU_ArchitectureType = CPU_ARCHTYPE_386FAST;
if (core == "normal") {
cpudecoder=&CPU_Core_Prefetch_Run;
CPU_PrefetchQueueSize = 16;
} else if (core == "auto") {
cpudecoder=&CPU_Core_Prefetch_Run;
CPU_PrefetchQueueSize = 16;
CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE);
} else {
E_Exit("prefetch queue emulation requires the normal core setting.");
}
} else if (cputype == "386_slow") {
CPU_ArchitectureType = CPU_ARCHTYPE_386SLOW;
} else if (cputype == "486_slow") {
CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW;
} else if (cputype == "486_prefetch") {
CPU_ArchitectureType = CPU_ARCHTYPE_486NEWSLOW;
if (core == "normal") {
cpudecoder=&CPU_Core_Prefetch_Run;
CPU_PrefetchQueueSize = 32;
} else if (core == "auto") {
cpudecoder=&CPU_Core_Prefetch_Run;
CPU_PrefetchQueueSize = 32;
CPU_AutoDetermineMode&=(~CPU_AUTODETERMINE_CORE);
} else {
E_Exit("prefetch queue emulation requires the normal core setting.");
}
} else if (cputype == "pentium_slow") {
CPU_ArchitectureType = CPU_ARCHTYPE_PENTIUMSLOW;
}
if (CPU_ArchitectureType>=CPU_ARCHTYPE_486NEWSLOW) CPU_flag_id_toggle=FLAG_ID;
else CPU_flag_id_toggle=0;
if(CPU_CycleMax <= 0) CPU_CycleMax = 3000; if(CPU_CycleMax <= 0) CPU_CycleMax = 3000;
if(CPU_CycleUp <= 0) CPU_CycleUp = 500; if(CPU_CycleUp <= 0) CPU_CycleUp = 500;
if(CPU_CycleDown <= 0) CPU_CycleDown = 20; if(CPU_CycleDown <= 0) CPU_CycleDown = 20;

View File

@ -277,7 +277,7 @@
#define RORB(op1,op2,load,save) \ #define RORB(op1,op2,load,save) \
if (!(op2&0x7)) { \ if (!(op2&0x7)) { \
if (op2&0x10) { \ if (op2&0x18) { \
FillFlagsNoCFOF(); \ FillFlagsNoCFOF(); \
SETFLAGBIT(CF,op1>>7); \ SETFLAGBIT(CF,op1>>7); \
SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \ SETFLAGBIT(OF,(op1>>7) ^ ((op1>>6) & 1)); \

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2002-2007 The DOSBox Team * Copyright (C) 2002-2008 The DOSBox Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
/* $Id: paging.cpp,v 1.35 2008/12/04 21:09:32 c2woody Exp $ */
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -31,9 +33,11 @@
#define LINK_TOTAL (64*1024) #define LINK_TOTAL (64*1024)
PagingBlock paging; #define USERWRITE_PROHIBITED ((cpu.cpl&cpu.mpl)==3)
PagingBlock paging;
Bitu PageHandler::readb(PhysPt addr) { Bitu PageHandler::readb(PhysPt addr) {
E_Exit("No byte handler for read from %d",addr); E_Exit("No byte handler for read from %d",addr);
@ -54,7 +58,7 @@ Bitu PageHandler::readd(PhysPt addr) {
void PageHandler::writeb(PhysPt addr,Bitu /*val*/) { void PageHandler::writeb(PhysPt addr,Bitu /*val*/) {
E_Exit("No byte handler for write to %d",addr); E_Exit("No byte handler for write to %d",addr);
}; }
void PageHandler::writew(PhysPt addr,Bitu val) { void PageHandler::writew(PhysPt addr,Bitu val) {
writeb(addr+0,(Bit8u) (val >> 0)); writeb(addr+0,(Bit8u) (val >> 0));
@ -65,7 +69,7 @@ void PageHandler::writed(PhysPt addr,Bitu val) {
writeb(addr+1,(Bit8u) (val >> 8)); writeb(addr+1,(Bit8u) (val >> 8));
writeb(addr+2,(Bit8u) (val >> 16)); writeb(addr+2,(Bit8u) (val >> 16));
writeb(addr+3,(Bit8u) (val >> 24)); writeb(addr+3,(Bit8u) (val >> 24));
}; }
HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) { HostPt PageHandler::GetHostReadPt(Bitu /*phys_page*/) {
return 0; return 0;
@ -75,14 +79,14 @@ HostPt PageHandler::GetHostWritePt(Bitu /*phys_page*/) {
return 0; return 0;
} }
bool PageHandler::readb_checked(PhysPt addr, Bitu * val) { bool PageHandler::readb_checked(PhysPt addr, Bit8u * val) {
*val=readb(addr); return false; *val=(Bit8u)readb(addr); return false;
} }
bool PageHandler::readw_checked(PhysPt addr, Bitu * val) { bool PageHandler::readw_checked(PhysPt addr, Bit16u * val) {
*val=readw(addr); return false; *val=(Bit16u)readw(addr); return false;
} }
bool PageHandler::readd_checked(PhysPt addr, Bitu * val) { bool PageHandler::readd_checked(PhysPt addr, Bit32u * val) {
*val=readd(addr); return false; *val=(Bit32u)readd(addr); return false;
} }
bool PageHandler::writeb_checked(PhysPt addr,Bitu val) { bool PageHandler::writeb_checked(PhysPt addr,Bitu val) {
writeb(addr,val); return false; writeb(addr,val); return false;
@ -100,6 +104,7 @@ struct PF_Entry {
Bitu cs; Bitu cs;
Bitu eip; Bitu eip;
Bitu page_addr; Bitu page_addr;
Bitu mpl;
}; };
#define PF_QUEUESIZE 16 #define PF_QUEUESIZE 16
@ -120,8 +125,10 @@ static Bits PageFaultCore(void) {
PF_Entry * entry=&pf_queue.entries[pf_queue.used-1]; PF_Entry * entry=&pf_queue.entries[pf_queue.used-1];
X86PageEntry pentry; X86PageEntry pentry;
pentry.load=phys_readd(entry->page_addr); pentry.load=phys_readd(entry->page_addr);
if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip) {
cpu.mpl=entry->mpl;
return -1; return -1;
}
return 0; return 0;
} }
#if C_DEBUG #if C_DEBUG
@ -130,7 +137,7 @@ Bitu DEBUG_EnableDebugger(void);
bool first=false; bool first=false;
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultcode) { void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu faultcode) {
/* Save the state of the cpu cores */ /* Save the state of the cpu cores */
LazyFlags old_lflags; LazyFlags old_lflags;
memcpy(&old_lflags,&lflags,sizeof(LazyFlags)); memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
@ -139,14 +146,16 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultc
cpudecoder=&PageFaultCore; cpudecoder=&PageFaultCore;
paging.cr2=lin_addr; paging.cr2=lin_addr;
PF_Entry * entry=&pf_queue.entries[pf_queue.used++]; PF_Entry * entry=&pf_queue.entries[pf_queue.used++];
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x:%x] queue %d",lin_addr,writefault,faultcode,pf_queue.used); LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type [%x] queue %d",lin_addr,faultcode,pf_queue.used);
// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx); // LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx);
// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp); // LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp);
entry->cs=SegValue(cs); entry->cs=SegValue(cs);
entry->eip=reg_eip; entry->eip=reg_eip;
entry->page_addr=page_addr; entry->page_addr=page_addr;
//Caused by a write by default? entry->mpl=cpu.mpl;
CPU_Exception(14,(writefault?0x02:0x00) | faultcode); cpu.mpl=3;
CPU_Exception(EXCEPTION_PF,faultcode);
#if C_DEBUG #if C_DEBUG
// DEBUG_EnableDebugger(); // DEBUG_EnableDebugger();
#endif #endif
@ -158,128 +167,433 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,bool writefault,Bitu faultc
// LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp); // LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp);
} }
static INLINE void InitPageUpdateLink(Bitu relink,PhysPt addr) {
if (relink==0) return;
if (paging.links.used) {
if (paging.links.entries[paging.links.used-1]==(addr>>12)) {
paging.links.used--;
PAGING_UnlinkPages(addr>>12,1);
}
}
if (relink>1) PAGING_LinkPage_ReadOnly(addr>>12,relink);
}
static INLINE void InitPageCheckPresence(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) {
Bitu lin_page=lin_addr >> 12;
Bitu d_index=lin_page >> 10;
Bitu t_index=lin_page & 0x3ff;
Bitu table_addr=(paging.base.page<<12)+d_index*4;
table.load=phys_readd(table_addr);
if (!table.block.p) {
LOG(LOG_PAGING,LOG_NORMAL)("NP Table");
PAGING_PageFault(lin_addr,table_addr,
(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04));
table.load=phys_readd(table_addr);
if (GCC_UNLIKELY(!table.block.p))
E_Exit("Pagefault didn't correct table");
}
Bitu entry_addr=(table.block.base<<12)+t_index*4;
entry.load=phys_readd(entry_addr);
if (!entry.block.p) {
// LOG(LOG_PAGING,LOG_NORMAL)("NP Page");
PAGING_PageFault(lin_addr,entry_addr,
(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04));
entry.load=phys_readd(entry_addr);
if (GCC_UNLIKELY(!entry.block.p))
E_Exit("Pagefault didn't correct page");
}
}
static INLINE bool InitPageCheckPresence_CheckOnly(PhysPt lin_addr,bool writing,X86PageEntry& table,X86PageEntry& entry) {
Bitu lin_page=lin_addr >> 12;
Bitu d_index=lin_page >> 10;
Bitu t_index=lin_page & 0x3ff;
Bitu table_addr=(paging.base.page<<12)+d_index*4;
table.load=phys_readd(table_addr);
if (!table.block.p) {
paging.cr2=lin_addr;
cpu.exception.which=EXCEPTION_PF;
cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04);
return false;
}
Bitu entry_addr=(table.block.base<<12)+t_index*4;
entry.load=phys_readd(entry_addr);
if (!entry.block.p) {
paging.cr2=lin_addr;
cpu.exception.which=EXCEPTION_PF;
cpu.exception.error=(writing?0x02:0x00) | (((cpu.cpl&cpu.mpl)==0)?0x00:0x04);
return false;
}
return true;
}
// check if a user-level memory access would trigger a privilege page fault
static INLINE bool InitPage_CheckUseraccess(Bitu u1,Bitu u2) {
switch (CPU_ArchitectureType) {
case CPU_ARCHTYPE_MIXED:
case CPU_ARCHTYPE_386SLOW:
case CPU_ARCHTYPE_386FAST:
default:
return ((u1)==0) && ((u2)==0);
case CPU_ARCHTYPE_486OLDSLOW:
case CPU_ARCHTYPE_486NEWSLOW:
case CPU_ARCHTYPE_PENTIUMSLOW:
return ((u1)==0) || ((u2)==0);
}
}
class InitPageHandler : public PageHandler { class InitPageHandler : public PageHandler {
public: public:
InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;} InitPageHandler() {
flags=PFLAG_INIT|PFLAG_NOCODE;
}
Bitu readb(PhysPt addr) { Bitu readb(PhysPt addr) {
InitPage(addr,false); Bitu needs_reset=InitPage(addr,false);
return mem_readb(addr); Bit8u val=mem_readb(addr);
InitPageUpdateLink(needs_reset,addr);
return val;
} }
Bitu readw(PhysPt addr) { Bitu readw(PhysPt addr) {
InitPage(addr,false); Bitu needs_reset=InitPage(addr,false);
return mem_readw(addr); Bit16u val=mem_readw(addr);
InitPageUpdateLink(needs_reset,addr);
return val;
} }
Bitu readd(PhysPt addr) { Bitu readd(PhysPt addr) {
InitPage(addr,false); Bitu needs_reset=InitPage(addr,false);
return mem_readd(addr); Bit32u val=mem_readd(addr);
InitPageUpdateLink(needs_reset,addr);
return val;
} }
void writeb(PhysPt addr,Bitu val) { void writeb(PhysPt addr,Bitu val) {
InitPage(addr,true); Bitu needs_reset=InitPage(addr,true);
mem_writeb(addr,val); mem_writeb(addr,val);
InitPageUpdateLink(needs_reset,addr);
} }
void writew(PhysPt addr,Bitu val) { void writew(PhysPt addr,Bitu val) {
InitPage(addr,true); Bitu needs_reset=InitPage(addr,true);
mem_writew(addr,val); mem_writew(addr,val);
InitPageUpdateLink(needs_reset,addr);
} }
void writed(PhysPt addr,Bitu val) { void writed(PhysPt addr,Bitu val) {
InitPage(addr,true); Bitu needs_reset=InitPage(addr,true);
mem_writed(addr,val); mem_writed(addr,val);
InitPageUpdateLink(needs_reset,addr);
} }
bool readb_checked(PhysPt addr, Bitu * val) { bool readb_checked(PhysPt addr, Bit8u * val) {
if (InitPage(addr,false,true)) { if (InitPageCheckOnly(addr,false)) {
*val=mem_readb(addr); *val=mem_readb(addr);
return false; return false;
} else return true; } else return true;
} }
bool readw_checked(PhysPt addr, Bitu * val) { bool readw_checked(PhysPt addr, Bit16u * val) {
if (InitPage(addr,false,true)){ if (InitPageCheckOnly(addr,false)){
*val=mem_readw(addr); *val=mem_readw(addr);
return false; return false;
} else return true; } else return true;
} }
bool readd_checked(PhysPt addr, Bitu * val) { bool readd_checked(PhysPt addr, Bit32u * val) {
if (InitPage(addr,false,true)) { if (InitPageCheckOnly(addr,false)) {
*val=mem_readd(addr); *val=mem_readd(addr);
return false; return false;
} else return true; } else return true;
} }
bool writeb_checked(PhysPt addr,Bitu val) { bool writeb_checked(PhysPt addr,Bitu val) {
if (InitPage(addr,true,true)) { if (InitPageCheckOnly(addr,true)) {
mem_writeb(addr,val); mem_writeb(addr,val);
return false; return false;
} else return true; } else return true;
} }
bool writew_checked(PhysPt addr,Bitu val) { bool writew_checked(PhysPt addr,Bitu val) {
if (InitPage(addr,true,true)) { if (InitPageCheckOnly(addr,true)) {
mem_writew(addr,val); mem_writew(addr,val);
return false; return false;
} else return true; } else return true;
} }
bool writed_checked(PhysPt addr,Bitu val) { bool writed_checked(PhysPt addr,Bitu val) {
if (InitPage(addr,true,true)) { if (InitPageCheckOnly(addr,true)) {
mem_writed(addr,val); mem_writed(addr,val);
return false; return false;
} else return true; } else return true;
} }
bool InitPage(Bitu lin_addr,bool writing,bool check_only=false) { Bitu InitPage(Bitu lin_addr,bool writing) {
Bitu lin_page=lin_addr >> 12; Bitu lin_page=lin_addr >> 12;
Bitu phys_page; Bitu phys_page;
if (paging.enabled) { if (paging.enabled) {
Bitu d_index=lin_page >> 10;
Bitu t_index=lin_page & 0x3ff;
Bitu table_addr=(paging.base.page<<12)+d_index*4;
X86PageEntry table; X86PageEntry table;
table.load=phys_readd(table_addr); X86PageEntry entry;
if (!table.block.p) { InitPageCheckPresence(lin_addr,writing,table,entry);
if (check_only) {
paging.cr2=lin_addr; // 0: no action
cpu.exception.which=14; // 1: can (but currently does not) fail a user-level access privilege check
cpu.exception.error=writing?0x02:0x00; // 2: can (but currently does not) fail a write privilege check
return false; // 3: fails a privilege check
Bitu priv_check=0;
if (InitPage_CheckUseraccess(entry.block.us,table.block.us)) {
if ((cpu.cpl&cpu.mpl)==3) priv_check=3;
else {
switch (CPU_ArchitectureType) {
case CPU_ARCHTYPE_MIXED:
case CPU_ARCHTYPE_386FAST:
default:
// priv_check=0; // default
break;
case CPU_ARCHTYPE_386SLOW:
case CPU_ARCHTYPE_486OLDSLOW:
case CPU_ARCHTYPE_486NEWSLOW:
case CPU_ARCHTYPE_PENTIUMSLOW:
priv_check=1;
break;
}
} }
LOG(LOG_PAGING,LOG_NORMAL)("NP Table");
PAGING_PageFault(lin_addr,table_addr,false,writing?0x02:0x00);
table.load=phys_readd(table_addr);
if (!table.block.p)
E_Exit("Pagefault didn't correct table");
} }
if ((entry.block.wr==0) || (table.block.wr==0)) {
// page is write-protected for user mode
if (priv_check==0) {
switch (CPU_ArchitectureType) {
case CPU_ARCHTYPE_MIXED:
case CPU_ARCHTYPE_386FAST:
default:
// priv_check=0; // default
break;
case CPU_ARCHTYPE_386SLOW:
case CPU_ARCHTYPE_486OLDSLOW:
case CPU_ARCHTYPE_486NEWSLOW:
case CPU_ARCHTYPE_PENTIUMSLOW:
priv_check=2;
break;
}
}
// check if actually failing the write-protected check
if (writing && USERWRITE_PROHIBITED) priv_check=3;
}
if (priv_check==3) {
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x05 | (writing?0x02:0x00));
priv_check=0;
}
if (!table.block.a) {
table.block.a=1; // set page table accessed
phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load);
}
if ((!entry.block.a) || (!entry.block.d)) {
entry.block.a=1; // set page accessed
// page is dirty if we're writing to it, or if we're reading but the
// page will be fully linked so we can't track later writes
if (writing || (priv_check==0)) entry.block.d=1; // mark page as dirty
phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load);
}
phys_page=entry.block.base;
// now see how the page should be linked best, if we need to catch privilege
// checks later on it should be linked as read-only page
if (priv_check==0) {
// if reading we could link the page as read-only to later cacth writes,
// will slow down pretty much but allows catching all dirty events
PAGING_LinkPage(lin_page,phys_page);
} else {
if (priv_check==1) {
PAGING_LinkPage(lin_page,phys_page);
return 1;
} else if (writing) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
PAGING_LinkPage(lin_page,phys_page);
if (!(handler->flags & PFLAG_READABLE)) return 1;
if (!(handler->flags & PFLAG_WRITEABLE)) return 1;
if (get_tlb_read(lin_addr)!=get_tlb_write(lin_addr)) return 1;
if (phys_page>1) return phys_page;
else return 1;
} else {
PAGING_LinkPage_ReadOnly(lin_page,phys_page);
}
}
} else {
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
else phys_page=lin_page;
PAGING_LinkPage(lin_page,phys_page);
}
return 0;
}
bool InitPageCheckOnly(Bitu lin_addr,bool writing) {
Bitu lin_page=lin_addr >> 12;
if (paging.enabled) {
X86PageEntry table;
X86PageEntry entry;
if (!InitPageCheckPresence_CheckOnly(lin_addr,writing,table,entry)) return false;
if (!USERWRITE_PROHIBITED) return true;
if (InitPage_CheckUseraccess(entry.block.us,table.block.us) ||
(((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
paging.cr2=lin_addr;
cpu.exception.which=EXCEPTION_PF;
cpu.exception.error=0x05 | (writing?0x02:0x00);
return false;
}
} else {
Bitu phys_page;
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
else phys_page=lin_page;
PAGING_LinkPage(lin_page,phys_page);
}
return true;
}
void InitPageForced(Bitu lin_addr) {
Bitu lin_page=lin_addr >> 12;
Bitu phys_page;
if (paging.enabled) {
X86PageEntry table;
X86PageEntry entry;
InitPageCheckPresence(lin_addr,false,table,entry);
if (!table.block.a) { if (!table.block.a) {
table.block.a=1; //Set access table.block.a=1; //Set access
phys_writed(table_addr,table.load); phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load);
} }
if (!entry.block.a) {
entry.block.a=1; //Set access
phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load);
}
phys_page=entry.block.base;
// maybe use read-only page here if possible
} else {
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
else phys_page=lin_page;
}
PAGING_LinkPage(lin_page,phys_page);
}
};
class InitPageUserROHandler : public PageHandler {
public:
InitPageUserROHandler() {
flags=PFLAG_INIT|PFLAG_NOCODE;
}
void writeb(PhysPt addr,Bitu val) {
InitPage(addr,(Bit8u)(val&0xff));
host_writeb(get_tlb_read(addr)+addr,(Bit8u)(val&0xff));
}
void writew(PhysPt addr,Bitu val) {
InitPage(addr,(Bit16u)(val&0xffff));
host_writew(get_tlb_read(addr)+addr,(Bit16u)(val&0xffff));
}
void writed(PhysPt addr,Bitu val) {
InitPage(addr,(Bit32u)val);
host_writed(get_tlb_read(addr)+addr,(Bit32u)val);
}
bool writeb_checked(PhysPt addr,Bitu val) {
Bitu writecode=InitPageCheckOnly(addr,(Bit8u)(val&0xff));
if (writecode) {
HostPt tlb_addr;
if (writecode>1) tlb_addr=get_tlb_read(addr);
else tlb_addr=get_tlb_write(addr);
host_writeb(tlb_addr+addr,(Bit8u)(val&0xff));
return false;
}
return true;
}
bool writew_checked(PhysPt addr,Bitu val) {
Bitu writecode=InitPageCheckOnly(addr,(Bit16u)(val&0xffff));
if (writecode) {
HostPt tlb_addr;
if (writecode>1) tlb_addr=get_tlb_read(addr);
else tlb_addr=get_tlb_write(addr);
host_writew(tlb_addr+addr,(Bit16u)(val&0xffff));
return false;
}
return true;
}
bool writed_checked(PhysPt addr,Bitu val) {
Bitu writecode=InitPageCheckOnly(addr,(Bit32u)val);
if (writecode) {
HostPt tlb_addr;
if (writecode>1) tlb_addr=get_tlb_read(addr);
else tlb_addr=get_tlb_write(addr);
host_writed(tlb_addr+addr,(Bit32u)val);
return false;
}
return true;
}
void InitPage(Bitu lin_addr,Bitu val) {
Bitu lin_page=lin_addr >> 12;
Bitu phys_page;
if (paging.enabled) {
if (!USERWRITE_PROHIBITED) return;
X86PageEntry table;
X86PageEntry entry; X86PageEntry entry;
Bitu entry_addr=(table.block.base<<12)+t_index*4; InitPageCheckPresence(lin_addr,true,table,entry);
entry.load=phys_readd(entry_addr);
if (!entry.block.p) { LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
if (check_only) { cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
paging.cr2=lin_addr; PAGING_PageFault(lin_addr,(table.block.base<<12)+(lin_page & 0x3ff)*4,0x07);
cpu.exception.which=14;
cpu.exception.error=writing?0x02:0x00; if (!table.block.a) {
return false; table.block.a=1; //Set access
} phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load);
// LOG(LOG_PAGING,LOG_NORMAL)("NP Page");
PAGING_PageFault(lin_addr,entry_addr,false,writing?0x02:0x00);
entry.load=phys_readd(entry_addr);
if (!entry.block.p)
E_Exit("Pagefault didn't correct page");
} }
if (cpu.cpl==3) {
if ((entry.block.us==0) || (table.block.us==0) && (((entry.block.wr==0) || (table.block.wr==0)) && writing)) {
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
if (check_only) {
paging.cr2=lin_addr;
cpu.exception.which=14;
cpu.exception.error=0x05 | (writing?0x02:0x00);
return false;
}
PAGING_PageFault(lin_addr,entry_addr,writing,0x05 | (writing?0x02:0x00));
}
}
if (check_only) return true;
if ((!entry.block.a) || (!entry.block.d)) { if ((!entry.block.a) || (!entry.block.d)) {
entry.block.a=1; //Set access entry.block.a=1; //Set access
entry.block.d=1; //Set dirty entry.block.d=1; //Set dirty
phys_writed(entry_addr,entry.load); phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load);
}
phys_page=entry.block.base;
PAGING_LinkPage(lin_page,phys_page);
} else {
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
else phys_page=lin_page;
PAGING_LinkPage(lin_page,phys_page);
}
}
Bitu InitPageCheckOnly(Bitu lin_addr,Bitu val) {
Bitu lin_page=lin_addr >> 12;
if (paging.enabled) {
if (!USERWRITE_PROHIBITED) return 2;
X86PageEntry table;
X86PageEntry entry;
if (!InitPageCheckPresence_CheckOnly(lin_addr,true,table,entry)) return 0;
if (InitPage_CheckUseraccess(entry.block.us,table.block.us) || (((entry.block.wr==0) || (table.block.wr==0)))) {
LOG(LOG_PAGING,LOG_NORMAL)("Page access denied: cpl=%i, %x:%x:%x:%x",
cpu.cpl,entry.block.us,table.block.us,entry.block.wr,table.block.wr);
paging.cr2=lin_addr;
cpu.exception.which=EXCEPTION_PF;
cpu.exception.error=0x07;
return 0;
}
PAGING_LinkPage(lin_page,entry.block.base);
} else {
Bitu phys_page;
if (lin_page<LINK_START) phys_page=paging.firstmb[lin_page];
else phys_page=lin_page;
PAGING_LinkPage(lin_page,phys_page);
}
return 1;
}
void InitPageForced(Bitu lin_addr) {
Bitu lin_page=lin_addr >> 12;
Bitu phys_page;
if (paging.enabled) {
X86PageEntry table;
X86PageEntry entry;
InitPageCheckPresence(lin_addr,true,table,entry);
if (!table.block.a) {
table.block.a=1; //Set access
phys_writed((paging.base.page<<12)+(lin_page >> 10)*4,table.load);
}
if (!entry.block.a) {
entry.block.a=1; //Set access
phys_writed((table.block.base<<12)+(lin_page & 0x3ff)*4,entry.load);
} }
phys_page=entry.block.base; phys_page=entry.block.base;
} else { } else {
@ -287,10 +601,10 @@ public:
else phys_page=lin_page; else phys_page=lin_page;
} }
PAGING_LinkPage(lin_page,phys_page); PAGING_LinkPage(lin_page,phys_page);
return true;
} }
}; };
bool PAGING_MakePhysPage(Bitu & page) { bool PAGING_MakePhysPage(Bitu & page) {
if (paging.enabled) { if (paging.enabled) {
Bitu d_index=page >> 10; Bitu d_index=page >> 10;
@ -302,25 +616,41 @@ bool PAGING_MakePhysPage(Bitu & page) {
entry.load=phys_readd((table.block.base<<12)+t_index*4); entry.load=phys_readd((table.block.base<<12)+t_index*4);
if (!entry.block.p) return false; if (!entry.block.p) return false;
page=entry.block.base; page=entry.block.base;
} else { } else {
if (page<LINK_START) page=paging.firstmb[page]; if (page<LINK_START) page=paging.firstmb[page];
//Else keep it the same //Else keep it the same
} }
return true; return true;
} }
static InitPageHandler init_page_handler; static InitPageHandler init_page_handler;
static InitPageUserROHandler init_page_handler_userro;
Bitu PAGING_GetDirBase(void) { Bitu PAGING_GetDirBase(void) {
return paging.cr3; return paging.cr3;
} }
bool PAGING_ForcePageInit(Bitu lin_addr) {
PageHandler * handler=get_tlb_readhandler(lin_addr);
if (handler==&init_page_handler) {
init_page_handler.InitPageForced(lin_addr);
return true;
} else if (handler==&init_page_handler_userro) {
PAGING_UnlinkPages(lin_addr>>12,1);
init_page_handler_userro.InitPageForced(lin_addr);
return true;
}
return false;
}
#if defined(USE_FULL_TLB)
void PAGING_InitTLB(void) { void PAGING_InitTLB(void) {
for (Bitu i=0;i<TLB_SIZE;i++) { for (Bitu i=0;i<TLB_SIZE;i++) {
paging.tlb.read[i]=0; paging.tlb.read[i]=0;
paging.tlb.write[i]=0; paging.tlb.write[i]=0;
paging.tlb.handler[i]=&init_page_handler; paging.tlb.readhandler[i]=&init_page_handler;
paging.tlb.writehandler[i]=&init_page_handler;
} }
paging.links.used=0; paging.links.used=0;
} }
@ -331,7 +661,8 @@ void PAGING_ClearTLB(void) {
Bitu page=*entries++; Bitu page=*entries++;
paging.tlb.read[page]=0; paging.tlb.read[page]=0;
paging.tlb.write[page]=0; paging.tlb.write[page]=0;
paging.tlb.handler[page]=&init_page_handler; paging.tlb.readhandler[page]=&init_page_handler;
paging.tlb.writehandler[page]=&init_page_handler;
} }
paging.links.used=0; paging.links.used=0;
} }
@ -340,7 +671,21 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
for (;pages>0;pages--) { for (;pages>0;pages--) {
paging.tlb.read[lin_page]=0; paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0; paging.tlb.write[lin_page]=0;
paging.tlb.handler[lin_page]=&init_page_handler; paging.tlb.readhandler[lin_page]=&init_page_handler;
paging.tlb.writehandler[lin_page]=&init_page_handler;
lin_page++;
}
}
void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
if (lin_page<LINK_START) {
paging.firstmb[lin_page]=phys_page;
paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.tlb.readhandler[lin_page]=&init_page_handler;
paging.tlb.writehandler[lin_page]=&init_page_handler;
} else {
PAGING_LinkPage(lin_page,phys_page);
} }
} }
@ -362,20 +707,137 @@ void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
else paging.tlb.write[lin_page]=0; else paging.tlb.write[lin_page]=0;
paging.links.entries[paging.links.used++]=lin_page; paging.links.entries[paging.links.used++]=lin_page;
paging.tlb.handler[lin_page]=handler; paging.tlb.readhandler[lin_page]=handler;
paging.tlb.writehandler[lin_page]=handler;
}
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
Bitu lin_base=lin_page << 12;
if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE)
E_Exit("Illegal page");
if (paging.links.used>=PAGING_LINKS) {
LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache");
PAGING_ClearTLB();
}
paging.tlb.phys_page[lin_page]=phys_page;
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=handler->GetHostReadPt(phys_page)-lin_base;
else paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.links.entries[paging.links.used++]=lin_page;
paging.tlb.readhandler[lin_page]=handler;
paging.tlb.writehandler[lin_page]=&init_page_handler_userro;
}
#else
static INLINE void InitTLBInt(tlb_entry *bank) {
for (Bitu i=0;i<TLB_SIZE;i++) {
bank[i].read=0;
bank[i].write=0;
bank[i].readhandler=&init_page_handler;
bank[i].writehandler=&init_page_handler;
}
}
void PAGING_InitTLBBank(tlb_entry **bank) {
*bank = (tlb_entry *)malloc(sizeof(tlb_entry)*TLB_SIZE);
if(!*bank) E_Exit("Out of Memory");
InitTLBInt(*bank);
}
void PAGING_InitTLB(void) {
InitTLBInt(paging.tlbh);
paging.links.used=0;
}
void PAGING_ClearTLB(void) {
Bit32u * entries=&paging.links.entries[0];
for (;paging.links.used>0;paging.links.used--) {
Bitu page=*entries++;
tlb_entry *entry = get_tlb_entry(page<<12);
entry->read=0;
entry->write=0;
entry->readhandler=&init_page_handler;
entry->writehandler=&init_page_handler;
}
paging.links.used=0;
}
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
for (;pages>0;pages--) {
tlb_entry *entry = get_tlb_entry(lin_page<<12);
entry->read=0;
entry->write=0;
entry->readhandler=&init_page_handler;
entry->writehandler=&init_page_handler;
lin_page++;
}
} }
void PAGING_MapPage(Bitu lin_page,Bitu phys_page) { void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
if (lin_page<LINK_START) { if (lin_page<LINK_START) {
paging.firstmb[lin_page]=phys_page; paging.firstmb[lin_page]=phys_page;
paging.tlb.read[lin_page]=0; paging.tlbh[lin_page].read=0;
paging.tlb.write[lin_page]=0; paging.tlbh[lin_page].write=0;
paging.tlb.handler[lin_page]=&init_page_handler; paging.tlbh[lin_page].readhandler=&init_page_handler;
paging.tlbh[lin_page].writehandler=&init_page_handler;
} else { } else {
PAGING_LinkPage(lin_page,phys_page); PAGING_LinkPage(lin_page,phys_page);
} }
} }
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
Bitu lin_base=lin_page << 12;
if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1)))
E_Exit("Illegal page");
if (paging.links.used>=PAGING_LINKS) {
LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache");
PAGING_ClearTLB();
}
tlb_entry *entry = get_tlb_entry(lin_base);
entry->phys_page=phys_page;
if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base;
else entry->read=0;
if (handler->flags & PFLAG_WRITEABLE) entry->write=handler->GetHostWritePt(phys_page)-lin_base;
else entry->write=0;
paging.links.entries[paging.links.used++]=lin_page;
entry->readhandler=handler;
entry->writehandler=handler;
}
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page) {
PageHandler * handler=MEM_GetPageHandler(phys_page);
Bitu lin_base=lin_page << 12;
if (lin_page>=(TLB_SIZE*(TLB_BANKS+1)) || phys_page>=(TLB_SIZE*(TLB_BANKS+1)))
E_Exit("Illegal page");
if (paging.links.used>=PAGING_LINKS) {
LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache");
PAGING_ClearTLB();
}
tlb_entry *entry = get_tlb_entry(lin_base);
entry->phys_page=phys_page;
if (handler->flags & PFLAG_READABLE) entry->read=handler->GetHostReadPt(phys_page)-lin_base;
else entry->read=0;
entry->write=0;
paging.links.entries[paging.links.used++]=lin_page;
entry->readhandler=handler;
entry->writehandler=&init_page_handler_userro;
}
#endif
void PAGING_SetDirBase(Bitu cr3) { void PAGING_SetDirBase(Bitu cr3) {
paging.cr3=cr3; paging.cr3=cr3;
@ -391,10 +853,8 @@ void PAGING_Enable(bool enabled) {
/* If paging is disable we work from a default paging table */ /* If paging is disable we work from a default paging table */
if (paging.enabled==enabled) return; if (paging.enabled==enabled) return;
paging.enabled=enabled; paging.enabled=enabled;
if (!enabled) { if (enabled) {
// LOG(LOG_PAGING,LOG_NORMAL)("Disabled"); if (GCC_UNLIKELY(cpudecoder==CPU_Core_Simple_Run)) {
} else {
if (cpudecoder==CPU_Core_Simple_Run) {
// LOG_MSG("CPU core simple won't run this game,switching to normal"); // LOG_MSG("CPU core simple won't run this game,switching to normal");
cpudecoder=CPU_Core_Normal_Run; cpudecoder=CPU_Core_Normal_Run;
CPU_CycleLeft+=CPU_Cycles; CPU_CycleLeft+=CPU_Cycles;

View File

@ -1,402 +0,0 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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 = :
host_triplet = @host@
ACLOCAL = @ACLOCAL@
ALSA_CFLAGS = @ALSA_CFLAGS@
ALSA_LIBS = @ALSA_LIBS@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GREP = @GREP@
HAVE_WINDRES_FALSE = @HAVE_WINDRES_FALSE@
HAVE_WINDRES_TRUE = @HAVE_WINDRES_TRUE@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
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@
RANLIB = @RANLIB@
SDL_CFLAGS = @SDL_CFLAGS@
SDL_CONFIG = @SDL_CONFIG@
SDL_LIBS = @SDL_LIBS@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
WINDRES = @WINDRES@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
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@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libdebug.a
libdebug_a_SOURCES = debug.cpp debug_gui.cpp debug_disasm.cpp debug_inc.h disasm_tables.h debug_win32.cpp
subdir = src/debug
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libdebug_a_AR = $(AR) cru
libdebug_a_LIBADD =
am_libdebug_a_OBJECTS = debug.$(OBJEXT) debug_gui.$(OBJEXT) \
debug_disasm.$(OBJEXT) debug_win32.$(OBJEXT)
libdebug_a_OBJECTS = $(am_libdebug_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/debug.Po ./$(DEPDIR)/debug_disasm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/debug_gui.Po ./$(DEPDIR)/debug_win32.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
-o $@
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libdebug_a_SOURCES)
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
SOURCES = $(libdebug_a_SOURCES)
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/debug/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
AR = ar
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libdebug.a: $(libdebug_a_OBJECTS) $(libdebug_a_DEPENDENCIES)
-rm -f libdebug.a
$(libdebug_a_AR) libdebug.a $(libdebug_a_OBJECTS) $(libdebug_a_LIBADD)
$(RANLIB) libdebug.a
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_disasm.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_gui.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug_win32.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
uninstall-info-am:
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
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; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
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; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(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; } \
END { 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
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
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)
installdirs:
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:
-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-generic 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:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
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
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
ps ps-am tags uninstall uninstall-am uninstall-info-am
# 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:

Some files were not shown because too many files have changed in this diff Show More