mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 18:11:50 +01:00
DOSBox 0.61
This commit is contained in:
parent
e99193553b
commit
a0ed243c23
38
ChangeLog
38
ChangeLog
@ -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
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Main Makefile for DOSBox
|
||||
|
||||
EXTRA_DIST = autogen.sh
|
||||
SUBDIRS = src include visualc docs
|
||||
SUBDIRS = src include visualc docs visualc_net
|
||||
|
||||
|
||||
|
||||
|
@ -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
38
NEWS
@ -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
105
README
@ -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.
|
||||
@ -45,6 +45,11 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
|
||||
-noconsole (Windows Only)
|
||||
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
3
THANKS
@ -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
4
aclocal.m4
vendored
@ -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 -*-
|
||||
|
||||
|
@ -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."
|
||||
|
18
config.h.in
18
config.h.in
@ -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
35
config.sub
vendored
@ -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
|
||||
;;
|
||||
|
73
configure.in
73
configure.in
@ -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
|
||||
],)
|
||||
|
||||
|
||||
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_MSG_RESULT(no)
|
||||
fi
|
||||
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])
|
||||
else
|
||||
AC_DEFINE(C_FPU,1)
|
||||
fi
|
||||
],AC_DEFINE(C_FPU,1))
|
||||
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
|
||||
])
|
||||
|
@ -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
|
||||
|
@ -26,7 +26,9 @@ regs.h \
|
||||
render.h \
|
||||
serialport.h \
|
||||
setup.h \
|
||||
shell.h \
|
||||
support.h \
|
||||
timer.h \
|
||||
vga.h \
|
||||
video.h
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
242
include/cpu.h
242
include/cpu.h
@ -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);
|
||||
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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
168
include/dma.h
168
include/dma.h
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
179
include/paging.h
179
include/paging.h
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
}
|
||||
@ -109,7 +98,6 @@ INLINE PhysPt SegPhys(SegNames index) {
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,18 +64,12 @@ 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;
|
||||
Bit8u bytes_skip;
|
||||
|
||||
/* Specific stuff memory write/read handling */
|
||||
|
||||
VGA_ReadHandler * readhandler;
|
||||
VGA_WriteHandler * writehandler;
|
||||
|
||||
Bit8u read_mode;
|
||||
Bit8u write_mode;
|
||||
@ -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];
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
@ -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());
|
||||
}
|
@ -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:;
|
||||
}
|
||||
|
@ -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]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_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
343
src/cpu/core_dyn_x86.cpp
Normal 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=®_eax;
|
||||
DynRegs[G_EAX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_ECX].data=®_ecx;
|
||||
DynRegs[G_ECX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_EDX].data=®_edx;
|
||||
DynRegs[G_EDX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_EBX].data=®_ebx;
|
||||
DynRegs[G_EBX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
|
||||
DynRegs[G_EBP].data=®_ebp;
|
||||
DynRegs[G_EBP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_ESP].data=®_esp;
|
||||
DynRegs[G_ESP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_EDI].data=®_edi;
|
||||
DynRegs[G_EDI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
||||
DynRegs[G_ESI].data=®_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=®_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=®_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
|
1
src/cpu/core_dyn_x86/Makefile.am
Normal file
1
src/cpu/core_dyn_x86/Makefile.am
Normal file
@ -0,0 +1 @@
|
||||
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h
|
@ -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
|
302
src/cpu/core_dyn_x86/cache.h
Normal file
302
src/cpu/core_dyn_x86/cache.h
Normal 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);
|
||||
}
|
1411
src/cpu/core_dyn_x86/decoder.h
Normal file
1411
src/cpu/core_dyn_x86/decoder.h
Normal file
File diff suppressed because it is too large
Load Diff
57
src/cpu/core_dyn_x86/helpers.h
Normal file
57
src/cpu/core_dyn_x86/helpers.h
Normal 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;
|
||||
}
|
799
src/cpu/core_dyn_x86/risc_x86.h
Normal file
799
src/cpu/core_dyn_x86/risc_x86.h
Normal 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);
|
||||
}
|
||||
|
||||
|
165
src/cpu/core_dyn_x86/string.h
Normal file
165
src/cpu/core_dyn_x86/string.h
Normal 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();
|
||||
}
|
@ -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) {
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,9 +61,12 @@ 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;
|
||||
goto l_M_Ew;
|
||||
case M_EwIw:
|
||||
inst.op2.d=Fetchw();
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 },
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
||||
if (GETFLAG(TF)) cpudecoder=CPU_Core_Normal_Decode_Trap;
|
||||
else cpudecoder=CPU_Core_Normal_Decode;
|
||||
void CPU_Core_Normal_Init(void) {
|
||||
|
||||
if (big) {
|
||||
core.index_default=0x200;
|
||||
core.prefix_default=PREFIX_ADDR;
|
||||
} else {
|
||||
core.index_default=0;
|
||||
core.prefix_default=0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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; \
|
||||
} \
|
||||
|
||||
|
@ -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;
|
||||
CASE_0F_W(0xa1) /* POP FS */
|
||||
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 */
|
||||
|
@ -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
|
||||
@ -24,8 +24,8 @@
|
||||
EAXId(ADDD);break;
|
||||
CASE_D(0x06) /* PUSH ES */
|
||||
Push_32(SegValue(es));break;
|
||||
CASE_D(0x07) /* POP ES */
|
||||
CPU_SetSegGeneral(es,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x07) /* POP ES */
|
||||
POPSEG(es,Pop_32(),4);break;
|
||||
CASE_D(0x09) /* OR Ed,Gd */
|
||||
RMEdGd(ORD);break;
|
||||
CASE_D(0x0b) /* OR Gd,Ed */
|
||||
@ -40,10 +40,12 @@
|
||||
RMGdEd(ADCD);break;
|
||||
CASE_D(0x15) /* ADC EAX,Id */
|
||||
EAXId(ADCD);break;
|
||||
CASE_D(0x16) /* PUSH SS */
|
||||
CASE_D(0x16) /* PUSH SS */
|
||||
Push_32(SegValue(ss));break;
|
||||
CASE_D(0x17) /* POP SS */
|
||||
CPU_SetSegGeneral(ss,(Bit16u)Pop_32());break;
|
||||
CASE_D(0x17) /* POP SS */
|
||||
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 */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
@ -30,8 +30,8 @@
|
||||
AXIw(ADDW);break;
|
||||
CASE_W(0x06) /* PUSH ES */
|
||||
Push_16(SegValue(es));break;
|
||||
CASE_W(0x07) /* POP ES */
|
||||
CPU_SetSegGeneral(es,Pop_16());break;
|
||||
CASE_W(0x07) /* POP ES */
|
||||
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 */
|
||||
@ -736,23 +739,16 @@
|
||||
reg_bp=Pop_16();
|
||||
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);}
|
||||
|
@ -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;
|
||||
|
@ -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 { \
|
||||
|
@ -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
|
||||
|
966
src/cpu/cpu.cpp
966
src/cpu/cpu.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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,8 +119,7 @@ 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,
|
||||
t_MUL,t_DIV,
|
||||
@ -82,3 +127,4 @@ enum {
|
||||
t_LASTFLAG
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
};
|
@ -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
|
||||
|
@ -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()) {
|
||||
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 = 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;
|
||||
};
|
||||
|
||||
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 (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 (!(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;
|
||||
}
|
||||
} 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;
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user