DOSBox 0.61

This commit is contained in:
Carl.Kenner 2009-05-02 21:53:27 +00:00
parent e99193553b
commit a0ed243c23
214 changed files with 14957 additions and 11260 deletions

View File

@ -1,3 +1,41 @@
0.61
- Added a beta dynamic cpu for x86 hosts (very unstable)
- Added opengl and hardware overlay display output
- Rewrote the vga screen updates to go in lines
- Added paging and v86 support to cpu emulation
- Added a config option to simulate a certain type of machine
- Added hercules graphics emulation
- Made CGA/TANDY modes more compatible
- Updated textmode drawing routines to support blinking colors
- Fixed VESA set page function that was documented wrong
- Fixed some wrongly emulated cpu opcodes.
- improved exception handling
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
- fixed some mscdex issues (drive letter header error, added get directory entry)
- added/fixed some bios funcs
- added some rarely used xms functions (thanks c2woody!)
- implemented GUS emulation
- Added 16-bit DMA support (for GUS and eventually SB16)
- Fixed many small bugs in filehandling routines
- Many small FPU fixes (c2woody/Fizzban)
- Some keyboard improvements (pharlab games)
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
- Lot's of mouse fixes (Help from various people)
- Enabled internal modem
- Made the DOS parsing routines a bit more flexible
- Added Subst (Srecko)
- Added cdrom ioctl support for linux (prompt)
- Many internal DOS fixes: memory/files/datastructures.
- Got some help from c2woody in allowing more than 1 irq being served
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
- Search configfile in $HOME directory if none present in current directory
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
- Fixed some odd badly documented behaviour with PSP/DTA
- Added some warnings on opening of readonly files in writemode(DOS default).
- Many shell enhanchements
- Fixed a win32 specific bug dealing with filenames starting with a "."
- Fixed some bugs with the directory structure: not found/can't save errors
0.60
- rewrote memory system for future paging support
- fixed several EMS and XMS bugs and rewrite for new memory system

View File

@ -1,7 +1,7 @@
# Main Makefile for DOSBox
EXTRA_DIST = autogen.sh
SUBDIRS = src include visualc docs
SUBDIRS = src include visualc docs visualc_net

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -133,7 +133,7 @@ target_os = @target_os@
target_vendor = @target_vendor@
EXTRA_DIST = autogen.sh
SUBDIRS = src include visualc docs
SUBDIRS = src include visualc docs visualc_net
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
@ -461,7 +461,7 @@ install-am: all-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -480,7 +480,6 @@ 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
@ -505,7 +504,6 @@ 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

38
NEWS
View File

@ -1,3 +1,41 @@
0.61
- Added a beta dynamic cpu for x86 hosts (very unstable)
- Added opengl and hardware overlay display output
- Rewrote the vga screen updates to go in lines
- Added paging and v86 support to cpu emulation
- Added a config option to simulate a certain type of machine
- Added hercules graphics emulation
- Made CGA/TANDY modes more compatible
- Updated textmode drawing routines to support blinking colors
- Fixed VESA set page function that was documented wrong
- Fixed some wrongly emulated cpu opcodes.
- improved exception handling
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
- fixed some mscdex issues (drive letter header error, added get directory entry)
- added/fixed some bios funcs
- added some rarely used xms functions (thanks c2woody!)
- implemented GUS emulation
- Added 16-bit DMA support (for GUS and eventually SB16)
- Fixed many small bugs in filehandling routines
- Many small FPU fixes (c2woody/Fizzban)
- Some keyboard improvements (pharlab games)
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
- Lot's of mouse fixes (Help from various people)
- Enabled internal modem
- Made the DOS parsing routines a bit more flexible
- Added Subst (Srecko)
- Added cdrom ioctl support for linux (prompt)
- Many internal DOS fixes: memory/files/datastructures.
- Got some help from c2woody in allowing more than 1 irq being served
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
- Search configfile in $HOME directory if none present in current directory
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
- Fixed some odd badly documented behaviour with PSP/DTA
- Added some warnings on opening of readonly files in writemode(DOS default).
- Many shell enhanchements
- Fixed a win32 specific bug dealing with filenames starting with a "."
- Fixed some bugs with the directory structure: not found/can't save errors
0.60
- rewrote memory system for future paging support
- fixed several EMS and XMS bugs and rewrite for new memory system

105
README
View File

@ -1,25 +1,25 @@
DOSBox v0.60
DOSBox v0.61
=====
NOTE:
=====
While we hope that, one day, DosBox will run virtually all programs
ever made for the PC...we are not there yet. At present, DosBox run on a 1.7
Gigahertz PC is roughly the equivalent of a 25MHz 386 PC. While the 0.60
While we hope that, one day, DOSBox will run virtually all programs
ever made for the PC...we are not there yet. At present, DOSBox run on a high-
end machine will roughly be the equivalent of a lowend 486 PC. While the 0.60
release has added support for "protected mode" allowing for more complex and
recent programs, but note that this support is early in development and
nowhere near as complete as the support for 386 real-mode games (or
earlier). Also note that "protected mode" games need substantially more
resources and may require a much faster processor for you to run it properly
in DosBox.
in DOSBox.
======
Usage:
======
dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
[-lang languagefile]
[-lang languagefile] [-machine machinetype] [-noconsole]
name
If "name" is a directory it'll mount that as the C: drive.
@ -46,6 +46,11 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
Start dosbox without showing the console window, output will
be redirected to stdout.txt and stderr.txt
-machine machinetype
Setup dosbox to emulate a specific type of machine. Valid choices are:
auto,hercules,cga,tandy,vga.
Note: If a name/command/configfile/languagefile contains a space in it, put
the whole name/command/configfile/languagefile between quotes("example").
@ -63,7 +68,7 @@ In Windows you can also drag directories/files onto the dosbox executable.
Internal Programs:
==================
dosbox supports most of the DOS commands found in command.com.
DOSBox supports most of the DOS commands found in command.com.
In addition, the following commands are available:
MOUNT "Emulated Drive letter" "Real Drive or Directory"
@ -111,13 +116,13 @@ MOUNT -cd
Note: It's possible to mount a local directory as cdrom drive.
Hardware support is then missing.
Basically, MOUNT allows you to connect real hardware to DosBox's "emulated"
PC. So MOUNT C C:\ tells DosBox to use your real C: drive as drive C: in
Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated"
PC. So MOUNT C C:\ tells DOSBox to use your real C: drive as drive C: in
DosBox. It also allows you to change the drive's letter identification for
programs that demand specific drive letters.
For example: Touche: Adventures of The Fifth Musketeer must be run on your C:
drive. Using DosBox and it's mount command, you can trick into thinking it
drive. Using DOSBox and it's mount command, you can trick into thinking it
is on C drive while placing it where you want it. For example, if the game
were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to
run Touche from the D drive.
@ -133,7 +138,7 @@ MOUNT -cd
mount d /media/cdrom -t cdrom -usecd 0
4. To mount a drive with 870 mb free diskspace (rarely needed! experts only):
mount c d:\ -size 4025,127,16513,1700
5. to mount /home/dos/dosgames as drive C in dosbox:
5. To mount /home/dos/dosgames as drive C in DOSBox:
mount c /home/dos/dosgames
MEM
@ -143,6 +148,11 @@ CONFIG [-writeconf] [-writelang] localfile
Write the current configuration or language settings to file.
"localfile" is located on the local drive !!!
Example:
To create a configfile in your current directory:
config -writeconf dosbox.conf
LOADFIX [-size] [program] [program-parameters]
LOADFIX -f
Program to "eat up" memory. Useful for old programs which don't expect much
@ -247,6 +257,60 @@ Q: The sound stutters.
A: You're using too much cpu power to keep dosbox running at the current speed.
You can either lower the cycles or skip frames or get a faster machine.
Q: I can't type \ in DOSBox.
A: This is a known problem. It only occurs if your keyboard layout isn't US.
Some possible fixes:
1. Switch your keyboard layout.
2. Use / instead.
3. Add the commands you want to execute in dosbox.conf
Q: The game/application can't find its CD-ROM.
A: Be sure to mount the CD-ROM with -t cdrom switch. Also try adding the cor-
rect label (-label LABEL). To enable more low-level cdrom support add
the following switch to mount: -usecd #, where # is the number of your
CD-ROM drive reported by mount -cd. If you run Win32 you can specify -ioctl
or -aspi. Look at the description elsewhere in this document for their
meaning.
Q: The game/application runs much too slow!
A: Look at the section "To run resource-demanding games" for more information.
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 dosbox.conf .
Startup your favourite editor and look at all the settings present. To
start DOSBox with your new settings: dosbox -conf dosbox.conf
Q: What sound hardware does DosBox presently emulate?
A: DosBox emulates several legacy sound devices:
- Internal PC speaker
This emulation includes both the tone generator and several forms of digital
sound output through the internal speaker.
- Creative CMS/Gameblaster
The is the first card released by Creative Labs(R). The default configuration places
it on port 0x220. It should be noted that enabling this with the Adlib emulation may
result in conflicts.
- Tandy 3 voice
The emulation of this sound hardware is complete with the exception of the noise channel,
which is not very well documented and as such is only a best guess as to the sound's accuracy.
- Adlib
Borrowed from MAME, this emulation is almost perfect and includes the Adlib's ability to almost
play digitized sound.
- SoundBlaster Pro
Coupled with the Adlib, DosBox provides Soundblaster Pro level 8-bit stereo sound.
- Disney Soundsource
Using the printer port, this sound device outputs digital sound only.
- Gravis Ultrasound
The emulation of this hardware is nearly complete, though the MIDI capabilities have been left
out since an MPU-401 has been emulated in other code.
- MPU-401
A MIDI passthrough interface is also emulated. This method of sound output will only work when
used with a General Midi or MT-32 device.
Q: Great README, but I still don't get it.
A: While unlikely this seems to happen. Maybe a look at "The Newbie's
pictorial guide to dosbox" located at
http://vogons.zetafleet.com/viewforum.php?f=39 might help you.
For more questions check the site/forum:
http://dosbox.sourceforge.net
@ -256,12 +320,21 @@ http://dosbox.sourceforge.net
The Config File:
================
A config file can be generated by CONFIG.COM. Edit it to customize DOSBox.
A config file can be generated by CONFIG.COM, which can be found on the
internal dosbox Z: drive when you start up dosbox. Look in the internal
programs section of the readme for usage of CONFIG.COM.
You can edit the generated configfile to customize DOSBox.
The file is divided into several sections (the names have [] around it).
Some sections have options which you can set.
# and % indicate commentlines.
# and % indicate comment-lines.
The generated configfile contains the current settings. You can alter them and
start dosbox with the -conf switch to load the file and use these settings.
start DOSBox with the -conf switch to load the file and use these settings.
DOSBox will if no configfile is specified with the -conf switch look in the
current directory for dosbox.conf. Then it will look for ~/.dosboxrc (linux),
~\dosbox.conf (win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX).
==================
The Language File:
@ -269,7 +342,7 @@ The Language File:
A language file can be generated by CONFIG.COM.
Read it and you will hopefully understand how to change it.
Start Dosbox with the -lang switch to use your new language file
Start DOSBox with the -lang switch to use your new language file
or you can setup the filename in the config file in the [dosbox] section.
There's a language= entry that can be changed with the filename.
@ -289,6 +362,8 @@ Vlad R. of the vdmsound project for excellent sound blaster info.
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
The Bochs and DOSemu projects which I used for information.
Freedos for ideas in making my shell.
Pierre-Yves Gérardy for hosting the old Beta Board.
Colin Snover for hosting our forum.
The Beta Testers.
========

3
THANKS
View File

@ -8,5 +8,8 @@ Jarek Burczynski for the new OPL emulator.
The Bochs and DOSemu projects which I used for information.
Freedos for ideas in making my shell.
Pierre-Yves Gérardy for hosting the old Beta Board.
Colin Snover for hosting our forum.
All the people who submitted a bug.
The Beta Testers.

4
aclocal.m4 vendored
View File

@ -1,4 +1,4 @@
# generated automatically by aclocal 1.7.7 -*- Autoconf -*-
# generated automatically by aclocal 1.7.9 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
@ -498,7 +498,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.7.7])])
[AM_AUTOMAKE_VERSION([1.7.9])])
# Helper functions for option handling. -*- Autoconf -*-

View File

@ -10,4 +10,5 @@ autoheader
automake --gnits --include-deps --add-missing --copy
autoconf
echo "Now you are ready to run ./configure, afterwards check config.h for extra build settings"
echo "Now you are ready to run ./configure."
echo "You can also run ./configure --help for extra features to enable/disable."

View File

@ -26,6 +26,9 @@
/* Define to 1 to enable internal debugger, requires libcurses */
#undef C_DEBUG
/* Define to 1 to use x86 dynamic cpu core */
#undef C_DYNAMIC_X86
/* Define to 1 to enable floating point emulation */
#undef C_FPU
@ -35,9 +38,15 @@
/* Define to 1 to enable heavy debugging, also have to enable C_DEBUG */
#undef C_HEAVY_DEBUG
/* The type of cpu this host has */
#undef C_HOSTCPU
/* 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 screenshots, requires libpng */
#undef C_SSHOT
@ -80,6 +89,9 @@
/* 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
@ -117,9 +129,11 @@
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
/* 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' if <sys/types.h> does not define. */
#undef size_t

35
config.sub vendored
View File

@ -3,7 +3,7 @@
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-10-07'
timestamp='2004-01-05'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@ -118,7 +118,8 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@ -379,6 +380,9 @@ case $basic_machine in
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@ -743,6 +747,10 @@ case $basic_machine in
basic_machine=or32-unknown
os=-coff
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@ -963,6 +971,10 @@ case $basic_machine in
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@ -1137,13 +1149,13 @@ case $os in
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1182,6 +1194,9 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@ -1203,6 +1218,9 @@ case $os in
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
@ -1225,6 +1243,9 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@ -1473,9 +1494,15 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;

1652
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
dnl Init.
AC_INIT(dosbox,0.60)
AC_INIT(dosbox,0.61)
AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(README)
@ -86,19 +86,51 @@ AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
AH_TEMPLATE(C_CORE_INLINE,[Define to 1 to use inlined memory functions in cpu core])
AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined memory handling in CPU Core]),[
if test x$enable_core_inline = xyes ; then
AC_MSG_RESULT([enabling inlined memory handling in CPU Core]),
AC_MSG_RESULT([enabling inlined memory handling in CPU Core])
AC_DEFINE(C_CORE_INLINE,1)
fi
],)
AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation])
AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable FPU support]),[
if test x$enable_fpu = xno ; then
AC_MSG_RESULT([disabling FPU supportd])
dnl The target cpu checks for dynamic cores
AH_TEMPLATE(C_HOSTCPU,[The type of cpu this host has])
AC_MSG_CHECKING(for target cpu type)
case "$target_cpu" in
i386|i486|i586|i686)
AC_DEFINE(C_HOSTCPU,X86)
AC_MSG_RESULT(x86 compatible)
c_hostcpu="x86"
;;
*)
AC_DEFINE(C_HOSTCPU,UNKOWN)
AC_MSG_RESULT(unknown)
;;
esac
AH_TEMPLATE(C_DYNAMIC_X86,[Define to 1 to use x86 dynamic cpu core])
AC_ARG_ENABLE(dynamic-x86,AC_HELP_STRING([--disable-dynamic-x86],[Disable x86 dynamic cpu core]),,enable_dynamic_x86=yes)
AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled)
if test x$enable_dynamic_x86 = xno ; then
AC_MSG_RESULT(no)
else
if test x$c_hostcpu = xx86 ; then
AC_DEFINE(C_DYNAMIC_X86,1)
AC_MSG_RESULT(yes)
else
AC_DEFINE(C_FPU,1)
AC_MSG_RESULT(no)
fi
],AC_DEFINE(C_FPU,1))
fi
AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation])
AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable fpu support]),,enable_fpu=yes)
AC_MSG_CHECKING(whether fpu emulation will be enabled)
if test x$enable_fpu = xyes ; then
AC_MSG_RESULT(yes)
AC_DEFINE(C_FPU,1)
else
AC_MSG_RESULT(no)
fi
AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng])
AC_CHECK_HEADER(png.h,have_png_h=yes,)
@ -120,6 +152,23 @@ else
AC_MSG_WARN([Can't find SDL_net, internal modem disabled])
fi
AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support])
AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes)
AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , )
AC_CHECK_LIB(opengl32, main, have_opengl32_lib=yes,have_opengl32_lib=no , )
AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , )
AC_MSG_CHECKING(whether opengl display output will be enabled)
if test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -lGL"
AC_DEFINE(C_OPENGL,1)
elif test x$enable_opengl = xyes -a x$have_gl_h = xyes -a x$have_opengl32_lib = xyes ; then
AC_MSG_RESULT(yes)
LIBS="$LIBS -lopengl32"
AC_DEFINE(C_OPENGL,1)
else
AC_MSG_RESULT(no)
fi
dnl Some host detection and actions for them
case "$target" in
@ -134,6 +183,9 @@ case "$target" in
AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X])
LIBS="$LIBS -framework AudioUnit"
;;
*-*-linux-gnu*)
AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux])
;;
esac
@ -141,9 +193,9 @@ AC_OUTPUT([
Makefile
src/Makefile
src/cpu/Makefile
src/cpu/core_16/Makefile
src/cpu/core_full/Makefile
src/cpu/core_normal/Makefile
src/cpu/core_dyn_x86/Makefile
src/debug/Makefile
src/dos/Makefile
src/fpu/Makefile
@ -155,6 +207,7 @@ src/shell/Makefile
src/platform/Makefile
src/platform/visualc/Makefile
visualc/Makefile
visualc_net/Makefile
include/Makefile
docs/Makefile
])

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -255,7 +255,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -274,7 +274,6 @@ clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
@ -297,7 +296,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -26,7 +26,9 @@ regs.h \
render.h \
serialport.h \
setup.h \
shell.h \
support.h \
timer.h \
vga.h \
video.h

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -157,8 +157,10 @@ regs.h \
render.h \
serialport.h \
setup.h \
shell.h \
support.h \
timer.h \
vga.h \
video.h
subdir = include
@ -281,7 +283,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -300,7 +302,6 @@ clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
@ -323,7 +324,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -114,6 +114,7 @@ private:
};
void BIOS_ZeroExtendedSize(void);
void char_out(Bit8u chr,Bit32u att,Bit8u page);
void INT10_StartUp(void);
void INT16_StartUp(void);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -47,9 +47,10 @@ void CALLBACK_Idle(void);
void CALLBACK_RunRealInt(Bit8u intnum);
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off);
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type);
bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress);
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* description=0);
bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress, const char* description=0);
const char* CALLBACK_GetDescription(Bitu callback);
bool CALLBACK_Free(Bitu callback);
void CALLBACK_SCF(bool val);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -33,18 +33,14 @@ extern Bits CPU_CycleMax;
typedef Bits (CPU_Decoder)(void);
extern CPU_Decoder * cpudecoder;
Bits CPU_Core_Normal_Run(void);
Bits CPU_Core_Normal_Trap_Run(void);
Bits CPU_Core_Full_Run(void);
Bits CPU_Core_Dyn_X86_Run(void);
//CPU Stuff
void SetCPU16bit( );
enum CODE_TYPE {
CODE_REAL,
CODE_PMODE16,
CODE_PMODE32,
CODE_INIT,
};
extern bool parity_lookup[256];
extern Bit16u parity_lookup[256];
void CPU_LLDT(Bitu selector);
void CPU_LTR(Bitu selector);
@ -70,34 +66,38 @@ bool CPU_LMSW(Bitu word);
void CPU_VERR(Bitu selector);
void CPU_VERW(Bitu selector);
bool CPU_JMP(bool use32,Bitu selector,Bitu offset);
bool CPU_CALL(bool use32,Bitu selector,Bitu offset);
bool CPU_RET(bool use32,Bitu bytes);
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen=0);
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen=0);
void CPU_RET(bool use32,Bitu bytes,Bitu opLen=0);
bool Interrupt(Bitu num);
bool CPU_IRET(bool use32);
void CPU_SetSegGeneral(SegNames seg,Bitu value);
#define CPU_INT_SOFTWARE 0x1
#define CPU_INT_EXCEPTION 0x2
#define CPU_INT_HAS_ERROR 0x4
void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen=0);
INLINE void CPU_HW_Interrupt(Bitu num) {
CPU_Interrupt(num,0);
}
INLINE void CPU_SW_Interrupt(Bitu num,Bitu OpLen) {
CPU_Interrupt(num,CPU_INT_SOFTWARE,OpLen);
}
void CPU_Exception(Bitu which,Bitu error=0);
void CPU_StartException(void);
void CPU_SetupException(Bitu which,Bitu error=0);
void CPU_IRET(bool use32);
bool CPU_SetSegGeneral(SegNames seg,Bitu value);
void CPU_HLT(Bitu opLen);
void CPU_CPUID(void);
void CPU_HLT(void);
Bitu CPU_Pop16(void);
Bitu CPU_Pop32(void);
void CPU_Push16(Bitu value);
void CPU_Push32(Bitu value);
void CPU_SetFlags(Bitu word);
INLINE void CPU_SetFlagsd(Bit32u word) {
CPU_SetFlags(word);
};
INLINE void CPU_SetFlagsw(Bit16u word) {
CPU_SetFlags((flags.word&0xffff0000)|word);
};
void CPU_SetFlags(Bitu word,Bitu mask);
// *********************************************************************
// Descriptor
@ -146,33 +146,25 @@ INLINE void CPU_SetFlagsw(Bit16u word) {
#define DESC_CODE_R_C_A 0x1e
#define DESC_CODE_R_C_NA 0x1f
#pragma pack(1)
/* TSS Struct from Bochs - http://bochs.sf.net */
struct TSS_386 {
Bit16u back, RESERVED0; /* Backlink */
Bit32u esp0; /* The CK stack pointer */
Bit16u ss0, RESERVED1; /* The CK stack selector */
Bit32u esp1; /* The parent KL stack pointer */
Bit16u ss1, RESERVED2; /* The parent KL stack selector */
Bit32u esp2; /* Unused */
Bit16u ss2, RESERVED3; /* Unused */
Bit32u cr3; /* The page directory pointer */
Bit32u eip; /* The instruction pointer */
Bit32u eflags; /* The flags */
Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
Bit32u esp, ebp, esi, edi; /* The special purpose registers */
Bit16u es, RESERVED4; /* The extra selector */
Bit16u cs, RESERVED5; /* The code selector */
Bit16u ss, RESERVED6; /* The application stack selector */
Bit16u ds, RESERVED7; /* The data selector */
Bit16u fs, RESERVED8; /* And another extra selector */
Bit16u gs, RESERVED9; /* ... and another one */
Bit16u ldt, RESERVED10; /* The local descriptor table */
Bit16u trap; /* The trap flag (for debugging) */
Bit16u io; /* The I/O Map base address */
} GCC_ATTRIBUTE(packed);;
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct S_Descriptor {
#ifdef WORDS_BIGENDIAN
Bit32u base_0_15 :16;
Bit32u limit_0_15 :16;
Bit32u base_24_31 :8;
Bit32u g :1;
Bit32u big :1;
Bit32u r :1;
Bit32u avl :1;
Bit32u limit_16_19 :4;
Bit32u p :1;
Bit32u dpl :2;
Bit32u type :5;
Bit32u base_16_23 :8;
#else
Bit32u limit_0_15 :16;
Bit32u base_0_15 :16;
Bit32u base_16_23 :8;
@ -185,9 +177,20 @@ struct S_Descriptor {
Bit32u big :1;
Bit32u g :1;
Bit32u base_24_31 :8;
#endif
}GCC_ATTRIBUTE(packed);
struct G_Descriptor {
#ifdef WORDS_BIGENDIAN
Bit32u selector: 16;
Bit32u offset_0_15 :16;
Bit32u offset_16_31 :16;
Bit32u p :1;
Bit32u dpl :2;
Bit32u type :5;
Bit32u reserved :3;
Bit32u paramcount :5;
#else
Bit32u offset_0_15 :16;
Bit32u selector :16;
Bit32u paramcount :5;
@ -196,57 +199,53 @@ struct G_Descriptor {
Bit32u dpl :2;
Bit32u p :1;
Bit32u offset_16_31 :16;
#endif
} GCC_ATTRIBUTE(packed);
#pragma pack()
struct TaskSegment_32 {
Bit32u esp0; /* The CK stack pointer */
Bit32u esp1; /* The parent KL stack pointer */
Bit32u esp2; /* Unused */
Bit32u cr3; /* The page directory pointer */
Bit32u eip; /* The instruction pointer */
Bit32u eflags; /* The flags */
Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
Bit32u esp, ebp, esi, edi; /* The special purpose registers */
Bit16u back; /* Backlink */
struct TSS_16 {
Bit16u back; /* Back link to other task */
Bit16u sp0; /* The CK stack pointer */
Bit16u ss0; /* The CK stack selector */
Bit16u sp1; /* The parent KL stack pointer */
Bit16u ss1; /* The parent KL stack selector */
Bit16u sp2; /* Unused */
Bit16u ss2; /* Unused */
Bit16u ip; /* The instruction pointer */
Bit16u flags; /* The flags */
Bit16u ax, cx, dx, bx; /* The general purpose registers */
Bit16u sp, bp, si, di; /* The special purpose registers */
Bit16u es; /* The extra selector */
Bit16u cs; /* The code selector */
Bit16u ss; /* The application stack selector */
Bit16u ds; /* The data selector */
Bit16u fs; /* And another extra selector */
Bit16u gs; /* ... and another one */
Bit16u ldt; /* The local descriptor table */
Bit16u trap; /* The trap flag (for debugging) */
Bit16u io; /* The I/O Map base address */
};
} GCC_ATTRIBUTE(packed);
void CPU_ReadTaskSeg32(PhysPt base,TaskSegment_32 * seg);
class TaskStateSegment
{
public:
bool Get_ss_esp(Bitu which,Bitu & _ss,Bitu & _esp) {
PhysPt reader=seg_base+offsetof(TSS_386,esp0)+which*8;
_esp=mem_readd(reader);
_ss=mem_readw(reader+4);
return true;
}
bool Get_cr3(Bitu which,Bitu & _cr3) {
_cr3=mem_readd(seg_base+offsetof(TSS_386,cr3));;
return true;
}
private:
PhysPt seg_base;
Bitu seg_limit;
Bitu seg_value;
};
struct TSS_32 {
Bit32u back; /* Back link to other task */
Bit32u esp0; /* The CK stack pointer */
Bit32u ss0; /* The CK stack selector */
Bit32u esp1; /* The parent KL stack pointer */
Bit32u ss1; /* The parent KL stack selector */
Bit32u esp2; /* Unused */
Bit32u ss2; /* Unused */
Bit32u cr3; /* The page directory pointer */
Bit32u eip; /* The instruction pointer */
Bit32u eflags; /* The flags */
Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
Bit32u esp, ebp, esi, edi; /* The special purpose registers */
Bit32u es; /* The extra selector */
Bit32u cs; /* The code selector */
Bit32u ss; /* The application stack selector */
Bit32u ds; /* The data selector */
Bit32u fs; /* And another extra selector */
Bit32u gs; /* ... and another one */
Bit32u ldt; /* The local descriptor table */
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack()
#endif
class Descriptor
{
public:
@ -316,7 +315,7 @@ protected:
class GDTDescriptorTable : public DescriptorTable {
public:
bool GetDescriptor (Bitu selector, Descriptor& desc) {
bool GetDescriptor(Bitu selector, Descriptor& desc) {
Bitu address=selector & ~7;
if (selector & 4) {
if (address>=ldt_limit) return false;
@ -328,7 +327,18 @@ public:
return true;
}
}
bool SetDescriptor(Bitu selector, Descriptor& desc) {
Bitu address=selector & ~7;
if (selector & 4) {
if (address>=ldt_limit) return false;
desc.Save(ldt_base+address);
return true;
} else {
if (address>=table_limit) return false;
desc.Save(table_base+address);
return true;
}
}
Bitu SLDT(void) {
return ldt_value;
}
@ -347,29 +357,55 @@ private:
Bitu ldt_value;
};
class TSS_Descriptor : public Descriptor {
public:
Bitu IsBusy(void) {
return saved.seg.type & 2;
}
Bitu Is386(void) {
return saved.seg.type & 8;
}
void SetBusy(bool busy) {
if (busy) saved.seg.type|=2;
else saved.seg.type&=~2;
}
};
struct CPUBlock {
Bitu cpl; /* Current Privilege */
Bitu cr0;
bool v86; /* Are we in a v86 task */
bool pmode; /* Is Protected mode enabled */
GDTDescriptorTable gdt;
DescriptorTable idt;
struct {
Bit16u val;
PhysPt base;
Bitu type;
} tr;
struct {
Bitu mask;
bool big;
} stack;
struct {
CODE_TYPE type; /* What kind of code are we running */
bool big;
} code;
struct {
Bitu cs,eip;
CPU_Decoder * old_decoder;
} hlt;
struct {
Bitu which,error;
} exception;
Bits direction;
};
extern CPUBlock cpu;
INLINE void CPU_SetFlagsd(Bitu word) {
Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL;
CPU_SetFlags(word,mask);
};
INLINE void CPU_SetFlagsw(Bitu word) {
Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff;
CPU_SetFlags(word,mask);
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cross.h,v 1.7 2004/02/02 19:22:23 qbix79 Exp $ */
#ifndef _CROSS_H
#define _CROSS_H
@ -37,7 +39,7 @@
#if defined (WIN32) /* Win 32 */
#define CROSS_FILENAME(blah)
#define CROSS_FILENAME(blah) {if(blah && *blah && (blah[strlen(blah)-1] == '\\')) strcat(blah,".");}
#define CROSS_FILESPLIT '\\'
#define F_OK 0
#else

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,14 +16,180 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dma.h,v 1.9 2004/01/10 14:03:33 qbix79 Exp $ */
#ifndef __DMA_H
#define __DMA_H
#include "mem.h"
#define DMA_MODE_DEMAND 0
#define DMA_MODE_SINGLE 1
#define DMA_MODE_BLOCK 2
#define DMA_MODE_CASCADE 3
#define DMA_BASEADDR 0
#define DMA_TRANSCOUNT 1
#define DMA_PAGEREG 2
#define DMA_CMDREG 0
#define DMA_MODEREG 1
#define DMA_CLEARREG 2
#define DMA_DMACREG 3
#define DMA_CLRMASKREG 4
#define DMA_SINGLEREG 5
#define DMA_WRITEALLREG 6
static Bit8u ChannelPorts [3][8] = { 0x00, 0x02, 0x04, 0x06, 0xff, 0xc4, 0xc8, 0xcc,
0x01, 0x03, 0x05, 0x07, 0xff, 0xc6, 0xca, 0xce,
0x87, 0x83, 0x81, 0x82, 0xff, 0x8b, 0x89, 0x8a };
static Bit8u ControllerPorts [2][7] = { 0x08, 0x0b, 0x0c, 0x0d, 0x0e, 0x0a, 0xf,
0xd0, 0xd6, 0xd8, 0xda, 0xdc, 0xd4, 0xde };
typedef void (* DMA_EnableCallBack)(bool enable);
typedef void (* DMA_NewCallBack)(void *useChannel, bool tc);
void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback);
void DMA_CheckEnabled(void * usechan);
Bitu DMA_8_Read(Bitu channel,Bit8u * buffer,Bitu count);
Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count);
Bitu DMA_16_Read(Bitu channel,Bit8u * buffer,Bitu count);
Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count);
extern Bit8u read_dmaB(Bit32u port);
extern Bit16u read_dmaW(Bit32u port);
extern void write_dmaB(Bit32u port,Bit8u val);
extern void write_dmaW(Bit32u port,Bit16u val);
class DmaController {
public:
bool flipflop;
Bit8u ctrlnum;
public:
DmaController(Bit8u num) {
int i;
for(i=0;i<7;i++) {
IO_RegisterReadBHandler(ControllerPorts[num][i],read_dmaB);
IO_RegisterReadWHandler(ControllerPorts[num][i],read_dmaW);
IO_RegisterWriteBHandler(ControllerPorts[num][i],write_dmaB);
IO_RegisterWriteWHandler(ControllerPorts[num][i],write_dmaW);
}
flipflop = true;
ctrlnum = num;
}
Bit16u portRead(Bit32u port, bool eightbit);
void portWrite(Bit32u port, Bit16u val, bool eightbit);
};
class DmaChannel {
public:
Bit8u channum;
Bit16u baseaddr;
Bit16u current_addr;
Bit16u pageaddr;
PhysPt physaddr;
PhysPt curraddr;
Bit32s transcnt;
Bit32s currcnt;
DmaController *myController;
bool DMA16;
bool addr_changed;
public:
Bit8u dmamode;
bool dir;
bool autoinit;
Bit8u trantype;
bool masked;
bool enabled;
DMA_EnableCallBack enable_callback;
DMA_NewCallBack newcallback;
DmaChannel(Bit8u num, DmaController *useController, bool sb) {
int i;
masked = true;
enabled = false;
enable_callback = NULL;
newcallback = NULL;
if(num == 4) return;
addr_changed=false;
for(i=0;i<3;i++) {
IO_RegisterReadBHandler(ChannelPorts[i][num],read_dmaB);
IO_RegisterReadWHandler(ChannelPorts[i][num],read_dmaW);
IO_RegisterWriteBHandler(ChannelPorts[i][num],write_dmaB);
IO_RegisterWriteWHandler(ChannelPorts[i][num],write_dmaW);
}
myController = useController;
channum = num;
DMA16 = sb;
baseaddr = 0;
pageaddr = 0;
physaddr = 0;
curraddr = 0;
transcnt = 0;
currcnt = 0;
dir = false;
autoinit = false;
}
void RegisterCallback(DMA_NewCallBack useCallBack) { newcallback = useCallBack; }
void reset(void) {
addr_changed=false;
curraddr = physaddr;
currcnt = transcnt+1;
current_addr = baseaddr;
//LOG(LOG_DMA,LOG_NORMAL)("Setup at address %X:%X count %X",pageaddr,baseaddr,currcnt);
}
void MakeCallback(bool tc) {
if (newcallback != NULL) {
if(tc) {
(*newcallback)(this, true);
} else {
if ((enabled) && (!masked) && (transcnt!=0)) {
(*newcallback)(this, false);
}
}
}
}
Bit32u Read(Bit32s requestsize, Bit8u * buffer);
Bit32u Write(Bit32s requestsize, Bit8u * buffer);
void calcPhys(void);
Bit16u portRead(Bit32u port, bool eightbit);
void portWrite(Bit32u port, Bit16u val, bool eightbit);
// Notify channel when mask changes
void Notify(void);
};
extern DmaChannel *DmaChannels[8];
extern DmaController *DmaControllers[2];
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -106,6 +106,8 @@ bool DOS_Canonicalize(char * name,char * big);
bool DOS_CreateTempFile(char * name,Bit16u * entry);
bool DOS_FileExists(char * name);
/* Helper Functions */
bool DOS_MakeName(char * name,char * fullname,Bit8u * drive);
/* Drive Handing Routines */
Bit8u DOS_GetDefaultDrive(void);
void DOS_SetDefaultDrive(Bit8u drive);
@ -117,6 +119,7 @@ bool DOS_RemoveDir(char * dir);
bool DOS_Rename(char * oldname,char * newname);
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free);
bool DOS_GetFileAttr(char * name,Bit16u * attr);
bool DOS_SetFileAttr(char * name,Bit16u attr);
/* IOCTL Stuff */
bool DOS_IOCTL(void);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_system.h,v 1.16 2003/10/09 13:50:27 finsterr Exp $ */
/* $Id: dos_system.h,v 1.20 2004/01/12 20:25:57 finsterr Exp $ */
#ifndef DOSSYSTEM_H_
#define DOSSYSTEM_H_
@ -117,6 +117,11 @@ public:
class CFileInfo {
public:
CFileInfo(void) {
orgname[0] = shortname[0] = 0;
nextEntry = shortNr = compareCount = 0;
isDir = false;
}
~CFileInfo(void) {
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
fileList.clear();
@ -140,6 +145,7 @@ private:
Bits GetLongName (CFileInfo* info, char* shortname);
void CreateShortName (CFileInfo* dir, CFileInfo* info);
Bit16u CreateShortNameID (CFileInfo* dir, const char* name);
int CompareShortname (const char* compareName, const char* shortName);
bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr);
bool IsCachedIn (CFileInfo* dir);
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
@ -221,6 +227,7 @@ public:
virtual Bit8u GetMediaByte(void)=0;
virtual void SetDir(const char* path) { strcpy(curdir,path); };
virtual void EmptyCache(void) { dirCache.EmptyCache(); };
virtual bool isRemote(void)=0;
char * GetInfo(void);
char curdir[DOS_PATHLENGTH];
char info[256];

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -19,7 +19,6 @@
#if !defined __DOSBOX_H
#define __DOSBOX_H
void E_Exit(char * message,...);
void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
@ -60,6 +59,16 @@ void DOSBOX_Init(void);
class Config;
extern Config * control;
enum MachineType {
MCH_HERC,
MCH_CGA,
MCH_TANDY,
MCH_VGA,
MCH_AUTO
};
extern MachineType machine;
#ifndef __LOGGING_H_
#include "logging.h"
#endif // the logging system.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,33 +16,43 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef Bit8u (IO_ReadHandler)(Bit32u port);
typedef void (IO_WriteHandler)(Bit32u port,Bit8u value);
typedef Bit8u (IO_ReadBHandler)(Bit32u port);
typedef Bit16u (IO_ReadWHandler)(Bit32u port);
typedef Bit32u (IO_ReadDHandler)(Bit32u port);
typedef void (IO_WriteBHandler)(Bit32u port,Bit8u value);
typedef void (IO_WriteWHandler)(Bit32u port,Bit16u value);
typedef void (IO_WriteDHandler)(Bit32u port,Bit32u value);
#define IO_MAX 1024
void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler);
void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler);
void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler);
struct IO_ReadBlock{
IO_ReadHandler * handler;
char * name;
};
void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler);
void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler);
void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler);
struct IO_WriteBlock{
IO_WriteHandler * handler;
char * name;
};
void IO_FreeReadHandler(Bitu port);
void IO_FreeWriteHandler(Bitu port);
extern IO_ReadBlock IO_ReadTable[IO_MAX];
extern IO_WriteBlock IO_WriteTable[IO_MAX];
void IO_Write(Bitu num,Bit8u val);
Bit8u IO_Read(Bitu num);
void IO_RegisterReadHandler(Bit32u port,IO_ReadHandler * handler,char * name);
void IO_RegisterWriteHandler(Bit32u port,IO_WriteHandler * handler,char * name);
void IO_FreeReadHandler(Bit32u port);
void IO_FreeWriteHandler(Bit32u port);
void IO_WriteB(Bitu port,Bit8u val);
Bit8u IO_ReadB(Bitu port);
void IO_WriteW(Bitu port,Bit16u val);
Bit16u IO_ReadW(Bitu port);
void IO_WriteD(Bitu port,Bit32u val);
Bit32u IO_ReadD(Bitu port);
INLINE void IO_Write(Bitu port,Bit8u val) {
IO_WriteB(port,val);
}
INLINE Bit8u IO_Read(Bitu port){
return IO_ReadB(port);
}
INLINE void IO_RegisterReadHandler(Bitu port,IO_ReadBHandler * handler,char * name) {
IO_RegisterReadBHandler(port,handler);
}
INLINE void IO_RegisterWriteHandler(Bitu port,IO_WriteBHandler * handler,char * name) {
IO_RegisterWriteBHandler(port,handler);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -26,7 +26,7 @@ typedef Bit32u PhysPt;
typedef Bit8u * HostPt;
typedef Bit32u RealPt;
typedef Bits MemHandle;
typedef Bit32s MemHandle;
#define MEM_PAGESIZE 4096
@ -43,12 +43,9 @@ MemHandle MEM_AllocatePages(Bitu pages,bool sequence);
PhysPt MEM_AllocatePage(void);
void MEM_ReleasePages(MemHandle handle);
bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence);
void MEM_MapPagesHandle(Bitu lin_page,MemHandle mem,Bitu mem_page,Bitu pages);
void MEM_MapPagesDirect(Bitu lin_page,Bitu phys_page,Bitu pages);
void MEM_UnmapPages(Bitu phys_page,Bitu pages);
MemHandle MEM_NextHandle(MemHandle handle);
MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where);
/*
The folowing six functions are used everywhere in the end so these should be changed for
@ -57,23 +54,23 @@ MemHandle MEM_NextHandle(MemHandle handle);
#ifdef WORDS_BIGENDIAN
INLINE Bit8u readb(HostPt off) {
INLINE Bit8u host_readb(HostPt off) {
return off[0];
};
INLINE Bit16u readw(HostPt off) {
INLINE Bit16u host_readw(HostPt off) {
return off[0] | (off[1] << 8);
};
INLINE Bit32u readd(HostPt off) {
INLINE Bit32u host_readd(HostPt off) {
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
};
INLINE void writeb(HostPt off,Bit8u val) {
INLINE void host_writeb(HostPt off,Bit8u val) {
off[0]=val;
};
INLINE void writew(HostPt off,Bit16u val) {
INLINE void host_writew(HostPt off,Bit16u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
};
INLINE void writed(HostPt off,Bit32u val) {
INLINE void host_writed(HostPt off,Bit32u val) {
off[0]=(Bit8u)(val);
off[1]=(Bit8u)(val >> 8);
off[2]=(Bit8u)(val >> 16);
@ -86,22 +83,22 @@ INLINE void writed(HostPt off,Bit32u val) {
#else
INLINE Bit8u readb(HostPt off) {
INLINE Bit8u host_readb(HostPt off) {
return *(Bit8u *)off;
};
INLINE Bit16u readw(HostPt off) {
INLINE Bit16u host_readw(HostPt off) {
return *(Bit16u *)off;
};
INLINE Bit32u readd(HostPt off) {
INLINE Bit32u host_readd(HostPt off) {
return *(Bit32u *)off;
};
INLINE void writeb(HostPt off,Bit8u val) {
INLINE void host_writeb(HostPt off,Bit8u val) {
*(Bit8u *)(off)=val;
};
INLINE void writew(HostPt off,Bit16u val) {
INLINE void host_writew(HostPt off,Bit16u val) {
*(Bit16u *)(off)=val;
};
INLINE void writed(HostPt off,Bit32u val) {
INLINE void host_writed(HostPt off,Bit32u val) {
*(Bit32u *)(off)=val;
};
@ -131,7 +128,6 @@ void phys_writew(PhysPt addr,Bit16u val);
void phys_writed(PhysPt addr,Bit32u val);
/* These don't check for alignment, better be sure it's correct */
Bit32u phys_page_readd(Bitu page,Bitu off);
void MEM_BlockWrite(PhysPt pt,void * data,Bitu size);
void MEM_BlockRead(PhysPt pt,void * data,Bitu size);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -22,49 +22,58 @@
#include "mem.h"
class PageDirectory;
struct PageEntry;
struct PageLink;
#define MEM_PAGE_SIZE (4096)
#define XMS_START (0x110)
#define TLB_SIZE (1024*1024)
enum EntryTypes { //The type of memory contained in this link
ENTRY_VGA,
ENTRY_CHANGES,
ENTRY_INIT,
ENTRY_NA,
ENTRY_ROM,
ENTRY_LFB,
ENTRY_RAM,
ENTRY_ALLOC,
};
#define PFLAG_READABLE 0x1
#define PFLAG_WRITEABLE 0x2
#define PFLAG_HASROM 0x4
#define PFLAG_HASCODE 0x8 //Page contains dynamic code
#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here
#define PFLAG_INIT 0x20 //No dynamic code can be generated here
enum VGA_RANGES {
VGA_RANGE_A000,
VGA_RANGE_B000,
VGA_RANGE_B800,
};
#define LINK_START ((1024+64)/4) //Start right after the HMA
//Allow 128 mb of memory to be linked
#define PAGING_LINKS (128*1024/4)
class PageChange {
class PageHandler {
public:
virtual void Changed(PageLink * link,Bitu start,Bitu end)=0;
virtual Bitu readb(PhysPt addr);
virtual Bitu readw(PhysPt addr);
virtual Bitu readd(PhysPt addr);
virtual void writeb(PhysPt addr,Bitu val);
virtual void writew(PhysPt addr,Bitu val);
virtual void writed(PhysPt addr,Bitu val);
virtual HostPt GetHostPt(Bitu phys_page);
Bitu flags;
};
/* Some other functions */
void PAGING_Enable(bool enabled);
bool PAGING_Enabled(void);
void MEM_CheckLinks(PageEntry * theentry);
PageDirectory * MEM_DefaultDirectory(void);
Bitu PAGING_GetDirBase(void);
void PAGING_SetDirBase(Bitu cr3);
void PAGING_InitTLB(void);
void PAGING_ClearTLB(void);
PageLink * MEM_LinkPage(Bitu phys_page,PhysPt lin_base);
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages);
/* This maps the page directly, only use when paging is disabled */
void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
bool PAGING_MakePhysPage(Bitu & page);
void MEM_UnlinkPage(PageLink * link);
void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt);
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler);
Bit32u MEM_PhysReadD(Bitu addr);
#pragma pack(1)
typedef struct {
@ -87,57 +96,23 @@ union X86PageEntry {
X86_PageEntryBlock block;
};
struct PageLink {
HostPt read;
HostPt write;
PageChange * change;
PhysPt lin_base;
PageEntry * entry;
union {
PageDirectory * dir;
Bitu table;
} data;
PageLink * next;
};
struct PageEntry {
PageLink * links;
EntryTypes type;
union {
HostPt mem;
PhysPt vga_base;
PageDirectory * dir;
} data;
MemHandle next_handle;
};
class PageDirectory {
public:
PageDirectory();
~PageDirectory();
void ClearDirectory(void);
void SetBase(PhysPt page);
void LinkPage(Bitu lin_page,Bitu phys_page);
bool InitPage(Bitu lin_address);
bool InitPageLinear(Bitu lin_address);
void InvalidateTable(Bitu table);
void InvalidateLink(Bitu table,Bitu index);
PageDirectory * next;
PageLink *links[1024*1024];
PageLink *tables[1024];
PageLink *link_dir; //Handler for main directory table
PageEntry entry_init; //Handler for pages that need init
PageLink link_init; //Handler for pages that need init
Bit32u base_page; //Base got from CR3
PageChange * table_change;
PageChange * dir_change;
};
struct PagingBlock {
PageDirectory * cache;
PageDirectory * dir;
PageLink * free_link;
Bitu cr3;
Bitu cr2;
struct {
Bitu page;
PhysPt addr;
} base;
struct {
HostPt read[TLB_SIZE];
HostPt write[TLB_SIZE];
PageHandler * handler[TLB_SIZE];
Bit32u phys_page[TLB_SIZE];
} tlb;
struct {
Bitu used;
Bit32u entries[PAGING_LINKS];
} links;
bool enabled;
};
@ -145,24 +120,7 @@ extern PagingBlock paging;
/* Some support functions */
static INLINE PageLink * GetPageLink(PhysPt address) {
Bitu index=(address>>12);
return paging.dir->links[index];
}
void PAGING_AddFreePageLink(PageLink * link);
PageLink * PAGING_GetFreePageLink(void);
void MEM_SetupVGA(VGA_RANGES range,HostPt base);
/* Page Handler functions */
Bit8u ENTRY_readb(PageEntry * pentry,PhysPt address);
Bit16u ENTRY_readw(PageEntry * pentry,PhysPt address);
Bit32u ENTRY_readd(PageEntry * pentry,PhysPt address);
void ENTRY_writeb(PageEntry * pentry,PhysPt address,Bit8u val);
void ENTRY_writew(PageEntry * pentry,PhysPt address,Bit16u val);
void ENTRY_writed(PageEntry * pentry,PhysPt address,Bit32u val);
PageHandler * MEM_GetPageHandler(Bitu phys_page);
/* Unaligned address handlers */
Bit16u mem_unalignedreadw(PhysPt address);
@ -173,52 +131,51 @@ void mem_unalignedwrited(PhysPt address,Bit32u val);
/* Special inlined memory reading/writing */
INLINE Bit8u mem_readb_inline(PhysPt address) {
PageLink * plink=GetPageLink(address);
if (plink->read) return readb(plink->read+address);
else return ENTRY_readb(plink->entry,address);
Bitu index=(address>>12);
if (paging.tlb.read[index]) return host_readb(paging.tlb.read[index]+address);
else return paging.tlb.handler[index]->readb(address);
}
INLINE Bit16u mem_readw_inline(PhysPt address) {
if (address & 1) return mem_unalignedreadw(address);
PageLink * plink=GetPageLink(address);
if (plink->read) return readw(plink->read+address);
else return ENTRY_readw(plink->entry,address);
Bitu index=(address>>12);
if (paging.tlb.read[index]) return host_readw(paging.tlb.read[index]+address);
else return paging.tlb.handler[index]->readw(address);
}
INLINE Bit32u mem_readd_inline(PhysPt address) {
if (address & 3) return mem_unalignedreadd(address);
PageLink * plink=GetPageLink(address);
if (plink->read) return readd(plink->read+address);
else return ENTRY_readd(plink->entry,address);
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);
}
INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
PageLink * plink=GetPageLink(address);
Bitu index=(address>>12);
if (plink->write) writeb(plink->write+address,val);
else ENTRY_writeb(plink->entry,address,val);
if (paging.tlb.write[index]) host_writeb(paging.tlb.write[index]+address,val);
else paging.tlb.handler[index]->writeb(address,val);
}
INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
if (address & 1) {mem_unalignedwritew(address,val);return;}
PageLink * plink=GetPageLink(address);
Bitu index=(address>>12);
if (plink->write) writew(plink->write+address,val);
else ENTRY_writew(plink->entry,address,val);
if (paging.tlb.write[index]) host_writew(paging.tlb.write[index]+address,val);
else paging.tlb.handler[index]->writew(address,val);
}
INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
if (address & 3) {mem_unalignedwrited(address,val);return;}
PageLink * plink=GetPageLink(address);
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);
if (plink->write) writed(plink->write+address,val);
else ENTRY_writed(plink->entry,address,val);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -49,20 +49,20 @@ INLINE Bit64u PIC_MicroCount(void) {
return PIC_Ticks*1000+PIC_Index();
}
void PIC_ActivateIRQ(Bit32u irq);
void PIC_ActivateIRQ(Bitu irq);
void PIC_DeActivateIRQ(Bit32u irq);
void PIC_DeActivateIRQ(Bitu irq);
void PIC_runIRQs(void);
void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name);
void PIC_FreeIRQ(Bit32u irq);
void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name);
void PIC_FreeIRQ(Bitu irq);
bool PIC_RunQueue(void);
void PIC_AddIRQ(Bitu irq,Bitu delay);
void PIC_AddEvent(PIC_EventHandler handler,Bitu delay);
void PIC_RemoveEvents(PIC_EventHandler handler);
void PIC_SetIRQMask(Bitu irq, bool masked);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -21,40 +21,33 @@
#include <mem.h>
struct Flag_Info {
union {
Bit8u b;
Bit16u w;
Bit32u d;
} var1,var2,result;
Bitu type;
Bitu prev_type;
Bitu oldcf;
Bitu word;
};
#define FLAG_CF 0x00000001
#define FLAG_PF 0x00000004
#define FLAG_AF 0x00000010
#define FLAG_ZF 0x00000040
#define FLAG_SF 0x00000080
#define FLAG_OF 0x00000800
#define FLAG_TF 0x00000100
#define FLAG_IF 0x00000200
#define FLAG_DF 0x00000400
#define FLAG_OF 0x00000800
#define FLAG_MASK (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)
#define FLAG_IOPL 0x00003000
#define FLAG_NT 0x00004000
#define FLAG_VM 0x00020000
#define FLAG_AC 0x00040000
#define FLAG_ID 0x00200000
#define FMASK_TEST (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)
#define FMASK_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF | FLAG_AC )
#define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT)
#define SETFLAGBIT(TYPE,TEST) if (TEST) flags.word|=FLAG_ ## TYPE; else flags.word&=~FLAG_ ## TYPE
#define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE
#define GETFLAG(TYPE) (flags.word & FLAG_ ## TYPE)
#define GETFLAGBOOL(TYPE) ((flags.word & FLAG_ ## TYPE) ? true : false )
#define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE)
#define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false )
#define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12)
struct Segment {
Bit16u val;
@ -91,17 +84,13 @@ union GenReg32 {
#endif
struct CPU_Regs {
GenReg32 regs[8],ip;
GenReg32 regs[8],ip;
Bitu flags;
};
extern Segments Segs;
extern Flag_Info flags;
extern CPU_Regs cpu_regs;
//#define SegPhys(index) Segs[index].phys
//#define SegValue(index) Segs[index].val
INLINE PhysPt SegPhys(SegNames index) {
return Segs.phys[index];
}
@ -110,7 +99,6 @@ INLINE Bit16u SegValue(SegNames index) {
return Segs.val[index];
}
INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
return RealMake(SegValue(index),off);
}
@ -121,7 +109,6 @@ INLINE void SegSet16(Bitu index,Bit16u val) {
Segs.phys[index]=val << 4;
}
enum {
REGI_AX, REGI_CX, REGI_DX, REGI_BX,
REGI_SP, REGI_BP, REGI_SI, REGI_DI
@ -140,7 +127,6 @@ enum {
#define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX])
#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
#define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX]
#define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX]
#define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX]
@ -176,5 +162,7 @@ enum {
#define reg_ip cpu_regs.ip.word[W_INDEX]
#define reg_eip cpu_regs.ip.dword[DW_INDEX]
#define reg_flags cpu_regs.flags
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,30 +16,25 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __RENDER_H
#define __RENDER_H
enum RENDER_Operation {
OP_None,
OP_Shot,
OP_Normal2x,
OP_AdvMame2x,
OP_Blit,
};
enum {
DoubleNone= 0x00,
DoubleWidth= 0x01,
DoubleHeight= 0x02,
DoubleBoth= 0x03
};
typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy);
typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler);
void RENDER_DoUpdate(void);
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler);
typedef void (* RENDER_Line_Handler)(Bit8u * src);
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh);
bool RENDER_StartUpdate(void);
void RENDER_EndUpdate(void);
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
extern RENDER_Line_Handler RENDER_DrawLine;
extern Bit8u * RENDER_TempLine;
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: setup.h,v 1.15 2004/01/29 09:26:43 qbix79 Exp $ */
#ifndef _SETUP_H_
#define _SETUP_H_
@ -53,6 +55,7 @@ union Value{
bool _bool;
int _int;
std::string* _string;
float _float;
};
class Property {
@ -75,6 +78,15 @@ public:
void GetValuestring(char* str);
~Prop_int(){ }
};
class Prop_float:public Property {
public:
Prop_float(const char* _propname, float _value):Property(_propname){
__value._float=_value;
}
void SetValue(char* input);
void GetValuestring(char* str);
~Prop_float(){ }
};
class Prop_bool:public Property {
public:
@ -143,11 +155,13 @@ class Section_prop:public Section {
void Add_string(const char* _propname, char* _value=NULL);
void Add_bool(const char* _propname, bool _value=false);
void Add_hex(const char* _propname, int _value=0);
void Add_float(const char* _propname, float _value=0.0);
int Get_int(const char* _propname);
const char* Get_string(const char* _propname);
bool Get_bool(const char* _propname);
int Get_hex(const char* _propname);
int Get_hex(const char* _propname);
float Get_float(const char* _propname);
void HandleInputline(char *gegevens);
void PrintData(FILE* outfile);
@ -180,7 +194,7 @@ public:
void ShutDown();
void StartUp();
void PrintConfig(const char* configfilename);
void ParseConfigFile(const char* configfilename);
bool ParseConfigFile(const char* configfilename);
void ParseEnv(char ** envp);
std::list<Section*> sectionlist;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,7 +16,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_inc.h,v 1.17 2003/09/08 18:19:28 qbix79 Exp $ */
/* $Id: shell.h,v 1.2 2004/01/10 14:03:33 qbix79 Exp $ */
#ifndef SHELL_H_
#define SHELL_H_
#include <ctype.h>
#include <stdio.h>
@ -96,6 +100,8 @@ public:
void CMD_CALL(char * args);
void SyntaxError(void);
void CMD_PAUSE(char * args);
void CMD_SUBST(char* args);
void CMD_LOADHIGH(char* args);
/* The shell's variables */
Bit16u input_handle;
BatchFile * bf;
@ -140,3 +146,4 @@ static inline char* ExpandDot(char*args, char* buffer)
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -33,6 +33,9 @@
//#define nocasestrcmp(a,b) stricmp(a,b)
#endif
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
void strreplace(char * str,char o,char n);
char *ltrim(char *str);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -23,8 +23,9 @@
#include "dosbox.h"
enum VGAModes {
M_TEXT16,
M_CGA2,M_CGA4,
M_TEXT2,M_TEXT16,
M_HERC,
M_CGA2,M_CGA4,M_CGA16,
M_TANDY16,
M_EGA2,M_EGA4,M_EGA16,
M_VGA,
@ -42,16 +43,6 @@ enum VGAModes {
#define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R))))
#define S3_MAX_CLOCK 150000 /* KHz */
/* Different functions that should be handle by memory handler */
#define MH_ROTATEOP 0x0001;
#define MH_SETRESET 0x0002;
#define MH_BITMASK 0x0004;
typedef Bit8u VGA_ReadHandler(PhysPt off);
typedef void VGA_WriteHandler(PhysPt off,Bit8u val);
typedef struct {
bool attrindex;
} VGA_Internal;
@ -73,9 +64,6 @@ typedef struct {
bool chained; /* Enable or Disabled Chain 4 Mode */
bool blinking; /* Attribute bit 7 is blinking */
bool vline_double;
Bit8u vline_height;
/* Pixel Scrolling */
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
Bit8u hlines_skip;
@ -83,9 +71,6 @@ typedef struct {
/* Specific stuff memory write/read handling */
VGA_ReadHandler * readhandler;
VGA_WriteHandler * writehandler;
Bit8u read_mode;
Bit8u write_mode;
Bit8u read_map_select;
@ -106,18 +91,40 @@ typedef struct {
typedef struct {
bool resizing;
bool drawing;
Bitu width;
Bitu height;
Bitu pitch;
Bitu blank;
bool double_width;
bool double_height;
Bitu lines;
Bitu blocks;
Bitu panning;
Bitu address;
Bitu address_add;
Bitu address_line_total;
Bitu address_line;
Bitu lines_total;
Bitu lines_left;
Bitu lines_scaled;
Bitu split_line;
Bitu parts_total;
Bitu parts_lines;
Bitu parts_left;
struct {
Bitu vtotal;
Bitu vstart;
Bitu vend;
Bitu htotal;
Bitu hstart;
Bitu hend;
Bitu parts;
} micro;
Bitu scaleh;
bool double_scan;
bool double_scan_active;
Bit8u font_height;
Bit8u font[64*1024];
Bitu font1_start;
Bitu font2_start;
Bitu rows,cols;
Bitu blinking;
struct {
Bit8u sline,eline;
Bit8u count,delay;
@ -150,6 +157,12 @@ typedef struct {
} VGA_S3;
typedef struct {
Bit8u mode_control;
Bit8u enable_bits;
} VGA_HERC;
typedef struct {
Bit8u mode_control;
Bit8u color_select;
} VGA_CGA;
@ -157,6 +170,10 @@ typedef struct {
Bit8u mem_bank;
Bit8u disp_bank;
Bit8u reg_index;
Bit8u mode_control1;
Bit8u palette_mask;
Bit8u border_color;
Bit8u mode_control2;
} VGA_TANDY;
typedef struct {
@ -267,6 +284,7 @@ typedef struct {
VGA_Dac dac;
VGA_Latch latch;
VGA_S3 s3;
VGA_HERC herc;
VGA_CGA cga;
VGA_TANDY tandy;
VGA_Memory mem;
@ -298,12 +316,18 @@ void VGA_SetClock(Bitu which,Bitu target);
void VGA_DACSetEntirePalette(void);
void VGA_StartRetrace(void);
void VGA_StartUpdateLFB(void);
void VGA_SetBlinking(Bitu enabled);
extern VGA_Type vga;
extern Bit32u ExpandTable[256];
extern Bit32u FillTable[16];
extern Bit32u CGA_2_Table[16];
extern Bit32u CGA_4_Table[256];
extern Bit32u CGA_16_Table[256];
extern Bit32u TXT_Font_Table[16];
extern Bit32u TXT_FG_Table[16];
extern Bit32u TXT_BG_Table[16];
extern Bit32u Expand16Table[4][16];
extern Bit32u Expand16BigTable[0x10000];

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -19,10 +19,7 @@
#ifndef __VIDEO_H
#define __VIDEO_H
typedef void (* GFX_ModeCallBack)(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags);
typedef void (* GFX_DrawCallBack)(void * data);
typedef void (* GFX_ResetCallBack)(void);
struct GFX_PalEntry {
Bit8u r;
@ -31,30 +28,21 @@ struct GFX_PalEntry {
Bit8u unused;
};
#define GFX_FIXED_BPP 0x01
#define GFX_RESIZEABLE 0x02
#define GFX_SHADOW 0x04
#define GFX_BLITTING 0x08
#define MODE_SET 0x01
#define MODE_FULLSCREEN 0x02
#define MODE_RESIZE 0x04
#define GFX_HASSCALING 0x0001
#define GFX_HASCONVERT 0x0002
void GFX_Events(void);
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags);
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback);
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset);
void GFX_Start(void);
void GFX_Stop(void);
void GFX_SwitchFullScreen(void);
void GFX_Render_Blit(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy);
void GFX_DoUpdate(void);
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
void GFX_EndUpdate(void);
#endif

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -443,7 +443,7 @@ install-am: all-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -462,7 +462,6 @@ 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
@ -487,7 +486,6 @@ installcheck-am: installcheck-binPROGRAMS
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

View File

@ -1,6 +1,7 @@
SUBDIRS = core_16 core_full core_normal
SUBDIRS = core_full core_normal core_dyn_x86
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp
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_dyn_x86.cpp

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -129,12 +129,13 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = core_16 core_full core_normal
SUBDIRS = core_full core_normal core_dyn_x86
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp
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_dyn_x86.cpp
subdir = src/cpu
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -146,17 +147,18 @@ LIBRARIES = $(noinst_LIBRARIES)
libcpu_a_AR = $(AR) cru
libcpu_a_LIBADD =
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
modrm.$(OBJEXT) slow_16.$(OBJEXT) core_full.$(OBJEXT) \
paging.$(OBJEXT) core_normal.$(OBJEXT)
modrm.$(OBJEXT) core_full.$(OBJEXT) paging.$(OBJEXT) \
core_normal.$(OBJEXT) core_dyn_x86.$(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 ./$(DEPDIR)/core_full.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_normal.Po ./$(DEPDIR)/cpu.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/flags.Po ./$(DEPDIR)/modrm.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/paging.Po ./$(DEPDIR)/slow_16.Po
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_dyn_x86.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/core_full.Po ./$(DEPDIR)/core_normal.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/cpu.Po ./$(DEPDIR)/flags.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/modrm.Po ./$(DEPDIR)/paging.Po
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
@ -203,13 +205,13 @@ 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_full.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_normal.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@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slow_16.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@ -419,7 +421,7 @@ install-am: all-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -438,7 +440,6 @@ 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
@ -463,7 +464,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,10 +16,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.cpp,v 1.16 2003/09/29 21:06:49 qbix79 Exp $ */
/* $Id: callback.cpp,v 1.19 2004/01/07 20:23:48 qbix79 Exp $ */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dosbox.h"
#include "callback.h"
@ -34,6 +35,8 @@
CallBack_Handler CallBack_Handlers[CB_MAX];
char* CallBack_Description[CB_MAX];
static Bitu call_stop,call_idle,call_default;
static Bitu illegal_handler(void) {
@ -95,9 +98,8 @@ void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
void CALLBACK_RunRealInt(Bit8u intnum) {
Bit32u oldeip=reg_eip;
Bit16u oldcs=SegValue(cs);
reg_eip=call_stop<<4;
reg_eip=(CB_MAX*16)+(intnum*6);
SegSet16(cs,CB_SEG);
Interrupt(intnum);
DOSBOX_RunMachine();
reg_eip=oldeip;
SegSet16(cs,oldcs);
@ -117,9 +119,22 @@ void CALLBACK_SCF(bool val) {
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF));
};
void CALLBACK_SetDescription(Bitu nr, const char* descr)
{
if (descr) {
CallBack_Description[nr] = new char[strlen(descr)+1];
strcpy(CallBack_Description[nr],descr);
} else
CallBack_Description[nr] = 0;
};
const char* CALLBACK_GetDescription(Bitu nr)
{
if (nr>=CB_MAX) return 0;
return CallBack_Description[nr];
};
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) {
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) {
if (callback>=CB_MAX) return false;
switch (type) {
case CB_RETF:
@ -147,10 +162,11 @@ bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) {
}
CallBack_Handlers[callback]=handler;
CALLBACK_SetDescription(callback,descr);
return true;
}
bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress) {
bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu linearAddress,const char* descr) {
if (callback>=CB_MAX) return false;
switch (type) {
case CB_RETF:
@ -176,6 +192,7 @@ bool CALLBACK_SetupAt(Bitu callback,CallBack_Handler handler,Bitu type,Bitu line
E_Exit("CALLBACK:Setup:Illegal type %d",type);
}
CallBack_Handlers[callback]=handler;
CALLBACK_SetDescription(callback,descr);
return true;
}
@ -205,7 +222,19 @@ void CALLBACK_Init(Section* sec) {
for (i=0;i<0x40;i++) {
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
}
/* Setup block of 0xCD 0xxx instructions */
PhysPt rint_base=CB_BASE+CB_MAX*16;
for (i=0;i<=0xff;i++) {
phys_writeb(rint_base,0xCD);
phys_writeb(rint_base+1,i);
phys_writeb(rint_base+2,0xFE);
phys_writeb(rint_base+3,0x38);
phys_writew(rint_base+4,call_stop);
rint_base+=6;
}
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff
//real_writed(0,0xf*4,0); some games don't like it
}

View File

@ -1,3 +0,0 @@
noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h support.h table_ea.h \
prefix_66_of.h

View File

@ -1,143 +0,0 @@
/*
* Copyright (C) 2002 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 GetEAa \
PhysPt eaa=(*lookupEATable)[rm]();
#define GetRMEAa \
GetRM; \
GetEAa;
#define RMEbGb(inst) \
{ \
GetRMrb; \
if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \
else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \
}
#define RMGbEb(inst) \
{ \
GetRMrb; \
if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \
else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \
}
#define RMEb(inst) \
{ \
if (rm >= 0xc0 ) {GetEArb;inst(*earb,LoadRb,SaveRb);} \
else {GetEAa;inst(eaa,LoadMb,SaveMb);} \
}
#define RMEwGw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
}
#define RMEwGwOp3(inst,op3) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,op3,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,*rmrw,op3,LoadMw,SaveMw);} \
}
#define RMGwEw(inst) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
}
#define RMGwEwOp3(inst,op3) \
{ \
GetRMrw; \
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,op3,LoadRw,SaveRw);} \
else {GetEAa;inst(*rmrw,LoadMw(eaa),op3,LoadRw,SaveRw);} \
}
#define RMEw(inst) \
{ \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
}
#define RMEdGd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
}
#define RMEdGdOp3(inst,op3) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,op3,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,*rmrd,op3,LoadMd,SaveMd);} \
}
#define RMGdEd(inst) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
}
#define RMGdEdOp3(inst,op3) \
{ \
GetRMrd; \
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,op3,LoadRd,SaveRd);} \
else {GetEAa;inst(*rmrd,LoadMd(eaa),op3,LoadRd,SaveRd);} \
}
#define RMEw(inst) \
{ \
if (rm >= 0xc0 ) {GetEArw;inst(*earw,LoadRw,SaveRw);} \
else {GetEAa;inst(eaa,LoadMw,SaveMw);} \
}
#define RMEd(inst) \
{ \
if (rm >= 0xc0 ) {GetEArd;inst(*eard,LoadRd,SaveRd);} \
else {GetEAa;inst(eaa,LoadMd,SaveMd);} \
}
#define ALIb(inst) \
{ inst(reg_al,Fetchb(),LoadRb,SaveRb)}
#define AXIw(inst) \
{ inst(reg_ax,Fetchw(),LoadRw,SaveRw);}
#define EAXId(inst) \
{ inst(reg_eax,Fetchd(),LoadRd,SaveRd);}
#define FPU_ESC(code) { \
Bit8u rm=Fetchb(); \
if (rm>=0xc0) { \
FPU_ESC ## code ## _Normal(rm); \
} else { \
GetEAa;FPU_ESC ## code ## _EA(rm,eaa); \
} \
}

File diff suppressed because it is too large Load Diff

View File

@ -1,490 +0,0 @@
/*
* Copyright (C) 2002 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.
*/
restart_66:
switch(Fetchb()) {
case 0x01: /* ADD Ed,Gd */
RMEdGd(ADDD);break;
case 0x03: /* ADD Gd,Ed */
RMGdEd(ADDD);break;
case 0x05: /* ADD EAX,Id */
EAXId(ADDD);break;
case 0x09: /* OR Ed,Gd */
RMEdGd(ORD);break;
case 0x0b: /* OR Gd,Ed */
RMGdEd(ORD);break;
case 0x0d: /* OR EAX,Id */
EAXId(ORD);break;
case 0x0f: /* 2 Byte opcodes */
#include "prefix_66_of.h"
break;
case 0x11: /* ADC Ed,Gd */
RMEdGd(ADCD);break;
case 0x13: /* ADC Gd,Ed */
RMGdEd(ADCD);break;
case 0x15: /* ADC EAX,Id */
EAXId(ADCD);break;
case 0x19: /* SBB Ed,Gd */
RMEdGd(SBBD);break;
case 0x1b: /* SBB Gd,Ed */
RMGdEd(SBBD);break;
case 0x1d: /* SBB EAX,Id */
EAXId(SBBD);break;
case 0x21: /* AND Ed,Gd */
RMEdGd(ANDD);break;
case 0x23: /* AND Gd,Ed */
RMGdEd(ANDD);break;
case 0x25: /* AND EAX,Id */
EAXId(ANDD);break;
case 0x29: /* SUB Ed,Gd */
RMEdGd(SUBD);break;
case 0x2b: /* SUB Gd,Ed */
RMGdEd(SUBD);break;
case 0x2d: /* SUB EAX,Id */
EAXId(SUBD);break;
case 0x31: /* XOR Ed,Gd */
RMEdGd(XORD);break;
case 0x33: /* XOR Gd,Ed */
RMGdEd(XORD);break;
case 0x35: /* XOR EAX,Id */
EAXId(XORD);break;
case 0x39: /* CMP Ed,Gd */
RMEdGd(CMPD);break;
case 0x3b: /* CMP Gd,Ed */
RMGdEd(CMPD);break;
case 0x3d: /* CMP EAX,Id */
EAXId(CMPD);break;
case 0x26: /* SEG ES: */
SegPrefix_66(es);break;
case 0x2e: /* SEG CS: */
SegPrefix_66(cs);break;
case 0x36: /* SEG SS: */
SegPrefix_66(ss);break;
case 0x3e: /* SEG DS: */
SegPrefix_66(ds);break;
case 0x40: /* INC EAX */
INCD(reg_eax,LoadRd,SaveRd);break;
case 0x41: /* INC ECX */
INCD(reg_ecx,LoadRd,SaveRd);break;
case 0x42: /* INC EDX */
INCD(reg_edx,LoadRd,SaveRd);break;
case 0x43: /* INC EBX */
INCD(reg_ebx,LoadRd,SaveRd);break;
case 0x44: /* INC ESP */
INCD(reg_esp,LoadRd,SaveRd);break;
case 0x45: /* INC EBP */
INCD(reg_ebp,LoadRd,SaveRd);break;
case 0x46: /* INC ESI */
INCD(reg_esi,LoadRd,SaveRd);break;
case 0x47: /* INC EDI */
INCD(reg_edi,LoadRd,SaveRd);break;
case 0x48: /* DEC EAX */
DECD(reg_eax,LoadRd,SaveRd);break;
case 0x49: /* DEC ECX */
DECD(reg_ecx,LoadRd,SaveRd);break;
case 0x4a: /* DEC EDX */
DECD(reg_edx,LoadRd,SaveRd);break;
case 0x4b: /* DEC EBX */
DECD(reg_ebx,LoadRd,SaveRd);break;
case 0x4c: /* DEC ESP */
DECD(reg_esp,LoadRd,SaveRd);break;
case 0x4d: /* DEC EBP */
DECD(reg_ebp,LoadRd,SaveRd);break;
case 0x4e: /* DEC ESI */
DECD(reg_esi,LoadRd,SaveRd);break;
case 0x4f: /* DEC EDI */
DECD(reg_edi,LoadRd,SaveRd);break;
case 0x50: /* PUSH EAX */
Push_32(reg_eax);break;
case 0x51: /* PUSH ECX */
Push_32(reg_ecx);break;
case 0x52: /* PUSH EDX */
Push_32(reg_edx);break;
case 0x53: /* PUSH EBX */
Push_32(reg_ebx);break;
case 0x54: /* PUSH ESP */
Push_32(reg_esp);break;
case 0x55: /* PUSH EBP */
Push_32(reg_ebp);break;
case 0x56: /* PUSH ESI */
Push_32(reg_esi);break;
case 0x57: /* PUSH EDI */
Push_32(reg_edi);break;
case 0x58: /* POP EAX */
reg_eax=Pop_32();break;
case 0x59: /* POP ECX */
reg_ecx=Pop_32();break;
case 0x5a: /* POP EDX */
reg_edx=Pop_32();break;
case 0x5b: /* POP EBX */
reg_ebx=Pop_32();break;
case 0x5c: /* POP ESP */
reg_esp=Pop_32();break;
case 0x5d: /* POP EBP */
reg_ebp=Pop_32();break;
case 0x5e: /* POP ESI */
reg_esi=Pop_32();break;
case 0x5f: /* POP EDI */
reg_edi=Pop_32();break;
case 0x60: /* PUSHAD */
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
break;
case 0x61: /* POPAD */
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
break;
case 0x64: /* SEG FS: */
SegPrefix_66(fs);break;
case 0x65: /* SEG GS: */
SegPrefix_66(gs);break;
case 0x67: /* Address Size Prefix */
#ifdef CPU_PREFIX_67
core_16.prefixes^=PREFIX_ADDR;
lookupEATable=EAPrefixTable[core_16.prefixes];
goto restart_66;
#else
NOTDONE;
#endif
case 0x68: /* PUSH Id */
Push_32(Fetchd());break;
case 0x69: /* IMUL Gd,Ed,Id */
RMGdEdOp3(DIMULD,Fetchds());
break;
case 0x6a: /* PUSH Ib */
Push_32(Fetchbs());break;
case 0x6b: /* IMUL Gd,Ed,Ib */
RMGdEdOp3(DIMULD,Fetchbs());
break;
case 0x81: /* Grpl Ed,Id */
{
GetRM;
if (rm>= 0xc0) {
GetEArd;Bit32u id=Fetchd();
switch (rm & 0x38) {
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
}
} else {
GetEAa;Bit32u id=Fetchd();
switch (rm & 0x38) {
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
}
}
}
break;
case 0x83: /* Grpl Ed,Ix */
{
GetRM;
if (rm>= 0xc0) {
GetEArd;Bit32u id=(Bit32s)Fetchbs();
switch (rm & 0x38) {
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
}
} else {
GetEAa;Bit32u id=(Bit32s)Fetchbs();
switch (rm & 0x38) {
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
}
}
}
break;
case 0x85: /* TEST Ed,Gd */
RMEdGd(TESTD);break;
case 0x87: /* XCHG Ev,Gv */
{
GetRMrd;Bit32u oldrmrd=*rmrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;*eard=oldrmrd;}
else {GetEAa;*rmrd=LoadMd(eaa);SaveMd(eaa,oldrmrd);}
break;
}
case 0x89: /* MOV Ed,Gd */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
else {GetEAa;SaveMd(eaa,*rmrd);}
break;
}
case 0x8b: /* MOV Gd,Ed */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
else {GetEAa;*rmrd=LoadMd(eaa);}
break;
}
case 0x8c:
LOG(LOG_CPU,LOG_NORMAL)("CPU:66:8c looped back");
break;
case 0x8d: /* LEA */
{
core_16.segbase=0;
core_16.prefixes|=PREFIX_SEG;
lookupEATable=EAPrefixTable[core_16.prefixes];
GetRMrd;GetEAa;
*rmrd=(Bit32u)eaa;
break;
}
case 0x8f: /* POP Ed */
{
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
else {GetEAa;SaveMd(eaa,Pop_32());}
break;
}
case 0x90: /* NOP */
break;
case 0x91: /* XCHG ECX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ecx;reg_ecx=temp; }
break;
case 0x92: /* XCHG EDX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_edx;reg_edx=temp; }
break;
case 0x93: /* XCHG EBX,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ebx;reg_ebx=temp; }
break;
case 0x94: /* XCHG ESP,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_esp;reg_esp=temp; }
break;
case 0x95: /* XCHG EBP,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_ebp;reg_ebp=temp; }
break;
case 0x96: /* XCHG ESI,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_esi;reg_esi=temp; }
break;
case 0x97: /* XCHG EDI,EAX */
{ Bit32u temp=reg_eax;reg_eax=reg_edi;reg_edi=temp; }
break;
case 0x98: /* CWD */
reg_eax=(Bit16s)reg_ax;break;
case 0x99: /* CDQ */
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
else reg_edx=0;
break;
case 0x9c: /* PUSHFD */
FillFlags();
Push_32(flags.word);
break;
case 0x9d: /* POPFD */
SETFLAGSd(Pop_32())
CheckTF();
#ifdef CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
#endif
break;
case 0xa1: /* MOV EAX,Ow */
reg_eax=LoadMd(GetEADirect[core_16.prefixes]());
break;
case 0xa3: /* MOV Ow,EAX */
SaveMd(GetEADirect[core_16.prefixes](),reg_eax);
break;
case 0xa5: /* MOVSD */
{
stringSI;stringDI;SaveMd(to,LoadMd(from));
if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; }
else { reg_si+=4;reg_di+=4;}
}
break;
case 0xa7: /* CMPSD */
{
stringSI;stringDI; CMPD(to,LoadMd(from),LoadMd,0);
if (GETFLAG(DF)) { reg_si-=4;reg_di-=4; }
else { reg_si+=4;reg_di+=4;}
}
break;
case 0xa9: /* TEST EAX,Id */
EAXId(TESTD);
break;
case 0xab: /* STOSD */
{
stringDI;
SaveMd(to,reg_eax);
if (GETFLAG(DF)) { reg_di-=4; }
else {reg_di+=4;}
break;
}
case 0xad: /* LODSD */
{
stringSI;
reg_eax=LoadMd(from);
if (GETFLAG(DF)) { reg_si-=4;}
else {reg_si+=4;}
break;
}
case 0xaf: /* SCASD */
{
stringDI;
CMPD(reg_eax,LoadMd(to),LoadRd,0);
if (GETFLAG(DF)) { reg_di-=4; }
else {reg_di+=4;}
break;
}
case 0xb8: /* MOV EAX,Id */
reg_eax=Fetchd();break;
case 0xb9: /* MOV ECX,Id */
reg_ecx=Fetchd();break;
case 0xba: /* MOV EDX,Iw */
reg_edx=Fetchd();break;
case 0xbb: /* MOV EBX,Id */
reg_ebx=Fetchd();break;
case 0xbc: /* MOV ESP,Id */
reg_esp=Fetchd();break;
case 0xbd: /* MOV EBP.Id */
reg_ebp=Fetchd();break;
case 0xbe: /* MOV ESI,Id */
reg_esi=Fetchd();break;
case 0xbf: /* MOV EDI,Id */
reg_edi=Fetchd();break;
case 0xc1: /* GRP2 Ed,Ib */
GRP2D(Fetchb());break;
case 0xc4: /* LES */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(es,LoadMw(eaa+4));
break;
}
case 0xc5: /* LDS */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);SegSet16(ds,LoadMw(eaa+4));
break;
}
case 0xc7: /* MOV Ed,Id */
{
GetRM;
if (rm>0xc0) {GetEArd;*eard=Fetchd();}
else {GetEAa;SaveMd(eaa,Fetchd());}
break;
}
case 0xd1: /* GRP2 Ed,1 */
GRP2D(1);break;
case 0xd3: /* GRP2 Ed,CL */
GRP2D(reg_cl);break;
case 0xed: /* IN EAX,DX */
reg_eax=IO_Read(reg_dx) |
(IO_Read(reg_dx+1) << 8) |
(IO_Read(reg_dx+2) << 16) |
(IO_Read(reg_dx+3) << 24);
break;
case 0xef: /* OUT DX,EAX */
IO_Write(reg_dx,(Bit8u)(reg_eax>>0));
IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8));
IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16));
IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24));
break;
case 0xf2: /* REPNZ */
Repeat_Normal(false,true);
continue;
case 0xf3: /* REPZ */
Repeat_Normal(true,true);
continue;
case 0xf7: /* GRP3 Ed(,Id) */
{
GetRM;
switch ((rm & 0x38)>>3) {
case 0x00: /* TEST Ed,Id */
case 0x01: /* TEST Ed,Id Undocumented*/
{
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
break;
}
case 0x02: /* NOT Ed */
{
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
break;
}
case 0x03: /* NEG Ed */
{
flags.type=t_NEGd;
if (rm >= 0xc0 ) {
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
*eard=flags.result.d;
} else {
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
SaveMd(eaa,flags.result.d);
}
break;
}
case 0x04: /* MUL EAX,Ed */
RMEd(MULD);
break;
case 0x05: /* IMUL EAX,Ed */
RMEd(IMULD);
break;
case 0x06: /* DIV Ed */
RMEd(DIVD);
break;
case 0x07: /* IDIV Ed */
RMEd(IDIVD);
break;
}
break;
}
case 0xff: /* Group 5 */
{
GetRM;
switch (rm & 0x38) {
case 0x00: /* INC Ed */
RMEd(INCD);
break;
case 0x08: /* DEC Ed */
RMEd(DECD);
break;
case 0x30: /* Push Ed */
if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
else {GetEAa;Push_32(LoadMd(eaa));}
break;
default:
E_Exit("CPU:66:GRP5:Illegal call %2X",rm & 0x38);
break;
}
break;
}
default:
NOTDONE66;
}

View File

@ -1,226 +0,0 @@
/*
* Copyright (C) 2002 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.
*/
switch (Fetchb()) {
case 0x01: /* Group 7 Ed */
{
GetRM;Bitu which=(rm>>3)&7;
if (rm < 0xc0) { //First ones all use EA
GetEAa;Bitu limit,base;
switch (which) {
case 0x00: /* SGDT */
CPU_SGDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x01: /* SIDT */
CPU_SIDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x02: /* LGDT */
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2));
break;
case 0x03: /* LIDT */
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2));
break;
case 0x04: /* SMSW */
CPU_SMSW(limit);
SaveMw(eaa,limit);
break;
case 0x06: /* LMSW */
limit=LoadMw(eaa);
if (!CPU_LMSW(limit)) goto decode_end;
break;
}
} else {
GetEArw;Bitu limit;
switch (which) {
case 0x04: /* SMSW */
CPU_SMSW(limit);
*earw=limit;
break;
case 0x06: /* LMSW */
if (!CPU_LMSW(*earw)) goto decode_end;
break;
default:
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
break;
}
}
}
break;
case 0xa4: /* SHLD Ed,Gd,Ib */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
break;
}
case 0xac: /* SHRD Ed,Gd,Ib */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
break;
}
case 0xad: /* SHRD Ed,Gd,Cl */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,reg_cl,LoadRd,SaveRd);}
else {GetEAa;DSHRD(eaa,*rmrd,reg_cl,LoadMd,SaveMd);}
break;
}
case 0xb6: /* MOVZX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
else {GetEAa;*rmrd=LoadMb(eaa);}
break;
}
case 0xaf: /* IMUL Gd,Ed */
{
RMGdEdOp3(DIMULD,*rmrd);
break;
};
case 0xb7: /* MOVXZ Gd,Ew */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
else {GetEAa;*rmrd=LoadMw(eaa);}
break;
}
case 0xba: /* GRP8 Ed,Ib */
{
GetRM;
if (rm >= 0xc0 ) {
GetEArd;
Bit32u mask=1 << (Fetchb() & 31);
SETFLAGBIT(CF,(*eard & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*eard|=mask;
break;
case 0x30: /* BTR */
*eard&=~mask;
break;
case 0x38: /* BTC */
if (GETFLAG(CF)) *eard&=~mask;
else *eard|=mask;
break;
default:
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
} else {
GetEAa;Bit32u old=LoadMd(eaa);
Bit32u mask=1 << (Fetchb() & 31);
SETFLAGBIT(CF,(old & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMd(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMd(eaa,old & ~mask);
break;
case 0x38: /* BTC */
if (GETFLAG(CF)) old&=~mask;
else old|=mask;
SaveMd(eaa,old);
break;
default:
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
}
case 0xbb: /* BTC Ed,Gd */
{
GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
*eard^=mask;
} else {
GetEAa;Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbc: /* BSF Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 0;
while ((value & 0x01)==0) { result++; value>>=1; }
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbd: /* BSR Gd,Ed */
{
GetRMrd;
Bit32u result,value;
if (rm >= 0xc0) { GetEArd; value=*eard; }
else { GetEAa; value=LoadMd(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 35; // Operandsize-1
while ((value & 0x80000000)==0) { result--; value<<=1; }
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbe: /* MOVSX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*(Bit8s *)earb;}
else {GetEAa;*rmrd=LoadMbs(eaa);}
break;
}
case 0xbf: /* MOVSX Gd,Ew */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArw;*rmrd=*(Bit16s *)earw;}
else {GetEAa;*rmrd=LoadMws(eaa);}
break;
}
default:
SUBIP(1);
E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb());
}

View File

@ -1,425 +0,0 @@
/*
* Copyright (C) 2002 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.
*/
switch(Fetchb()) {
case 0x00: /* GRP 6 */
{
GetRM;Bitu which=(rm>>3)&7;
switch (which) {
case 0x00: /* SLDT */
case 0x01: /* STR */
{
Bitu saveval;
if (!which) CPU_SLDT(saveval);
else CPU_STR(saveval);
if (rm>0xc0) {GetEArw;*earw=saveval;}
else {GetEAa;SaveMw(eaa,saveval);}
}
break;
case 0x02:case 0x03:case 0x04:case 0x05:
{
Bitu loadval;
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
else {GetEAa;loadval=LoadMw(eaa);}
break;
switch (which) {
case 0x02:CPU_LLDT(loadval);break;
case 0x03:CPU_LTR(loadval);break;
case 0x04:CPU_VERR(loadval);break;
case 0x05:CPU_VERW(loadval);break;
}
}
default:
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
}
}
break;
case 0x01: /* Group 7 Ew */
{
GetRM;Bitu which=(rm>>3)&7;
if (rm < 0xc0) { //First ones all use EA
GetEAa;Bitu limit,base;
switch (which) {
case 0x00: /* SGDT */
CPU_SGDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x01: /* SIDT */
CPU_SIDT(limit,base);
SaveMw(eaa,limit);
SaveMd(eaa+2,base);
break;
case 0x02: /* LGDT */
CPU_LGDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
break;
case 0x03: /* LIDT */
CPU_LIDT(LoadMw(eaa),LoadMd(eaa+2) & 0xFFFFFF);
break;
case 0x04: /* SMSW */
CPU_SMSW(limit);
SaveMw(eaa,limit);
break;
case 0x06: /* LMSW */
limit=LoadMw(eaa);
if (!CPU_LMSW(limit)) goto decode_end;
break;
}
} else {
GetEArw;Bitu limit;
switch (which) {
case 0x04: /* SMSW */
CPU_SMSW(limit);
*earw=limit;
break;
case 0x06: /* LMSW */
if (!CPU_LMSW(*earw)) goto decode_end;
break;
default:
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
break;
}
}
}
break;
case 0x20: /* MOV Rd.CRx */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
*eard=CPU_GET_CRX(which);
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,CR%d with non-register",which);
}
}
break;
case 0x22: /* MOV CRx,Rd */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
if (!CPU_SET_CRX(which,*eard)) goto decode_end;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which);
}
}
break;
case 0x23: /* MOV DRx,Rd */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV DR%,XXX with non-register",which);
}
}
break;
case 0x80: /* JO */
JumpSIw(get_OF());break;
case 0x81: /* JNO */
JumpSIw(!get_OF());break;
case 0x82: /* JB */
JumpSIw(get_CF());break;
case 0x83: /* JNB */
JumpSIw(!get_CF());break;
case 0x84: /* JZ */
JumpSIw(get_ZF());break;
case 0x85: /* JNZ */
JumpSIw(!get_ZF()); break;
case 0x86: /* JBE */
JumpSIw(get_CF() || get_ZF());break;
case 0x87: /* JNBE */
JumpSIw(!get_CF() && !get_ZF());break;
case 0x88: /* JS */
JumpSIw(get_SF());break;
case 0x89: /* JNS */
JumpSIw(!get_SF());break;
case 0x8a: /* JP */
JumpSIw(get_PF());break;
case 0x8b: /* JNP */
JumpSIw(!get_PF());break;
case 0x8c: /* JL */
JumpSIw(get_SF() != get_OF());break;
case 0x8d: /* JNL */
JumpSIw(get_SF() == get_OF());break;
case 0x8e: /* JLE */
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
case 0x8f: /* JNLE */
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
case 0x90: /* SETO */
SETcc(get_OF());break;
case 0x91: /* SETNO */
SETcc(!get_OF());break;
case 0x92: /* SETB */
SETcc(get_CF());break;
case 0x93: /* SETNB */
SETcc(!get_CF());break;
case 0x94: /* SETZ */
SETcc(get_ZF());break;
case 0x95: /* SETNZ */
SETcc(!get_ZF()); break;
case 0x96: /* SETBE */
SETcc(get_CF() || get_ZF());break;
case 0x97: /* SETNBE */
SETcc(!get_CF() && !get_ZF());break;
case 0x98: /* SETS */
SETcc(get_SF());break;
case 0x99: /* SETNS */
SETcc(!get_SF());break;
case 0x9a: /* SETP */
SETcc(get_PF());break;
case 0x9b: /* SETNP */
SETcc(!get_PF());break;
case 0x9c: /* SETL */
SETcc(get_SF() != get_OF());break;
case 0x9d: /* SETNL */
SETcc(get_SF() == get_OF());break;
case 0x9e: /* SETLE */
SETcc(get_ZF() || (get_SF() != get_OF()));break;
case 0x9f: /* SETNLE */
SETcc((get_SF() == get_OF()) && !get_ZF());break;
case 0xa0: /* PUSH FS */
Push_16(SegValue(fs));break;
case 0xa1: /* POP FS */
SegSet16(fs,Pop_16());break;
case 0xa2:
CPU_CPUID();
break;
case 0xa3: /* BT Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xa4: /* SHLD Ew,Gw,Ib */
RMEwGwOp3(DSHLW,Fetchb());
break;
case 0xa5: /* SHLD Ew,Gw,CL */
RMEwGwOp3(DSHLW,reg_cl);
break;
case 0xa8: /* PUSH GS */
Push_16(SegValue(gs));break;
case 0xa9: /* POP GS */
SegSet16(gs,Pop_16());break;
case 0xab: /* BTS Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw|=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xac: /* SHRD Ew,Gw,Ib */
RMEwGwOp3(DSHRW,Fetchb());
break;
case 0xad: /* SHRD Ew,Gw,CL */
RMEwGwOp3(DSHRW,reg_cl);
break;
case 0xaf: /* IMUL Gw,Ew */
RMGwEwOp3(DIMULW,*rmrw);
break;
case 0xb2: /* LSS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(ss,LoadMw(eaa+2));
CPU_Cycles++;//Be sure we run another instruction
break;
}
case 0xb3: /* BTR Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw&= ~mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old & ~mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xb4: /* LFS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(fs,LoadMw(eaa+2));
break;
}
case 0xb5: /* LGS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);SegSet16(gs,LoadMw(eaa+2));
break;
}
case 0xb6: /* MOVZX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
else {GetEAa;*rmrw=LoadMb(eaa);}
break;
}
case 0xb7: /* MOVZX Gw,Ew */
case 0xbf: /* MOVSX Gw,Ew */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArw;*rmrw=*earw;}
else {GetEAa;*rmrw=LoadMw(eaa);}
break;
}
case 0xba: /* GRP8 Ew,Ib */
{
GetRM;
if (rm >= 0xc0 ) {
GetEArw;
Bit16u mask=1 << (Fetchb() & 15);
SETFLAGBIT(CF,(*earw & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
*earw|=mask;
break;
case 0x30: /* BTR */
*earw&= ~mask;
break;
case 0x38: /* BTC */
*earw^=mask;
break;
default:
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
} else {
GetEAa;Bit16u old=LoadMw(eaa);
Bit16u mask=1 << (Fetchb() & 15);
SETFLAGBIT(CF,(old & mask));
switch (rm & 0x38) {
case 0x20: /* BT */
break;
case 0x28: /* BTS */
SaveMw(eaa,old|mask);
break;
case 0x30: /* BTR */
SaveMw(eaa,old & ~mask);
break;
case 0x38: /* BTC */
SaveMw(eaa,old ^ mask);
break;
default:
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbb: /* BTC Ew,Gw */
{
GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw^=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
case 0xbc: /* 0xbc BSF Gw,Ew */
{
GetRMrw;
Bit16u result,value;
if (rm >= 0xc0) { GetEArw; value=*earw; }
else { GetEAa; value=LoadMw(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 0;
while ((value & 0x01)==0) { result++; value>>=1; }
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbd: /* 0xbd BSR Gw,Ew */
{
GetRMrw;
Bit16u result,value;
if (rm >= 0xc0) { GetEArw; value=*earw; }
else { GetEAa; value=LoadMw(eaa); }
if (value==0) {
SETFLAGBIT(ZF,true);
} else {
result = 15; // Operandsize-1
while ((value & 0x8000)==0) { result--; value<<=1; }
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
break;
}
case 0xbe: /* MOVSX Gw,Eb */
{
GetRMrw;
if (rm >= 0xc0 ) {GetEArb;*rmrw=*(Bit8s *)earb;}
else {GetEAa;*rmrw=LoadMbs(eaa);}
break;
}
case 0xc8: BSWAP(reg_eax); break;
case 0xc9: BSWAP(reg_ecx); break;
case 0xca: BSWAP(reg_edx); break;
case 0xcb: BSWAP(reg_ebx); break;
case 0xcc: BSWAP(reg_esp); break;
case 0xcd: BSWAP(reg_ebp); break;
case 0xce: BSWAP(reg_esi); break;
case 0xcf: BSWAP(reg_edi); break;
default:
SUBIP(1);
E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb());
}

View File

@ -1,401 +0,0 @@
/*
* Copyright (C) 2002 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 SUBIP(a) core_16.ip_lookup-=a
#define SETIP(a) core_16.ip_lookup=SegBase(cs)+a
#define GETIP (Bit16u)(core_16.ip_lookup-SegBase(cs))
#define SAVEIP reg_ip=GETIP
#define LOADIP core_16.ip_lookup=SegBase(cs)+reg_ip
#define LEAVECORE \
SAVEIP; \
FillFlags();
static INLINE void ADDIP(Bit16u add) {
core_16.ip_lookup=SegBase(cs)+((Bit16u)(((Bit16u)(core_16.ip_lookup-SegBase(cs)))+(Bit16u)add));
}
static INLINE void ADDIPFAST(Bit16s blah) {
core_16.ip_lookup+=blah;
}
#define CheckTF() \
if (GETFLAG(TF)) { \
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
goto decode_end; \
}
#define EXCEPTION(blah) \
{ \
Bit8u new_num=blah; \
core_16.ip_lookup=core_16.ip_start; \
LEAVECORE; \
if (Interrupt(new_num)) { \
if (GETFLAG(TF)) { \
cpudecoder=CPU_Real_16_Slow_Decode_Trap; \
return CBRET_NONE; \
} \
goto decode_start; \
} else return CBRET_NONE; \
}
static INLINE Bit8u Fetchb() {
Bit8u temp=LoadMb(core_16.ip_lookup);
core_16.ip_lookup+=1;
return temp;
}
static INLINE Bit16u Fetchw() {
Bit16u temp=LoadMw(core_16.ip_lookup);
core_16.ip_lookup+=2;
return temp;
}
static INLINE Bit32u Fetchd() {
Bit32u temp=LoadMd(core_16.ip_lookup);
core_16.ip_lookup+=4;
return temp;
}
static INLINE Bit8s Fetchbs() {
return Fetchb();
}
static INLINE Bit16s Fetchws() {
return Fetchw();
}
static INLINE Bit32s Fetchds() {
return Fetchd();
}
static INLINE void Push_16(Bit16u blah) {
reg_sp-=2;
SaveMw(SegBase(ss)+reg_sp,blah);
};
static INLINE void Push_32(Bit32u blah) {
reg_sp-=4;
SaveMd(SegBase(ss)+reg_sp,blah);
};
static INLINE Bit16u Pop_16() {
Bit16u temp=LoadMw(SegBase(ss)+reg_sp);
reg_sp+=2;
return temp;
};
static INLINE Bit32u Pop_32() {
Bit32u temp=LoadMd(SegBase(ss)+reg_sp);
reg_sp+=4;
return temp;
};
#define JumpSIb(blah) \
if (blah) { \
ADDIPFAST(Fetchbs()); \
} else { \
ADDIPFAST(1); \
}
#define JumpSIw(blah) \
if (blah) { \
ADDIPFAST(Fetchws()); \
} else { \
ADDIPFAST(2); \
}
#define SETcc(cc) \
{ \
GetRM; \
if (rm >= 0xc0 ) {GetEArb;*earb=(cc) ? 1 : 0;} \
else {GetEAa;SaveMb(eaa,(cc) ? 1 : 0);} \
}
#define NOTDONE \
SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb());
#define NOTDONE66 \
SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb());
#define stringDI \
PhysPt to; \
to=SegBase(es)+reg_di
#define stringSI \
PhysPt from; \
if (core_16.prefixes & PREFIX_SEG) { \
from=(core_16.segbase+reg_si); \
} else { \
from=SegBase(ds)+reg_si; \
}
#include "helpers.h"
#include "table_ea.h"
#include "../modrm.h"
static void Repeat_Normal(bool testz,bool prefix_66) {
PhysPt base_si,base_di;
Bit16s direct;
if (GETFLAG(DF)) direct=-1;
else direct=1;
base_di=SegBase(es);
if (core_16.prefixes & PREFIX_ADDR) E_Exit("Unhandled 0x67 prefixed string op");
rep_again:
if (core_16.prefixes & PREFIX_SEG) {
base_si=(core_16.segbase);
} else {
base_si=SegBase(ds);
}
switch (Fetchb()) {
case 0x26: /* ES Prefix */
core_16.segbase=SegBase(es);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x2e: /* CS Prefix */
core_16.segbase=SegBase(cs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x36: /* SS Prefix */
core_16.segbase=SegBase(ss);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x3e: /* DS Prefix */
core_16.segbase=SegBase(ds);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x64: /* FS Prefix */
core_16.segbase=SegBase(fs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x65: /* GS Prefix */
core_16.segbase=SegBase(gs);
core_16.prefixes|=PREFIX_SEG;
goto rep_again;
case 0x66: /* Size Prefix */
prefix_66=!prefix_66;
goto rep_again;
case 0x6c: /* REP INSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,IO_Read(reg_dx));
reg_di+=direct;
}
break;
case 0x6d: /* REP INSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0));
SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1));
SaveMb(base_di+reg_di+2,IO_Read(reg_dx+2));
SaveMb(base_di+reg_di+3,IO_Read(reg_dx+3));
reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di+0,IO_Read(reg_dx+0));
SaveMb(base_di+reg_di+1,IO_Read(reg_dx+1));
reg_di+=direct;
}
}
break;
case 0x6e: /* REP OUTSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx,LoadMb(base_si+reg_si));
reg_si+=direct;
}
break;
case 0x6f: /* REP OUTSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0));
IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1));
IO_Write(reg_dx+2,LoadMb(base_si+reg_si+2));
IO_Write(reg_dx+3,LoadMb(base_si+reg_si+3));
reg_si+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
IO_Write(reg_dx+0,LoadMb(base_si+reg_si+0));
IO_Write(reg_dx+1,LoadMb(base_si+reg_si+1));
reg_si+=direct;
}
}
break;
case 0xa4: /* REP MOVSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,LoadMb(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
break;
case 0xa5: /* REP MOVSW/D */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMd(base_di+reg_di,LoadMd(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMw(base_di+reg_di,LoadMw(base_si+reg_si));
reg_si+=direct;reg_di+=direct;
}
}
break;
case 0xa6: /* REP CMPSB */
{
Bit8u op1,op2;
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMb(base_si+reg_si);op2=LoadMb(base_di+reg_di);
reg_cx--;reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPB(op1,op2,LoadRb,0);goto normalexit; }
}
CMPB(op1,op2,LoadRb,0);
}
break;
case 0xa7: /* REP CMPSW */
{
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
if (prefix_66) {
direct*=4;Bit32u op1,op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMd(base_si+reg_si);op2=LoadMd(base_di+reg_di);
reg_cx--;reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPD(op1,op2,LoadRd,0);goto normalexit; }
}
CMPD(op1,op2,LoadRd,0);
} else {
direct*=2;Bit16u op1,op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op1=LoadMw(base_si+reg_si);op2=LoadMw(base_di+reg_di);
reg_cx--,reg_si+=direct;reg_di+=direct;
if ((op1==op2)!=testz || !reg_cx) { CMPW(op1,op2,LoadRw,0);goto normalexit; }
}
CMPW(op1,op2,LoadRw,0);
}
}
break;
case 0xaa: /* REP STOSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMb(base_di+reg_di,reg_al);
reg_di+=direct;
}
break;
case 0xab: /* REP STOSW */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMd(base_di+reg_di,reg_eax);
reg_di+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
SaveMw(base_di+reg_di,reg_ax);
reg_di+=direct;
}
}
break;
case 0xac: /* REP LODSB */
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_al=LoadMb(base_si+reg_si);
reg_si+=direct;
}
break;
case 0xad: /* REP LODSW */
if (prefix_66) {
direct*=4;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_eax=LoadMd(base_si+reg_si);
reg_si+=direct;
}
} else {
direct*=2;
for (;CPU_Cycles>0;CPU_Cycles--) {
if (!reg_cx) goto normalexit; reg_cx--;
reg_ax=LoadMw(base_si+reg_si);
reg_si+=direct;
}
}
break;
case 0xae: /* REP SCASB */
{
Bit8u op2;
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMb(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_al==op2)!=testz || !reg_cx) { CMPB(reg_al,op2,LoadRb,0);goto normalexit; }
}
CMPB(reg_al,op2,LoadRb,0);
}
break;
case 0xaf: /* REP SCASW */
{
if (!reg_cx) { CPU_Cycles--;goto normalexit; }
if (prefix_66) {
direct*=4;Bit32u op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMd(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_eax==op2)!=testz || !reg_cx) { CMPD(reg_eax,op2,LoadRd,0);goto normalexit; }
}
CMPD(reg_eax,op2,LoadRd,0);
} else {
direct*=2;Bit16u op2;
for (;CPU_Cycles>0;CPU_Cycles--) {
op2=LoadMw(base_di+reg_di);
reg_cx--;reg_di+=direct;
if ((reg_ax==op2)!=testz || !reg_cx) { CMPW(reg_ax,op2,LoadRw,0);goto normalexit; }
}
CMPW(reg_ax,op2,LoadRw,0);
}
}
break;
default:
core_16.ip_lookup--;
LOG(LOG_CPU,LOG_ERROR)("Unhandled REP Prefix %X",Fetchb());
goto normalexit;
}
/* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */
core_16.ip_lookup=core_16.ip_start;
normalexit:;
}

View File

@ -1,381 +0,0 @@
/*
* Copyright (C) 2002 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.
*/
/* Some variables for EA Loolkup */
typedef PhysPt (*GetEATable[256])(void);
typedef PhysPt (*EA_LookupHandler)(void);
static GetEATable * lookupEATable;
#define PREFIX_NONE 0x0
#define PREFIX_SEG 0x1
#define PREFIX_ADDR 0x2
#define PREFIX_SEG_ADDR 0x3
/* Gets initialized at the bottem, can't seem to declare forward references */
static GetEATable * EAPrefixTable[4];
#define SegPrefix(blah) \
core_16.segbase=SegBase(blah); \
core_16.prefixes|=PREFIX_SEG; \
lookupEATable=EAPrefixTable[core_16.prefixes]; \
goto restart;
#define SegPrefix_66(blah) \
core_16.segbase=SegBase(blah); \
core_16.prefixes|=PREFIX_SEG; \
lookupEATable=EAPrefixTable[core_16.prefixes]; \
goto restart_66;
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
static PhysPt EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
static PhysPt EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
static PhysPt EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
static PhysPt EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
static PhysPt EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
static GetEATable GetEA_16_n={
/* 00 */
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
/* 01 */
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
/* 10 */
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static PhysPt EA_16_00_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si); }
static PhysPt EA_16_01_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di); }
static PhysPt EA_16_02_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si); }
static PhysPt EA_16_03_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di); }
static PhysPt EA_16_04_s(void) { return core_16.segbase+(Bit16u)(reg_si); }
static PhysPt EA_16_05_s(void) { return core_16.segbase+(Bit16u)(reg_di); }
static PhysPt EA_16_06_s(void) { return core_16.segbase+(Bit16u)(Fetchw()); }
static PhysPt EA_16_07_s(void) { return core_16.segbase+(Bit16u)(reg_bx); }
static PhysPt EA_16_40_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_41_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_42_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
static PhysPt EA_16_43_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
static PhysPt EA_16_44_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchbs()); }
static PhysPt EA_16_45_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchbs()); }
static PhysPt EA_16_46_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchbs()); }
static PhysPt EA_16_47_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchbs()); }
static PhysPt EA_16_80_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_81_s(void) { return core_16.segbase+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_82_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
static PhysPt EA_16_83_s(void) { return core_16.segbase+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
static PhysPt EA_16_84_s(void) { return core_16.segbase+(Bit16u)(reg_si+Fetchws()); }
static PhysPt EA_16_85_s(void) { return core_16.segbase+(Bit16u)(reg_di+Fetchws()); }
static PhysPt EA_16_86_s(void) { return core_16.segbase+(Bit16u)(reg_bp+Fetchws()); }
static PhysPt EA_16_87_s(void) { return core_16.segbase+(Bit16u)(reg_bx+Fetchws()); }
static GetEATable GetEA_16_s={
/* 00 */
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
/* 01 */
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
/* 10 */
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static Bit32u SIBZero=0;
static Bit32u * SIBIndex[8]= { &reg_eax,&reg_ecx,&reg_edx,&reg_ebx,&SIBZero,&reg_ebp,&reg_esi,&reg_edi };
INLINE PhysPt Sib(Bitu mode) {
Bit8u sib=Fetchb();
PhysPt base;
switch (sib&7) {
case 0: /* EAX Base */
base=SegBase(ds)+reg_eax;break;
case 1: /* ECX Base */
base=SegBase(ds)+reg_ecx;break;
case 2: /* EDX Base */
base=SegBase(ds)+reg_edx;break;
case 3: /* EBX Base */
base=SegBase(ds)+reg_ebx;break;
case 4: /* ESP Base */
base=SegBase(ss)+reg_esp;break;
case 5: /* #1 Base */
if (!mode) {
base=SegBase(ds)+Fetchd();break;
} else {
base=SegBase(ss)+reg_ebp;break;
}
case 6: /* ESI Base */
base=SegBase(ds)+reg_esi;break;
case 7: /* EDI Base */
base=SegBase(ds)+reg_edi;break;
}
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
return base;
};
static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
static PhysPt EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
static PhysPt EA_32_04_n(void) { return Sib(0);}
static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
static GetEATable GetEA_32_n={
/* 00 */
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
/* 01 */
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
/* 10 */
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
INLINE PhysPt Sib_s(Bitu mode) {
Bit8u sib=Fetchb();
PhysPt base;
switch (sib&7) {
case 0: /* EAX Base */
base=reg_eax;break;
case 1: /* ECX Base */
base=reg_ecx;break;
case 2: /* EDX Base */
base=reg_edx;break;
case 3: /* EBX Base */
base=reg_ebx;break;
case 4: /* ESP Base */
base=reg_esp;break;
case 5: /* #1 Base */
if (!mode) {
base=Fetchd();break;
} else {
base=reg_ebp;break;
}
case 6: /* ESI Base */
base=reg_esi;break;
case 7: /* EDI Base */
base=reg_edi;break;
}
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
return base;
};
static PhysPt EA_32_00_s(void) { return core_16.segbase+(Bit32u)(reg_eax); }
static PhysPt EA_32_01_s(void) { return core_16.segbase+(Bit32u)(reg_ecx); }
static PhysPt EA_32_02_s(void) { return core_16.segbase+(Bit32u)(reg_edx); }
static PhysPt EA_32_03_s(void) { return core_16.segbase+(Bit32u)(reg_ebx); }
static PhysPt EA_32_04_s(void) { return core_16.segbase+(Bit32u)(Sib_s(0));}
static PhysPt EA_32_05_s(void) { return core_16.segbase+(Bit32u)(Fetchd()); }
static PhysPt EA_32_06_s(void) { return core_16.segbase+(Bit32u)(reg_esi); }
static PhysPt EA_32_07_s(void) { return core_16.segbase+(Bit32u)(reg_edi); }
static PhysPt EA_32_40_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchbs()); }
static PhysPt EA_32_41_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchbs()); }
static PhysPt EA_32_42_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchbs()); }
static PhysPt EA_32_43_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchbs()); }
static PhysPt EA_32_44_s(void) { return core_16.segbase+(Bit32u)(Sib_s(1)+Fetchbs());}
static PhysPt EA_32_45_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchbs()); }
static PhysPt EA_32_46_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchbs()); }
static PhysPt EA_32_47_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchbs()); }
static PhysPt EA_32_80_s(void) { return core_16.segbase+(Bit32u)(reg_eax+Fetchds()); }
static PhysPt EA_32_81_s(void) { return core_16.segbase+(Bit32u)(reg_ecx+Fetchds()); }
static PhysPt EA_32_82_s(void) { return core_16.segbase+(Bit32u)(reg_edx+Fetchds()); }
static PhysPt EA_32_83_s(void) { return core_16.segbase+(Bit32u)(reg_ebx+Fetchds()); }
static PhysPt EA_32_84_s(void) { return core_16.segbase+(Bit32u)(Sib_s(2)+Fetchds());}
static PhysPt EA_32_85_s(void) { return core_16.segbase+(Bit32u)(reg_ebp+Fetchds()); }
static PhysPt EA_32_86_s(void) { return core_16.segbase+(Bit32u)(reg_esi+Fetchds()); }
static PhysPt EA_32_87_s(void) { return core_16.segbase+(Bit32u)(reg_edi+Fetchds()); }
static GetEATable GetEA_32_s={
/* 00 */
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
EA_32_00_s,EA_32_01_s,EA_32_02_s,EA_32_03_s,EA_32_04_s,EA_32_05_s,EA_32_06_s,EA_32_07_s,
/* 01 */
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
EA_32_40_s,EA_32_41_s,EA_32_42_s,EA_32_43_s,EA_32_44_s,EA_32_45_s,EA_32_46_s,EA_32_47_s,
/* 10 */
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
EA_32_80_s,EA_32_81_s,EA_32_82_s,EA_32_83_s,EA_32_84_s,EA_32_85_s,EA_32_86_s,EA_32_87_s,
/* 11 These are illegal so make em 0 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static PhysPt GetEADirect_NONE(void) {
PhysPt result=SegBase(ds)+Fetchw();
return result;
}
static PhysPt GetEADirect_SEG(void) {
PhysPt result=core_16.segbase+Fetchw();
return result;
}
static PhysPt GetEADirect_ADDR(void) {
PhysPt result=SegBase(ds)+Fetchd();
return result;
}
static PhysPt GetEADirect_SEG_ADDR(void) {
PhysPt result=core_16.segbase+Fetchd();
return result;
}
static EA_LookupHandler GetEADirect[4]={GetEADirect_NONE,GetEADirect_SEG,GetEADirect_ADDR,GetEADirect_SEG_ADDR};

343
src/cpu/core_dyn_x86.cpp Normal file
View File

@ -0,0 +1,343 @@
/*
* Copyright (C) 2002-2004 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.
*/
#include "dosbox.h"
#if (C_DYNAMIC_X86)
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "callback.h"
#include "regs.h"
#include "mem.h"
#include "cpu.h"
#include "debug.h"
#include "paging.h"
#include "inout.h"
#define CACHE_TOTAL (1024*1024*2)
#define CACHE_MAXSIZE (4096)
#define CACHE_BLOCKS (50*1024)
#define CACHE_ALIGN (16)
#define DYN_HASH_SHIFT (4)
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
#define DYN_LINKS (16)
#if 0
#define DYN_LOG LOG_MSG
#else
#define DYN_LOG
#endif
enum {
G_EAX,G_ECX,G_EDX,G_EBX,
G_ESP,G_EBP,G_ESI,G_EDI,
G_ES,G_CS,G_SS,G_DS,G_FS,G_GS,
G_FLAGS,G_SMASK,G_EIP,
G_EA,G_STACK,G_CYCLES,
G_TMPB,G_TMPW,G_SHIFT,
G_EXIT,
G_MAX,
};
enum SingleOps {
SOP_INC,SOP_DEC,
SOP_NOT,SOP_NEG,
};
enum DualOps {
DOP_ADD,DOP_ADC,
DOP_SUB,DOP_SBB,
DOP_CMP,DOP_XOR,
DOP_AND,DOP_OR,
DOP_MOV,
DOP_TEST,
DOP_XCHG,
};
enum ShiftOps {
SHIFT_ROL,SHIFT_ROR,
SHIFT_RCL,SHIFT_RCR,
SHIFT_SHL,SHIFT_SHR,
SHIFT_SAR,
};
enum BranchTypes {
BR_O,BR_NO,BR_B,BR_NB,
BR_Z,BR_NZ,BR_BE,BR_NBE,
BR_S,BR_NS,BR_P,BR_NP,
BR_L,BR_NL,BR_LE,BR_NLE
};
enum BlockType {
BT_Free=0,
BT_Normal,
BT_SingleLink,
BT_DualLink,
BT_CheckFlags,
};
enum BlockReturn {
BR_Normal=0,
BR_Cycles,
BR_Link1,BR_Link2,
BR_Opcode,
BR_CallBack,
};
#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support
#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support
#define DYNFLG_LOAD 0x4 //Load value when accessed
#define DYNFLG_SAVE 0x8 //Needs to be saved back at the end of block
#define DYNFLG_CHANGED 0x10 //Value is in a register and changed from load
#define DYNFLG_ACTIVE 0x20 //Register has an active value
class GenReg;
class CodePageHandler;
struct DynReg {
Bitu flags;
GenReg * genreg;
void * data;
};
enum DynAccess {
DA_d,DA_w,
DA_bh,DA_bl
};
enum ByteCombo {
BC_ll,BC_lh,
BC_hl,BC_hh,
};
static DynReg DynRegs[G_MAX];
#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ]
static struct {
Bitu ea,tmpb,tmpd,stack,shift;
} extra_regs;
static void IllegalOption(void) {
E_Exit("Illegal option");
}
#include "core_dyn_x86/cache.h"
static struct {
Bitu callback;
} core_dyn;
#include "core_dyn_x86/risc_x86.h"
struct DynState {
DynReg regs[G_MAX];
};
static void dyn_releaseregs(void) {
for (Bitu i=0;i<G_MAX;i++) gen_releasereg(&DynRegs[i]);
}
static void dyn_load_flags(void) {
/* Load the host flags with emulated flags */
gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(FLAGS));
gen_dop_word_imm(DOP_AND,true,DREG(TMPW),FMASK_TEST);
gen_load_flags(DREG(TMPW));
gen_releasereg(DREG(TMPW));
gen_releasereg(DREG(FLAGS));
}
static void dyn_save_flags(bool stored=false) {
/* Store the host flags back in emulated ones */
gen_save_flags(DREG(EXIT),stored);
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FMASK_TEST);
gen_dop_word(DOP_OR,true,DREG(FLAGS),DREG(EXIT)); //flags are marked for save
gen_releasereg(DREG(EXIT));
}
static void dyn_savestate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
state->regs[i].flags=DynRegs[i].flags;
state->regs[i].genreg=DynRegs[i].genreg;
}
}
static void dyn_loadstate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
gen_setupreg(&DynRegs[i],&state->regs[i]);
}
}
static void dyn_synchstate(DynState * state) {
for (Bitu i=0;i<G_MAX;i++) {
gen_synchreg(&DynRegs[i],&state->regs[i]);
}
}
#include "core_dyn_x86/decoder.h"
Bits CPU_Core_Dyn_X86_Run(void) {
/* Determine the linear address of CS:EIP */
restart_core:
PhysPt ip_point=SegPhys(cs)+reg_eip;
Bitu ip_page=ip_point>>12;
mem_readb(ip_point); //Init whatever page we are in
PageHandler * handler=paging.tlb.handler[ip_page];
CodePageHandler * chandler=0;
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
if (handler->flags & PFLAG_HASCODE) {
/* Find correct Dynamic Block to run */
chandler=(CodePageHandler *)handler;
findblock:;
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
if (!block) {
cache.block.running=0;
block=CreateCacheBlock(ip_point,cpu.code.big,128);
// DYN_LOG("Created block size %x type %d",block->cache.size,block->type);
chandler->AddCacheBlock(block);
if (block->page.end>=4096) {
DYN_LOG("block crosses page boundary");
}
}
run_block:
BlockReturn ret=gen_runcode(block->cache.start);
switch (ret) {
case BR_Normal:
/* Maybe check if we staying in the same page? */
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
goto restart_core;
case BR_Cycles:
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
return CBRET_NONE;
case BR_CallBack:
return core_dyn.callback;
case BR_Opcode:
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
return CPU_Core_Normal_Run();
case BR_Link1:
case BR_Link2:
{
Bitu temp_ip=SegPhys(cs)+reg_eip;
Bitu temp_page=temp_ip >> 12;
CodePageHandler * temp_handler=(CodePageHandler *)paging.tlb.handler[temp_page];
if (temp_handler->flags & PFLAG_HASCODE) {
block=temp_handler->FindCacheBlock(temp_ip & 4095);
if (!block) goto restart_core;
cache_linkblocks(cache.block.running,block,ret==BR_Link2);
goto run_block;
}
}
goto restart_core;
}
} else {
if (handler->flags & PFLAG_NOCODE) {
LOG_MSG("DYNX86:Can't run code in this page");
return CPU_Core_Normal_Run();
}
Bitu phys_page=ip_page;
if (!PAGING_MakePhysPage(phys_page)) {
LOG_MSG("DYNX86:Can't find physpage");
return CPU_Core_Normal_Run();
}
chandler=new CodePageHandler(handler);
MEM_SetPageHandler(phys_page,1,chandler); //Setup the handler
PAGING_UnlinkPages(ip_page,1);
goto findblock;
}
return 0;
}
void CPU_Core_Dyn_X86_Init(void) {
Bits i;
/* Setup the global registers and their flags */
for (i=0;i<G_MAX;i++) DynRegs[i].genreg=0;
DynRegs[G_EAX].data=&reg_eax;
DynRegs[G_EAX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ECX].data=&reg_ecx;
DynRegs[G_ECX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EDX].data=&reg_edx;
DynRegs[G_EDX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EBX].data=&reg_ebx;
DynRegs[G_EBX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EBP].data=&reg_ebp;
DynRegs[G_EBP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ESP].data=&reg_esp;
DynRegs[G_ESP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EDI].data=&reg_edi;
DynRegs[G_EDI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ESI].data=&reg_esi;
DynRegs[G_ESI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_ES].data=&Segs.phys[es];
DynRegs[G_ES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_CS].data=&Segs.phys[cs];
DynRegs[G_CS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_SS].data=&Segs.phys[ss];
DynRegs[G_SS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_DS].data=&Segs.phys[ds];
DynRegs[G_DS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_FS].data=&Segs.phys[fs];
DynRegs[G_FS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_GS].data=&Segs.phys[gs];
DynRegs[G_GS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_FLAGS].data=&reg_flags;
DynRegs[G_FLAGS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_SMASK].data=&cpu.stack.mask;
DynRegs[G_SMASK].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EIP].data=&reg_eip;
DynRegs[G_EIP].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_EA].data=&extra_regs.ea;
DynRegs[G_EA].flags=0;
DynRegs[G_STACK].data=&extra_regs.stack;
DynRegs[G_STACK].flags=0;
DynRegs[G_CYCLES].data=&CPU_Cycles;
DynRegs[G_CYCLES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
DynRegs[G_TMPB].data=&extra_regs.tmpb;
DynRegs[G_TMPB].flags=DYNFLG_HAS8|DYNFLG_HAS16;
DynRegs[G_TMPW].data=&extra_regs.tmpd;
DynRegs[G_TMPW].flags=DYNFLG_HAS16;
DynRegs[G_SHIFT].data=&extra_regs.shift;
DynRegs[G_SHIFT].flags=DYNFLG_HAS8|DYNFLG_HAS16;
DynRegs[G_EXIT].data=0;
DynRegs[G_EXIT].flags=DYNFLG_HAS16;
/* Initialize code cache and dynamic blocks */
cache_init();
/* Init the generator */
gen_init();
return;
}
#endif

View File

@ -0,0 +1 @@
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -129,11 +129,8 @@ target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h support.h table_ea.h \
prefix_66_of.h
subdir = src/cpu/core_16
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h
subdir = src/cpu/core_dyn_x86
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
@ -147,7 +144,7 @@ all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnits src/cpu/core_16/Makefile
$(AUTOMAKE) --gnits 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:
@ -253,7 +250,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -272,7 +269,6 @@ clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
@ -295,7 +291,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -0,0 +1,302 @@
struct CacheBlock {
public:
struct {
Bit16s start,end; //Where the page is the original code
Bitu first,last;
} page;
struct {
Bit8u * start; //Where in the cache are we
Bitu size;
} cache;
BlockType type;
CodePageHandler * code_page; //Page containing this code
CacheBlock * page_link; //For code crossing a page boundary
struct {
CacheBlock * next;
} hash;
CacheBlock * list_next;
struct {
CacheBlock * to[2];
CacheBlock * from[DYN_LINKS];
Bitu index;
} link;
CacheBlock * links[2];
};
static struct {
struct {
CacheBlock * first;
CacheBlock * active;
CacheBlock * free;
CacheBlock * running;
} block;
Bit8u * pos;
CacheBlock linkblocks[2];
} cache;
static Bit8u cache_code_link_blocks[2][16];
static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE];
static CacheBlock cache_blocks[CACHE_BLOCKS];
static void cache_resetblock(CacheBlock * block);
class CodePageHandler :public PageHandler {
public:
CodePageHandler(PageHandler * _old_pagehandler) {
old_pagehandler=_old_pagehandler;
flags=old_pagehandler->flags|PFLAG_HASCODE;
flags&=~PFLAG_WRITEABLE;
memset(&hash_map,0,sizeof(hash_map));
memset(&write_map,0,sizeof(write_map));
}
void InvalidateRange(Bits start,Bits end) {
Bits maps=start>>DYN_HASH_SHIFT;
Bits map=maps;
Bits count=write_map[maps];
while (map>=0 && count>0) {
CacheBlock * block=hash_map[map];
CacheBlock * * where=&hash_map[map];
while (block) {
CacheBlock * nextblock=block->hash.next;
if (start<=block->page.end && end>=block->page.start) {
for (Bitu i=block->page.first;i<=block->page.last;i++) write_map[i]--;
block->code_page=0; //Else resetblock will do double work
count--;
if (block==cache.block.running) LOG_MSG("Writing to current block");
cache_resetblock(block);
*where=nextblock;
} else {
where=&block->hash.next;
}
block=nextblock;
}
map--;
}
}
void writeb(PhysPt addr,Bitu val){
if (val!=host_readb(hostmem+(addr&4095))) {
InvalidateRange(addr&4095,addr&4095);
host_writeb(hostmem+(addr&4095),val);
}
}
void writew(PhysPt addr,Bitu val){
if (val!=host_readw(hostmem+(addr&4095))) {
InvalidateRange(addr&4095,(addr&4095)+1);
host_writew(hostmem+(addr&4095),val);
}
}
void writed(PhysPt addr,Bitu val){
if (val!=host_readd(hostmem+(addr&4095))) {
InvalidateRange(addr&4095,(addr&4095)+3);
host_writed(hostmem+(addr&4095),val);
}
}
void AddCacheBlock(CacheBlock * block) {
Bit16u first,last;
if (block->page.start<0) first=0;
else first=block->page.start>>DYN_HASH_SHIFT;
block->hash.next=hash_map[first];
hash_map[first]=block;
if (block->page.end>=4096) last=DYN_PAGE_HASH-1;
else last=block->page.end>>DYN_HASH_SHIFT;
block->page.first=first;
block->page.last=last;
for (;first<=last;first++) {
write_map[first]++;
}
block->code_page=this;
}
void DelCacheBlock(CacheBlock * block) {
CacheBlock * * where=&hash_map[block->page.first];
while (*where) {
if (*where==block) {
*where=block->hash.next;
break;
}
where=&((*where)->hash.next);
}
for (Bitu i=block->page.first;i<=block->page.last;i++) {
write_map[i]--;
}
}
CacheBlock * FindCacheBlock(Bitu start) {
CacheBlock * block=hash_map[start>>DYN_HASH_SHIFT];
while (block) {
if (block->page.start==start) return block;
block=block->hash.next;
}
return 0;
}
HostPt GetHostPt(Bitu phys_page) {
hostmem=old_pagehandler->GetHostPt(phys_page);
return hostmem;
}
private:
PageHandler * old_pagehandler;
CacheBlock * hash_map[DYN_PAGE_HASH];
Bit8u write_map[DYN_PAGE_HASH];
HostPt hostmem;
};
static INLINE void cache_addunsedblock(CacheBlock * block) {
block->list_next=cache.block.free;
cache.block.free=block;
}
static CacheBlock * cache_getblock(void) {
CacheBlock * ret=cache.block.free;
if (!ret) E_Exit("Ran out of CacheBlocks" );
cache.block.free=ret->list_next;
return ret;
}
static INLINE void cache_clearlinkfrom(CacheBlock * block,CacheBlock * from) {
for (Bitu i=0;i<DYN_LINKS;i++) {
if (block->link.from[i]==from) block->link.from[i]=0;
}
}
static INLINE void cache_clearlinkto(CacheBlock * block,CacheBlock * to) {
if (block->link.to[0]==to) block->link.to[0]=&cache.linkblocks[0];
if (block->link.to[1]==to) block->link.to[1]=&cache.linkblocks[1];
}
static void cache_linkblocks(CacheBlock * from,CacheBlock * to,Bitu link) {
from->link.to[link]=to;
CacheBlock * clear=to->link.from[to->link.index];
if (clear) {
DYN_LOG("backlink buffer full");
cache_clearlinkto(to->link.from[to->link.index],to);
}
to->link.from[to->link.index]=from;
to->link.index++;
if (to->link.index>=DYN_LINKS) to->link.index=0;
}
static void cache_resetblock(CacheBlock * block) {
Bits i;
DYN_LOG("Resetted block");
block->type=BT_Free;
/* Clear all links to this block from other blocks */
for (i=0;i<DYN_LINKS;i++) {
if (block->link.from[i]) cache_clearlinkto(block->link.from[i],block);
block->link.from[i]=0;
}
/* Clear all links from this block to other blocks */
if (block->link.to[0]!=&cache.linkblocks[0]) {
cache_clearlinkfrom(block->link.to[0],block);
block->link.to[0]=&cache.linkblocks[0];
}
if (block->link.to[1]!=&cache.linkblocks[1]) {
cache_clearlinkfrom(block->link.to[1],block);
block->link.to[1]=&cache.linkblocks[1];
}
block->link.index=0;
if (block->code_page) block->code_page->DelCacheBlock(block);
}
static CacheBlock * cache_openblock(void) {
CacheBlock * block=cache.block.active;
/* check for enough space in this block */
Bitu size=block->cache.size;
CacheBlock * nextblock=block->list_next;
while (size<CACHE_MAXSIZE) {
if (!nextblock) goto skipresize;
size+=nextblock->cache.size;
CacheBlock * tempblock=nextblock->list_next;
if (nextblock->type!=BT_Free) cache_resetblock(nextblock);
cache_addunsedblock(nextblock);
nextblock=tempblock;
}
skipresize:
block->cache.size=size;
block->list_next=nextblock;
cache.pos=block->cache.start;
return block;
}
static void cache_closeblock(BlockType type) {
CacheBlock * block=cache.block.active;
/* Setup some structures in the block determined by type */
block->type=type;
switch (type) {
case BT_Normal:
break;
case BT_SingleLink:
block->link.to[0]=&cache.linkblocks[0];
break;
case BT_DualLink:
block->link.to[0]=&cache.linkblocks[0];
block->link.to[1]=&cache.linkblocks[1];
break;
}
/* Close the block with correct alignments */
Bitu written=cache.pos-block->cache.start;
if (written>block->cache.size) {
if (!block->list_next) {
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun");
} else E_Exit("CacheBlock overrun");
} else {
Bitu new_size;
Bitu left=block->cache.size-written;
/* Smaller than cache align then don't bother to resize */
if (left>CACHE_ALIGN) {
new_size=((written-1)|(CACHE_ALIGN-1))+1;
} else new_size=block->cache.size;
CacheBlock * newblock=cache_getblock();
newblock->cache.start=block->cache.start+new_size;
newblock->cache.size=block->cache.size-new_size;
newblock->list_next=block->list_next;
newblock->type=BT_Free;
block->cache.size=new_size;
block->list_next=newblock;
}
/* Advance the active block pointer */
if (!block->list_next) {
DYN_LOG("Cache full restarting");
cache.block.active=cache.block.first;
} else {
cache.block.active=block->list_next;
}
}
static INLINE void cache_addb(Bit8u val) {
*cache.pos++=val;
}
static INLINE void cache_addw(Bit16u val) {
*(Bit16u*)cache.pos=val;
cache.pos+=2;
}
static INLINE void cache_addd(Bit32u val) {
*(Bit32u*)cache.pos=val;
cache.pos+=4;
}
static void gen_return(BlockReturn retcode);
static void cache_init(void) {
Bits i;
memset(&cache_blocks,0,sizeof(cache_blocks));
cache.block.free=&cache_blocks[0];
for (i=0;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].list_next=&cache_blocks[i+1];
cache_blocks[i].link.to[0]=&cache.linkblocks[0];
cache_blocks[i].link.to[1]=&cache.linkblocks[1];
}
CacheBlock * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.start=&cache_code[0];
block->cache.size=CACHE_TOTAL;
block->list_next=0; //Last block in the list
cache.pos=&cache_code_link_blocks[0][0];
cache.linkblocks[0].cache.start=cache.pos;
gen_return(BR_Link1);
cache.pos=&cache_code_link_blocks[1][0];
cache.linkblocks[1].cache.start=cache.pos;
gen_return(BR_Link2);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
static Bitu dyn_helper_divb(Bit8u val) {
if (!val) return 1;
Bitu quo=reg_ax / val;
reg_ah=(Bit8u)(reg_ax % val);
reg_al=(Bit8u)quo;
if (quo>0xff) return 1;
return 0;
}
static Bitu dyn_helper_idivb(Bit8s val) {
if (!val) return 1;
Bits quo=(Bit16s)reg_ax / val;
reg_ah=(Bit8s)((Bit16s)reg_ax % val);
reg_al=(Bit8s)quo;
if (quo!=(Bit8s)reg_al) return 1;
return 0;
}
static Bitu dyn_helper_divw(Bit16u val) {
if (!val) return 1;
Bitu num=(reg_dx<<16)|reg_ax;
Bitu quo=num/val;
reg_dx=(Bit16u)(num % val);
reg_ax=(Bit16u)quo;
if (quo!=reg_ax) return 1;
return 0;
}
static Bitu dyn_helper_idivw(Bit16s val) {
if (!val) return 1;
Bits num=(reg_dx<<16)|reg_ax;
Bits quo=num/val;
reg_dx=(Bit16s)(num % val);
reg_ax=(Bit16s)quo;
if (quo!=(Bit16s)reg_ax) return 1;
return 0;
}
static Bitu dyn_helper_divd(Bit32u val) {
if (!val) return 1;
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
Bit64u quo=num/val;
reg_edx=(Bit32u)(num % val);
reg_eax=(Bit32u)quo;
if (quo!=(Bit64u)reg_eax) return 1;
return 0;
}
static Bitu dyn_helper_idivd(Bit32s val) {
if (!val) return 1;
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
Bit64s quo=num/val;
reg_edx=(Bit32s)(num % val);
reg_eax=(Bit32s)(quo);
if (quo!=(Bit64s)((Bit32s)reg_eax)) return 1;
return 0;
}

View File

@ -0,0 +1,799 @@
/*
* Copyright (C) 2002-2004 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.
*/
static void gen_init(void);
/* End of needed */
#define X86_REGS 7
#define X86_REG_EAX 0x00
#define X86_REG_ECX 0x01
#define X86_REG_EDX 0x02
#define X86_REG_EBX 0x03
#define X86_REG_EBP 0x04
#define X86_REG_ESI 0x05
#define X86_REG_EDI 0x06
#define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_)
static struct {
Bitu last_used;
Bitu stored_flags;
GenReg * regs[X86_REGS];
} x86gen;
class GenReg {
public:
GenReg(Bit8u _index,bool _protect) {
index=_index;protect=_protect;
notusable=false;dynreg=0;
}
DynReg * dynreg;
Bitu last_used; //Keeps track of last assigned regs
Bit8u index;
bool notusable;
bool protect;
void Load(DynReg * _dynreg) {
if (!_dynreg) return;
if (dynreg) Clear();
dynreg=_dynreg;
last_used=x86gen.last_used;
dynreg->flags&=~DYNFLG_CHANGED;
dynreg->genreg=this;
if (dynreg->flags & (DYNFLG_LOAD|DYNFLG_ACTIVE)) {
cache_addw(0x058b+(index << (8+3))); //Mov reg,[data]
cache_addd((Bit32u)dynreg->data);
}
dynreg->flags|=DYNFLG_ACTIVE;
}
void Save(void) {
if (!dynreg) IllegalOption();
dynreg->flags&=~DYNFLG_CHANGED;
cache_addw(0x0589+(index << (8+3))); //Mov [data],reg
cache_addd((Bit32u)dynreg->data);
}
void Release(void) {
if (!dynreg) return;
if (dynreg->flags&DYNFLG_CHANGED && dynreg->flags&DYNFLG_SAVE) {
Save();
}
dynreg->flags&=~(DYNFLG_CHANGED|DYNFLG_ACTIVE);
dynreg->genreg=0;dynreg=0;
}
void Clear(void) {
if (!dynreg) return;
if (dynreg->flags&DYNFLG_CHANGED) {
Save();
}
dynreg->genreg=0;dynreg=0;
}
};
static BlockReturn gen_runcode(Bit8u * code) {
BlockReturn retval;
#if defined (_MSC_VER)
__asm {
/* Prepare the flags */
mov eax,[code]
push ebx
push ebp
push esi
push edi
mov ebx,[reg_flags]
and ebx,FMASK_TEST
push ebx
popfd
call eax
/* Restore the flags */
pushfd
and dword ptr [reg_flags],~FMASK_TEST
pop ecx
and ecx,FMASK_TEST
or [reg_flags],ecx
pop edi
pop esi
pop ebp
pop ebx
mov [retval],eax
}
#else
__asm__ volatile (
"movl %1,%%esi \n"
"andl %2,%%esi \n"
"pushl %%ebp \n"
"pushl %%esi \n"
"popfl \n"
"calll *%4 \n"
"popl %%ebp \n"
"pushfl \n"
"andl %3,(%1) \n"
"popl %%esi \n"
"andl %2,%%esi \n"
"orl %%esi,(%1) \n"
:"=a" (retval)
:"m" (reg_flags), "n" (FMASK_TEST),"n" (~FMASK_TEST),"r" (code)
:"%ecx","%edx","%ebx","%edi","%esi","cc","memory"
);
#endif
return retval;
}
static GenReg * FindDynReg(DynReg * dynreg) {
x86gen.last_used++;
if (dynreg->genreg) {
dynreg->genreg->last_used=x86gen.last_used;
return dynreg->genreg;
}
/* Find best match for selected global reg */
Bits i;
Bits first_used,first_index;
first_used=-1;
if (dynreg->flags & DYNFLG_HAS8) {
/* Has to be eax,ebx,ecx,edx */
for (i=first_index=0;i<=X86_REG_EDX;i++) {
GenReg * genreg=x86gen.regs[i];
if (genreg->notusable) continue;
if (!(genreg->dynreg)) {
genreg->Load(dynreg);
return genreg;
}
if (genreg->last_used<first_used) {
first_used=genreg->last_used;
first_index=i;
}
}
/* No free register found use earliest assigned one */
GenReg * newreg=x86gen.regs[first_index];
newreg->Load(dynreg);
return newreg;
} else {
for (i=first_index=X86_REGS-1;i>=0;i--) {
GenReg * genreg=x86gen.regs[i];
if (genreg->notusable) continue;
if (!(genreg->dynreg)) {
genreg->Load(dynreg);
return genreg;
}
if (genreg->last_used<first_used) {
first_used=genreg->last_used;
first_index=i;
}
}
/* No free register found use earliest assigned one */
GenReg * newreg=x86gen.regs[first_index];
newreg->Load(dynreg);
return newreg;
}
}
static GenReg * ForceDynReg(GenReg * genreg,DynReg * dynreg) {
genreg->last_used=++x86gen.last_used;
if (dynreg->genreg==genreg) return genreg;
if (genreg->dynreg) genreg->Clear();
if (dynreg->genreg) dynreg->genreg->Clear();
genreg->Load(dynreg);
return genreg;
}
static void gen_preloadreg(DynReg * dynreg) {
FindDynReg(dynreg);
}
static void gen_releasereg(DynReg * dynreg) {
GenReg * genreg=dynreg->genreg;
if (genreg) genreg->Release();
else dynreg->flags&=~(DYNFLG_ACTIVE|DYNFLG_CHANGED);
}
static void gen_setupreg(DynReg * dnew,DynReg * dsetup) {
dnew->flags=dsetup->flags;
if (dnew->genreg==dsetup->genreg) return;
/* Not the same genreg must be wrong */
if (dnew->genreg) {
/* Check if the genreg i'm changing is actually linked to me */
if (dnew->genreg->dynreg==dnew) dnew->genreg->dynreg=0;
}
dnew->genreg=dsetup->genreg;
if (dnew->genreg) dnew->genreg->dynreg=dnew;
}
static void gen_synchreg(DynReg * dnew,DynReg * dsynch) {
/* First make sure the registers match */
if (dnew->genreg!=dsynch->genreg) {
if (dnew->genreg) dnew->genreg->Clear();
if (dsynch->genreg) {
dsynch->genreg->Load(dnew);
}
}
/* Always use the loadonce flag from either state */
dnew->flags|=(dsynch->flags & dnew->flags&DYNFLG_ACTIVE);
if ((dnew->flags ^ dsynch->flags) & DYNFLG_CHANGED) {
/* Ensure the changed value gets saved */
if (dnew->flags & DYNFLG_CHANGED) {
dnew->genreg->Save();
} else dnew->flags|=DYNFLG_CHANGED;
}
}
static void gen_storeflags(void) {
if (!x86gen.stored_flags) {
cache_addb(0x9c); //PUSHFD
}
x86gen.stored_flags++;
}
static void gen_restoreflags(bool noreduce=false) {
if (noreduce) {
cache_addb(0x9d);
return;
}
if (x86gen.stored_flags) {
x86gen.stored_flags--;
if (!x86gen.stored_flags)
cache_addb(0x9d); //POPFD
} else IllegalOption();
}
static void gen_reinit(void) {
x86gen.last_used=0;
x86gen.stored_flags=0;
for (Bitu i=0;i<X86_REGS;i++) {
x86gen.regs[i]->dynreg=0;
}
}
static void gen_dop_byte(DualOps op,DynReg * dr1,Bit8u di1,DynReg * dr2,Bit8u di2) {
GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);
switch (op) {
case DOP_ADD:cache_addb(0x02);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_OR: cache_addb(0x0a);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_ADC:cache_addb(0x12);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SBB:cache_addb(0x1a);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_AND:cache_addb(0x22);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SUB:cache_addb(0x2a);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_XOR:cache_addb(0x32);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_CMP:cache_addb(0x3a);break;
case DOP_MOV:cache_addb(0x8a);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_XCHG:cache_addb(0x86);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break;
case DOP_TEST:cache_addb(0x84);break;
default:
IllegalOption();
}
cache_addb(0xc0+((gr1->index+di1)<<3)+gr2->index+di2);
}
static void gen_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1,Bitu imm) {
GenReg * gr1=FindDynReg(dr1);
switch (op) {
case DOP_ADD:
cache_addw(0xc080+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_OR:
cache_addw(0xc880+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_ADC:
cache_addw(0xd080+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_SBB:
cache_addw(0xd880+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_AND:
cache_addw(0xe080+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_SUB:
cache_addw(0xe880+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_XOR:
cache_addw(0xf080+((gr1->index+di1)<<8));
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_CMP:
cache_addw(0xf880+((gr1->index+di1)<<8));
break;//Doesn't change
case DOP_MOV:
cache_addb(0xb0+gr1->index+di1);
dr1->flags|=DYNFLG_CHANGED;
break;
case DOP_TEST:
cache_addw(0xc0f6+((gr1->index+di1)<<8));
break;//Doesn't change
default:
IllegalOption();
}
cache_addb(imm);
}
static void gen_sop_byte(SingleOps op,DynReg * dr1,Bit8u di1) {
GenReg * gr1=FindDynReg(dr1);
switch (op) {
case SOP_INC:cache_addw(0xc0FE + ((gr1->index+di1)<<8));break;
case SOP_DEC:cache_addw(0xc8FE + ((gr1->index+di1)<<8));break;
case SOP_NOT:cache_addw(0xd0f6 + ((gr1->index+di1)<<8));break;
case SOP_NEG:cache_addw(0xd8f6 + ((gr1->index+di1)<<8));break;
default:
IllegalOption();
}
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_extend_word(bool sign,DynReg * ddr,DynReg * dsr) {
GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr);
if (sign) cache_addw(0xbf0f);
else cache_addw(0xb70f);
cache_addb(0xc0+(gdr->index<<3)+(gsr->index));
ddr->flags|=DYNFLG_CHANGED;
}
static void gen_extend_byte(bool sign,bool dword,DynReg * ddr,DynReg * dsr,Bit8u dsi) {
GenReg * gdr=FindDynReg(ddr);GenReg * gsr=FindDynReg(dsr);
if (!dword) cache_addb(0x66);
if (sign) cache_addw(0xbe0f);
else cache_addw(0xb60f);
cache_addb(0xc0+(gdr->index<<3)+(gsr->index+dsi));
ddr->flags|=DYNFLG_CHANGED;
}
static void gen_lea(DynReg * ddr,DynReg * dsr1,DynReg * dsr2,Bitu scale,Bits imm) {
GenReg * gdr=FindDynReg(ddr);
Bitu imm_size;
Bit8u rm_base=(gdr->index << 3);
if (dsr1) {
GenReg * gsr1=FindDynReg(dsr1);
if (!imm && (gsr1->index!=0x5)) {
imm_size=0; rm_base+=0x0; //no imm
} else if ((imm>=-128 && imm<=127)) {
imm_size=1;rm_base+=0x40; //Signed byte imm
} else {
imm_size=4;rm_base+=0x80; //Signed dword imm
}
if (dsr2) {
GenReg * gsr2=FindDynReg(dsr2);
cache_addb(0x8d); //LEA
cache_addb(rm_base+0x4); //The sib indicator
Bit8u sib=(gsr1->index)+(gsr2->index<<3)+(scale<<6);
cache_addb(sib);
} else {
cache_addb(0x8d); //LEA
cache_addb(rm_base+gsr1->index);
}
} else {
if (dsr2) {
GenReg * gsr2=FindDynReg(dsr2);
cache_addb(0x8d); //LEA
cache_addb(rm_base+0x4); //The sib indicator
Bit8u sib=(5+(gsr2->index<<3)+(scale<<6));
cache_addb(sib);
imm_size=4;
} else {
cache_addb(0x8d); //LEA
cache_addb(rm_base+0x05); //dword imm
imm_size=4;
}
}
switch (imm_size) {
case 0: break;
case 1:cache_addb(imm);break;
case 4:cache_addd(imm);break;
}
ddr->flags|=DYNFLG_CHANGED;
}
static void gen_dop_word(DualOps op,bool dword,DynReg * dr1,DynReg * dr2) {
GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);
if (!dword) cache_addb(0x66);
switch (op) {
case DOP_ADD:cache_addb(0x03);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_OR: cache_addb(0x0b);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_ADC:cache_addb(0x13);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SBB:cache_addb(0x1b);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_AND:cache_addb(0x23);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SUB:cache_addb(0x2b);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_XOR:cache_addb(0x33);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_CMP:cache_addb(0x3b);break;
case DOP_MOV:cache_addb(0x8b);dr1->flags|=DYNFLG_CHANGED;break;
case DOP_XCHG:cache_addb(0x87);dr1->flags|=DYNFLG_CHANGED;dr2->flags|=DYNFLG_CHANGED;break;
case DOP_TEST:cache_addb(0x85);break;
default:
IllegalOption();
}
cache_addb(0xc0+(gr1->index<<3)+gr2->index);
}
static void gen_dop_word_imm(DualOps op,bool dword,DynReg * dr1,Bits imm) {
GenReg * gr1=FindDynReg(dr1);
if (!dword) cache_addb(0x66);
switch (op) {
case DOP_ADD:cache_addw(0xc081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_OR: cache_addw(0xc881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_ADC:cache_addw(0xd081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SBB:cache_addw(0xd881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_AND:cache_addw(0xe081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_SUB:cache_addw(0xe881+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_XOR:cache_addw(0xf081+(gr1->index<<8));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_CMP:cache_addw(0xf881+(gr1->index<<8));break;//Doesn't change
case DOP_MOV:cache_addb(0xb8+(gr1->index));dr1->flags|=DYNFLG_CHANGED;break;
case DOP_TEST:cache_addw(0xc0f7+(gr1->index<<8));break;//Doesn't change
default:
IllegalOption();
}
if (dword) cache_addd(imm);
else cache_addw(imm);
}
static void gen_imul_word(bool dword,DynReg * dr1,DynReg * dr2) {
GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);
if (!dword) cache_addb(0x66);
cache_addw(0xaf0f);
cache_addb(0xc0+(gr1->index<<3)+gr2->index);
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_imul_word_imm(bool dword,DynReg * dr1,DynReg * dr2,Bits imm) {
GenReg * gr1=FindDynReg(dr1);GenReg * gr2=FindDynReg(dr2);
if (!dword) cache_addb(0x66);
if ((imm>=-128 && imm<=127)) {
cache_addb(0x6b);
cache_addb(0xc0+(gr1->index<<3)+gr2->index);
cache_addb(imm);
} else {
cache_addb(0x69);
cache_addb(0xc0+(gr1->index<<3)+gr2->index);
if (dword) cache_addd(imm);
else cache_addw(imm);
}
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) {
GenReg * gr1=FindDynReg(dr1);
if (!dword) cache_addb(0x66);
switch (op) {
case SOP_INC:cache_addb(0x40+gr1->index);break;
case SOP_DEC:cache_addb(0x48+gr1->index);break;
case SOP_NOT:cache_addw(0xd0f7+(gr1->index<<8));break;
case SOP_NEG:cache_addw(0xd8f7+(gr1->index<<8));break;
default:
IllegalOption();
}
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_shift_byte(ShiftOps op,DynReg * drecx,DynReg * dr1,Bit8u di1) {
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
GenReg * gr1=FindDynReg(dr1);
switch (op) {
case SHIFT_ROL:cache_addw(0xc0d2+((gr1->index+di1)<<8));break;
case SHIFT_ROR:cache_addw(0xc8d2+((gr1->index+di1)<<8));break;
case SHIFT_RCL:cache_addw(0xd0d2+((gr1->index+di1)<<8));break;
case SHIFT_RCR:cache_addw(0xd8d2+((gr1->index+di1)<<8));break;
case SHIFT_SHL:cache_addw(0xe0d2+((gr1->index+di1)<<8));break;
case SHIFT_SHR:cache_addw(0xe8d2+((gr1->index+di1)<<8));break;
case SHIFT_SAR:cache_addw(0xf8d2+((gr1->index+di1)<<8));break;
default:
IllegalOption();
}
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) {
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
GenReg * gr1=FindDynReg(dr1);
if (!dword) cache_addb(0x66);
switch (op) {
case SHIFT_ROL:cache_addw(0xc0d3+((gr1->index)<<8));break;
case SHIFT_ROR:cache_addw(0xc8d3+((gr1->index)<<8));break;
case SHIFT_RCL:cache_addw(0xd0d3+((gr1->index)<<8));break;
case SHIFT_RCR:cache_addw(0xd8d3+((gr1->index)<<8));break;
case SHIFT_SHL:cache_addw(0xe0d3+((gr1->index)<<8));break;
case SHIFT_SHR:cache_addw(0xe8d3+((gr1->index)<<8));break;
case SHIFT_SAR:cache_addw(0xf8d3+((gr1->index)<<8));break;
default:
IllegalOption();
}
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_shift_word_imm(ShiftOps op,bool dword,DynReg * dr1,Bit8u imm) {
GenReg * gr1=FindDynReg(dr1);
if (!dword) cache_addb(0x66);
switch (op) {
case SHIFT_ROL:cache_addw(0xc0c1+((gr1->index)<<8));break;
case SHIFT_ROR:cache_addw(0xc8c1+((gr1->index)<<8));break;
case SHIFT_RCL:cache_addw(0xd0c1+((gr1->index)<<8));break;
case SHIFT_RCR:cache_addw(0xd8c1+((gr1->index)<<8));break;
case SHIFT_SHL:cache_addw(0xe0c1+((gr1->index)<<8));break;
case SHIFT_SHR:cache_addw(0xe8c1+((gr1->index)<<8));break;
case SHIFT_SAR:cache_addw(0xf8c1+((gr1->index)<<8));break;
default:
IllegalOption();
}
cache_addb(imm);
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_cbw(bool dword,DynReg * dyn_ax) {
ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);
if (!dword) cache_addb(0x66);
cache_addb(0x98);
dyn_ax->flags|=DYNFLG_CHANGED;
}
static void gen_cwd(bool dword,DynReg * dyn_ax,DynReg * dyn_dx) {
ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);
ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx);
if (!dword) cache_addb(0x66);
cache_addb(0x99);
dyn_ax->flags|=DYNFLG_CHANGED;
dyn_dx->flags|=DYNFLG_CHANGED;
}
static void gen_mul_byte(bool imul,DynReg * dyn_ax,DynReg * dr1,Bit8u di1) {
ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);
GenReg * gr1=FindDynReg(dr1);
if (imul) cache_addw(0xe8f6+((gr1->index+di1)<<8));
else cache_addw(0xe0f6+((gr1->index+di1)<<8));
dyn_ax->flags|=DYNFLG_CHANGED;
}
static void gen_mul_word(bool imul,DynReg * dyn_ax,DynReg * dyn_dx,bool dword,DynReg * dr1) {
ForceDynReg(x86gen.regs[X86_REG_EAX],dyn_ax);
ForceDynReg(x86gen.regs[X86_REG_EDX],dyn_dx);
GenReg * gr1=FindDynReg(dr1);
if (!dword) cache_addb(0x66);
if (imul) cache_addw(0xe8f7+(gr1->index<<8));
else cache_addw(0xe0f7+(gr1->index<<8));
dyn_ax->flags|=DYNFLG_CHANGED;
dyn_dx->flags|=DYNFLG_CHANGED;
}
static void gen_dshift_imm(bool dword,bool left,DynReg * dr1,DynReg * dr2,Bitu imm) {
GenReg * gr1=FindDynReg(dr1);
GenReg * gr2=FindDynReg(dr2);
if (!dword) cache_addb(0x66);
if (left) cache_addw(0xa40f); //SHLD IMM
else cache_addw(0xac0f); //SHRD IMM
cache_addb(0xc0+gr1->index+(gr2->index<<3));
cache_addb(imm);
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_dshift_cl(bool dword,bool left,DynReg * dr1,DynReg * dr2,DynReg * drecx) {
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
GenReg * gr1=FindDynReg(dr1);
GenReg * gr2=FindDynReg(dr2);
if (!dword) cache_addb(0x66);
if (left) cache_addw(0xa50f); //SHLD CL
else cache_addw(0xad0f); //SHRD CL
cache_addb(0xc0+gr1->index+(gr2->index<<3));
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_call_function(void * func,char * ops,...) {
Bits paramcount=0;
struct ParamInfo {
char * line;
Bitu value;
} pinfo[32];
ParamInfo * retparam=0;
/* Clear the EAX Genreg for usage */
x86gen.regs[X86_REG_EAX]->Clear();
x86gen.regs[X86_REG_EAX]->notusable=true;;
/* Save the flags */
gen_storeflags();
/* Scan for the amount of params */
if (ops) {
va_list params;
va_start(params,ops);
Bits pindex=0;
while (*ops) {
if (*ops=='%') {
pinfo[pindex].line=ops+1;
pinfo[pindex].value=va_arg(params,Bitu);
pindex++;
}
ops++;
}
paramcount=0;
while (pindex) {
pindex--;
char * scan=pinfo[pindex].line;
switch (*scan++) {
case 'I': /* immediate value */
paramcount++;
cache_addb(0x68); //Push immediate
cache_addd(pinfo[pindex].value); //Push value
break;
case 'D': /* Dynamic register */
{
bool release=false;
paramcount++;
DynReg * dynreg=(DynReg *)pinfo[pindex].value;
GenReg * genreg=FindDynReg(dynreg);
scanagain:
switch (*scan++) {
case 'd':
cache_addb(0x50+genreg->index); //Push reg
break;
case 'w':
cache_addw(0xb70f); //MOVZX EAX,reg
cache_addb(0xc0+genreg->index);
cache_addb(0x50); //Push EAX
break;
case 'l':
cache_addw(0xb60f); //MOVZX EAX,reg[0]
cache_addb(0xc0+genreg->index);
cache_addb(0x50); //Push EAX
break;
case 'h':
cache_addw(0xb60f); //MOVZX EAX,reg[1]
cache_addb(0xc4+genreg->index);
cache_addb(0x50); //Push EAX
break;
case 'r': /* release the reg afterwards */
release=true;
goto scanagain;
default:
IllegalOption();
}
if (release) gen_releasereg(dynreg);
}
break;
case 'R': /* Dynamic register to get the return value */
retparam =&pinfo[pindex];
pinfo[pindex].line=scan;
break;
default:
IllegalOption();
}
}
}
/* Clear some unprotected registers */
x86gen.regs[X86_REG_ECX]->Clear();
x86gen.regs[X86_REG_EDX]->Clear();
/* Do the actual call to the procedure */
cache_addb(0xe8);
cache_addd((Bit32u)func - (Bit32u)cache.pos-4);
/* Restore the params of the stack */
if (paramcount) {
cache_addw(0xc483); //add ESP,imm byte
cache_addb(paramcount*4);
}
/* Save the return value in correct register */
if (retparam) {
DynReg * dynreg=(DynReg *)retparam->value;
GenReg * genreg=FindDynReg(dynreg);
switch (*retparam->line) {
case 'd':
cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax
break;
case 'w':
cache_addb(0x66);
cache_addw(0xc08b+(genreg->index <<(8+3))); //mov reg,eax
break;
case 'l':
cache_addw(0xc08a+(genreg->index <<(8+3))); //mov reg,eax
break;
case 'h':
cache_addw(0xc08a+((genreg->index+4) <<(8+3))); //mov reg,eax
break;
}
dynreg->flags|=DYNFLG_CHANGED;
}
gen_restoreflags();
/* Restore EAX registers to be used again */
x86gen.regs[X86_REG_EAX]->notusable=false;
}
static Bit8u * gen_create_branch(BranchTypes type) {
/* First free all registers */
cache_addb(0x70+type);
cache_addb(0);
return (cache.pos-1);
}
static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) {
*data=(from-data-1);
}
static Bit8u * gen_create_jump(Bit8u * to=0) {
/* First free all registers */
cache_addb(0xe9);
cache_addd(to-(cache.pos+4));
return (cache.pos-4);
}
static void gen_fill_jump(Bit8u * data,Bit8u * to=cache.pos) {
*(Bit32u*)data=(to-data-4);
}
static void gen_jmp_ptr(void * ptr,Bits imm=0) {
cache_addb(0xa1);
cache_addd((Bit32u)ptr);
cache_addb(0xff); //JMP EA
if (!imm) { //NO EBP
cache_addb(0x20);
} else if ((imm>=-128 && imm<=127)) {
cache_addb(0x60);
cache_addb(imm);
} else {
cache_addb(0xa0);
cache_addd(imm);
}
}
static void gen_save_flags(DynReg * dynreg,bool stored) {
GenReg * genreg=FindDynReg(dynreg);
if (!stored) cache_addb(0x9c); //Pushfd
cache_addb(0x58+genreg->index); //POP 32 REG
dynreg->flags|=DYNFLG_CHANGED;
}
static void gen_load_flags(DynReg * dynreg) {
GenReg * genreg=FindDynReg(dynreg);
cache_addb(0x50+genreg->index); //PUSH 32
cache_addb(0x9d); //POPFD
}
static void gen_save_host_direct(void * data,Bits imm) {
cache_addw(0x05c7); //MOV [],dword
cache_addd((Bit32u)data);
cache_addd(imm);
}
static void gen_load_host(void * data,DynReg * dr1,Bitu size) {
GenReg * gr1=FindDynReg(dr1);
switch (size) {
case 1:cache_addw(0xb60f);break; //movzx byte
case 2:cache_addw(0xb70f);break; //movzx word
case 4:cache_addb(0x8b);break; //mov
default:
IllegalOption();
}
cache_addb(0x5+(gr1->index<<3));
cache_addd((Bit32u)data);
dr1->flags|=DYNFLG_CHANGED;
}
static void gen_return(BlockReturn retcode) {
cache_addb(0xb8);
cache_addd(retcode);
cache_addb(0xc3);
}
static void gen_init(void) {
x86gen.regs[X86_REG_EAX]=new GenReg(0,false);
x86gen.regs[X86_REG_ECX]=new GenReg(1,false);
x86gen.regs[X86_REG_EDX]=new GenReg(2,false);
x86gen.regs[X86_REG_EBX]=new GenReg(3,true);
x86gen.regs[X86_REG_EBP]=new GenReg(5,true);
x86gen.regs[X86_REG_ESI]=new GenReg(6,true);
x86gen.regs[X86_REG_EDI]=new GenReg(7,true);
}

View File

@ -0,0 +1,165 @@
/*
* Copyright (C) 2002-2004 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.
*/
enum STRING_OP {
STR_OUTSB=0,STR_OUTSW,STR_OUTSD,
STR_INSB=4,STR_INSW,STR_INSD,
STR_MOVSB=8,STR_MOVSW,STR_MOVSD,
STR_LODSB=12,STR_LODSW,STR_LODSD,
STR_STOSB=16,STR_STOSW,STR_STOSD,
STR_SCASB=20,STR_SCASW,STR_SCASD,
STR_CMPSB=24,STR_CMPSW,STR_CMPSD,
};
static void dyn_string(STRING_OP op) {
DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS);
DynReg * di_base=DREG(ES);
DynReg * tmp_reg;bool usesi;bool usedi;
gen_storeflags();
if (decode.rep) {
gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles);
gen_releasereg(DREG(CYCLES));
decode.cycles=0;
}
/* Check what each string operation will be using */
switch (op) {
case STR_MOVSB: case STR_MOVSW: case STR_MOVSD:
case STR_CMPSB: case STR_CMPSW: case STR_CMPSD:
tmp_reg=DREG(TMPB);usesi=true;usedi=true;break;
case STR_LODSB: case STR_LODSW: case STR_LODSD:
tmp_reg=DREG(EAX);usesi=true;usedi=false;break;
case STR_OUTSB: case STR_OUTSW: case STR_OUTSD:
tmp_reg=DREG(TMPB);usesi=true;usedi=false;break;
case STR_SCASB: case STR_SCASW: case STR_SCASD:
case STR_STOSB: case STR_STOSW: case STR_STOSD:
tmp_reg=DREG(EAX);usesi=false;usedi=true;break;
case STR_INSB: case STR_INSW: case STR_INSD:
tmp_reg=DREG(TMPB);usesi=false;usedi=true;break;
default:
IllegalOption();
}
gen_load_host(&cpu.direction,DREG(TMPW),4);
switch (op & 3) {
case 0:break;
case 1:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),1);break;
case 2:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),2);break;
default:
IllegalOption();
}
if (usesi) {
gen_preloadreg(DREG(ESI));
DynRegs[G_ESI].flags|=DYNFLG_CHANGED;
gen_preloadreg(si_base);
}
if (usedi) {
gen_preloadreg(DREG(EDI));
DynRegs[G_EDI].flags|=DYNFLG_CHANGED;
gen_preloadreg(di_base);
}
if (decode.rep) {
gen_preloadreg(DREG(ECX));
DynRegs[G_ECX].flags|=DYNFLG_CHANGED;
}
DynState rep_state;
dyn_savestate(&rep_state);
Bit8u * rep_start=cache.pos;
Bit8u * rep_ecx_jmp;
/* Check if ECX!=zero and decrease it */
if (decode.rep) {
gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX));
Bit8u * branch_ecx=gen_create_branch(BR_NZ);
rep_ecx_jmp=gen_create_jump();
gen_fill_branch(branch_ecx);
gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX));
}
if (usesi) {
if (!decode.big_addr) {
gen_extend_word(false,DREG(EA),DREG(ESI));
gen_lea(DREG(EA),si_base,DREG(EA),0,0);
} else {
gen_lea(DREG(EA),si_base,DREG(ESI),0,0);
}
gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW));
switch (op&3) {
case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break;
case 1:dyn_read_word(DREG(EA),tmp_reg,false);break;
case 2:dyn_read_word(DREG(EA),tmp_reg,true);break;
}
switch (op) {
case STR_OUTSB:
gen_call_function((void*)&IO_WriteB,"%Id%Dl",DREG(EDX),tmp_reg);break;
case STR_OUTSW:
gen_call_function((void*)&IO_WriteW,"%Id%Dw",DREG(EDX),tmp_reg);break;
case STR_OUTSD:
gen_call_function((void*)&IO_WriteD,"%Id%Dd",DREG(EDX),tmp_reg);break;
}
}
if (usedi) {
if (!decode.big_addr) {
gen_extend_word(false,DREG(EA),DREG(EDI));
gen_lea(DREG(EA),di_base,DREG(EA),0,0);
} else {
gen_lea(DREG(EA),di_base,DREG(EDI),0,0);
}
gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW));
/* Maybe something special to be done to fill the value */
switch (op) {
case STR_INSB:
gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),tmp_reg);
case STR_MOVSB:
case STR_STOSB:
dyn_write_byte(DREG(EA),tmp_reg,false);
break;
case STR_INSW:
gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),tmp_reg);
case STR_MOVSW:
case STR_STOSW:
dyn_write_word(DREG(EA),tmp_reg,false);
break;
case STR_INSD:
gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),tmp_reg);
case STR_MOVSD:
case STR_STOSD:
dyn_write_word(DREG(EA),tmp_reg,true);
break;
default:
IllegalOption();
}
}
gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));
if (decode.rep) {
DynState cycle_state;
gen_sop_word(SOP_DEC,true,DREG(CYCLES));
gen_releasereg(DREG(CYCLES));
dyn_savestate(&cycle_state);
Bit8u * cycle_branch=gen_create_branch(BR_NLE);
gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start);
dyn_releaseregs();
gen_restoreflags(true);
gen_return(BR_Cycles);
gen_fill_branch(cycle_branch);
dyn_loadstate(&cycle_state);
dyn_synchstate(&rep_state);
/* Jump back to start of ECX check */
gen_create_jump(rep_start);
gen_fill_jump(rep_ecx_jmp);
}
gen_releasereg(DREG(TMPW));
gen_restoreflags();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -47,6 +47,8 @@ typedef PhysPt EAPoint;
#define LoadD(reg) reg
#define SaveD(reg,val) reg=val
#include "core_full/loadwrite.h"
#include "core_full/support.h"
#include "core_full/optable.h"
@ -59,15 +61,16 @@ typedef PhysPt EAPoint;
#define EXCEPTION(blah) \
{ \
Bit8u new_num=blah; \
IPPoint=inst.start_entry; \
IPPoint=inst.opcode_start; \
LEAVECORE; \
Interrupt(new_num); \
CPU_Exception(new_num,0); \
LoadIP(); \
goto nextopcode; \
}
Bits Full_DeCode(void) {
Bits CPU_Core_Full_Run(void) {
FullData inst;
restart_core:
if (!cpu.code.big) {
inst.start_prefix=0x0;;
inst.start_entry=0x0;
@ -77,8 +80,8 @@ Bits Full_DeCode(void) {
}
EAPoint IPPoint;
LoadIP();
flags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
lflags.type=t_UNKNOWN;
while (CPU_Cycles-->0) {
#if C_DEBUG
cycle_count++;
#if C_HEAVY_DEBUG
@ -89,7 +92,7 @@ Bits Full_DeCode(void) {
};
#endif
#endif
inst.start=IPPoint;
inst.opcode_start=IPPoint;
inst.entry=inst.start_entry;
inst.prefix=inst.start_prefix;
restartopcode:
@ -99,13 +102,13 @@ restartopcode:
#include "core_full/op.h"
#include "core_full/save.h"
nextopcode:;
CPU_Cycles--;
}
exit_core:
LEAVECORE;
return CBRET_NONE;
}
void CPU_Core_Full_Start(bool big) {
cpudecoder=&Full_DeCode;
void CPU_Core_Full_Init(void) {
}

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -253,7 +253,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -272,7 +272,6 @@ clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
@ -295,7 +294,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -1,5 +1,12 @@
switch (inst.code.load) {
/* General loading */
case L_POPwRM:
inst.op1.w = Pop_16();
goto case_L_MODRM;
case L_POPdRM:
inst.op1.d = Pop_32();
goto case_L_MODRM;
case_L_MODRM:
case L_MODRM:
inst.rm=Fetchb();
inst.rm_index=(inst.rm >> 3) & 7;
@ -54,6 +61,9 @@ l_M_Ewx:
if (inst.rm<0xc0) inst.op1.ds=(Bit16s)LoadMw(inst.rm_eaa);
else inst.op1.ds=(Bit16s)reg_16(inst.rm_eai);
break;
case M_EwIb:
inst.op2.d=Fetchb();
goto l_M_Ew;
case M_EwIbx:
inst.op2.ds=Fetchbs();
goto l_M_Ew;
@ -65,6 +75,11 @@ l_M_Ewx:
goto l_M_EwGw;
case M_EwGwIb:
inst.imm.d=Fetchb();
goto l_M_EwGw;
case M_EwGwt:
inst.op2.d=reg_16(inst.rm_index);
inst.rm_eaa+=((Bit16s)inst.op2.d >> 4) * 2;
goto l_M_Ew;
l_M_EwGw:
case M_EwGw:
inst.op2.d=reg_16(inst.rm_index);
@ -89,6 +104,9 @@ l_M_Ew:
if (inst.rm<0xc0) inst.op1.d=(Bit32s)LoadMd(inst.rm_eaa);
else inst.op1.d=(Bit32s)reg_32(inst.rm_eai);
break;
case M_EdIb:
inst.op2.d=Fetchb();
goto l_M_Ed;
case M_EdIbx:
inst.op2.ds=Fetchbs();
goto l_M_Ed;
@ -98,8 +116,13 @@ l_M_Ew:
case M_EdGdCL:
inst.imm.d=reg_cl;
goto l_M_EdGd;
case M_EdGdt:
inst.op2.d=reg_32(inst.rm_index);
inst.rm_eaa+=((Bit32s)inst.op2.d >> 5) * 4;
goto l_M_Ed;
case M_EdGdIb:
inst.imm.d=Fetchb();
goto l_M_EdGd;
l_M_EdGd:
case M_EdGd:
inst.op2.d=reg_32(inst.rm_index);
@ -224,8 +247,7 @@ l_M_Ed:
inst.op1.d=reg_32(inst.code.extra);
break;
case L_FLG:
FillFlags();
inst.op1.d = flags.word;
inst.op1.d = FillFlags();
break;
case L_SEG:
inst.op1.d=SegValue((SegNames)inst.code.extra);
@ -260,7 +282,7 @@ l_M_Ed:
inst.repz=true;
goto restartopcode;
case L_PREOP:
inst.entry^=0x200;
inst.entry=inst.start_entry ^ 0x200;
goto restartopcode;
case L_PREADD:
inst.prefix^=PREFIX_ADDR;
@ -273,49 +295,41 @@ l_M_Ed:
inst.op1.d=4;
break;
case D_IRETw:
flags.type=t_UNKNOWN;
if (!CPU_IRET(false)) return CBRET_NONE;
LEAVECORE;
CPU_IRET(false);
if (GETFLAG(IF) && PIC_IRQCheck) {
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
goto restart_core;
case D_IRETd:
flags.type=t_UNKNOWN;
if (!CPU_IRET(true)) return CBRET_NONE;
LEAVECORE;
CPU_IRET(true);
if (GETFLAG(IF) && PIC_IRQCheck) {
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
goto restart_core;
case D_RETFwIw:
if (!CPU_RET(false,Fetchw())) {
FillFlags();
return CBRET_NONE;
{
Bitu words=Fetchw();
LEAVECORE;
CPU_RET(false,words);
goto restart_core;
}
LoadIP();
goto nextopcode;
case D_RETFw:
if (!CPU_RET(false,0)) {
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_RET(false,0);
goto restart_core;
case D_RETFdIw:
if (!CPU_RET(true,Fetchw())) {
FillFlags();
return CBRET_NONE;
{
Bitu words=Fetchw();
LEAVECORE;
CPU_RET(true,words);
goto restart_core;
}
LoadIP();
goto nextopcode;
case D_RETFd:
if (!CPU_RET(true,0)) {
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_RET(true,0);
goto restart_core;
/* Direct operations */
case L_STRING:
#include "string.h"
@ -342,16 +356,37 @@ l_M_Ed:
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
goto nextopcode;
case D_POPSEGw:
if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_16())) {
LEAVECORE;
reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=2;
CPU_StartException();goto restart_core;
}
goto nextopcode;
case D_POPSEGd:
if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_32())) {
LEAVECORE;
reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=4;
CPU_StartException();goto restart_core;
}
goto nextopcode;
case D_SETALC:
reg_al = get_CF() ? 0xFF : 0;
goto nextopcode;
case D_XLATw:
if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_bx+reg_al);
else reg_al=LoadMb(SegBase(ds)+reg_bx+reg_al);
goto nextopcode;
case D_XLATd:
if (inst.prefix & PREFIX_SEG) reg_al=LoadMb(inst.seg.base+reg_ebx+reg_al);
else reg_al=LoadMb(SegBase(ds)+reg_ebx+reg_al);
case D_XLAT:
if (inst.prefix & PREFIX_SEG) {
if (inst.prefix & PREFIX_ADDR) {
reg_al=LoadMb(inst.seg.base+(Bit32u)(reg_ebx+reg_al));
} else {
reg_al=LoadMb(inst.seg.base+(Bit16u)(reg_bx+reg_al));
}
} else {
if (inst.prefix & PREFIX_ADDR) {
reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al));
} else {
reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al));
}
}
goto nextopcode;
case D_CBW:
reg_ax=(Bit8s)reg_al;
@ -378,25 +413,22 @@ l_M_Ed:
}
goto nextopcode;
case D_STC:
SETFLAGBIT(CF,true);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
FillFlags();SETFLAGBIT(CF,true);
goto nextopcode;
case D_CLC:
SETFLAGBIT(CF,false);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
FillFlags();SETFLAGBIT(CF,false);
goto nextopcode;
case D_CMC:
SETFLAGBIT(CF,!get_CF());
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
FillFlags();
SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
goto nextopcode;
case D_CLD:
SETFLAGBIT(DF,false);
cpu.direction=1;
goto nextopcode;
case D_STD:
SETFLAGBIT(DF,true);
cpu.direction=-1;
goto nextopcode;
case D_WAIT:
case D_NOP:
@ -492,8 +524,11 @@ l_M_Ed:
goto nextopcode;
case D_HLT:
LEAVECORE;
CPU_HLT();
CPU_HLT(IPPoint-inst.opcode_start);
return CBRET_NONE;
case D_CLTS:
//TODO Really clear it sometime
goto nextopcode;
default:
LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry);
break;

View File

@ -27,26 +27,34 @@ static INLINE Bit32u the_Fetchd(EAPoint & loc) {
#define Fetchws() (Bit16s)the_Fetchw(IPPoint)
#define Fetchds() (Bit32s)the_Fetchd(IPPoint)
#if 0
static INLINE void Push_16(Bit16u blah) {
reg_esp-=2;
SaveMw(SegBase(ss) + (reg_esp & cpu.stack.mask),blah);
SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
}
static INLINE void Push_32(Bit32u blah) {
reg_esp-=4;
SaveMd(SegBase(ss) + (reg_esp & cpu.stack.mask),blah);
SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
}
static INLINE Bit16u Pop_16(void) {
Bit16u temp=LoadMw(SegBase(ss) + (reg_esp & cpu.stack.mask));
Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask));
reg_esp+=2;
return temp;
}
static INLINE Bit32u Pop_32(void) {
Bit32u temp=LoadMd(SegBase(ss) + (reg_esp & cpu.stack.mask));
Bit32u temp=LoadMd(SegBase(ss)+(reg_esp & cpu.stack.mask));
reg_esp+=4;
return temp;
}
#else
#define Push_16 CPU_Push16
#define Push_32 CPU_Push32
#define Pop_16 CPU_Pop16
#define Pop_32 CPU_Pop32
#endif

View File

@ -1,60 +1,62 @@
/* Do the actual opcode */
switch (inst.code.op) {
case t_ADDb: case t_ADDw: case t_ADDd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d + lf_var2d;
lflags.type=inst.code.op;
break;
case t_CMPb: case t_CMPw: case t_CMPd:
case t_SUBb: case t_SUBw: case t_SUBd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d - lf_var2d;
lflags.type=inst.code.op;
break;
case t_ORb: case t_ORw: case t_ORd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d | flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d | lf_var2d;
lflags.type=inst.code.op;
break;
case t_XORb: case t_XORw: case t_XORd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d ^ flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d ^ lf_var2d;
lflags.type=inst.code.op;
break;
case t_TESTb: case t_TESTw: case t_TESTd:
case t_ANDb: case t_ANDw: case t_ANDd:
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d & flags.var2.d;
flags.type=inst.code.op;
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d & lf_var2d;
lflags.type=inst.code.op;
break;
case t_ADCb: case t_ADCw: case t_ADCd:
flags.oldcf=get_CF();
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d + flags.var2.d + flags.oldcf;
flags.type=inst.code.op;
lflags.oldcf=(get_CF()!=0);
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d + lf_var2d + lflags.oldcf;
lflags.type=inst.code.op;
break;
case t_SBBb: case t_SBBw: case t_SBBd:
flags.oldcf=get_CF();
flags.var1.d=inst.op1.d;
flags.var2.d=inst.op2.d;
inst.op1.d=flags.result.d=flags.var1.d - flags.var2.d - flags.oldcf;
flags.type=inst.code.op;
lflags.oldcf=(get_CF()!=0);
lf_var1d=inst.op1.d;
lf_var2d=inst.op2.d;
inst.op1.d=lf_resd=lf_var1d - lf_var2d - lflags.oldcf;
lflags.type=inst.code.op;
break;
case t_INCb: case t_INCw: case t_INCd:
SETFLAGBIT(CF,get_CF());
inst.op1.d=flags.result.d=inst.op1.d+1;
flags.type=inst.code.op;
LoadCF;
lf_var1d=inst.op1.d;
inst.op1.d=lf_resd=inst.op1.d+1;
lflags.type=inst.code.op;
break;
case t_DECb: case t_DECw: case t_DECd:
SETFLAGBIT(CF,get_CF());
inst.op1.d=flags.result.d=inst.op1.d-1;
flags.type=inst.code.op;
LoadCF;
lf_var1d=inst.op1.d;
inst.op1.d=lf_resd=inst.op1.d-1;
lflags.type=inst.code.op;
break;
/* Using the instructions.h defines */
case t_ROLb:
@ -149,19 +151,19 @@ switch (inst.code.op) {
}
case t_NEGb:
flags.var1.b=inst.op1.b;
inst.op1.b=flags.result.b=0-inst.op1.b;
flags.type=t_NEGb;
lf_var1b=inst.op1.b;
inst.op1.b=lf_resb=0-inst.op1.b;
lflags.type=t_NEGb;
break;
case t_NEGw:
flags.var1.w=inst.op1.w;
inst.op1.w=flags.result.w=0-inst.op1.w;
flags.type=t_NEGw;
lf_var1w=inst.op1.w;
inst.op1.w=lf_resw=0-inst.op1.w;
lflags.type=t_NEGw;
break;
case t_NEGd:
flags.var1.d=inst.op1.d;
inst.op1.d=flags.result.d=0-inst.op1.d;
flags.type=t_NEGd;
lf_var1d=inst.op1.d;
inst.op1.d=lf_resd=0-inst.op1.d;
lflags.type=t_NEGd;
break;
case O_NOT:
@ -218,22 +220,22 @@ switch (inst.code.op) {
AAD(inst.op1.b);
goto nextopcode;
case O_C_O: inst.cond=get_OF(); break;
case O_C_NO: inst.cond=!get_OF(); break;
case O_C_B: inst.cond=get_CF(); break;
case O_C_NB: inst.cond=!get_CF(); break;
case O_C_Z: inst.cond=get_ZF(); break;
case O_C_NZ: inst.cond=!get_ZF(); break;
case O_C_BE: inst.cond=get_CF() || get_ZF(); break;
case O_C_NBE: inst.cond=!get_CF() && !get_ZF(); break;
case O_C_S: inst.cond=get_SF(); break;
case O_C_NS: inst.cond=!get_SF(); break;
case O_C_P: inst.cond=get_PF(); break;
case O_C_NP: inst.cond=!get_PF(); break;
case O_C_L: inst.cond=get_SF() != get_OF(); break;
case O_C_NL: inst.cond=get_SF() == get_OF(); break;
case O_C_LE: inst.cond=get_ZF() || (get_SF() != get_OF()); break;
case O_C_NLE: inst.cond=(get_SF() == get_OF()) && !get_ZF(); break;
case O_C_O: inst.cond=TFLG_O; break;
case O_C_NO: inst.cond=TFLG_NO; break;
case O_C_B: inst.cond=TFLG_B; break;
case O_C_NB: inst.cond=TFLG_NB; break;
case O_C_Z: inst.cond=TFLG_Z; break;
case O_C_NZ: inst.cond=TFLG_NZ; break;
case O_C_BE: inst.cond=TFLG_BE; break;
case O_C_NBE: inst.cond=TFLG_NBE; break;
case O_C_S: inst.cond=TFLG_S; break;
case O_C_NS: inst.cond=TFLG_NS; break;
case O_C_P: inst.cond=TFLG_P; break;
case O_C_NP: inst.cond=TFLG_NP; break;
case O_C_L: inst.cond=TFLG_L; break;
case O_C_NL: inst.cond=TFLG_NL; break;
case O_C_LE: inst.cond=TFLG_LE; break;
case O_C_NLE: inst.cond=TFLG_NLE; break;
case O_ALOP:
reg_al=LoadMb(inst.rm_eaa);
@ -320,66 +322,48 @@ switch (inst.code.op) {
Push_32(reg_eip);
break;
case O_CALLFw:
SaveIP();
if (!CPU_CALL(false,inst.op2.d,inst.op1.d)) {
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_CALL(false,inst.op2.d,inst.op1.d);
goto restart_core;
case O_CALLFd:
SaveIP();
if (!CPU_CALL(true,inst.op2.d,inst.op1.d)) {
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_CALL(true,inst.op2.d,inst.op1.d);
goto restart_core;
case O_JMPFw:
if (!CPU_JMP(false,inst.op2.d,inst.op1.d)){
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_JMP(false,inst.op2.d,inst.op1.d);
goto restart_core;
case O_JMPFd:
if (!CPU_JMP(true,inst.op2.d,inst.op1.d)) {
FillFlags();
return CBRET_NONE;
}
LoadIP();
goto nextopcode;
LEAVECORE;
CPU_JMP(true,inst.op2.d,inst.op1.d);
goto restart_core;
case O_INT:
LEAVECORE;
#if C_DEBUG
if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint()) return debugCallback;
else if (DEBUG_IntBreakpoint(inst.op1.b)) return debugCallback;
if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint())
return debugCallback;
else if (DEBUG_IntBreakpoint(inst.op1.b))
return debugCallback;
#endif
if (!Interrupt(inst.op1.b)) return CBRET_NONE;
LoadIP();
break;
CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.opcode_start);
goto restart_core;
case O_INb:
reg_al=IO_Read(inst.op1.d);
reg_al=IO_ReadB(inst.op1.d);
goto nextopcode;
case O_INw:
reg_ax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8);
reg_ax=IO_ReadW(inst.op1.d);
goto nextopcode;
case O_INd:
reg_eax=IO_Read(inst.op1.d) | (IO_Read(inst.op1.d+1) << 8) | (IO_Read(inst.op1.d+2) << 16) | (IO_Read(inst.op1.d+3) << 24);
reg_eax=IO_ReadD(inst.op1.d);
goto nextopcode;
case O_OUTb:
IO_Write(inst.op1.d,reg_al);
IO_WriteB(inst.op1.d,reg_al);
goto nextopcode;
case O_OUTw:
IO_Write(inst.op1.d+0,(Bit8u)reg_ax);
IO_Write(inst.op1.d+1,(Bit8u)(reg_ax >> 8));
IO_WriteW(inst.op1.d,reg_ax);
goto nextopcode;
case O_OUTd:
IO_Write(inst.op1.d+0,(Bit8u)reg_eax);
IO_Write(inst.op1.d+1,(Bit8u)(reg_eax >> 8));
IO_Write(inst.op1.d+2,(Bit8u)(reg_eax >> 16));
IO_Write(inst.op1.d+3,(Bit8u)(reg_eax >> 24));
IO_WriteD(inst.op1.d,reg_eax);
goto nextopcode;
case O_CBACK:
LEAVECORE;
@ -458,12 +442,19 @@ switch (inst.code.op) {
LOG(LOG_CPU,LOG_ERROR)("Group 7 Illegal subfunction %X",inst.rm_index);
}
break;
case O_M_Cd_Rd:
case O_M_CRx_Rd:
CPU_SET_CRX(inst.rm_index,inst.op1.d);
break;
case O_M_Rd_Cd:
case O_M_Rd_CRx:
inst.op1.d=CPU_GET_CRX(inst.rm_index);
break;
case O_M_DRx_Rd:
// LOG(LOG_CPU,LOG_NORMAL)("MOV DR%d,%X",inst.rm_index,inst.op1.d);
break;
case O_M_Rd_DRx:
inst.op1.d=0;
// LOG(LOG_CPU,LOG_NORMAL)("MOV %X,DR%d",inst.op1.d,inst.rm_index);
break;
case O_LAR:
{
FillFlags();
@ -491,11 +482,12 @@ switch (inst.code.op) {
FillFlags();
if (!inst.op1.w) {
SETFLAGBIT(ZF,true);
goto nextopcode;
} else {
Bitu count=0;
while (count<16) {
if ((inst.op1.w>>count) & 1) break;
count++;
while (1) {
if (inst.op1.w & 0x1) break;
count++;inst.op1.w>>=1;
}
inst.op1.d=count;
SETFLAGBIT(ZF,false);
@ -507,11 +499,12 @@ switch (inst.code.op) {
FillFlags();
if (!inst.op1.d) {
SETFLAGBIT(ZF,true);
goto nextopcode;
} else {
Bitu count=0;
while (count<32) {
if ((inst.op1.d>>count) & 1) break;
count++;
while (1) {
if (inst.op1.d & 0x1) break;
count++;inst.op1.d>>=1;
}
inst.op1.d=count;
SETFLAGBIT(ZF,false);
@ -523,11 +516,12 @@ switch (inst.code.op) {
FillFlags();
if (!inst.op1.w) {
SETFLAGBIT(ZF,true);
goto nextopcode;
} else {
Bits count=15;
while (count>0) {
if ((inst.op1.w>>count) & 1) break;
count--;
Bitu count=15;
while (1) {
if (inst.op1.w & 0x8000) break;
count--;inst.op1.w<<=1;
}
inst.op1.d=count;
SETFLAGBIT(ZF,false);
@ -539,11 +533,12 @@ switch (inst.code.op) {
FillFlags();
if (!inst.op1.d) {
SETFLAGBIT(ZF,true);
goto nextopcode;
} else {
Bits count=31;
while (count>0) {
if ((inst.op1.d>>count) & 1) break;
count--;
Bitu count=31;
while (1) {
if (inst.op1.d & 0x80000000) break;
count--;inst.op1.d<<=1;
}
inst.op1.d=count;
SETFLAGBIT(ZF,false);
@ -551,56 +546,42 @@ switch (inst.code.op) {
}
break;
case O_BTw:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
break;
case O_BTSw:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
inst.op1.d|=(1 << (inst.op2.d & 15));
break;
case O_BTCw:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
inst.op1.d^=(1 << (inst.op2.d & 15));
break;
case O_BTRw:
{
Bitu val;PhysPt read;
Bitu mask=1 << (inst.op1.d & 15);
FillFlags();
if (inst.rm<0xc0) {
read=inst.rm_eaa;//+2*(inst.op1.d / 16);
val=mem_readw(read);
} else {
val=reg_16(inst.rm_eai);
}
SETFLAGBIT(CF,(val&mask)>0);
if (inst.code.op==O_BTSw) val|=mask;
if (inst.code.op==O_BTRw) val&=~mask;
if (inst.code.op==O_BTCw) val^=mask;
if (inst.code.op==O_BTw) break;
if (inst.rm<0xc0) {
mem_writew(read,val);
} else {
reg_16(inst.rm_eai)=val;
}
}
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 15))));
inst.op1.d&=~(1 << (inst.op2.d & 15));
break;
case O_BTd:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
break;
case O_BTSd:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
inst.op1.d|=(1 << (inst.op2.d & 31));
break;
case O_BTCd:
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
inst.op1.d^=(1 << (inst.op2.d & 31));
break;
case O_BTRd:
{
Bitu val;PhysPt read;
Bitu mask=1 << (inst.op1.d & 31);
FillFlags();
if (inst.rm<0xc0) {
read=inst.rm_eaa;//+4*(inst.op1.d / 32);
val=mem_readd(read);
} else {
val=reg_32(inst.rm_eai);
}
SETFLAGBIT(CF,(val&mask)>0);
if (inst.code.op==O_BTSd) val|=mask;
if (inst.code.op==O_BTRd) val&=~mask;
if (inst.code.op==O_BTCd) val^=mask;
if (inst.code.op==O_BTd) break;
if (inst.rm<0xc0) {
mem_writed(read,val);
} else {
reg_32(inst.rm_eai)=val;
}
}
FillFlags();
SETFLAGBIT(CF,(inst.op1.d & (1 << (inst.op2.d & 31))));
inst.op1.d&=~(1 << (inst.op2.d & 31));
break;
case O_BSWAP:
BSWAP(inst.op1.d);

View File

@ -4,7 +4,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDw ,S_Ew ,M_EwGw },
{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDw ,S_Gw ,M_GwEw },
{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADDw ,S_REGw ,REGI_AX },
{L_SEG ,0 ,S_PUSHw,es },{L_POPw ,0 ,S_SEGI ,es },
{L_SEG ,0 ,S_PUSHw,es },{D_POPSEGw,0 ,0 ,es },
/* 0x08 - 0x0f */
{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORw ,S_Ew ,M_EwGw },
{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORw ,S_Gw ,M_GwEw },
@ -15,12 +15,12 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCw ,S_Ew ,M_EwGw },
{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCw ,S_Gw ,M_GwEw },
{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGwIw ,t_ADCw ,S_REGw ,REGI_AX },
{L_SEG ,0 ,S_PUSHw,ss },{L_POPw ,0 ,S_SEGI ,ss },
{L_SEG ,0 ,S_PUSHw,ss },{D_POPSEGw,0 ,0 ,ss },
/* 0x18 - 0x1f */
{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBw ,S_Ew ,M_EwGw },
{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBw ,S_Gw ,M_GwEw },
{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGwIw ,t_SBBw ,S_REGw ,REGI_AX },
{L_SEG ,0 ,S_PUSHw,ds },{L_POPw ,0 ,S_SEGI ,ds },
{L_SEG ,0 ,S_PUSHw,ds },{D_POPSEGw,0 ,0 ,ds },
/* 0x20 - 0x27 */
{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDw ,S_Ew ,M_EwGw },
@ -100,7 +100,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ew ,M_Gw },
{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew },
{L_MODRM ,0 ,S_Ew ,M_SEG },{L_MODRM ,0 ,S_Gw ,M_EA },
{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ew ,M_POPw },
{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPwRM ,0 ,S_Ew ,M_None },
/* 0x90 - 0x97 */
{D_NOP ,0 ,0 ,0 },{L_REGw ,O_XCHG_AX ,S_REGw ,REGI_CX},
@ -150,7 +150,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,6 ,0 ,M_GRP_1 },
{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,6 ,0 ,M_GRP_CL },
{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 },
{D_SETALC ,0 ,0 ,0 },{D_XLATw ,0 ,0 ,0 },
{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 },
//TODO FPU
/* 0xd8 - 0xdf */
{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 },
@ -184,7 +184,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew },
{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew },
{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 },
/* 0x108 - 0x10f */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
@ -203,8 +203,8 @@ static OpCode OpCodeTable[1024]={
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x120 - 0x127 */
{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 },
{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 },
{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
@ -293,24 +293,24 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 },
/* 0x1a0 - 0x1a7 */
{L_SEG ,0 ,S_PUSHw ,fs },{L_POPw ,0 ,S_SEGI ,fs },
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,0 ,M_Gw },
{L_SEG ,0 ,S_PUSHw ,fs },{D_POPSEGw,0 ,0 ,fs },
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTw ,S_Ew ,M_EwGwt },
{L_MODRM ,O_DSHLw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHLw ,S_Ew ,M_EwGwCL },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x1a8 - 0x1af */
{L_SEG ,0 ,S_PUSHw ,gs },{L_POPw ,0 ,S_SEGI ,gs },
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,0 ,M_Gw },
{L_SEG ,0 ,S_PUSHw ,gs },{D_POPSEGw,0 ,0 ,gs },
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSw ,S_Ew ,M_EwGwt },
{L_MODRM ,O_DSHRw ,S_Ew,M_EwGwIb },{L_MODRM ,O_DSHRw ,S_Ew ,M_EwGwCL },
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRw ,S_Gw ,M_EwxGwx },
/* 0x1b0 - 0x1b7 */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,0 ,M_Gw },
{L_MODRM ,O_SEGSS ,S_SEGGw,M_Efw },{L_MODRM ,O_BTRw ,S_Ew ,M_EwGwt },
{L_MODRM ,O_SEGFS ,S_SEGGw,M_Efw },{L_MODRM ,O_SEGGS ,S_SEGGw,M_Efw },
{L_MODRM ,0 ,S_Gw ,M_Eb },{L_MODRM ,0 ,S_Gw ,M_Ew },
/* 0x1b8 - 0x1bf */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,0 ,M_Gw },
{L_MODRM ,0xe ,0 ,M_GRP },{L_MODRM ,O_BTCw ,S_Ew ,M_EwGwt },
{L_MODRM ,O_BSFw ,S_Gw ,M_Ew },{L_MODRM ,O_BSRw ,S_Gw ,M_Ew },
{L_MODRM ,0 ,S_Gw ,M_Ebx },{L_MODRM ,0 ,S_Gw ,M_Ewx },
@ -363,7 +363,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,t_ADDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADDd ,S_Ed ,M_EdGd },
{L_MODRM ,t_ADDb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADDd ,S_Gd ,M_GdEd },
{L_REGbIb ,t_ADDb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADDd ,S_REGd ,REGI_AX },
{L_SEG ,0 ,S_PUSHd,es },{L_POPd ,0 ,S_SEGI ,es },
{L_SEG ,0 ,S_PUSHd,es },{D_POPSEGd,0 ,0 ,es },
/* 0x208 - 0x20f */
{L_MODRM ,t_ORb ,S_Eb ,M_EbGb },{L_MODRM ,t_ORd ,S_Ed ,M_EdGd },
{L_MODRM ,t_ORb ,S_Gb ,M_GbEb },{L_MODRM ,t_ORd ,S_Gd ,M_GdEd },
@ -374,12 +374,12 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,t_ADCb ,S_Eb ,M_EbGb },{L_MODRM ,t_ADCd ,S_Ed ,M_EdGd },
{L_MODRM ,t_ADCb ,S_Gb ,M_GbEb },{L_MODRM ,t_ADCd ,S_Gd ,M_GdEd },
{L_REGbIb ,t_ADCb ,S_REGb ,REGI_AL },{L_REGdId ,t_ADCd ,S_REGd ,REGI_AX },
{L_SEG ,0 ,S_PUSHd,ss },{L_POPd ,0 ,S_SEGI ,ss },
{L_SEG ,0 ,S_PUSHd,ss },{D_POPSEGd,0 ,0 ,ss },
/* 0x218 - 0x21f */
{L_MODRM ,t_SBBb ,S_Eb ,M_EbGb },{L_MODRM ,t_SBBd ,S_Ed ,M_EdGd },
{L_MODRM ,t_SBBb ,S_Gb ,M_GbEb },{L_MODRM ,t_SBBd ,S_Gd ,M_GdEd },
{L_REGbIb ,t_SBBb ,S_REGb ,REGI_AL },{L_REGdId ,t_SBBd ,S_REGd ,REGI_AX },
{L_SEG ,0 ,S_PUSHd,ds },{L_POPd ,0 ,S_SEGI ,ds },
{L_SEG ,0 ,S_PUSHd,ds },{D_POPSEGd,0 ,0 ,ds },
/* 0x220 - 0x227 */
{L_MODRM ,t_ANDb ,S_Eb ,M_EbGb },{L_MODRM ,t_ANDd ,S_Ed ,M_EdGd },
@ -456,7 +456,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,0 ,S_Eb ,M_Gb },{L_MODRM ,0 ,S_Ed ,M_Gd },
{L_MODRM ,0 ,S_Gb ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ed },
{L_MODRM ,0 ,S_EdMw ,M_SEG },{L_MODRM ,0 ,S_Gd ,M_EA },
{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_MODRM ,0 ,S_Ed ,M_POPd },
{L_MODRM ,0 ,S_SEGm ,M_Ew },{L_POPdRM ,0 ,S_Ed ,M_None },
/* 0x290 - 0x297 */
{D_NOP ,0 ,0 ,0 },{L_REGd ,O_XCHG_EAX ,S_REGd ,REGI_CX},
@ -506,7 +506,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,5 ,0 ,M_GRP_1 },{L_MODRM ,7 ,0 ,M_GRP_1 },
{L_MODRM ,5 ,0 ,M_GRP_CL },{L_MODRM ,7 ,0 ,M_GRP_CL },
{L_Ib ,O_AAM ,0 ,0 },{L_Ib ,O_AAD ,0 ,0 },
{D_SETALC ,0 ,0 ,0 },{D_XLATd ,0 ,0 ,0 },
{D_SETALC ,0 ,0 ,0 },{D_XLAT ,0 ,0 ,0 },
/* 0x2d8 - 0x2df */
{L_MODRM ,O_FPU ,0 ,0 },{L_MODRM ,O_FPU ,1 ,0 },
{L_MODRM ,O_FPU ,2 ,0 },{L_MODRM ,O_FPU ,3 ,0 },
@ -540,7 +540,7 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew },
{L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew },
{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 },
/* 0x308 - 0x30f */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
@ -559,8 +559,8 @@ static OpCode OpCodeTable[1024]={
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x320 - 0x327 */
{L_MODRM ,O_M_Rd_Cd ,S_Ed ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,O_M_Cd_Rd ,0 ,M_Ed },{0 ,0 ,0 ,0 },
{L_MODRM ,O_M_Rd_CRx ,S_Ed ,0 },{L_MODRM ,O_M_Rd_DRx ,S_Ed ,0 },
{L_MODRM ,O_M_CRx_Rd ,0 ,M_Ed },{L_MODRM ,O_M_DRx_Rd ,0 ,M_Ed },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
@ -649,24 +649,24 @@ static OpCode OpCodeTable[1024]={
{L_MODRM ,O_C_LE ,S_C_Eb,0 },{L_MODRM ,O_C_NLE ,S_C_Eb,0 },
/* 0x3a0 - 0x3a7 */
{L_SEG ,0 ,S_PUSHd ,fs },{L_POPd ,0 ,S_SEGI ,fs },
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,0 ,M_Gd },
{L_SEG ,0 ,S_PUSHd ,fs },{D_POPSEGd,0 ,0 ,fs },
{D_CPUID ,0 ,0 ,0 },{L_MODRM ,O_BTd ,S_Ed ,M_EdGdt },
{L_MODRM ,O_DSHLd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHLd ,S_Ed ,M_EdGdCL },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
/* 0x3a8 - 0x3af */
{L_SEG ,0 ,S_PUSHd ,gs },{L_POPd ,0 ,S_SEGI ,gs },
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,0 ,M_Gd },
{L_SEG ,0 ,S_PUSHd ,gs },{D_POPSEGd,0 ,0 ,gs },
{0 ,0 ,0 ,0 },{L_MODRM ,O_BTSd ,S_Ed ,M_EdGdt },
{L_MODRM ,O_DSHRd ,S_Ed,M_EdGdIb },{L_MODRM ,O_DSHRd ,S_Ed ,M_EdGdCL },
{0 ,0 ,0 ,0 },{L_MODRM ,O_IMULRd ,S_Gd ,M_EdxGdx },
/* 0x3b0 - 0x3b7 */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,O_SEGSS ,S_SEGGd,M_Efd },{L_MODRM ,O_BTRd ,0 ,M_Gd },
{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 ,0 ,S_Gd ,M_Eb },{L_MODRM ,0 ,S_Gd ,M_Ew },
/* 0x3b8 - 0x3bf */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,0 ,M_Gd },
{L_MODRM ,0xf ,0 ,M_GRP },{L_MODRM ,O_BTCd ,S_Ed ,M_EdGdt },
{L_MODRM ,O_BSFd ,S_Gd ,M_Ed },{L_MODRM ,O_BSRd ,S_Gd ,M_Ed },
{L_MODRM ,0 ,S_Gd ,M_Ebx },{L_MODRM ,0 ,S_Gd ,M_Ewx },
@ -796,13 +796,13 @@ static OpCode Groups[16][8]={
},{ /* 0x0e Group 8 Ew */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,O_BTw ,0 ,M_Ib },{0 ,O_BTSw ,0 ,M_Ib },
{0 ,O_BTRw ,0 ,M_Ib },{0 ,O_BTCw ,0 ,M_Ib },
{0 ,O_BTw ,S_Ew ,M_EwIb },{0 ,O_BTSw ,S_Ew ,M_EwIb },
{0 ,O_BTRw ,S_Ew ,M_EwIb },{0 ,O_BTCw ,S_Ew ,M_EwIb },
},{ /* 0x0f Group 8 Ed */
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
{0 ,O_BTd ,0 ,M_Ib },{0 ,O_BTSd ,0 ,M_Ib },
{0 ,O_BTRd ,0 ,M_Ib },{0 ,O_BTCd ,0 ,M_Ib },
{0 ,O_BTd ,S_Ed ,M_EdIb },{0 ,O_BTSd ,S_Ed ,M_EdIb },
{0 ,O_BTRd ,S_Ed ,M_EdIb },{0 ,O_BTCd ,S_Ed ,M_EdIb },

View File

@ -55,19 +55,31 @@ switch (inst.code.save) {
case S_REGd:
reg_32(inst.code.extra)=inst.op1.d;
break;
case S_SEGI:
CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op1.w);
break;
case S_SEGm:
CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w);
if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) {
LEAVECORE;
reg_eip-=(IPPoint-inst.opcode_start);
CPU_StartException();
goto restart_core;
}
break;
case S_SEGGw:
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) {
LEAVECORE;
reg_eip-=(IPPoint-inst.opcode_start);
CPU_StartException();
goto restart_core;
}
reg_16(inst.rm_index)=inst.op1.w;
CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w);
break;
case S_SEGGd:
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) {
LEAVECORE;
reg_eip-=(IPPoint-inst.opcode_start);
CPU_StartException();
goto restart_core;
}
reg_32(inst.rm_index)=inst.op1.d;
CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w);
break;
case S_PUSHw:
Push_16(inst.op1.w);

View File

@ -23,53 +23,49 @@
count=1;
} else {
/* Calculate amount of ops to do before cycles run out */
CPU_Cycles++;
if ((count>(Bitu)CPU_Cycles) && (inst.code.op<R_SCASB)) {
count_left=count-CPU_Cycles;
count=CPU_Cycles;
CPU_Cycles=0;
IPPoint=inst.start; //Reset IP to start of instruction
IPPoint=inst.opcode_start; //Reset IP to start of instruction
} else {
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
count_left=0;
}
}
add_index=GETFLAG(DF) ? -1 : 1;
add_index=cpu.direction;
if (count) switch (inst.code.op) {
case R_OUTSB:
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_WriteB(reg_dx,LoadMb(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_OUTSW:
add_index<<=1;
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
IO_WriteW(reg_dx,LoadMw(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_OUTSD:
add_index<<=2;
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
IO_Write(reg_dx+2,LoadMb(si_base+si_index+2));
IO_Write(reg_dx+3,LoadMb(si_base+si_index+3));
IO_WriteD(reg_dx,LoadMd(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_INSB:
for (;count>0;count--) {
SaveMb(di_base+di_index,IO_Read(reg_dx));
SaveMb(di_base+di_index,IO_ReadB(reg_dx));
di_index=(di_index+add_index) & add_mask;
}
break;
case R_INSW:
add_index<<=1;
for (;count>0;count--) {
SaveMb(di_base+di_index,IO_Read(reg_dx));
SaveMb(di_base+di_index+1,IO_Read(reg_dx+1));
SaveMw(di_base+di_index,IO_ReadW(reg_dx));
di_index=(di_index+add_index) & add_mask;
}
break;

View File

@ -2,7 +2,7 @@ enum {
L_N=0,
L_SKIP,
/* Grouped ones using MOD/RM */
L_MODRM,
L_MODRM,L_POPwRM,L_POPdRM,
L_Ib,L_Iw,L_Id,
L_Ibx,L_Iwx,L_Idx, //Sign extend
@ -15,8 +15,6 @@ enum {
L_POPfw,L_POPfd,
L_SEG,
L_FLG,L_INTO,
L_VAL,
@ -29,22 +27,23 @@ enum {
D_IRETw,D_IRETd,
D_PUSHAw,D_PUSHAd,
D_POPAw,D_POPAd,
D_POPSEGw,D_POPSEGd,
D_DAA,D_DAS,
D_AAA,D_AAS,
D_CBW,D_CWDE,
D_CWD,D_CDQ,
D_SETALC,
D_XLATw,D_XLATd,
D_XLAT,
D_CLI,D_STI,D_STC,D_CLC,D_CMC,D_CLD,D_STD,
D_NOP,D_WAIT,
D_ENTERw,D_ENTERd,
D_LEAVEw,D_LEAVEd,
L_ERROR,
D_RETFw,D_RETFd,
D_RETFwIw,D_RETFdIw,
D_CPUID,
D_HLT,
D_HLT,D_CLTS,
L_ERROR,
};
@ -82,7 +81,8 @@ enum {
O_GRP6w,O_GRP6d,
O_GRP7w,O_GRP7d,
O_M_Cd_Rd,O_M_Rd_Cd,
O_M_CRx_Rd,O_M_Rd_CRx,
O_M_DRx_Rd,O_M_Rd_DRx,
O_LAR,O_LSL,
O_ARPL,
@ -106,7 +106,6 @@ enum {
S_REGb,S_REGw,S_REGd,
S_PUSHw,S_PUSHd,
S_SEGI,
S_SEGm,
S_SEGGw,S_SEGGd,
@ -131,10 +130,10 @@ enum {
enum {
M_None=0,
M_Ebx,M_Eb,M_Gb,M_EbGb,M_GbEb,
M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,
M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,
M_Ewx,M_Ew,M_Gw,M_EwGw,M_GwEw,M_EwxGwx,M_EwGwt,
M_Edx,M_Ed,M_Gd,M_EdGd,M_GdEd,M_EdxGdx,M_EdGdt,
M_EbIb,
M_EbIb,M_EwIb,M_EdIb,
M_EwIw,M_EwIbx,M_EwxIbx,M_EwxIwx,M_EwGwIb,M_EwGwCL,
M_EdId,M_EdIbx,M_EdGdIb,M_EdGdCL,
@ -156,7 +155,7 @@ struct OpCode {
struct FullData {
Bitu entry;
EAPoint start;
EAPoint opcode_start;
Bitu rm;
EAPoint rm_eaa;
Bitu rm_off;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -115,6 +115,9 @@ static struct {
PhysPt seg_prefix_base;
bool rep_zero;
GetEATable * ea_table;
struct {
bool skip;
} trap;
} core;
#include "instructions.h"
@ -148,14 +151,18 @@ static GetEATable * EAPrefixTable[8] = {
#define EALookupTable (*(core.ea_table))
static Bits CPU_Core_Normal_Decode_Trap(void);
static Bits CPU_Core_Normal_Decode(void) {
Bits CPU_Core_Normal_Run(void) {
decode_start:
if (cpu.code.big) {
core.index_default=0x200;
core.prefix_default=PREFIX_ADDR;
} else {
core.index_default=0;
core.prefix_default=0;
}
LOADIP;
flags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
lflags.type=t_UNKNOWN;
while (CPU_Cycles-->0) {
core.op_start=core.ip_lookup;
core.opcode_index=core.index_default;
core.prefixes=core.prefix_default;
@ -169,7 +176,6 @@ decode_start:
};
#endif
#endif
CPU_Cycles--;
restart_prefix:
core.ea_table=EAPrefixTable[core.prefixes];
restart_opcode:
@ -193,33 +199,23 @@ restart_opcode:
return CBRET_NONE;
}
static Bits CPU_Core_Normal_Decode_Trap(void) {
Bits CPU_Core_Normal_Trap_Run(void) {
Bits oldCycles = CPU_Cycles;
CPU_Cycles = 1;
Bits ret=CPU_Core_Normal_Decode();
Interrupt(1);
core.trap.skip=false;
Bits ret=CPU_Core_Normal_Run();
if (!core.trap.skip) CPU_SW_Interrupt(1,0);
CPU_Cycles = oldCycles-1;
cpudecoder = &CPU_Core_Normal_Decode;
cpudecoder = &CPU_Core_Normal_Run;
return ret;
}
void CPU_Core_Normal_Start(bool big) {
void CPU_Core_Normal_Init(void) {
if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap;
else cpudecoder=CPU_Core_Normal_Decode;
if (big) {
core.index_default=0x200;
core.prefix_default=PREFIX_ADDR;
} else {
core.index_default=0;
core.prefix_default=0;
}
}

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -253,7 +253,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -272,7 +272,6 @@ clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am
@ -295,7 +294,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -141,3 +141,17 @@
} \
}
#define POPSEG(_SEG_,_VAL_,_ESP_CHANGE_) \
if (CPU_SetSegGeneral(_SEG_,_VAL_)) { \
LEAVECORE; \
reg_eip-=(core.ip_lookup-core.op_start);reg_esp-=_ESP_CHANGE_; \
CPU_StartException();goto decode_start; \
}
#define LOADSEG(_SEG_,_SEG_VAL_) \
if (CPU_SetSegGeneral(_SEG_,_SEG_VAL_)) { \
LEAVECORE; \
reg_eip-=(core.ip_lookup-core.op_start); \
CPU_StartException();goto decode_start; \
} \

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -36,7 +36,6 @@
Bitu loadval;
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
else {GetEAa;loadval=LoadMw(eaa);}
break;
switch (which) {
case 0x02:CPU_LLDT(loadval);break;
case 0x03:CPU_LTR(loadval);break;
@ -44,6 +43,7 @@
case 0x05:CPU_VERW(loadval);break;
}
}
break;
default:
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
}
@ -121,6 +121,8 @@
*rmrw=(Bit16u)limit;
}
break;
CASE_0F_B(0x06) /* CLTS */
break;
CASE_0F_B(0x20) /* MOV Rd.CRx */
{
GetRM;
@ -134,13 +136,25 @@
}
}
break;
CASE_0F_B(0x21) /* MOV Rd,DRx */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV XXX,DR% with non-register",which);
}
}
break;
CASE_0F_B(0x22) /* MOV CRx,Rd */
{
GetRM;
Bitu which=(rm >> 3) & 7;
if (rm >= 0xc0 ) {
GetEArd;
if (!CPU_SET_CRX(which,*eard)) goto decode_end;
CPU_SET_CRX(which,*eard);
} else {
GetEAa;
LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which);
@ -160,88 +174,89 @@
}
break;
CASE_0F_W(0x80) /* JO */
JumpSIw(get_OF());break;
JumpCond16_w(TFLG_O);break;
CASE_0F_W(0x81) /* JNO */
JumpSIw(!get_OF());break;
JumpCond16_w(TFLG_NO);break;
CASE_0F_W(0x82) /* JB */
JumpSIw(get_CF());break;
JumpCond16_w(TFLG_B);break;
CASE_0F_W(0x83) /* JNB */
JumpSIw(!get_CF());break;
JumpCond16_w(TFLG_NB);break;
CASE_0F_W(0x84) /* JZ */
JumpSIw(get_ZF());break;
JumpCond16_w(TFLG_Z);break;
CASE_0F_W(0x85) /* JNZ */
JumpSIw(!get_ZF());break;
JumpCond16_w(TFLG_NZ);break;
CASE_0F_W(0x86) /* JBE */
JumpSIw(get_CF() || get_ZF());break;
JumpCond16_w(TFLG_BE);break;
CASE_0F_W(0x87) /* JNBE */
JumpSIw(!get_CF() && !get_ZF());break;
JumpCond16_w(TFLG_NBE);break;
CASE_0F_W(0x88) /* JS */
JumpSIw(get_SF());break;
JumpCond16_w(TFLG_S);break;
CASE_0F_W(0x89) /* JNS */
JumpSIw(!get_SF());break;
JumpCond16_w(TFLG_NS);break;
CASE_0F_W(0x8a) /* JP */
JumpSIw(get_PF());break;
JumpCond16_w(TFLG_P);break;
CASE_0F_W(0x8b) /* JNP */
JumpSIw(!get_PF());break;
JumpCond16_w(TFLG_NP);break;
CASE_0F_W(0x8c) /* JL */
JumpSIw(get_SF() != get_OF());break;
JumpCond16_w(TFLG_L);break;
CASE_0F_W(0x8d) /* JNL */
JumpSIw(get_SF() == get_OF());break;
JumpCond16_w(TFLG_NL);break;
CASE_0F_W(0x8e) /* JLE */
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
JumpCond16_w(TFLG_LE);break;
CASE_0F_W(0x8f) /* JNLE */
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
JumpCond16_w(TFLG_NLE);break;
CASE_0F_B(0x90) /* SETO */
SETcc(get_OF());break;
SETcc(TFLG_O);break;
CASE_0F_B(0x91) /* SETNO */
SETcc(!get_OF());break;
SETcc(TFLG_NO);break;
CASE_0F_B(0x92) /* SETB */
SETcc(get_CF());break;
SETcc(TFLG_B);break;
CASE_0F_B(0x93) /* SETNB */
SETcc(!get_CF());break;
SETcc(TFLG_NB);break;
CASE_0F_B(0x94) /* SETZ */
SETcc(get_ZF());break;
SETcc(TFLG_Z);break;
CASE_0F_B(0x95) /* SETNZ */
SETcc(!get_ZF()); break;
SETcc(TFLG_NZ); break;
CASE_0F_B(0x96) /* SETBE */
SETcc(get_CF() || get_ZF());break;
SETcc(TFLG_BE);break;
CASE_0F_B(0x97) /* SETNBE */
SETcc(!get_CF() && !get_ZF());break;
SETcc(TFLG_NBE);break;
CASE_0F_B(0x98) /* SETS */
SETcc(get_SF());break;
SETcc(TFLG_S);break;
CASE_0F_B(0x99) /* SETNS */
SETcc(!get_SF());break;
SETcc(TFLG_NS);break;
CASE_0F_B(0x9a) /* SETP */
SETcc(get_PF());break;
SETcc(TFLG_P);break;
CASE_0F_B(0x9b) /* SETNP */
SETcc(!get_PF());break;
SETcc(TFLG_NP);break;
CASE_0F_B(0x9c) /* SETL */
SETcc(get_SF() != get_OF());break;
SETcc(TFLG_L);break;
CASE_0F_B(0x9d) /* SETNL */
SETcc(get_SF() == get_OF());break;
SETcc(TFLG_NL);break;
CASE_0F_B(0x9e) /* SETLE */
SETcc(get_ZF() || (get_SF() != get_OF()));break;
SETcc(TFLG_LE);break;
CASE_0F_B(0x9f) /* SETNLE */
SETcc((get_SF() == get_OF()) && !get_ZF());break;
SETcc(TFLG_NLE);break;
CASE_0F_W(0xa0) /* PUSH FS */
Push_16(SegValue(fs));break;
CASE_0F_W(0xa1) /* POP FS */
CPU_SetSegGeneral(fs,Pop_16());break;
POPSEG(fs,Pop_16(),2);
break;
CASE_0F_B(0xa2) /* CPUID */
CPU_CPUID();break;
CASE_0F_W(0xa3) /* BT Ew,Gw */
{
GetRMrw;
FillFlags();GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
} else {
GetEAa;Bit16u old=LoadMw(eaa);
GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2;
Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_W(0xa4) /* SHLD Ew,Gw,Ib */
@ -253,21 +268,21 @@
CASE_0F_W(0xa8) /* PUSH GS */
Push_16(SegValue(gs));break;
CASE_0F_W(0xa9) /* POP GS */
CPU_SetSegGeneral(gs,Pop_16());break;
POPSEG(gs,Pop_16(),2);break;
CASE_0F_W(0xab) /* BTS Ew,Gw */
{
GetRMrw;
FillFlags();GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw|=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2;
Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_W(0xac) /* SHRD Ew,Gw,Ib */
@ -282,35 +297,38 @@
CASE_0F_W(0xb2) /* LSS Ew */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+2));
LOADSEG(ss,LoadMw(eaa+2));
*rmrw=LoadMw(eaa);
break;
}
CASE_0F_W(0xb3) /* BTR Ew,Gw */
{
GetRMrw;
FillFlags();GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw&= ~mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2;
Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old & ~mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_W(0xb4) /* LFS Ew */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+2));
LOADSEG(fs,LoadMw(eaa+2));
*rmrw=LoadMw(eaa);
break;
}
CASE_0F_W(0xb5) /* LGS Ew */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+2));
LOADSEG(gs,LoadMw(eaa+2));
*rmrw=LoadMw(eaa);
break;
}
CASE_0F_W(0xb6) /* MOVZX Gw,Eb */
@ -330,7 +348,7 @@
}
CASE_0F_W(0xba) /* GRP8 Ew,Ib */
{
GetRM;
FillFlags();GetRM;
if (rm >= 0xc0 ) {
GetEArw;
Bit16u mask=1 << (Fetchb() & 15);
@ -370,23 +388,22 @@
E_Exit("CPU:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_W(0xbb) /* BTC Ew,Gw */
{
GetRMrw;
FillFlags();GetRMrw;
Bit16u mask=1 << (*rmrw & 15);
if (rm >= 0xc0 ) {
GetEArw;
SETFLAGBIT(CF,(*earw & mask));
*earw^=mask;
} else {
GetEAa;Bit16u old=LoadMw(eaa);
GetEAa;eaa+=(((Bit16s)*rmrw)>>4)*2;
Bit16u old=LoadMw(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMw(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_W(0xbc) /* BSF Gw,Ew */
@ -403,7 +420,7 @@
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_W(0xbd) /* BSR Gw,Ew */
@ -420,7 +437,7 @@
SETFLAGBIT(ZF,false);
*rmrw = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_W(0xbe) /* MOVSX Gw,Eb */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -25,7 +25,7 @@
CASE_D(0x06) /* PUSH ES */
Push_32(SegValue(es));break;
CASE_D(0x07) /* POP ES */
CPU_SetSegGeneral(es,(Bit16u)Pop_32());break;
POPSEG(es,Pop_32(),4);break;
CASE_D(0x09) /* OR Ed,Gd */
RMEdGd(ORD);break;
CASE_D(0x0b) /* OR Gd,Ed */
@ -43,7 +43,9 @@
CASE_D(0x16) /* PUSH SS */
Push_32(SegValue(ss));break;
CASE_D(0x17) /* POP SS */
CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break;
POPSEG(ss,Pop_32(),4);
CPU_Cycles++;
break;
CASE_D(0x19) /* SBB Ed,Gd */
RMEdGd(SBBD);break;
CASE_D(0x1b) /* SBB Gd,Ed */
@ -53,7 +55,7 @@
CASE_D(0x1e) /* PUSH DS */
Push_32(SegValue(ds));break;
CASE_D(0x1f) /* POP DS */
CPU_SetSegGeneral(ds,(Bit16u)Pop_32());break;
POPSEG(ds,Pop_32(),4);break;
CASE_D(0x21) /* AND Ed,Gd */
RMEdGd(ANDD);break;
CASE_D(0x23) /* AND Gd,Ed */
@ -143,9 +145,11 @@
CASE_D(0x5f) /* POP EDI */
reg_edi=Pop_32();break;
CASE_D(0x60) /* PUSHAD */
{
Bitu tmpesp = reg_esp;
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
break;
Push_32(tmpesp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
}; break;
CASE_D(0x61) /* POPAD */
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
@ -186,6 +190,38 @@
CASE_D(0x6b) /* IMUL Gd,Ed,Ib */
RMGdEdOp3(DIMULD,Fetchbs());
break;
CASE_D(0x70) /* JO */
JumpCond32_b(TFLG_O);break;
CASE_D(0x71) /* JNO */
JumpCond32_b(TFLG_NO);break;
CASE_D(0x72) /* JB */
JumpCond32_b(TFLG_B);break;
CASE_D(0x73) /* JNB */
JumpCond32_b(TFLG_NB);break;
CASE_D(0x74) /* JZ */
JumpCond32_b(TFLG_Z);break;
CASE_D(0x75) /* JNZ */
JumpCond32_b(TFLG_NZ);break;
CASE_D(0x76) /* JBE */
JumpCond32_b(TFLG_BE);break;
CASE_D(0x77) /* JNBE */
JumpCond32_b(TFLG_NBE);break;
CASE_D(0x78) /* JS */
JumpCond32_b(TFLG_S);break;
CASE_D(0x79) /* JNS */
JumpCond32_b(TFLG_NS);break;
CASE_D(0x7a) /* JP */
JumpCond32_b(TFLG_P);break;
CASE_D(0x7b) /* JNP */
JumpCond32_b(TFLG_NP);break;
CASE_D(0x7c) /* JL */
JumpCond32_b(TFLG_L);break;
CASE_D(0x7d) /* JNL */
JumpCond32_b(TFLG_NL);break;
CASE_D(0x7e) /* JLE */
JumpCond32_b(TFLG_LE);break;
CASE_D(0x7f) /* JNLE */
JumpCond32_b(TFLG_NLE);break;
CASE_D(0x81) /* Grpl Ed,Id */
{
GetRM;Bitu which=(rm>>3)&7;
@ -307,9 +343,10 @@
}
CASE_D(0x8f) /* POP Ed */
{
Bit32u val=Pop_32();
GetRM;
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
else {GetEAa;SaveMd(eaa,Pop_32());}
if (rm >= 0xc0 ) {GetEArd;*eard=val;}
else {GetEAa;SaveMd(eaa,val);}
break;
}
CASE_D(0x91) /* XCHG ECX,EAX */
@ -341,27 +378,28 @@
CASE_D(0x9a) /* CALL FAR Ad */
{
Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
SAVEIP;
if (CPU_CALL(true,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
LEAVECORE;
CPU_CALL(true,newcs,newip);
goto decode_start;
}
CASE_D(0x9c) /* PUSHFD */
FillFlags();
Push_32(flags.word);
Push_32(reg_flags);
break;
CASE_D(0x9d) /* POPFD */
if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) {
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
CPU_Exception(13,0);
goto decode_start;
}
SETFLAGSd(Pop_32())
#if CPU_TRAP_CHECK
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Decode_Trap;
cpudecoder=CPU_Core_Normal_Trap_Run;
goto decode_end;
}
#endif
#ifdef CPU_PIC_CHECK
#if CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
#endif
@ -420,13 +458,15 @@
CASE_D(0xc4) /* LES */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+4));
LOADSEG(es,LoadMw(eaa+4));
*rmrd=LoadMd(eaa);
break;
}
CASE_D(0xc5) /* LDS */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+4));
LOADSEG(ds,LoadMw(eaa+4));
*rmrd=LoadMd(eaa);
break;
}
CASE_D(0xc7) /* MOV Ed,Id */
@ -475,61 +515,43 @@
break;
CASE_D(0xca) /* RETF Iw */
{
if (CPU_RET(true,Fetchw())) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
}
Bitu words=Fetchw();
LEAVECORE;
CPU_RET(true,words,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_D(0xcb) /* RETF */
{
if (CPU_RET(true,0)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
LEAVECORE;
CPU_RET(true,0,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_D(0xcf) /* IRET */
{
if (CPU_IRET(true)) {
LEAVECORE;
CPU_IRET(true);
#if CPU_TRAP_CHECK
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Decode_Trap;
return CBRET_NONE;
}
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Trap_Run;
return CBRET_NONE;
}
#endif
#ifdef CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
#if CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
#endif
//TODO TF check
goto decode_start;
} else return CBRET_NONE;
break;
goto decode_start;
}
CASE_D(0xd1) /* GRP2 Ed,1 */
GRP2D(1);break;
CASE_D(0xd3) /* GRP2 Ed,CL */
GRP2D(reg_cl);break;
CASE_D(0xe5) /* IN EAX,Ib */
{
Bit16u port=Fetchb();
reg_eax=IO_Read(port) |
(IO_Read(port+1) << 8 ) |
(IO_Read(port+2) << 16 ) |
(IO_Read(port+3) << 24 );
break;
}
reg_eax=IO_ReadD(Fetchb());
break;
CASE_D(0xe7) /* OUT Ib,EAX */
{
Bit16u port=Fetchb();
IO_Write(port+0,(Bit8u)(reg_eax >> 0));
IO_Write(port+1,(Bit8u)(reg_eax >> 8));
IO_Write(port+2,(Bit8u)(reg_eax >> 16));
IO_Write(port+3,(Bit8u)(reg_eax >> 24));
break;
}
IO_WriteD(Fetchb(),reg_eax);
break;
CASE_D(0xe8) /* CALL Jd */
{
Bit32s newip=Fetchds();
@ -544,25 +566,15 @@
{
Bit32u newip=Fetchd();
Bit16u newcs=Fetchw();
SAVEIP;
if (CPU_JMP(true,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
LEAVECORE;
CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_D(0xed) /* IN EAX,DX */
reg_eax=IO_Read(reg_dx) |
(IO_Read(reg_dx+1) << 8) |
(IO_Read(reg_dx+2) << 16) |
(IO_Read(reg_dx+3) << 24);
reg_eax=IO_ReadD(reg_dx);
break;
CASE_D(0xef) /* OUT DX,EAX */
IO_Write(reg_dx,(Bit8u)(reg_eax>>0));
IO_Write(reg_dx+1,(Bit8u)(reg_eax>>8));
IO_Write(reg_dx+2,(Bit8u)(reg_eax>>16));
IO_Write(reg_dx+3,(Bit8u)(reg_eax>>24));
IO_WriteD(reg_dx,reg_eax);
break;
CASE_D(0xf7) /* GRP3 Ed(,Id) */
{
@ -583,13 +595,13 @@
}
case 0x03: /* NEG Ed */
{
flags.type=t_NEGd;
lflags.type=t_NEGd;
if (rm >= 0xc0 ) {
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
*eard=flags.result.d;
GetEArd;lf_var1d=*eard;lf_resd=0-lf_var1d;
*eard=lf_resd;
} else {
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
SaveMd(eaa,flags.result.d);
GetEAa;lf_var1d=LoadMd(eaa);lf_resd=0-lf_var1d;
SaveMd(eaa,lf_resd);
}
break;
}
@ -627,12 +639,9 @@
GetEAa;
Bit32u newip=LoadMd(eaa);
Bit16u newcs=LoadMw(eaa+4);
SAVEIP;
if (CPU_CALL(true,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
LEAVECORE;
CPU_CALL(true,newcs,newip);
goto decode_start;
}
break;
case 0x04: /* JMP NEAR Ed */
@ -644,12 +653,9 @@
GetEAa;
Bit32u newip=LoadMd(eaa);
Bit16u newcs=LoadMw(eaa+4);
SAVEIP;
if (CPU_JMP(true,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
LEAVECORE;
CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
break;
case 0x06: /* Push Ed */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -36,7 +36,6 @@
Bitu loadval;
if (rm >= 0xc0 ) {GetEArw;loadval=*earw;}
else {GetEAa;loadval=LoadMw(eaa);}
break;
switch (which) {
case 0x02:CPU_LLDT(loadval);break;
case 0x03:CPU_LTR(loadval);break;
@ -44,6 +43,7 @@
case 0x05:CPU_VERW(loadval);break;
}
}
break;
default:
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
}
@ -120,59 +120,58 @@
} else {
GetEAa;CPU_LSL(LoadMw(eaa),limit);
}
*rmrd=(Bit16u)limit;
*rmrd=(Bit32u)limit;
}
break;
CASE_0F_D(0x80) /* JO */
JumpSId(get_OF());break;
JumpCond32_d(TFLG_O);break;
CASE_0F_D(0x81) /* JNO */
JumpSId(!get_OF());break;
JumpCond32_d(TFLG_NO);break;
CASE_0F_D(0x82) /* JB */
JumpSId(get_CF());break;
JumpCond32_d(TFLG_B);break;
CASE_0F_D(0x83) /* JNB */
JumpSId(!get_CF());break;
JumpCond32_d(TFLG_NB);break;
CASE_0F_D(0x84) /* JZ */
JumpSId(get_ZF());break;
JumpCond32_d(TFLG_Z);break;
CASE_0F_D(0x85) /* JNZ */
JumpSId(!get_ZF());break;
JumpCond32_d(TFLG_NZ);break;
CASE_0F_D(0x86) /* JBE */
JumpSId(get_CF() || get_ZF());break;
JumpCond32_d(TFLG_BE);break;
CASE_0F_D(0x87) /* JNBE */
JumpSId(!get_CF() && !get_ZF());break;
JumpCond32_d(TFLG_NBE);break;
CASE_0F_D(0x88) /* JS */
JumpSId(get_SF());break;
JumpCond32_d(TFLG_S);break;
CASE_0F_D(0x89) /* JNS */
JumpSId(!get_SF());break;
JumpCond32_d(TFLG_NS);break;
CASE_0F_D(0x8a) /* JP */
JumpSId(get_PF());break;
JumpCond32_d(TFLG_P);break;
CASE_0F_D(0x8b) /* JNP */
JumpSId(!get_PF());break;
JumpCond32_d(TFLG_NP);break;
CASE_0F_D(0x8c) /* JL */
JumpSId(get_SF() != get_OF());break;
JumpCond32_d(TFLG_L);break;
CASE_0F_D(0x8d) /* JNL */
JumpSId(get_SF() == get_OF());break;
JumpCond32_d(TFLG_NL);break;
CASE_0F_D(0x8e) /* JLE */
JumpSId(get_ZF() || (get_SF() != get_OF()));break;
JumpCond32_d(TFLG_LE);break;
CASE_0F_D(0x8f) /* JNLE */
JumpSId((get_SF() == get_OF()) && !get_ZF());break;
JumpCond32_d(TFLG_NLE);break;
CASE_0F_D(0xa0) /* PUSH FS */
Push_32(SegValue(fs));break;
CASE_0F_D(0xa1) /* POP FS */
CPU_SetSegGeneral(fs,(Bit16u)Pop_32());break;
POPSEG(fs,Pop_32(),4);break;
CASE_0F_D(0xa3) /* BT Ed,Gd */
{
GetRMrd;
FillFlags();GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
} else {
GetEAa;Bit32u old=LoadMd(eaa);
GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4;
Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_D(0xa4) /* SHLD Ed,Gd,Ib */
@ -184,21 +183,21 @@
CASE_0F_D(0xa8) /* PUSH GS */
Push_32(SegValue(gs));break;
CASE_0F_D(0xa9) /* POP GS */
CPU_SetSegGeneral(gs,(Bit16u)Pop_32());break;
POPSEG(gs,Pop_32(),4);break;
CASE_0F_D(0xab) /* BTS Ed,Gd */
{
GetRMrd;
FillFlags();GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
*eard|=mask;
} else {
GetEAa;Bit32u old=LoadMd(eaa);
GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4;
Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old | mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
@ -208,25 +207,6 @@
CASE_0F_D(0xad) /* SHRD Ed,Gd,CL */
RMEdGdOp3(DSHRD,reg_cl);
break;
CASE_0F_D(0xb4) /* LFS Ed */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(fs,LoadMw(eaa+4));
break;
}
CASE_0F_D(0xb5) /* LGS Ed */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(gs,LoadMw(eaa+4));
break;
}
CASE_0F_D(0xb6) /* MOVZX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
else {GetEAa;*rmrd=LoadMb(eaa);}
break;
}
CASE_0F_D(0xaf) /* IMUL Gd,Ed */
{
RMGdEdOp3(DIMULD,*rmrd);
@ -235,7 +215,45 @@
CASE_0F_D(0xb2) /* LSS Ed */
{
GetRMrd;GetEAa;
*rmrd=LoadMd(eaa);CPU_SetSegGeneral(ss,LoadMw(eaa+4));
LOADSEG(ss,LoadMw(eaa+4));
*rmrd=LoadMd(eaa);
break;
}
CASE_0F_D(0xb3) /* BTR Ed,Gd */
{
FillFlags();GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
*eard&= ~mask;
} else {
GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4;
Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old & ~mask);
}
break;
}
CASE_0F_D(0xb4) /* LFS Ed */
{
GetRMrd;GetEAa;
LOADSEG(fs,LoadMw(eaa+4));
*rmrd=LoadMd(eaa);
break;
}
CASE_0F_D(0xb5) /* LGS Ed */
{
GetRMrd;GetEAa;
LOADSEG(gs,LoadMw(eaa+4));
*rmrd=LoadMd(eaa);
break;
}
CASE_0F_D(0xb6) /* MOVZX Gd,Eb */
{
GetRMrd;
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
else {GetEAa;*rmrd=LoadMb(eaa);}
break;
}
CASE_0F_D(0xb7) /* MOVXZ Gd,Ew */
@ -247,7 +265,7 @@
}
CASE_0F_D(0xba) /* GRP8 Ed,Ib */
{
GetRM;
FillFlags();GetRM;
if (rm >= 0xc0 ) {
GetEArd;
Bit32u mask=1 << (Fetchb() & 31);
@ -290,24 +308,22 @@
E_Exit("CPU:66:0F:BA:Illegal subfunction %X",rm & 0x38);
}
}
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
}
CASE_0F_D(0xbb) /* BTC Ed,Gd */
{
GetRMrd;
FillFlags();GetRMrd;
Bit32u mask=1 << (*rmrd & 31);
if (rm >= 0xc0 ) {
GetEArd;
SETFLAGBIT(CF,(*eard & mask));
*eard^=mask;
} else {
GetEAa;Bit32u old=LoadMd(eaa);
GetEAa;eaa+=(((Bit32s)*rmrd)>>5)*4;
Bit32u old=LoadMd(eaa);
SETFLAGBIT(CF,(old & mask));
SaveMd(eaa,old ^ mask);
}
if (flags.type!=t_CF) { flags.prev_type=flags.type;flags.type=t_CF; }
break;
}
CASE_0F_D(0xbc) /* BSF Gd,Ed */
@ -324,7 +340,7 @@
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_D(0xbd) /* BSR Gd,Ed */
@ -341,7 +357,7 @@
SETFLAGBIT(ZF,false);
*rmrd = result;
}
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
break;
}
CASE_0F_D(0xbe) /* MOVSX Gd,Eb */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -31,7 +31,7 @@
CASE_W(0x06) /* PUSH ES */
Push_16(SegValue(es));break;
CASE_W(0x07) /* POP ES */
CPU_SetSegGeneral(es,Pop_16());break;
POPSEG(es,Pop_16(),2);break;
CASE_B(0x08) /* OR Eb,Gb */
RMEbGb(ORB);break;
CASE_W(0x09) /* OR Ew,Gw */
@ -65,7 +65,9 @@
CASE_W(0x16) /* PUSH SS */
Push_16(SegValue(ss));break;
CASE_W(0x17) /* POP SS */
CPU_SetSegGeneral(ss,Pop_16());break;
POPSEG(ss,Pop_16(),2);
CPU_Cycles++; //Always do another instruction
break;
CASE_B(0x18) /* SBB Eb,Gb */
RMEbGb(SBBB);break;
CASE_W(0x19) /* SBB Ew,Gw */
@ -81,7 +83,8 @@
CASE_W(0x1e) /* PUSH DS */
Push_16(SegValue(ds));break;
CASE_W(0x1f) /* POP DS */
CPU_SetSegGeneral(ds,Pop_16());break;
POPSEG(ds,Pop_16(),2);
break;
CASE_B(0x20) /* AND Eb,Gb */
RMEbGb(ANDB);break;
CASE_W(0x21) /* AND Ew,Gw */
@ -187,7 +190,6 @@
CASE_W(0x53) /* PUSH BX */
Push_16(reg_bx);break;
CASE_W(0x54) /* PUSH SP */
//TODO Check if this is correct i think it's SP+2 or something
Push_16(reg_sp);break;
CASE_W(0x55) /* PUSH BP */
Push_16(reg_bp);break;
@ -253,7 +255,7 @@
CASE_B(0x65) /* SEG GS: */
DO_PREFIX_SEG(gs);break;
CASE_B(0x66) /* Operand Size Prefix */
core.opcode_index^=OPCODE_SIZE;
core.opcode_index=core.index_default^OPCODE_SIZE;
goto restart_opcode;
CASE_B(0x67) /* Address Size Prefix */
DO_PREFIX_ADDR();
@ -276,38 +278,38 @@
DoString(R_OUTSB);break;
CASE_W(0x6f) /* OUTSW */
DoString(R_OUTSW);break;
CASE_B(0x70) /* JO */
JumpSIb(get_OF());break;
CASE_B(0x71) /* JNO */
JumpSIb(!get_OF());break;
CASE_B(0x72) /* JB */
JumpSIb(get_CF());break;
CASE_B(0x73) /* JNB */
JumpSIb(!get_CF());break;
CASE_B(0x74) /* JZ */
JumpSIb(get_ZF());break;
CASE_B(0x75) /* JNZ */
JumpSIb(!get_ZF());break;
CASE_B(0x76) /* JBE */
JumpSIb(get_CF() || get_ZF());break;
CASE_B(0x77) /* JNBE */
JumpSIb(!get_CF() && !get_ZF());break;
CASE_B(0x78) /* JS */
JumpSIb(get_SF());break;
CASE_B(0x79) /* JNS */
JumpSIb(!get_SF());break;
CASE_B(0x7a) /* JP */
JumpSIb(get_PF());break;
CASE_B(0x7b) /* JNP */
JumpSIb(!get_PF());break;
CASE_B(0x7c) /* JL */
JumpSIb(get_SF() != get_OF());break;
CASE_B(0x7d) /* JNL */
JumpSIb(get_SF() == get_OF());break;
CASE_B(0x7e) /* JLE */
JumpSIb(get_ZF() || (get_SF() != get_OF()));break;
CASE_B(0x7f) /* JNLE */
JumpSIb((get_SF() == get_OF()) && !get_ZF());break;
CASE_W(0x70) /* JO */
JumpCond16_b(TFLG_O);break;
CASE_W(0x71) /* JNO */
JumpCond16_b(TFLG_NO);break;
CASE_W(0x72) /* JB */
JumpCond16_b(TFLG_B);break;
CASE_W(0x73) /* JNB */
JumpCond16_b(TFLG_NB);break;
CASE_W(0x74) /* JZ */
JumpCond16_b(TFLG_Z);break;
CASE_W(0x75) /* JNZ */
JumpCond16_b(TFLG_NZ);break;
CASE_W(0x76) /* JBE */
JumpCond16_b(TFLG_BE);break;
CASE_W(0x77) /* JNBE */
JumpCond16_b(TFLG_NBE);break;
CASE_W(0x78) /* JS */
JumpCond16_b(TFLG_S);break;
CASE_W(0x79) /* JNS */
JumpCond16_b(TFLG_NS);break;
CASE_W(0x7a) /* JP */
JumpCond16_b(TFLG_P);break;
CASE_W(0x7b) /* JNP */
JumpCond16_b(TFLG_NP);break;
CASE_W(0x7c) /* JL */
JumpCond16_b(TFLG_L);break;
CASE_W(0x7d) /* JNL */
JumpCond16_b(TFLG_NL);break;
CASE_W(0x7e) /* JLE */
JumpCond16_b(TFLG_LE);break;
CASE_W(0x7f) /* JNLE */
JumpCond16_b(TFLG_NLE);break;
CASE_B(0x80) /* Grpl Eb,Ib */
CASE_B(0x82) /* Grpl Eb,Ib Mirror instruction*/
{
@ -489,20 +491,17 @@
if (rm >= 0xc0 ) {GetEArw;val=*earw;}
else {GetEAa;val=LoadMw(eaa);}
switch (which) {
case 0x02: /* MOV SS,Ew */
CPU_Cycles++; //Always do another instruction
case 0x00: /* MOV ES,Ew */
CPU_SetSegGeneral(es,val);break;
case 0x03: /* MOV DS,Ew */
case 0x05: /* MOV GS,Ew */
case 0x04: /* MOV FS,Ew */
LOADSEG((SegNames)which,val);
break;
case 0x01: /* MOV CS,Ew Illegal*/
E_Exit("CPU:Illegal MOV CS Call");
break;
case 0x02: /* MOV SS,Ew */
CPU_SetSegGeneral(ss,val);
break;
case 0x03: /* MOV DS,Ew */
CPU_SetSegGeneral(ds,val);break;
case 0x04: /* MOV FS,Ew */
CPU_SetSegGeneral(fs,val);break;
case 0x05: /* MOV GS,Ew */
CPU_SetSegGeneral(gs,val);break;
default:
E_Exit("CPU:8E:Illegal RM Byte");
}
@ -510,9 +509,10 @@
}
CASE_W(0x8f) /* POP Ew */
{
Bit16u val=Pop_16();
GetRM;
if (rm >= 0xc0 ) {GetEArw;*earw=Pop_16();}
else {GetEAa;SaveMw(eaa,Pop_16());}
if (rm >= 0xc0 ) {GetEArw;*earw=val;}
else {GetEAa;SaveMw(eaa,val);}
break;
}
CASE_B(0x90) /* NOP */
@ -546,29 +546,30 @@
CASE_W(0x9a) /* CALL Ap */
{
Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
SAVEIP;
if (CPU_CALL(false,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
LEAVECORE;
CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_B(0x9b) /* WAIT */
break; /* No waiting here */
CASE_W(0x9c) /* PUSHF */
FillFlags();
Push_16(flags.word);
Push_16(reg_flags);
break;
CASE_W(0x9d) /* POPF */
if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) {
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
CPU_Exception(13,0);
goto decode_start;
}
SETFLAGSw(Pop_16());
#if CPU_TRAP_CHECK
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Decode_Trap;
cpudecoder=CPU_Core_Normal_Trap_Run;
goto decode_end;
}
#endif
#ifdef CPU_PIC_CHECK
#if CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
#endif
break;
@ -577,7 +578,7 @@
break;
CASE_B(0x9f) /* LAHF */
FillFlags();
reg_ah=flags.word&0xff;
reg_ah=reg_flags&0xff;
break;
CASE_B(0xa0) /* MOV AL,Ob */
{
@ -675,13 +676,15 @@
CASE_W(0xc4) /* LES */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(es,LoadMw(eaa+2));
LOADSEG(es,LoadMw(eaa+2));
*rmrw=LoadMw(eaa);
break;
}
CASE_W(0xc5) /* LDS */
{
GetRMrw;GetEAa;
*rmrw=LoadMw(eaa);CPU_SetSegGeneral(ds,LoadMw(eaa+2));
LOADSEG(ds,LoadMw(eaa+2));
*rmrw=LoadMw(eaa);
break;
}
CASE_B(0xc6) /* MOV Eb,Ib */
@ -737,22 +740,15 @@
break;
CASE_W(0xca) /* RETF Iw */
{
if (CPU_RET(false,Fetchw())) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
Bitu words=Fetchw();
LEAVECORE;
CPU_RET(false,words,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_W(0xcb) /* RETF */
{
if (CPU_RET(false,0)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
}
LEAVECORE;
CPU_RET(false,0,core.ip_lookup-core.op_start);
goto decode_start;
CASE_B(0xcc) /* INT3 */
LEAVECORE;
#if C_DEBUG
@ -760,7 +756,10 @@
return debugCallback;
}
#endif
if (!Interrupt(3)) return CBRET_NONE;
CPU_SW_Interrupt(3,(core.ip_lookup-core.op_start));
#if CPU_TRAP_CHECK
core.trap.skip=true;
#endif
goto decode_start;
CASE_B(0xcd) /* INT Ib */
{
@ -771,35 +770,39 @@
return debugCallback;
}
#endif
if (!Interrupt(num)) return CBRET_NONE;
goto decode_start; //Restore IP with a LOADIP
CPU_SW_Interrupt(num,core.ip_lookup-core.op_start);
#if CPU_TRAP_CHECK
core.trap.skip=true;
#endif
goto decode_start;
}
break;
CASE_B(0xce) /* INTO */
if (get_OF()) {
LEAVECORE;
if (!Interrupt(4)) return CBRET_NONE;
goto decode_start; //Restore IP with a LOADIP
CPU_SW_Interrupt(4,core.ip_lookup-core.op_start);
#if CPU_TRAP_CHECK
core.trap.skip=true;
#endif
goto decode_start;
}
break;
CASE_W(0xcf) /* IRET */
{
if (CPU_IRET(false)) {
#ifdef CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
LEAVECORE;
CPU_IRET(false);
#if CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
#endif
#if CPU_TRAP_CHECK
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Decode_Trap;
return CBRET_NONE;
}
if (GETFLAG(TF)) {
cpudecoder=CPU_Core_Normal_Trap_Run;
return CBRET_NONE;
}
#endif
goto decode_start;
} else {
return CBRET_NONE;
}
break;
}
CASE_B(0xd0) /* GRP2 Eb,1 */
GRP2B(1);break;
CASE_W(0xd1) /* GRP2 Ew,1 */
@ -901,31 +904,17 @@
break;
}
CASE_B(0xe4) /* IN AL,Ib */
{
Bit16u port=Fetchb();
reg_al=IO_Read(port);
break;
}
reg_al=IO_ReadB(Fetchb());
break;
CASE_W(0xe5) /* IN AX,Ib */
{
Bit16u port=Fetchb();
reg_al=IO_Read(port);
reg_ah=IO_Read(port+1);
break;
}
reg_ax=IO_ReadW(Fetchb());
break;
CASE_B(0xe6) /* OUT Ib,AL */
{
Bit16u port=Fetchb();
IO_Write(port,reg_al);
break;
}
IO_WriteB(Fetchb(),reg_al);
break;
CASE_W(0xe7) /* OUT Ib,AX */
{
Bit16u port=Fetchb();
IO_Write(port,reg_al);
IO_Write(port+1,reg_ah);
break;
}
IO_WriteW(Fetchb(),reg_ax);
break;
CASE_W(0xe8) /* CALL Jw */
{
Bit16s newip=Fetchws();
@ -940,13 +929,9 @@
{
Bit16u newip=Fetchw();
Bit16u newcs=Fetchw();
SAVEIP;
if (CPU_JMP(false,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
break;
LEAVECORE;
CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
CASE_B(0xeb) /* JMP Jb */
ADDIPFAST(Fetchbs());break;
@ -956,9 +941,9 @@
reg_al=IO_Read(reg_dx);reg_ah=IO_Read(reg_dx+1);
break;
CASE_B(0xee) /* OUT DX,AL */
IO_Write(reg_dx,reg_al);break;
IO_WriteB(reg_dx,reg_al);break;
CASE_W(0xef) /* OUT DX,AX */
IO_Write(reg_dx,reg_al);IO_Write(reg_dx+1,reg_ah);break;
IO_WriteW(reg_dx,reg_ax);break;
CASE_B(0xf0) /* LOCK */
LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK");
break;
@ -970,12 +955,11 @@
break;
CASE_B(0xf4) /* HLT */
LEAVECORE;
CPU_HLT();
return CBRET_NONE;
CPU_HLT(core.ip_lookup-core.op_start);
return CBRET_NONE; //Needs to return for hlt cpu core
CASE_B(0xf5) /* CMC */
SETFLAGBIT(CF,!get_CF());
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
FillFlags();
SETFLAGBIT(CF,!(reg_flags & FLAG_CF));
break;
CASE_B(0xf6) /* GRP3 Eb(,Ib) */
{
@ -996,13 +980,13 @@
}
case 0x03: /* NEG Eb */
{
flags.type=t_NEGb;
lflags.type=t_NEGb;
if (rm >= 0xc0 ) {
GetEArb;flags.var1.b=*earb;flags.result.b=0-flags.var1.b;
*earb=flags.result.b;
GetEArb;lf_var1b=*earb;lf_resb=0-lf_var1b;
*earb=lf_resb;
} else {
GetEAa;flags.var1.b=LoadMb(eaa);flags.result.b=0-flags.var1.b;
SaveMb(eaa,flags.result.b);
GetEAa;lf_var1b=LoadMb(eaa);lf_resb=0-lf_var1b;
SaveMb(eaa,lf_resb);
}
break;
}
@ -1040,13 +1024,13 @@
}
case 0x03: /* NEG Ew */
{
flags.type=t_NEGw;
lflags.type=t_NEGw;
if (rm >= 0xc0 ) {
GetEArw;flags.var1.w=*earw;flags.result.w=0-flags.var1.w;
*earw=flags.result.w;
GetEArw;lf_var1w=*earw;lf_resw=0-lf_var1w;
*earw=lf_resw;
} else {
GetEAa;flags.var1.w=LoadMw(eaa);flags.result.w=0-flags.var1.w;
SaveMw(eaa,flags.result.w);
GetEAa;lf_var1w=LoadMw(eaa);lf_resw=0-lf_var1w;
SaveMw(eaa,lf_resw);
}
break;
}
@ -1066,29 +1050,39 @@
break;
}
CASE_B(0xf8) /* CLC */
FillFlags();
SETFLAGBIT(CF,false);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
CASE_B(0xf9) /* STC */
FillFlags();
SETFLAGBIT(CF,true);
if (flags.type!=t_CF) flags.prev_type=flags.type;
flags.type=t_CF;
break;
CASE_B(0xfa) /* CLI */
if (cpu.pmode && (GETFLAG_IOPL<cpu.cpl)) {
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
CPU_Exception(13,0);
goto decode_start;
}
SETFLAGBIT(IF,false);
break;
CASE_B(0xfb) /* STI */
if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPL<cpu.cpl)) {
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
CPU_Exception(13,0);
goto decode_start;
}
SETFLAGBIT(IF,true);
#ifdef CPU_PIC_CHECK
#if CPU_PIC_CHECK
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
#endif
break;
CASE_B(0xfc) /* CLD */
SETFLAGBIT(DF,false);
cpu.direction=1;
break;
CASE_B(0xfd) /* STD */
SETFLAGBIT(DF,true);
cpu.direction=-1;
break;
CASE_B(0xfe) /* GRP4 Eb */
{
@ -1131,12 +1125,9 @@
GetEAa;
Bit16u newip=LoadMw(eaa);
Bit16u newcs=LoadMw(eaa+2);
SAVEIP;
if (CPU_CALL(false,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
}
LEAVECORE;
CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
break;
case 0x04: /* JMP Ev */
@ -1148,12 +1139,10 @@
GetEAa;
Bit16u newip=LoadMw(eaa);
Bit16u newcs=LoadMw(eaa+2);
SAVEIP;
if (CPU_JMP(false,newcs,newip)) {
LOADIP;
} else {
FillFlags();return CBRET_NONE;
} }
LEAVECORE;
CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start);
goto decode_start;
}
break;
case 0x06: /* PUSH Ev */
if (rm >= 0xc0 ) {GetEArw;Push_16(*earw);}

View File

@ -46,43 +46,38 @@ static void DoString(STRING_OP type) {
count_left=0;
}
}
add_index=GETFLAG(DF) ? -1 : 1;
add_index=cpu.direction;
if (count) switch (type) {
case R_OUTSB:
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_WriteB(reg_dx,LoadMb(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_OUTSW:
add_index<<=1;
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
IO_WriteW(reg_dx,LoadMw(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_OUTSD:
add_index<<=2;
for (;count>0;count--) {
IO_Write(reg_dx,LoadMb(si_base+si_index));
IO_Write(reg_dx+1,LoadMb(si_base+si_index+1));
IO_Write(reg_dx+2,LoadMb(si_base+si_index+2));
IO_Write(reg_dx+3,LoadMb(si_base+si_index+3));
IO_WriteD(reg_dx,LoadMd(si_base+si_index));
si_index=(si_index+add_index) & add_mask;
}
break;
case R_INSB:
for (;count>0;count--) {
SaveMb(di_base+di_index,IO_Read(reg_dx));
SaveMb(di_base+di_index,IO_ReadB(reg_dx));
di_index=(di_index+add_index) & add_mask;
}
break;
case R_INSW:
add_index<<=1;
for (;count>0;count--) {
SaveMb(di_base+di_index,IO_Read(reg_dx));
SaveMb(di_base+di_index+1,IO_Read(reg_dx+1));
SaveMw(di_base+di_index,IO_ReadW(reg_dx));
di_index=(di_index+add_index) & add_mask;
}
break;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -37,9 +37,11 @@ static INLINE void ADDIPd(Bits add) {
LOADIP;
}
static INLINE void ADDIPFAST(Bits blah) {
core.ip_lookup+=blah;
// core.ip_lookup+=blah;
SAVEIP;
reg_eip=(reg_eip+blah);
LOADIP;
}
#define EXCEPTION(blah) \
@ -47,9 +49,8 @@ static INLINE void ADDIPFAST(Bits blah) {
Bit8u new_num=blah; \
core.ip_lookup=core.op_start; \
LEAVECORE; \
if (Interrupt(new_num)) { \
goto decode_start; \
} else return CBRET_NONE; \
CPU_Exception(new_num); \
goto decode_start; \
}
static INLINE Bit8u Fetchb() {
@ -80,6 +81,8 @@ static INLINE Bit32s Fetchds() {
return Fetchd();
}
#if 0
static INLINE void Push_16(Bit16u blah) {
reg_esp-=2;
SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
@ -102,14 +105,31 @@ static INLINE Bit32u Pop_32() {
return temp;
};
#define JumpSIb(blah) \
#else
#define Push_16 CPU_Push16
#define Push_32 CPU_Push32
#define Pop_16 CPU_Pop16
#define Pop_32 CPU_Pop32
#endif
//TODO Could probably make all byte operands fast?
#define JumpCond16_b(blah) \
if (blah) { \
ADDIPFAST(Fetchbs()); \
ADDIPw(Fetchbs()); \
} else { \
ADDIPFAST(1); \
}
#define JumpSIw(blah) \
#define JumpCond32_b(blah) \
if (blah) { \
ADDIPd(Fetchbs()); \
} else { \
ADDIPFAST(1); \
}
#define JumpCond16_w(blah) \
if (blah) { \
ADDIPw(Fetchws()); \
} else { \
@ -117,7 +137,7 @@ static INLINE Bit32u Pop_32() {
}
#define JumpSId(blah) \
#define JumpCond32_d(blah) \
if (blah) { \
ADDIPd(Fetchds()); \
} else { \

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -20,442 +20,439 @@
/* All Byte genereal instructions */
#define ADDB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b+flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ADDb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b+lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_ADDb;
#define ADCB(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b+flags.var2.b+flags.oldcf; \
save(op1,flags.result.b); \
flags.type=t_ADCb;
lflags.oldcf=get_CF()!=0; \
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b+lf_var2b+lflags.oldcf; \
save(op1,lf_resb); \
lflags.type=t_ADCb;
#define SBBB(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-(flags.var2.b+flags.oldcf); \
save(op1,flags.result.b); \
flags.type=t_SBBb;
lflags.oldcf=get_CF()!=0; \
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-(lf_var2b+lflags.oldcf); \
save(op1,lf_resb); \
lflags.type=t_SBBb;
#define SUBB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SUBb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_SUBb;
#define ORB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b | flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ORb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b | lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_ORb;
#define XORB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b ^ flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_XORb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b ^ lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_XORb;
#define ANDB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b & flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_ANDb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b & lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_ANDb;
#define CMPB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b-flags.var2.b; \
flags.type=t_CMPb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b-lf_var2b; \
lflags.type=t_CMPb;
#define TESTB(op1,op2,load,save) \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b & flags.var2.b; \
flags.type=t_TESTb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b & lf_var2b; \
lflags.type=t_TESTb;
/* All Word General instructions */
#define ADDW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w+flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ADDw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w+lf_var2w; \
save(op1,lf_resw); \
lflags.type=t_ADDw;
#define ADCW(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w+flags.var2.w+flags.oldcf; \
save(op1,flags.result.w); \
flags.type=t_ADCw;
lflags.oldcf=get_CF()!=0; \
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w+lf_var2w+lflags.oldcf; \
save(op1,lf_resw); \
lflags.type=t_ADCw;
#define SBBW(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-(flags.var2.w+flags.oldcf); \
save(op1,flags.result.w); \
flags.type=t_SBBw;
lflags.oldcf=get_CF()!=0; \
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-(lf_var2w+lflags.oldcf); \
save(op1,lf_resw); \
lflags.type=t_SBBw;
#define SUBW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_SUBw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-lf_var2w; \
save(op1,lf_resw); \
lflags.type=t_SUBw;
#define ORW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w | flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ORw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w | lf_var2w; \
save(op1,lf_resw); \
lflags.type=t_ORw;
#define XORW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w ^ flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_XORw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w ^ lf_var2w; \
save(op1,lf_resw); \
lflags.type=t_XORw;
#define ANDW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w & flags.var2.w; \
save(op1,flags.result.w); \
flags.type=t_ANDw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w & lf_var2w; \
save(op1,lf_resw); \
lflags.type=t_ANDw;
#define CMPW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w-flags.var2.w; \
flags.type=t_CMPw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w-lf_var2w; \
lflags.type=t_CMPw;
#define TESTW(op1,op2,load,save) \
flags.var1.w=load(op1);flags.var2.w=op2; \
flags.result.w=flags.var1.w & flags.var2.w; \
flags.type=t_TESTw;
lf_var1w=load(op1);lf_var2w=op2; \
lf_resw=lf_var1w & lf_var2w; \
lflags.type=t_TESTw;
/* All DWORD General Instructions */
#define ADDD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d+flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ADDd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d+lf_var2d; \
save(op1,lf_resd); \
lflags.type=t_ADDd;
#define ADCD(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d+flags.var2.d+flags.oldcf; \
save(op1,flags.result.d); \
flags.type=t_ADCd;
lflags.oldcf=get_CF()!=0; \
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d+lf_var2d+lflags.oldcf; \
save(op1,lf_resd); \
lflags.type=t_ADCd;
#define SBBD(op1,op2,load,save) \
flags.oldcf=get_CF(); \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-(flags.var2.d+flags.oldcf); \
save(op1,flags.result.d); \
flags.type=t_SBBd;
lflags.oldcf=get_CF()!=0; \
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-(lf_var2d+lflags.oldcf); \
save(op1,lf_resd); \
lflags.type=t_SBBd;
#define SUBD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_SUBd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-lf_var2d; \
save(op1,lf_resd); \
lflags.type=t_SUBd;
#define ORD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d | flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ORd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d | lf_var2d; \
save(op1,lf_resd); \
lflags.type=t_ORd;
#define XORD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d ^ flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_XORd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d ^ lf_var2d; \
save(op1,lf_resd); \
lflags.type=t_XORd;
#define ANDD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d & flags.var2.d; \
save(op1,flags.result.d); \
flags.type=t_ANDd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d & lf_var2d; \
save(op1,lf_resd); \
lflags.type=t_ANDd;
#define CMPD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d-flags.var2.d; \
flags.type=t_CMPd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d-lf_var2d; \
lflags.type=t_CMPd;
#define TESTD(op1,op2,load,save) \
flags.var1.d=load(op1);flags.var2.d=op2; \
flags.result.d=flags.var1.d & flags.var2.d; \
flags.type=t_TESTd;
lf_var1d=load(op1);lf_var2d=op2; \
lf_resd=lf_var1d & lf_var2d; \
lflags.type=t_TESTd;
#define INCB(op1,load,save) \
LoadCF;flags.result.b=load(op1)+1; \
save(op1,flags.result.b); \
flags.type=t_INCb; \
LoadCF;lf_var1b=load(op1); \
lf_resb=lf_var1b+1; \
save(op1,lf_resb); \
lflags.type=t_INCb; \
#define INCW(op1,load,save) \
LoadCF;flags.result.w=load(op1)+1; \
save(op1,flags.result.w); \
flags.type=t_INCw;
LoadCF;lf_var1w=load(op1); \
lf_resw=lf_var1w+1; \
save(op1,lf_resw); \
lflags.type=t_INCw;
#define INCD(op1,load,save) \
LoadCF;flags.result.d=load(op1)+1; \
save(op1,flags.result.d); \
flags.type=t_INCd;
LoadCF;lf_var1d=load(op1); \
lf_resd=lf_var1d+1; \
save(op1,lf_resd); \
lflags.type=t_INCd;
#define DECB(op1,load,save) \
LoadCF;flags.result.b=load(op1)-1; \
save(op1,flags.result.b); \
flags.type=t_DECb;
LoadCF;lf_var1b=load(op1); \
lf_resb=lf_var1b-1; \
save(op1,lf_resb); \
lflags.type=t_DECb;
#define DECW(op1,load,save) \
LoadCF;flags.result.w=load(op1)-1; \
save(op1,flags.result.w); \
flags.type=t_DECw;
LoadCF;lf_var1w=load(op1); \
lf_resw=lf_var1w-1; \
save(op1,lf_resw); \
lflags.type=t_DECw;
#define DECD(op1,load,save) \
LoadCF;flags.result.d=load(op1)-1; \
save(op1,flags.result.d); \
flags.type=t_DECd;
LoadCF;lf_var1d=load(op1); \
lf_resd=lf_var1d-1; \
save(op1,lf_resd); \
lflags.type=t_DECd;
#define ROLB(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
flags.var1.b=load(op1); \
flags.var2.b=op2&0x07; \
flags.result.b=(flags.var1.b << flags.var2.b) | \
(flags.var1.b >> (8-flags.var2.b)); \
save(op1,flags.result.b); \
flags.type=t_ROLb; \
lf_var1b=load(op1); \
lf_var2b=op2&0x07; \
lf_resb=(lf_var1b << lf_var2b) | \
(lf_var1b >> (8-lf_var2b)); \
save(op1,lf_resb); \
lflags.type=t_ROLb; \
#define ROLW(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
flags.var1.w=load(op1); \
flags.var2.b=op2&0x0F; \
flags.result.w=(flags.var1.w << flags.var2.b) | \
(flags.var1.w >> (16-flags.var2.b)); \
save(op1,flags.result.w); \
flags.type=t_ROLw; \
lf_var1w=load(op1); \
lf_var2b=op2&0x0F; \
lf_resw=(lf_var1w << lf_var2b) | \
(lf_var1w >> (16-lf_var2b)); \
save(op1,lf_resw); \
lflags.type=t_ROLw; \
#define ROLD(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.result.d=(flags.var1.d << flags.var2.b) | \
(flags.var1.d >> (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_ROLd; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lf_resd=(lf_var1d << lf_var2b) | \
(lf_var1d >> (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_ROLd; \
#define RORB(op1,op2,load,save) \
LoadZF;LoadSF;LoadAF; \
flags.var1.b=load(op1); \
flags.var2.b=op2&0x07; \
flags.result.b=(flags.var1.b >> flags.var2.b) | \
(flags.var1.b << (8-flags.var2.b)); \
save(op1,flags.result.b); \
flags.type=t_RORb; \
lf_var1b=load(op1); \
lf_var2b=op2&0x07; \
lf_resb=(lf_var1b >> lf_var2b) | \
(lf_var1b << (8-lf_var2b)); \
save(op1,lf_resb); \
lflags.type=t_RORb; \
#define RORW(op1,op2,load,save) \
if (op2&0x0F) { \
LoadZF;LoadSF;LoadAF; \
flags.var1.w=load(op1); \
flags.var2.b=op2&0x0F; \
flags.result.w=(flags.var1.w >> flags.var2.b) | \
(flags.var1.w << (16-flags.var2.b)); \
save(op1,flags.result.w); \
flags.type=t_RORw; \
lf_var1w=load(op1); \
lf_var2b=op2&0x0F; \
lf_resw=(lf_var1w >> lf_var2b) | \
(lf_var1w << (16-lf_var2b)); \
save(op1,lf_resw); \
lflags.type=t_RORw; \
}
#define RORD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.result.d=(flags.var1.d >> flags.var2.b) | \
(flags.var1.d << (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_RORd; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lf_resd=(lf_var1d >> lf_var2b) | \
(lf_var1d << (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_RORd; \
}
#define RCLB(op1,op2,load,save) \
if (op2%9) { \
LoadZF;LoadSF;LoadAF; \
Bit8u cf=get_CF(); \
flags.var1.b=load(op1); \
flags.var2.b=op2%9; \
flags.type=t_RCLb; \
flags.result.b=(flags.var1.b << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.b >> (9-flags.var2.b)); \
SETFLAGBIT(CF,((flags.var1.b >> (8-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.b ^ flags.result.b) & 0x80); \
save(op1,flags.result.b); \
Bit8u cf=(Bit8u)FillFlags()&0x1; \
lf_var1b=load(op1); \
lf_var2b=op2%9; \
lflags.type=t_RCLb; \
lf_resb=(lf_var1b << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1b >> (9-lf_var2b)); \
SETFLAGBIT(CF,((lf_var1b >> (8-lf_var2b)) & 1)); \
save(op1,lf_resb); \
}
#define RCLW(op1,op2,load,save) \
if (op2%17) { \
LoadZF;LoadSF;LoadAF; \
Bit16u cf=get_CF(); \
flags.var1.w=load(op1); \
flags.var2.b=op2%17; \
flags.type=t_RCLw; \
flags.result.w=(flags.var1.w << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.w >> (17-flags.var2.b)); \
SETFLAGBIT(CF,((flags.var1.w >> (16-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.w ^ flags.result.w) & 0x8000); \
save(op1,flags.result.w); \
Bit16u cf=(Bit16u)FillFlags()&0x1; \
lf_var1w=load(op1); \
lf_var2b=op2%17; \
lflags.type=t_RCLw; \
lf_resw=(lf_var1w << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1w >> (17-lf_var2b)); \
SETFLAGBIT(CF,((lf_var1w >> (16-lf_var2b)) & 1)); \
save(op1,lf_resw); \
}
#define RCLD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
Bit32u cf=get_CF(); \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.type=t_RCLd; \
if (flags.var2.b==1) { \
flags.result.d=(flags.var1.d << 1) | cf; \
Bit32u cf=(Bit32u)FillFlags()&0x1; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lflags.type=t_RCLd; \
if (lf_var2b==1) { \
lf_resd=(lf_var1d << 1) | cf; \
} else { \
flags.result.d=(flags.var1.d << flags.var2.b) | \
(cf << (flags.var2.b-1)) | \
(flags.var1.d >> (33-flags.var2.b)); \
lf_resd=(lf_var1d << lf_var2b) | \
(cf << (lf_var2b-1)) | \
(lf_var1d >> (33-lf_var2b)); \
} \
SETFLAGBIT(CF,((flags.var1.d >> (32-flags.var2.b)) & 1)); \
SETFLAGBIT(OF,(flags.var1.d ^ flags.result.d) & 0x80000000); \
save(op1,flags.result.d); \
SETFLAGBIT(CF,((lf_var1d >> (32-lf_var2b)) & 1)); \
save(op1,lf_resd); \
}
#define RCRB(op1,op2,load,save) \
if (op2%9) { \
LoadZF;LoadSF;LoadAF; \
Bit8u cf=get_CF(); \
flags.var1.b=load(op1); \
flags.var2.b=op2%9; \
flags.type=t_RCRb; \
flags.result.b=(flags.var1.b >> flags.var2.b) | \
(cf << (8-flags.var2.b)) | \
(flags.var1.b << (9-flags.var2.b)); \
save(op1,flags.result.b); \
Bit8u cf=(Bit8u)FillFlags()&0x1; \
lf_var1b=load(op1); \
lf_var2b=op2%9; \
lflags.type=t_RCRb; \
lf_resb=(lf_var1b >> lf_var2b) | \
(cf << (8-lf_var2b)) | \
(lf_var1b << (9-lf_var2b)); \
save(op1,lf_resb); \
}
#define RCRW(op1,op2,load,save) \
if (op2%17) { \
LoadZF;LoadSF;LoadAF; \
Bit16u cf=get_CF(); \
flags.var1.w=load(op1); \
flags.var2.b=op2%17; \
flags.type=t_RCRw; \
flags.result.w=(flags.var1.w >> flags.var2.b) | \
(cf << (16-flags.var2.b)) | \
(flags.var1.w << (17-flags.var2.b)); \
save(op1,flags.result.w); \
Bit16u cf=(Bit16u)FillFlags()&0x1; \
lf_var1w=load(op1); \
lf_var2b=op2%17; \
lflags.type=t_RCRw; \
lf_resw=(lf_var1w >> lf_var2b) | \
(cf << (16-lf_var2b)) | \
(lf_var1w << (17-lf_var2b)); \
save(op1,lf_resw); \
}
#define RCRD(op1,op2,load,save) \
if (op2) { \
LoadZF;LoadSF;LoadAF; \
Bit32u cf=get_CF(); \
flags.var1.d=load(op1); \
flags.var2.b=op2; \
flags.type=t_RCRd; \
if (flags.var2.b==1) { \
flags.result.d=flags.var1.d >> 1 | cf << 31; \
Bit32u cf=(Bit32u)FillFlags()&0x1; \
lf_var1d=load(op1); \
lf_var2b=op2; \
lflags.type=t_RCRd; \
if (lf_var2b==1) { \
lf_resd=lf_var1d >> 1 | cf << 31; \
} else { \
flags.result.d=(flags.var1.d >> flags.var2.b) | \
(cf << (32-flags.var2.b)) | \
(flags.var1.d << (33-flags.var2.b)); \
lf_resd=(lf_var1d >> lf_var2b) | \
(cf << (32-lf_var2b)) | \
(lf_var1d << (33-lf_var2b)); \
} \
save(op1,flags.result.d); \
save(op1,lf_resd); \
}
#define SHLB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b << flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SHLb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b << lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_SHLb;
#define SHLW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2 ; \
flags.result.w=flags.var1.w << flags.var2.b; \
save(op1,flags.result.w); \
flags.type=t_SHLw;
lf_var1w=load(op1);lf_var2b=op2 ; \
lf_resw=lf_var1w << lf_var2b; \
save(op1,lf_resw); \
lflags.type=t_SHLw;
#define SHLD(op1,op2,load,save) \
if (!op2) break; \
flags.var1.d=load(op1);flags.var2.b=op2; \
flags.result.d=flags.var1.d << flags.var2.b; \
save(op1,flags.result.d); \
flags.type=t_SHLd;
lf_var1d=load(op1);lf_var2b=op2; \
lf_resd=lf_var1d << lf_var2b; \
save(op1,lf_resd); \
lflags.type=t_SHLd;
#define SHRB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
flags.result.b=flags.var1.b >> flags.var2.b; \
save(op1,flags.result.b); \
flags.type=t_SHRb;
lf_var1b=load(op1);lf_var2b=op2; \
lf_resb=lf_var1b >> lf_var2b; \
save(op1,lf_resb); \
lflags.type=t_SHRb;
#define SHRW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2; \
flags.result.w=flags.var1.w >> flags.var2.b; \
save(op1,flags.result.w); \
flags.type=t_SHRw;
lf_var1w=load(op1);lf_var2b=op2; \
lf_resw=lf_var1w >> lf_var2b; \
save(op1,lf_resw); \
lflags.type=t_SHRw;
#define SHRD(op1,op2,load,save) \
if (!op2) break; \
flags.var1.d=load(op1);flags.var2.b=op2; \
flags.result.d=flags.var1.d >> flags.var2.b; \
save(op1,flags.result.d); \
flags.type=t_SHRd;
lf_var1d=load(op1);lf_var2b=op2; \
lf_resd=lf_var1d >> lf_var2b; \
save(op1,lf_resd); \
lflags.type=t_SHRd;
#define SARB(op1,op2,load,save) \
if (!op2) break; \
flags.var1.b=load(op1);flags.var2.b=op2; \
if (flags.var2.b>8) flags.var2.b=8; \
if (flags.var1.b & 0x80) { \
flags.result.b=(flags.var1.b >> flags.var2.b)| \
(0xff << (8 - flags.var2.b)); \
lf_var1b=load(op1);lf_var2b=op2; \
if (lf_var2b>8) lf_var2b=8; \
if (lf_var1b & 0x80) { \
lf_resb=(lf_var1b >> lf_var2b)| \
(0xff << (8 - lf_var2b)); \
} else { \
flags.result.b=flags.var1.b >> flags.var2.b; \
lf_resb=lf_var1b >> lf_var2b; \
} \
save(op1,flags.result.b); \
flags.type=t_SARb;
save(op1,lf_resb); \
lflags.type=t_SARb;
#define SARW(op1,op2,load,save) \
if (!op2) break; \
flags.var1.w=load(op1);flags.var2.b=op2; \
if (flags.var2.b>16) flags.var2.b=16; \
if (flags.var1.w & 0x8000) { \
flags.result.w=(flags.var1.w >> flags.var2.b)| \
(0xffff << (16 - flags.var2.b)); \
lf_var1w=load(op1);lf_var2b=op2; \
if (lf_var2b>16) lf_var2b=16; \
if (lf_var1w & 0x8000) { \
lf_resw=(lf_var1w >> lf_var2b)| \
(0xffff << (16 - lf_var2b)); \
} else { \
flags.result.w=flags.var1.w >> flags.var2.b; \
lf_resw=lf_var1w >> lf_var2b; \
} \
save(op1,flags.result.w); \
flags.type=t_SARw;
save(op1,lf_resw); \
lflags.type=t_SARw;
#define SARD(op1,op2,load,save) \
if (!op2) break; \
flags.var2.b=op2;flags.var1.d=load(op1); \
if (flags.var1.d & 0x80000000) { \
flags.result.d=(flags.var1.d >> flags.var2.b)| \
(0xffffffff << (32 - flags.var2.b)); \
lf_var2b=op2;lf_var1d=load(op1); \
if (lf_var1d & 0x80000000) { \
lf_resd=(lf_var1d >> lf_var2b)| \
(0xffffffff << (32 - lf_var2b)); \
} else { \
flags.result.d=flags.var1.d >> flags.var2.b; \
lf_resd=lf_var1d >> lf_var2b; \
} \
save(op1,flags.result.d); \
flags.type=t_SARd;
save(op1,lf_resd); \
lflags.type=t_SARd;
@ -474,7 +471,7 @@
} \
SETFLAGBIT(SF,(reg_al&0x80)); \
SETFLAGBIT(ZF,(reg_al==0)); \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define DAS() \
@ -490,7 +487,7 @@
} else { \
SETFLAGBIT(CF,false); \
} \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAA() \
@ -505,7 +502,7 @@
SETFLAGBIT(CF,false); \
} \
reg_al &= 0x0F; \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAS() \
if (((reg_al & 0x0f)>9) || get_AF()) { \
@ -519,14 +516,14 @@
SETFLAGBIT(CF,false); \
} \
reg_al &= 0x0F; \
flags.type=t_UNKNOWN;
lflags.type=t_UNKNOWN;
#define AAM(op1) \
{ \
Bit8u BLAH=op1; \
reg_ah=reg_al / BLAH; \
reg_al=reg_al % BLAH; \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
SETFLAGBIT(SF,(reg_al & 0x80)); \
SETFLAGBIT(ZF,(reg_al == 0)); \
SETFLAGBIT(PF,parity_lookup[reg_al]); \
@ -547,11 +544,11 @@
SETFLAGBIT(SF,reg_al >= 0x80); \
SETFLAGBIT(ZF,reg_al == 0); \
SETFLAGBIT(PF,parity_lookup[reg_al]); \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
}
#define MULB(op1,load,save) \
flags.type=t_MUL; \
lflags.type=t_MUL; \
reg_ax=reg_al*load(op1); \
if (reg_ax & 0xff00) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
@ -564,7 +561,7 @@
Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \
reg_ax=(Bit16u)(tempu); \
reg_dx=(Bit16u)(tempu >> 16); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (reg_dx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
} else { \
@ -577,7 +574,7 @@
Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \
reg_eax=(Bit32u)(tempu); \
reg_edx=(Bit32u)(tempu >> 32); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (reg_edx) { \
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
} else { \
@ -654,7 +651,7 @@
#define IMULB(op1,load,save) \
{ \
flags.type=t_MUL; \
lflags.type=t_MUL; \
reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \
if ((reg_ax & 0xff80)==0xff80 || \
(reg_ax & 0xff80)==0x0000) { \
@ -670,7 +667,7 @@
Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \
reg_ax=(Bit16s)(temps); \
reg_dx=(Bit16s)(temps >> 16); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if (((temps & 0xffff8000)==0xffff8000 || \
(temps & 0xffff8000)==0x0000)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -685,7 +682,7 @@
((Bit64s)((Bit32s)(load(op1)))); \
reg_eax=(Bit32u)(temps); \
reg_edx=(Bit32u)(temps >> 32); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((reg_edx==0xffffffff) && \
(reg_eax & 0x80000000) ) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -702,7 +699,7 @@
Bits res; \
res=((Bit16s)op2) * ((Bit16s)op3); \
save(op1,res & 0xffff); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((res> -32768) && (res<32767)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
} else { \
@ -714,7 +711,7 @@
{ \
Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \
save(op1,(Bit32s)res); \
flags.type=t_MUL; \
lflags.type=t_MUL; \
if ((res>-((Bit64s)(2147483647)+1)) && \
(res<(Bit64s)2147483647)) { \
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
@ -827,39 +824,39 @@
#define DSHLW(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=(load(op1)<<16)|op2; \
Bit32u tempd=flags.var1.d << flags.var2.b; \
if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \
flags.result.w=(Bit16u)(tempd >> 16); \
save(op1,flags.result.w); \
flags.type=t_DSHLw;
lf_var2b=val;lf_var1d=(load(op1)<<16)|op2; \
Bit32u tempd=lf_var1d << lf_var2b; \
if (lf_var2b>16) tempd |= (op2 << (lf_var2b - 16)); \
lf_resw=(Bit16u)(tempd >> 16); \
save(op1,lf_resw); \
lflags.type=t_DSHLw;
#define DSHLD(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=load(op1); \
flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHLd;
lf_var2b=val;lf_var1d=load(op1); \
lf_resd=(lf_var1d << lf_var2b) | (op2 >> (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_DSHLd;
/* double-precision shift right has high bits in second argument */
#define DSHRW(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=(op2<<16)|load(op1); \
Bit32u tempd=flags.var1.d >> flags.var2.b; \
if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \
flags.result.w=(Bit16u)(tempd); \
save(op1,flags.result.w); \
flags.type=t_DSHRw;
lf_var2b=val;lf_var1d=(op2<<16)|load(op1); \
Bit32u tempd=lf_var1d >> lf_var2b; \
if (lf_var2b>16) tempd |= (op2 << (32-lf_var2b )); \
lf_resw=(Bit16u)(tempd); \
save(op1,lf_resw); \
lflags.type=t_DSHRw;
#define DSHRD(op1,op2,op3,load,save) \
Bit8u val=op3 & 0x1F; \
if (!val) break; \
flags.var2.b=val;flags.var1.d=load(op1); \
flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \
save(op1,flags.result.d); \
flags.type=t_DSHRd;
lf_var2b=val;lf_var1d=load(op1); \
lf_resd=(lf_var1d >> lf_var2b) | (op2 << (32-lf_var2b)); \
save(op1,lf_resd); \
lflags.type=t_DSHRd;
#define BSWAP(op1) \
op1 = (op1>>24)|((op1>>8)&0xFF00)|((op1<<8)&0xFF0000)|((op1<<24)&0xFF000000);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,6 +16,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#if !defined __LAZYFLAGS_H
#define __LAZYFLAG_H
//Flag Handling
Bitu get_CF(void);
Bitu get_AF(void);
@ -24,25 +27,51 @@ Bitu get_SF(void);
Bitu get_OF(void);
Bitu get_PF(void);
void FillFlags(void);
Bitu FillFlags(void);
#include "regs.h"
struct LazyFlags {
GenReg32 var1,var2,res;
Bitu type;
Bitu prev_type;
Bitu oldcf;
};
extern LazyFlags lfags;
#define lf_var1b lflags.var1.byte[BL_INDEX]
#define lf_var2b lflags.var2.byte[BL_INDEX]
#define lf_resb lflags.res.byte[BL_INDEX]
#define lf_var1w lflags.var1.word[W_INDEX]
#define lf_var2w lflags.var2.word[W_INDEX]
#define lf_resw lflags.res.word[W_INDEX]
#define lf_var1d lflags.var1.dword[DW_INDEX]
#define lf_var2d lflags.var2.dword[DW_INDEX]
#define lf_resd lflags.res.dword[DW_INDEX]
extern LazyFlags lflags;
#define SETFLAGSb(FLAGB) \
{ \
SETFLAGBIT(OF,get_OF()); \
flags.type=t_UNKNOWN; \
CPU_SetFlags((flags.word&0xffffff00)|((FLAGB) & 0xff)); \
lflags.type=t_UNKNOWN; \
CPU_SetFlags(FLAGB,FMASK_NORMAL & 0xff); \
}
#define SETFLAGSw(FLAGW) \
{ \
flags.type=t_UNKNOWN; \
lflags.type=t_UNKNOWN; \
CPU_SetFlagsw(FLAGW); \
}
#define SETFLAGSd(FLAGD) \
{ \
flags.type=t_UNKNOWN; \
CPU_SetFlags(FLAGD); \
lflags.type=t_UNKNOWN; \
CPU_SetFlagsd(FLAGD); \
}
#define LoadCF SETFLAGBIT(CF,get_CF());
@ -51,6 +80,23 @@ void FillFlags(void);
#define LoadOF SETFLAGBIT(OF,get_OF());
#define LoadAF SETFLAGBIT(AF,get_AF());
#define TFLG_O (get_OF())
#define TFLG_NO (!get_OF())
#define TFLG_B (get_CF())
#define TFLG_NB (!get_CF())
#define TFLG_Z (get_ZF())
#define TFLG_NZ (!get_ZF())
#define TFLG_BE (get_CF() || get_ZF())
#define TFLG_NBE (!get_CF() && !get_ZF())
#define TFLG_S (get_SF())
#define TFLG_NS (!get_SF())
#define TFLG_P (get_PF())
#define TFLG_NP (!get_PF())
#define TFLG_L ((get_SF()!=0) != (get_OF()!=0))
#define TFLG_NL ((get_SF()!=0) == (get_OF()!=0))
#define TFLG_LE (get_ZF() || ((get_SF()!=0) != (get_OF()!=0)))
#define TFLG_NLE (!get_ZF() && ((get_SF()!=0) == (get_OF()!=0)))
//Types of Flag changing instructions
enum {
t_UNKNOWN=0,
@ -73,7 +119,6 @@ enum {
t_RCLb,t_RCLw,t_RCLd,
t_RCRb,t_RCRw,t_RCRd,
t_NEGb,t_NEGw,t_NEGd,
t_CF,t_ZF,
t_DSHLw,t_DSHLd,
t_DSHRw,t_DSHRd,
@ -82,3 +127,4 @@ enum {
t_LASTFLAG
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -23,169 +23,267 @@
#include "dosbox.h"
#include "mem.h"
#include "paging.h"
#include "../hardware/vga.h"
#include "regs.h"
#include "lazyflags.h"
#include "cpu.h"
#include "debug.h"
#define LINK_TOTAL (64*1024)
static PageLink link_list[LINK_TOTAL];
struct PagingBlock paging;
PagingBlock paging;
static Bit32u mapfirstmb[LINK_START];
class PageDirChange : public PageChange {
public:
PageDirChange(PageDirectory * mydir) { dir=mydir;}
void Changed(PageLink * link,Bitu start,Bitu end) {
start>>=2;end>>=2;
for (;start<=end;start++) {
dir->InvalidateTable(start);
}
}
private:
PageDirectory * dir;
Bitu PageHandler::readb(PhysPt addr) {
E_Exit("No byte handler for read from %d",addr);
return 0;
}
Bitu PageHandler::readw(PhysPt addr) {
return
(readb(addr+0) << 0) |
(readb(addr+1) << 8);
}
Bitu PageHandler::readd(PhysPt addr) {
return
(readb(addr+0) << 0) |
(readb(addr+1) << 8) |
(readb(addr+2) << 16) |
(readb(addr+3) << 24);
}
void PageHandler::writeb(PhysPt addr,Bitu val) {
E_Exit("No byte handler for write to %d",addr);
};
class PageTableChange : public PageChange {
public:
PageTableChange(PageDirectory * mydir) { dir=mydir;}
void Changed(PageLink * link,Bitu start,Bitu end) {
start>>=2;end>>=2;
for (;start<=end;start++) {
dir->InvalidateLink(link->data.table,start);
}
}
private:
PageDirectory * dir;
void PageHandler::writew(PhysPt addr,Bitu val) {
writeb(addr+0,(Bit8u) (val >> 0));
writeb(addr+1,(Bit8u) (val >> 8));
}
void PageHandler::writed(PhysPt addr,Bitu val) {
writeb(addr+0,(Bit8u) (val >> 0));
writeb(addr+1,(Bit8u) (val >> 8));
writeb(addr+2,(Bit8u) (val >> 16));
writeb(addr+3,(Bit8u) (val >> 24));
};
HostPt PageHandler::GetHostPt(Bitu phys_page) {
return 0;
}
PageDirectory::PageDirectory() {
entry_init.data.dir=this;
entry_init.type=ENTRY_INIT;
link_init.read=0;
link_init.write=0;
link_init.entry=&entry_init;
table_change = new PageTableChange(this);
dir_change = new PageDirChange(this);
struct PF_Entry {
Bitu cs;
Bitu eip;
Bitu page_addr;
};
#define PF_QUEUESIZE 16
struct {
Bitu used;
PF_Entry entries[PF_QUEUESIZE];
} pf_queue;
static Bits PageFaultCore(void) {
CPU_CycleLeft+=CPU_Cycles;
CPU_Cycles=1;
Bitu ret=CPU_Core_Full_Run();
CPU_CycleLeft+=CPU_Cycles;
if (ret<0) E_Exit("Got a dosbox close machine in pagefault core?");
if (ret)
return ret;
if (!pf_queue.used) E_Exit("PF Core without PF");
PF_Entry * entry=&pf_queue.entries[pf_queue.used-1];
X86PageEntry pentry;
pentry.load=MEM_PhysReadD(entry->page_addr);
if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip)
return -1;
return 0;
}
PageDirectory::~PageDirectory() {
delete table_change;
delete dir_change;
#if C_DEBUG
Bitu DEBUG_EnableDebugger(void);
#endif
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) {
/* Save the state of the cpu cores */
LazyFlags old_lflags;
memcpy(&old_lflags,&lflags,sizeof(LazyFlags));
CPU_Decoder * old_cpudecoder;
old_cpudecoder=cpudecoder;
cpudecoder=&PageFaultCore;
paging.cr2=lin_addr;
PF_Entry * entry=&pf_queue.entries[pf_queue.used++];
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used);
entry->cs=SegValue(cs);
entry->eip=reg_eip;
entry->page_addr=page_addr;
//Caused by a write by default?
CPU_Exception(14,0x2 );
#if C_DEBUG
// DEBUG_EnableDebugger();
#endif
DOSBOX_RunMachine();
pf_queue.used--;
LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,pf_queue.used);
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
cpudecoder=old_cpudecoder;
}
void PageDirectory::ClearDirectory(void) {
Bitu i;
for (i=0;i<1024*1024;i++) links[i]=&link_init;
for (i=0;i<1024;i++) {
tables[i]=0;
void MEM_PhysWriteD(Bitu addr,Bit32u val);
class InitPageHandler : public PageHandler {
public:
InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;}
Bitu readb(PhysPt addr) {
InitPage(addr);
return mem_readb(addr);
}
}
void PageDirectory::SetBase(PhysPt page) {
base_page=page;
ClearDirectory();
/* Setup handler for PageDirectory changes */
link_dir=MEM_LinkPage(base_page,0);
if (!link_dir) E_Exit("PAGING:Directory setup on illegal address");
link_dir->data.dir=this;
link_dir->change=dir_change;
MEM_CheckLinks(link_dir->entry);
}
void PageDirectory::LinkPage(Bitu lin_page,Bitu phys_page) {
if (links[lin_page] != &link_init) MEM_UnlinkPage(links[lin_page]);
PageLink * link=MEM_LinkPage(phys_page,lin_page*4096);
if (link) links[lin_page]=link;
else links[lin_page]=&link_init;
}
bool PageDirectory::InitPage(Bitu lin_address) {
Bitu lin_page=lin_address >> 12;
Bitu table=lin_page >> 10;
Bitu index=lin_page & 0x3ff;
/* Check if there already is table linked */
if (!tables[table]) {
X86PageEntry table_entry;
table_entry.load=phys_page_readd(base_page,0);
if (!table_entry.block.p) {
LOG(LOG_PAGING,LOG_ERROR)("NP TABLE");
return false;
}
PageLink * link=MEM_LinkPage(table_entry.block.base,table_entry.block.base);
if (!link) return false;
link->data.table=table;
link->change=table_change;
MEM_CheckLinks(link->entry);
tables[table]=link;
Bitu readw(PhysPt addr) {
InitPage(addr);
return mem_readw(addr);
}
X86PageEntry entry;
entry.load=phys_page_readd(tables[table]->lin_base,index);
if (!entry.block.p) {
LOG(LOG_PAGING,LOG_ERROR)("NP PAGE");
return false;
Bitu readd(PhysPt addr) {
InitPage(addr);
return mem_readd(addr);
}
PageLink * link=MEM_LinkPage(entry.block.base,lin_page*4096);
if (!link) return false;
links[lin_page]=link;
return true;
}
bool PageDirectory::InitPageLinear(Bitu lin_address) {
Bitu phys_page=lin_address >> 12;
PageLink * link=MEM_LinkPage(phys_page,phys_page*4096);
if (link) {
/* Set the page entry in our table */
links[phys_page]=link;
return true;
void writeb(PhysPt addr,Bitu val) {
InitPage(addr);
mem_writeb(addr,val);
}
return false;
}
void PageDirectory::InvalidateTable(Bitu table) {
if (tables[table]) {
MEM_UnlinkPage(tables[table]);
tables[table]=0;
for (Bitu i=(table*1024);i<(table+1)*1024;i++) {
if (links[i]!=&link_init) {
MEM_UnlinkPage(links[i]);
links[i]=&link_init;
void writew(PhysPt addr,Bitu val) {
InitPage(addr);
mem_writew(addr,val);
}
void writed(PhysPt addr,Bitu val) {
InitPage(addr);
mem_writed(addr,val);
}
void InitPage(Bitu lin_addr) {
Bitu lin_page=lin_addr >> 12;
Bitu phys_page;
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;
table.load=MEM_PhysReadD(table_addr);
if (!table.block.p) {
LOG(LOG_PAGING,LOG_ERROR)("NP Table");
PAGING_PageFault(lin_addr,table_addr,0);
table.load=MEM_PhysReadD(table_addr);
if (!table.block.p)
E_Exit("Pagefault didn't correct table");
}
table.block.a=table.block.d=1; //Set access/Dirty
MEM_PhysWriteD(table_addr,table.load);
X86PageEntry entry;
Bitu entry_addr=(table.block.base<<12)+t_index*4;
entry.load=MEM_PhysReadD(entry_addr);
if (!entry.block.p) {
LOG(LOG_PAGING,LOG_ERROR)("NP Page");
PAGING_PageFault(lin_addr,entry_addr,0);
entry.load=MEM_PhysReadD(entry_addr);
if (!entry.block.p)
E_Exit("Pagefault didn't correct page");
}
entry.block.a=entry.block.d=1; //Set access/Dirty
MEM_PhysWriteD(entry_addr,entry.load);
phys_page=entry.block.base;
} else {
if (lin_page<LINK_START) phys_page=mapfirstmb[lin_page];
else phys_page=lin_page;
}
PAGING_LinkPage(lin_page,phys_page);
}
};
bool PAGING_MakePhysPage(Bitu & page) {
if (paging.enabled) {
Bitu d_index=page >> 10;
Bitu t_index=page & 0x3ff;
X86PageEntry table;
table.load=MEM_PhysReadD((paging.base.page<<12)+d_index*4);
if (!table.block.p) return false;
X86PageEntry entry;
entry.load=MEM_PhysReadD((table.block.base<<12)+t_index*4);
if (!entry.block.p) return false;
page=entry.block.base;
} else {
if (page<LINK_START) page=mapfirstmb[page];
//Else keep it the same
}
return true;
}
void PageDirectory::InvalidateLink(Bitu table,Bitu index) {
Bitu i=(table*1024)+index;
if (links[i]!=&link_init) {
MEM_UnlinkPage(links[i]);
links[i]=&link_init;
}
}
static InitPageHandler init_page_handler;
Bitu PAGING_GetDirBase(void) {
return paging.cr3;
}
void PAGING_InitTLB(void) {
for (Bitu i=0;i<TLB_SIZE;i++) {
paging.tlb.read[i]=0;
paging.tlb.write[i]=0;
paging.tlb.handler[i]=&init_page_handler;
}
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++;
paging.tlb.read[page]=0;
paging.tlb.write[page]=0;
paging.tlb.handler[page]=&init_page_handler;
}
paging.links.used=0;
}
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
for (;pages>0;pages--) {
paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.tlb.handler[lin_page]=&init_page_handler;
}
}
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 || phys_page>=TLB_SIZE)
E_Exit("Illegal page");
HostPt host_mem=handler->GetHostPt(phys_page);
paging.tlb.phys_page[lin_page]=phys_page;
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base;
else paging.tlb.read[lin_page]=0;
if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base;
else paging.tlb.write[lin_page]=0;
if (paging.links.used>=PAGING_LINKS) E_Exit("Not enough paging links");
paging.links.entries[paging.links.used++]=lin_page;
paging.tlb.handler[lin_page]=handler;
}
void PAGING_MapPage(Bitu lin_page,Bitu phys_page) {
if (lin_page<LINK_START) {
mapfirstmb[lin_page]=phys_page;
paging.tlb.read[lin_page]=0;
paging.tlb.write[lin_page]=0;
paging.tlb.handler[lin_page]=&init_page_handler;
} else {
PAGING_LinkPage(lin_page,phys_page);
}
}
void PAGING_SetDirBase(Bitu cr3) {
paging.cr3=cr3;
Bitu base_page=cr3 >> 12;
LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,base_page);
paging.base.page=cr3 >> 12;
paging.base.addr=cr3 & ~4095;
LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page);
if (paging.enabled) {
/* Check if we already have this one cached */
PageDirectory * dir=paging.cache;
while (dir) {
if (dir->base_page==base_page) {
paging.dir=dir;
return;
}
dir=dir->next;
}
/* Couldn't find cached directory, make a new one */
dir=new PageDirectory();
dir->next=paging.cache;
paging.cache=dir;
dir->SetBase(base_page);
paging.dir=dir;
PAGING_ClearTLB();
}
}
@ -195,59 +293,25 @@ void PAGING_Enable(bool enabled) {
paging.enabled=enabled;
if (!enabled) {
LOG(LOG_PAGING,LOG_NORMAL)("Disabled");
paging.dir=MEM_DefaultDirectory();
} else {
LOG(LOG_PAGING,LOG_NORMAL)("Enabled");
#if !(C_DEBUG)
E_Exit("CPU Paging features aren't supported");
#endif
PAGING_SetDirBase(paging.cr3);
}
PAGING_ClearTLB();
}
bool PAGING_Enabled(void) {
return paging.enabled;
}
void PAGING_FreePageLink(PageLink * link) {
MEM_UnlinkPage(link);
PAGING_AddFreePageLink(link);
}
void PAGING_LinkPage(PageDirectory * dir,Bitu lin_page,Bitu phys_page) {
PageLink * link=MEM_LinkPage(phys_page,lin_page*4096);
/* Only replace if we can */
if (link) {
PAGING_FreePageLink(dir->links[lin_page]);
dir->links[lin_page]=link;
}
}
void PAGING_AddFreePageLink(PageLink * link) {
link->read=0;
link->write=0;
link->change=0;
link->next=paging.free_link;
link->entry=0;
paging.free_link=link;
}
PageLink * PAGING_GetFreePageLink(void) {
PageLink * ret;
if (paging.free_link) ret=paging.free_link;
else E_Exit("PAGING:Ran out of PageEntries");
paging.free_link=ret->next;
ret->next=0;
return ret;
}
void PAGING_Init(Section * sec) {
Bitu i;
/* Setup the free pages tables for fast page allocation */
paging.cache=0;
paging.free_link=0;
for (i=0;i<LINK_TOTAL;i++) PAGING_AddFreePageLink(&link_list[i]);
/* Setup default Page Directory, force it to update */
paging.enabled=true;PAGING_Enable(false);
paging.enabled=false;
PAGING_InitTLB();
Bitu i;
for (i=0;i<LINK_START;i++) {
mapfirstmb[i]=i;
}
pf_queue.used=0;
}

View File

@ -1,125 +0,0 @@
/*
* Copyright (C) 2002-2003 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.
*/
#include "dosbox.h"
#include "mem.h"
#include "cpu.h"
#include "lazyflags.h"
#include "inout.h"
#include "callback.h"
#include "pic.h"
#include "fpu.h"
#if C_DEBUG
#include "debug.h"
#endif
typedef PhysPt EAPoint;
#define SegBase(c) SegPhys(c)
#define LoadMb(off) mem_readb(off)
#define LoadMw(off) mem_readw(off)
#define LoadMd(off) mem_readd(off)
#define LoadMbs(off) (Bit8s)(LoadMb(off))
#define LoadMws(off) (Bit16s)(LoadMw(off))
#define LoadMds(off) (Bit32s)(LoadMd(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)
#define LoadRb(reg) reg
#define LoadRw(reg) reg
#define LoadRd(reg) reg
#define SaveRb(reg,val) reg=val
#define SaveRw(reg,val) reg=val
#define SaveRd(reg,val) reg=val
extern Bitu cycle_count;
/* Enable parts of the cpu emulation */
#define CPU_386 //Enable 386 instructions
#define CPU_PREFIX_67 //Enable the 0x67 prefix
#define CPU_PIC_CHECK //Check for IRQ's on critical moment
#if C_FPU
#define CPU_FPU //Enable FPU escape instructions
#endif
static struct {
Bitu prefixes;
PhysPt segbase;
PhysPt ip_lookup;
PhysPt ip_start;
}core_16 ;
#include "instructions.h"
#include "core_16/support.h"
static Bits CPU_Real_16_Slow_Decode_Trap(void);
static Bits CPU_Real_16_Slow_Decode(void) {
decode_start:
LOADIP;
flags.type=t_UNKNOWN;
while (CPU_Cycles>0) {
#if C_DEBUG
cycle_count++;
#if C_HEAVY_DEBUG
LEAVECORE;
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
#endif
core_16.ip_start=core_16.ip_lookup;
core_16.prefixes=0;
lookupEATable=EAPrefixTable[0];
#include "core_16/main.h"
CPU_Cycles--;
}
decode_end:
LEAVECORE;
return CBRET_NONE;
}
static Bits CPU_Real_16_Slow_Decode_Trap(void) {
Bits oldCycles = CPU_Cycles;
CPU_Cycles = 1;
Bits ret=CPU_Real_16_Slow_Decode();
// LOG_DEBUG("TRAP: Trap Flag executed");
Interrupt(1);
CPU_Cycles = oldCycles-1;
cpudecoder = &CPU_Real_16_Slow_Decode;
return ret;
}
void CPU_Real_16_Slow_Start(bool big) {
if (big) E_Exit("Core 16 only runs 16-bit code");
cpudecoder=&CPU_Real_16_Slow_Decode;
EAPrefixTable[2]=&GetEA_32_n;
EAPrefixTable[3]=&GetEA_32_s;
EAPrefixTable[0]=&GetEA_16_n;
EAPrefixTable[1]=&GetEA_16_s;
};

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -318,7 +318,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -338,7 +338,6 @@ 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
@ -363,7 +362,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: debug.cpp,v 1.52 2004/01/27 14:52:28 qbix79 Exp $ */
#include "programs.h"
#include <string.h>
@ -34,8 +36,9 @@
#include "mixer.h"
#include "debug_inc.h"
#include "timer.h"
#include "paging.h"
#include "../ints/xms.h"
#include "../shell/shell_inc.h"
#include "shell.h"
#ifdef WIN32
void WIN32_Console();
@ -51,8 +54,12 @@ static void DrawCode(void);
static bool DEBUG_Log_Loop(int count);
static void DEBUG_RaiseTimerIrq(void);
char* AnalyzeInstruction(char* inst, bool saveSelector);
void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num);
void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num);
Bit32u GetHexValue(char* str, char*& hex);
void LogGDT(void);
void LogLDT(void);
void LogIDT(void);
void OutputVecTable(char* filename);
class DEBUG;
@ -60,6 +67,13 @@ DEBUG* pDebugcom = 0;
bool exitLoop = false;
bool logHeavy = false;
// Heavy Debugging Vars for logging
#if C_HEAVY_DEBUG
static FILE* cpuLogFile = 0;
static bool cpuLog = false;
static int cpuLogCounter = 0;
#endif
static struct {
Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip;
} oldregs;
@ -110,13 +124,18 @@ Bit32u PhysMakeProt(Bit16u selector, Bit32u offset)
Bit32u GetAddress(Bit16u seg, Bit32u offset)
{
if (cpu.pmode) return PhysMakeProt(seg,offset);
if (seg==SegValue(cs)) return SegPhys(cs)+offset;
if (cpu.pmode) {
Descriptor desc;
if (cpu.gdt.GetDescriptor(seg,desc)) return PhysMakeProt(seg,offset);
}
return (seg<<4)+offset;
};
}
bool GetDescriptorInfo(char* selname, char* out1, char* out2)
{
Bit16u sel;
Bitu sel;
Descriptor desc;
if (strstr(selname,"cs") || strstr(selname,"CS")) sel = SegValue(cs); else
@ -174,7 +193,7 @@ std::list<CDebugVar*> CDebugVar::varList;
bool skipFirstInstruction = false;
enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY };
enum EBreakpoint { BKPNT_UNKNOWN, BKPNT_PHYSICAL, BKPNT_INTERRUPT, BKPNT_MEMORY, BKPNT_MEMORY_PROT, BKPNT_MEMORY_LINEAR };
#define BPINT_ALL 0x100
@ -341,19 +360,29 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off)
}
#if C_HEAVY_DEBUG
// Memory breakpoint support
else if ((bp->GetType()==BKPNT_MEMORY) && bp->IsActive()) {
Bitu address = GetAddress(bp->GetSegment(),bp->GetOffset());
// Bitu address = bp->GetSegment()*16 + bp->GetOffset();
Bit8u value = mem_readb(address);
if (bp->GetValue() != value) {
// Yup, memory value changed
DEBUG_ShowMsg("DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value);
bp->SetValue(value);
return true;
};
else if (bp->IsActive()) {
if ((bp->GetType()==BKPNT_MEMORY) || (bp->GetType()==BKPNT_MEMORY_PROT) || (bp->GetType()==BKPNT_MEMORY_LINEAR)) {
// Watch Protected Mode Memoryonly in pmode
if (bp->GetType()==BKPNT_MEMORY_PROT) {
// Check if pmode is active
if (!cpu.pmode) return false;
// Check if descriptor is valid
Descriptor desc;
if (!cpu.gdt.GetDescriptor(bp->GetSegment(),desc)) return false;
if (desc.GetLimit()==0) return false;
}
Bitu address;
if (bp->GetType()==BKPNT_MEMORY_LINEAR) address = bp->GetOffset();
else address = GetAddress(bp->GetSegment(),bp->GetOffset());
Bit8u value = mem_readb(address);
if (bp->GetValue() != value) {
// Yup, memory value changed
DEBUG_ShowMsg("DEBUG: Memory breakpoint %s: %04X:%04X - %02X -> %02X",(bp->GetType()==BKPNT_MEMORY_PROT)?"(Prot)":"",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value);
bp->SetValue(value);
return true;
};
}
};
#endif
};
@ -574,7 +603,9 @@ static void DrawData(void) {
mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add);
for (int x=0; x<16; x++) {
address = GetAddress(dataSeg,add);
if (address<8*1024*1024) ch = mem_readb(address); else ch = 0;
if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) {
ch = mem_readb(address);
} else ch = 0;
mvwprintw (dbg.win_data,1+y,11+3*x,"%02X",ch);
if (ch<32) ch='.';
mvwprintw (dbg.win_data,1+y,60+x,"%c",ch);
@ -606,31 +637,35 @@ static void DrawRegisters(void) {
/*Individual flags*/
SetColor((flags.word ^ oldflags)&FLAG_CF);
SetColor((reg_flags ^ oldflags)&FLAG_CF);
mvwprintw (dbg.win_reg,1,53,"%01X",GETFLAG(CF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_ZF);
SetColor((reg_flags ^ oldflags)&FLAG_ZF);
mvwprintw (dbg.win_reg,1,56,"%01X",GETFLAG(ZF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_SF);
SetColor((reg_flags ^ oldflags)&FLAG_SF);
mvwprintw (dbg.win_reg,1,59,"%01X",GETFLAG(SF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_OF);
SetColor((reg_flags ^ oldflags)&FLAG_OF);
mvwprintw (dbg.win_reg,1,62,"%01X",GETFLAG(OF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_AF);
SetColor((reg_flags ^ oldflags)&FLAG_AF);
mvwprintw (dbg.win_reg,1,65,"%01X",GETFLAG(AF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_PF);
SetColor((reg_flags ^ oldflags)&FLAG_PF);
mvwprintw (dbg.win_reg,1,68,"%01X",GETFLAG(PF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_DF);
SetColor((reg_flags ^ oldflags)&FLAG_DF);
mvwprintw (dbg.win_reg,1,71,"%01X",GETFLAG(DF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_IF);
SetColor((reg_flags ^ oldflags)&FLAG_IF);
mvwprintw (dbg.win_reg,1,74,"%01X",GETFLAG(IF) ? 1:0);
SetColor((flags.word ^ oldflags)&FLAG_TF);
SetColor((reg_flags ^ oldflags)&FLAG_TF);
mvwprintw (dbg.win_reg,1,77,"%01X",GETFLAG(TF) ? 1:0);
oldflags=flags.word;
oldflags=reg_flags;
if (cpu.pmode) mvwprintw(dbg.win_reg,0,76,"Prot");
else mvwprintw(dbg.win_reg,0,76,"Real");
if (cpu.pmode) {
if (reg_flags & FLAG_VM) mvwprintw(dbg.win_reg,0,76,"VM86");
else if (cpu.code.big) mvwprintw(dbg.win_reg,0,76,"Pr32");
else mvwprintw(dbg.win_reg,0,76,"Pr16");
} else
mvwprintw(dbg.win_reg,0,76,"Real");
// Selector info, if available
if ((cpu.pmode) && curSelectorName[0]) {
@ -788,21 +823,21 @@ bool ChangeRegister(char* str)
if (strstr(hex,"EBP")==hex) { hex+=3; reg_ebp = GetHexValue(hex,hex); } else
if (strstr(hex,"ESP")==hex) { hex+=3; reg_esp = GetHexValue(hex,hex); } else
if (strstr(hex,"EIP")==hex) { hex+=3; reg_eip = GetHexValue(hex,hex); } else
if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = GetHexValue(hex,hex); } else
if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = GetHexValue(hex,hex); } else
if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = GetHexValue(hex,hex); } else
if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = GetHexValue(hex,hex); } else
if (strstr(hex,"SI")==hex) { hex+=2; reg_si = GetHexValue(hex,hex); } else
if (strstr(hex,"DI")==hex) { hex+=2; reg_di = GetHexValue(hex,hex); } else
if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = GetHexValue(hex,hex); } else
if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = GetHexValue(hex,hex); } else
if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = GetHexValue(hex,hex); } else
if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,GetHexValue(hex,hex)); } else
if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,GetHexValue(hex,hex)); } else
if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,GetHexValue(hex,hex)); } else
if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,GetHexValue(hex,hex)); } else
if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,GetHexValue(hex,hex)); } else
if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,GetHexValue(hex,hex)); } else
if (strstr(hex,"AX")==hex) { hex+=2; reg_ax = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"BX")==hex) { hex+=2; reg_bx = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"CX")==hex) { hex+=2; reg_cx = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"DX")==hex) { hex+=2; reg_dx = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"SI")==hex) { hex+=2; reg_si = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"DI")==hex) { hex+=2; reg_di = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"BP")==hex) { hex+=2; reg_bp = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"SP")==hex) { hex+=2; reg_sp = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"IP")==hex) { hex+=2; reg_ip = (Bit16u)GetHexValue(hex,hex); } else
if (strstr(hex,"CS")==hex) { hex+=2; SegSet16(cs,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"DS")==hex) { hex+=2; SegSet16(ds,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"ES")==hex) { hex+=2; SegSet16(es,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"FS")==hex) { hex+=2; SegSet16(fs,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"GS")==hex) { hex+=2; SegSet16(gs,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"SS")==hex) { hex+=2; SegSet16(ss,(Bit16u)GetHexValue(hex,hex)); } else
if (strstr(hex,"AF")==hex) { hex+=2; SETFLAGBIT(AF,GetHexValue(hex,hex)); } else
if (strstr(hex,"CF")==hex) { hex+=2; SETFLAGBIT(CF,GetHexValue(hex,hex)); } else
if (strstr(hex,"DF")==hex) { hex+=2; SETFLAGBIT(PF,GetHexValue(hex,hex)); } else
@ -825,7 +860,7 @@ bool ParseCommand(char* str)
found = strstr(str,"MEMDUMP ");
if (found) { // Insert variable
found+=8;
Bit16u seg = GetHexValue(found,found); found++;
Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
Bit32u ofs = GetHexValue(found,found); found++;
Bit32u num = GetHexValue(found,found); found++;
SaveMemory(seg,ofs,num);
@ -835,8 +870,8 @@ bool ParseCommand(char* str)
found = strstr(str,"IV ");
if (found) { // Insert variable
found+=3;
Bit16u seg = GetHexValue(found,found); found++;
Bit32u ofs = GetHexValue(found,found); found++;
Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
Bit32u ofs = (Bit16u)GetHexValue(found,found); found++;
char name[16];
for (int i=0; i<16; i++) {
if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i];
@ -880,7 +915,7 @@ bool ParseCommand(char* str)
found = strstr(str,"BP ");
if (found) { // Add new breakpoint
found+=3;
Bit16u seg = GetHexValue(found,found);found++; // skip ":"
Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
Bit32u ofs = GetHexValue(found,found);
CBreakpoint::AddBreakpoint(seg,ofs,false);
DEBUG_ShowMsg("DEBUG: Set breakpoint at %04X:%04X",seg,ofs);
@ -890,18 +925,37 @@ bool ParseCommand(char* str)
found = strstr(str,"BPM ");
if (found) { // Add new breakpoint
found+=3;
Bit16u seg = GetHexValue(found,found);found++; // skip ":"
Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
Bit32u ofs = GetHexValue(found,found);
CBreakpoint::AddMemBreakpoint(seg,ofs);
DEBUG_ShowMsg("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs);
return true;
}
found = strstr(str,"BPPM ");
if (found) { // Add new breakpoint
found+=4;
Bit16u seg = (Bit16u)GetHexValue(found,found);found++; // skip ":"
Bit32u ofs = GetHexValue(found,found);
CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(seg,ofs);
if (bp) bp->SetType(BKPNT_MEMORY_PROT);
DEBUG_ShowMsg("DEBUG: Set prot-mode memory breakpoint at %04X:%08X",seg,ofs);
return true;
}
found = strstr(str,"BPLM ");
if (found) { // Add new breakpoint
found+=4;
Bitu ofs = GetHexValue(found,found);
CBreakpoint* bp = CBreakpoint::AddMemBreakpoint(0,ofs);
if (bp) bp->SetType(BKPNT_MEMORY_LINEAR);
DEBUG_ShowMsg("DEBUG: Set linear memory breakpoint at %08X",ofs);
return true;
}
#endif
found = strstr(str,"BPINT");
if (found) { // Add Interrupt Breakpoint
found+=5;
Bit8u intNr = GetHexValue(found,found); found++;
Bit8u valAH = GetHexValue(found,found);
Bit8u intNr = (Bit8u)GetHexValue(found,found); found++;
Bit8u valAH = (Bit8u)GetHexValue(found,found);
if ((valAH==0x00) && (*found=='*')) {
CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false);
DEBUG_ShowMsg("DEBUG: Set interrupt breakpoint at INT %02X",intNr);
@ -922,7 +976,7 @@ bool ParseCommand(char* str)
found = strstr(str,"BPDEL");
if (found) { // Delete Breakpoints
found+=5;
Bit8u bpNr = GetHexValue(found,found);
Bit8u bpNr = (Bit8u)GetHexValue(found,found);
if ((bpNr==0x00) && (*found=='*')) { // Delete all
CBreakpoint::DeleteAll();
DEBUG_ShowMsg("DEBUG: Breakpoints deleted.");
@ -935,7 +989,7 @@ bool ParseCommand(char* str)
found = strstr(str,"C ");
if (found==(char*)str) { // Set code overview
found++;
Bit16u codeSeg = GetHexValue(found,found); found++;
Bit16u codeSeg = (Bit16u)GetHexValue(found,found); found++;
Bit32u codeOfs = GetHexValue(found,found);
DEBUG_ShowMsg("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs);
codeViewData.useCS = codeSeg;
@ -945,19 +999,32 @@ bool ParseCommand(char* str)
found = strstr(str,"D ");
if (found==(char*)str) { // Set data overview
found++;
dataSeg = GetHexValue(found,found); found++;
dataSeg = (Bit16u)GetHexValue(found,found); found++;
dataOfs = GetHexValue(found,found);
DEBUG_ShowMsg("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs);
return true;
}
#if C_HEAVY_DEBUG
found = strstr(str,"LOG ");
if (found) { // Create Cpu log file
found+=4;
DEBUG_ShowMsg("DEBUG: Starting log");
DEBUG_Log_Loop(GetHexValue(found,found));
DEBUG_ShowMsg("DEBUG: Logfile LOGCPU.TXT created.");
// DEBUG_Log_Loop(GetHexValue(found,found));
cpuLogFile = fopen("LOGCPU.TXT","wt");
if (!cpuLogFile) {
DEBUG_ShowMsg("DEBUG: Logfile couldnt be created.");
return false;
}
cpuLog = true;
cpuLogCounter = GetHexValue(found,found);
debugging=false;
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
ignoreAddressOnce = SegPhys(cs)+reg_eip;
DOSBOX_SetNormalLoop();
return true;
}
#endif
found = strstr(str,"SR ");
if (found) { // Set register value
found+=2;
@ -968,13 +1035,13 @@ bool ParseCommand(char* str)
found = strstr(str,"SM ");
if (found) { // Set memory with following values
found+=3;
Bit16u seg = GetHexValue(found,found); found++;
Bit16u seg = (Bit16u)GetHexValue(found,found); found++;
Bit32u ofs = GetHexValue(found,found); found++;
Bit16u count = 0;
while (*found) {
while (*found==' ') found++;
if (*found) {
Bit8u value = GetHexValue(found,found); found++;
Bit8u value = (Bit8u)GetHexValue(found,found); found++;
mem_writeb(GetAddress(seg,ofs+count),value);
count++;
}
@ -985,23 +1052,23 @@ bool ParseCommand(char* str)
found = strstr(str,"INTT ");
if (found) { // Create Cpu log file
found+=4;
Bit8u intNr = GetHexValue(found,found);
Bit8u intNr = (Bit8u)GetHexValue(found,found);
DEBUG_ShowMsg("DEBUG: Tracing INT %02X",intNr);
Interrupt(intNr);
CPU_HW_Interrupt(intNr);
SetCodeWinStart();
return true;
}
found = strstr(str,"INT ");
if (found) { // Create Cpu log file
found+=4;
Bit8u intNr = GetHexValue(found,found);
Bit8u intNr = (Bit8u)GetHexValue(found,found);
DEBUG_ShowMsg("DEBUG: Starting INT %02X",intNr);
CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true);
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true);
debugging=false;
DrawCode();
DOSBOX_SetNormalLoop();
Interrupt(intNr);
CPU_HW_Interrupt(intNr);
return true;
}
found = strstr(str,"SELINFO ");
@ -1015,7 +1082,46 @@ bool ParseCommand(char* str)
DEBUG_ShowMsg("%s",out2);
};
/* found = strstr(str,"EXCEPTION ");
found = strstr(str,"GDT");
if (found) {
LogGDT();
}
found = strstr(str,"LDT");
if (found) {
LogLDT();
}
found = strstr(str,"IDT");
if (found) {
LogIDT();
}
found = strstr(str,"INTVEC ");
if (found)
{
found += 7;
while (found[0]==' ') found++;
if (found[0] != 0)
OutputVecTable(found);
}
found = strstr(str,"INTHAND ");
if (found)
{
found += 8;
while (found[0]==' ') found++;
if (found[0] != 0)
{
Bit8u intNr = (Bit8u)GetHexValue(found,found);
DEBUG_ShowMsg("DEBUG: Set code overview to interrupt handler %X",intNr);
codeViewData.useCS = mem_readw(intNr*4+2);
codeViewData.useEIP = mem_readw(intNr*4);
return true;
}
}
/* found = strstr(str,"EXCEPTION ");
if (found) {
found += 9;
Bit8u num = GetHexValue(found,found);
@ -1051,6 +1157,8 @@ bool ParseCommand(char* str)
wprintw(dbg.win_out,"BPINT [intNr] [ah] - Set interrupt breakpoint with ah\n");
#if C_HEAVY_DEBUG
wprintw(dbg.win_out,"BPM [segment]:[offset] - Set memory breakpoint (memory change)\n");
wprintw(dbg.win_out,"BPPM [selector]:[offset]- Set pmode-memory breakpoint (memory change)\n");
wprintw(dbg.win_out,"BPLM [linear address] - Set linear memory breakpoint (memory change)\n");
#endif
wprintw(dbg.win_out,"BPLIST - List breakpoints\n");
wprintw(dbg.win_out,"BPDEL [bpNr] / * - Delete breakpoint nr / all\n");
@ -1069,6 +1177,10 @@ bool ParseCommand(char* str)
wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n");
wprintw(dbg.win_out,"SELINFO [segName] - Show selector info\n");
wprintw(dbg.win_out,"INTVEC [filename] - Writes interrupt vector table to file\n");
wprintw(dbg.win_out,"INTHAND [intNum] - Set code view to interrupt handler\n");
wprintw(dbg.win_out,"H - Help\n");
wrefresh(dbg.win_out);
@ -1097,7 +1209,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector)
prefix[0] = tolower(*segpos);
prefix[1] = tolower(*(segpos+1));
prefix[2] = 0;
seg = GetHexValue(segpos,segpos);
seg = (Bit16u)GetHexValue(segpos,segpos);
} else {
if (strstr(pos,"SP") || strstr(pos,"BP")) {
seg = SegValue(ss);
@ -1121,25 +1233,27 @@ char* AnalyzeInstruction(char* inst, bool saveSelector)
pos++;
};
Bit32u address = GetAddress(seg,adr);
// if (address<(XMS_GetSize()+1)*1024*1024) {
static char outmask[] = "%s:[%04X]=%02X";
if (!(paging.tlb.handler[address >> 12]->flags & PFLAG_INIT)) {
static char outmask[] = "%s:[%04X]=%02X";
if (cpu.pmode) outmask[6] = '8';
switch (DasmLastOperandSize()) {
case 8 : { Bit8u val = mem_readb(address);
outmask[12] = '2';
sprintf(result,outmask,prefix,adr,val);
} break;
case 16: { Bit16u val = mem_readw(address);
outmask[12] = '4';
sprintf(result,outmask,prefix,adr,val);
} break;
case 32: { Bit32u val = mem_readd(address);
outmask[12] = '8';
sprintf(result,outmask,prefix,adr,val);
} break;
if (cpu.pmode) outmask[6] = '8';
switch (DasmLastOperandSize()) {
case 8 : { Bit8u val = mem_readb(address);
outmask[12] = '2';
sprintf(result,outmask,prefix,adr,val);
} break;
case 16: { Bit16u val = mem_readw(address);
outmask[12] = '4';
sprintf(result,outmask,prefix,adr,val);
} break;
case 32: { Bit32u val = mem_readd(address);
outmask[12] = '8';
sprintf(result,outmask,prefix,adr,val);
} break;
}
} else {
sprintf(result,"[illegal]");
}
// }
// Variable found ?
CDebugVar* var = CDebugVar::FindVar(address);
if (var) {
@ -1159,6 +1273,16 @@ char* AnalyzeInstruction(char* inst, bool saveSelector)
strcpy(curSelectorName,prefix);
};
};
// If it is a callback add additional info
pos = strstr(inst,"callback");
if (pos) {
pos += 9;
Bitu nr = GetHexValue(pos,pos);
const char* descr = CALLBACK_GetDescription(nr);
if (descr) {
strcat(inst," ("); strcat(inst,descr); strcat(inst,")");
}
};
return result;
};
@ -1189,7 +1313,7 @@ Bit32u DEBUG_CheckKeys(void) {
};
int key=getch();
Bit32u ret=0;
Bits ret=0;
if (key>0) {
switch (toupper(key)) {
case '1':
@ -1274,7 +1398,6 @@ Bit32u DEBUG_CheckKeys(void) {
skipFirstInstruction = true; // for heavy debugger
CPU_Cycles = 1;
Bitu ret=(*cpudecoder)();
if (ret>0) ret=(*CallBack_Handlers[ret])();
SetCodeWinStart();
CBreakpoint::ignoreOnce = 0;
}
@ -1284,11 +1407,20 @@ Bit32u DEBUG_CheckKeys(void) {
skipFirstInstruction = true; // for heavy debugger
CPU_Cycles = 1;
ret = (*cpudecoder)();
if (ret>0) ret=(*CallBack_Handlers[ret])();
SetCodeWinStart();
CBreakpoint::ignoreOnce = 0;
break;
}
if (ret<0) return ret;
if (ret>0){
ret=(*CallBack_Handlers[ret])();
if (ret) {
exitLoop=true;
CPU_Cycles=CPU_CycleLeft=0;
return ret;
}
}
ret=0;
DEBUG_DrawScreen();
}
return ret;
@ -1324,10 +1456,64 @@ void DEBUG_DrawScreen(void) {
DrawCode();
DrawRegisters();
}
static void DEBUG_RaiseTimerIrq(void) {
PIC_ActivateIRQ(0);
}
void LogGDT(void)
{
char out1[512];
Descriptor desc;
Bitu length = cpu.gdt.GetLimit();
PhysPt address = cpu.gdt.GetBase();
PhysPt max = address + length;
Bitu i = 0;
LOG(LOG_MISC,LOG_ERROR)("GDT Base:%08X Limit:%08X",address,length);
while (address<max) {
desc.Load(address);
sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3),desc.GetBase(),desc.saved.seg.type);
LOG(LOG_MISC,LOG_ERROR)(out1);
sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
LOG(LOG_MISC,LOG_ERROR)(out1);
address+=8; i++;
};
};
void LogLDT(void)
{
char out1[512];
Descriptor desc;
Bitu ldtSelector = cpu.gdt.SLDT();
cpu.gdt.GetDescriptor(ldtSelector,desc);
Bitu length = desc.GetLimit();
PhysPt address = desc.GetBase();
PhysPt max = address + length;
Bitu i = 0;
LOG(LOG_MISC,LOG_ERROR)("LDT Base:%08X Limit:%08X",address,length);
while (address<max) {
desc.Load(address);
sprintf(out1,"%04X: b:%08X type: %02X parbg",(i<<3)|4,desc.GetBase(),desc.saved.seg.type);
LOG(LOG_MISC,LOG_ERROR)(out1);
sprintf(out1," l:%08X dpl : %01X %1X%1X%1X%1X%1X",desc.GetLimit(),desc.saved.seg.dpl,desc.saved.seg.p,desc.saved.seg.avl,desc.saved.seg.r,desc.saved.seg.big,desc.saved.seg.g);
LOG(LOG_MISC,LOG_ERROR)(out1);
address+=8; i++;
};
};
void LogIDT(void)
{
char out1[512];
Descriptor desc;
Bitu address = 0;
while (address<256*8) {
cpu.idt.GetDescriptor(address,desc);
sprintf(out1,"%04X: sel:%04X off:%02X",address/8,desc.GetSelector(),desc.GetOffset());
LOG(LOG_MISC,LOG_ERROR)(out1);
address+=8;
};
};
static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer)
{
static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
@ -1344,9 +1530,8 @@ static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer)
if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," ");
// Get register values
sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),
GETFLAGBOOL(CF),GETFLAGBOOL(ZF),GETFLAGBOOL(SF),GETFLAGBOOL(OF),GETFLAGBOOL(AF),GETFLAGBOOL(PF));
sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X IF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),
GETFLAGBOOL(CF),GETFLAGBOOL(ZF),GETFLAGBOOL(SF),GETFLAGBOOL(OF),GETFLAGBOOL(AF),GETFLAGBOOL(PF),GETFLAGBOOL(IF));
};
static bool DEBUG_Log_Loop(int count) {
@ -1450,6 +1635,7 @@ Bitu DEBUG_EnableDebugger(void)
{
exitLoop = true;
DEBUG_Enable();
CPU_Cycles=CPU_CycleLeft=0;
return 0;
};
@ -1583,7 +1769,7 @@ bool CDebugVar::LoadVars(char* name)
return true;
};
void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num)
void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num)
{
FILE* f = fopen("MEMDUMP.TXT","wt");
if (!f) {
@ -1610,6 +1796,22 @@ void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num)
DEBUG_ShowMsg("DEBUG: Memory dump success.");
};
void OutputVecTable(char* filename)
{
FILE* f = fopen(filename, "wt");
if (!f)
{
DEBUG_ShowMsg("DEBUG: Output of interrupt vector table failed.");
return;
}
for (int i=0; i<256; i++)
fprintf(f,"INT %02X: %04X:%04X\n", i, mem_readw(i*4+2), mem_readw(i*4));
fclose(f);
DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename);
}
// HEAVY DEBUGGING STUFF
#if C_HEAVY_DEBUG
@ -1662,6 +1864,21 @@ void DEBUG_HeavyWriteLogInstruction(void)
bool DEBUG_HeavyIsBreakpoint(void)
{
if (cpuLog) {
if (cpuLogCounter>0) {
static char buffer[4096];
LogInstruction(SegValue(cs),reg_eip,buffer);
fprintf(cpuLogFile,"%s",buffer);
cpuLogCounter--;
}
if (cpuLogCounter<=0) {
fclose(cpuLogFile);
DEBUG_ShowMsg("DEBUG: cpu log LOGCPU.TXT created");
cpuLog = false;
DEBUG_EnableDebugger();
return true;
}
}
// LogInstruction
if (logHeavy) DEBUG_HeavyLogInstruction();
@ -1670,10 +1887,7 @@ bool DEBUG_HeavyIsBreakpoint(void)
return false;
}
PhysPt where = SegPhys(cs)+reg_eip;
if (CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) {
// exitLoop = true;
// DEBUG_Enable();
return true;
}
return false;

View File

@ -220,8 +220,7 @@ static char *op386map1[256] = {
"js %Jb", "jns %Jb", "jpe %Jb", "jpo %Jb",
"jl %Jb", "jge %Jb", "jle %Jb", "jg %Jb",
/* 8 */
/* "%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ib", "%g0 %Ev,%Ib", */
"%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Ev,%Ix", "%g0 %Ev,%Ix",
"%g0 %Eb,%Ib", "%g0 %Ev,%Iv", "%g0 %Eb,%Ib", "%g0 %Ev,%Ix",
"test %Eb,%Gb", "test %Ev,%Gv", "xchg %Eb,%Gb", "xchg %Ev,%Gv",
"mov %Eb,%Gb", "mov %Ev,%Gv", "mov %Gb,%Eb", "mov %Gv,%Ev",
"mov %Ew,%Sw", "lea %Gv,%M ", "mov %Sw,%Ew", "pop %Ev",

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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
@ -216,7 +216,7 @@ void DBGUI_StartUp(void) {
nodelay(dbg.win_main,true);
keypad(dbg.win_main,true);
#ifndef WIN32
resizeterm(50,80);
resizeterm(50,81);
touchwin(dbg.win_main);
old_cursor_state = curs_set(0);
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2003 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 The DOSBox Team
* Copyright (C) 2002-2004 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

View File

@ -1,9 +1,9 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libdos.a
EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h
EXTRA_DIST = scsidefs.h wnaspi32.h
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \
dev_con.h dos_mscdex.cpp \
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.7.7 from Makefile.am.
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
@ -132,12 +132,12 @@ target_vendor = @target_vendor@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libdos.a
EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h
EXTRA_DIST = scsidefs.h wnaspi32.h
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \
dev_con.h dos_mscdex.cpp \
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp
subdir = src/dos
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@ -154,7 +154,8 @@ am_libdos_a_OBJECTS = dos.$(OBJEXT) dos_devices.$(OBJEXT) \
dos_programs.$(OBJEXT) dos_tables.$(OBJEXT) drives.$(OBJEXT) \
drive_virtual.$(OBJEXT) drive_local.$(OBJEXT) \
drive_cache.$(OBJEXT) dos_mscdex.$(OBJEXT) cdrom.$(OBJEXT) \
cdrom_ioctl_win32.$(OBJEXT) cdrom_aspi_win32.$(OBJEXT)
cdrom_ioctl_win32.$(OBJEXT) cdrom_aspi_win32.$(OBJEXT) \
cdrom_ioctl_linux.$(OBJEXT)
libdos_a_OBJECTS = $(am_libdos_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@ -162,6 +163,7 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/cdrom.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_aspi_win32.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_linux.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_win32.Po ./$(DEPDIR)/dos.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/dos_classes.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/dos_devices.Po \
@ -213,6 +215,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_aspi_win32.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_ioctl_linux.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_ioctl_win32.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_classes.Po@am__quote@
@ -354,7 +357,7 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
@ -374,7 +377,6 @@ 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
@ -399,7 +401,6 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am

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